Project import
diff --git a/protobuf/Android.bp b/protobuf/Android.bp
new file mode 100644
index 0000000..9b747a0
--- /dev/null
+++ b/protobuf/Android.bp
@@ -0,0 +1,311 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// 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.
+//
+//
+
+IGNORED_WARNINGS = [
+    "-Wno-sign-compare",
+    "-Wno-unused-parameter",
+    "-Wno-sign-promo",
+    "-Wno-error=return-type",
+]
+
+cc_defaults {
+    name: "libprotobuf-cpp-lite-defaults",
+    srcs: [
+        "src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc",
+        "src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc",
+        "src/google/protobuf/stubs/common.cc",
+        "src/google/protobuf/stubs/once.cc",
+        "src/google/protobuf/stubs/stringprintf.cc",
+        "src/google/protobuf/extension_set.cc",
+        "src/google/protobuf/generated_message_util.cc",
+        "src/google/protobuf/message_lite.cc",
+        "src/google/protobuf/repeated_field.cc",
+        "src/google/protobuf/wire_format_lite.cc",
+        "src/google/protobuf/io/coded_stream.cc",
+        "src/google/protobuf/io/zero_copy_stream.cc",
+        "src/google/protobuf/io/zero_copy_stream_impl_lite.cc",
+    ],
+
+    local_include_dirs: [
+        "android",
+        "src",
+    ],
+    export_include_dirs: ["src"],
+
+    cflags: IGNORED_WARNINGS,
+}
+
+// C++ lite library for the NDK.
+// =======================================================
+cc_library_static {
+    name: "libprotobuf-cpp-lite-ndk",
+    defaults: ["libprotobuf-cpp-lite-defaults"],
+
+    cflags: ["-DGOOGLE_PROTOBUF_NO_RTTI"],
+
+    sdk_version: "9",
+
+    stl: "stlport_static",
+}
+
+// C++ lite library for the platform and host.
+// =======================================================
+cc_library {
+    name: "libprotobuf-cpp-lite",
+    host_supported: true,
+    defaults: ["libprotobuf-cpp-lite-defaults"],
+
+    cflags: ["-DGOOGLE_PROTOBUF_NO_RTTI"],
+
+    target: {
+        windows: {
+            enabled: true,
+        },
+    },
+}
+
+// C++ lite library + rtti (libc++ flavored for the platform and host)
+// =======================================================
+cc_library_shared {
+    name: "libprotobuf-cpp-lite-rtti",
+    host_supported: true,
+    defaults: ["libprotobuf-cpp-lite-defaults"],
+
+    rtti: true,
+}
+
+// C++ full library
+// =======================================================
+protobuf_cc_full_src_files = [
+    "src/google/protobuf/stubs/strutil.cc",
+    "src/google/protobuf/stubs/substitute.cc",
+    "src/google/protobuf/stubs/structurally_valid.cc",
+    "src/google/protobuf/descriptor.cc",
+    "src/google/protobuf/descriptor.pb.cc",
+    "src/google/protobuf/descriptor_database.cc",
+    "src/google/protobuf/dynamic_message.cc",
+    "src/google/protobuf/extension_set_heavy.cc",
+    "src/google/protobuf/generated_message_reflection.cc",
+    "src/google/protobuf/message.cc",
+    "src/google/protobuf/reflection_ops.cc",
+    "src/google/protobuf/service.cc",
+    "src/google/protobuf/text_format.cc",
+    "src/google/protobuf/unknown_field_set.cc",
+    "src/google/protobuf/wire_format.cc",
+    "src/google/protobuf/io/gzip_stream.cc",
+    "src/google/protobuf/io/printer.cc",
+    "src/google/protobuf/io/strtod.cc",
+    "src/google/protobuf/io/tokenizer.cc",
+    "src/google/protobuf/io/zero_copy_stream_impl.cc",
+    "src/google/protobuf/compiler/importer.cc",
+    "src/google/protobuf/compiler/parser.cc",
+]
+
+// C++ full library for the NDK.
+// =======================================================
+cc_library_static {
+    name: "libprotobuf-cpp-full-ndk",
+    defaults: ["libprotobuf-cpp-lite-defaults"],
+
+    srcs: protobuf_cc_full_src_files,
+    shared_libs: ["libz"],
+
+    cflags: ["-DGOOGLE_PROTOBUF_NO_RTTI"],
+
+    sdk_version: "9",
+
+    stl: "stlport_static",
+}
+
+// C++ full library for the NDK, Gnustl+rtti version.
+// =======================================================
+cc_library_static {
+    name: "libprotobuf-cpp-full-ndk-gnustl-rtti",
+    defaults: ["libprotobuf-cpp-lite-defaults"],
+
+    srcs: protobuf_cc_full_src_files,
+    shared_libs: ["libz"],
+
+    rtti: true,
+    sdk_version: "14",
+    stl: "gnustl_static",
+
+}
+
+// C++ full library for the platform and host
+// =======================================================
+cc_library_shared {
+    name: "libprotobuf-cpp-full",
+    defaults: ["libprotobuf-cpp-lite-defaults"],
+    host_supported: true,
+
+    srcs: protobuf_cc_full_src_files,
+
+    cflags: ["-DGOOGLE_PROTOBUF_NO_RTTI"],
+    target: {
+        android: {
+            shared_libs: ["libz"],
+        },
+        host: {
+            shared_libs: ["libz-host"],
+        },
+    },
+}
+
+// C++ full library + rtti for the platform and host
+// =======================================================
+cc_library_shared {
+    name: "libprotobuf-cpp-full-rtti",
+    defaults: ["libprotobuf-cpp-lite-defaults"],
+
+    srcs: protobuf_cc_full_src_files,
+
+    rtti: true,
+    target: {
+        android: {
+            shared_libs: ["libz"],
+        },
+        host: {
+            shared_libs: ["libz-host"],
+        },
+    },
+}
+
+// Android Protocol buffer compiler, aprotoc (host executable)
+// used by the build systems as $(PROTOC) defined in
+// build/core/config.mk
+// =======================================================
+cc_binary_host {
+    name: "aprotoc",
+
+    target: {
+        windows: {
+            enabled: true,
+        },
+        not_windows: {
+            host_ldlibs: ["-lpthread"],
+        },
+    },
+
+    // Statically link libc++ because we copy aprotoc to unbundled projects where
+    // libc++.so may not be available.
+    stl: "libc++_static",
+
+    srcs: [
+        "src/google/protobuf/descriptor.cc",
+        "src/google/protobuf/descriptor.pb.cc",
+        "src/google/protobuf/descriptor_database.cc",
+        "src/google/protobuf/dynamic_message.cc",
+        "src/google/protobuf/extension_set.cc",
+        "src/google/protobuf/extension_set_heavy.cc",
+        "src/google/protobuf/generated_message_reflection.cc",
+        "src/google/protobuf/generated_message_util.cc",
+        "src/google/protobuf/message.cc",
+        "src/google/protobuf/message_lite.cc",
+        "src/google/protobuf/reflection_ops.cc",
+        "src/google/protobuf/repeated_field.cc",
+        "src/google/protobuf/service.cc",
+        "src/google/protobuf/text_format.cc",
+        "src/google/protobuf/unknown_field_set.cc",
+        "src/google/protobuf/wire_format.cc",
+        "src/google/protobuf/wire_format_lite.cc",
+        "src/google/protobuf/compiler/code_generator.cc",
+        "src/google/protobuf/compiler/command_line_interface.cc",
+        "src/google/protobuf/compiler/importer.cc",
+        "src/google/protobuf/compiler/main.cc",
+        "src/google/protobuf/compiler/parser.cc",
+        "src/google/protobuf/compiler/plugin.cc",
+        "src/google/protobuf/compiler/plugin.pb.cc",
+        "src/google/protobuf/compiler/subprocess.cc",
+        "src/google/protobuf/compiler/zip_writer.cc",
+        "src/google/protobuf/compiler/cpp/cpp_enum.cc",
+        "src/google/protobuf/compiler/cpp/cpp_enum_field.cc",
+        "src/google/protobuf/compiler/cpp/cpp_extension.cc",
+        "src/google/protobuf/compiler/cpp/cpp_field.cc",
+        "src/google/protobuf/compiler/cpp/cpp_file.cc",
+        "src/google/protobuf/compiler/cpp/cpp_generator.cc",
+        "src/google/protobuf/compiler/cpp/cpp_helpers.cc",
+        "src/google/protobuf/compiler/cpp/cpp_message.cc",
+        "src/google/protobuf/compiler/cpp/cpp_message_field.cc",
+        "src/google/protobuf/compiler/cpp/cpp_primitive_field.cc",
+        "src/google/protobuf/compiler/cpp/cpp_service.cc",
+        "src/google/protobuf/compiler/cpp/cpp_string_field.cc",
+        "src/google/protobuf/compiler/java/java_context.cc",
+        "src/google/protobuf/compiler/java/java_enum.cc",
+        "src/google/protobuf/compiler/java/java_enum_field.cc",
+        "src/google/protobuf/compiler/java/java_extension.cc",
+        "src/google/protobuf/compiler/java/java_field.cc",
+        "src/google/protobuf/compiler/java/java_file.cc",
+        "src/google/protobuf/compiler/java/java_generator.cc",
+        "src/google/protobuf/compiler/java/java_generator_factory.cc",
+        "src/google/protobuf/compiler/java/java_helpers.cc",
+        "src/google/protobuf/compiler/java/java_lazy_message_field.cc",
+        "src/google/protobuf/compiler/java/java_message.cc",
+        "src/google/protobuf/compiler/java/java_message_field.cc",
+        "src/google/protobuf/compiler/java/java_name_resolver.cc",
+        "src/google/protobuf/compiler/java/java_primitive_field.cc",
+        "src/google/protobuf/compiler/java/java_shared_code_generator.cc",
+        "src/google/protobuf/compiler/java/java_service.cc",
+        "src/google/protobuf/compiler/java/java_string_field.cc",
+        "src/google/protobuf/compiler/java/java_doc_comment.cc",
+        "src/google/protobuf/compiler/javamicro/javamicro_enum.cc",
+        "src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc",
+        "src/google/protobuf/compiler/javamicro/javamicro_field.cc",
+        "src/google/protobuf/compiler/javamicro/javamicro_file.cc",
+        "src/google/protobuf/compiler/javamicro/javamicro_generator.cc",
+        "src/google/protobuf/compiler/javamicro/javamicro_helpers.cc",
+        "src/google/protobuf/compiler/javamicro/javamicro_message.cc",
+        "src/google/protobuf/compiler/javamicro/javamicro_message_field.cc",
+        "src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc",
+        "src/google/protobuf/compiler/javanano/javanano_enum.cc",
+        "src/google/protobuf/compiler/javanano/javanano_enum_field.cc",
+        "src/google/protobuf/compiler/javanano/javanano_extension.cc",
+        "src/google/protobuf/compiler/javanano/javanano_field.cc",
+        "src/google/protobuf/compiler/javanano/javanano_file.cc",
+        "src/google/protobuf/compiler/javanano/javanano_generator.cc",
+        "src/google/protobuf/compiler/javanano/javanano_helpers.cc",
+        "src/google/protobuf/compiler/javanano/javanano_message.cc",
+        "src/google/protobuf/compiler/javanano/javanano_message_field.cc",
+        "src/google/protobuf/compiler/javanano/javanano_primitive_field.cc",
+        "src/google/protobuf/compiler/python/python_generator.cc",
+        "src/google/protobuf/io/coded_stream.cc",
+        "src/google/protobuf/io/gzip_stream.cc",
+        "src/google/protobuf/io/printer.cc",
+        "src/google/protobuf/io/strtod.cc",
+        "src/google/protobuf/io/tokenizer.cc",
+        "src/google/protobuf/io/zero_copy_stream.cc",
+        "src/google/protobuf/io/zero_copy_stream_impl.cc",
+        "src/google/protobuf/io/zero_copy_stream_impl_lite.cc",
+        "src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc",
+        "src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc",
+        "src/google/protobuf/stubs/common.cc",
+        "src/google/protobuf/stubs/once.cc",
+        "src/google/protobuf/stubs/structurally_valid.cc",
+        "src/google/protobuf/stubs/strutil.cc",
+        "src/google/protobuf/stubs/substitute.cc",
+        "src/google/protobuf/stubs/stringprintf.cc",
+    ],
+
+    local_include_dirs: [
+        "android",
+        "src",
+    ],
+
+    static_libs: ["libz"],
+
+    cflags: IGNORED_WARNINGS,
+
+}
diff --git a/protobuf/Android.mk b/protobuf/Android.mk
new file mode 100644
index 0000000..c27bcad
--- /dev/null
+++ b/protobuf/Android.mk
@@ -0,0 +1,232 @@
+# Copyright (C) 2009 The Android Open Source Project
+#
+# 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.
+#
+#
+
+LOCAL_PATH := $(call my-dir)
+
+JAVA_LITE_SRC_FILES := \
+    java/src/main/java/com/google/protobuf/UninitializedMessageException.java \
+    java/src/main/java/com/google/protobuf/MessageLite.java \
+    java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \
+    java/src/main/java/com/google/protobuf/CodedOutputStream.java \
+    java/src/main/java/com/google/protobuf/ByteString.java \
+    java/src/main/java/com/google/protobuf/CodedInputStream.java \
+    java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java \
+    java/src/main/java/com/google/protobuf/AbstractMessageLite.java \
+    java/src/main/java/com/google/protobuf/AbstractParser.java \
+    java/src/main/java/com/google/protobuf/FieldSet.java \
+    java/src/main/java/com/google/protobuf/Internal.java \
+    java/src/main/java/com/google/protobuf/WireFormat.java \
+    java/src/main/java/com/google/protobuf/GeneratedMessageLite.java \
+    java/src/main/java/com/google/protobuf/BoundedByteString.java \
+    java/src/main/java/com/google/protobuf/LazyField.java \
+    java/src/main/java/com/google/protobuf/LazyFieldLite.java \
+    java/src/main/java/com/google/protobuf/LazyStringList.java \
+    java/src/main/java/com/google/protobuf/LazyStringArrayList.java \
+    java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java \
+    java/src/main/java/com/google/protobuf/LiteralByteString.java \
+    java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java \
+    java/src/main/java/com/google/protobuf/Parser.java \
+    java/src/main/java/com/google/protobuf/ProtocolStringList.java \
+    java/src/main/java/com/google/protobuf/RopeByteString.java \
+    java/src/main/java/com/google/protobuf/SmallSortedMap.java \
+    java/src/main/java/com/google/protobuf/Utf8.java
+
+# This contains more source files than needed for the full version, but the
+# additional files should not create any conflict.
+JAVA_FULL_SRC_FILES := \
+    $(call all-java-files-under, java/src/main/java) \
+    src/google/protobuf/descriptor.proto
+
+# Java nano library (for device-side users)
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libprotobuf-java-nano
+LOCAL_MODULE_TAGS := optional
+LOCAL_SDK_VERSION := 8
+
+LOCAL_SRC_FILES := $(call all-java-files-under, java/src/main/java/com/google/protobuf/nano)
+LOCAL_SRC_FILES += $(call all-java-files-under, java/src/device/main/java/com/google/protobuf/nano)
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Java nano library (for host-side users)
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := host-libprotobuf-java-nano
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, java/src/main/java/com/google/protobuf/nano)
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+# Java micro library (for device-side users)
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libprotobuf-java-micro
+LOCAL_MODULE_TAGS := optional
+LOCAL_SDK_VERSION := 8
+
+LOCAL_SRC_FILES := $(call all-java-files-under, java/src/main/java/com/google/protobuf/micro)
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Java micro library (for host-side users)
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := host-libprotobuf-java-micro
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, java/src/main/java/com/google/protobuf/micro)
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+# Java lite library (for device-side users)
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libprotobuf-java-lite
+LOCAL_MODULE_TAGS := optional
+LOCAL_SDK_VERSION := 9
+
+LOCAL_SRC_FILES := $(JAVA_LITE_SRC_FILES)
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Java lite library (for host-side users)
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := host-libprotobuf-java-lite
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(JAVA_LITE_SRC_FILES)
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+# Java full library (for host-side users)
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := host-libprotobuf-java-full
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(JAVA_FULL_SRC_FILES)
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+# To test java proto params build rules.
+# =======================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := aprotoc-test-nano-params
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := nano
+
+LOCAL_SRC_FILES := \
+        src/google/protobuf/unittest_import_nano.proto \
+        src/google/protobuf/unittest_simple_nano.proto \
+        src/google/protobuf/unittest_stringutf8_nano.proto \
+        src/google/protobuf/unittest_recursive_nano.proto
+
+
+LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/src
+
+LOCAL_PROTO_JAVA_OUTPUT_PARAMS := \
+        java_package = $(LOCAL_PATH)/src/google/protobuf/unittest_import_nano.proto|com.google.protobuf.nano, \
+        java_outer_classname = $(LOCAL_PATH)/src/google/protobuf/unittest_import_nano.proto|UnittestImportNano
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# To test Android-specific nanoproto features.
+# =======================================================
+include $(CLEAR_VARS)
+
+# Parcelable messages
+LOCAL_MODULE := android-nano-test-parcelable
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+# Only needed at compile-time.
+LOCAL_JAVA_LIBRARIES := android-support-annotations
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := nano
+
+LOCAL_SRC_FILES := src/google/protobuf/unittest_simple_nano.proto
+
+LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/src
+
+LOCAL_PROTO_JAVA_OUTPUT_PARAMS := \
+        parcelable_messages = true, \
+        generate_intdefs = true
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+
+# Parcelable and extendable messages
+LOCAL_MODULE := android-nano-test-parcelable-extendable
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+# Only needed at compile-time.
+LOCAL_JAVA_LIBRARIES := android-support-annotations
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := nano
+
+LOCAL_SRC_FILES := src/google/protobuf/unittest_extension_nano.proto
+
+LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/src
+
+LOCAL_PROTO_JAVA_OUTPUT_PARAMS := \
+        parcelable_messages = true, \
+        generate_intdefs = true, \
+        store_unknown_fields = true
+
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+
+# Test APK
+LOCAL_PACKAGE_NAME := NanoAndroidTest
+
+LOCAL_SDK_VERSION := 8
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, java/src/device/test/java/com/google/protobuf/nano)
+
+LOCAL_MANIFEST_FILE := java/src/device/test/AndroidManifest.xml
+
+LOCAL_STATIC_JAVA_LIBRARIES := libprotobuf-java-nano \
+        android-nano-test-parcelable \
+        android-nano-test-parcelable-extendable
+
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
diff --git a/protobuf/CHANGES.txt b/protobuf/CHANGES.txt
new file mode 100644
index 0000000..0d0ac81
--- /dev/null
+++ b/protobuf/CHANGES.txt
@@ -0,0 +1,593 @@
+2014-10-20 version 2.6.1:
+
+  C++
+  * Added atomicops support for Solaris.
+  * Released memory allocated by InitializeDefaultRepeatedFields() and
+    GetEmptyString(). Some memory sanitizers reported them as memory leaks.
+
+  Java
+  * Updated DynamicMessage.setField() to handle repeated enum values
+    correctly.
+  * Fixed a bug that caused NullPointerException to be thrown when
+    converting manually constructed FileDescriptorProto to
+    FileDescriptor.
+
+  Python
+  * Fixed WhichOneof() to work with de-serialized protobuf messages.
+  * Fixed a missing file problem of Python C++ implementation.
+
+2014-08-15 version 2.6.0:
+
+  General
+  * Added oneofs(unions) feature. Fields in the same oneof will share
+    memory and at most one field can be set at the same time. Use the
+    oneof keyword to define a oneof like:
+      message SampleMessage {
+        oneof test_oneof {
+          string name = 4;
+          YourMessage sub_message = 9;
+        }
+      }
+  * Files, services, enums, messages, methods and enum values can be marked
+    as deprecated now.
+  * Added Support for list values, including lists of mesaages, when
+    parsing text-formatted protos in C++ and Java.
+      For example:  foo: [1, 2, 3]
+
+  C++
+  * Enhanced customization on TestFormat printing.
+  * Added SwapFields() in reflection API to swap a subset of fields.
+    Added SetAllocatedMessage() in reflection API.
+  * Repeated primitive extensions are now packable. The
+    [packed=true] option only affects serializers. Therefore, it is
+    possible to switch a repeated extension field to packed format
+    without breaking backwards-compatibility.
+  * Various speed optimizations.
+
+  Java
+  * writeTo() method in ByteString can now write a substring to an
+    output stream. Added endWith() method for ByteString.
+  * ByteString and ByteBuffer are now supported in CodedInputStream
+    and CodedOutputStream.
+  * java_generate_equals_and_hash can now be used with the LITE_RUNTIME.
+
+  Python
+  * A new C++-backed extension module (aka "cpp api v2") that replaces the
+    old ("cpp api v1") one.  Much faster than the pure Python code.  This one
+    resolves many bugs and is recommended for general use over the
+    pure Python when possible.
+  * Descriptors now have enum_types_by_name and extension_types_by_name dict
+    attributes.
+  * Support for Python 3.
+
+2013-02-27 version 2.5.0:
+
+  General
+  * New notion "import public" that allows a proto file to forward the content
+    it imports to its importers. For example,
+      // foo.proto
+      import public "bar.proto";
+      import "baz.proto";
+
+      // qux.proto
+      import "foo.proto";
+      // Stuff defined in bar.proto may be used in this file, but stuff from
+      // baz.proto may NOT be used without importing it explicitly.
+    This is useful for moving proto files. To move a proto file, just leave
+    a single "import public" in the old proto file.
+  * New enum option "allow_alias" that specifies whether different symbols can
+    be assigned the same numeric value. Default value is "true". Setting it to
+    false causes the compiler to reject enum definitions where multiple symbols
+    have the same numeric value.
+    Note: We plan to flip the default value to "false" in a future release.
+    Projects using enum aliases should set the option to "true" in their .proto
+    files.
+
+  C++
+  * New generated method set_allocated_foo(Type* foo) for message and string
+    fields. This method allows you to set the field to a pre-allocated object
+    and the containing message takes the ownership of that object.
+  * Added SetAllocatedExtension() and ReleaseExtension() to extensions API.
+  * Custom options are now formatted correctly when descriptors are printed in
+    text format.
+  * Various speed optimizations.
+
+  Java
+  * Comments in proto files are now collected and put into generated code as
+    comments for corresponding classes and data members.
+  * Added Parser to parse directly into messages without a Builder. For
+    example,
+      Foo foo = Foo.PARSER.ParseFrom(input);
+    Using Parser is ~25% faster than using Builder to parse messages.
+  * Added getters/setters to access the underlying ByteString of a string field
+    directly.
+  * ByteString now supports more operations: substring(), prepend(), and
+    append(). The implementation of ByteString uses a binary tree structure
+    to support these operations efficiently.
+  * New method findInitializationErrors() that lists all missing required
+    fields.
+  * Various code size and speed optimizations.
+
+  Python
+  * Added support for dynamic message creation. DescriptorDatabase,
+    DescriptorPool, and MessageFactory work like their C++ couterparts to
+    simplify Descriptor construction from *DescriptorProtos, and MessageFactory
+    provides a message instance from a Descriptor.
+  * Added pickle support for protobuf messages.
+  * Unknown fields are now preserved after parsing.
+  * Fixed bug where custom options were not correctly populated. Custom
+    options can be accessed now.
+  * Added EnumTypeWrapper that provides better accessibility to enum types.
+  * Added ParseMessage(descriptor, bytes) to generate a new Message instance
+    from a descriptor and a byte string.
+
+2011-05-01 version 2.4.1:
+
+  C++
+  * Fixed the frendship problem for old compilers to make the library now gcc 3
+    compatible again.
+  * Fixed vcprojects/extract_includes.bat to extract compiler/plugin.h.
+
+  Java
+  * Removed usages of JDK 1.6 only features to make the library now JDK 1.5
+    compatible again.
+  * Fixed a bug about negative enum values.
+  * serialVersionUID is now defined in generated messages for java serializing.
+  * Fixed protoc to use java.lang.Object, which makes "Object" now a valid
+    message name again.
+
+  Python
+  * Experimental C++ implementation now requires C++ protobuf library installed.
+    See the README.txt in the python directory for details.
+
+2011-02-02 version 2.4.0:
+
+  General
+  * The RPC (cc|java|py)_generic_services default value is now false instead of
+    true.
+  * Custom options can have aggregate types. For example,
+      message MyOption {
+        optional string comment = 1;
+        optional string author = 2;
+      }
+      extend google.protobuf.FieldOptions {
+        optional MyOption myoption = 12345;
+      }
+    This option can now be set as follows:
+      message SomeType {
+        optional int32 field = 1 [(myoption) = { comment:'x' author:'y' }];
+      }
+
+  C++
+  * Various speed and code size optimizations.
+  * Added a release_foo() method on string and message fields.
+  * Fixed gzip_output_stream sub-stream handling.
+
+  Java
+  * Builders now maintain sub-builders for sub-messages. Use getFooBuilder() to
+    get the builder for the sub-message "foo". This allows you to repeatedly
+    modify deeply-nested sub-messages without rebuilding them.
+  * Builder.build() no longer invalidates the Builder for generated messages
+    (You may continue to modify it and then build another message).
+  * Code generator will generate efficient equals() and hashCode()
+    implementations if new option java_generate_equals_and_hash is enabled.
+    (Otherwise, reflection-based implementations are used.)
+  * Generated messages now implement Serializable.
+  * Fields with [deprecated=true] will be marked with @Deprecated in Java.
+  * Added lazy conversion of UTF-8 encoded strings to String objects to improve
+    performance.
+  * Various optimizations.
+  * Enum value can be accessed directly, instead of calling getNumber() on the
+    enum member.
+  * For each enum value, an integer constant is also generated with the suffix
+    _VALUE.
+
+  Python
+  * Added an experimental  C++ implementation for Python messages via a Python
+    extension. Implementation type is controlled by an environment variable
+    PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION (valid values: "cpp" and "python")
+    The default value is currently "python" but will be changed to "cpp" in
+    future release.
+  * Improved performance on message instantiation significantly.
+    Most of the work on message instantiation is done just once per message
+    class, instead of once per message instance.
+  * Improved performance on text message parsing.
+  * Allow add() to forward keyword arguments to the concrete class.
+      E.g. instead of
+        item = repeated_field.add()
+        item.foo = bar
+        item.baz = quux
+      You can do:
+        repeated_field.add(foo=bar, baz=quux)
+  * Added a sort() interface to the BaseContainer.
+  * Added an extend() method to repeated composite fields.
+  * Added UTF8 debug string support.
+
+2010-01-08 version 2.3.0:
+
+  General
+  * Parsers for repeated numeric fields now always accept both packed and
+    unpacked input.  The [packed=true] option only affects serializers.
+    Therefore, it is possible to switch a field to packed format without
+    breaking backwards-compatibility -- as long as all parties are using
+    protobuf 2.3.0 or above, at least.
+  * The generic RPC service code generated by the C++, Java, and Python
+    generators can be disabled via file options:
+      option cc_generic_services = false;
+      option java_generic_services = false;
+      option py_generic_services = false;
+    This allows plugins to generate alternative code, possibly specific to some
+    particular RPC implementation.
+
+  protoc
+  * Now supports a plugin system for code generators.  Plugins can generate
+    code for new languages or inject additional code into the output of other
+    code generators.  Plugins are just binaries which accept a protocol buffer
+    on stdin and write a protocol buffer to stdout, so they may be written in
+    any language.  See src/google/protobuf/compiler/plugin.proto.
+    **WARNING**:  Plugins are experimental.  The interface may change in a
+    future version.
+  * If the output location ends in .zip or .jar, protoc will write its output
+    to a zip/jar archive instead of a directory.  For example:
+      protoc --java_out=myproto_srcs.jar --python_out=myproto.zip myproto.proto
+    Currently the archive contents are not compressed, though this could change
+    in the future.
+  * inf, -inf, and nan can now be used as default values for float and double
+    fields.
+
+  C++
+  * Various speed and code size optimizations.
+  * DynamicMessageFactory is now fully thread-safe.
+  * Message::Utf8DebugString() method is like DebugString() but avoids escaping
+    UTF-8 bytes.
+  * Compiled-in message types can now contain dynamic extensions, through use
+    of CodedInputStream::SetExtensionRegistry().
+  * Now compiles shared libraries (DLLs) by default on Cygwin and MinGW, to
+    match other platforms.  Use --disable-shared to avoid this.
+
+  Java
+  * parseDelimitedFrom() and mergeDelimitedFrom() now detect EOF and return
+    false/null instead of throwing an exception.
+  * Fixed some initialization ordering bugs.
+  * Fixes for OpenJDK 7.
+
+  Python
+  * 10-25 times faster than 2.2.0, still pure-Python.
+  * Calling a mutating method on a sub-message always instantiates the message
+    in its parent even if the mutating method doesn't actually mutate anything
+    (e.g. parsing from an empty string).
+  * Expanded descriptors a bit.
+
+2009-08-11 version 2.2.0:
+
+  C++
+  * Lite mode:  The "optimize_for = LITE_RUNTIME" option causes the compiler
+    to generate code which only depends libprotobuf-lite, which is much smaller
+    than libprotobuf but lacks descriptors, reflection, and some other features.
+  * Fixed bug where Message.Swap(Message) was only implemented for
+    optimize_for_speed.  Swap now properly implemented in both modes
+    (Issue 91).
+  * Added RemoveLast and SwapElements(index1, index2) to Reflection
+    interface for repeated elements.
+  * Added Swap(Message) to Reflection interface.
+  * Floating-point literals in generated code that are intended to be
+    single-precision now explicitly have 'f' suffix to avoid pedantic warnings
+    produced by some compilers.
+  * The [deprecated=true] option now causes the C++ code generator to generate
+    a GCC-style deprecation annotation (no-op on other compilers).
+  * google::protobuf::GetEnumDescriptor<SomeGeneratedEnumType>() returns the
+    EnumDescriptor for that type -- useful for templates which cannot call
+    SomeGeneratedEnumType_descriptor().
+  * Various optimizations and obscure bug fixes.
+
+  Java
+  * Lite mode:  The "optimize_for = LITE_RUNTIME" option causes the compiler
+    to generate code which only depends libprotobuf-lite, which is much smaller
+    than libprotobuf but lacks descriptors, reflection, and some other features.
+  * Lots of style cleanups.
+
+  Python
+  * Fixed endianness bug with floats and doubles.
+  * Text format parsing support.
+  * Fix bug with parsing packed repeated fields in embedded messages.
+  * Ability to initialize fields by passing keyword args to constructor.
+  * Support iterators in extend and __setslice__ for containers.
+
+2009-05-13 version 2.1.0:
+
+  General
+  * Repeated fields of primitive types (types other that string, group, and
+    nested messages) may now use the option [packed = true] to get a more
+    efficient encoding.  In the new encoding, the entire list is written
+    as a single byte blob using the "length-delimited" wire type.  Within
+    this blob, the individual values are encoded the same way they would
+    be normally except without a tag before each value (thus, they are
+    tightly "packed").
+  * For each field, the generated code contains an integer constant assigned
+    to the field number.  For example, the .proto file:
+      message Foo { optional int bar_baz = 123; }
+    would generate the following constants, all with the integer value 123:
+      C++:     Foo::kBarBazFieldNumber
+      Java:    Foo.BAR_BAZ_FIELD_NUMBER
+      Python:  Foo.BAR_BAZ_FIELD_NUMBER
+    Constants are also generated for extensions, with the same naming scheme.
+    These constants may be used as switch cases.
+  * Updated bundled Google Test to version 1.3.0.  Google Test is now bundled
+    in its verbatim form as a nested autoconf package, so you can drop in any
+    other version of Google Test if needed.
+  * optimize_for = SPEED is now the default, by popular demand.  Use
+    optimize_for = CODE_SIZE if code size is more important in your app.
+  * It is now an error to define a default value for a repeated field.
+    Previously, this was silently ignored (it had no effect on the generated
+    code).
+  * Fields can now be marked deprecated like:
+      optional int32 foo = 1 [deprecated = true];
+    Currently this does not have any actual effect, but in the future the code
+    generators may generate deprecation annotations in each language.
+  * Cross-compiling should now be possible using the --with-protoc option to
+    configure.  See README.txt for more info.
+
+  protoc
+  * --error_format=msvs option causes errors to be printed in Visual Studio
+    format, which should allow them to be clicked on in the build log to go
+    directly to the error location.
+  * The type name resolver will no longer resolve type names to fields.  For
+    example, this now works:
+      message Foo {}
+      message Bar {
+        optional int32 Foo = 1;
+        optional Foo baz = 2;
+      }
+    Previously, the type of "baz" would resolve to "Bar.Foo", and you'd get
+    an error because Bar.Foo is a field, not a type.  Now the type of "baz"
+    resolves to the message type Foo.  This change is unlikely to make a
+    difference to anyone who follows the Protocol Buffers style guide.
+
+  C++
+  * Several optimizations, including but not limited to:
+    - Serialization, especially to flat arrays, is 10%-50% faster, possibly
+      more for small objects.
+    - Several descriptor operations which previously required locking no longer
+      do.
+    - Descriptors are now constructed lazily on first use, rather than at
+      process startup time.  This should save memory in programs which do not
+      use descriptors or reflection.
+    - UnknownFieldSet completely redesigned to be more efficient (especially in
+      terms of memory usage).
+    - Various optimizations to reduce code size (though the serialization speed
+      optimizations increased code size).
+  * Message interface has method ParseFromBoundedZeroCopyStream() which parses
+    a limited number of bytes from an input stream rather than parsing until
+    EOF.
+  * GzipInputStream and GzipOutputStream support reading/writing gzip- or
+    zlib-compressed streams if zlib is available.
+    (google/protobuf/io/gzip_stream.h)
+  * DescriptorPool::FindAllExtensions() and corresponding
+    DescriptorDatabase::FindAllExtensions() can be used to enumerate all
+    extensions of a given type.
+  * For each enum type Foo, protoc will generate functions:
+      const string& Foo_Name(Foo value);
+      bool Foo_Parse(const string& name, Foo* result);
+    The former returns the name of the enum constant corresponding to the given
+    value while the latter finds the value corresponding to a name.
+  * RepeatedField and RepeatedPtrField now have back-insertion iterators.
+  * String fields now have setters that take a char* and a size, in addition
+    to the existing ones that took char* or const string&.
+  * DescriptorPool::AllowUnknownDependencies() may be used to tell
+    DescriptorPool to create placeholder descriptors for unknown entities
+    referenced in a FileDescriptorProto.  This can allow you to parse a .proto
+    file without having access to other .proto files that it imports, for
+    example.
+  * Updated gtest to latest version.  The gtest package is now included as a
+    nested autoconf package, so it should be able to drop new versions into the
+    "gtest" subdirectory without modification.
+
+  Java
+  * Fixed bug where Message.mergeFrom(Message) failed to merge extensions.
+  * Message interface has new method toBuilder() which is equivalent to
+    newBuilderForType().mergeFrom(this).
+  * All enums now implement the ProtocolMessageEnum interface.
+  * Setting a field to null now throws NullPointerException.
+  * Fixed tendency for TextFormat's parsing to overflow the stack when
+    parsing large string values.  The underlying problem is with Java's
+    regex implementation (which unfortunately uses recursive backtracking
+    rather than building an NFA).  Worked around by making use of possesive
+    quantifiers.
+  * Generated service classes now also generate pure interfaces.  For a service
+    Foo, Foo.Interface is a pure interface containing all of the service's
+    defined methods.  Foo.newReflectiveService() can be called to wrap an
+    instance of this interface in a class that implements the generic
+    RpcService interface, which provides reflection support that is usually
+    needed by RPC server implementations.
+  * RPC interfaces now support blocking operation in addition to non-blocking.
+    The protocol compiler generates separate blocking and non-blocking stubs
+    which operate against separate blocking and non-blocking RPC interfaces.
+    RPC implementations will have to implement the new interfaces in order to
+    support blocking mode.
+  * New I/O methods parseDelimitedFrom(), mergeDelimitedFrom(), and
+    writeDelimitedTo() read and write "delemited" messages from/to a stream,
+    meaning that the message size precedes the data.  This way, you can write
+    multiple messages to a stream without having to worry about delimiting
+    them yourself.
+  * Throw a more descriptive exception when build() is double-called.
+  * Add a method to query whether CodedInputStream is at the end of the input
+    stream.
+  * Add a method to reset a CodedInputStream's size counter; useful when
+    reading many messages with the same stream.
+  * equals() and hashCode() now account for unknown fields.
+
+  Python
+  * Added slicing support for repeated scalar fields. Added slice retrieval and
+    removal of repeated composite fields.
+  * Updated RPC interfaces to allow for blocking operation.  A client may
+    now pass None for a callback when making an RPC, in which case the
+    call will block until the response is received, and the response
+    object will be returned directly to the caller.  This interface change
+    cannot be used in practice until RPC implementations are updated to
+    implement it.
+  * Changes to input_stream.py should make protobuf compatible with appengine.
+
+2008-11-25 version 2.0.3:
+
+  protoc
+  * Enum values may now have custom options, using syntax similar to field
+    options.
+  * Fixed bug where .proto files which use custom options but don't actually
+    define them (i.e. they import another .proto file defining the options)
+    had to explicitly import descriptor.proto.
+  * Adjacent string literals in .proto files will now be concatenated, like in
+    C.
+  * If an input file is a Windows absolute path (e.g. "C:\foo\bar.proto") and
+    the import path only contains "." (or contains "." but does not contain
+    the file), protoc incorrectly thought that the file was under ".", because
+    it thought that the path was relative (since it didn't start with a slash).
+    This has been fixed.
+
+  C++
+  * Generated message classes now have a Swap() method which efficiently swaps
+    the contents of two objects.
+  * All message classes now have a SpaceUsed() method which returns an estimate
+    of the number of bytes of allocated memory currently owned by the object.
+    This is particularly useful when you are reusing a single message object
+    to improve performance but want to make sure it doesn't bloat up too large.
+  * New method Message::SerializeAsString() returns a string containing the
+    serialized data.  May be more convenient than calling
+    SerializeToString(string*).
+  * In debug mode, log error messages when string-type fields are found to
+    contain bytes that are not valid UTF-8.
+  * Fixed bug where a message with multiple extension ranges couldn't parse
+    extensions.
+  * Fixed bug where MergeFrom(const Message&) didn't do anything if invoked on
+    a message that contained no fields (but possibly contained extensions).
+  * Fixed ShortDebugString() to not be O(n^2).  Durr.
+  * Fixed crash in TextFormat parsing if the first token in the input caused a
+    tokenization error.
+  * Fixed obscure bugs in zero_copy_stream_impl.cc.
+  * Added support for HP C++ on Tru64.
+  * Only build tests on "make check", not "make".
+  * Fixed alignment issue that caused crashes when using DynamicMessage on
+    64-bit Sparc machines.
+  * Simplify template usage to work with MSVC 2003.
+  * Work around GCC 4.3.x x86_64 compiler bug that caused crashes on startup.
+    (This affected Fedora 9 in particular.)
+  * Now works on "Solaris 10 using recent Sun Studio".
+
+  Java
+  * New overload of mergeFrom() which parses a slice of a byte array instead
+    of the whole thing.
+  * New method ByteString.asReadOnlyByteBuffer() does what it sounds like.
+  * Improved performance of isInitialized() when optimizing for code size.
+
+  Python
+  * Corrected ListFields() signature in Message base class to match what
+    subclasses actually implement.
+  * Some minor refactoring.
+  * Don't pass self as first argument to superclass constructor (no longer
+    allowed in Python 2.6).
+
+2008-09-29 version 2.0.2:
+
+  General
+  * License changed from Apache 2.0 to New BSD.
+  * It is now possible to define custom "options", which are basically
+    annotations which may be placed on definitions in a .proto file.
+    For example, you might define a field option called "foo" like so:
+      import "google/protobuf/descriptor.proto"
+      extend google.protobuf.FieldOptions {
+        optional string foo = 12345;
+      }
+    Then you annotate a field using the "foo" option:
+      message MyMessage {
+        optional int32 some_field = 1 [(foo) = "bar"]
+      }
+    The value of this option is then visible via the message's
+    Descriptor:
+      const FieldDescriptor* field =
+        MyMessage::descriptor()->FindFieldByName("some_field");
+      assert(field->options().GetExtension(foo) == "bar");
+    This feature has been implemented and tested in C++ and Java.
+    Other languages may or may not need to do extra work to support
+    custom options, depending on how they construct descriptors.
+
+  C++
+  * Fixed some GCC warnings that only occur when using -pedantic.
+  * Improved static initialization code, making ordering more
+    predictable among other things.
+  * TextFormat will no longer accept messages which contain multiple
+    instances of a singular field.  Previously, the latter instance
+    would overwrite the former.
+  * Now works on systems that don't have hash_map.
+
+  Java
+  * Print @Override annotation in generated code where appropriate.
+
+  Python
+  * Strings now use the "unicode" type rather than the "str" type.
+    String fields may still be assigned ASCII "str" values; they will
+    automatically be converted.
+  * Adding a property to an object representing a repeated field now
+    raises an exception.  For example:
+      # No longer works (and never should have).
+      message.some_repeated_field.foo = 1
+
+  Windows
+  * We now build static libraries rather than DLLs by default on MSVC.
+    See vsprojects/readme.txt for more information.
+
+2008-08-15 version 2.0.1:
+
+  protoc
+  * New flags --encode and --decode can be used to convert between protobuf text
+    format and binary format from the command-line.
+  * New flag --descriptor_set_out can be used to write FileDescriptorProtos for
+    all parsed files directly into a single output file.  This is particularly
+    useful if you wish to parse .proto files from programs written in languages
+    other than C++: just run protoc as a background process and have it output
+    a FileDescriptorList, then parse that natively.
+  * Improved error message when an enum value's name conflicts with another
+    symbol defined in the enum type's scope, e.g. if two enum types declared
+    in the same scope have values with the same name.  This is disallowed for
+    compatibility with C++, but this wasn't clear from the error.
+  * Fixed absolute output paths on Windows.
+  * Allow trailing slashes in --proto_path mappings.
+
+  C++
+  * Reflection objects are now per-class rather than per-instance.  To make this
+    possible, the Reflection interface had to be changed such that all methods
+    take the Message instance as a parameter.  This change improves performance
+    significantly in memory-bandwidth-limited use cases, since it makes the
+    message objects smaller.  Note that source-incompatible interface changes
+    like this will not be made again after the library leaves beta.
+  * Heuristically detect sub-messages when printing unknown fields.
+  * Fix static initialization ordering bug that caused crashes at startup when
+    compiling on Mac with static linking.
+  * Fixed TokenizerTest when compiling with -DNDEBUG on Linux.
+  * Fixed incorrect definition of kint32min.
+  * Fix bytes type setter to work with byte sequences with embedded NULLs.
+  * Other irrelevant tweaks.
+
+  Java
+  * Fixed UnknownFieldSet's parsing of varints larger than 32 bits.
+  * Fixed TextFormat's parsing of "inf" and "nan".
+  * Fixed TextFormat's parsing of comments.
+  * Added info to Java POM that will be required when we upload the
+    package to a Maven repo.
+
+  Python
+  * MergeFrom(message) and CopyFrom(message) are now implemented.
+  * SerializeToString() raises an exception if the message is missing required
+    fields.
+  * Code organization improvements.
+  * Fixed doc comments for RpcController and RpcChannel, which had somehow been
+    swapped.
+  * Fixed text_format_test on Windows where floating-point exponents sometimes
+    contain extra zeros.
+  * Fix Python service CallMethod() implementation.
+
+  Other
+  * Improved readmes.
+  * VIM syntax highlighting improvements.
+
+2008-07-07 version 2.0.0:
+
+  * First public release.
diff --git a/protobuf/CONTRIBUTORS.txt b/protobuf/CONTRIBUTORS.txt
new file mode 100644
index 0000000..717ffc1
--- /dev/null
+++ b/protobuf/CONTRIBUTORS.txt
@@ -0,0 +1,93 @@
+This file contains a list of people who have made large contributions
+to the public version of Protocol Buffers.
+
+Original Protocol Buffers design and implementation:
+  Sanjay Ghemawat <sanjay@google.com>
+  Jeff Dean <jeff@google.com>
+  Daniel Dulitz <daniel@google.com>
+  Craig Silverstein
+  Paul Haahr <haahr@google.com>
+  Corey Anderson <corin@google.com>
+  (and many others)
+
+Proto2 C++ and Java primary author:
+  Kenton Varda <kenton@google.com>
+
+Proto2 Python primary authors:
+  Will Robinson <robinson@google.com>
+  Petar Petrov <petar@google.com>
+
+Large code contributions:
+  Jason Hsueh <jasonh@google.com>
+  Joseph Schorr <jschorr@google.com>
+  Wenbo Zhu <wenboz@google.com>
+
+Large quantity of code reviews:
+  Scott Bruce <sbruce@google.com>
+  Frank Yellin
+  Neal Norwitz <nnorwitz@google.com>
+  Jeffrey Yasskin <jyasskin@google.com>
+  Ambrose Feinstein <ambrose@google.com>
+
+Documentation:
+  Lisa Carey <lcarey@google.com>
+
+Maven packaging:
+  Gregory Kick <gak@google.com>
+
+Patch contributors:
+  Kevin Ko <kevin.s.ko@gmail.com>
+    * Small patch to handle trailing slashes in --proto_path flag.
+  Johan Euphrosine <proppy@aminche.com>
+    * Small patch to fix Python CallMethod().
+  Ulrich Kunitz <kune@deine-taler.de>
+    * Small optimizations to Python serialization.
+  Leandro Lucarella <llucax@gmail.com>
+    * VI syntax highlighting tweaks.
+    * Fix compiler to not make output executable.
+  Dilip Joseph <dilip.antony.joseph@gmail.com>
+    * Heuristic detection of sub-messages when printing unknown fields in
+      text format.
+  Brian Atkinson <nairb774@gmail.com>
+    * Added @Override annotation to generated Java code where appropriate.
+  Vincent Choinière <Choiniere.Vincent@hydro.qc.ca>
+    * Tru64 support.
+  Monty Taylor <monty.taylor@gmail.com>
+    * Solaris 10 + Sun Studio fixes.
+  Alek Storm <alek.storm@gmail.com>
+    * Slicing support for repeated scalar fields for the Python API.
+  Oleg Smolsky <oleg.smolsky@gmail.com>
+    * MS Visual Studio error format option.
+    * Detect unordered_map in stl_hash.m4.
+  Brian Olson <brianolson@google.com>
+    * gzip/zlib I/O support.
+  Michael Poole <mdpoole@troilus.org>
+    * Fixed warnings about generated constructors not explicitly initializing
+      all fields (only present with certain compiler settings).
+    * Added generation of field number constants.
+  Wink Saville <wink@google.com>
+    * Fixed initialization ordering problem in logging code.
+  Will Pierce <willp@nuclei.com>
+    * Small patch improving performance of in Python serialization.
+  Alexandre Vassalotti <alexandre@peadrop.com>
+    * Emacs mode for Protocol Buffers (editors/protobuf-mode.el).
+  Scott Stafford <scott.stafford@gmail.com>
+    * Added Swap(), SwapElements(), and RemoveLast() to Reflection interface.
+  Alexander Melnikov <alm@sibmail.ru>
+    * HPUX support.
+  Oliver Jowett <oliver.jowett@gmail.com>
+    * Detect whether zlib is new enough in configure script.
+    * Fixes for Solaris 10 32/64-bit confusion.
+  Evan Jones <evanj@mit.edu>
+    * Optimize Java serialization code when writing a small message to a stream.
+    * Optimize Java serialization of strings so that UTF-8 encoding happens only
+      once per string per serialization call.
+    * Clean up some Java warnings.
+    * Fix bug with permanent callbacks that delete themselves when run.
+  Michael Kucharski <m.kucharski@gmail.com>
+    * Added CodedInputStream.getTotalBytesRead().
+  Kacper Kowalik <xarthisius.kk@gmail.com>
+    * Fixed m4/acx_pthread.m4 problem for some Linux distributions.
+  William Orr <will@worrbase.com>
+    * Fixed detection of sched_yield on Solaris.
+    * Added atomicops for Solaris
diff --git a/protobuf/CleanSpec.mk b/protobuf/CleanSpec.mk
new file mode 100644
index 0000000..b84e1b6
--- /dev/null
+++ b/protobuf/CleanSpec.mk
@@ -0,0 +1,49 @@
+# Copyright (C) 2007 The Android Open Source Project
+#
+# 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.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list.  These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+#     $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+#     $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list.  E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/protobuf/INSTALL.txt b/protobuf/INSTALL.txt
new file mode 100644
index 0000000..ce3b094
--- /dev/null
+++ b/protobuf/INSTALL.txt
@@ -0,0 +1,237 @@
+This file contains detailed but generic information on building and
+installing the C++ part of this project.  For shorter instructions,
+as well as instructions for compiling and installing the Java or
+Python parts, see README.
+
+======================================================================
+
+Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/protobuf/LICENSE b/protobuf/LICENSE
new file mode 100644
index 0000000..705db57
--- /dev/null
+++ b/protobuf/LICENSE
@@ -0,0 +1,33 @@
+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.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it.  This code is not
+standalone and requires a support library to be linked with it.  This
+support library is itself covered by the above license.
diff --git a/protobuf/MODULE_LICENSE_APACHE2 b/protobuf/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/protobuf/MODULE_LICENSE_APACHE2
diff --git a/protobuf/Makefile.am b/protobuf/Makefile.am
new file mode 100644
index 0000000..24e5e55
--- /dev/null
+++ b/protobuf/Makefile.am
@@ -0,0 +1,267 @@
+## Process this file with automake to produce Makefile.in
+
+ACLOCAL_AMFLAGS = -I m4
+
+AUTOMAKE_OPTIONS = foreign
+
+# Build . before src so that our all-local and clean-local hooks kicks in at
+# the right time.
+SUBDIRS = . src
+
+# Always include gtest in distributions.
+DIST_SUBDIRS = $(subdirs) src
+
+# Build gtest before we build protobuf tests.  We don't add gtest to SUBDIRS
+# because then "make check" would also build and run all of gtest's own tests,
+# which takes a lot of time and is generally not useful to us.  Also, we don't
+# want "make install" to recurse into gtest since we don't want to overwrite
+# the installed version of gtest if there is one.
+check-local:
+	@echo "Making lib/libgtest.a lib/libgtest_main.a in gtest"
+	@cd gtest && $(MAKE) $(AM_MAKEFLAGS) lib/libgtest.la lib/libgtest_main.la
+
+# We would like to clean gtest when "make clean" is invoked.  But we have to
+# be careful because clean-local is also invoked during "make distclean", but
+# "make distclean" already recurses into gtest because it's listed among the
+# DIST_SUBDIRS.  distclean will delete gtest/Makefile, so if we then try to
+# cd to the directory again and "make clean" it will fail.  So, check that the
+# Makefile exists before recursing.
+clean-local:
+	@if test -e gtest/Makefile; then \
+	  echo "Making clean in gtest"; \
+	  cd gtest && $(MAKE) $(AM_MAKEFLAGS) clean; \
+	fi
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = protobuf.pc protobuf-lite.pc
+
+EXTRA_DIST =                                                                 \
+  autogen.sh                                                                 \
+  generate_descriptor_proto.sh                                               \
+  README.md                                                                  \
+  INSTALL.txt                                                                \
+  LICENSE                                                                    \
+  CONTRIBUTORS.txt                                                           \
+  CHANGES.txt                                                                \
+  editors/README.txt                                                         \
+  editors/proto.vim                                                          \
+  editors/protobuf-mode.el                                                   \
+  vsprojects/config.h                                                        \
+  vsprojects/extract_includes.bat                                            \
+  vsprojects/libprotobuf.vcproj                                              \
+  vsprojects/libprotobuf-lite.vcproj                                         \
+  vsprojects/libprotoc.vcproj                                                \
+  vsprojects/protobuf.sln                                                    \
+  vsprojects/protoc.vcproj                                                   \
+  vsprojects/readme.txt                                                      \
+  vsprojects/test_plugin.vcproj                                              \
+  vsprojects/tests.vcproj                                                    \
+  vsprojects/lite-test.vcproj                                                \
+  vsprojects/convert2008to2005.sh                                            \
+  examples/README.txt                                                        \
+  examples/Makefile                                                          \
+  examples/addressbook.proto                                                 \
+  examples/add_person.cc                                                     \
+  examples/list_people.cc                                                    \
+  examples/AddPerson.java                                                    \
+  examples/ListPeople.java                                                   \
+  examples/add_person.py                                                     \
+  examples/list_people.py                                                    \
+  java/src/main/java/com/google/protobuf/AbstractMessage.java                \
+  java/src/main/java/com/google/protobuf/AbstractMessageLite.java            \
+  java/src/main/java/com/google/protobuf/AbstractParser.java                 \
+  java/src/main/java/com/google/protobuf/BlockingRpcChannel.java             \
+  java/src/main/java/com/google/protobuf/BlockingService.java                \
+  java/src/main/java/com/google/protobuf/BoundedByteString.java              \
+  java/src/main/java/com/google/protobuf/ByteString.java                     \
+  java/src/main/java/com/google/protobuf/CodedInputStream.java               \
+  java/src/main/java/com/google/protobuf/CodedOutputStream.java              \
+  java/src/main/java/com/google/protobuf/Descriptors.java                    \
+  java/src/main/java/com/google/protobuf/DynamicMessage.java                 \
+  java/src/main/java/com/google/protobuf/Extension.java                      \
+  java/src/main/java/com/google/protobuf/ExtensionRegistry.java              \
+  java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java          \
+  java/src/main/java/com/google/protobuf/FieldSet.java                       \
+  java/src/main/java/com/google/protobuf/GeneratedMessage.java               \
+  java/src/main/java/com/google/protobuf/GeneratedMessageLite.java           \
+  java/src/main/java/com/google/protobuf/Internal.java                       \
+  java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \
+  java/src/main/java/com/google/protobuf/LazyField.java                      \
+  java/src/main/java/com/google/protobuf/LazyFieldLite.java                  \
+  java/src/main/java/com/google/protobuf/LazyStringArrayList.java            \
+  java/src/main/java/com/google/protobuf/LazyStringList.java                 \
+  java/src/main/java/com/google/protobuf/LiteralByteString.java              \
+  java/src/main/java/com/google/protobuf/Message.java                        \
+  java/src/main/java/com/google/protobuf/MessageLite.java                    \
+  java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java           \
+  java/src/main/java/com/google/protobuf/MessageOrBuilder.java               \
+  java/src/main/java/com/google/protobuf/MessageReflection.java              \
+  java/src/main/java/com/google/protobuf/Parser.java                         \
+  java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java            \
+  java/src/main/java/com/google/protobuf/ProtocolStringList.java             \
+  java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java           \
+  java/src/main/java/com/google/protobuf/RopeByteString.java                 \
+  java/src/main/java/com/google/protobuf/RpcCallback.java                    \
+  java/src/main/java/com/google/protobuf/RpcChannel.java                     \
+  java/src/main/java/com/google/protobuf/RpcController.java                  \
+  java/src/main/java/com/google/protobuf/RpcUtil.java                        \
+  java/src/main/java/com/google/protobuf/ServiceException.java               \
+  java/src/main/java/com/google/protobuf/Service.java                        \
+  java/src/main/java/com/google/protobuf/SingleFieldBuilder.java             \
+  java/src/main/java/com/google/protobuf/SmallSortedMap.java                 \
+  java/src/main/java/com/google/protobuf/TextFormat.java                     \
+  java/src/main/java/com/google/protobuf/UninitializedMessageException.java  \
+  java/src/main/java/com/google/protobuf/UnknownFieldSet.java                \
+  java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java     \
+  java/src/main/java/com/google/protobuf/Utf8.java                           \
+  java/src/main/java/com/google/protobuf/WireFormat.java                     \
+  java/src/test/java/com/google/protobuf/AbstractMessageTest.java            \
+  java/src/test/java/com/google/protobuf/BoundedByteStringTest.java          \
+  java/src/test/java/com/google/protobuf/ByteStringTest.java                 \
+  java/src/test/java/com/google/protobuf/CheckUtf8Test.java                  \
+  java/src/test/java/com/google/protobuf/CodedInputStreamTest.java           \
+  java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java          \
+  java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java            \
+  java/src/test/java/com/google/protobuf/DescriptorsTest.java                \
+  java/src/test/java/com/google/protobuf/DynamicMessageTest.java             \
+  java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java       \
+  java/src/test/java/com/google/protobuf/GeneratedMessageTest.java           \
+  java/src/test/java/com/google/protobuf/IsValidUtf8Test.java                \
+  java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java            \
+  java/src/test/java/com/google/protobuf/LazyFieldTest.java                  \
+  java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java              \
+  java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java            \
+  java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java        \
+  java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java         \
+  java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java          \
+  java/src/test/java/com/google/protobuf/LiteralByteStringTest.java          \
+  java/src/test/java/com/google/protobuf/LiteTest.java                       \
+  java/src/test/java/com/google/protobuf/MessageTest.java                    \
+  java/src/test/java/com/google/protobuf/NestedBuildersTest.java             \
+  java/src/test/java/com/google/protobuf/ParserTest.java                     \
+  java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java       \
+  java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java    \
+  java/src/test/java/com/google/protobuf/RopeByteStringTest.java             \
+  java/src/test/java/com/google/protobuf/ServiceTest.java                    \
+  java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java         \
+  java/src/test/java/com/google/protobuf/SmallSortedMapTest.java             \
+  java/src/test/java/com/google/protobuf/TestBadIdentifiers.java             \
+  java/src/test/java/com/google/protobuf/TestUtil.java                       \
+  java/src/test/java/com/google/protobuf/TextFormatTest.java                 \
+  java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java            \
+  java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \
+  java/src/test/java/com/google/protobuf/WireFormatTest.java                 \
+  java/src/test/java/com/google/protobuf/lazy_fields_lite.proto              \
+  java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto          \
+  java/src/test/java/com/google/protobuf/multiple_files_test.proto           \
+  java/src/test/java/com/google/protobuf/nested_builders_test.proto          \
+  java/src/test/java/com/google/protobuf/nested_extension_lite.proto         \
+  java/src/test/java/com/google/protobuf/nested_extension.proto              \
+  java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto     \
+  java/src/test/java/com/google/protobuf/non_nested_extension.proto          \
+  java/src/test/java/com/google/protobuf/outer_class_name_test.proto         \
+  java/src/test/java/com/google/protobuf/outer_class_name_test2.proto        \
+  java/src/test/java/com/google/protobuf/outer_class_name_test3.proto        \
+  java/src/test/java/com/google/protobuf/test_bad_identifiers.proto          \
+  java/src/test/java/com/google/protobuf/test_check_utf8.proto               \
+  java/src/test/java/com/google/protobuf/test_check_utf8_size.proto          \
+  java/src/test/java/com/google/protobuf/test_custom_options.proto           \
+  java/pom.xml                                                               \
+  java/README.txt                                                            \
+  python/google/protobuf/internal/api_implementation.cc                      \
+  python/google/protobuf/internal/api_implementation.py                      \
+  python/google/protobuf/internal/api_implementation_default_test.py         \
+  python/google/protobuf/internal/containers.py                              \
+  python/google/protobuf/internal/cpp_message.py                             \
+  python/google/protobuf/internal/decoder.py                                 \
+  python/google/protobuf/internal/descriptor_database_test.py                \
+  python/google/protobuf/internal/descriptor_pool_test.py                    \
+  python/google/protobuf/internal/descriptor_pool_test1.proto                \
+  python/google/protobuf/internal/descriptor_pool_test2.proto                \
+  python/google/protobuf/internal/descriptor_python_test.py                  \
+  python/google/protobuf/internal/descriptor_test.py                         \
+  python/google/protobuf/internal/encoder.py                                 \
+  python/google/protobuf/internal/enum_type_wrapper.py                       \
+  python/google/protobuf/internal/factory_test1.proto                        \
+  python/google/protobuf/internal/factory_test2.proto                        \
+  python/google/protobuf/internal/generator_test.py                          \
+  python/google/protobuf/internal/message_factory_python_test.py             \
+  python/google/protobuf/internal/message_factory_test.py                    \
+  python/google/protobuf/internal/message_listener.py                        \
+  python/google/protobuf/internal/message_python_test.py                     \
+  python/google/protobuf/internal/message_test.py                            \
+  python/google/protobuf/internal/missing_enum_values.proto                  \
+  python/google/protobuf/internal/more_extensions.proto                      \
+  python/google/protobuf/internal/more_extensions_dynamic.proto              \
+  python/google/protobuf/internal/more_messages.proto                        \
+  python/google/protobuf/internal/python_message.py                          \
+  python/google/protobuf/internal/reflection_test.py                         \
+  python/google/protobuf/internal/service_reflection_test.py                 \
+  python/google/protobuf/internal/symbol_database_test.py                    \
+  python/google/protobuf/internal/test_bad_identifiers.proto                 \
+  python/google/protobuf/internal/test_util.py                               \
+  python/google/protobuf/internal/text_encoding_test.py                      \
+  python/google/protobuf/internal/text_format_test.py                        \
+  python/google/protobuf/internal/type_checkers.py                           \
+  python/google/protobuf/internal/unknown_fields_test.py                     \
+  python/google/protobuf/internal/wire_format.py                             \
+  python/google/protobuf/internal/wire_format_test.py                        \
+  python/google/protobuf/internal/__init__.py                                \
+  python/google/protobuf/pyext/README                                        \
+  python/google/protobuf/pyext/cpp_message.py                                \
+  python/google/protobuf/pyext/descriptor.h                                  \
+  python/google/protobuf/pyext/descriptor.cc                                 \
+  python/google/protobuf/pyext/descriptor_cpp2_test.py                       \
+  python/google/protobuf/pyext/extension_dict.h                              \
+  python/google/protobuf/pyext/extension_dict.cc                             \
+  python/google/protobuf/pyext/message.h                                     \
+  python/google/protobuf/pyext/message.cc                                    \
+  python/google/protobuf/pyext/message_factory_cpp2_test.py                  \
+  python/google/protobuf/pyext/proto2_api_test.proto                         \
+  python/google/protobuf/pyext/python.proto                                  \
+  python/google/protobuf/pyext/python_protobuf.h                             \
+  python/google/protobuf/pyext/reflection_cpp2_generated_test.py             \
+  python/google/protobuf/pyext/repeated_composite_container.h                \
+  python/google/protobuf/pyext/repeated_composite_container.cc               \
+  python/google/protobuf/pyext/repeated_scalar_container.h                   \
+  python/google/protobuf/pyext/repeated_scalar_container.cc                  \
+  python/google/protobuf/pyext/scoped_pyobject_ptr.h                         \
+  python/google/protobuf/pyext/__init__.py                                   \
+  python/google/protobuf/descriptor.py                                       \
+  python/google/protobuf/descriptor_database.py                              \
+  python/google/protobuf/descriptor_pool.py                                  \
+  python/google/protobuf/message.py                                          \
+  python/google/protobuf/message_factory.py                                  \
+  python/google/protobuf/reflection.py                                       \
+  python/google/protobuf/service.py                                          \
+  python/google/protobuf/service_reflection.py                               \
+  python/google/protobuf/symbol_database.py                                  \
+  python/google/protobuf/text_encoding.py                                    \
+  python/google/protobuf/text_format.py                                      \
+  python/google/protobuf/__init__.py                                         \
+  python/google/__init__.py                                                  \
+  python/ez_setup.py                                                         \
+  python/setup.py                                                            \
+  python/mox.py                                                              \
+  python/stubout.py                                                          \
+  python/README.txt
+
+# Deletes all the files generated by autogen.sh.
+MAINTAINERCLEANFILES =   \
+  aclocal.m4             \
+  config.guess           \
+  config.sub             \
+  configure              \
+  depcomp                \
+  install-sh             \
+  ltmain.sh              \
+  Makefile.in            \
+  missing                \
+  mkinstalldirs          \
+  config.h.in            \
+  stamp.h.in             \
+  m4/ltsugar.m4          \
+  m4/libtool.m4          \
+  m4/ltversion.m4        \
+  m4/lt~obsolete.m4      \
+  m4/ltoptions.m4
diff --git a/protobuf/Makefile.in b/protobuf/Makefile.in
new file mode 100644
index 0000000..93d7a44
--- /dev/null
+++ b/protobuf/Makefile.in
@@ -0,0 +1,1141 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = .
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(srcdir)/config.h.in $(srcdir)/protobuf.pc.in \
+	$(srcdir)/protobuf-lite.pc.in compile config.guess config.sub \
+	depcomp install-sh missing ltmain.sh
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_system_extensions.m4 \
+	$(top_srcdir)/m4/acx_check_suncc.m4 \
+	$(top_srcdir)/m4/acx_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/stl_hash.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = protobuf.pc protobuf-lite.pc
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
+DATA = $(pkgconfig_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISAINFO = @ISAINFO@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POW_LIB = @POW_LIB@
+PROTOBUF_OPT_FLAG = @PROTOBUF_OPT_FLAG@
+PROTOC = @PROTOC@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+acx_pthread_config = @acx_pthread_config@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I m4
+AUTOMAKE_OPTIONS = foreign
+
+# Build . before src so that our all-local and clean-local hooks kicks in at
+# the right time.
+SUBDIRS = . src
+
+# Always include gtest in distributions.
+DIST_SUBDIRS = $(subdirs) src
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = protobuf.pc protobuf-lite.pc
+EXTRA_DIST = \
+  autogen.sh                                                                 \
+  generate_descriptor_proto.sh                                               \
+  README.md                                                                  \
+  INSTALL.txt                                                                \
+  LICENSE                                                                    \
+  CONTRIBUTORS.txt                                                           \
+  CHANGES.txt                                                                \
+  editors/README.txt                                                         \
+  editors/proto.vim                                                          \
+  editors/protobuf-mode.el                                                   \
+  vsprojects/config.h                                                        \
+  vsprojects/extract_includes.bat                                            \
+  vsprojects/libprotobuf.vcproj                                              \
+  vsprojects/libprotobuf-lite.vcproj                                         \
+  vsprojects/libprotoc.vcproj                                                \
+  vsprojects/protobuf.sln                                                    \
+  vsprojects/protoc.vcproj                                                   \
+  vsprojects/readme.txt                                                      \
+  vsprojects/test_plugin.vcproj                                              \
+  vsprojects/tests.vcproj                                                    \
+  vsprojects/lite-test.vcproj                                                \
+  vsprojects/convert2008to2005.sh                                            \
+  examples/README.txt                                                        \
+  examples/Makefile                                                          \
+  examples/addressbook.proto                                                 \
+  examples/add_person.cc                                                     \
+  examples/list_people.cc                                                    \
+  examples/AddPerson.java                                                    \
+  examples/ListPeople.java                                                   \
+  examples/add_person.py                                                     \
+  examples/list_people.py                                                    \
+  java/src/main/java/com/google/protobuf/AbstractMessage.java                \
+  java/src/main/java/com/google/protobuf/AbstractMessageLite.java            \
+  java/src/main/java/com/google/protobuf/AbstractParser.java                 \
+  java/src/main/java/com/google/protobuf/BlockingRpcChannel.java             \
+  java/src/main/java/com/google/protobuf/BlockingService.java                \
+  java/src/main/java/com/google/protobuf/BoundedByteString.java              \
+  java/src/main/java/com/google/protobuf/ByteString.java                     \
+  java/src/main/java/com/google/protobuf/CodedInputStream.java               \
+  java/src/main/java/com/google/protobuf/CodedOutputStream.java              \
+  java/src/main/java/com/google/protobuf/Descriptors.java                    \
+  java/src/main/java/com/google/protobuf/DynamicMessage.java                 \
+  java/src/main/java/com/google/protobuf/Extension.java                      \
+  java/src/main/java/com/google/protobuf/ExtensionRegistry.java              \
+  java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java          \
+  java/src/main/java/com/google/protobuf/FieldSet.java                       \
+  java/src/main/java/com/google/protobuf/GeneratedMessage.java               \
+  java/src/main/java/com/google/protobuf/GeneratedMessageLite.java           \
+  java/src/main/java/com/google/protobuf/Internal.java                       \
+  java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \
+  java/src/main/java/com/google/protobuf/LazyField.java                      \
+  java/src/main/java/com/google/protobuf/LazyFieldLite.java                  \
+  java/src/main/java/com/google/protobuf/LazyStringArrayList.java            \
+  java/src/main/java/com/google/protobuf/LazyStringList.java                 \
+  java/src/main/java/com/google/protobuf/LiteralByteString.java              \
+  java/src/main/java/com/google/protobuf/Message.java                        \
+  java/src/main/java/com/google/protobuf/MessageLite.java                    \
+  java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java           \
+  java/src/main/java/com/google/protobuf/MessageOrBuilder.java               \
+  java/src/main/java/com/google/protobuf/MessageReflection.java              \
+  java/src/main/java/com/google/protobuf/Parser.java                         \
+  java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java            \
+  java/src/main/java/com/google/protobuf/ProtocolStringList.java             \
+  java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java           \
+  java/src/main/java/com/google/protobuf/RopeByteString.java                 \
+  java/src/main/java/com/google/protobuf/RpcCallback.java                    \
+  java/src/main/java/com/google/protobuf/RpcChannel.java                     \
+  java/src/main/java/com/google/protobuf/RpcController.java                  \
+  java/src/main/java/com/google/protobuf/RpcUtil.java                        \
+  java/src/main/java/com/google/protobuf/ServiceException.java               \
+  java/src/main/java/com/google/protobuf/Service.java                        \
+  java/src/main/java/com/google/protobuf/SingleFieldBuilder.java             \
+  java/src/main/java/com/google/protobuf/SmallSortedMap.java                 \
+  java/src/main/java/com/google/protobuf/TextFormat.java                     \
+  java/src/main/java/com/google/protobuf/UninitializedMessageException.java  \
+  java/src/main/java/com/google/protobuf/UnknownFieldSet.java                \
+  java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java     \
+  java/src/main/java/com/google/protobuf/Utf8.java                           \
+  java/src/main/java/com/google/protobuf/WireFormat.java                     \
+  java/src/test/java/com/google/protobuf/AbstractMessageTest.java            \
+  java/src/test/java/com/google/protobuf/BoundedByteStringTest.java          \
+  java/src/test/java/com/google/protobuf/ByteStringTest.java                 \
+  java/src/test/java/com/google/protobuf/CheckUtf8Test.java                  \
+  java/src/test/java/com/google/protobuf/CodedInputStreamTest.java           \
+  java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java          \
+  java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java            \
+  java/src/test/java/com/google/protobuf/DescriptorsTest.java                \
+  java/src/test/java/com/google/protobuf/DynamicMessageTest.java             \
+  java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java       \
+  java/src/test/java/com/google/protobuf/GeneratedMessageTest.java           \
+  java/src/test/java/com/google/protobuf/IsValidUtf8Test.java                \
+  java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java            \
+  java/src/test/java/com/google/protobuf/LazyFieldTest.java                  \
+  java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java              \
+  java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java            \
+  java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java        \
+  java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java         \
+  java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java          \
+  java/src/test/java/com/google/protobuf/LiteralByteStringTest.java          \
+  java/src/test/java/com/google/protobuf/LiteTest.java                       \
+  java/src/test/java/com/google/protobuf/MessageTest.java                    \
+  java/src/test/java/com/google/protobuf/NestedBuildersTest.java             \
+  java/src/test/java/com/google/protobuf/ParserTest.java                     \
+  java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java       \
+  java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java    \
+  java/src/test/java/com/google/protobuf/RopeByteStringTest.java             \
+  java/src/test/java/com/google/protobuf/ServiceTest.java                    \
+  java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java         \
+  java/src/test/java/com/google/protobuf/SmallSortedMapTest.java             \
+  java/src/test/java/com/google/protobuf/TestBadIdentifiers.java             \
+  java/src/test/java/com/google/protobuf/TestUtil.java                       \
+  java/src/test/java/com/google/protobuf/TextFormatTest.java                 \
+  java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java            \
+  java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \
+  java/src/test/java/com/google/protobuf/WireFormatTest.java                 \
+  java/src/test/java/com/google/protobuf/lazy_fields_lite.proto              \
+  java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto          \
+  java/src/test/java/com/google/protobuf/multiple_files_test.proto           \
+  java/src/test/java/com/google/protobuf/nested_builders_test.proto          \
+  java/src/test/java/com/google/protobuf/nested_extension_lite.proto         \
+  java/src/test/java/com/google/protobuf/nested_extension.proto              \
+  java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto     \
+  java/src/test/java/com/google/protobuf/non_nested_extension.proto          \
+  java/src/test/java/com/google/protobuf/outer_class_name_test.proto         \
+  java/src/test/java/com/google/protobuf/outer_class_name_test2.proto        \
+  java/src/test/java/com/google/protobuf/outer_class_name_test3.proto        \
+  java/src/test/java/com/google/protobuf/test_bad_identifiers.proto          \
+  java/src/test/java/com/google/protobuf/test_check_utf8.proto               \
+  java/src/test/java/com/google/protobuf/test_check_utf8_size.proto          \
+  java/src/test/java/com/google/protobuf/test_custom_options.proto           \
+  java/pom.xml                                                               \
+  java/README.txt                                                            \
+  python/google/protobuf/internal/api_implementation.cc                      \
+  python/google/protobuf/internal/api_implementation.py                      \
+  python/google/protobuf/internal/api_implementation_default_test.py         \
+  python/google/protobuf/internal/containers.py                              \
+  python/google/protobuf/internal/cpp_message.py                             \
+  python/google/protobuf/internal/decoder.py                                 \
+  python/google/protobuf/internal/descriptor_database_test.py                \
+  python/google/protobuf/internal/descriptor_pool_test.py                    \
+  python/google/protobuf/internal/descriptor_pool_test1.proto                \
+  python/google/protobuf/internal/descriptor_pool_test2.proto                \
+  python/google/protobuf/internal/descriptor_python_test.py                  \
+  python/google/protobuf/internal/descriptor_test.py                         \
+  python/google/protobuf/internal/encoder.py                                 \
+  python/google/protobuf/internal/enum_type_wrapper.py                       \
+  python/google/protobuf/internal/factory_test1.proto                        \
+  python/google/protobuf/internal/factory_test2.proto                        \
+  python/google/protobuf/internal/generator_test.py                          \
+  python/google/protobuf/internal/message_factory_python_test.py             \
+  python/google/protobuf/internal/message_factory_test.py                    \
+  python/google/protobuf/internal/message_listener.py                        \
+  python/google/protobuf/internal/message_python_test.py                     \
+  python/google/protobuf/internal/message_test.py                            \
+  python/google/protobuf/internal/missing_enum_values.proto                  \
+  python/google/protobuf/internal/more_extensions.proto                      \
+  python/google/protobuf/internal/more_extensions_dynamic.proto              \
+  python/google/protobuf/internal/more_messages.proto                        \
+  python/google/protobuf/internal/python_message.py                          \
+  python/google/protobuf/internal/reflection_test.py                         \
+  python/google/protobuf/internal/service_reflection_test.py                 \
+  python/google/protobuf/internal/symbol_database_test.py                    \
+  python/google/protobuf/internal/test_bad_identifiers.proto                 \
+  python/google/protobuf/internal/test_util.py                               \
+  python/google/protobuf/internal/text_encoding_test.py                      \
+  python/google/protobuf/internal/text_format_test.py                        \
+  python/google/protobuf/internal/type_checkers.py                           \
+  python/google/protobuf/internal/unknown_fields_test.py                     \
+  python/google/protobuf/internal/wire_format.py                             \
+  python/google/protobuf/internal/wire_format_test.py                        \
+  python/google/protobuf/internal/__init__.py                                \
+  python/google/protobuf/pyext/README                                        \
+  python/google/protobuf/pyext/cpp_message.py                                \
+  python/google/protobuf/pyext/descriptor.h                                  \
+  python/google/protobuf/pyext/descriptor.cc                                 \
+  python/google/protobuf/pyext/descriptor_cpp2_test.py                       \
+  python/google/protobuf/pyext/extension_dict.h                              \
+  python/google/protobuf/pyext/extension_dict.cc                             \
+  python/google/protobuf/pyext/message.h                                     \
+  python/google/protobuf/pyext/message.cc                                    \
+  python/google/protobuf/pyext/message_factory_cpp2_test.py                  \
+  python/google/protobuf/pyext/proto2_api_test.proto                         \
+  python/google/protobuf/pyext/python.proto                                  \
+  python/google/protobuf/pyext/python_protobuf.h                             \
+  python/google/protobuf/pyext/reflection_cpp2_generated_test.py             \
+  python/google/protobuf/pyext/repeated_composite_container.h                \
+  python/google/protobuf/pyext/repeated_composite_container.cc               \
+  python/google/protobuf/pyext/repeated_scalar_container.h                   \
+  python/google/protobuf/pyext/repeated_scalar_container.cc                  \
+  python/google/protobuf/pyext/scoped_pyobject_ptr.h                         \
+  python/google/protobuf/pyext/__init__.py                                   \
+  python/google/protobuf/descriptor.py                                       \
+  python/google/protobuf/descriptor_database.py                              \
+  python/google/protobuf/descriptor_pool.py                                  \
+  python/google/protobuf/message.py                                          \
+  python/google/protobuf/message_factory.py                                  \
+  python/google/protobuf/reflection.py                                       \
+  python/google/protobuf/service.py                                          \
+  python/google/protobuf/service_reflection.py                               \
+  python/google/protobuf/symbol_database.py                                  \
+  python/google/protobuf/text_encoding.py                                    \
+  python/google/protobuf/text_format.py                                      \
+  python/google/protobuf/__init__.py                                         \
+  python/google/__init__.py                                                  \
+  python/ez_setup.py                                                         \
+  python/setup.py                                                            \
+  python/mox.py                                                              \
+  python/stubout.py                                                          \
+  python/README.txt
+
+
+# Deletes all the files generated by autogen.sh.
+MAINTAINERCLEANFILES = \
+  aclocal.m4             \
+  config.guess           \
+  config.sub             \
+  configure              \
+  depcomp                \
+  install-sh             \
+  ltmain.sh              \
+  Makefile.in            \
+  missing                \
+  mkinstalldirs          \
+  config.h.in            \
+  stamp.h.in             \
+  m4/ltsugar.m4          \
+  m4/libtool.m4          \
+  m4/ltversion.m4        \
+  m4/lt~obsolete.m4      \
+  m4/ltoptions.m4
+
+all: config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+	@:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+	@test -f $@ || rm -f stamp-h1
+	@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
+	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f config.h stamp-h1
+protobuf.pc: $(top_builddir)/config.status $(srcdir)/protobuf.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+protobuf-lite.pc: $(top_builddir)/config.status $(srcdir)/protobuf-lite.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+	done
+
+uninstall-pkgconfigDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__post_remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	    --srcdir=.. --prefix="$$dc_install_base" \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__post_remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-recursive
+all-am: Makefile $(DATA) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+	distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-pkgconfigDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-pkgconfigDATA
+
+.MAKE: $(am__recursive_targets) all check-am install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+	am--refresh check check-am check-local clean clean-cscope \
+	clean-generic clean-libtool clean-local cscope cscopelist-am \
+	ctags ctags-am dist dist-all dist-bzip2 dist-gzip dist-lzip \
+	dist-shar dist-tarZ dist-xz dist-zip distcheck distclean \
+	distclean-generic distclean-hdr distclean-libtool \
+	distclean-tags distcleancheck distdir distuninstallcheck dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-pkgconfigDATA
+
+
+# Build gtest before we build protobuf tests.  We don't add gtest to SUBDIRS
+# because then "make check" would also build and run all of gtest's own tests,
+# which takes a lot of time and is generally not useful to us.  Also, we don't
+# want "make install" to recurse into gtest since we don't want to overwrite
+# the installed version of gtest if there is one.
+check-local:
+	@echo "Making lib/libgtest.a lib/libgtest_main.a in gtest"
+	@cd gtest && $(MAKE) $(AM_MAKEFLAGS) lib/libgtest.la lib/libgtest_main.la
+
+# We would like to clean gtest when "make clean" is invoked.  But we have to
+# be careful because clean-local is also invoked during "make distclean", but
+# "make distclean" already recurses into gtest because it's listed among the
+# DIST_SUBDIRS.  distclean will delete gtest/Makefile, so if we then try to
+# cd to the directory again and "make clean" it will fail.  So, check that the
+# Makefile exists before recursing.
+clean-local:
+	@if test -e gtest/Makefile; then \
+	  echo "Making clean in gtest"; \
+	  cd gtest && $(MAKE) $(AM_MAKEFLAGS) clean; \
+	fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/protobuf/NOTICE b/protobuf/NOTICE
new file mode 100644
index 0000000..705db57
--- /dev/null
+++ b/protobuf/NOTICE
@@ -0,0 +1,33 @@
+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.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it.  This code is not
+standalone and requires a support library to be linked with it.  This
+support library is itself covered by the above license.
diff --git a/protobuf/README.android b/protobuf/README.android
new file mode 100644
index 0000000..2a19787
--- /dev/null
+++ b/protobuf/README.android
@@ -0,0 +1,26 @@
+URL: http://code.google.com/p/protobuf/downloads/list
+Version: 2.2.0a
+License: Google BSD like
+Description: "Protobuf: The Google protobuf compiler and runtimes for various languages"
+
+Local Modifications: Initial changes include support for the micro
+protobuf compiler and the assoicated runtime.
+
+Protocol Buffers are a way of encoding structured data in an efficient
+yet extensible format. Google uses Protocol Buffers for almost all
+of its internal RPC protocols and file formats.
+
+Initially the protoc compiler is not integrated into the Android build system
+and the Android.mk will simply build the javamicro runtime static library.
+
+To build the compiler follow the instructions in README.txt for
+compiling and installing.
+
+The Android.mk file creates the a static library which can be added
+to any Android application by Adding to LOCAL_STATIC_JAVA_LIBRARIES
+com.google.protobuf.micro:
+
+  LOCAL_STATIC_JAVA_LIBRARIES += com.google.protobuf.micro
+
+Follow the instructions in Micro section of java/README.txt for
+details on compiling .proto files for the micro runtine.
diff --git a/protobuf/README.md b/protobuf/README.md
new file mode 100644
index 0000000..5fbb344
--- /dev/null
+++ b/protobuf/README.md
@@ -0,0 +1,167 @@
+Protocol Buffers - Google's data interchange format
+===================================================
+
+Copyright 2008 Google Inc.
+
+https://developers.google.com/protocol-buffers/
+
+C++ Installation - Unix
+-----------------------
+
+If you get the source from github, you need to generate the configure script
+first:
+
+    $ ./autogen.sh
+
+This will download gtest source (which is used for C++ Protocol Buffer
+unit-tests) to the current directory and run automake, autoconf, etc.
+to generate the configure script and various template makefiles.
+
+You can skip this step if you are using a release package (which already
+contains gtest and the configure script).
+
+To build and install the C++ Protocol Buffer runtime and the Protocol
+Buffer compiler (protoc) execute the following:
+
+    $ ./configure
+    $ make
+    $ make check
+    $ make install
+
+If "make check" fails, you can still install, but it is likely that
+some features of this library will not work correctly on your system.
+Proceed at your own risk.
+
+"make install" may require superuser privileges.
+
+For advanced usage information on configure and make, see INSTALL.txt.
+
+**Hint on install location**
+
+  By default, the package will be installed to /usr/local.  However,
+  on many platforms, /usr/local/lib is not part of LD_LIBRARY_PATH.
+  You can add it, but it may be easier to just install to /usr
+  instead.  To do this, invoke configure as follows:
+
+    ./configure --prefix=/usr
+
+  If you already built the package with a different prefix, make sure
+  to run "make clean" before building again.
+
+**Compiling dependent packages**
+
+  To compile a package that uses Protocol Buffers, you need to pass
+  various flags to your compiler and linker.  As of version 2.2.0,
+  Protocol Buffers integrates with pkg-config to manage this.  If you
+  have pkg-config installed, then you can invoke it to get a list of
+  flags like so:
+
+    pkg-config --cflags protobuf         # print compiler flags
+    pkg-config --libs protobuf           # print linker flags
+    pkg-config --cflags --libs protobuf  # print both
+
+  For example:
+
+    c++ my_program.cc my_proto.pb.cc `pkg-config --cflags --libs protobuf`
+
+  Note that packages written prior to the 2.2.0 release of Protocol
+  Buffers may not yet integrate with pkg-config to get flags, and may
+  not pass the correct set of flags to correctly link against
+  libprotobuf.  If the package in question uses autoconf, you can
+  often fix the problem by invoking its configure script like:
+
+    configure CXXFLAGS="$(pkg-config --cflags protobuf)" \
+              LIBS="$(pkg-config --libs protobuf)"
+
+  This will force it to use the correct flags.
+
+  If you are writing an autoconf-based package that uses Protocol
+  Buffers, you should probably use the PKG_CHECK_MODULES macro in your
+  configure script like:
+
+    PKG_CHECK_MODULES([protobuf], [protobuf])
+
+  See the pkg-config man page for more info.
+
+  If you only want protobuf-lite, substitute "protobuf-lite" in place
+  of "protobuf" in these examples.
+
+**Note for cross-compiling**
+
+  The makefiles normally invoke the protoc executable that they just
+  built in order to build tests.  When cross-compiling, the protoc
+  executable may not be executable on the host machine.  In this case,
+  you must build a copy of protoc for the host machine first, then use
+  the --with-protoc option to tell configure to use it instead.  For
+  example:
+
+    ./configure --with-protoc=protoc
+
+  This will use the installed protoc (found in your $PATH) instead of
+  trying to execute the one built during the build process.  You can
+  also use an executable that hasn't been installed.  For example, if
+  you built the protobuf package for your host machine in ../host,
+  you might do:
+
+    ./configure --with-protoc=../host/src/protoc
+
+  Either way, you must make sure that the protoc executable you use
+  has the same version as the protobuf source code you are trying to
+  use it with.
+
+**Note for Solaris users**
+
+  Solaris 10 x86 has a bug that will make linking fail, complaining
+  about libstdc++.la being invalid.  We have included a work-around
+  in this package.  To use the work-around, run configure as follows:
+
+    ./configure LDFLAGS=-L$PWD/src/solaris
+
+  See src/solaris/libstdc++.la for more info on this bug.
+
+**Note for HP C++ Tru64 users**
+
+  To compile invoke configure as follows:
+
+    ./configure CXXFLAGS="-O -std ansi -ieee -D__USE_STD_IOSTREAM"
+
+  Also, you will need to use gmake instead of make.
+
+C++ Installation - Windows
+--------------------------
+
+If you are using Microsoft Visual C++, see vsprojects/readme.txt.
+
+If you are using Cygwin or MinGW, follow the Unix installation
+instructions, above.
+
+Binary Compatibility Warning
+----------------------------
+
+Due to the nature of C++, it is unlikely that any two versions of the
+Protocol Buffers C++ runtime libraries will have compatible ABIs.
+That is, if you linked an executable against an older version of
+libprotobuf, it is unlikely to work with a newer version without
+re-compiling.  This problem, when it occurs, will normally be detected
+immediately on startup of your app.  Still, you may want to consider
+using static linkage.  You can configure this package to install
+static libraries only using:
+
+    ./configure --disable-shared
+
+Java and Python Installation
+----------------------------
+
+The Java and Python runtime libraries for Protocol Buffers are located
+in the java and python directories.  See the README file in each
+directory for more information on how to compile and install them.
+Note that both of them require you to first install the Protocol
+Buffer compiler (protoc), which is part of the C++ package.
+
+Usage
+-----
+
+The complete documentation for Protocol Buffers is available via the
+web at:
+
+    https://developers.google.com/protocol-buffers/
diff --git a/protobuf/README.version b/protobuf/README.version
new file mode 100644
index 0000000..e92bd5d
--- /dev/null
+++ b/protobuf/README.version
@@ -0,0 +1,3 @@
+URL: https://protobuf.googlecode.com/svn/rc/protobuf-2.6.0.tar.gz
+Version: 2.6.0
+BugComponent: 99142
diff --git a/protobuf/aclocal.m4 b/protobuf/aclocal.m4
new file mode 100644
index 0000000..bb4cc70
--- /dev/null
+++ b/protobuf/aclocal.m4
@@ -0,0 +1,1194 @@
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.14'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.14.1], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'.  In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+      [$1], [UPC],  [depcc="$UPC"  am_compiler_list=],
+      [$1], [GCJ],  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                    [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+  m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES([CC])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+  fi
+fi])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless 'enable' is passed literally.
+# For symmetry, 'disable' may be passed as well.  Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+       [enable], [m4_define([am_maintainer_other], [disable])],
+       [disable], [m4_define([am_maintainer_other], [enable])],
+       [m4_define([am_maintainer_other], [enable])
+        m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+  AC_ARG_ENABLE([maintainer-mode],
+    [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
+      am_maintainer_other[ make rules and dependencies not useful
+      (and sometimes confusing) to the casual installer])],
+    [USE_MAINTAINER_MODE=$enableval],
+    [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+  AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+  AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST([MAINT])dnl
+]
+)
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$[*]" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$[*]" != "X $srcdir/configure conftest.file" \
+	&& test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment])
+     fi
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  for _am_tool in $_am_tools; do
+    case $_am_tool in
+    gnutar)
+      for _am_tar in tar gnutar gtar; do
+        AM_RUN_LOG([$_am_tar --version]) && break
+      done
+      am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+      am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+      am__untar="$_am_tar -xf -"
+      ;;
+    plaintar)
+      # Must skip GNU tar: if it does not support --format= it doesn't create
+      # ustar tarball either.
+      (tar --version) >/dev/null 2>&1 && continue
+      am__tar='tar chf - "$$tardir"'
+      am__tar_='tar chf - "$tardir"'
+      am__untar='tar xf -'
+      ;;
+    pax)
+      am__tar='pax -L -x $1 -w "$$tardir"'
+      am__tar_='pax -L -x $1 -w "$tardir"'
+      am__untar='pax -r'
+      ;;
+    cpio)
+      am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+      am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+      am__untar='cpio -i -H $1 -d'
+      ;;
+    none)
+      am__tar=false
+      am__tar_=false
+      am__untar=false
+      ;;
+    esac
+
+    # If the value was cached, stop now.  We just wanted to have am__tar
+    # and am__untar set.
+    test -n "${am_cv_prog_tar_$1}" && break
+
+    # tar/untar a dummy directory, and stop if the command works.
+    rm -rf conftest.dir
+    mkdir conftest.dir
+    echo GrepMe > conftest.dir/file
+    AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+    rm -rf conftest.dir
+    if test -s conftest.tar; then
+      AM_RUN_LOG([$am__untar <conftest.tar])
+      AM_RUN_LOG([cat conftest.dir/file])
+      grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+    fi
+  done
+  rm -rf conftest.dir
+
+  AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+  AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/ac_system_extensions.m4])
+m4_include([m4/acx_check_suncc.m4])
+m4_include([m4/acx_pthread.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/stl_hash.m4])
diff --git a/protobuf/android/config.h b/protobuf/android/config.h
new file mode 100644
index 0000000..2cbd548
--- /dev/null
+++ b/protobuf/android/config.h
@@ -0,0 +1,163 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* the name of <hash_set> */
+#define HASH_MAP_CLASS unordered_map
+
+/* the location of <hash_map> */
+#define HASH_MAP_H <tr1/unordered_map>
+
+/* the namespace of hash_map/hash_set */
+#define HASH_NAMESPACE std::tr1
+
+/* the name of <hash_set> */
+#define HASH_SET_CLASS unordered_set
+
+/* the location of <hash_set> */
+#define HASH_SET_H <tr1/unordered_set>
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+#if defined(ANDROID)
+/*
+ * TODO: Figure out how to use stlport unordered_map and set.
+ * For some reason they don't work when I try to point the
+ * HASH_MAP_H and HASH_SET_H to the stlport files, I get
+ * compile timer errors.
+ */
+
+/* define if the compiler has hash_map */
+#undef HAVE_HASH_MAP
+
+/* define if the compiler has hash_set */
+#undef HAVE_HASH_SET
+#else
+/* define if the compiler has hash_map */
+#define HAVE_HASH_MAP 1
+
+/* define if the compiler has hash_set */
+#define HAVE_HASH_SET 1
+#endif
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `memset' function. */
+#define HAVE_MEMSET 1
+
+/* Define to 1 if you have the `mkdir' function. */
+#define HAVE_MKDIR 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strchr' function. */
+#define HAVE_STRCHR 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strtol' function. */
+#define HAVE_STRTOL 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Enable classes using zlib compression. */
+#define HAVE_ZLIB 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "protobuf"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "protobuf@googlegroups.com"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "Protocol Buffers"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "Protocol Buffers 2.3.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "protobuf"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.3.0"
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "2.3.0"
+
+/* Define to 1 if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+/* # undef _ALL_SOURCE */
+#endif
+
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
+
+/* Enable extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
diff --git a/protobuf/autogen.sh b/protobuf/autogen.sh
new file mode 100755
index 0000000..c3e026d
--- /dev/null
+++ b/protobuf/autogen.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+# Run this script to generate the configure script and other files that will
+# be included in the distribution.  These files are not checked in because they
+# are automatically generated.
+
+set -e
+
+# Check that we're being run from the right directory.
+if test ! -f src/google/protobuf/stubs/common.h; then
+  cat >&2 << __EOF__
+Could not find source code.  Make sure you are running this script from the
+root of the distribution tree.
+__EOF__
+  exit 1
+fi
+
+# Check that gtest is present.  Usually it is already there since the
+# directory is set up as an SVN external.
+if test ! -e gtest; then
+  echo "Google Test not present.  Fetching gtest-1.5.0 from the web..."
+  curl http://googletest.googlecode.com/files/gtest-1.5.0.tar.bz2 | tar jx
+  mv gtest-1.5.0 gtest
+fi
+
+set -ex
+
+# Temporary hack:  Must change C runtime library to "multi-threaded DLL",
+#   otherwise it will be set to "multi-threaded static" when MSVC upgrades
+#   the project file to MSVC 2005/2008.  vladl of Google Test says gtest will
+#   probably change their default to match, then this will be unnecessary.
+#   One of these mappings converts the debug configuration and the other
+#   converts the release configuration.  I don't know which is which.
+sed -i -e 's/RuntimeLibrary="5"/RuntimeLibrary="3"/g;
+           s/RuntimeLibrary="4"/RuntimeLibrary="2"/g;' gtest/msvc/*.vcproj
+
+# TODO(kenton):  Remove the ",no-obsolete" part and fix the resulting warnings.
+autoreconf -f -i -Wall,no-obsolete
+
+rm -rf autom4te.cache config.h.in~
+exit 0
diff --git a/protobuf/benchmarks/ProtoBench.java b/protobuf/benchmarks/ProtoBench.java
new file mode 100644
index 0000000..86d62fe
--- /dev/null
+++ b/protobuf/benchmarks/ProtoBench.java
@@ -0,0 +1,203 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2009 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protocolbuffers;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Method;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.CodedInputStream;
+import com.google.protobuf.CodedOutputStream;
+import com.google.protobuf.Message;
+
+public class ProtoBench {
+  
+  private static final long MIN_SAMPLE_TIME_MS = 2 * 1000;
+  private static final long TARGET_TIME_MS = 30 * 1000;
+
+  private ProtoBench() {
+    // Prevent instantiation
+  }
+  
+  public static void main(String[] args) {
+    if (args.length < 2 || (args.length % 2) != 0) {
+      System.err.println("Usage: ProtoBench <descriptor type name> <input data>");
+      System.err.println("The descriptor type name is the fully-qualified message name,");
+      System.err.println("e.g. com.google.protocolbuffers.benchmark.Message1");
+      System.err.println("(You can specify multiple pairs of descriptor type name and input data.)");
+      System.exit(1);
+    }
+    boolean success = true;
+    for (int i = 0; i < args.length; i += 2) {
+      success &= runTest(args[i], args[i + 1]);
+    }
+    System.exit(success ? 0 : 1);
+  }
+
+  /**
+   * Runs a single test. Error messages are displayed to stderr, and the return value
+   * indicates general success/failure.
+   */
+  public static boolean runTest(String type, String file) {
+    System.out.println("Benchmarking " + type + " with file " + file);
+    final Message defaultMessage;
+    try {
+      Class<?> clazz = Class.forName(type);
+      Method method = clazz.getDeclaredMethod("getDefaultInstance");
+      defaultMessage = (Message) method.invoke(null);
+    } catch (Exception e) {
+      // We want to do the same thing with all exceptions. Not generally nice,
+      // but this is slightly different.
+      System.err.println("Unable to get default message for " + type);
+      return false;
+    }
+    
+    try {
+      final byte[] inputData = readAllBytes(file);
+      final ByteArrayInputStream inputStream = new ByteArrayInputStream(inputData);
+      final ByteString inputString = ByteString.copyFrom(inputData);
+      final Message sampleMessage = defaultMessage.newBuilderForType().mergeFrom(inputString).build();
+      FileOutputStream devNullTemp = null;
+      CodedOutputStream reuseDevNullTemp = null;
+      try {
+        devNullTemp = new FileOutputStream("/dev/null");
+        reuseDevNullTemp = CodedOutputStream.newInstance(devNullTemp);
+      } catch (FileNotFoundException e) {
+        // ignore: this is probably Windows, where /dev/null does not exist
+      }
+      final FileOutputStream devNull = devNullTemp;
+      final CodedOutputStream reuseDevNull = reuseDevNullTemp;
+      benchmark("Serialize to byte string", inputData.length, new Action() {
+        public void execute() { sampleMessage.toByteString(); }
+      });      
+      benchmark("Serialize to byte array", inputData.length, new Action() {
+        public void execute() { sampleMessage.toByteArray(); }
+      });
+      benchmark("Serialize to memory stream", inputData.length, new Action() {
+        public void execute() throws IOException { 
+          sampleMessage.writeTo(new ByteArrayOutputStream()); 
+        }
+      });
+      if (devNull != null) {
+        benchmark("Serialize to /dev/null with FileOutputStream", inputData.length, new Action() {
+          public void execute() throws IOException {
+            sampleMessage.writeTo(devNull);
+          }
+        });
+        benchmark("Serialize to /dev/null reusing FileOutputStream", inputData.length, new Action() {
+          public void execute() throws IOException {
+            sampleMessage.writeTo(reuseDevNull);
+            reuseDevNull.flush();  // force the write to the OutputStream
+          }
+        });
+      }
+      benchmark("Deserialize from byte string", inputData.length, new Action() {
+        public void execute() throws IOException { 
+          defaultMessage.newBuilderForType().mergeFrom(inputString).build();
+        }
+      });
+      benchmark("Deserialize from byte array", inputData.length, new Action() {
+        public void execute() throws IOException { 
+          defaultMessage.newBuilderForType()
+            .mergeFrom(CodedInputStream.newInstance(inputData)).build();
+        }
+      });
+      benchmark("Deserialize from memory stream", inputData.length, new Action() {
+        public void execute() throws IOException { 
+          defaultMessage.newBuilderForType()
+            .mergeFrom(CodedInputStream.newInstance(inputStream)).build();
+          inputStream.reset();
+        }
+      });
+      System.out.println();
+      return true;
+    } catch (Exception e) {
+      System.err.println("Error: " + e.getMessage());
+      System.err.println("Detailed exception information:");
+      e.printStackTrace(System.err);
+      return false;
+    }
+  }
+  
+  private static void benchmark(String name, long dataSize, Action action) throws IOException {
+    // Make sure it's JITted "reasonably" hard before running the first progress test
+    for (int i=0; i < 100; i++) {
+      action.execute();
+    }
+    
+    // Run it progressively more times until we've got a reasonable sample
+    int iterations = 1;
+    long elapsed = timeAction(action, iterations);
+    while (elapsed < MIN_SAMPLE_TIME_MS) {
+      iterations *= 2;
+      elapsed = timeAction(action, iterations);
+    }
+    
+    // Upscale the sample to the target time. Do this in floating point arithmetic
+    // to avoid overflow issues.
+    iterations = (int) ((TARGET_TIME_MS / (double) elapsed) * iterations);
+    elapsed = timeAction(action, iterations);
+    System.out.println(name + ": " + iterations + " iterations in "
+         + (elapsed/1000f) + "s; " 
+         + (iterations * dataSize) / (elapsed * 1024 * 1024 / 1000f) 
+         + "MB/s");
+  }
+  
+  private static long timeAction(Action action, int iterations) throws IOException {
+    System.gc();    
+    long start = System.currentTimeMillis();
+    for (int i = 0; i < iterations; i++) {
+      action.execute();
+    }
+    long end = System.currentTimeMillis();
+    return end - start;
+  }
+  
+  private static byte[] readAllBytes(String filename) throws IOException {
+    RandomAccessFile file = new RandomAccessFile(new File(filename), "r");
+    byte[] content = new byte[(int) file.length()];
+    file.readFully(content);
+    return content;
+  }
+
+  /**
+   * Interface used to capture a single action to benchmark.
+   */
+  interface Action {
+    void execute() throws IOException;
+  }
+}
diff --git a/protobuf/benchmarks/google_message1.dat b/protobuf/benchmarks/google_message1.dat
new file mode 100644
index 0000000..bc0f064
--- /dev/null
+++ b/protobuf/benchmarks/google_message1.dat
Binary files differ
diff --git a/protobuf/benchmarks/google_message2.dat b/protobuf/benchmarks/google_message2.dat
new file mode 100644
index 0000000..06c0944
--- /dev/null
+++ b/protobuf/benchmarks/google_message2.dat
Binary files differ
diff --git a/protobuf/benchmarks/google_size.proto b/protobuf/benchmarks/google_size.proto
new file mode 100644
index 0000000..3e6fbdb
--- /dev/null
+++ b/protobuf/benchmarks/google_size.proto
@@ -0,0 +1,136 @@
+package benchmarks;
+
+option java_outer_classname = "GoogleSize";
+option optimize_for = CODE_SIZE;
+
+message SizeMessage1 {
+  required string field1 = 1;
+  optional string field9 = 9;
+  optional string field18 = 18;
+  optional bool field80 = 80 [default=false];
+  optional bool field81 = 81 [default=true];
+  required int32 field2 = 2;
+  required int32 field3 = 3;
+  optional int32 field280 = 280;
+  optional int32 field6 = 6 [default=0];
+  optional int64 field22 = 22;
+  optional string field4 = 4;
+  repeated fixed64 field5 = 5;
+  optional bool field59 = 59 [default=false];
+  optional string field7 = 7;
+  optional int32 field16 = 16;
+  optional int32 field130 = 130 [default=0];
+  optional bool field12 = 12 [default=true];
+  optional bool field17 = 17 [default=true];
+  optional bool field13 = 13 [default=true];
+  optional bool field14 = 14 [default=true];
+  optional int32 field104 = 104 [default=0];
+  optional int32 field100 = 100 [default=0];
+  optional int32 field101 = 101 [default=0];
+  optional string field102 = 102;
+  optional string field103 = 103;
+  optional int32 field29 = 29 [default=0];
+  optional bool field30 = 30 [default=false];
+  optional int32 field60 = 60 [default=-1];
+  optional int32 field271 = 271 [default=-1];
+  optional int32 field272 = 272 [default=-1];
+  optional int32 field150 = 150;
+  optional int32 field23 = 23 [default=0];
+  optional bool field24 = 24 [default=false];
+  optional int32 field25 = 25 [default=0];
+  optional SizeMessage1SubMessage field15 = 15;
+  optional bool field78 = 78;
+  optional int32 field67 = 67 [default=0];
+  optional int32 field68 = 68;
+  optional int32 field128 = 128 [default=0];
+  optional string field129 = 129 [default="xxxxxxxxxxxxxxxxxxxxx"];
+  optional int32 field131 = 131 [default=0];
+}
+
+message SizeMessage1SubMessage {
+  optional int32 field1 = 1 [default=0];
+  optional int32 field2 = 2 [default=0];
+  optional int32 field3 = 3 [default=0];
+  optional string field15 = 15;
+  optional bool field12 = 12 [default=true];
+  optional int64 field13 = 13;
+  optional int64 field14 = 14;
+  optional int32 field16 = 16;
+  optional int32 field19 = 19 [default=2];
+  optional bool field20  = 20 [default=true];
+  optional bool field28 = 28 [default=true];
+  optional fixed64 field21 = 21;
+  optional int32 field22 = 22;
+  optional bool field23 = 23 [ default=false ];
+  optional bool field206 = 206 [default=false];
+  optional fixed32 field203 = 203;
+  optional int32 field204 = 204;
+  optional string field205 = 205;
+  optional uint64 field207 = 207;
+  optional uint64 field300 = 300;
+}
+
+message SizeMessage2 {
+  optional string field1 = 1;
+  optional int64 field3 = 3;
+  optional int64 field4 = 4;
+  optional int64 field30 = 30;
+  optional bool field75  = 75 [default=false];
+  optional string field6 = 6;
+  optional bytes field2 = 2;
+  optional int32 field21 = 21 [default=0];
+  optional int32 field71 = 71;
+  optional float field25 = 25;
+  optional int32 field109 = 109 [default=0];
+  optional int32 field210 = 210 [default=0];
+  optional int32 field211 = 211 [default=0];
+  optional int32 field212 = 212 [default=0];
+  optional int32 field213 = 213 [default=0];
+  optional int32 field216 = 216 [default=0];
+  optional int32 field217 = 217 [default=0];
+  optional int32 field218 = 218 [default=0];
+  optional int32 field220 = 220 [default=0];
+  optional int32 field221 = 221 [default=0];
+  optional float field222 = 222 [default=0.0];
+  optional int32 field63 = 63;
+
+  repeated group Group1 = 10 {
+    required float field11 = 11;
+    optional float field26 = 26;
+    optional string field12 = 12;
+    optional string field13 = 13;
+    repeated string field14 = 14;
+    required uint64 field15 = 15;
+    optional int32 field5 = 5;
+    optional string field27 = 27;
+    optional int32 field28 = 28;
+    optional string field29 = 29;
+    optional string field16 = 16;
+    repeated string field22 = 22;
+    repeated int32 field73 = 73;
+    optional int32 field20 = 20 [default=0];
+    optional string field24 = 24;
+    optional SizeMessage2GroupedMessage field31 = 31;
+  }
+  repeated string field128 = 128;
+  optional int64 field131 = 131;
+  repeated string field127 = 127;
+  optional int32 field129 = 129;
+  repeated int64 field130 = 130;
+  optional bool field205 = 205 [default=false];
+  optional bool field206 = 206 [default=false];
+}
+
+message SizeMessage2GroupedMessage {
+  optional float field1 = 1;
+  optional float field2 = 2;
+  optional float field3 = 3 [default=0.0];
+  optional bool field4 = 4;
+  optional bool field5 = 5;
+  optional bool field6 = 6 [default=true];
+  optional bool field7 = 7 [default=false];
+  optional float field8 = 8;
+  optional bool field9 = 9;
+  optional float field10 = 10;
+  optional int64 field11 = 11;
+}
diff --git a/protobuf/benchmarks/google_speed.proto b/protobuf/benchmarks/google_speed.proto
new file mode 100644
index 0000000..d6cd032
--- /dev/null
+++ b/protobuf/benchmarks/google_speed.proto
@@ -0,0 +1,136 @@
+package benchmarks;
+
+option java_outer_classname = "GoogleSpeed";
+option optimize_for = SPEED;
+
+message SpeedMessage1 {
+  required string field1 = 1;
+  optional string field9 = 9;
+  optional string field18 = 18;
+  optional bool field80 = 80 [default=false];
+  optional bool field81 = 81 [default=true];
+  required int32 field2 = 2;
+  required int32 field3 = 3;
+  optional int32 field280 = 280;
+  optional int32 field6 = 6 [default=0];
+  optional int64 field22 = 22;
+  optional string field4 = 4;
+  repeated fixed64 field5 = 5;
+  optional bool field59 = 59 [default=false];
+  optional string field7 = 7;
+  optional int32 field16 = 16;
+  optional int32 field130 = 130 [default=0];
+  optional bool field12 = 12 [default=true];
+  optional bool field17 = 17 [default=true];
+  optional bool field13 = 13 [default=true];
+  optional bool field14 = 14 [default=true];
+  optional int32 field104 = 104 [default=0];
+  optional int32 field100 = 100 [default=0];
+  optional int32 field101 = 101 [default=0];
+  optional string field102 = 102;
+  optional string field103 = 103;
+  optional int32 field29 = 29 [default=0];
+  optional bool field30 = 30 [default=false];
+  optional int32 field60 = 60 [default=-1];
+  optional int32 field271 = 271 [default=-1];
+  optional int32 field272 = 272 [default=-1];
+  optional int32 field150 = 150;
+  optional int32 field23 = 23 [default=0];
+  optional bool field24 = 24 [default=false];
+  optional int32 field25 = 25 [default=0];
+  optional SpeedMessage1SubMessage field15 = 15;
+  optional bool field78 = 78;
+  optional int32 field67 = 67 [default=0];
+  optional int32 field68 = 68;
+  optional int32 field128 = 128 [default=0];
+  optional string field129 = 129 [default="xxxxxxxxxxxxxxxxxxxxx"];
+  optional int32 field131 = 131 [default=0];
+}
+
+message SpeedMessage1SubMessage {
+  optional int32 field1 = 1 [default=0];
+  optional int32 field2 = 2 [default=0];
+  optional int32 field3 = 3 [default=0];
+  optional string field15 = 15;
+  optional bool field12 = 12 [default=true];
+  optional int64 field13 = 13;
+  optional int64 field14 = 14;
+  optional int32 field16 = 16;
+  optional int32 field19 = 19 [default=2];
+  optional bool field20  = 20 [default=true];
+  optional bool field28 = 28 [default=true];
+  optional fixed64 field21 = 21;
+  optional int32 field22 = 22;
+  optional bool field23 = 23 [ default=false ];
+  optional bool field206 = 206 [default=false];
+  optional fixed32 field203 = 203;
+  optional int32 field204 = 204;
+  optional string field205 = 205;
+  optional uint64 field207 = 207;
+  optional uint64 field300 = 300;
+}
+
+message SpeedMessage2 {
+  optional string field1 = 1;
+  optional int64 field3 = 3;
+  optional int64 field4 = 4;
+  optional int64 field30 = 30;
+  optional bool field75  = 75 [default=false];
+  optional string field6 = 6;
+  optional bytes field2 = 2;
+  optional int32 field21 = 21 [default=0];
+  optional int32 field71 = 71;
+  optional float field25 = 25;
+  optional int32 field109 = 109 [default=0];
+  optional int32 field210 = 210 [default=0];
+  optional int32 field211 = 211 [default=0];
+  optional int32 field212 = 212 [default=0];
+  optional int32 field213 = 213 [default=0];
+  optional int32 field216 = 216 [default=0];
+  optional int32 field217 = 217 [default=0];
+  optional int32 field218 = 218 [default=0];
+  optional int32 field220 = 220 [default=0];
+  optional int32 field221 = 221 [default=0];
+  optional float field222 = 222 [default=0.0];
+  optional int32 field63 = 63;
+
+  repeated group Group1 = 10 {
+    required float field11 = 11;
+    optional float field26 = 26;
+    optional string field12 = 12;
+    optional string field13 = 13;
+    repeated string field14 = 14;
+    required uint64 field15 = 15;
+    optional int32 field5 = 5;
+    optional string field27 = 27;
+    optional int32 field28 = 28;
+    optional string field29 = 29;
+    optional string field16 = 16;
+    repeated string field22 = 22;
+    repeated int32 field73 = 73;
+    optional int32 field20 = 20 [default=0];
+    optional string field24 = 24;
+    optional SpeedMessage2GroupedMessage field31 = 31;
+  }
+  repeated string field128 = 128;
+  optional int64 field131 = 131;
+  repeated string field127 = 127;
+  optional int32 field129 = 129;
+  repeated int64 field130 = 130;
+  optional bool field205 = 205 [default=false];
+  optional bool field206 = 206 [default=false];
+}
+
+message SpeedMessage2GroupedMessage {
+  optional float field1 = 1;
+  optional float field2 = 2;
+  optional float field3 = 3 [default=0.0];
+  optional bool field4 = 4;
+  optional bool field5 = 5;
+  optional bool field6 = 6 [default=true];
+  optional bool field7 = 7 [default=false];
+  optional float field8 = 8;
+  optional bool field9 = 9;
+  optional float field10 = 10;
+  optional int64 field11 = 11;
+}
diff --git a/protobuf/benchmarks/readme.txt b/protobuf/benchmarks/readme.txt
new file mode 100644
index 0000000..2c836d0
--- /dev/null
+++ b/protobuf/benchmarks/readme.txt
@@ -0,0 +1,50 @@
+Contents
+--------
+
+This folder contains three kinds of file:
+
+- Code, such as ProtoBench.java, to build the benchmarking framework.
+- Protocol buffer definitions (.proto files)
+- Sample data files
+
+If we end up with a lot of different benchmarks it may be worth
+separating these out info different directories, but while there are
+so few they might as well all be together.
+
+Running a benchmark (Java)
+--------------------------
+
+1) Build protoc and the Java protocol buffer library. The examples
+   below assume a jar file (protobuf.jar) has been built and copied
+   into this directory.
+
+2) Build ProtoBench:
+   $ javac -d tmp -cp protobuf.jar ProtoBench.java
+   
+3) Generate code for the relevant benchmark protocol buffer, e.g.
+   $ protoc --java_out=tmp google_size.proto google_speed.proto
+   
+4) Build the generated code, e.g.
+   $ cd tmp
+   $ javac -d . -cp ../protobuf.jar benchmarks/*.java
+           
+5) Run the test. Arguments are given in pairs - the first argument
+   is the descriptor type; the second is the filename. For example:
+   $ java -cp .;../protobuf.jar com.google.protocolbuffers.ProtoBench
+          benchmarks.GoogleSize$SizeMessage1 ../google_message1.dat
+          benchmarks.GoogleSpeed$SpeedMessage1 ../google_message1.dat
+          benchmarks.GoogleSize$SizeMessage2 ../google_message2.dat
+          benchmarks.GoogleSpeed$SpeedMessage2 ../google_message2.dat
+          
+6) Wait! Each test runs for around 30 seconds, and there are 6 tests
+   per class/data combination. The above command would therefore take
+   about 12 minutes to run.
+
+   
+Benchmarks available
+--------------------
+
+From Google:
+google_size.proto and google_speed.proto, messages
+google_message1.dat and google_message2.dat. The proto files are
+equivalent, but optimized differently.
diff --git a/protobuf/build.gradle b/protobuf/build.gradle
new file mode 100644
index 0000000..7aa8ac2
--- /dev/null
+++ b/protobuf/build.gradle
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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.
+ */
+
+apply plugin: 'java'
+
+configurations {
+    micro
+    nano
+    lite
+}
+
+sourceSets {
+
+    micro {
+        java {
+            srcDirs = ['java/src/main/java/']
+            include("com/google/protobuf/micro/*")
+        }
+    }
+
+    lite {
+        java {
+            srcDirs = ['java/src/main/java/']
+            include 'com/google/protobuf/UninitializedMessageException.java'
+            include 'com/google/protobuf/MessageLite.java'
+            include 'com/google/protobuf/InvalidProtocolBufferException.java'
+            include 'com/google/protobuf/CodedOutputStream.java'
+            include 'com/google/protobuf/ByteString.java'
+            include 'com/google/protobuf/CodedInputStream.java'
+            include 'com/google/protobuf/ExtensionRegistryLite.java'
+            include 'com/google/protobuf/AbstractMessageLite.java'
+            include 'com/google/protobuf/AbstractParser.java'
+            include 'com/google/protobuf/FieldSet.java'
+            include 'com/google/protobuf/Internal.java'
+            include 'com/google/protobuf/WireFormat.java'
+            include 'com/google/protobuf/GeneratedMessageLite.java'
+            include 'com/google/protobuf/BoundedByteString.java'
+            include 'com/google/protobuf/LazyField.java'
+            include 'com/google/protobuf/LazyFieldLite.java'
+            include 'com/google/protobuf/LazyStringList.java'
+            include 'com/google/protobuf/LazyStringArrayList.java'
+            include 'com/google/protobuf/UnmodifiableLazyStringList.java'
+            include 'com/google/protobuf/LiteralByteString.java'
+            include 'com/google/protobuf/MessageLiteOrBuilder.java'
+            include 'com/google/protobuf/Parser.java'
+            include 'com/google/protobuf/ProtocolStringList.java'
+            include 'com/google/protobuf/RopeByteString.java'
+            include 'com/google/protobuf/SmallSortedMap.java'
+            include 'com/google/protobuf/Utf8.java'
+        }
+    }
+
+    nano {
+        java {
+            srcDirs = [
+                    'java/src/main/java/',
+                    'java/src/device/main/java/'
+            ]
+            include("com/google/protobuf/nano/**")
+        }
+    }
+}
+
+if (project == rootProject) {
+    ext.getAndroidPrebuilt = { apiLevel ->
+        files("$rootDir/../../prebuilts/sdk/$apiLevel/android.jar")
+    }
+}
+
+dependencies {
+    compile getAndroidPrebuilt('8')
+    nanoCompile getAndroidPrebuilt('8')
+}
+
+jar {
+    from sourceSets.nano.output, sourceSets.micro.output
+    baseName "libprotobuf"
+    appendix "java"
+    version "2.6"
+    classifier "micronano"
+}
+
+task nanoJar(type: Jar) {
+    from sourceSets.nano.output
+    dependsOn nanoClasses
+    baseName "libprotobuf"
+    appendix "java"
+    version "2.6"
+    classifier "nano"
+}
+
+task microJar(type: Jar) {
+    from sourceSets.micro.output
+    dependsOn microClasses
+    baseName "libprotobuf"
+    appendix "java"
+    version "2.6"
+    classifier "micro"
+}
+
+task liteJar(type: Jar) {
+    from sourceSets.lite.output
+    dependsOn liteClasses
+    baseName "libprotobuf"
+    appendix "java"
+    version "2.3"
+    classifier "lite"
+}
+
+artifacts {
+    micro microJar
+    nano nanoJar
+    lite liteJar
+}
+
diff --git a/protobuf/compile b/protobuf/compile
new file mode 100755
index 0000000..531136b
--- /dev/null
+++ b/protobuf/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/protobuf/config.guess b/protobuf/config.guess
new file mode 100755
index 0000000..b79252d
--- /dev/null
+++ b/protobuf/config.guess
@@ -0,0 +1,1558 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
+
+timestamp='2013-06-10'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2013 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+	# If the system lacks a compiler, then just pick glibc.
+	# We could probably try harder.
+	LIBC=gnu
+
+	eval $set_cc_for_build
+	cat <<-EOF > $dummy.c
+	#include <features.h>
+	#if defined(__UCLIBC__)
+	LIBC=uclibc
+	#elif defined(__dietlibc__)
+	LIBC=dietlibc
+	#else
+	LIBC=gnu
+	#endif
+	EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+		os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:Bitrig:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+	echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm*:riscos:*:*|arm*:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+	# DG/UX returns AViiON for all architectures
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[4567])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		    case "${sc_cpu_version}" in
+		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		      532)                      # CPU_PA_RISC2_0
+			case "${sc_kernel_bits}" in
+			  32) HP_ARCH="hppa2.0n" ;;
+			  64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+			esac ;;
+		    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^		//' << EOF >$dummy.c
+
+		#define _HPUX_SOURCE
+		#include <stdlib.h>
+		#include <unistd.h>
+
+		int main ()
+		{
+		#if defined(_SC_KERNEL_BITS)
+		    long bits = sysconf(_SC_KERNEL_BITS);
+		#endif
+		    long cpu  = sysconf (_SC_CPU_VERSION);
+
+		    switch (cpu)
+			{
+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+			case CPU_PA_RISC2_0:
+		#if defined(_SC_KERNEL_BITS)
+			    switch (bits)
+				{
+				case 64: puts ("hppa2.0w"); break;
+				case 32: puts ("hppa2.0n"); break;
+				default: puts ("hppa2.0"); break;
+				} break;
+		#else  /* !defined(_SC_KERNEL_BITS) */
+			    puts ("hppa2.0"); break;
+		#endif
+			default: puts ("hppa1.0"); break;
+			}
+		    exit (0);
+		}
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+	exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+	exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+	exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+	exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    5000:UNIX_System_V:4.*:*)
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	case ${UNAME_PROCESSOR} in
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
+	exit ;;
+    i*:windows32*:*)
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    aarch64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    aarch64_be:Linux:*:*)
+	UNAME_MACHINE=aarch64_be
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+	esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arc:Linux:*:* | arceb:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	else
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+	    fi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    cris:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    crisv32:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    frv:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    hexagon:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+	;;
+    or1k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    or32:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-${LIBC}
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+	  *)    echo hppa-unknown-linux-${LIBC} ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-${LIBC}
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-${LIBC}
+	exit ;;
+    ppc64le:Linux:*:*)
+	echo powerpc64le-unknown-linux-${LIBC}
+	exit ;;
+    ppcle:Linux:*:*)
+	echo powerpcle-unknown-linux-${LIBC}
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+	exit ;;
+    sh64*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+	exit ;;
+    x86_64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+	# Unixware is an offshoot of SVR4, but it has its own version
+	# number series starting with 2...
+	# I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+	# Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+	# uname -m prints for DJGPP always 'pc', but it prints nothing about
+	# the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+	exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <Richard.M.Bartel@ccMail.Census.GOV>
+	echo i586-unisys-sysv4
+	exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+		echo mips-nec-sysv${UNAME_RELEASE}
+	else
+		echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+	exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    x86_64:Haiku:*:*)
+	echo x86_64-unknown-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	eval $set_cc_for_build
+	if test "$UNAME_PROCESSOR" = unknown ; then
+	    UNAME_PROCESSOR=powerpc
+	fi
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		case $UNAME_PROCESSOR in
+		    i386) UNAME_PROCESSOR=x86_64 ;;
+		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		esac
+	    fi
+	fi
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSE-*:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+	echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+    x86_64:VMkernel:*:*)
+	echo ${UNAME_MACHINE}-unknown-esx
+	exit ;;
+esac
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+	"4"
+#else
+	""
+#endif
+	); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/protobuf/config.h.in b/protobuf/config.h.in
new file mode 100644
index 0000000..e70582e
--- /dev/null
+++ b/protobuf/config.h.in
@@ -0,0 +1,152 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* the name of <hash_map> */
+#undef HASH_MAP_CLASS
+
+/* the location of <unordered_map> or <hash_map> */
+#undef HASH_MAP_H
+
+/* the namespace of hash_map/hash_set */
+#undef HASH_NAMESPACE
+
+/* the name of <hash_set> */
+#undef HASH_SET_CLASS
+
+/* the location of <unordered_set> or <hash_set> */
+#undef HASH_SET_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* define if the compiler has hash_map */
+#undef HAVE_HASH_MAP
+
+/* define if the compiler has hash_set */
+#undef HAVE_HASH_SET
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have the `mkdir' function. */
+#undef HAVE_MKDIR
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Enable classes using zlib compression. */
+#undef HAVE_ZLIB
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* 64bit enabled */
+#undef SOLARIS_64BIT_ENABLED
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
diff --git a/protobuf/config.sub b/protobuf/config.sub
new file mode 100755
index 0000000..9633db7
--- /dev/null
+++ b/protobuf/config.sub
@@ -0,0 +1,1791 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
+
+timestamp='2013-08-10'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2013 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze*)
+		os=
+		basic_machine=$1
+		;;
+	-bluegene*)
+		os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+	-chorusrdb)
+		os=-chorusrdb
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*178)
+		os=-lynxos178
+		;;
+	-lynx*5)
+		os=-lynxos5
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| aarch64 | aarch64_be \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arceb \
+	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+	| avr | avr32 \
+	| be32 | be64 \
+	| bfin \
+	| c4x | c8051 | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| epiphany \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| hexagon \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| le32 | le64 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipsr5900 | mipsr5900el \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 | nios2eb | nios2el \
+	| ns16k | ns32k \
+	| open8 \
+	| or1k | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pyramid \
+	| rl78 | rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| we32k \
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+	xgate)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| aarch64-* | aarch64_be-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| be32-* | be64-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| c8051-* | clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| hexagon-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| le32-* | le64-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+	| microblaze-* | microblazeel-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipsr5900-* | mipsr5900el-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* | nios2eb-* | nios2el-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pyramid-* \
+	| rl78-* | romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile*-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+	| vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16 | cr16-*)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	microblaze*)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw64)
+		basic_machine=x86_64-pc
+		os=-mingw64
+		;;
+	mingw32)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	msys)
+		basic_machine=i686-pc
+		os=-msys
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	nacl)
+		basic_machine=le32-unknown
+		os=-nacl
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos | rdos64)
+		basic_machine=x86_64-pc
+		os=-rdos
+		;;
+	rdos32)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tile*)
+		basic_machine=$basic_machine-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+	# First match some system type aliases
+	# that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-auroraux)
+		os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* | -plan9* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -bitrig* | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	score-*)
+		os=-elf
+		;;
+	spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	c8051-*)
+		os=-elf
+		;;
+	hexagon-*)
+		os=-elf
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or1k-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/protobuf/configure b/protobuf/configure
new file mode 100755
index 0000000..746dca2
--- /dev/null
+++ b/protobuf/configure
@@ -0,0 +1,19726 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for Protocol Buffers 2.6.1.
+#
+# Report bugs to <protobuf@googlegroups.com>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: protobuf@googlegroups.com about your system, including
+$0: any error possibly output before this message. Then
+$0: install a modern shell, or manually run the script
+$0: under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='Protocol Buffers'
+PACKAGE_TARNAME='protobuf'
+PACKAGE_VERSION='2.6.1'
+PACKAGE_STRING='Protocol Buffers 2.6.1'
+PACKAGE_BUGREPORT='protobuf@googlegroups.com'
+PACKAGE_URL=''
+
+ac_unique_file="src/google/protobuf/message.cc"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+enable_option_checking=no
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+subdirs
+PTHREAD_CFLAGS
+PTHREAD_LIBS
+PTHREAD_CC
+acx_pthread_config
+USE_EXTERNAL_PROTOC_FALSE
+USE_EXTERNAL_PROTOC_TRUE
+PROTOC
+HAVE_ZLIB_FALSE
+HAVE_ZLIB_TRUE
+POW_LIB
+LIBOBJS
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+LIBTOOL
+ISAINFO
+PROTOBUF_OPT_FLAG
+GCC_FALSE
+GCC_TRUE
+EGREP
+GREP
+CXXCPP
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_os
+target_vendor
+target_cpu
+target
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+enable_silent_rules
+with_zlib
+with_protoc
+enable_dependency_tracking
+enable_64bit_solaris
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CXXCPP'
+ac_subdirs_all='gtest'
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures Protocol Buffers 2.6.1 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/protobuf]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of Protocol Buffers 2.6.1:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-maintainer-mode
+                          disable make rules and dependencies not useful (and
+                          sometimes confusing) to the casual installer
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --disable-64bit-solaris Build 64 bit binary on Solaris [default=on]
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-zlib             include classes for streaming compressed data in and
+                          out [default=check]
+  --with-protoc=COMMAND   use the given protoc command instead of building a
+                          new one when building tests (useful for
+                          cross-compiling)
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CXXCPP      C++ preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <protobuf@googlegroups.com>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+Protocol Buffers configure 2.6.1
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_cxx_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ---------------------------------------- ##
+## Report this to protobuf@googlegroups.com ##
+## ---------------------------------------- ##"
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_mongrel
+
+# ac_fn_cxx_try_run LINENO
+# ------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_cxx_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_run
+
+# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_cxx_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_compile
+
+# ac_fn_cxx_check_decl LINENO SYMBOL VAR INCLUDES
+# -----------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_cxx_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+  (void) $as_decl_use;
+#else
+  (void) $as_decl_name;
+#endif
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_decl
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_cxx_check_func LINENO FUNC VAR
+# ------------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_cxx_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_func
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Protocol Buffers $as_me 2.6.1, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+    # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+  enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=yes
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+   if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+
+  MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+
+# autoconf's default CXXFLAGS are usually "-g -O2".  These aren't necessarily
+# the best choice for libprotobuf.
+if test "x${ac_cv_env_CFLAGS_set}" = "x"; then :
+  CFLAGS=""
+fi
+if test "x${ac_cv_env_CXXFLAGS_set}" = "x"; then :
+  CXXFLAGS=""
+fi
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+$as_echo_n "checking target system type... " >&6; }
+if ${ac_cv_target+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$target_alias" = x; then
+  ac_cv_target=$ac_cv_host
+else
+  ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+$as_echo "$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+am__api_version='1.14'
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$*" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$*" != "X $srcdir/configure conftest.file" \
+	&& test "$*" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment" "$LINENO" 5
+     fi
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if ${ac_cv_path_mkdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='protobuf'
+ VERSION='2.6.1'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+  fi
+fi
+
+
+# Check whether --with-zlib was given.
+if test "${with_zlib+set}" = set; then :
+  withval=$with_zlib;
+else
+  with_zlib=check
+fi
+
+
+
+# Check whether --with-protoc was given.
+if test "${with_protoc+set}" = set; then :
+  withval=$with_protoc;
+else
+  with_protoc=no
+fi
+
+
+# Checks for programs.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CXX"  am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CXX_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CXX_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+  ac_fn_cxx_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+  if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+  fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#         define __EXTENSIONS__ 1
+          $ac_includes_default
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_safe_to_define___extensions__=yes
+else
+  ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+  test $ac_cv_safe_to_define___extensions__ = yes &&
+    $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+  $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+  $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+
+
+
+
+ if test "$GCC" = yes; then
+  GCC_TRUE=
+  GCC_FALSE='#'
+else
+  GCC_TRUE='#'
+  GCC_FALSE=
+fi
+   # let the Makefile know if we're gcc
+
+# test_util.cc takes forever to compile with GCC and optimization turned on.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking C++ compiler flags..." >&5
+$as_echo_n "checking C++ compiler flags...... " >&6; }
+if test "x${ac_cv_env_CXXFLAGS_set}" = "x"; then :
+
+  if test "$GCC" = "yes"; then :
+
+    PROTOBUF_OPT_FLAG="-O2"
+    CXXFLAGS="${CXXFLAGS} -g"
+
+fi
+
+  # Protocol Buffers contains several checks that are intended to be used only
+  # for debugging and which might hurt performance.  Most users are probably
+  # end users who don't want these checks, so add -DNDEBUG by default.
+  CXXFLAGS="$CXXFLAGS -DNDEBUG"
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: use default: $PROTOBUF_OPT_FLAG $CXXFLAGS" >&5
+$as_echo "use default: $PROTOBUF_OPT_FLAG $CXXFLAGS" >&6; }
+
+else
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: use user-supplied: $CXXFLAGS" >&5
+$as_echo "use user-supplied: $CXXFLAGS" >&6; }
+
+fi
+
+
+
+
+
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+  ac_fn_cxx_check_decl "$LINENO" "__SUNPRO_CC" "ac_cv_have_decl___SUNPRO_CC" "$ac_includes_default"
+if test "x$ac_cv_have_decl___SUNPRO_CC" = xyes; then :
+  SUNCC="yes"
+else
+  SUNCC="no"
+fi
+
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+  # Check whether --enable-64bit-solaris was given.
+if test "${enable_64bit_solaris+set}" = set; then :
+  enableval=$enable_64bit_solaris; ac_enable_64bit="$enableval"
+else
+  ac_enable_64bit="yes"
+fi
+
+
+  if test "$SUNCC" = "yes" -a "x${ac_cv_env_CXXFLAGS_set}" = "x"; then :
+
+            CXXFLAGS="-g0 -xO3 -xlibmil -xdepend -xbuiltin -mt -compat=5 -library=stlport4 -library=Crun -template=no%extdef ${CXXFLAGS}"
+
+fi
+
+  case $host_os in
+    *solaris*)
+      for ac_prog in isainfo
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ISAINFO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ISAINFO"; then
+  ac_cv_prog_ISAINFO="$ISAINFO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ISAINFO="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ISAINFO=$ac_cv_prog_ISAINFO
+if test -n "$ISAINFO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ISAINFO" >&5
+$as_echo "$ISAINFO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ISAINFO" && break
+done
+test -n "$ISAINFO" || ISAINFO="no"
+
+      if test "x$ISAINFO" != "xno"; then :
+  isainfo_b=`${ISAINFO} -b`
+else
+  isainfo_b="x"
+fi
+
+      if test "$isainfo_b" != "x"; then :
+
+
+        isainfo_k=`${ISAINFO} -k`
+
+        if test "x$ac_enable_64bit" = "xyes"; then :
+
+
+
+$as_echo "#define SOLARIS_64BIT_ENABLED 1" >>confdefs.h
+
+          if test "x$libdir" = "x\${exec_prefix}/lib"; then :
+
+                                 libdir="${libdir}/${isainfo_k}"
+
+fi
+
+                                        if test "x${ac_cv_env_CXXFLAGS_set}" = "x"; then :
+
+            CXXFLAGS="${CXXFLAGS} -m64"
+            ac_cv_env_CXXFLAGS_set=set
+            ac_cv_env_CXXFLAGS_value='-m64'
+
+fi
+
+          if test "x${ac_cv_env_CFLAGS_set}" = "x"; then :
+
+            CFLAGS="${CFLAGS} -m64"
+            ac_cv_env_CFLAGS_set=set
+            ac_cv_env_CFLAGS_value='-m64'
+
+fi
+
+          if test "$target_cpu" = "sparc" -a "x$SUNCC" = "xyes" ; then :
+
+            CXXFLAGS="-xmemalign=8s ${CXXFLAGS}"
+
+fi
+
+fi
+
+fi
+    ;;
+  esac
+
+
+
+# Have to do libtool after SUNCC, other wise it "helpfully" adds Crun Cstd
+# to the link
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in dumpbin "link -dump"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[	 ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len" && \
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DLLTOOL" = x; then
+    DLLTOOL="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DLLTOOL=$ac_ct_DLLTOOL
+  fi
+else
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    case `/usr/bin/file conftest.o` in
+	      *x86-64*)
+		LD="${LD-ld} -m elf32_x86_64"
+		;;
+	      *)
+		LD="${LD-ld} -m elf_i386"
+		;;
+	    esac
+	    ;;
+	  powerpc64le-*)
+	    LD="${LD-ld} -m elf32lppclinux"
+	    ;;
+	  powerpc64-*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  powerpcle-*)
+	    LD="${LD-ld} -m elf64lppc"
+	    ;;
+	  powerpc-*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
+else
+  lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_NMEDIT="nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_LIPO="lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OTOOL="otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OTOOL64="otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&5
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=no
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+  # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='--shared'
+	lt_prog_compiler_static='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec=
+	  tmp_sharedflag='--shared' ;;
+	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	link_all_deplibs=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      export_dynamic_flag_spec='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  archive_cmds_need_lc=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	old_archive_from_new_cmds='true'
+	# FIXME: Should let the user specify the lib program.
+	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  link_all_deplibs=yes
+  allow_undefined_flag="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+	hardcode_direct=yes
+	hardcode_direct_absolute=yes
+	export_dynamic_flag_spec='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  hardcode_direct_absolute=yes
+	  export_dynamic_flag_spec='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+           LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	hardcode_direct_absolute=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$lt_prog_compiler_wl
+	  pic_flag=$lt_prog_compiler_pic
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag
+	  allow_undefined_flag=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	  then
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+  lt_cv_dlopen="shl_load"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report which library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+CC="$lt_save_CC"
+
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+else
+  _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+  # save warnings/boilerplate of simple test code
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  compiler_CXX=$CC
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+    else
+      lt_prog_compiler_no_builtin_flag_CXX=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          whole_archive_flag_spec_CXX=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+    ld_shlibs_CXX=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+      aix[4-9]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        archive_cmds_CXX=''
+        hardcode_direct_CXX=yes
+        hardcode_direct_absolute_CXX=yes
+        hardcode_libdir_separator_CXX=':'
+        link_all_deplibs_CXX=yes
+        file_list_spec_CXX='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[012]|aix4.[012].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    hardcode_direct_CXX=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    hardcode_minus_L_CXX=yes
+	    hardcode_libdir_flag_spec_CXX='-L$libdir'
+	    hardcode_libdir_separator_CXX=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        export_dynamic_flag_spec_CXX='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        always_export_symbols_CXX=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          allow_undefined_flag_CXX='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	    allow_undefined_flag_CXX="-z nodefs"
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    no_undefined_flag_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      whole_archive_flag_spec_CXX='$convenience'
+	    fi
+	    archive_cmds_need_lc_CXX=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  allow_undefined_flag_CXX=unsupported
+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX=' '
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=yes
+	  file_list_spec_CXX='@'
+	  # Tell ltmain to make .lib files, not .a files.
+	  libext=lib
+	  # Tell ltmain to make .dll files, not .so files.
+	  shrext_cmds=".dll"
+	  # FIXME: Setting linknames here is a bad hack.
+	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+	  enable_shared_with_static_runtimes_CXX=yes
+	  # Don't use ranlib
+	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
+	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX='-L$libdir'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=no
+	  enable_shared_with_static_runtimes_CXX=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	  else
+	    ld_shlibs_CXX=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_CXX=no
+  hardcode_direct_CXX=no
+  hardcode_automatic_CXX=yes
+  hardcode_shlibpath_var_CXX=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec_CXX=''
+  fi
+  link_all_deplibs_CXX=yes
+  allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+
+  else
+  ld_shlibs_CXX=no
+  fi
+
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        ld_shlibs_CXX=no
+        ;;
+
+      freebsd-elf*)
+        archive_cmds_need_lc_CXX=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        ld_shlibs_CXX=yes
+        ;;
+
+      haiku*)
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        link_all_deplibs_CXX=yes
+        ;;
+
+      hpux9*)
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        export_dynamic_flag_spec_CXX='${wl}-E'
+        hardcode_direct_CXX=yes
+        hardcode_minus_L_CXX=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            ld_shlibs_CXX=no
+            ;;
+          aCC*)
+            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              ld_shlibs_CXX=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      export_dynamic_flag_spec_CXX='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct_CXX=no
+            hardcode_shlibpath_var_CXX=no
+            ;;
+          *)
+            hardcode_direct_CXX=yes
+            hardcode_direct_absolute_CXX=yes
+            hardcode_minus_L_CXX=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[3-9]*)
+	hardcode_direct_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    link_all_deplibs_CXX=yes
+	    ;;
+        esac
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        inherit_rpath_CXX=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    archive_cmds_need_lc_CXX=no
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+	      prelink_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      old_archive_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      archive_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      no_undefined_flag_CXX=' -zdefs'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      hardcode_libdir_flag_spec_CXX='-R$libdir'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      compiler_needs_object_CXX=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='func_echo_all'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  hardcode_libdir_flag_spec_CXX='-R$libdir'
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        ld_shlibs_CXX=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	  hardcode_direct_absolute_CXX=yes
+	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        allow_undefined_flag_CXX=' -expect_unresolved \*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+		;;
+	    esac
+
+	    hardcode_libdir_separator_CXX=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	      hardcode_libdir_separator_CXX=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            archive_cmds_need_lc_CXX=yes
+	    no_undefined_flag_CXX=' -zdefs'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    hardcode_libdir_flag_spec_CXX='-R$libdir'
+	    hardcode_shlibpath_var_CXX=no
+	    case $host_os in
+	      solaris2.[0-5] | solaris2.[0-5].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    link_all_deplibs_CXX=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[0-5] | solaris2.[0-5].*) ;;
+		*)
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_CXX='${wl}-z,text'
+      archive_cmds_need_lc_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
+	archive_cmds_need_lc_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+	hardcode_libdir_separator_CXX=':'
+	link_all_deplibs_CXX=yes
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+	      '"$old_archive_cmds_CXX"
+	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+	      '"$reload_cmds_CXX"
+	    ;;
+	  *)
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+    GCC_CXX="$GXX"
+    LD_CXX="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case ${prev}${p} in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
+	 -L | -R)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_CXX='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_CXX='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static_CXX=
+      ;;
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_CXX=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	lt_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_CXX='-fPIC -shared'
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[4-9]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  lt_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      mingw* | cygwin* | os2* | pw32* | cegcc*)
+	# This hack is so that the source file can tell whether it is being
+	# built for inclusion in a dll (and should export symbols for example).
+	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fpic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-qpic'
+	    lt_prog_compiler_static_CXX='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      lt_prog_compiler_pic_CXX='-KPIC'
+	      lt_prog_compiler_static_CXX='-Bstatic'
+	      lt_prog_compiler_wl_CXX='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd* | netbsdelf*-gnu)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        lt_prog_compiler_pic_CXX='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_CXX=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works_CXX=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_CXX=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works_CXX=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+fi
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  case $host_os in
+  aix[4-9]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+      ;;
+    esac
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs_CXX=no
+    ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$lt_prog_compiler_wl_CXX
+	  pic_flag=$lt_prog_compiler_pic_CXX
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+	  allow_undefined_flag_CXX=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	  then
+	    lt_cv_archive_cmds_need_lc_CXX=no
+	  else
+	    lt_cv_archive_cmds_need_lc_CXX=yes
+	  fi
+	  allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+   test -n "$runpath_var_CXX" ||
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_CXX" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+# Checks for header files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+for ac_header in fcntl.h inttypes.h limits.h stdlib.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# Checks for library functions.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5
+$as_echo_n "checking for working memcmp... " >&6; }
+if ${ac_cv_func_memcmp_working+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_memcmp_working=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+  /* Some versions of memcmp are not 8-bit clean.  */
+  char c0 = '\100', c1 = '\200', c2 = '\201';
+  if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0)
+    return 1;
+
+  /* The Next x86 OpenStep bug shows up only when comparing 16 bytes
+     or more and with at least one buffer not starting on a 4-byte boundary.
+     William Lewis provided this test program.   */
+  {
+    char foo[21];
+    char bar[21];
+    int i;
+    for (i = 0; i < 4; i++)
+      {
+	char *a = foo + i;
+	char *b = bar + i;
+	strcpy (a, "--------01111111");
+	strcpy (b, "--------10000000");
+	if (memcmp (a, b, 16) >= 0)
+	  return 1;
+      }
+    return 0;
+  }
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+  ac_cv_func_memcmp_working=yes
+else
+  ac_cv_func_memcmp_working=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5
+$as_echo "$ac_cv_func_memcmp_working" >&6; }
+test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in
+  *" memcmp.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS memcmp.$ac_objext"
+ ;;
+esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strtod" >&5
+$as_echo_n "checking for working strtod... " >&6; }
+if ${ac_cv_func_strtod+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_strtod=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+$ac_includes_default
+#ifndef strtod
+double strtod ();
+#endif
+int
+main()
+{
+  {
+    /* Some versions of Linux strtod mis-parse strings with leading '+'.  */
+    char *string = " +69";
+    char *term;
+    double value;
+    value = strtod (string, &term);
+    if (value != 69 || term != (string + 4))
+      return 1;
+  }
+
+  {
+    /* Under Solaris 2.4, strtod returns the wrong value for the
+       terminating character under some conditions.  */
+    char *string = "NaN";
+    char *term;
+    strtod (string, &term);
+    if (term != string && *(term - 1) == 0)
+      return 1;
+  }
+  return 0;
+}
+
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+  ac_cv_func_strtod=yes
+else
+  ac_cv_func_strtod=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strtod" >&5
+$as_echo "$ac_cv_func_strtod" >&6; }
+if test $ac_cv_func_strtod = no; then
+  case " $LIBOBJS " in
+  *" strtod.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strtod.$ac_objext"
+ ;;
+esac
+
+ac_fn_cxx_check_func "$LINENO" "pow" "ac_cv_func_pow"
+if test "x$ac_cv_func_pow" = xyes; then :
+
+fi
+
+if test $ac_cv_func_pow = no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5
+$as_echo_n "checking for pow in -lm... " >&6; }
+if ${ac_cv_lib_m_pow+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pow ();
+int
+main ()
+{
+return pow ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_m_pow=yes
+else
+  ac_cv_lib_m_pow=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5
+$as_echo "$ac_cv_lib_m_pow" >&6; }
+if test "x$ac_cv_lib_m_pow" = xyes; then :
+  POW_LIB=-lm
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find library containing definition of pow" >&5
+$as_echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;}
+fi
+
+fi
+
+fi
+
+for ac_func in ftruncate memset mkdir strchr strerror strtol
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Check for zlib.
+HAVE_ZLIB=0
+if test "$with_zlib" != no; then :
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking zlib version" >&5
+$as_echo_n "checking zlib version... " >&6; }
+
+  # First check the zlib header version.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+        #include <zlib.h>
+        #if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204)
+        # error zlib version too old
+        #endif
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (1.2.0.4 or later)" >&5
+$as_echo "ok (1.2.0.4 or later)" >&6; }
+
+    # Also need to add -lz to the linker flags and make sure this succeeds.
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing zlibVersion" >&5
+$as_echo_n "checking for library containing zlibVersion... " >&6; }
+if ${ac_cv_search_zlibVersion+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char zlibVersion ();
+int
+main ()
+{
+return zlibVersion ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' z; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_search_zlibVersion=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_zlibVersion+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_zlibVersion+:} false; then :
+
+else
+  ac_cv_search_zlibVersion=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_zlibVersion" >&5
+$as_echo "$ac_cv_search_zlibVersion" >&6; }
+ac_res=$ac_cv_search_zlibVersion
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+
+$as_echo "#define HAVE_ZLIB 1" >>confdefs.h
+
+      HAVE_ZLIB=1
+
+else
+
+      if test "$with_zlib" != check; then :
+
+        { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-zlib was given, but no working zlib library was found
+See \`config.log' for more details" "$LINENO" 5; }
+
+fi
+
+fi
+
+
+else
+
+    if test "$with_zlib" = check; then :
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: headers missing or too old (requires 1.2.0.4)" >&5
+$as_echo "headers missing or too old (requires 1.2.0.4)" >&6; }
+
+else
+
+      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-zlib was given, but zlib headers were not present or were too old (requires 1.2.0.4)
+See \`config.log' for more details" "$LINENO" 5; }
+
+fi
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+ if test $HAVE_ZLIB = 1; then
+  HAVE_ZLIB_TRUE=
+  HAVE_ZLIB_FALSE='#'
+else
+  HAVE_ZLIB_TRUE='#'
+  HAVE_ZLIB_FALSE=
+fi
+
+
+if test "$with_protoc" != "no"; then :
+
+  PROTOC=$with_protoc
+  if test "$with_protoc" = "yes"; then :
+
+    # No argument given.  Use system protoc.
+    PROTOC=protoc
+
+fi
+  if echo "$PROTOC" | grep -q '^[^/].*/'; then :
+
+    # Does not start with a slash, but contains a slash.  So, it's a relative
+    # path (as opposed to an absolute path or an executable in $PATH).
+    # Since it will actually be executed from the src directory, prefix with
+    # the current directory.  We also insert $ac_top_build_prefix in case this
+    # is a nested package and --with-protoc was actually given on the outer
+    # package's configure script.
+    PROTOC=`pwd`/${ac_top_build_prefix}$PROTOC
+
+fi
+
+
+fi
+ if test "$with_protoc" != "no"; then
+  USE_EXTERNAL_PROTOC_TRUE=
+  USE_EXTERNAL_PROTOC_FALSE='#'
+else
+  USE_EXTERNAL_PROTOC_TRUE='#'
+  USE_EXTERNAL_PROTOC_FALSE=
+fi
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
+$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+                ;;
+
+                -*)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
+$as_echo_n "checking whether pthreads work with $flag... " >&6; }
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+		pthread-config)
+		# Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_acx_pthread_config+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$acx_pthread_config"; then
+  ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_acx_pthread_config="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no"
+fi
+fi
+acx_pthread_config=$ac_cv_prog_acx_pthread_config
+if test -n "$acx_pthread_config"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5
+$as_echo "$acx_pthread_config" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+		if test x"$acx_pthread_config" = xno; then continue; fi
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
+
+                *)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
+$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+	attr_name=unknown
+	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int attr=$attr; return attr;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  attr_name=$attr; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	done
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5
+$as_echo "$attr_name" >&6; }
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $attr_name
+_ACEOF
+
+        fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
+$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5
+$as_echo "${flag}" >&6; }
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+        # More AIX lossage: must compile with xlc_r or cc_r
+	if test x"$GCC" != xyes; then
+          for ac_prog in xlc_r cc_r
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PTHREAD_CC"; then
+  ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PTHREAD_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PTHREAD_CC" && break
+done
+test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}"
+
+        else
+          PTHREAD_CC=$CC
+	fi
+
+	# The next part tries to detect GCC inconsistency with -shared on some
+	# architectures and systems. The problem is that in certain
+	# configurations, when -shared is specified, GCC "forgets" to
+	# internally use various flags which are still necessary.
+
+	#
+	# Prepare the flags
+	#
+	save_CFLAGS="$CFLAGS"
+	save_LIBS="$LIBS"
+	save_CC="$CC"
+
+	# Try with the flags determined by the earlier checks.
+	#
+	# -Wl,-z,defs forces link-time symbol resolution, so that the
+	# linking checks with -shared actually have any value
+	#
+	# FIXME: -fPIC is required for -shared on many architectures,
+	# so we specify it here, but the right way would probably be to
+	# properly detect whether it is actually required.
+	CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+	CC="$PTHREAD_CC"
+
+	# In order not to create several levels of indentation, we test
+	# the value of "$done" until we find the cure or run out of ideas.
+	done="no"
+
+	# First, make sure the CFLAGS we added are actually accepted by our
+	# compiler.  If not (and OS X's ld, for instance, does not accept -z),
+	# then we can't do this test.
+	if test x"$done" = xno; then
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to check for GCC pthread/shared inconsistencies" >&5
+$as_echo_n "checking whether to check for GCC pthread/shared inconsistencies... " >&6; }
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+  done=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	   if test "x$done" = xyes ; then
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	   else
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	   fi
+	fi
+
+	if test x"$done" = xno; then
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -pthread is sufficient with -shared" >&5
+$as_echo_n "checking whether -pthread is sufficient with -shared... " >&6; }
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  done=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	   if test "x$done" = xyes; then
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	   else
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	   fi
+	fi
+
+	#
+	# Linux gcc on some architectures such as mips/mipsel forgets
+	# about -lpthread
+	#
+	if test x"$done" = xno; then
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lpthread fixes that" >&5
+$as_echo_n "checking whether -lpthread fixes that... " >&6; }
+	   LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  done=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	   if test "x$done" = xyes; then
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	      PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
+	   else
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	   fi
+	fi
+	#
+	# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
+	#
+	if test x"$done" = xno; then
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc_r fixes that" >&5
+$as_echo_n "checking whether -lc_r fixes that... " >&6; }
+	   LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+	        pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	        pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  done=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	   if test "x$done" = xyes; then
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	      PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
+	   else
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	   fi
+	fi
+	if test x"$done" = xno; then
+	   # OK, we have run out of ideas
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries" >&5
+$as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries" >&2;}
+
+	   # so it's not safe to assume that we may use pthreads
+	   acx_pthread_ok=no
+	fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether what we have so far is sufficient with -nostdlib" >&5
+$as_echo_n "checking whether what we have so far is sufficient with -nostdlib... " >&6; }
+	CFLAGS="-nostdlib $CFLAGS"
+	# we need c with nostdlib
+	LIBS="$LIBS -lc"
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+	       pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	       pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  done=yes
+else
+  done=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	if test "x$done" = xyes; then
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	fi
+
+	if test x"$done" = xno; then
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lpthread saves the day" >&5
+$as_echo_n "checking whether -lpthread saves the day... " >&6; }
+	   LIBS="-lpthread $LIBS"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+	       pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	       pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  done=yes
+else
+  done=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	   if test "x$done" = xyes; then
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	      PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
+	   else
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib" >&5
+$as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries and -nostdlib" >&2;}
+	   fi
+	fi
+
+	CFLAGS="$save_CFLAGS"
+	LIBS="$save_LIBS"
+	CC="$save_CC"
+else
+        PTHREAD_CC="$CC"
+fi
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+
+$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+        :
+else
+        acx_pthread_ok=no
+
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking the location of hash_map" >&5
+$as_echo_n "checking the location of hash_map... " >&6; }
+
+   ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+   ac_cv_cxx_hash_map=""
+   # First try unordered_map, but not on gcc's before 4.2 -- I've
+   # seen unexplainable unordered_map bugs with -O2 on older gcc's.
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
+                   # error GCC too old for unordered_map
+                   #endif
+
+int
+main ()
+{
+/* no program body necessary */
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  stl_hash_old_gcc=no
+else
+  stl_hash_old_gcc=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   for location in unordered_map tr1/unordered_map; do
+     for namespace in std std::tr1; do
+       if test -z "$ac_cv_cxx_hash_map" -a "$stl_hash_old_gcc" != yes; then
+         # Some older gcc's have a buggy tr1, so test a bit of code.
+         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$location>
+int
+main ()
+{
+const ${namespace}::unordered_map<int, int> t;
+                         return t.find(5) == t.end();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_cxx_hash_map="<$location>";
+                         ac_cv_cxx_hash_namespace="$namespace";
+                         ac_cv_cxx_hash_map_class="unordered_map";
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       fi
+     done
+   done
+   # Now try hash_map
+   for location in ext/hash_map hash_map; do
+     for namespace in __gnu_cxx "" std stdext; do
+       if test -z "$ac_cv_cxx_hash_map"; then
+         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$location>
+int
+main ()
+{
+${namespace}::hash_map<int, int> t
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_cxx_hash_map="<$location>";
+                         ac_cv_cxx_hash_namespace="$namespace";
+                         ac_cv_cxx_hash_map_class="hash_map";
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       fi
+     done
+   done
+   ac_cv_cxx_hash_set=`echo "$ac_cv_cxx_hash_map" | sed s/map/set/`;
+   ac_cv_cxx_hash_set_class=`echo "$ac_cv_cxx_hash_map_class" | sed s/map/set/`;
+   if test -n "$ac_cv_cxx_hash_map"; then
+
+$as_echo "#define HAVE_HASH_MAP 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_HASH_SET 1" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define HASH_MAP_H $ac_cv_cxx_hash_map
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define HASH_SET_H $ac_cv_cxx_hash_set
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define HASH_NAMESPACE $ac_cv_cxx_hash_namespace
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define HASH_MAP_CLASS $ac_cv_cxx_hash_map_class
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define HASH_SET_CLASS $ac_cv_cxx_hash_set_class
+_ACEOF
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_hash_map" >&5
+$as_echo "$ac_cv_cxx_hash_map" >&6; }
+   else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
+$as_echo "" >&6; }
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: could not find an STL hash_map" >&5
+$as_echo "$as_me: WARNING: could not find an STL hash_map" >&2;}
+   fi
+
+
+case "$target_os" in
+  mingw* | cygwin* | win*)
+    ;;
+  *)
+    # Need to link against rt on Solaris
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sched_yield" >&5
+$as_echo_n "checking for library containing sched_yield... " >&6; }
+if ${ac_cv_search_sched_yield+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sched_yield ();
+int
+main ()
+{
+return sched_yield ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' rt; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_search_sched_yield=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_sched_yield+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_sched_yield+:} false; then :
+
+else
+  ac_cv_search_sched_yield=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sched_yield" >&5
+$as_echo "$ac_cv_search_sched_yield" >&6; }
+ac_res=$ac_cv_search_sched_yield
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "sched_yield was not found on your system
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+    ;;
+esac
+
+# HACK:  Make gtest's configure script pick up our copy of CFLAGS and CXXFLAGS,
+#   since the flags added by ACX_CHECK_SUNCC must be used when compiling gtest
+#   too.
+export CFLAGS
+export CXXFLAGS
+
+
+subdirs="$subdirs gtest"
+
+
+ac_config_files="$ac_config_files Makefile src/Makefile protobuf.pc protobuf-lite.pc"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+  as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${GCC_TRUE}" && test -z "${GCC_FALSE}"; then
+  as_fn_error $? "conditional \"GCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_ZLIB_TRUE}" && test -z "${HAVE_ZLIB_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_ZLIB\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${USE_EXTERNAL_PROTOC_TRUE}" && test -z "${USE_EXTERNAL_PROTOC_FALSE}"; then
+  as_fn_error $? "conditional \"USE_EXTERNAL_PROTOC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Protocol Buffers $as_me 2.6.1, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <protobuf@googlegroups.com>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+Protocol Buffers config.status 2.6.1
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+    "protobuf.pc") CONFIG_FILES="$CONFIG_FILES protobuf.pc" ;;
+    "protobuf-lite.pc") CONFIG_FILES="$CONFIG_FILES protobuf-lite.pc" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\    # positional parameters, so assign one to ordinary parameter first.\
+\    func_stripname_result=${3}\
+\    func_stripname_result=${func_stripname_result#"${1}"}\
+\    func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+  # Remove --cache-file, --srcdir, and --disable-option-checking arguments
+  # so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  eval "set x $ac_configure_args"
+  shift
+  for ac_arg
+  do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case $ac_arg in
+    -cache-file | --cache-file | --cache-fil | --cache-fi \
+    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+      ac_prev=cache_file ;;
+    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
+    | --c=*)
+      ;;
+    --config-cache | -C)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+      ac_prev=prefix ;;
+    -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+      ;;
+    --disable-option-checking)
+      ;;
+    *)
+      case $ac_arg in
+      *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      esac
+      as_fn_append ac_sub_configure_args " '$ac_arg'" ;;
+    esac
+  done
+
+  # Always prepend --prefix to ensure using the same prefix
+  # in subdir configurations.
+  ac_arg="--prefix=$prefix"
+  case $ac_arg in
+  *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args"
+
+  # Pass --silent
+  if test "$silent" = yes; then
+    ac_sub_configure_args="--silent $ac_sub_configure_args"
+  fi
+
+  # Always prepend --disable-option-checking to silence warnings, since
+  # different subdirs can have different --enable and --with options.
+  ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args"
+
+  ac_popdir=`pwd`
+  for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+    # Do not complain, so a configure script can configure whichever
+    # parts of a large source tree are present.
+    test -d "$srcdir/$ac_dir" || continue
+
+    ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)"
+    $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5
+    $as_echo "$ac_msg" >&6
+    as_dir="$ac_dir"; as_fn_mkdir_p
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+    cd "$ac_dir"
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      ac_sub_configure=$ac_srcdir/configure.gnu
+    elif test -f "$ac_srcdir/configure"; then
+      ac_sub_configure=$ac_srcdir/configure
+    elif test -f "$ac_srcdir/configure.in"; then
+      # This should be Cygnus configure.
+      ac_sub_configure=$ac_aux_dir/configure
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5
+$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+      ac_sub_configure=
+    fi
+
+    # The recursion is here.
+    if test -n "$ac_sub_configure"; then
+      # Make the cache file name correct relative to the subdirectory.
+      case $cache_file in
+      [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+      *) # Relative name.
+	ac_sub_cache_file=$ac_top_build_prefix$cache_file ;;
+      esac
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+      # The eval makes quoting arguments work.
+      eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \
+	   --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" ||
+	as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5
+    fi
+
+    cd "$ac_popdir"
+  done
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/protobuf/configure.ac b/protobuf/configure.ac
new file mode 100644
index 0000000..c07067c
--- /dev/null
+++ b/protobuf/configure.ac
@@ -0,0 +1,159 @@
+## Process this file with autoconf to produce configure.
+## In general, the safest way to proceed is to run ./autogen.sh
+
+AC_PREREQ(2.59)
+
+# Note:  If you change the version, you must also update it in:
+# * java/pom.xml
+# * python/setup.py
+# * src/google/protobuf/stubs/common.h
+# * src/Makefile.am (Update -version-info for LDFLAGS if needed)
+#
+# In the SVN trunk, the version should always be the next anticipated release
+# version with the "-pre" suffix.  (We used to use "-SNAPSHOT" but this pushed
+# the size of one file name in the dist tarfile over the 99-char limit.)
+AC_INIT([Protocol Buffers],[2.6.1],[protobuf@googlegroups.com],[protobuf])
+
+AM_MAINTAINER_MODE([enable])
+
+AC_CONFIG_SRCDIR(src/google/protobuf/message.cc)
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+# autoconf's default CXXFLAGS are usually "-g -O2".  These aren't necessarily
+# the best choice for libprotobuf.
+AS_IF([test "x${ac_cv_env_CFLAGS_set}" = "x"],
+      [CFLAGS=""])
+AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],
+      [CXXFLAGS=""])
+
+AC_CANONICAL_TARGET
+
+AM_INIT_AUTOMAKE([subdir-objects])
+
+AC_ARG_WITH([zlib],
+  [AS_HELP_STRING([--with-zlib],
+    [include classes for streaming compressed data in and out @<:@default=check@:>@])],
+  [],[with_zlib=check])
+
+AC_ARG_WITH([protoc],
+  [AS_HELP_STRING([--with-protoc=COMMAND],
+    [use the given protoc command instead of building a new one when building tests (useful for cross-compiling)])],
+  [],[with_protoc=no])
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CXX
+AC_LANG([C++])
+ACX_USE_SYSTEM_EXTENSIONS
+AM_CONDITIONAL(GCC, test "$GCC" = yes)   # let the Makefile know if we're gcc
+
+# test_util.cc takes forever to compile with GCC and optimization turned on.
+AC_MSG_CHECKING([C++ compiler flags...])
+AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],[
+  AS_IF([test "$GCC" = "yes"],[
+    PROTOBUF_OPT_FLAG="-O2"
+    CXXFLAGS="${CXXFLAGS} -g"
+  ])
+
+  # Protocol Buffers contains several checks that are intended to be used only
+  # for debugging and which might hurt performance.  Most users are probably
+  # end users who don't want these checks, so add -DNDEBUG by default.
+  CXXFLAGS="$CXXFLAGS -DNDEBUG"
+
+  AC_MSG_RESULT([use default: $PROTOBUF_OPT_FLAG $CXXFLAGS])
+],[
+  AC_MSG_RESULT([use user-supplied: $CXXFLAGS])
+])
+
+AC_SUBST(PROTOBUF_OPT_FLAG)
+
+ACX_CHECK_SUNCC
+
+# Have to do libtool after SUNCC, other wise it "helpfully" adds Crun Cstd
+# to the link
+AC_PROG_LIBTOOL
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h stdlib.h unistd.h])
+
+# Checks for library functions.
+AC_FUNC_MEMCMP
+AC_FUNC_STRTOD
+AC_CHECK_FUNCS([ftruncate memset mkdir strchr strerror strtol])
+
+# Check for zlib.
+HAVE_ZLIB=0
+AS_IF([test "$with_zlib" != no], [
+  AC_MSG_CHECKING([zlib version])
+
+  # First check the zlib header version.
+  AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM([[
+        #include <zlib.h>
+        #if !defined(ZLIB_VERNUM) || (ZLIB_VERNUM < 0x1204)
+        # error zlib version too old
+        #endif
+        ]], [])], [
+    AC_MSG_RESULT([ok (1.2.0.4 or later)])
+
+    # Also need to add -lz to the linker flags and make sure this succeeds.
+    AC_SEARCH_LIBS([zlibVersion], [z], [
+      AC_DEFINE([HAVE_ZLIB], [1], [Enable classes using zlib compression.])
+      HAVE_ZLIB=1
+    ], [
+      AS_IF([test "$with_zlib" != check], [
+        AC_MSG_FAILURE([--with-zlib was given, but no working zlib library was found])
+      ])
+    ])
+  ], [
+    AS_IF([test "$with_zlib" = check], [
+      AC_MSG_RESULT([headers missing or too old (requires 1.2.0.4)])
+    ], [
+      AC_MSG_FAILURE([--with-zlib was given, but zlib headers were not present or were too old (requires 1.2.0.4)])
+    ])
+  ])
+])
+AM_CONDITIONAL([HAVE_ZLIB], [test $HAVE_ZLIB = 1])
+
+AS_IF([test "$with_protoc" != "no"], [
+  PROTOC=$with_protoc
+  AS_IF([test "$with_protoc" = "yes"], [
+    # No argument given.  Use system protoc.
+    PROTOC=protoc
+  ])
+  AS_IF([echo "$PROTOC" | grep -q '^@<:@^/@:>@.*/'], [
+    # Does not start with a slash, but contains a slash.  So, it's a relative
+    # path (as opposed to an absolute path or an executable in $PATH).
+    # Since it will actually be executed from the src directory, prefix with
+    # the current directory.  We also insert $ac_top_build_prefix in case this
+    # is a nested package and --with-protoc was actually given on the outer
+    # package's configure script.
+    PROTOC=`pwd`/${ac_top_build_prefix}$PROTOC
+  ])
+  AC_SUBST([PROTOC])
+])
+AM_CONDITIONAL([USE_EXTERNAL_PROTOC], [test "$with_protoc" != "no"])
+
+ACX_PTHREAD
+AC_CXX_STL_HASH
+
+case "$target_os" in
+  mingw* | cygwin* | win*)
+    ;;
+  *)
+    # Need to link against rt on Solaris
+    AC_SEARCH_LIBS([sched_yield], [rt], [], [AC_MSG_FAILURE([sched_yield was not found on your system])])
+    ;;
+esac
+
+# HACK:  Make gtest's configure script pick up our copy of CFLAGS and CXXFLAGS,
+#   since the flags added by ACX_CHECK_SUNCC must be used when compiling gtest
+#   too.
+export CFLAGS
+export CXXFLAGS
+AC_CONFIG_SUBDIRS([gtest])
+
+AC_CONFIG_FILES([Makefile src/Makefile protobuf.pc protobuf-lite.pc])
+AC_OUTPUT
diff --git a/protobuf/depcomp b/protobuf/depcomp
new file mode 100755
index 0000000..4ebd5b3
--- /dev/null
+++ b/protobuf/depcomp
@@ -0,0 +1,791 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+    echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+    exit 1;
+    ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by 'PROGRAMS ARGS'.
+  object      Object file output by 'PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputting dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'.  Note that this directory component will
+# be either empty or ending with a '/' character.  This is deliberate.
+set_dir_from ()
+{
+  case $1 in
+    */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+      *) dir=;;
+  esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+  base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+  echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+  # If the compiler actually managed to produce a dependency file,
+  # post-process it.
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form 'foo.o: dependency.h'.
+    # Do two passes, one to just change these to
+    #   $object: dependency.h
+    # and one to simply output
+    #   dependency.h:
+    # which is needed to avoid the deleted-header problem.
+    { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+      sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+    } > "$depfile"
+    rm -f "$tmpdepfile"
+  else
+    make_dummy_depfile
+  fi
+}
+
+# A tabulation character.
+tab='	'
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+  # This is just like dashmstdout with a different argument.
+  dashmflag=-xM
+  depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+  # This is just like msvisualcpp but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+  # This is just like msvc7 but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+  # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+  gccflag=-qmakedep=gcc,-MF
+  depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).  Also, it might not be
+##   supported by the other compilers which use the 'gcc' depmode.
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The second -e expression handles DOS-style file names with drive
+  # letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+## Some versions of gcc put a space before the ':'.  On the theory
+## that the space means something, we add a space to the output as
+## well.  hp depmode also adds that space, but also prefixes the VPATH
+## to the object.  Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like '#:fec' to the end of the
+    # dependency line.
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+      | tr "$nl" ' ' >> "$depfile"
+    echo >> "$depfile"
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+      >> "$depfile"
+  else
+    make_dummy_depfile
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+xlc)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts '$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  set_dir_from "$object"
+  set_base_from "$object"
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  aix_post_process_depfile
+  ;;
+
+tcc)
+  # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+  # FIXME: That version still under development at the moment of writing.
+  #        Make that this statement remains true also for stable, released
+  #        versions.
+  # It will wrap lines (doesn't matter whether long or short) with a
+  # trailing '\', as in:
+  #
+  #   foo.o : \
+  #    foo.c \
+  #    foo.h \
+  #
+  # It will put a trailing '\' even on the last line, and will use leading
+  # spaces rather than leading tabs (at least since its commit 0394caf7
+  # "Emit spaces for -MD").
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+  # We have to change lines of the first kind to '$object: \'.
+  sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+  # And for each line of the second kind, we have to emit a 'dep.h:'
+  # dummy dependency, to avoid the deleted-header problem.
+  sed -n -e 's|^  *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file.  A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+  # Portland's C compiler understands '-MD'.
+  # Will always output deps to 'file.d' where file is the root name of the
+  # source file under compilation, even if file resides in a subdirectory.
+  # The object file name does not affect the name of the '.d' file.
+  # pgcc 10.2 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using '\' :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+  set_dir_from "$object"
+  # Use the source, not the object, to determine the base name, since
+  # that's sadly what pgcc will do too.
+  set_base_from "$source"
+  tmpdepfile=$base.d
+
+  # For projects that build the same source file twice into different object
+  # files, the pgcc approach of using the *source* file root name can cause
+  # problems in parallel builds.  Use a locking strategy to avoid stomping on
+  # the same $tmpdepfile.
+  lockdir=$base.d-lock
+  trap "
+    echo '$0: caught signal, cleaning up...' >&2
+    rmdir '$lockdir'
+    exit 1
+  " 1 2 13 15
+  numtries=100
+  i=$numtries
+  while test $i -gt 0; do
+    # mkdir is a portable test-and-set.
+    if mkdir "$lockdir" 2>/dev/null; then
+      # This process acquired the lock.
+      "$@" -MD
+      stat=$?
+      # Release the lock.
+      rmdir "$lockdir"
+      break
+    else
+      # If the lock is being held by a different process, wait
+      # until the winning process is done or we timeout.
+      while test -d "$lockdir" && test $i -gt 0; do
+        sleep 1
+        i=`expr $i - 1`
+      done
+    fi
+    i=`expr $i - 1`
+  done
+  trap - 1 2 13 15
+  if test $i -le 0; then
+    echo "$0: failed to acquire lock after $numtries attempts" >&2
+    echo "$0: check lockdir '$lockdir'" >&2
+    exit 1
+  fi
+
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  set_dir_from  "$object"
+  set_base_from "$object"
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add 'dependent.h:' lines.
+    sed -ne '2,${
+               s/^ *//
+               s/ \\*$//
+               s/$/:/
+               p
+             }' "$tmpdepfile" >> "$depfile"
+  else
+    make_dummy_depfile
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+  # The Tru64 compiler uses -MD to generate dependencies as a side
+  # effect.  'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+  # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+  # dependencies in 'foo.d' instead, so we check for that too.
+  # Subdirectories are respected.
+  set_dir_from  "$object"
+  set_base_from "$object"
+
+  if test "$libtool" = yes; then
+    # Libtool generates 2 separate objects for the 2 libraries.  These
+    # two compilations output dependencies in $dir.libs/$base.o.d and
+    # in $dir$base.o.d.  We have to check for both files, because
+    # one of the two compilations can be disabled.  We should prefer
+    # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+    # automatically cleaned when .libs/ is deleted, while ignoring
+    # the former would cause a distcleancheck panic.
+    tmpdepfile1=$dir$base.o.d          # libtool 1.5
+    tmpdepfile2=$dir.libs/$base.o.d    # Likewise.
+    tmpdepfile3=$dir.libs/$base.d      # Compaq CCC V6.2-504
+    "$@" -Wc,-MD
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    tmpdepfile3=$dir$base.d
+    "$@" -MD
+  fi
+
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  # Same post-processing that is required for AIX mode.
+  aix_post_process_depfile
+  ;;
+
+msvc7)
+  if test "$libtool" = yes; then
+    showIncludes=-Wc,-showIncludes
+  else
+    showIncludes=-showIncludes
+  fi
+  "$@" $showIncludes > "$tmpdepfile"
+  stat=$?
+  grep -v '^Note: including file: ' "$tmpdepfile"
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The first sed program below extracts the file names and escapes
+  # backslashes for cygpath.  The second sed program outputs the file
+  # name when reading, but also accumulates all include files in the
+  # hold buffer in order to output them again at the end.  This only
+  # works with sed implementations that can handle large buffers.
+  sed < "$tmpdepfile" -n '
+/^Note: including file:  *\(.*\)/ {
+  s//\1/
+  s/\\/\\\\/g
+  p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+  s/.*/'"$tab"'/
+  G
+  p
+}' >> "$depfile"
+  echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+  rm -f "$tmpdepfile"
+  ;;
+
+msvc7msys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove '-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for ':'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+  "$@" $dashmflag |
+    sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this sed invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  # makedepend may prepend the VPATH from the source file name to the object.
+  # No need to regex-escape $object, excess matching of '.' is harmless.
+  sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process the last invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed '1,2d' "$tmpdepfile" \
+    | tr ' ' "$nl" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove '-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E \
+    | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+             -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+    | sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+        set fnord "$@"
+        shift
+        shift
+        ;;
+    *)
+        set fnord "$@" "$arg"
+        shift
+        shift
+        ;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+  echo "$tab" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/protobuf/editors/README.txt b/protobuf/editors/README.txt
new file mode 100644
index 0000000..3e9fc79
--- /dev/null
+++ b/protobuf/editors/README.txt
@@ -0,0 +1,5 @@
+This directory contains syntax highlighting and configuration files for editors
+to properly display Protocol Buffer files.
+
+See each file's header comment for directions on how to use it with the
+appropriate editor.
diff --git a/protobuf/editors/proto.vim b/protobuf/editors/proto.vim
new file mode 100644
index 0000000..7cd1dbf
--- /dev/null
+++ b/protobuf/editors/proto.vim
@@ -0,0 +1,105 @@
+" Protocol Buffers - Google's data interchange format
+" Copyright 2008 Google Inc.  All rights reserved.
+" https://developers.google.com/protocol-buffers/
+"
+" Redistribution and use in source and binary forms, with or without
+" modification, are permitted provided that the following conditions are
+" met:
+"
+"     * Redistributions of source code must retain the above copyright
+" notice, this list of conditions and the following disclaimer.
+"     * Redistributions in binary form must reproduce the above
+" copyright notice, this list of conditions and the following disclaimer
+" in the documentation and/or other materials provided with the
+" distribution.
+"     * Neither the name of Google Inc. nor the names of its
+" contributors may be used to endorse or promote products derived from
+" this software without specific prior written permission.
+"
+" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+" A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+" OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+" This is the Vim syntax file for Google Protocol Buffers.
+"
+" Usage:
+"
+" 1. cp proto.vim ~/.vim/syntax/
+" 2. Add the following to ~/.vimrc:
+"
+" augroup filetype
+"   au! BufRead,BufNewFile *.proto setfiletype proto
+" augroup end
+"
+" Or just create a new file called ~/.vim/ftdetect/proto.vim with the
+" previous lines on it.
+
+if version < 600
+  syntax clear
+elseif exists("b:current_syntax")
+  finish
+endif
+
+syn case match
+
+syn keyword pbTodo       contained TODO FIXME XXX
+syn cluster pbCommentGrp contains=pbTodo
+
+syn keyword pbSyntax     syntax import option
+syn keyword pbStructure  package message group
+syn keyword pbRepeat     optional required repeated
+syn keyword pbDefault    default
+syn keyword pbExtend     extend extensions to max
+syn keyword pbRPC        service rpc returns
+
+syn keyword pbType      int32 int64 uint32 uint64 sint32 sint64
+syn keyword pbType      fixed32 fixed64 sfixed32 sfixed64
+syn keyword pbType      float double bool string bytes
+syn keyword pbTypedef   enum
+syn keyword pbBool      true false
+
+syn match   pbInt     /-\?\<\d\+\>/
+syn match   pbInt     /\<0[xX]\x+\>/
+syn match   pbFloat   /\<-\?\d*\(\.\d*\)\?/
+syn region  pbComment start="\/\*" end="\*\/" contains=@pbCommentGrp
+syn region  pbComment start="//" skip="\\$" end="$" keepend contains=@pbCommentGrp
+syn region  pbString  start=/"/ skip=/\\./ end=/"/
+syn region  pbString  start=/'/ skip=/\\./ end=/'/
+
+if version >= 508 || !exists("did_proto_syn_inits")
+  if version < 508
+    let did_proto_syn_inits = 1
+    command -nargs=+ HiLink hi link <args>
+  else
+    command -nargs=+ HiLink hi def link <args>
+  endif
+
+  HiLink pbTodo         Todo
+
+  HiLink pbSyntax       Include
+  HiLink pbStructure    Structure
+  HiLink pbRepeat       Repeat
+  HiLink pbDefault      Keyword
+  HiLink pbExtend       Keyword
+  HiLink pbRPC          Keyword
+  HiLink pbType         Type
+  HiLink pbTypedef      Typedef
+  HiLink pbBool         Boolean
+
+  HiLink pbInt          Number
+  HiLink pbFloat        Float
+  HiLink pbComment      Comment
+  HiLink pbString       String
+
+  delcommand HiLink
+endif
+
+let b:current_syntax = "proto"
diff --git a/protobuf/editors/protobuf-mode.el b/protobuf/editors/protobuf-mode.el
new file mode 100644
index 0000000..09aecc9
--- /dev/null
+++ b/protobuf/editors/protobuf-mode.el
@@ -0,0 +1,220 @@
+;;; protobuf-mode.el --- major mode for editing protocol buffers.
+
+;; Author: Alexandre Vassalotti <alexandre@peadrop.com>
+;; Created: 23-Apr-2009
+;; Version: 0.3
+;; Keywords: google protobuf languages
+
+;; 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.
+
+;;; Commentary:
+
+;; Installation:
+;;   - Put `protobuf-mode.el' in your Emacs load-path.
+;;   - Add this line to your .emacs file:
+;;       (require 'protobuf-mode)
+;;
+;; You can customize this mode just like any mode derived from CC Mode.  If
+;; you want to add customizations specific to protobuf-mode, you can use the
+;; `protobuf-mode-hook'. For example, the following would make protocol-mode
+;; use 2-space indentation:
+;;
+;;   (defconst my-protobuf-style
+;;     '((c-basic-offset . 2)
+;;       (indent-tabs-mode . nil)))
+;;
+;;   (add-hook 'protobuf-mode-hook
+;;     (lambda () (c-add-style "my-style" my-protobuf-style t)))
+;;
+;; Refer to the documentation of CC Mode for more information about
+;; customization details and how to use this mode.
+;;
+;; TODO:
+;;   - Make highlighting for enum values work properly.
+;;   - Fix the parser to recognize extensions as identifiers and not
+;;     as casts.
+;;   - Improve the parsing of option assignment lists. For example:
+;;       optional int32 foo = 1 [(my_field_option) = 4.5];
+;;   - Add support for fully-qualified identifiers (e.g., with a leading ".").
+
+;;; Code:
+
+(require 'cc-mode)
+
+(eval-when-compile
+  (require 'cc-langs)
+  (require 'cc-fonts))
+
+;; This mode does not inherit properties from other modes. So, we do not use 
+;; the usual `c-add-language' function.
+(eval-and-compile
+  (put 'protobuf-mode 'c-mode-prefix "protobuf-"))
+
+;; The following code uses of the `c-lang-defconst' macro define syntactic
+;; features of protocol buffer language.  Refer to the documentation in the
+;; cc-langs.el file for information about the meaning of the -kwds variables.
+
+(c-lang-defconst c-primitive-type-kwds
+  protobuf '("double" "float" "int32" "int64" "uint32" "uint64" "sint32"
+             "sint64" "fixed32" "fixed64" "sfixed32" "sfixed64" "bool"
+             "string" "bytes" "group"))
+
+(c-lang-defconst c-modifier-kwds
+  protobuf '("required" "optional" "repeated"))
+
+(c-lang-defconst c-class-decl-kwds
+  protobuf '("message" "enum" "service"))
+
+(c-lang-defconst c-constant-kwds
+  protobuf '("true" "false"))
+
+(c-lang-defconst c-other-decl-kwds
+  protobuf '("package" "import"))
+
+(c-lang-defconst c-other-kwds
+  protobuf '("default" "max"))
+
+(c-lang-defconst c-identifier-ops
+  ;; Handle extended identifiers like google.protobuf.MessageOptions
+  protobuf '((left-assoc ".")))
+
+;; The following keywords do not fit well in keyword classes defined by
+;; cc-mode.  So, we approximate as best we can.
+
+(c-lang-defconst c-type-list-kwds
+  protobuf '("extensions" "to"))
+
+(c-lang-defconst c-typeless-decl-kwds
+  protobuf '("extend" "rpc" "option" "returns"))
+
+
+;; Here we remove default syntax for loops, if-statements and other C
+;; syntactic features that are not supported by the protocol buffer language.
+
+(c-lang-defconst c-brace-list-decl-kwds
+  ;; Remove syntax for C-style enumerations.
+  protobuf nil)
+
+(c-lang-defconst c-block-stmt-1-kwds
+  ;; Remove syntax for "do" and "else" keywords.
+  protobuf nil)
+
+(c-lang-defconst c-block-stmt-2-kwds
+  ;; Remove syntax for "for", "if", "switch" and "while" keywords.
+  protobuf nil)
+
+(c-lang-defconst c-simple-stmt-kwds
+  ;; Remove syntax for "break", "continue", "goto" and "return" keywords.
+  protobuf nil)
+
+(c-lang-defconst c-paren-stmt-kwds
+  ;; Remove special case for the "(;;)" in for-loops.
+  protobuf nil)
+
+(c-lang-defconst c-label-kwds
+  ;; Remove case label syntax for the "case" and "default" keywords.
+  protobuf nil)
+
+(c-lang-defconst c-before-label-kwds
+  ;; Remove special case for the label in a goto statement.
+  protobuf nil)
+
+(c-lang-defconst c-cpp-matchers
+  ;; Disable all the C preprocessor syntax.
+  protobuf nil)
+
+(c-lang-defconst c-decl-prefix-re
+  ;; Same as for C, except it does not match "(". This is needed for disabling
+  ;; the syntax for casts.
+  protobuf "\\([\{\};,]+\\)")
+
+
+;; Add support for variable levels of syntax highlighting.
+
+(defconst protobuf-font-lock-keywords-1 (c-lang-const c-matchers-1 protobuf)
+  "Minimal highlighting for protobuf-mode.")
+
+(defconst protobuf-font-lock-keywords-2 (c-lang-const c-matchers-2 protobuf)
+  "Fast normal highlighting for protobuf-mode.")
+
+(defconst protobuf-font-lock-keywords-3 (c-lang-const c-matchers-3 protobuf)
+  "Accurate normal highlighting for protobuf-mode.")
+
+(defvar protobuf-font-lock-keywords protobuf-font-lock-keywords-3
+  "Default expressions to highlight in protobuf-mode.")
+
+;; Our syntax table is auto-generated from the keyword classes we defined
+;; previously with the `c-lang-const' macro.
+(defvar protobuf-mode-syntax-table nil
+  "Syntax table used in protobuf-mode buffers.")
+(or protobuf-mode-syntax-table
+    (setq protobuf-mode-syntax-table
+          (funcall (c-lang-const c-make-mode-syntax-table protobuf))))
+
+(defvar protobuf-mode-abbrev-table nil
+  "Abbreviation table used in protobuf-mode buffers.")
+
+(defvar protobuf-mode-map nil
+  "Keymap used in protobuf-mode buffers.")
+(or protobuf-mode-map
+    (setq protobuf-mode-map (c-make-inherited-keymap)))
+
+(easy-menu-define protobuf-menu protobuf-mode-map
+  "Protocol Buffers Mode Commands"
+  (cons "Protocol Buffers" (c-lang-const c-mode-menu protobuf)))
+
+;;;###autoload (add-to-list 'auto-mode-alist '("\\.proto\\'" . protobuf-mode))
+
+;;;###autoload
+(defun protobuf-mode ()
+  "Major mode for editing Protocol Buffers description language.
+
+The hook `c-mode-common-hook' is run with no argument at mode
+initialization, then `protobuf-mode-hook'.
+
+Key bindings:
+\\{protobuf-mode-map}"
+  (interactive)
+  (kill-all-local-variables)
+  (set-syntax-table protobuf-mode-syntax-table)
+  (setq major-mode 'protobuf-mode
+        mode-name "Protocol-Buffers"
+        local-abbrev-table protobuf-mode-abbrev-table
+        abbrev-mode t)
+  (use-local-map protobuf-mode-map)
+  (c-initialize-cc-mode t)
+  (if (fboundp 'c-make-emacs-variables-local)
+      (c-make-emacs-variables-local))
+  (c-init-language-vars protobuf-mode)
+  (c-common-init 'protobuf-mode)
+  (easy-menu-add protobuf-menu)
+  (c-run-mode-hooks 'c-mode-common-hook 'protobuf-mode-hook)
+  (c-update-modeline))
+
+(provide 'protobuf-mode)
+
+;;; protobuf-mode.el ends here
diff --git a/protobuf/examples/AddPerson.java b/protobuf/examples/AddPerson.java
new file mode 100644
index 0000000..ca5ac27
--- /dev/null
+++ b/protobuf/examples/AddPerson.java
@@ -0,0 +1,95 @@
+// See README.txt for information and build instructions.
+
+import com.example.tutorial.AddressBookProtos.AddressBook;
+import com.example.tutorial.AddressBookProtos.Person;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.PrintStream;
+
+class AddPerson {
+  // This function fills in a Person message based on user input.
+  static Person PromptForAddress(BufferedReader stdin,
+                                 PrintStream stdout) throws IOException {
+    Person.Builder person = Person.newBuilder();
+
+    stdout.print("Enter person ID: ");
+    person.setId(Integer.valueOf(stdin.readLine()));
+
+    stdout.print("Enter name: ");
+    person.setName(stdin.readLine());
+
+    stdout.print("Enter email address (blank for none): ");
+    String email = stdin.readLine();
+    if (email.length() > 0) {
+      person.setEmail(email);
+    }
+
+    while (true) {
+      stdout.print("Enter a phone number (or leave blank to finish): ");
+      String number = stdin.readLine();
+      if (number.length() == 0) {
+        break;
+      }
+
+      Person.PhoneNumber.Builder phoneNumber =
+        Person.PhoneNumber.newBuilder().setNumber(number);
+
+      stdout.print("Is this a mobile, home, or work phone? ");
+      String type = stdin.readLine();
+      if (type.equals("mobile")) {
+        phoneNumber.setType(Person.PhoneType.MOBILE);
+      } else if (type.equals("home")) {
+        phoneNumber.setType(Person.PhoneType.HOME);
+      } else if (type.equals("work")) {
+        phoneNumber.setType(Person.PhoneType.WORK);
+      } else {
+        stdout.println("Unknown phone type.  Using default.");
+      }
+
+      person.addPhone(phoneNumber);
+    }
+
+    return person.build();
+  }
+
+  // Main function:  Reads the entire address book from a file,
+  //   adds one person based on user input, then writes it back out to the same
+  //   file.
+  public static void main(String[] args) throws Exception {
+    if (args.length != 1) {
+      System.err.println("Usage:  AddPerson ADDRESS_BOOK_FILE");
+      System.exit(-1);
+    }
+
+    AddressBook.Builder addressBook = AddressBook.newBuilder();
+
+    // Read the existing address book.
+    try {
+      FileInputStream input = new FileInputStream(args[0]);
+      try {
+        addressBook.mergeFrom(input);
+      } finally {
+        try { input.close(); } catch (Throwable ignore) {}
+      }
+    } catch (FileNotFoundException e) {
+      System.out.println(args[0] + ": File not found.  Creating a new file.");
+    }
+
+    // Add an address.
+    addressBook.addPerson(
+      PromptForAddress(new BufferedReader(new InputStreamReader(System.in)),
+                       System.out));
+
+    // Write the new address book back to disk.
+    FileOutputStream output = new FileOutputStream(args[0]);
+    try {
+      addressBook.build().writeTo(output);
+    } finally {
+      output.close();
+    }
+  }
+}
diff --git a/protobuf/examples/ListPeople.java b/protobuf/examples/ListPeople.java
new file mode 100644
index 0000000..b2f153a
--- /dev/null
+++ b/protobuf/examples/ListPeople.java
@@ -0,0 +1,50 @@
+// See README.txt for information and build instructions.
+
+import com.example.tutorial.AddressBookProtos.AddressBook;
+import com.example.tutorial.AddressBookProtos.Person;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+class ListPeople {
+  // Iterates though all people in the AddressBook and prints info about them.
+  static void Print(AddressBook addressBook) {
+    for (Person person: addressBook.getPersonList()) {
+      System.out.println("Person ID: " + person.getId());
+      System.out.println("  Name: " + person.getName());
+      if (person.hasEmail()) {
+        System.out.println("  E-mail address: " + person.getEmail());
+      }
+
+      for (Person.PhoneNumber phoneNumber : person.getPhoneList()) {
+        switch (phoneNumber.getType()) {
+          case MOBILE:
+            System.out.print("  Mobile phone #: ");
+            break;
+          case HOME:
+            System.out.print("  Home phone #: ");
+            break;
+          case WORK:
+            System.out.print("  Work phone #: ");
+            break;
+        }
+        System.out.println(phoneNumber.getNumber());
+      }
+    }
+  }
+
+  // Main function:  Reads the entire address book from a file and prints all
+  //   the information inside.
+  public static void main(String[] args) throws Exception {
+    if (args.length != 1) {
+      System.err.println("Usage:  ListPeople ADDRESS_BOOK_FILE");
+      System.exit(-1);
+    }
+
+    // Read the existing address book.
+    AddressBook addressBook =
+      AddressBook.parseFrom(new FileInputStream(args[0]));
+
+    Print(addressBook);
+  }
+}
diff --git a/protobuf/examples/Makefile b/protobuf/examples/Makefile
new file mode 100644
index 0000000..8dc9083
--- /dev/null
+++ b/protobuf/examples/Makefile
@@ -0,0 +1,58 @@
+# See README.txt.
+
+.PHONY: all cpp java python clean
+
+all: cpp java python
+
+cpp:    add_person_cpp    list_people_cpp
+java:   add_person_java   list_people_java
+python: add_person_python list_people_python
+
+clean:
+	rm -f add_person_cpp list_people_cpp add_person_java list_people_java add_person_python list_people_python
+	rm -f javac_middleman AddPerson*.class ListPeople*.class com/example/tutorial/*.class
+	rm -f protoc_middleman addressbook.pb.cc addressbook.pb.h addressbook_pb2.py com/example/tutorial/AddressBookProtos.java
+	rm -f *.pyc
+	rmdir com/example/tutorial 2>/dev/null || true
+	rmdir com/example 2>/dev/null || true
+	rmdir com 2>/dev/null || true
+
+protoc_middleman: addressbook.proto
+	protoc --cpp_out=. --java_out=. --python_out=. addressbook.proto
+	@touch protoc_middleman
+
+add_person_cpp: add_person.cc protoc_middleman
+	pkg-config --cflags protobuf  # fails if protobuf is not installed
+	c++ add_person.cc addressbook.pb.cc -o add_person_cpp `pkg-config --cflags --libs protobuf`
+
+list_people_cpp: list_people.cc protoc_middleman
+	pkg-config --cflags protobuf  # fails if protobuf is not installed
+	c++ list_people.cc addressbook.pb.cc -o list_people_cpp `pkg-config --cflags --libs protobuf`
+
+javac_middleman: AddPerson.java ListPeople.java protoc_middleman
+	javac AddPerson.java ListPeople.java com/example/tutorial/AddressBookProtos.java
+	@touch javac_middleman
+
+add_person_java: javac_middleman
+	@echo "Writing shortcut script add_person_java..."
+	@echo '#! /bin/sh' > add_person_java
+	@echo 'java -classpath .:$$CLASSPATH AddPerson "$$@"' >> add_person_java
+	@chmod +x add_person_java
+
+list_people_java: javac_middleman
+	@echo "Writing shortcut script list_people_java..."
+	@echo '#! /bin/sh' > list_people_java
+	@echo 'java -classpath .:$$CLASSPATH ListPeople "$$@"' >> list_people_java
+	@chmod +x list_people_java
+
+add_person_python: add_person.py protoc_middleman
+	@echo "Writing shortcut script add_person_python..."
+	@echo '#! /bin/sh' > add_person_python
+	@echo './add_person.py "$$@"' >> add_person_python
+	@chmod +x add_person_python
+
+list_people_python: list_people.py protoc_middleman
+	@echo "Writing shortcut script list_people_python..."
+	@echo '#! /bin/sh' > list_people_python
+	@echo './list_people.py "$$@"' >> list_people_python
+	@chmod +x list_people_python
diff --git a/protobuf/examples/README.txt b/protobuf/examples/README.txt
new file mode 100644
index 0000000..f5530a5
--- /dev/null
+++ b/protobuf/examples/README.txt
@@ -0,0 +1,29 @@
+This directory contains example code that uses Protocol Buffers to manage an
+address book.  Two programs are provided, each with three different
+implementations, one written in each of C++, Java, and Python.  The add_person
+example adds a new person to an address book, prompting the user to input
+the person's information.  The list_people example lists people already in the
+address book.  The examples use the exact same format in all three languages,
+so you can, for example, use add_person_java to create an address book and then
+use list_people_python to read it.
+
+You must install the protobuf package before you can build these.
+
+To build all the examples (on a unix-like system), simply run "make".  This
+creates the following executable files in the current directory:
+  add_person_cpp     list_people_cpp
+  add_person_java    list_people_java
+  add_person_python  list_people_python
+
+If you only want to compile examples in one language, use "make cpp"*,
+"make java", or "make python".
+
+All of these programs simply take an address book file as their parameter.
+The add_person programs will create the file if it doesn't already exist.
+
+These examples are part of the Protocol Buffers tutorial, located at:
+  https://developers.google.com/protocol-buffers/docs/tutorials
+
+* Note that on some platforms you may have to edit the Makefile and remove
+"-lpthread" from the linker commands (perhaps replacing it with something else).
+We didn't do this automatically because we wanted to keep the example simple.
diff --git a/protobuf/examples/add_person.cc b/protobuf/examples/add_person.cc
new file mode 100644
index 0000000..b9ca44f
--- /dev/null
+++ b/protobuf/examples/add_person.cc
@@ -0,0 +1,95 @@
+// See README.txt for information and build instructions.
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include "addressbook.pb.h"
+using namespace std;
+
+// This function fills in a Person message based on user input.
+void PromptForAddress(tutorial::Person* person) {
+  cout << "Enter person ID number: ";
+  int id;
+  cin >> id;
+  person->set_id(id);
+  cin.ignore(256, '\n');
+
+  cout << "Enter name: ";
+  getline(cin, *person->mutable_name());
+
+  cout << "Enter email address (blank for none): ";
+  string email;
+  getline(cin, email);
+  if (!email.empty()) {
+    person->set_email(email);
+  }
+
+  while (true) {
+    cout << "Enter a phone number (or leave blank to finish): ";
+    string number;
+    getline(cin, number);
+    if (number.empty()) {
+      break;
+    }
+
+    tutorial::Person::PhoneNumber* phone_number = person->add_phone();
+    phone_number->set_number(number);
+
+    cout << "Is this a mobile, home, or work phone? ";
+    string type;
+    getline(cin, type);
+    if (type == "mobile") {
+      phone_number->set_type(tutorial::Person::MOBILE);
+    } else if (type == "home") {
+      phone_number->set_type(tutorial::Person::HOME);
+    } else if (type == "work") {
+      phone_number->set_type(tutorial::Person::WORK);
+    } else {
+      cout << "Unknown phone type.  Using default." << endl;
+    }
+  }
+}
+
+// Main function:  Reads the entire address book from a file,
+//   adds one person based on user input, then writes it back out to the same
+//   file.
+int main(int argc, char* argv[]) {
+  // Verify that the version of the library that we linked against is
+  // compatible with the version of the headers we compiled against.
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  if (argc != 2) {
+    cerr << "Usage:  " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
+    return -1;
+  }
+
+  tutorial::AddressBook address_book;
+
+  {
+    // Read the existing address book.
+    fstream input(argv[1], ios::in | ios::binary);
+    if (!input) {
+      cout << argv[1] << ": File not found.  Creating a new file." << endl;
+    } else if (!address_book.ParseFromIstream(&input)) {
+      cerr << "Failed to parse address book." << endl;
+      return -1;
+    }
+  }
+
+  // Add an address.
+  PromptForAddress(address_book.add_person());
+
+  {
+    // Write the new address book back to disk.
+    fstream output(argv[1], ios::out | ios::trunc | ios::binary);
+    if (!address_book.SerializeToOstream(&output)) {
+      cerr << "Failed to write address book." << endl;
+      return -1;
+    }
+  }
+
+  // Optional:  Delete all global objects allocated by libprotobuf.
+  google::protobuf::ShutdownProtobufLibrary();
+
+  return 0;
+}
diff --git a/protobuf/examples/add_person.py b/protobuf/examples/add_person.py
new file mode 100755
index 0000000..78e5696
--- /dev/null
+++ b/protobuf/examples/add_person.py
@@ -0,0 +1,58 @@
+#! /usr/bin/python
+
+# See README.txt for information and build instructions.
+
+import addressbook_pb2
+import sys
+
+# This function fills in a Person message based on user input.
+def PromptForAddress(person):
+  person.id = int(raw_input("Enter person ID number: "))
+  person.name = raw_input("Enter name: ")
+
+  email = raw_input("Enter email address (blank for none): ")
+  if email != "":
+    person.email = email
+
+  while True:
+    number = raw_input("Enter a phone number (or leave blank to finish): ")
+    if number == "":
+      break
+
+    phone_number = person.phone.add()
+    phone_number.number = number
+
+    type = raw_input("Is this a mobile, home, or work phone? ")
+    if type == "mobile":
+      phone_number.type = addressbook_pb2.Person.MOBILE
+    elif type == "home":
+      phone_number.type = addressbook_pb2.Person.HOME
+    elif type == "work":
+      phone_number.type = addressbook_pb2.Person.WORK
+    else:
+      print "Unknown phone type; leaving as default value."
+
+# Main procedure:  Reads the entire address book from a file,
+#   adds one person based on user input, then writes it back out to the same
+#   file.
+if len(sys.argv) != 2:
+  print "Usage:", sys.argv[0], "ADDRESS_BOOK_FILE"
+  sys.exit(-1)
+
+address_book = addressbook_pb2.AddressBook()
+
+# Read the existing address book.
+try:
+  f = open(sys.argv[1], "rb")
+  address_book.ParseFromString(f.read())
+  f.close()
+except IOError:
+  print sys.argv[1] + ": File not found.  Creating a new file."
+
+# Add an address.
+PromptForAddress(address_book.person.add())
+
+# Write the new address book back to disk.
+f = open(sys.argv[1], "wb")
+f.write(address_book.SerializeToString())
+f.close()
diff --git a/protobuf/examples/addressbook.proto b/protobuf/examples/addressbook.proto
new file mode 100644
index 0000000..b14829e
--- /dev/null
+++ b/protobuf/examples/addressbook.proto
@@ -0,0 +1,30 @@
+// See README.txt for information and build instructions.
+
+package tutorial;
+
+option java_package = "com.example.tutorial";
+option java_outer_classname = "AddressBookProtos";
+
+message Person {
+  required string name = 1;
+  required int32 id = 2;        // Unique ID number for this person.
+  optional string email = 3;
+
+  enum PhoneType {
+    MOBILE = 0;
+    HOME = 1;
+    WORK = 2;
+  }
+
+  message PhoneNumber {
+    required string number = 1;
+    optional PhoneType type = 2 [default = HOME];
+  }
+
+  repeated PhoneNumber phone = 4;
+}
+
+// Our address book file is just one of these.
+message AddressBook {
+  repeated Person person = 1;
+}
diff --git a/protobuf/examples/list_people.cc b/protobuf/examples/list_people.cc
new file mode 100644
index 0000000..5363152
--- /dev/null
+++ b/protobuf/examples/list_people.cc
@@ -0,0 +1,68 @@
+// See README.txt for information and build instructions.
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include "addressbook.pb.h"
+using namespace std;
+
+// Iterates though all people in the AddressBook and prints info about them.
+void ListPeople(const tutorial::AddressBook& address_book) {
+  for (int i = 0; i < address_book.person_size(); i++) {
+    const tutorial::Person& person = address_book.person(i);
+
+    cout << "Person ID: " << person.id() << endl;
+    cout << "  Name: " << person.name() << endl;
+    if (person.has_email()) {
+      cout << "  E-mail address: " << person.email() << endl;
+    }
+
+    for (int j = 0; j < person.phone_size(); j++) {
+      const tutorial::Person::PhoneNumber& phone_number = person.phone(j);
+
+      switch (phone_number.type()) {
+        case tutorial::Person::MOBILE:
+          cout << "  Mobile phone #: ";
+          break;
+        case tutorial::Person::HOME:
+          cout << "  Home phone #: ";
+          break;
+        case tutorial::Person::WORK:
+          cout << "  Work phone #: ";
+          break;
+      }
+      cout << phone_number.number() << endl;
+    }
+  }
+}
+
+// Main function:  Reads the entire address book from a file and prints all
+//   the information inside.
+int main(int argc, char* argv[]) {
+  // Verify that the version of the library that we linked against is
+  // compatible with the version of the headers we compiled against.
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  if (argc != 2) {
+    cerr << "Usage:  " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
+    return -1;
+  }
+
+  tutorial::AddressBook address_book;
+
+  {
+    // Read the existing address book.
+    fstream input(argv[1], ios::in | ios::binary);
+    if (!address_book.ParseFromIstream(&input)) {
+      cerr << "Failed to parse address book." << endl;
+      return -1;
+    }
+  }
+
+  ListPeople(address_book);
+
+  // Optional:  Delete all global objects allocated by libprotobuf.
+  google::protobuf::ShutdownProtobufLibrary();
+
+  return 0;
+}
diff --git a/protobuf/examples/list_people.py b/protobuf/examples/list_people.py
new file mode 100755
index 0000000..f9f36b9
--- /dev/null
+++ b/protobuf/examples/list_people.py
@@ -0,0 +1,38 @@
+#! /usr/bin/python
+
+# See README.txt for information and build instructions.
+
+import addressbook_pb2
+import sys
+
+# Iterates though all people in the AddressBook and prints info about them.
+def ListPeople(address_book):
+  for person in address_book.person:
+    print "Person ID:", person.id
+    print "  Name:", person.name
+    if person.HasField('email'):
+      print "  E-mail address:", person.email
+
+    for phone_number in person.phone:
+      if phone_number.type == addressbook_pb2.Person.MOBILE:
+        print "  Mobile phone #:",
+      elif phone_number.type == addressbook_pb2.Person.HOME:
+        print "  Home phone #:",
+      elif phone_number.type == addressbook_pb2.Person.WORK:
+        print "  Work phone #:",
+      print phone_number.number
+
+# Main procedure:  Reads the entire address book from a file and prints all
+#   the information inside.
+if len(sys.argv) != 2:
+  print "Usage:", sys.argv[0], "ADDRESS_BOOK_FILE"
+  sys.exit(-1)
+
+address_book = addressbook_pb2.AddressBook()
+
+# Read the existing address book.
+f = open(sys.argv[1], "rb")
+address_book.ParseFromString(f.read())
+f.close()
+
+ListPeople(address_book)
diff --git a/protobuf/generate_descriptor_proto.sh b/protobuf/generate_descriptor_proto.sh
new file mode 100755
index 0000000..07219dc
--- /dev/null
+++ b/protobuf/generate_descriptor_proto.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# Run this script to regenerate descriptor.pb.{h,cc} after the protocol
+# compiler changes.  Since these files are compiled into the protocol compiler
+# itself, they cannot be generated automatically by a make rule.  "make check"
+# will fail if these files do not match what the protocol compiler would
+# generate.
+#
+# HINT:  Flags passed to generate_descriptor_proto.sh will be passed directly
+#   to make when building protoc.  This is particularly useful for passing
+#   -j4 to run 4 jobs simultaneously.
+
+if test ! -e src/google/protobuf/stubs/common.h; then
+  cat >&2 << __EOF__
+Could not find source code.  Make sure you are running this script from the
+root of the distribution tree.
+__EOF__
+  exit 1
+fi
+
+if test ! -e src/Makefile; then
+  cat >&2 << __EOF__
+Could not find src/Makefile.  You must run ./configure (and perhaps
+./autogen.sh) first.
+__EOF__
+  exit 1
+fi
+
+cd src
+make $@ protoc &&
+  ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:. google/protobuf/descriptor.proto && \
+  ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:. google/protobuf/compiler/plugin.proto
+cd ..
diff --git a/protobuf/gtest/CHANGES b/protobuf/gtest/CHANGES
new file mode 100644
index 0000000..e574415
--- /dev/null
+++ b/protobuf/gtest/CHANGES
@@ -0,0 +1,98 @@
+Changes for 1.5.0:
+
+ * New feature: assertions can be safely called in multiple threads
+   where the pthreads library is available.
+ * New feature: predicates used inside EXPECT_TRUE() and friends
+   can now generate custom failure messages.
+ * New feature: Google Test can now be compiled as a DLL.
+ * New feature: fused source files are included.
+ * New feature: prints help when encountering unrecognized Google Test flags.
+ * Experimental feature: CMake build script (requires CMake 2.6.4+).
+ * Experimental feature: the Pump script for meta programming.
+ * double values streamed to an assertion are printed with enough precision
+   to differentiate any two different values.
+ * Google Test now works on Solaris and AIX.
+ * Build and test script improvements.
+ * Bug fixes and implementation clean-ups.
+
+ Potentially breaking changes:
+
+ * Stopped supporting VC++ 7.1 with exceptions disabled.
+ * Dropped support for 'make install'.
+
+Changes for 1.4.0:
+
+ * New feature: the event listener API
+ * New feature: test shuffling
+ * New feature: the XML report format is closer to junitreport and can
+   be parsed by Hudson now.
+ * New feature: when a test runs under Visual Studio, its failures are
+   integrated in the IDE.
+ * New feature: /MD(d) versions of VC++ projects.
+ * New feature: elapsed time for the tests is printed by default.
+ * New feature: comes with a TR1 tuple implementation such that Boost
+   is no longer needed for Combine().
+ * New feature: EXPECT_DEATH_IF_SUPPORTED macro and friends.
+ * New feature: the Xcode project can now produce static gtest
+   libraries in addition to a framework.
+ * Compatibility fixes for Solaris, Cygwin, minGW, Windows Mobile,
+   Symbian, gcc, and C++Builder.
+ * Bug fixes and implementation clean-ups.
+
+Changes for 1.3.0:
+
+ * New feature: death tests on Windows, Cygwin, and Mac.
+ * New feature: ability to use Google Test assertions in other testing
+   frameworks.
+ * New feature: ability to run disabled test via
+   --gtest_also_run_disabled_tests.
+ * New feature: the --help flag for printing the usage.
+ * New feature: access to Google Test flag values in user code.
+ * New feature: a script that packs Google Test into one .h and one
+   .cc file for easy deployment.
+ * New feature: support for distributing test functions to multiple
+   machines (requires support from the test runner).
+ * Bug fixes and implementation clean-ups.
+
+Changes for 1.2.1:
+
+ * Compatibility fixes for Linux IA-64 and IBM z/OS.
+ * Added support for using Boost and other TR1 implementations.
+ * Changes to the build scripts to support upcoming release of Google C++
+   Mocking Framework.
+ * Added Makefile to the distribution package.
+ * Improved build instructions in README.
+
+Changes for 1.2.0:
+
+ * New feature: value-parameterized tests.
+ * New feature: the ASSERT/EXPECT_(NON)FATAL_FAILURE(_ON_ALL_THREADS)
+   macros.
+ * Changed the XML report format to match JUnit/Ant's.
+ * Added tests to the Xcode project.
+ * Added scons/SConscript for building with SCons.
+ * Added src/gtest-all.cc for building Google Test from a single file.
+ * Fixed compatibility with Solaris and z/OS.
+ * Enabled running Python tests on systems with python 2.3 installed,
+   e.g. Mac OS X 10.4.
+ * Bug fixes.
+
+Changes for 1.1.0:
+
+ * New feature: type-parameterized tests.
+ * New feature: exception assertions.
+ * New feature: printing elapsed time of tests.
+ * Improved the robustness of death tests.
+ * Added an Xcode project and samples.
+ * Adjusted the output format on Windows to be understandable by Visual Studio.
+ * Minor bug fixes.
+
+Changes for 1.0.1:
+
+ * Added project files for Visual Studio 7.1.
+ * Fixed issues with compiling on Mac OS X.
+ * Fixed issues with compiling on Cygwin.
+
+Changes for 1.0.0:
+
+ * Initial Open Source release of Google Test
diff --git a/protobuf/gtest/CMakeLists.txt b/protobuf/gtest/CMakeLists.txt
new file mode 100644
index 0000000..7910b5d
--- /dev/null
+++ b/protobuf/gtest/CMakeLists.txt
@@ -0,0 +1,384 @@
+########################################################################
+# Experimental CMake build script for Google Test.
+#
+# Consider this a prototype.  It will change drastically.  For now,
+# this is only for people on the cutting edge.
+#
+# To run the tests for Google Test itself on Linux, use 'make test' or
+# ctest.  You can select which tests to run using 'ctest -R regex'.
+# For more options, run 'ctest --help'.
+
+# For hermetic builds, we may need to tell CMake to use compiler in a
+# specific location.
+if (gtest_compiler)
+  include(CMakeForceCompiler)
+  cmake_force_c_compiler("${gtest_compiler}" "")
+  cmake_force_cxx_compiler("${gtest_compiler}" "")
+endif()
+
+########################################################################
+#
+# Project-wide settings
+
+# Name of the project.
+#
+# CMake files in this project can refer to the root source directory
+# as ${gtest_SOURCE_DIR} and to the root binary directory as
+# ${gtest_BINARY_DIR}.
+# Language "C" is required for find_package(Threads).
+project(gtest CXX C)
+cmake_minimum_required(VERSION 2.6.4)
+
+if (MSVC)
+  # For MSVC, CMake sets certain flags to defaults we want to override.
+  # This replacement code is taken from sample in the CMake Wiki at
+  # http://www.cmake.org/Wiki/CMake_FAQ#Dynamic_Replace.
+  foreach (flag_var
+           CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
+           CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
+    # In hermetic build environments, tests may not have access to MS runtime
+    # DLLs, so this replaces /MD (CRT libraries in DLLs) with /MT (static CRT
+    # libraries).
+    string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
+    # We prefer more strict warning checking for building Google Test.
+    # Replaces /W3 with /W4 in defaults.
+    string(REPLACE "/W3" "-W4" ${flag_var} "${${flag_var}}")
+  endforeach()
+endif()
+
+# Where gtest's .h files can be found.
+include_directories(
+  ${gtest_SOURCE_DIR}/include
+  ${gtest_SOURCE_DIR})
+
+# Where the gtest libraries can be found.
+link_directories(
+  ${gtest_BINARY_DIR}/src)
+
+# Defines CMAKE_USE_PTHREADS_INIT and CMAKE_THREAD_LIBS_INIT.
+find_package(Threads)
+
+# Defines the compiler/linker flags used to build gtest.  You can
+# tweak these definitions to suit your need.  A variable's value is
+# empty before it's explicitly assigned to.
+
+if (MSVC)
+  # Newlines inside flags variables break CMake's NMake generator.
+  set(cxx_base_flags "-GS -W4 -WX -wd4275 -nologo -J -Zi")
+  set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32")
+  set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN")
+  set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
+  set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0")
+  set(cxx_no_rtti_flags "-GR-")
+elseif (CMAKE_COMPILER_IS_GNUCXX)
+  set(cxx_base_flags "-Wall -Wshadow")
+  set(cxx_exception_flags "-fexceptions")
+  set(cxx_no_exception_flags "-fno-exceptions")
+  # Until version 4.3.2, GCC doesn't define a macro to indicate
+  # whether RTTI is enabled.  Therefore we define GTEST_HAS_RTTI
+  # explicitly.
+  set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
+  set(cxx_strict_flags "-Wextra")
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
+  set(cxx_exception_flags "-features=except")
+  # Sun Pro doesn't provide macros to indicate whether exceptions and
+  # RTTI are enabled, so we define GTEST_HAS_* explicitly.
+  set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0")
+  set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0")
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR
+        CMAKE_CXX_COMPILER_ID STREQUAL "XL")
+  # CMake 2.8 changes Visual Age's compiler ID to "XL".
+  set(cxx_exception_flags "-qeh")
+  set(cxx_no_exception_flags "-qnoeh")
+  # Until version 9.0, Visual Age doesn't define a macro to indicate
+  # whether RTTI is enabled.  Therefore we define GTEST_HAS_RTTI
+  # explicitly.
+  set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0")
+endif()
+
+if (CMAKE_USE_PTHREADS_INIT)  # The pthreads library is available.
+  set(cxx_base_flags "${cxx_base_flags} -DGTEST_HAS_PTHREAD=1")
+endif()
+
+# For building gtest's own tests and samples.
+set(cxx_exception "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_exception_flags}")
+set(cxx_no_exception
+    "${CMAKE_CXX_FLAGS} ${cxx_base_flags} ${cxx_no_exception_flags}")
+set(cxx_default "${cxx_exception}")
+set(cxx_no_rtti "${cxx_default} ${cxx_no_rtti_flags}")
+set(cxx_use_own_tuple "${cxx_default} -DGTEST_USE_OWN_TR1_TUPLE=1")
+
+# For building the gtest libraries.
+set(cxx_strict "${cxx_default} ${cxx_strict_flags}")
+
+########################################################################
+#
+# Defines the gtest & gtest_main libraries.  User tests should link
+# with one of them.
+function(cxx_library_with_type name type cxx_flags)
+  # type can be either STATIC or SHARED to denote a static or shared library.
+  # ARGN refers to additional arguments after 'cxx_flags'.
+  add_library(${name} ${type} ${ARGN})
+  set_target_properties(${name}
+    PROPERTIES
+    COMPILE_FLAGS "${cxx_flags}")
+    if (CMAKE_USE_PTHREADS_INIT)
+      target_link_libraries(${name} ${CMAKE_THREAD_LIBS_INIT})
+    endif()
+endfunction()
+
+function(cxx_static_library name cxx_flags)
+  cxx_library_with_type(${name} STATIC "${cxx_flags}" ${ARGN})
+endfunction()
+
+function(cxx_shared_library name cxx_flags)
+  cxx_library_with_type(${name} SHARED "${cxx_flags}" ${ARGN})
+endfunction()
+
+function(cxx_library name cxx_flags)
+  # TODO(vladl@google.com): Make static/shared a user option.
+  cxx_static_library(${name} "${cxx_flags}" ${ARGN})
+endfunction()
+
+# Static versions of Google Test libraries.  We build them using more
+# strict warnings than what are used for other targets, to ensure that
+# gtest can be compiled by a user aggressive about warnings.
+cxx_static_library(gtest "${cxx_strict}" src/gtest-all.cc)
+cxx_static_library(gtest_main "${cxx_strict}" src/gtest_main.cc)
+target_link_libraries(gtest_main gtest)
+
+########################################################################
+#
+# Samples on how to link user tests with gtest or gtest_main.
+#
+# They are not built by default.  To build them, set the
+# build_gtest_samples option to ON.  You can do it by running ccmake
+# or specifying the -Dbuild_gtest_samples=ON flag when running cmake.
+
+option(build_gtest_samples "Build gtest's sample programs." OFF)
+
+# cxx_executable_with_flags(name cxx_flags lib srcs...)
+#
+# creates a named C++ executable that depends on the given library and
+# is built from the given source files with the given compiler flags.
+function(cxx_executable_with_flags name cxx_flags lib)
+  add_executable(${name} ${ARGN})
+  if (cxx_flags)
+    set_target_properties(${name}
+      PROPERTIES
+      COMPILE_FLAGS "${cxx_flags}")
+  endif()
+  target_link_libraries(${name} ${lib})
+endfunction()
+
+# cxx_executable(name dir lib srcs...)
+#
+# creates a named target that depends on the given lib and is built
+# from the given source files.  dir/name.cc is implicitly included in
+# the source file list.
+function(cxx_executable name dir lib)
+  cxx_executable_with_flags(
+    ${name} "${cxx_default}" ${lib} "${dir}/${name}.cc" ${ARGN})
+endfunction()
+
+if (build_gtest_samples)
+  cxx_executable(sample1_unittest samples gtest_main samples/sample1.cc)
+  cxx_executable(sample2_unittest samples gtest_main samples/sample2.cc)
+  cxx_executable(sample3_unittest samples gtest_main)
+  cxx_executable(sample4_unittest samples gtest_main samples/sample4.cc)
+  cxx_executable(sample5_unittest samples gtest_main samples/sample1.cc)
+  cxx_executable(sample6_unittest samples gtest_main)
+  cxx_executable(sample7_unittest samples gtest_main)
+  cxx_executable(sample8_unittest samples gtest_main)
+  cxx_executable(sample9_unittest samples gtest)
+  cxx_executable(sample10_unittest samples gtest)
+endif()
+
+########################################################################
+#
+# Google Test's own tests.
+#
+# You can skip this section if you aren't interested in testing
+# Google Test itself.
+#
+# Most of the tests are not built by default.  To build them, set the
+# build_all_gtest_tests option to ON.  You can do it by running ccmake
+# or specifying the -Dbuild_all_gtest_tests=ON flag when running cmake.
+
+option(build_all_gtest_tests "Build all of gtest's own tests." OFF)
+
+# This must be set in the root directory for the tests to be run by
+# 'make test' or ctest.
+enable_testing()
+
+# Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE.
+find_package(PythonInterp)
+
+############################################################
+# C++ tests built with standard compiler flags.
+
+# cxx_test_with_flags(name cxx_flags libs srcs...)
+#
+# creates a named C++ test that depends on the given libs and is built
+# from the given source files with the given compiler flags.
+function(cxx_test_with_flags name cxx_flags libs)
+  add_executable(${name} ${ARGN})
+  set_target_properties(${name}
+    PROPERTIES
+    COMPILE_FLAGS "${cxx_flags}")
+  # To support mixing linking in static and dynamic libraries, link each
+  # library in with an extra call to target_link_libraries.
+  foreach (lib "${libs}")
+    target_link_libraries(${name} ${lib})
+  endforeach()
+  add_test(${name} ${name})
+endfunction()
+
+# cxx_test(name libs srcs...)
+#
+# creates a named test target that depends on the given libs and is
+# built from the given source files.  Unlike cxx_test_with_flags,
+# test/name.cc is already implicitly included in the source file list.
+function(cxx_test name libs)
+  cxx_test_with_flags("${name}" "${cxx_default}" "${libs}"
+    "test/${name}.cc" ${ARGN})
+endfunction()
+
+cxx_test(gtest_unittest gtest_main)
+
+if (build_all_gtest_tests)
+  cxx_test(gtest-death-test_test gtest_main)
+  cxx_test(gtest_environment_test gtest)
+  cxx_test(gtest-filepath_test gtest_main)
+  cxx_test(gtest-linked_ptr_test gtest_main)
+  cxx_test(gtest-listener_test gtest_main)
+  cxx_test(gtest_main_unittest gtest_main)
+  cxx_test(gtest-message_test gtest_main)
+  cxx_test(gtest_no_test_unittest gtest)
+  cxx_test(gtest-options_test gtest_main)
+  cxx_test(gtest-param-test_test gtest
+    test/gtest-param-test2_test.cc)
+  cxx_test(gtest-port_test gtest_main)
+  cxx_test(gtest_pred_impl_unittest gtest_main)
+  cxx_test(gtest_prod_test gtest_main
+    test/production.cc)
+  cxx_test(gtest_repeat_test gtest)
+  cxx_test(gtest_sole_header_test gtest_main)
+  cxx_test(gtest_stress_test gtest)
+  cxx_test(gtest-test-part_test gtest_main)
+  cxx_test(gtest_throw_on_failure_ex_test gtest)
+  cxx_test(gtest-typed-test_test gtest_main
+    test/gtest-typed-test2_test.cc)
+  cxx_test(gtest-unittest-api_test gtest)
+endif()
+
+############################################################
+# C++ tests built with non-standard compiler flags.
+
+if (build_all_gtest_tests)
+  cxx_library(gtest_no_exception "${cxx_no_exception}"
+    src/gtest-all.cc)
+  cxx_library(gtest_main_no_rtti "${cxx_no_rtti}"
+    src/gtest-all.cc src/gtest_main.cc)
+
+  cxx_test_with_flags(gtest_no_rtti_unittest "${cxx_no_rtti}"
+    gtest_main_no_rtti test/gtest_unittest.cc)
+
+  set(cxx_use_shared_gtest "${cxx_default} -DGTEST_LINKED_AS_SHARED_LIBRARY=1")
+  set(cxx_build_shared_gtest "${cxx_default} -DGTEST_CREATE_SHARED_LIBRARY=1")
+  if (MSVC)
+    # Disables the "class 'X' needs to have dll-interface to be used
+    # by clients of class 'Y'" warning. This particularly concerns generic
+    # classes like vector that MS doesn't mark as exported.
+    set(cxx_use_shared_gtest "${cxx_use_shared_gtest} -wd4251")
+    set(cxx_build_shared_gtest "${cxx_build_shared_gtest} -wd4251")
+  endif()
+
+  cxx_shared_library(gtest_dll "${cxx_build_shared_gtest}"
+    src/gtest-all.cc)
+
+  # TODO(vladl): This and the next tests may not run in the hermetic
+  # environment on Windows. Re-evaluate and possibly make them
+  # platform-conditional after implementing hermetic builds.
+  cxx_executable_with_flags(gtest_dll_test_ "${cxx_use_shared_gtest}"
+    gtest_dll test/gtest_all_test.cc)
+
+  if (NOT(MSVC AND (MSVC_VERSION EQUAL 1600)))
+    # The C++ Standard specifies tuple_element<int, class>.
+    # Yet MSVC 10's <utility> declares tuple_element<size_t, class>.
+    # That declaration conflicts with our own standard-conforming
+    # tuple implementation.  Therefore using our own tuple with
+    # MSVC 10 doesn't compile.
+    cxx_library(gtest_main_use_own_tuple "${cxx_use_own_tuple}"
+      src/gtest-all.cc src/gtest_main.cc)
+
+    cxx_test_with_flags(gtest-tuple_test "${cxx_use_own_tuple}"
+      gtest_main_use_own_tuple test/gtest-tuple_test.cc)
+
+    cxx_test_with_flags(gtest_use_own_tuple_test "${cxx_use_own_tuple}"
+      gtest_main_use_own_tuple
+      test/gtest-param-test_test.cc test/gtest-param-test2_test.cc)
+  endif()
+
+endif()
+
+############################################################
+# Python tests.
+
+# py_test(name)
+#
+# creates a Python test with the given name whose main module is in
+# test/name.py.  It does nothing if Python is not installed.
+function(py_test name)
+  if (PYTHONINTERP_FOUND)
+    # ${gtest_BINARY_DIR} is known at configuration time, so we can
+    # directly bind it from cmake. ${CTEST_CONFIGURATION_TYPE} is known
+    # only at ctest runtime (by calling ctest -c <Configuration>), so
+    # we have to escape $ to delay variable substitution here.
+    add_test(${name}
+      ${PYTHON_EXECUTABLE} ${gtest_SOURCE_DIR}/test/${name}.py
+          --gtest_build_dir=${gtest_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE})
+  endif()
+endfunction()
+
+if (build_all_gtest_tests)
+  cxx_executable(gtest_break_on_failure_unittest_ test gtest)
+  py_test(gtest_break_on_failure_unittest)
+
+  cxx_executable(gtest_color_test_ test gtest)
+  py_test(gtest_color_test)
+
+  cxx_executable(gtest_env_var_test_ test gtest)
+  py_test(gtest_env_var_test)
+
+  cxx_executable(gtest_filter_unittest_ test gtest)
+  py_test(gtest_filter_unittest)
+
+  cxx_executable(gtest_help_test_ test gtest_main)
+  py_test(gtest_help_test)
+
+  cxx_executable(gtest_list_tests_unittest_ test gtest)
+  py_test(gtest_list_tests_unittest)
+
+  cxx_executable(gtest_output_test_ test gtest)
+  py_test(gtest_output_test)
+
+  cxx_executable(gtest_shuffle_test_ test gtest)
+  py_test(gtest_shuffle_test)
+
+  cxx_executable(gtest_throw_on_failure_test_ test gtest_no_exception)
+  set_target_properties(gtest_throw_on_failure_test_
+    PROPERTIES
+    COMPILE_FLAGS "${cxx_no_exception}")
+  py_test(gtest_throw_on_failure_test)
+
+  cxx_executable(gtest_uninitialized_test_ test gtest)
+  py_test(gtest_uninitialized_test)
+
+  cxx_executable(gtest_xml_outfile1_test_ test gtest_main)
+  cxx_executable(gtest_xml_outfile2_test_ test gtest_main)
+  py_test(gtest_xml_outfiles_test)
+
+  cxx_executable(gtest_xml_output_unittest_ test gtest)
+  py_test(gtest_xml_output_unittest)
+endif()
diff --git a/protobuf/gtest/CONTRIBUTORS b/protobuf/gtest/CONTRIBUTORS
new file mode 100644
index 0000000..0934ae1
--- /dev/null
+++ b/protobuf/gtest/CONTRIBUTORS
@@ -0,0 +1,36 @@
+# 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>
+Balázs Dán <balazs.dan@gmail.com>
+Bharat Mediratta <bharat@menalto.com>
+Chandler Carruth <chandlerc@google.com>
+Chris Prince <cprince@google.com>
+Chris Taylor <taylorc@google.com>
+Dan Egnor <egnor@google.com>
+Eric Roman <eroman@chromium.org>
+Hady Zalek <hady.zalek@gmail.com>
+Jeffrey Yasskin <jyasskin@google.com>
+Jói Sigurðsson <joi@google.com>
+Keir Mierle <mierle@gmail.com>
+Keith Ray <keith.ray@gmail.com>
+Kenton Varda <kenton@google.com>
+Manuel Klimek <klimek@google.com>
+Markus Heule <markus.heule@gmail.com>
+Mika Raento <mikie@iki.fi>
+Miklós Fazekas <mfazekas@szemafor.com>
+Patrick Hanna <phanna@google.com>
+Patrick Riley <pfr@google.com>
+Peter Kaminski <piotrk@google.com>
+Preston Jackson <preston.a.jackson@gmail.com>
+Rainer Klaffenboeck <rainer.klaffenboeck@dynatrace.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>
+Vadim Berman <vadimb@google.com>
+Vlad Losev <vladl@google.com>
+Zhanyong Wan <wan@google.com>
diff --git a/protobuf/gtest/COPYING b/protobuf/gtest/COPYING
new file mode 100644
index 0000000..1941a11
--- /dev/null
+++ b/protobuf/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/protobuf/gtest/Makefile.am b/protobuf/gtest/Makefile.am
new file mode 100644
index 0000000..8d75e32
--- /dev/null
+++ b/protobuf/gtest/Makefile.am
@@ -0,0 +1,284 @@
+# Automake file
+
+# Nonstandard package files for distribution
+EXTRA_DIST = \
+  CHANGES \
+  CONTRIBUTORS \
+  include/gtest/gtest-param-test.h.pump \
+  include/gtest/internal/gtest-tuple.h.pump \
+  include/gtest/internal/gtest-type-util.h.pump \
+  include/gtest/internal/gtest-param-util-generated.h.pump \
+  make/Makefile \
+  scripts/fuse_gtest_files.py \
+  scripts/gen_gtest_pred_impl.py \
+  scripts/pump.py \
+  scripts/test/Makefile
+
+# gtest source files that we don't compile directly.  They are
+# #included by gtest-all.cc.
+GTEST_SRC = \
+  src/gtest.cc \
+  src/gtest-death-test.cc \
+  src/gtest-filepath.cc \
+  src/gtest-internal-inl.h \
+  src/gtest-port.cc \
+  src/gtest-test-part.cc \
+  src/gtest-typed-test.cc
+
+EXTRA_DIST += $(GTEST_SRC)
+
+# Sample files that we don't compile.
+EXTRA_DIST += \
+  samples/prime_tables.h \
+  samples/sample2_unittest.cc \
+  samples/sample3_unittest.cc \
+  samples/sample4_unittest.cc \
+  samples/sample5_unittest.cc \
+  samples/sample6_unittest.cc \
+  samples/sample7_unittest.cc \
+  samples/sample8_unittest.cc \
+  samples/sample9_unittest.cc
+
+# C++ test files that we don't compile directly.
+EXTRA_DIST += \
+  test/gtest-death-test_test.cc \
+  test/gtest_environment_test.cc \
+  test/gtest-filepath_test.cc \
+  test/gtest-linked_ptr_test.cc \
+  test/gtest-message_test.cc \
+  test/gtest_no_test_unittest.cc \
+  test/gtest-options_test.cc \
+  test/gtest-param-test_test.cc \
+  test/gtest-param-test2_test.cc \
+  test/gtest-param-test_test.h \
+  test/gtest-port_test.cc \
+  test/gtest_pred_impl_unittest.cc \
+  test/gtest_prod_test.cc \
+  test/production.cc \
+  test/production.h \
+  test/gtest_repeat_test.cc \
+  test/gtest_sole_header_test.cc \
+  test/gtest_stress_test.cc \
+  test/gtest-test-part_test.cc \
+  test/gtest_throw_on_failure_ex_test.cc \
+  test/gtest-typed-test_test.cc \
+  test/gtest-typed-test2_test.cc \
+  test/gtest-typed-test_test.h \
+  test/gtest_unittest.cc \
+  test/gtest-unittest-api_test.cc \
+  test/gtest-listener_test.cc \
+  test/gtest_main_unittest.cc \
+  test/gtest_unittest.cc \
+  test/gtest-tuple_test.cc \
+  test/gtest-param-test_test.cc \
+  test/gtest-param-test2_test.cc \
+  test/gtest_break_on_failure_unittest_.cc \
+  test/gtest_color_test_.cc \
+  test/gtest_env_var_test_.cc \
+  test/gtest_filter_unittest_.cc \
+  test/gtest_help_test_.cc \
+  test/gtest_list_tests_unittest_.cc \
+  test/gtest_output_test_.cc \
+  test/gtest_shuffle_test_.cc \
+  test/gtest_throw_on_failure_test_.cc \
+  test/gtest_uninitialized_test_.cc \
+  test/gtest_xml_outfile1_test_.cc \
+  test/gtest_xml_outfile2_test_.cc \
+  test/gtest_xml_output_unittest_.cc
+
+# Python tests that we don't run.
+EXTRA_DIST += \
+  test/gtest_test_utils.py \
+  test/gtest_xml_test_utils.py \
+  test/gtest_break_on_failure_unittest.py \
+  test/gtest_color_test.py \
+  test/gtest_env_var_test.py \
+  test/gtest_filter_unittest.py \
+  test/gtest_help_test.py \
+  test/gtest_list_tests_unittest.py \
+  test/gtest_output_test.py \
+  test/gtest_output_test_golden_lin.txt \
+  test/gtest_output_test_golden_win.txt \
+  test/gtest_shuffle_test.py \
+  test/gtest_throw_on_failure_test.py \
+  test/gtest_uninitialized_test.py \
+  test/gtest_xml_outfiles_test.py \
+  test/gtest_xml_output_unittest.py \
+  test/run_tests_util.py \
+  test/run_tests_util_test.py
+
+# CMake script
+EXTRA_DIST += \
+  CMakeLists.txt
+
+# MSVC project files
+EXTRA_DIST += \
+  msvc/gtest-md.sln \
+  msvc/gtest.sln \
+  msvc/gtest-md.vcproj \
+  msvc/gtest.vcproj \
+  msvc/gtest_main-md.vcproj \
+  msvc/gtest_main.vcproj \
+  msvc/gtest_prod_test-md.vcproj \
+  msvc/gtest_prod_test.vcproj \
+  msvc/gtest_unittest-md.vcproj \
+  msvc/gtest_unittest.vcproj
+
+# xcode project files
+EXTRA_DIST += \
+  xcode/Config/DebugProject.xcconfig \
+  xcode/Config/FrameworkTarget.xcconfig \
+  xcode/Config/General.xcconfig \
+  xcode/Config/ReleaseProject.xcconfig \
+  xcode/Config/StaticLibraryTarget.xcconfig \
+  xcode/Config/TestTarget.xcconfig \
+  xcode/Resources/Info.plist \
+  xcode/Scripts/versiongenerate.py \
+  xcode/Scripts/runtests.sh \
+  xcode/gtest.xcodeproj/project.pbxproj
+
+# xcode sample files
+EXTRA_DIST += \
+  xcode/Samples/FrameworkSample/Info.plist \
+  xcode/Samples/FrameworkSample/runtests.sh \
+  xcode/Samples/FrameworkSample/widget_test.cc \
+  xcode/Samples/FrameworkSample/widget.cc \
+  xcode/Samples/FrameworkSample/widget.h \
+  xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
+
+# C++Builder project files
+EXTRA_DIST += \
+  codegear/gtest_all.cc \
+  codegear/gtest_link.cc \
+  codegear/gtest.cbproj \
+  codegear/gtest_main.cbproj \
+  codegear/gtest_unittest.cbproj \
+  codegear/gtest.groupproj
+
+# Scripts and utilities
+bin_SCRIPTS = scripts/gtest-config
+CLEANFILES = $(bin_SCRIPTS)
+
+# Distribute and install M4 macro
+m4datadir = $(datadir)/aclocal
+m4data_DATA = m4/gtest.m4
+EXTRA_DIST += $(m4data_DATA)
+
+# We define the global AM_CPPFLAGS as everything we compile includes from these
+# directories.
+AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include
+
+# Modifies compiler and linker flags for pthreads compatibility.
+if HAVE_PTHREADS
+  AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1
+  AM_LIBS = @PTHREAD_LIBS@
+else
+  AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0
+endif
+
+# Build rules for libraries.
+lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la
+
+lib_libgtest_la_SOURCES = src/gtest-all.cc
+
+pkginclude_HEADERS = include/gtest/gtest.h \
+                     include/gtest/gtest-death-test.h \
+                     include/gtest/gtest-message.h \
+                     include/gtest/gtest-param-test.h \
+                     include/gtest/gtest_pred_impl.h \
+                     include/gtest/gtest_prod.h \
+                     include/gtest/gtest-spi.h \
+                     include/gtest/gtest-test-part.h \
+                     include/gtest/gtest-typed-test.h
+
+pkginclude_internaldir = $(pkgincludedir)/internal
+pkginclude_internal_HEADERS = \
+  include/gtest/internal/gtest-death-test-internal.h \
+  include/gtest/internal/gtest-filepath.h \
+  include/gtest/internal/gtest-internal.h \
+  include/gtest/internal/gtest-linked_ptr.h \
+  include/gtest/internal/gtest-param-util-generated.h \
+  include/gtest/internal/gtest-param-util.h \
+  include/gtest/internal/gtest-port.h \
+  include/gtest/internal/gtest-string.h \
+  include/gtest/internal/gtest-tuple.h \
+  include/gtest/internal/gtest-type-util.h
+
+lib_libgtest_main_la_SOURCES = src/gtest_main.cc
+lib_libgtest_main_la_LIBADD = lib/libgtest.la
+
+# Bulid rules for samples and tests. Automake's naming for some of
+# these variables isn't terribly obvious, so this is a brief
+# reference:
+#
+# TESTS -- Programs run automatically by "make check"
+# check_PROGRAMS -- Programs built by "make check" but not necessarily run
+
+noinst_LTLIBRARIES = samples/libsamples.la
+
+samples_libsamples_la_SOURCES = samples/sample1.cc \
+                                samples/sample1.h \
+                                samples/sample2.cc \
+                                samples/sample2.h \
+                                samples/sample3-inl.h \
+                                samples/sample4.cc \
+                                samples/sample4.h
+
+TESTS=
+TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \
+                    GTEST_BUILD_DIR="$(top_builddir)/test"
+check_PROGRAMS=
+
+# A simple sample on using gtest.
+TESTS += samples/sample1_unittest
+check_PROGRAMS += samples/sample1_unittest
+samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc
+samples_sample1_unittest_LDADD = lib/libgtest_main.la \
+                                 samples/libsamples.la
+
+# Another sample.  It also verifies that libgtest works.
+TESTS += samples/sample10_unittest
+check_PROGRAMS += samples/sample10_unittest
+samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc
+samples_sample10_unittest_LDADD = lib/libgtest.la
+
+# This tests most constructs of gtest and verifies that libgtest_main
+# works.
+TESTS += test/gtest_all_test
+check_PROGRAMS += test/gtest_all_test
+test_gtest_all_test_SOURCES = test/gtest_all_test.cc
+test_gtest_all_test_LDADD = lib/libgtest_main.la
+
+# Tests that fused gtest files compile and work.
+FUSED_GTEST_SRC = \
+  fused-src/gtest/gtest-all.cc \
+  fused-src/gtest/gtest_main.cc \
+  fused-src/gtest/gtest.h
+
+TESTS += test/fused_gtest_test
+check_PROGRAMS += test/fused_gtest_test
+test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \
+                                samples/sample1.cc samples/sample1_unittest.cc
+test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src"
+
+# Build rules for putting fused Google Test files into the distribution
+# package. The user can also create those files by manually running
+# scripts/fuse_gtest_files.py.
+$(test_fused_gtest_test_SOURCES): fused-gtest
+
+fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \
+             $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \
+             scripts/fuse_gtest_files.py
+	mkdir -p "$(srcdir)/fused-src"
+	chmod -R u+w "$(srcdir)/fused-src"
+	rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc"
+	rm -f "$(srcdir)/fused-src/gtest/gtest.h"
+	"$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src"
+	cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/"
+
+maintainer-clean-local:
+	rm -rf "$(srcdir)/fused-src"
+
+# Death tests may produce core dumps in the build directory. In case
+# this happens, clean them to keep distcleancheck happy.
+CLEANFILES += core
diff --git a/protobuf/gtest/Makefile.in b/protobuf/gtest/Makefile.in
new file mode 100644
index 0000000..c62fd54
--- /dev/null
+++ b/protobuf/gtest/Makefile.in
@@ -0,0 +1,1770 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Automake file
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = samples/sample1_unittest$(EXEEXT) \
+	samples/sample10_unittest$(EXEEXT) \
+	test/gtest_all_test$(EXEEXT) test/fused_gtest_test$(EXEEXT)
+check_PROGRAMS = samples/sample1_unittest$(EXEEXT) \
+	samples/sample10_unittest$(EXEEXT) \
+	test/gtest_all_test$(EXEEXT) test/fused_gtest_test$(EXEEXT)
+subdir = .
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(top_srcdir)/build-aux/config.h.in \
+	$(top_srcdir)/scripts/gtest-config.in \
+	$(top_srcdir)/build-aux/depcomp $(pkginclude_HEADERS) \
+	$(pkginclude_internal_HEADERS) \
+	$(top_srcdir)/build-aux/test-driver COPYING README \
+	build-aux/compile build-aux/config.guess build-aux/config.sub \
+	build-aux/depcomp build-aux/install-sh build-aux/missing \
+	build-aux/ltmain.sh $(top_srcdir)/build-aux/compile \
+	$(top_srcdir)/build-aux/config.guess \
+	$(top_srcdir)/build-aux/config.sub \
+	$(top_srcdir)/build-aux/install-sh \
+	$(top_srcdir)/build-aux/ltmain.sh \
+	$(top_srcdir)/build-aux/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/build-aux/config.h
+CONFIG_CLEAN_FILES = scripts/gtest-config
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+	"$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(pkgincludedir)" \
+	"$(DESTDIR)$(pkginclude_internaldir)"
+LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
+lib_libgtest_la_LIBADD =
+am__dirstamp = $(am__leading_dot)dirstamp
+am_lib_libgtest_la_OBJECTS = src/gtest-all.lo
+lib_libgtest_la_OBJECTS = $(am_lib_libgtest_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+lib_libgtest_main_la_DEPENDENCIES = lib/libgtest.la
+am_lib_libgtest_main_la_OBJECTS = src/gtest_main.lo
+lib_libgtest_main_la_OBJECTS = $(am_lib_libgtest_main_la_OBJECTS)
+samples_libsamples_la_LIBADD =
+am_samples_libsamples_la_OBJECTS = samples/sample1.lo \
+	samples/sample2.lo samples/sample4.lo
+samples_libsamples_la_OBJECTS = $(am_samples_libsamples_la_OBJECTS)
+am_samples_sample10_unittest_OBJECTS =  \
+	samples/sample10_unittest.$(OBJEXT)
+samples_sample10_unittest_OBJECTS =  \
+	$(am_samples_sample10_unittest_OBJECTS)
+samples_sample10_unittest_DEPENDENCIES = lib/libgtest.la
+am_samples_sample1_unittest_OBJECTS =  \
+	samples/sample1_unittest.$(OBJEXT)
+samples_sample1_unittest_OBJECTS =  \
+	$(am_samples_sample1_unittest_OBJECTS)
+samples_sample1_unittest_DEPENDENCIES = lib/libgtest_main.la \
+	samples/libsamples.la
+am__objects_1 =  \
+	fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT) \
+	fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT)
+am_test_fused_gtest_test_OBJECTS = $(am__objects_1) \
+	samples/test_fused_gtest_test-sample1.$(OBJEXT) \
+	samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT)
+test_fused_gtest_test_OBJECTS = $(am_test_fused_gtest_test_OBJECTS)
+test_fused_gtest_test_LDADD = $(LDADD)
+am_test_gtest_all_test_OBJECTS = test/gtest_all_test.$(OBJEXT)
+test_gtest_all_test_OBJECTS = $(am_test_gtest_all_test_OBJECTS)
+test_gtest_all_test_DEPENDENCIES = lib/libgtest_main.la
+SCRIPTS = $(bin_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/build-aux
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(lib_libgtest_la_SOURCES) $(lib_libgtest_main_la_SOURCES) \
+	$(samples_libsamples_la_SOURCES) \
+	$(samples_sample10_unittest_SOURCES) \
+	$(samples_sample1_unittest_SOURCES) \
+	$(test_fused_gtest_test_SOURCES) \
+	$(test_gtest_all_test_SOURCES)
+DIST_SOURCES = $(lib_libgtest_la_SOURCES) \
+	$(lib_libgtest_main_la_SOURCES) \
+	$(samples_libsamples_la_SOURCES) \
+	$(samples_sample10_unittest_SOURCES) \
+	$(samples_sample1_unittest_SOURCES) \
+	$(test_fused_gtest_test_SOURCES) \
+	$(test_gtest_all_test_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+DATA = $(m4data_DATA)
+HEADERS = $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+AM_RECURSIVE_TARGETS = cscope check recheck
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2 $(distdir).zip
+GZIP_ENV = --best
+DIST_TARGETS = dist-bzip2 dist-gzip dist-zip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PYTHON = @PYTHON@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+acx_pthread_config = @acx_pthread_config@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Nonstandard package files for distribution
+
+# Sample files that we don't compile.
+
+# C++ test files that we don't compile directly.
+
+# Python tests that we don't run.
+
+# CMake script
+
+# MSVC project files
+
+# xcode project files
+
+# xcode sample files
+
+# C++Builder project files
+EXTRA_DIST = CHANGES CONTRIBUTORS \
+	include/gtest/gtest-param-test.h.pump \
+	include/gtest/internal/gtest-tuple.h.pump \
+	include/gtest/internal/gtest-type-util.h.pump \
+	include/gtest/internal/gtest-param-util-generated.h.pump \
+	make/Makefile scripts/fuse_gtest_files.py \
+	scripts/gen_gtest_pred_impl.py scripts/pump.py \
+	scripts/test/Makefile $(GTEST_SRC) samples/prime_tables.h \
+	samples/sample2_unittest.cc samples/sample3_unittest.cc \
+	samples/sample4_unittest.cc samples/sample5_unittest.cc \
+	samples/sample6_unittest.cc samples/sample7_unittest.cc \
+	samples/sample8_unittest.cc samples/sample9_unittest.cc \
+	test/gtest-death-test_test.cc test/gtest_environment_test.cc \
+	test/gtest-filepath_test.cc test/gtest-linked_ptr_test.cc \
+	test/gtest-message_test.cc test/gtest_no_test_unittest.cc \
+	test/gtest-options_test.cc test/gtest-param-test_test.cc \
+	test/gtest-param-test2_test.cc test/gtest-param-test_test.h \
+	test/gtest-port_test.cc test/gtest_pred_impl_unittest.cc \
+	test/gtest_prod_test.cc test/production.cc test/production.h \
+	test/gtest_repeat_test.cc test/gtest_sole_header_test.cc \
+	test/gtest_stress_test.cc test/gtest-test-part_test.cc \
+	test/gtest_throw_on_failure_ex_test.cc \
+	test/gtest-typed-test_test.cc test/gtest-typed-test2_test.cc \
+	test/gtest-typed-test_test.h test/gtest_unittest.cc \
+	test/gtest-unittest-api_test.cc test/gtest-listener_test.cc \
+	test/gtest_main_unittest.cc test/gtest_unittest.cc \
+	test/gtest-tuple_test.cc test/gtest-param-test_test.cc \
+	test/gtest-param-test2_test.cc \
+	test/gtest_break_on_failure_unittest_.cc \
+	test/gtest_color_test_.cc test/gtest_env_var_test_.cc \
+	test/gtest_filter_unittest_.cc test/gtest_help_test_.cc \
+	test/gtest_list_tests_unittest_.cc test/gtest_output_test_.cc \
+	test/gtest_shuffle_test_.cc \
+	test/gtest_throw_on_failure_test_.cc \
+	test/gtest_uninitialized_test_.cc \
+	test/gtest_xml_outfile1_test_.cc \
+	test/gtest_xml_outfile2_test_.cc \
+	test/gtest_xml_output_unittest_.cc test/gtest_test_utils.py \
+	test/gtest_xml_test_utils.py \
+	test/gtest_break_on_failure_unittest.py \
+	test/gtest_color_test.py test/gtest_env_var_test.py \
+	test/gtest_filter_unittest.py test/gtest_help_test.py \
+	test/gtest_list_tests_unittest.py test/gtest_output_test.py \
+	test/gtest_output_test_golden_lin.txt \
+	test/gtest_output_test_golden_win.txt \
+	test/gtest_shuffle_test.py test/gtest_throw_on_failure_test.py \
+	test/gtest_uninitialized_test.py \
+	test/gtest_xml_outfiles_test.py \
+	test/gtest_xml_output_unittest.py test/run_tests_util.py \
+	test/run_tests_util_test.py CMakeLists.txt msvc/gtest-md.sln \
+	msvc/gtest.sln msvc/gtest-md.vcproj msvc/gtest.vcproj \
+	msvc/gtest_main-md.vcproj msvc/gtest_main.vcproj \
+	msvc/gtest_prod_test-md.vcproj msvc/gtest_prod_test.vcproj \
+	msvc/gtest_unittest-md.vcproj msvc/gtest_unittest.vcproj \
+	xcode/Config/DebugProject.xcconfig \
+	xcode/Config/FrameworkTarget.xcconfig \
+	xcode/Config/General.xcconfig \
+	xcode/Config/ReleaseProject.xcconfig \
+	xcode/Config/StaticLibraryTarget.xcconfig \
+	xcode/Config/TestTarget.xcconfig xcode/Resources/Info.plist \
+	xcode/Scripts/versiongenerate.py xcode/Scripts/runtests.sh \
+	xcode/gtest.xcodeproj/project.pbxproj \
+	xcode/Samples/FrameworkSample/Info.plist \
+	xcode/Samples/FrameworkSample/runtests.sh \
+	xcode/Samples/FrameworkSample/widget_test.cc \
+	xcode/Samples/FrameworkSample/widget.cc \
+	xcode/Samples/FrameworkSample/widget.h \
+	xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj \
+	codegear/gtest_all.cc codegear/gtest_link.cc \
+	codegear/gtest.cbproj codegear/gtest_main.cbproj \
+	codegear/gtest_unittest.cbproj codegear/gtest.groupproj \
+	$(m4data_DATA)
+
+# gtest source files that we don't compile directly.  They are
+# #included by gtest-all.cc.
+GTEST_SRC = \
+  src/gtest.cc \
+  src/gtest-death-test.cc \
+  src/gtest-filepath.cc \
+  src/gtest-internal-inl.h \
+  src/gtest-port.cc \
+  src/gtest-test-part.cc \
+  src/gtest-typed-test.cc
+
+
+# Scripts and utilities
+bin_SCRIPTS = scripts/gtest-config
+
+# Death tests may produce core dumps in the build directory. In case
+# this happens, clean them to keep distcleancheck happy.
+CLEANFILES = $(bin_SCRIPTS) core
+
+# Distribute and install M4 macro
+m4datadir = $(datadir)/aclocal
+m4data_DATA = m4/gtest.m4
+
+# We define the global AM_CPPFLAGS as everything we compile includes from these
+# directories.
+AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/include
+@HAVE_PTHREADS_FALSE@AM_CXXFLAGS = -DGTEST_HAS_PTHREAD=0
+
+# Modifies compiler and linker flags for pthreads compatibility.
+@HAVE_PTHREADS_TRUE@AM_CXXFLAGS = @PTHREAD_CFLAGS@ -DGTEST_HAS_PTHREAD=1
+@HAVE_PTHREADS_TRUE@AM_LIBS = @PTHREAD_LIBS@
+
+# Build rules for libraries.
+lib_LTLIBRARIES = lib/libgtest.la lib/libgtest_main.la
+lib_libgtest_la_SOURCES = src/gtest-all.cc
+pkginclude_HEADERS = include/gtest/gtest.h \
+                     include/gtest/gtest-death-test.h \
+                     include/gtest/gtest-message.h \
+                     include/gtest/gtest-param-test.h \
+                     include/gtest/gtest_pred_impl.h \
+                     include/gtest/gtest_prod.h \
+                     include/gtest/gtest-spi.h \
+                     include/gtest/gtest-test-part.h \
+                     include/gtest/gtest-typed-test.h
+
+pkginclude_internaldir = $(pkgincludedir)/internal
+pkginclude_internal_HEADERS = \
+  include/gtest/internal/gtest-death-test-internal.h \
+  include/gtest/internal/gtest-filepath.h \
+  include/gtest/internal/gtest-internal.h \
+  include/gtest/internal/gtest-linked_ptr.h \
+  include/gtest/internal/gtest-param-util-generated.h \
+  include/gtest/internal/gtest-param-util.h \
+  include/gtest/internal/gtest-port.h \
+  include/gtest/internal/gtest-string.h \
+  include/gtest/internal/gtest-tuple.h \
+  include/gtest/internal/gtest-type-util.h
+
+lib_libgtest_main_la_SOURCES = src/gtest_main.cc
+lib_libgtest_main_la_LIBADD = lib/libgtest.la
+
+# Bulid rules for samples and tests. Automake's naming for some of
+# these variables isn't terribly obvious, so this is a brief
+# reference:
+#
+# TESTS -- Programs run automatically by "make check"
+# check_PROGRAMS -- Programs built by "make check" but not necessarily run
+noinst_LTLIBRARIES = samples/libsamples.la
+samples_libsamples_la_SOURCES = samples/sample1.cc \
+                                samples/sample1.h \
+                                samples/sample2.cc \
+                                samples/sample2.h \
+                                samples/sample3-inl.h \
+                                samples/sample4.cc \
+                                samples/sample4.h
+
+TESTS_ENVIRONMENT = GTEST_SOURCE_DIR="$(srcdir)/test" \
+                    GTEST_BUILD_DIR="$(top_builddir)/test"
+
+samples_sample1_unittest_SOURCES = samples/sample1_unittest.cc
+samples_sample1_unittest_LDADD = lib/libgtest_main.la \
+                                 samples/libsamples.la
+
+samples_sample10_unittest_SOURCES = samples/sample10_unittest.cc
+samples_sample10_unittest_LDADD = lib/libgtest.la
+test_gtest_all_test_SOURCES = test/gtest_all_test.cc
+test_gtest_all_test_LDADD = lib/libgtest_main.la
+
+# Tests that fused gtest files compile and work.
+FUSED_GTEST_SRC = \
+  fused-src/gtest/gtest-all.cc \
+  fused-src/gtest/gtest_main.cc \
+  fused-src/gtest/gtest.h
+
+test_fused_gtest_test_SOURCES = $(FUSED_GTEST_SRC) \
+                                samples/sample1.cc samples/sample1_unittest.cc
+
+test_fused_gtest_test_CPPFLAGS = -I"$(srcdir)/fused-src"
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+am--refresh: Makefile
+	@:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+build-aux/config.h: build-aux/stamp-h1
+	@test -f $@ || rm -f build-aux/stamp-h1
+	@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) build-aux/stamp-h1
+
+build-aux/stamp-h1: $(top_srcdir)/build-aux/config.h.in $(top_builddir)/config.status
+	@rm -f build-aux/stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status build-aux/config.h
+$(top_srcdir)/build-aux/config.h.in:  $(am__configure_deps) 
+	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+	rm -f build-aux/stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f build-aux/config.h build-aux/stamp-h1
+scripts/gtest-config: $(top_builddir)/config.status $(top_srcdir)/scripts/gtest-config.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+	}
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+	done
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+	@list='$(lib_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+src/$(am__dirstamp):
+	@$(MKDIR_P) src
+	@: > src/$(am__dirstamp)
+src/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) src/$(DEPDIR)
+	@: > src/$(DEPDIR)/$(am__dirstamp)
+src/gtest-all.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+lib/$(am__dirstamp):
+	@$(MKDIR_P) lib
+	@: > lib/$(am__dirstamp)
+
+lib/libgtest.la: $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_DEPENDENCIES) $(EXTRA_lib_libgtest_la_DEPENDENCIES) lib/$(am__dirstamp)
+	$(AM_V_CXXLD)$(CXXLINK) -rpath $(libdir) $(lib_libgtest_la_OBJECTS) $(lib_libgtest_la_LIBADD) $(LIBS)
+src/gtest_main.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+
+lib/libgtest_main.la: $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_DEPENDENCIES) $(EXTRA_lib_libgtest_main_la_DEPENDENCIES) lib/$(am__dirstamp)
+	$(AM_V_CXXLD)$(CXXLINK) -rpath $(libdir) $(lib_libgtest_main_la_OBJECTS) $(lib_libgtest_main_la_LIBADD) $(LIBS)
+samples/$(am__dirstamp):
+	@$(MKDIR_P) samples
+	@: > samples/$(am__dirstamp)
+samples/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) samples/$(DEPDIR)
+	@: > samples/$(DEPDIR)/$(am__dirstamp)
+samples/sample1.lo: samples/$(am__dirstamp) \
+	samples/$(DEPDIR)/$(am__dirstamp)
+samples/sample2.lo: samples/$(am__dirstamp) \
+	samples/$(DEPDIR)/$(am__dirstamp)
+samples/sample4.lo: samples/$(am__dirstamp) \
+	samples/$(DEPDIR)/$(am__dirstamp)
+
+samples/libsamples.la: $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_DEPENDENCIES) $(EXTRA_samples_libsamples_la_DEPENDENCIES) samples/$(am__dirstamp)
+	$(AM_V_CXXLD)$(CXXLINK)  $(samples_libsamples_la_OBJECTS) $(samples_libsamples_la_LIBADD) $(LIBS)
+
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+samples/sample10_unittest.$(OBJEXT): samples/$(am__dirstamp) \
+	samples/$(DEPDIR)/$(am__dirstamp)
+
+samples/sample10_unittest$(EXEEXT): $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_DEPENDENCIES) $(EXTRA_samples_sample10_unittest_DEPENDENCIES) samples/$(am__dirstamp)
+	@rm -f samples/sample10_unittest$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(samples_sample10_unittest_OBJECTS) $(samples_sample10_unittest_LDADD) $(LIBS)
+samples/sample1_unittest.$(OBJEXT): samples/$(am__dirstamp) \
+	samples/$(DEPDIR)/$(am__dirstamp)
+
+samples/sample1_unittest$(EXEEXT): $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_DEPENDENCIES) $(EXTRA_samples_sample1_unittest_DEPENDENCIES) samples/$(am__dirstamp)
+	@rm -f samples/sample1_unittest$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(samples_sample1_unittest_OBJECTS) $(samples_sample1_unittest_LDADD) $(LIBS)
+fused-src/gtest/$(am__dirstamp):
+	@$(MKDIR_P) fused-src/gtest
+	@: > fused-src/gtest/$(am__dirstamp)
+fused-src/gtest/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) fused-src/gtest/$(DEPDIR)
+	@: > fused-src/gtest/$(DEPDIR)/$(am__dirstamp)
+fused-src/gtest/test_fused_gtest_test-gtest-all.$(OBJEXT):  \
+	fused-src/gtest/$(am__dirstamp) \
+	fused-src/gtest/$(DEPDIR)/$(am__dirstamp)
+fused-src/gtest/test_fused_gtest_test-gtest_main.$(OBJEXT):  \
+	fused-src/gtest/$(am__dirstamp) \
+	fused-src/gtest/$(DEPDIR)/$(am__dirstamp)
+samples/test_fused_gtest_test-sample1.$(OBJEXT):  \
+	samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp)
+samples/test_fused_gtest_test-sample1_unittest.$(OBJEXT):  \
+	samples/$(am__dirstamp) samples/$(DEPDIR)/$(am__dirstamp)
+test/$(am__dirstamp):
+	@$(MKDIR_P) test
+	@: > test/$(am__dirstamp)
+
+test/fused_gtest_test$(EXEEXT): $(test_fused_gtest_test_OBJECTS) $(test_fused_gtest_test_DEPENDENCIES) $(EXTRA_test_fused_gtest_test_DEPENDENCIES) test/$(am__dirstamp)
+	@rm -f test/fused_gtest_test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_fused_gtest_test_OBJECTS) $(test_fused_gtest_test_LDADD) $(LIBS)
+test/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) test/$(DEPDIR)
+	@: > test/$(DEPDIR)/$(am__dirstamp)
+test/gtest_all_test.$(OBJEXT): test/$(am__dirstamp) \
+	test/$(DEPDIR)/$(am__dirstamp)
+
+test/gtest_all_test$(EXEEXT): $(test_gtest_all_test_OBJECTS) $(test_gtest_all_test_DEPENDENCIES) $(EXTRA_test_gtest_all_test_DEPENDENCIES) test/$(am__dirstamp)
+	@rm -f test/gtest_all_test$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_gtest_all_test_OBJECTS) $(test_gtest_all_test_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n' \
+	    -e 'h;s|.*|.|' \
+	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+	      if (++n[d] == $(am__install_max)) { \
+		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+	    else { print "f", d "/" $$4, $$1 } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	     test -z "$$files" || { \
+	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	     } \
+	; done
+
+uninstall-binSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+	-rm -f fused-src/gtest/*.$(OBJEXT)
+	-rm -f samples/*.$(OBJEXT)
+	-rm -f samples/*.lo
+	-rm -f src/*.$(OBJEXT)
+	-rm -f src/*.lo
+	-rm -f test/*.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample10_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample1_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/sample4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest-all.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gtest_main.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/gtest_all_test.Po@am__quote@
+
+.cc.o:
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+fused-src/gtest/test_fused_gtest_test-gtest-all.o: fused-src/gtest/gtest-all.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest-all.o -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.o `test -f 'fused-src/gtest/gtest-all.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest-all.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='fused-src/gtest/gtest-all.cc' object='fused-src/gtest/test_fused_gtest_test-gtest-all.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.o `test -f 'fused-src/gtest/gtest-all.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest-all.cc
+
+fused-src/gtest/test_fused_gtest_test-gtest-all.obj: fused-src/gtest/gtest-all.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest-all.obj -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.obj `if test -f 'fused-src/gtest/gtest-all.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest-all.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest-all.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='fused-src/gtest/gtest-all.cc' object='fused-src/gtest/test_fused_gtest_test-gtest-all.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest-all.obj `if test -f 'fused-src/gtest/gtest-all.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest-all.cc'; fi`
+
+fused-src/gtest/test_fused_gtest_test-gtest_main.o: fused-src/gtest/gtest_main.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest_main.o -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.o `test -f 'fused-src/gtest/gtest_main.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest_main.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='fused-src/gtest/gtest_main.cc' object='fused-src/gtest/test_fused_gtest_test-gtest_main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.o `test -f 'fused-src/gtest/gtest_main.cc' || echo '$(srcdir)/'`fused-src/gtest/gtest_main.cc
+
+fused-src/gtest/test_fused_gtest_test-gtest_main.obj: fused-src/gtest/gtest_main.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fused-src/gtest/test_fused_gtest_test-gtest_main.obj -MD -MP -MF fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.obj `if test -f 'fused-src/gtest/gtest_main.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest_main.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Tpo fused-src/gtest/$(DEPDIR)/test_fused_gtest_test-gtest_main.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='fused-src/gtest/gtest_main.cc' object='fused-src/gtest/test_fused_gtest_test-gtest_main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fused-src/gtest/test_fused_gtest_test-gtest_main.obj `if test -f 'fused-src/gtest/gtest_main.cc'; then $(CYGPATH_W) 'fused-src/gtest/gtest_main.cc'; else $(CYGPATH_W) '$(srcdir)/fused-src/gtest/gtest_main.cc'; fi`
+
+samples/test_fused_gtest_test-sample1.o: samples/sample1.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1.o -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo -c -o samples/test_fused_gtest_test-sample1.o `test -f 'samples/sample1.cc' || echo '$(srcdir)/'`samples/sample1.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='samples/sample1.cc' object='samples/test_fused_gtest_test-sample1.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1.o `test -f 'samples/sample1.cc' || echo '$(srcdir)/'`samples/sample1.cc
+
+samples/test_fused_gtest_test-sample1.obj: samples/sample1.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1.obj -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo -c -o samples/test_fused_gtest_test-sample1.obj `if test -f 'samples/sample1.cc'; then $(CYGPATH_W) 'samples/sample1.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='samples/sample1.cc' object='samples/test_fused_gtest_test-sample1.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1.obj `if test -f 'samples/sample1.cc'; then $(CYGPATH_W) 'samples/sample1.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1.cc'; fi`
+
+samples/test_fused_gtest_test-sample1_unittest.o: samples/sample1_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1_unittest.o -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo -c -o samples/test_fused_gtest_test-sample1_unittest.o `test -f 'samples/sample1_unittest.cc' || echo '$(srcdir)/'`samples/sample1_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='samples/sample1_unittest.cc' object='samples/test_fused_gtest_test-sample1_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1_unittest.o `test -f 'samples/sample1_unittest.cc' || echo '$(srcdir)/'`samples/sample1_unittest.cc
+
+samples/test_fused_gtest_test-sample1_unittest.obj: samples/sample1_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT samples/test_fused_gtest_test-sample1_unittest.obj -MD -MP -MF samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo -c -o samples/test_fused_gtest_test-sample1_unittest.obj `if test -f 'samples/sample1_unittest.cc'; then $(CYGPATH_W) 'samples/sample1_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Tpo samples/$(DEPDIR)/test_fused_gtest_test-sample1_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='samples/sample1_unittest.cc' object='samples/test_fused_gtest_test-sample1_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_fused_gtest_test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o samples/test_fused_gtest_test-sample1_unittest.obj `if test -f 'samples/sample1_unittest.cc'; then $(CYGPATH_W) 'samples/sample1_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/samples/sample1_unittest.cc'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+	-rm -rf lib/.libs lib/_libs
+	-rm -rf samples/.libs samples/_libs
+	-rm -rf src/.libs src/_libs
+	-rm -rf test/.libs test/_libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-m4dataDATA: $(m4data_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(m4datadir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(m4datadir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(m4datadir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(m4datadir)" || exit $$?; \
+	done
+
+uninstall-m4dataDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir)
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
+	done
+
+uninstall-pkgincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir)
+install-pkginclude_internalHEADERS: $(pkginclude_internal_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(pkginclude_internal_HEADERS)'; test -n "$(pkginclude_internaldir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkginclude_internaldir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkginclude_internaldir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkginclude_internaldir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkginclude_internaldir)" || exit $$?; \
+	done
+
+uninstall-pkginclude_internalHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkginclude_internal_HEADERS)'; test -n "$(pkginclude_internaldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(pkginclude_internaldir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+samples/sample1_unittest.log: samples/sample1_unittest$(EXEEXT)
+	@p='samples/sample1_unittest$(EXEEXT)'; \
+	b='samples/sample1_unittest'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+samples/sample10_unittest.log: samples/sample10_unittest$(EXEEXT)
+	@p='samples/sample10_unittest$(EXEEXT)'; \
+	b='samples/sample10_unittest'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test/gtest_all_test.log: test/gtest_all_test$(EXEEXT)
+	@p='test/gtest_all_test$(EXEEXT)'; \
+	b='test/gtest_all_test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test/fused_gtest_test.log: test/fused_gtest_test$(EXEEXT)
+	@p='test/fused_gtest_test$(EXEEXT)'; \
+	b='test/fused_gtest_test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@	@p='$<'; \
+@am__EXEEXT_TRUE@	$(am__set_b); \
+@am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__post_remove_distdir)
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	    --srcdir=.. --prefix="$$dc_install_base" \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__post_remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(DATA) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkginclude_internaldir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-rm -f fused-src/gtest/$(DEPDIR)/$(am__dirstamp)
+	-rm -f fused-src/gtest/$(am__dirstamp)
+	-rm -f lib/$(am__dirstamp)
+	-rm -f samples/$(DEPDIR)/$(am__dirstamp)
+	-rm -f samples/$(am__dirstamp)
+	-rm -f src/$(DEPDIR)/$(am__dirstamp)
+	-rm -f src/$(am__dirstamp)
+	-rm -f test/$(DEPDIR)/$(am__dirstamp)
+	-rm -f test/$(am__dirstamp)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
+	clean-libtool clean-noinstLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf fused-src/gtest/$(DEPDIR) samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-m4dataDATA install-pkgincludeHEADERS \
+	install-pkginclude_internalHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binSCRIPTS install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -rf fused-src/gtest/$(DEPDIR) samples/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic \
+	maintainer-clean-local
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binSCRIPTS uninstall-libLTLIBRARIES \
+	uninstall-m4dataDATA uninstall-pkgincludeHEADERS \
+	uninstall-pkginclude_internalHEADERS
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \
+	check-am clean clean-checkPROGRAMS clean-cscope clean-generic \
+	clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
+	cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
+	dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
+	distcheck distclean distclean-compile distclean-generic \
+	distclean-hdr distclean-libtool distclean-tags distcleancheck \
+	distdir distuninstallcheck dvi dvi-am html html-am info \
+	info-am install install-am install-binSCRIPTS install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-libLTLIBRARIES install-m4dataDATA \
+	install-man install-pdf install-pdf-am \
+	install-pkgincludeHEADERS install-pkginclude_internalHEADERS \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic maintainer-clean-local mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+	uninstall-am uninstall-binSCRIPTS uninstall-libLTLIBRARIES \
+	uninstall-m4dataDATA uninstall-pkgincludeHEADERS \
+	uninstall-pkginclude_internalHEADERS
+
+
+# Build rules for putting fused Google Test files into the distribution
+# package. The user can also create those files by manually running
+# scripts/fuse_gtest_files.py.
+$(test_fused_gtest_test_SOURCES): fused-gtest
+
+fused-gtest: $(pkginclude_HEADERS) $(pkginclude_internal_HEADERS) \
+             $(GTEST_SRC) src/gtest-all.cc src/gtest_main.cc \
+             scripts/fuse_gtest_files.py
+	mkdir -p "$(srcdir)/fused-src"
+	chmod -R u+w "$(srcdir)/fused-src"
+	rm -f "$(srcdir)/fused-src/gtest/gtest-all.cc"
+	rm -f "$(srcdir)/fused-src/gtest/gtest.h"
+	"$(srcdir)/scripts/fuse_gtest_files.py" "$(srcdir)/fused-src"
+	cp -f "$(srcdir)/src/gtest_main.cc" "$(srcdir)/fused-src/gtest/"
+
+maintainer-clean-local:
+	rm -rf "$(srcdir)/fused-src"
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/protobuf/gtest/README b/protobuf/gtest/README
new file mode 100644
index 0000000..ec61190
--- /dev/null
+++ b/protobuf/gtest/README
@@ -0,0 +1,417 @@
+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, Symbian, etc).  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 the
+mailing list for questions, discussions, and development.  There is
+also an IRC channel on OFTC (irc.oftc.net) #gtest available.  Please
+join us!
+
+Requirements for End Users
+--------------------------
+
+Google Test is designed to have fairly minimal requirements to build
+and use with your projects, but there are some.  Currently, we support
+Linux, Windows, Mac OS X, and Cygwin.  We will also make our best
+effort to support other platforms (e.g. Solaris, AIX, and z/OS).
+However, since core members of the Google Test project have no access
+to these platforms, Google Test may have outstanding issues there.  If
+you notice any problems on your platform, please notify
+googletestframework@googlegroups.com.  Patches for fixing them are
+even more welcome!
+
+### 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-standard-compliant compiler
+
+### Windows Requirements ###
+
+  * Microsoft Visual C++ 7.1 or newer
+
+### Cygwin Requirements ###
+
+  * Cygwin 1.5.25-14 or newer
+
+### Mac OS X Requirements ###
+
+  * Mac OS X 10.4 Tiger or newer
+  * Developer Tools Installed
+
+Also, you'll need CMake 2.6.4 or higher if you want to build the
+samples using the provided CMake script, regardless of the platform.
+
+Requirements for Contributors
+-----------------------------
+
+We welcome patches.  If you plan to contribute a patch, you need to
+build Google Test and its own tests from an SVN checkout (described
+below), which has further requirements:
+
+  * Python version 2.3 or newer (for running some of the tests and
+    re-generating certain source files from templates)
+  * CMake 2.6.4 or newer
+
+Getting the Source
+------------------
+
+There are two primary ways of getting Google Test's source code: you
+can download a stable source release in your preferred archive format,
+or directly check out the source from our Subversion (SVN) repositary.
+The SVN checkout requires a few extra steps and some extra software
+packages on your system, but lets you track the latest development and
+make patches much more easily, so we highly encourage it.
+
+### Source Package ###
+
+Google Test is released in versioned source packages which can be
+downloaded from the 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] http://code.google.com/p/googletest/downloads/list
+
+Once the package is downloaded, expand it using whichever tools you
+prefer for that type.  This will result in a new directory with the
+name "gtest-X.Y.Z" which contains all of the source code.  Here are
+some examples on Linux:
+
+  tar -xvzf gtest-X.Y.Z.tar.gz
+  tar -xvjf gtest-X.Y.Z.tar.bz2
+  unzip gtest-X.Y.Z.zip
+
+### SVN Checkout ###
+
+To check out the main branch (also known as the "trunk") of Google
+Test, run the following Subversion command:
+
+  svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn
+
+Setting up the Build
+--------------------
+
+To build Google Test and your tests that use it, you need to tell your
+build system where to find its headers and source files.  The exact
+way to do it depends on which build system you use, and is usually
+straightforward.
+
+### Generic Build Instructions ###
+
+Suppose you put Google Test in directory ${GTEST_DIR}.  To build it,
+create a library build target (or a project as called by Visual Studio
+and Xcode) to compile
+
+  ${GTEST_DIR}/src/gtest-all.cc
+
+with
+
+  ${GTEST_DIR}/include and ${GTEST_DIR}
+
+in the header search path.  Assuming a Linux-like system and gcc,
+something like the following will do:
+
+  g++ -I${GTEST_DIR}/include -I${GTEST_DIR} -c ${GTEST_DIR}/src/gtest-all.cc
+  ar -rv libgtest.a gtest-all.o
+
+Next, you should compile your test source file with
+${GTEST_DIR}/include in the header search path, and link it with gtest
+and any other necessary libraries:
+
+  g++ -I${GTEST_DIR}/include path/to/your_test.cc libgtest.a -o your_test
+
+As an example, the make/ directory contains a Makefile that you can
+use to build Google Test on systems where GNU make is available
+(e.g. Linux, Mac OS X, and Cygwin).  It doesn't try to build Google
+Test's own tests.  Instead, it just builds the Google Test library and
+a sample test.  You can use it as a starting point for your own build
+script.
+
+If the default settings are correct for your environment, the
+following commands should succeed:
+
+  cd ${GTEST_DIR}/make
+  make
+  ./sample1_unittest
+
+If you see errors, try to tweak the contents of make/Makefile to make
+them go away.  There are instructions in make/Makefile on how to do
+it.
+
+### Using CMake ###
+
+Google Test comes with a CMake build script (CMakeLists.txt) that can
+be used on a wide range of platforms ("C" stands for cross-platofrm.).
+If you don't have CMake installed already, you can download it for
+free from http://www.cmake.org/.
+
+CMake works by generating native makefiles or build projects that can
+be used in the compiler environment of your choice.  The typical
+workflow starts with:
+
+  mkdir mybuild       # Create a directory to hold the build output.
+  cd mybuild
+  cmake ${GTEST_DIR}  # Generate native build scripts.
+
+If you want to build Google Test's samples, you should replace the
+last command with
+
+  cmake -Dbuild_gtest_samples=ON ${GTEST_DIR}
+
+If you are on a *nix system, you should now see a Makefile in the
+current directory.  Just type 'make' to build gtest.
+
+If you use Windows and have Vistual Studio installed, a gtest.sln file
+and several .vcproj files will be created.  You can then build them
+using Visual Studio.
+
+On Mac OS X with Xcode installed, a .xcodeproj file will be generated.
+
+### Legacy Build Scripts ###
+
+Before settling on CMake, we have been providing hand-maintained build
+projects/scripts for Visual Studio, Xcode, and Autotools.  While we
+continue to provide them for convenience, they are not actively
+maintained any more.  We highly recommend that you follow the
+instructions in the previous two sections to integrate Google Test
+with your existing build system.
+
+If you still need to use the legacy build scripts, here's how:
+
+The msvc\ folder contains two solutions with Visual C++ projects.
+Open the gtest.sln or gtest-md.sln file using Visual Studio, and you
+are ready to build Google Test the same way you build any Visual
+Studio project.  Files that have names ending with -md use DLL
+versions of Microsoft runtime libraries (the /MD or the /MDd compiler
+option).  Files without that suffix use static versions of the runtime
+libraries (the /MT or the /MTd option).  Please note that one must use
+the same option to compile both gtest and the test code.  If you use
+Visual Studio 2005 or above, we recommend the -md version as /MD is
+the default for new projects in these versions of Visual Studio.
+
+On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using
+Xcode.  Build the "gtest" target.  The universal binary framework will
+end up in your selected build directory (selected in the Xcode
+"Preferences..." -> "Building" pane and defaults to xcode/build).
+Alternatively, at the command line, enter:
+
+  xcodebuild
+
+This will build the "Release" configuration of gtest.framework in your
+default build location.  See the "xcodebuild" man page for more
+information about building different configurations and building in
+different locations.
+
+Tweaking Google Test
+--------------------
+
+Google Test can be used in diverse environments.  The default
+configuration may not work (or may not work well) out of the box in
+some environments.  However, you can easily tweak Google Test by
+defining control macros on the compiler command line.  Generally,
+these macros are named like GTEST_XYZ and you define them to either 1
+or 0 to enable or disable a certain feature.
+
+We list the most frequently used macros below.  For a complete list,
+see file include/gtest/internal/gtest-port.h.
+
+### Choosing a TR1 Tuple Library ###
+
+Some Google Test features require the C++ Technical Report 1 (TR1)
+tuple library, which is not yet available with all compilers.  The
+good news is that Google Test implements a subset of TR1 tuple that's
+enough for its own need, and will automatically use this when the
+compiler doesn't provide TR1 tuple.
+
+Usually you don't need to care about which tuple library Google Test
+uses.  However, if your project already uses TR1 tuple, you need to
+tell Google Test to use the same TR1 tuple library the rest of your
+project uses, or the two tuple implementations will clash.  To do
+that, add
+
+  -DGTEST_USE_OWN_TR1_TUPLE=0
+
+to the compiler flags while compiling Google Test and your tests.  If
+you want to force Google Test to use its own tuple library, just add
+
+  -DGTEST_USE_OWN_TR1_TUPLE=1
+
+to the compiler flags instead.
+
+If you don't want Google Test to use tuple at all, add
+
+  -DGTEST_HAS_TR1_TUPLE=0
+
+and all features using tuple will be disabled.
+
+### Multi-threaded Tests ###
+
+Google Test is thread-safe where the pthread library is available.
+After #include <gtest/gtest.h>, you can check the GTEST_IS_THREADSAFE
+macro to see whether this is the case (yes if the macro is #defined to
+1, no if it's undefined.).
+
+If Google Test doesn't correctly detect whether pthread is available
+in your environment, you can force it with
+
+  -DGTEST_HAS_PTHREAD=1
+
+or
+
+  -DGTEST_HAS_PTHREAD=0
+
+When Google Test uses pthread, you may need to add flags to your
+compiler and/or linker to select the pthread library, or you'll get
+link errors.  If you use the CMake script or the deprecated Autotools
+script, this is taken care of for you.  If you use your own build
+script, you'll need to read your compiler and linker's manual to
+figure out what flags to add.
+
+### As a Shared Library (DLL) ###
+
+Google Test is compact, so most users can build and link it as a
+static library for the simplicity.  You can choose to use Google Test
+as a shared library (known as a DLL on Windows) if you prefer.
+
+To compile gtest as a shared library, add
+
+  -DGTEST_CREATE_SHARED_LIBRARY=1
+
+to the compiler flags.  You'll also need to tell the linker to produce
+a shared library instead - consult your linker's manual for how to do
+it.
+
+To compile your tests that use the gtest shared library, add
+
+  -DGTEST_LINKED_AS_SHARED_LIBRARY=1
+
+to the compiler flags.
+
+### Avoiding Macro Name Clashes ###
+
+In C++, macros don't obey namespaces.  Therefore two libraries that
+both define a macro of the same name will clash if you #include both
+definitions.  In case a Google Test macro clashes with another
+library, you can force Google Test to rename its macro to avoid the
+conflict.
+
+Specifically, if both Google Test and some other code define macro
+FOO, you can add
+
+  -DGTEST_DONT_DEFINE_FOO=1
+
+to the compiler flags to tell Google Test to change the macro's name
+from FOO to GTEST_FOO.  Currently FOO can be FAIL, SUCCEED, or TEST.
+For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write
+
+  GTEST_TEST(SomeTest, DoesThis) { ... }
+
+instead of
+
+  TEST(SomeTest, DoesThis) { ... }
+
+in order to define a test.
+
+Upgrating from an Earlier Version
+---------------------------------
+
+We strive to keep Google Test releases backward compatible.
+Sometimes, though, we have to make some breaking changes for the
+users' long-term benefits.  This section describes what you'll need to
+do if you are upgrading from an earlier version of Google Test.
+
+### Upgrading from 1.3.0 or Earlier ###
+
+You may need to explicitly enable or disable Google Test's own TR1
+tuple library.  See the instructions in section "Choosing a TR1 Tuple
+Library".
+
+### Upgrading from 1.4.0 or Earlier ###
+
+The Autotools build script (configure + make) is no longer officially
+supportted.  You are encouraged to migrate to your own build system or
+use CMake.  If you still need to use Autotools, you can find
+instructions in the README file from Google Test 1.4.0.
+
+On platforms where the pthread library is available, Google Test uses
+it in order to be thread-safe.  See the "Multi-threaded Tests" section
+for what this means to your build script.
+
+If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google
+Test will no longer compile.  This should affect very few people, as a
+large portion of STL (including <string>) doesn't compile in this mode
+anyway.  We decided to stop supporting it in order to greatly simplify
+Google Test's implementation.
+
+Developing Google Test
+----------------------
+
+This section discusses how to make your own changes to Google Test.
+
+### Testing Google Test Itself ###
+
+To make sure your changes work as intended and don't break existing
+functionality, you'll want to compile and run Google Test's own tests.
+For that you can use CMake:
+
+  mkdir mybuild
+  cd mybuild
+  cmake -Dbuild_all_gtest_tests=ON ${GTEST_DIR}
+
+Make sure you have Python installed, as some of Google Test's tests
+are written in Python.  If the cmake command complains about not being
+able to find Python ("Could NOT find PythonInterp (missing:
+PYTHON_EXECUTABLE)"), try telling it explicitly where your Python
+executable can be found:
+
+  cmake -DPYTHON_EXECUTABLE=path/to/python -Dbuild_all_gtest_tests=ON \
+      ${GTEST_DIR}
+
+Next, you can build Google Test and all of its own tests.  On *nix,
+this is usually done by 'make'.  To run the tests, do
+
+  make test
+
+All tests should pass.
+
+### Regenerating Source Files ###
+
+Some of Google Test's source files are generated from templates (not
+in the C++ sense) using a script.  A template file is named FOO.pump,
+where FOO is the name of the file it will generate.  For example, the
+file include/gtest/internal/gtest-type-util.h.pump is used to generate
+gtest-type-util.h in the same directory.
+
+Normally you don't need to worry about regenerating the source files,
+unless you need to modify them.  In that case, you should modify the
+corresponding .pump files instead and run the pump.py Python script to
+regenerate them.  You can find pump.py in the scripts/ directory.
+Read the Pump manual [2] for how to use it.
+
+  [2] http://code.google.com/p/googletest/wiki/PumpManual
+
+### Contributing a Patch ###
+
+We welcome patches.  Please read the Google Test developer's guide [3]
+for how you can contribute.  In particular, make sure you have signed
+the Contributor License Agreement, or we won't be able to accept the
+patch.
+
+  [3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide
+
+Happy testing!
diff --git a/protobuf/gtest/aclocal.m4 b/protobuf/gtest/aclocal.m4
new file mode 100644
index 0000000..bed39b9
--- /dev/null
+++ b/protobuf/gtest/aclocal.m4
@@ -0,0 +1,9986 @@
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 57 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    _LT_PATH_MAGIC
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable.  If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins.  After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script.  The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+  -h, --help      print this help, then exit
+  -V, --version   print version number, then exit
+  -q, --quiet     do not print progress messages
+  -d, --debug     don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
+
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test "$silent" = yes &&
+  lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+  _LT_PROG_LTMAIN
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  _LT_PROG_REPLACE_SHELLFNS
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Go],			[_LT_LANG(GO)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_GO.  When it is available in    #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC],     [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+  fi
+fi
+if test -z "$GOC"; then
+  AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+  [LT_LANG(GO)],
+  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS="$save_LDFLAGS"
+    ])
+
+    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+      [lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+  else
+    _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  fi
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    m4_if([$1], [CXX],
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+  lt_aix_libpath_sed='[
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }]'
+  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi],[])
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+  fi
+  ])
+  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*" 
+}
+
+case "$ECHO" in
+  printf*) AC_MSG_RESULT([printf]) ;;
+  print*) AC_MSG_RESULT([print -r]) ;;
+  *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+  test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test "X`printf %s $ECHO`" = "X$ECHO" \
+      || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[  --with-sysroot[=DIR] Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted.  We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   AC_MSG_RESULT([${with_sysroot}])
+   AC_MSG_ERROR([The sysroot must be an absolute path.])
+   ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    case `/usr/bin/file conftest.o` in
+	      *x86-64*)
+		LD="${LD-ld} -m elf32_x86_64"
+		;;
+	      *)
+		LD="${LD-ld} -m elf_i386"
+		;;
+	    esac
+	    ;;
+	  powerpc64le-*)
+	    LD="${LD-ld} -m elf32lppclinux"
+	    ;;
+	  powerpc64-*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  powerpcle-*)
+	    LD="${LD-ld} -m elf64lppc"
+	    ;;
+	  powerpc-*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+  [lt_cv_ar_at_file=no
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+     [echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([lt_ar_try])
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	AC_TRY_EVAL([lt_ar_try])
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+     ])
+  ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+  [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+    [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len" && \
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[[4-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+m4_if([$1], [],[
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[23]].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+    [lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+	 LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+      [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+	 [lt_cv_shlibpath_overrides_runpath=yes])])
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+    ])
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+    [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+    [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+    [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+  AC_SUBST([DUMPBIN])
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+    [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+  [lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+  esac
+
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT@&t@_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT@&t@_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+    [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      mingw* | cygwin* | os2* | pw32* | cegcc*)
+	# This hack is so that the source file can tell whether it is being
+	# built for inclusion in a dll (and should export symbols for example).
+	m4_if([$1], [GCJ], [],
+	  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd* | netbsdelf*-gnu)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+      if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+      fi
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+        *Intel*\ [[CF]]*Compiler*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	  ;;
+	*Portland\ Group*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      ;;
+    esac
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+	  *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    haiku*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix[[4-9]]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	_LT_TAGVAR(link_all_deplibs, $1)=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX([$1])
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX([$1])
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  fi
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	_LT_TAGVAR(always_export_symbols, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	# FIXME: Should let the user specify the lib program.
+	_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
+
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	m4_if($1, [], [
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  _LT_LINKER_OPTION([if $CC understands -b],
+	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+	  [lt_cv_irix_exported_symbol],
+	  [save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+	   AC_LINK_IFELSE(
+	     [AC_LANG_SOURCE(
+	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+			      [C++], [[int foo (void) { return 0; }]],
+			      [Fortran 77], [[
+      subroutine foo
+      end]],
+			      [Fortran], [[
+      subroutine foo
+      end]])])],
+	      [lt_cv_irix_exported_symbol=yes],
+	      [lt_cv_irix_exported_symbol=no])
+           LDFLAGS="$save_LDFLAGS"])
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+	[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+	[$RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	  pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+	  _LT_TAGVAR(allow_undefined_flag, $1)=
+	  if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+	  then
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	  else
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  fi
+	  _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+	])
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+    [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report which library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[[4-9]]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  AC_MSG_RESULT([$enable_shared])
+
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
+
+  _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+      LT_PATH_LD
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+      aix[[4-9]]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX([$1])
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX([$1])
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    fi
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=yes
+	  _LT_TAGVAR(file_list_spec, $1)='@'
+	  # Tell ltmain to make .lib files, not .a files.
+	  libext=lib
+	  # Tell ltmain to make .dll files, not .so files.
+	  shrext_cmds=".dll"
+	  # FIXME: Setting linknames here is a bad hack.
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	  # Don't use ranlib
+	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=no
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      haiku*)
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+	    ;;
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='func_echo_all'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+	      '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+	      '"$_LT_TAGVAR(reload_cmds, $1)"
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
+
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case ${prev}${p} in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
+	 -L | -R)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${F77-"f77"}
+  CFLAGS=$FFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+  CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+  _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${FC-"f95"}
+  CFLAGS=$FCFLAGS
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
+
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([	 ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary parameter first.
+    func_stripname_result=${3}
+    func_stripname_result=${func_stripname_result#"${1}"}
+    func_stripname_result=${func_stripname_result%"${2}"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+    case ${1} in
+      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+      *)    func_lo2o_result=${1} ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
+
+  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
+
+  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+    func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+         [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+         [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
+
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+#   Inc.
+#   Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+        _LT_MANGLE_DEFUN([$1], [$2]),
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+		      [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME.  If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+    [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+  dnl
+  dnl Simply set some default values (i.e off) if boolean options were not
+  dnl specified:
+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+  ])
+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+  ])
+  dnl
+  dnl If no reference was made to various pairs of opposing options, then
+  dnl we run the default mode handler for the pair.  For example, if neither
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
+  dnl archives by default:
+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+  		   [_LT_ENABLE_FAST_INSTALL])
+  ])
+])# _LT_SET_OPTIONS
+
+
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS],      [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+    _LT_DECL([build_libtool_libs], [enable_shared], [0],
+	[Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+    _LT_DECL([build_old_libs], [enable_static], [0],
+	[Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+	 [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+    [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+		 [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+		 [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+		 [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+		 [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+		 [m4_define([_LTDL_TYPE], [convenience])])
+
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
+
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
+
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
+
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.14'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.14.1], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'.  In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+      [$1], [UPC],  [depcc="$UPC"  am_compiler_list=],
+      [$1], [GCJ],  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                    [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+  m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES([CC])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+  fi
+fi])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# ---------------------------------------------------------------------------
+# Adds support for distributing Python modules and packages.  To
+# install modules, copy them to $(pythondir), using the python_PYTHON
+# automake variable.  To install a package with the same name as the
+# automake package, install to $(pkgpythondir), or use the
+# pkgpython_PYTHON automake variable.
+#
+# The variables $(pyexecdir) and $(pkgpyexecdir) are provided as
+# locations to install python extension modules (shared libraries).
+# Another macro is required to find the appropriate flags to compile
+# extension modules.
+#
+# If your package is configured with a different prefix to python,
+# users will have to add the install directory to the PYTHONPATH
+# environment variable, or create a .pth file (see the python
+# documentation for details).
+#
+# If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will
+# cause an error if the version of python installed on the system
+# doesn't meet the requirement.  MINIMUM-VERSION should consist of
+# numbers and dots only.
+AC_DEFUN([AM_PATH_PYTHON],
+ [
+  dnl Find a Python interpreter.  Python versions prior to 2.0 are not
+  dnl supported. (2.0 was released on October 16, 2000).
+  m4_define_default([_AM_PYTHON_INTERPRETER_LIST],
+[python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl
+ python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0])
+
+  AC_ARG_VAR([PYTHON], [the Python interpreter])
+
+  m4_if([$1],[],[
+    dnl No version check is needed.
+    # Find any Python interpreter.
+    if test -z "$PYTHON"; then
+      AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :)
+    fi
+    am_display_PYTHON=python
+  ], [
+    dnl A version check is needed.
+    if test -n "$PYTHON"; then
+      # If the user set $PYTHON, use it and don't search something else.
+      AC_MSG_CHECKING([whether $PYTHON version is >= $1])
+      AM_PYTHON_CHECK_VERSION([$PYTHON], [$1],
+			      [AC_MSG_RESULT([yes])],
+			      [AC_MSG_RESULT([no])
+			       AC_MSG_ERROR([Python interpreter is too old])])
+      am_display_PYTHON=$PYTHON
+    else
+      # Otherwise, try each interpreter until we find one that satisfies
+      # VERSION.
+      AC_CACHE_CHECK([for a Python interpreter with version >= $1],
+	[am_cv_pathless_PYTHON],[
+	for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do
+	  test "$am_cv_pathless_PYTHON" = none && break
+	  AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break])
+	done])
+      # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON.
+      if test "$am_cv_pathless_PYTHON" = none; then
+	PYTHON=:
+      else
+        AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON])
+      fi
+      am_display_PYTHON=$am_cv_pathless_PYTHON
+    fi
+  ])
+
+  if test "$PYTHON" = :; then
+  dnl Run any user-specified action, or abort.
+    m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])])
+  else
+
+  dnl Query Python for its version number.  Getting [:3] seems to be
+  dnl the best way to do this; it's what "site.py" does in the standard
+  dnl library.
+
+  AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version],
+    [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`])
+  AC_SUBST([PYTHON_VERSION], [$am_cv_python_version])
+
+  dnl Use the values of $prefix and $exec_prefix for the corresponding
+  dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX.  These are made
+  dnl distinct variables so they can be overridden if need be.  However,
+  dnl general consensus is that you shouldn't need this ability.
+
+  AC_SUBST([PYTHON_PREFIX], ['${prefix}'])
+  AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}'])
+
+  dnl At times (like when building shared libraries) you may want
+  dnl to know which OS platform Python thinks this is.
+
+  AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform],
+    [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`])
+  AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform])
+
+  # Just factor out some code duplication.
+  am_python_setup_sysconfig="\
+import sys
+# Prefer sysconfig over distutils.sysconfig, for better compatibility
+# with python 3.x.  See automake bug#10227.
+try:
+    import sysconfig
+except ImportError:
+    can_use_sysconfig = 0
+else:
+    can_use_sysconfig = 1
+# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs:
+# <https://github.com/pypa/virtualenv/issues/118>
+try:
+    from platform import python_implementation
+    if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7':
+        can_use_sysconfig = 0
+except ImportError:
+    pass"
+
+  dnl Set up 4 directories:
+
+  dnl pythondir -- where to install python scripts.  This is the
+  dnl   site-packages directory, not the python standard library
+  dnl   directory like in previous automake betas.  This behavior
+  dnl   is more consistent with lispdir.m4 for example.
+  dnl Query distutils for this directory.
+  AC_CACHE_CHECK([for $am_display_PYTHON script directory],
+    [am_cv_python_pythondir],
+    [if test "x$prefix" = xNONE
+     then
+       am_py_prefix=$ac_default_prefix
+     else
+       am_py_prefix=$prefix
+     fi
+     am_cv_python_pythondir=`$PYTHON -c "
+$am_python_setup_sysconfig
+if can_use_sysconfig:
+    sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'})
+else:
+    from distutils import sysconfig
+    sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix')
+sys.stdout.write(sitedir)"`
+     case $am_cv_python_pythondir in
+     $am_py_prefix*)
+       am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'`
+       am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"`
+       ;;
+     *)
+       case $am_py_prefix in
+         /usr|/System*) ;;
+         *)
+	  am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages
+	  ;;
+       esac
+       ;;
+     esac
+    ])
+  AC_SUBST([pythondir], [$am_cv_python_pythondir])
+
+  dnl pkgpythondir -- $PACKAGE directory under pythondir.  Was
+  dnl   PYTHON_SITE_PACKAGE in previous betas, but this naming is
+  dnl   more consistent with the rest of automake.
+
+  AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE])
+
+  dnl pyexecdir -- directory for installing python extension modules
+  dnl   (shared libraries)
+  dnl Query distutils for this directory.
+  AC_CACHE_CHECK([for $am_display_PYTHON extension module directory],
+    [am_cv_python_pyexecdir],
+    [if test "x$exec_prefix" = xNONE
+     then
+       am_py_exec_prefix=$am_py_prefix
+     else
+       am_py_exec_prefix=$exec_prefix
+     fi
+     am_cv_python_pyexecdir=`$PYTHON -c "
+$am_python_setup_sysconfig
+if can_use_sysconfig:
+    sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'})
+else:
+    from distutils import sysconfig
+    sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix')
+sys.stdout.write(sitedir)"`
+     case $am_cv_python_pyexecdir in
+     $am_py_exec_prefix*)
+       am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'`
+       am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"`
+       ;;
+     *)
+       case $am_py_exec_prefix in
+         /usr|/System*) ;;
+         *)
+	   am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages
+	   ;;
+       esac
+       ;;
+     esac
+    ])
+  AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir])
+
+  dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE)
+
+  AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE])
+
+  dnl Run any user-specified action.
+  $2
+  fi
+
+])
+
+
+# AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+# ---------------------------------------------------------------------------
+# Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION.
+# Run ACTION-IF-FALSE otherwise.
+# This test uses sys.hexversion instead of the string equivalent (first
+# word of sys.version), in order to cope with versions such as 2.2c1.
+# This supports Python 2.0 or higher. (2.0 was released on October 16, 2000).
+AC_DEFUN([AM_PYTHON_CHECK_VERSION],
+ [prog="import sys
+# split strings by '.' and convert to numeric.  Append some zeros
+# because we need at least 4 digits for the hex conversion.
+# map returns an iterator in Python 3.0 and a list in 2.x
+minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]]
+minverhex = 0
+# xrange is not present in Python 3.0 and range returns an iterator
+for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
+sys.exit(sys.hexversion < minverhex)"
+  AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$[*]" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$[*]" != "X $srcdir/configure conftest.file" \
+	&& test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment])
+     fi
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  for _am_tool in $_am_tools; do
+    case $_am_tool in
+    gnutar)
+      for _am_tar in tar gnutar gtar; do
+        AM_RUN_LOG([$_am_tar --version]) && break
+      done
+      am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+      am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+      am__untar="$_am_tar -xf -"
+      ;;
+    plaintar)
+      # Must skip GNU tar: if it does not support --format= it doesn't create
+      # ustar tarball either.
+      (tar --version) >/dev/null 2>&1 && continue
+      am__tar='tar chf - "$$tardir"'
+      am__tar_='tar chf - "$tardir"'
+      am__untar='tar xf -'
+      ;;
+    pax)
+      am__tar='pax -L -x $1 -w "$$tardir"'
+      am__tar_='pax -L -x $1 -w "$tardir"'
+      am__untar='pax -r'
+      ;;
+    cpio)
+      am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+      am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+      am__untar='cpio -i -H $1 -d'
+      ;;
+    none)
+      am__tar=false
+      am__tar_=false
+      am__untar=false
+      ;;
+    esac
+
+    # If the value was cached, stop now.  We just wanted to have am__tar
+    # and am__untar set.
+    test -n "${am_cv_prog_tar_$1}" && break
+
+    # tar/untar a dummy directory, and stop if the command works.
+    rm -rf conftest.dir
+    mkdir conftest.dir
+    echo GrepMe > conftest.dir/file
+    AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+    rm -rf conftest.dir
+    if test -s conftest.tar; then
+      AM_RUN_LOG([$am__untar <conftest.tar])
+      AM_RUN_LOG([cat conftest.dir/file])
+      grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+    fi
+  done
+  rm -rf conftest.dir
+
+  AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+  AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
diff --git a/protobuf/gtest/build-aux/compile b/protobuf/gtest/build-aux/compile
new file mode 100755
index 0000000..531136b
--- /dev/null
+++ b/protobuf/gtest/build-aux/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/protobuf/gtest/build-aux/config.guess b/protobuf/gtest/build-aux/config.guess
new file mode 100755
index 0000000..b79252d
--- /dev/null
+++ b/protobuf/gtest/build-aux/config.guess
@@ -0,0 +1,1558 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
+
+timestamp='2013-06-10'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2013 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+	# If the system lacks a compiler, then just pick glibc.
+	# We could probably try harder.
+	LIBC=gnu
+
+	eval $set_cc_for_build
+	cat <<-EOF > $dummy.c
+	#include <features.h>
+	#if defined(__UCLIBC__)
+	LIBC=uclibc
+	#elif defined(__dietlibc__)
+	LIBC=dietlibc
+	#else
+	LIBC=gnu
+	#endif
+	EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+		os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:Bitrig:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	exitcode=$?
+	trap '' 0
+	exit $exitcode ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+	echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm*:riscos:*:*|arm*:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+	echo m68k-milan-mint${UNAME_RELEASE}
+	exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+	echo m68k-hades-mint${UNAME_RELEASE}
+	exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+	echo m68k-unknown-mint${UNAME_RELEASE}
+	exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+	# DG/UX returns AViiON for all architectures
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[4567])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+		    case "${sc_cpu_version}" in
+		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		      532)                      # CPU_PA_RISC2_0
+			case "${sc_kernel_bits}" in
+			  32) HP_ARCH="hppa2.0n" ;;
+			  64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+			esac ;;
+		    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^		//' << EOF >$dummy.c
+
+		#define _HPUX_SOURCE
+		#include <stdlib.h>
+		#include <unistd.h>
+
+		int main ()
+		{
+		#if defined(_SC_KERNEL_BITS)
+		    long bits = sysconf(_SC_KERNEL_BITS);
+		#endif
+		    long cpu  = sysconf (_SC_CPU_VERSION);
+
+		    switch (cpu)
+			{
+			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+			case CPU_PA_RISC2_0:
+		#if defined(_SC_KERNEL_BITS)
+			    switch (bits)
+				{
+				case 64: puts ("hppa2.0w"); break;
+				case 32: puts ("hppa2.0n"); break;
+				default: puts ("hppa2.0"); break;
+				} break;
+		#else  /* !defined(_SC_KERNEL_BITS) */
+			    puts ("hppa2.0"); break;
+		#endif
+			default: puts ("hppa1.0"); break;
+			}
+		    exit (0);
+		}
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+	exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+	exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+	exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+	exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    5000:UNIX_System_V:4.*:*)
+	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	UNAME_PROCESSOR=`/usr/bin/uname -p`
+	case ${UNAME_PROCESSOR} in
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:MSYS*:*)
+	echo ${UNAME_MACHINE}-pc-msys
+	exit ;;
+    i*:windows32*:*)
+	# uname -m includes "-pc" on this system.
+	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    aarch64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    aarch64_be:Linux:*:*)
+	UNAME_MACHINE=aarch64_be
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+	esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arc:Linux:*:* | arceb:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	else
+	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+		| grep -q __ARM_PCS_VFP
+	    then
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+	    else
+		echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+	    fi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    cris:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    crisv32:Linux:*:*)
+	echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+	exit ;;
+    frv:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    hexagon:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:Linux:*:*)
+	echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+	;;
+    or1k:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    or32:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-${LIBC}
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+	  PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+	  *)    echo hppa-unknown-linux-${LIBC} ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-${LIBC}
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-${LIBC}
+	exit ;;
+    ppc64le:Linux:*:*)
+	echo powerpc64le-unknown-linux-${LIBC}
+	exit ;;
+    ppcle:Linux:*:*)
+	echo powerpcle-unknown-linux-${LIBC}
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+	exit ;;
+    sh64*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    tile*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+	exit ;;
+    x86_64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    xtensa*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+	# Unixware is an offshoot of SVR4, but it has its own version
+	# number series starting with 2...
+	# I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+	# Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+	# uname -m prints for DJGPP always 'pc', but it prints nothing about
+	# the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+	exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+			# says <Richard.M.Bartel@ccMail.Census.GOV>
+	echo i586-unisys-sysv4
+	exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+		echo mips-nec-sysv${UNAME_RELEASE}
+	else
+		echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+	exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    x86_64:Haiku:*:*)
+	echo x86_64-unknown-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	eval $set_cc_for_build
+	if test "$UNAME_PROCESSOR" = unknown ; then
+	    UNAME_PROCESSOR=powerpc
+	fi
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		case $UNAME_PROCESSOR in
+		    i386) UNAME_PROCESSOR=x86_64 ;;
+		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		esac
+	    fi
+	fi
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NEO-?:NONSTOP_KERNEL:*:*)
+	echo neo-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSE-*:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+	echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+    x86_64:VMkernel:*:*)
+	echo ${UNAME_MACHINE}-unknown-esx
+	exit ;;
+esac
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+	"4"
+#else
+	""
+#endif
+	); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/protobuf/gtest/build-aux/config.h.in b/protobuf/gtest/build-aux/config.h.in
new file mode 100644
index 0000000..843b5b1
--- /dev/null
+++ b/protobuf/gtest/build-aux/config.h.in
@@ -0,0 +1,69 @@
+/* build-aux/config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
diff --git a/protobuf/gtest/build-aux/config.sub b/protobuf/gtest/build-aux/config.sub
new file mode 100755
index 0000000..9633db7
--- /dev/null
+++ b/protobuf/gtest/build-aux/config.sub
@@ -0,0 +1,1791 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
+
+timestamp='2013-08-10'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2013 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze*)
+		os=
+		basic_machine=$1
+		;;
+	-bluegene*)
+		os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+	-chorusrdb)
+		os=-chorusrdb
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*178)
+		os=-lynxos178
+		;;
+	-lynx*5)
+		os=-lynxos5
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| aarch64 | aarch64_be \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arceb \
+	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+	| avr | avr32 \
+	| be32 | be64 \
+	| bfin \
+	| c4x | c8051 | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| epiphany \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| hexagon \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| le32 | le64 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipsr5900 | mipsr5900el \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nds32 | nds32le | nds32be \
+	| nios | nios2 | nios2eb | nios2el \
+	| ns16k | ns32k \
+	| open8 \
+	| or1k | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pyramid \
+	| rl78 | rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu \
+	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+	| we32k \
+	| x86 | xc16x | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	c54x)
+		basic_machine=tic54x-unknown
+		;;
+	c55x)
+		basic_machine=tic55x-unknown
+		;;
+	c6x)
+		basic_machine=tic6x-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	strongarm | thumb | xscale)
+		basic_machine=arm-unknown
+		;;
+	xgate)
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	xscaleeb)
+		basic_machine=armeb-unknown
+		;;
+
+	xscaleel)
+		basic_machine=armel-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| aarch64-* | aarch64_be-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| be32-* | be64-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* \
+	| c8051-* | clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| hexagon-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| le32-* | le64-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+	| microblaze-* | microblazeel-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipsr5900-* | mipsr5900el-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nds32-* | nds32le-* | nds32be-* \
+	| nios-* | nios2-* | nios2eb-* | nios2el-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| open8-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pyramid-* \
+	| rl78-* | romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+	| tahoe-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tile*-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+	| vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c54x-*)
+		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c55x-*)
+		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c6x-*)
+		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16 | cr16-*)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	microblaze*)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw64)
+		basic_machine=x86_64-pc
+		os=-mingw64
+		;;
+	mingw32)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	msys)
+		basic_machine=i686-pc
+		os=-msys
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	nacl)
+		basic_machine=le32-unknown
+		os=-nacl
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	neo-tandem)
+		basic_machine=neo-tandem
+		;;
+	nse-tandem)
+		basic_machine=nse-tandem
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc | ppcbe)	basic_machine=powerpc-unknown
+		;;
+	ppc-* | ppcbe-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos | rdos64)
+		basic_machine=x86_64-pc
+		os=-rdos
+		;;
+	rdos32)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	strongarm-* | thumb-*)
+		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tile*)
+		basic_machine=$basic_machine-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	xscale-* | xscalee[bl]-*)
+		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+	# First match some system type aliases
+	# that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-auroraux)
+		os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* | -plan9* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -bitrig* | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-nacl*)
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	score-*)
+		os=-elf
+		;;
+	spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	c8051-*)
+		os=-elf
+		;;
+	hexagon-*)
+		os=-elf
+		;;
+	tic54x-*)
+		os=-coff
+		;;
+	tic55x-*)
+		os=-coff
+		;;
+	tic6x-*)
+		os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or1k-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/protobuf/gtest/build-aux/depcomp b/protobuf/gtest/build-aux/depcomp
new file mode 100755
index 0000000..4ebd5b3
--- /dev/null
+++ b/protobuf/gtest/build-aux/depcomp
@@ -0,0 +1,791 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2013-05-30.07; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+    echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+    exit 1;
+    ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by 'PROGRAMS ARGS'.
+  object      Object file output by 'PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputting dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+# Get the directory component of the given path, and save it in the
+# global variables '$dir'.  Note that this directory component will
+# be either empty or ending with a '/' character.  This is deliberate.
+set_dir_from ()
+{
+  case $1 in
+    */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
+      *) dir=;;
+  esac
+}
+
+# Get the suffix-stripped basename of the given path, and save it the
+# global variable '$base'.
+set_base_from ()
+{
+  base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
+}
+
+# If no dependency file was actually created by the compiler invocation,
+# we still have to create a dummy depfile, to avoid errors with the
+# Makefile "include basename.Plo" scheme.
+make_dummy_depfile ()
+{
+  echo "#dummy" > "$depfile"
+}
+
+# Factor out some common post-processing of the generated depfile.
+# Requires the auxiliary global variable '$tmpdepfile' to be set.
+aix_post_process_depfile ()
+{
+  # If the compiler actually managed to produce a dependency file,
+  # post-process it.
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form 'foo.o: dependency.h'.
+    # Do two passes, one to just change these to
+    #   $object: dependency.h
+    # and one to simply output
+    #   dependency.h:
+    # which is needed to avoid the deleted-header problem.
+    { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
+      sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
+    } > "$depfile"
+    rm -f "$tmpdepfile"
+  else
+    make_dummy_depfile
+  fi
+}
+
+# A tabulation character.
+tab='	'
+# A newline character.
+nl='
+'
+# Character ranges might be problematic outside the C locale.
+# These definitions help.
+upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
+lower=abcdefghijklmnopqrstuvwxyz
+digits=0123456789
+alpha=${upper}${lower}
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Avoid interferences from the environment.
+gccflag= dashmflag=
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+  # This is just like dashmstdout with a different argument.
+  dashmflag=-xM
+  depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+  # This is just like msvisualcpp but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvisualcpp
+fi
+
+if test "$depmode" = msvc7msys; then
+  # This is just like msvc7 but w/o cygpath translation.
+  # Just convert the backslash-escaped backslashes to single forward
+  # slashes to satisfy depend.m4
+  cygpath_u='sed s,\\\\,/,g'
+  depmode=msvc7
+fi
+
+if test "$depmode" = xlc; then
+  # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
+  gccflag=-qmakedep=gcc,-MF
+  depmode=gcc
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
+## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
+## (see the conditional assignment to $gccflag above).
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).  Also, it might not be
+##   supported by the other compilers which use the 'gcc' depmode.
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The second -e expression handles DOS-style file names with drive
+  # letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the "deleted header file" problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+## Some versions of gcc put a space before the ':'.  On the theory
+## that the space means something, we add a space to the output as
+## well.  hp depmode also adds that space, but also prefixes the VPATH
+## to the object.  Take care to not repeat it in the output.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like '#:fec' to the end of the
+    # dependency line.
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
+      | tr "$nl" ' ' >> "$depfile"
+    echo >> "$depfile"
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' "$nl" < "$tmpdepfile" \
+      | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+      >> "$depfile"
+  else
+    make_dummy_depfile
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+xlc)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts '$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  set_dir_from "$object"
+  set_base_from "$object"
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  aix_post_process_depfile
+  ;;
+
+tcc)
+  # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
+  # FIXME: That version still under development at the moment of writing.
+  #        Make that this statement remains true also for stable, released
+  #        versions.
+  # It will wrap lines (doesn't matter whether long or short) with a
+  # trailing '\', as in:
+  #
+  #   foo.o : \
+  #    foo.c \
+  #    foo.h \
+  #
+  # It will put a trailing '\' even on the last line, and will use leading
+  # spaces rather than leading tabs (at least since its commit 0394caf7
+  # "Emit spaces for -MD").
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
+  # We have to change lines of the first kind to '$object: \'.
+  sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
+  # And for each line of the second kind, we have to emit a 'dep.h:'
+  # dummy dependency, to avoid the deleted-header problem.
+  sed -n -e 's|^  *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+## The order of this option in the case statement is important, since the
+## shell code in configure will try each of these formats in the order
+## listed in this file.  A plain '-MD' option would be understood by many
+## compilers, so we must ensure this comes after the gcc and icc options.
+pgcc)
+  # Portland's C compiler understands '-MD'.
+  # Will always output deps to 'file.d' where file is the root name of the
+  # source file under compilation, even if file resides in a subdirectory.
+  # The object file name does not affect the name of the '.d' file.
+  # pgcc 10.2 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using '\' :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+  set_dir_from "$object"
+  # Use the source, not the object, to determine the base name, since
+  # that's sadly what pgcc will do too.
+  set_base_from "$source"
+  tmpdepfile=$base.d
+
+  # For projects that build the same source file twice into different object
+  # files, the pgcc approach of using the *source* file root name can cause
+  # problems in parallel builds.  Use a locking strategy to avoid stomping on
+  # the same $tmpdepfile.
+  lockdir=$base.d-lock
+  trap "
+    echo '$0: caught signal, cleaning up...' >&2
+    rmdir '$lockdir'
+    exit 1
+  " 1 2 13 15
+  numtries=100
+  i=$numtries
+  while test $i -gt 0; do
+    # mkdir is a portable test-and-set.
+    if mkdir "$lockdir" 2>/dev/null; then
+      # This process acquired the lock.
+      "$@" -MD
+      stat=$?
+      # Release the lock.
+      rmdir "$lockdir"
+      break
+    else
+      # If the lock is being held by a different process, wait
+      # until the winning process is done or we timeout.
+      while test -d "$lockdir" && test $i -gt 0; do
+        sleep 1
+        i=`expr $i - 1`
+      done
+    fi
+    i=`expr $i - 1`
+  done
+  trap - 1 2 13 15
+  if test $i -le 0; then
+    echo "$0: failed to acquire lock after $numtries attempts" >&2
+    echo "$0: check lockdir '$lockdir'" >&2
+    exit 1
+  fi
+
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  set_dir_from  "$object"
+  set_base_from "$object"
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -ne 0; then
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add 'dependent.h:' lines.
+    sed -ne '2,${
+               s/^ *//
+               s/ \\*$//
+               s/$/:/
+               p
+             }' "$tmpdepfile" >> "$depfile"
+  else
+    make_dummy_depfile
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+  # The Tru64 compiler uses -MD to generate dependencies as a side
+  # effect.  'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
+  # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+  # dependencies in 'foo.d' instead, so we check for that too.
+  # Subdirectories are respected.
+  set_dir_from  "$object"
+  set_base_from "$object"
+
+  if test "$libtool" = yes; then
+    # Libtool generates 2 separate objects for the 2 libraries.  These
+    # two compilations output dependencies in $dir.libs/$base.o.d and
+    # in $dir$base.o.d.  We have to check for both files, because
+    # one of the two compilations can be disabled.  We should prefer
+    # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+    # automatically cleaned when .libs/ is deleted, while ignoring
+    # the former would cause a distcleancheck panic.
+    tmpdepfile1=$dir$base.o.d          # libtool 1.5
+    tmpdepfile2=$dir.libs/$base.o.d    # Likewise.
+    tmpdepfile3=$dir.libs/$base.d      # Compaq CCC V6.2-504
+    "$@" -Wc,-MD
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    tmpdepfile3=$dir$base.d
+    "$@" -MD
+  fi
+
+  stat=$?
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  # Same post-processing that is required for AIX mode.
+  aix_post_process_depfile
+  ;;
+
+msvc7)
+  if test "$libtool" = yes; then
+    showIncludes=-Wc,-showIncludes
+  else
+    showIncludes=-showIncludes
+  fi
+  "$@" $showIncludes > "$tmpdepfile"
+  stat=$?
+  grep -v '^Note: including file: ' "$tmpdepfile"
+  if test $stat -ne 0; then
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The first sed program below extracts the file names and escapes
+  # backslashes for cygpath.  The second sed program outputs the file
+  # name when reading, but also accumulates all include files in the
+  # hold buffer in order to output them again at the end.  This only
+  # works with sed implementations that can handle large buffers.
+  sed < "$tmpdepfile" -n '
+/^Note: including file:  *\(.*\)/ {
+  s//\1/
+  s/\\/\\\\/g
+  p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+  s/.*/'"$tab"'/
+  G
+  p
+}' >> "$depfile"
+  echo >> "$depfile" # make sure the fragment doesn't end with a backslash
+  rm -f "$tmpdepfile"
+  ;;
+
+msvc7msys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove '-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for ':'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
+  "$@" $dashmflag |
+    sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this sed invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  tr ' ' "$nl" < "$tmpdepfile" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  # makedepend may prepend the VPATH from the source file name to the object.
+  # No need to regex-escape $object, excess matching of '.' is harmless.
+  sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process the last invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed '1,2d' "$tmpdepfile" \
+    | tr ' ' "$nl" \
+    | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
+    | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove '-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E \
+    | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+             -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+    | sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+        set fnord "$@"
+        shift
+        shift
+        ;;
+    *)
+        set fnord "$@" "$arg"
+        shift
+        shift
+        ;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
+  echo "$tab" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/protobuf/gtest/build-aux/install-sh b/protobuf/gtest/build-aux/install-sh
new file mode 100755
index 0000000..377bb86
--- /dev/null
+++ b/protobuf/gtest/build-aux/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-11-20.07; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	# Protect names problematic for 'test' and other utilities.
+	case $dst_arg in
+	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
+	esac
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call 'install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names problematic for 'test' and other utilities.
+  case $src in
+    -* | [=\(\)!]) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+    dst=$dst_arg
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	[-=\(\)!]*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test X"$d" = X && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/protobuf/gtest/build-aux/ltmain.sh b/protobuf/gtest/build-aux/ltmain.sh
new file mode 100644
index 0000000..a356aca
--- /dev/null
+++ b/protobuf/gtest/build-aux/ltmain.sh
@@ -0,0 +1,9661 @@
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+#       --config             show all configuration variables
+#       --debug              enable verbose shell tracing
+#   -n, --dry-run            display commands without modifying any files
+#       --features           display basic configuration information and exit
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --no-warn            don't display warning messages
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+#         clean              remove files from the build directory
+#         compile            compile a source file into a libtool object
+#         execute            automatically set library path, then run a program
+#         finish             complete the installation of libtool libraries
+#         install            install libraries or executables
+#         link               create a library or an executable
+#         uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#         host-triplet:	$host
+#         shell:		$SHELL
+#         compiler:		$LTCC
+#         compiler flags:		$LTCFLAGS
+#         linker:		$LD (gnu? $with_gnu_ld)
+#         $progname:	(GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1
+#         automake:	$automake_version
+#         autoconf:	$autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.2 Debian-2.4.2-1.7ubuntu1"
+TIMESTAMP=""
+package_revision=1.3337
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+          save_$lt_var=\$$lt_var
+          $lt_var=C
+	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+	fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+    case ${2} in
+      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+		s@/\./@/@g
+		t dotsl
+		s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
+
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=$func_dirname_result
+     progdir=`cd "$progdir" && pwd`
+     progpath="$progdir/$progname"
+     ;;
+  *)
+     save_IFS="$IFS"
+     IFS=${PATH_SEPARATOR-:}
+     for progdir in $PATH; do
+       IFS="$save_IFS"
+       test -x "$progdir/$progname" && break
+     done
+     IFS="$save_IFS"
+     test -n "$progdir" || progdir=`pwd`
+     progpath="$progdir/$progname"
+     ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+    # bash bug again:
+    :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information."  ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    my_directory_path="$1"
+    my_dir_list=
+
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$my_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list incase some portion of path contains whitespace.
+        my_dir_list="$my_directory_path:$my_dir_list"
+
+        # If the last portion added has no slash in it, the list is done
+        case $my_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+      done
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$my_dir" 2>/dev/null || :
+      done
+      IFS="$save_mkdir_p_IFS"
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
+    fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$opt_dry_run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+        # Failing that, at least try and use $RANDOM to avoid a race
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+        save_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
+
+    $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
+
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "$1" | $SED \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
+
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
+
+    func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $opt_debug
+
+    $SED -n '/(C)/!b go
+	:more
+	/\./!{
+	  N
+	  s/\n# / /
+	  b more
+	}
+	:go
+	/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    echo
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+	:print
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+	p
+	d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
+    fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    $opt_debug
+
+    func_error "missing argument for $1."
+    exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
+
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
+
+    exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+
+    exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+  # Global variable:
+  tagname="$1"
+
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
+
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
+    *)
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+    fi
+
+    exit $EXIT_MISMATCH
+  fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
+  ;;
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
+  ;;
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
+  ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+  # this just eases exit handling
+  while test $# -gt 0; do
+    opt="$1"
+    shift
+    case $opt in
+      --debug|-x)	opt_debug='set -x'
+			func_echo "enabling shell trace mode"
+			$opt_debug
+			;;
+      --dry-run|--dryrun|-n)
+			opt_dry_run=:
+			;;
+      --config)
+			opt_config=:
+func_config
+			;;
+      --dlopen|-dlopen)
+			optarg="$1"
+			opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+			shift
+			;;
+      --preserve-dup-deps)
+			opt_preserve_dup_deps=:
+			;;
+      --features)
+			opt_features=:
+func_features
+			;;
+      --finish)
+			opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+			;;
+      --help)
+			opt_help=:
+			;;
+      --help-all)
+			opt_help_all=:
+opt_help=': help-all'
+			;;
+      --mode)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+			shift
+			;;
+      --no-silent|--no-quiet)
+			opt_silent=false
+func_append preserve_args " $opt"
+			;;
+      --no-warning|--no-warn)
+			opt_warning=false
+func_append preserve_args " $opt"
+			;;
+      --no-verbose)
+			opt_verbose=false
+func_append preserve_args " $opt"
+			;;
+      --silent|--quiet)
+			opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+			;;
+      --verbose|-v)
+			opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+			;;
+      --tag)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+			shift
+			;;
+
+      -\?|-h)		func_usage				;;
+      --help)		func_help				;;
+      --version)	func_version				;;
+
+      # Separate optargs to long options:
+      --*=*)
+			func_split_long_opt "$opt"
+			set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+			func_split_short_opt "$opt"
+			set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      --)		break					;;
+      -*)		func_fatal_help "unrecognized option \`$opt'" ;;
+      *)		set dummy "$opt" ${1+"$@"};	shift; break  ;;
+    esac
+  done
+
+  # Validate options:
+
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
+  fi
+
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
+
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+      ;;
+  esac
+
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
+
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
+    fi
+
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
+
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
+
+
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+##    Main.    ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case "$lalib_p_line" in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $opt_debug
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$save_ifs
+      eval cmd=\"$cmd\"
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $opt_debug
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case "$lt_sysroot:$1" in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result="=$func_stripname_result"
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $opt_debug
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	func_append_quoted CC_quoted "$arg"
+      done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	      # Double-quote args containing other shell metacharacters.
+	      func_append_quoted CC_quoted "$arg"
+	    done
+	    CC_expanded=`func_echo_all $CC`
+	    CC_quoted_expanded=`func_echo_all $CC_quoted`
+	    case "$@ " in
+	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with \`--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
+    else
+      write_lobj=none
+    fi
+
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
+    else
+      write_oldobj=none
+    fi
+
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+      $MV "${write_libobj}T" "${write_libobj}"
+    }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero error code, so we
+    # are forced to check the contents of stdout. On the other hand, if the
+    # command is not found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both error code of
+    # zero AND non-empty stdout, which explains the odd construction:
+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$lt_sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $opt_debug
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=""
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
+      fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $opt_debug
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $opt_debug
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  \`$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result="$1"
+  fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $opt_debug
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  \`$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result="$3"
+    fi
+  fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $opt_debug
+  case $4 in
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $opt_debug
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $opt_debug
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
+      ;;
+  esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $opt_debug
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
+  fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $opt_debug
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $opt_debug
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify \`-o' more than once"
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-pie | -fpie | -fPIE)
+          func_append pie_flag " $arg"
+	  continue
+	  ;;
+
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  func_append later " $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+	  for arg in $args; do
+	    IFS="$save_ifs"
+	    func_append_quoted lastarg "$arg"
+	  done
+	  IFS="$save_ifs"
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
+
+	  # Add the arguments to base_compile.
+	  func_append base_compile " $lastarg"
+	  continue
+	  ;;
+
+	*)
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      func_append_quoted base_compile "$lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with \`-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj="$func_basename_result"
+      }
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
+
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	continue
+	;;
+
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
+
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      func_append removelist " $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
+
+    $opt_dry_run || $RM $removelist
+    func_append removelist " $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      func_mkdir_p "$xdir$objdir"
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	func_append command " -o $lobj"
+      fi
+
+      func_show_eval_locale "$command"	\
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	func_append command " -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      func_append command "$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
+
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+      # Unlock the critical section if it was locked
+      if test "$need_locks" != no; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
+
+    exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $opt_mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
+
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
+  -Wc,FLAG          pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+        ;;
+
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode \`$opt_mode'"
+        ;;
+    esac
+
+    echo
+    $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test "$opt_help" = :; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	func_mode_help
+      done
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	echo
+	func_mode_help
+      done
+    } |
+    sed '1d
+      /^When reporting/,/^Report/{
+	H
+	d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $opt_debug
+    # The first argument is the command name.
+    cmd="$nonopt"
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $opt_dlopen; do
+      test -f "$file" \
+	|| func_fatal_help "\`$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  func_append dir "/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+	;;
+
+      *)
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -* | *.la | *.lo ) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_append_quoted args "$file"
+    done
+
+    if test "X$opt_dry_run" = Xfalse; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+	      else
+		$lt_unset $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $opt_debug
+    libs=
+    libdirs=
+    admincmds=
+
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+	func_append libdirs " $opt"
+
+      elif test -f "$opt"; then
+	if func_lalib_unsafe_p "$opt"; then
+	  func_append libs " $opt"
+	else
+	  func_warning "\`$opt' is not a valid libtool archive"
+	fi
+
+      else
+	func_fatal_error "invalid argument \`$opt'"
+      fi
+    done
+
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
+
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+	  sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	    > $tmpdir/tmp-la
+	  mv -f $tmpdir/tmp-la $lib
+	done
+        ${RM}r "$tmpdir"
+      fi
+    fi
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || func_append admincmds "
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_silent && exit $EXIT_SUCCESS
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      echo "Libraries have been installed in:"
+      for libdir in $libdirs; do
+	$ECHO "   $libdir"
+      done
+      echo
+      echo "If you ever happen to want to link against installed libraries"
+      echo "in a given directory, LIBDIR, you must either use libtool, and"
+      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+      echo "flag during linking and do at least one of the following:"
+      if test -n "$shlibpath_var"; then
+	echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+	echo "     during execution"
+      fi
+      if test -n "$runpath_var"; then
+	echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+	echo "     during linking"
+      fi
+      if test -n "$hardcode_libdir_flag_spec"; then
+	libdir=LIBDIR
+	eval flag=\"$hardcode_libdir_flag_spec\"
+
+	$ECHO "   - use the \`$flag' linker flag"
+      fi
+      if test -n "$admincmds"; then
+	$ECHO "   - have your system administrator run these commands:$admincmds"
+      fi
+      if test -f /etc/ld.so.conf; then
+	echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+      fi
+      echo
+
+      echo "See any operating system documentation about shared libraries for"
+      case $host in
+	solaris2.[6789]|solaris2.1[0-9])
+	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	  echo "pages."
+	  ;;
+	*)
+	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
+	  ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
+    exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $opt_debug
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       case $nonopt in *shtool*) :;; *) false;; esac; then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    no_mode=:
+    for arg
+    do
+      arg2=
+      if test -n "$dest"; then
+	func_append files " $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f)
+	if $install_cp; then :; else
+	  prev=$arg
+	fi
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  if test "x$prev" = x-m && test -n "$install_override_mode"; then
+	    arg2=$install_override_mode
+	    no_mode=false
+	  fi
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
+      if test -n "$arg2"; then
+	func_quote_for_eval "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_for_eval_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prev' option requires an argument"
+
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+	func_quote_for_eval "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_for_eval_result"
+      fi
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "\`$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	func_append staticlibs " $file"
+	;;
+
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
+
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append current_libdirs " $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append future_libdirs " $libdir" ;;
+	  esac
+	fi
+
+	func_dirname "$file" "/" ""
+	dir="$func_dirname_result"
+	func_append dir "$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  func_warning "relinking \`$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname="$1"
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme="$stripme"
+	  case $host_os in
+	  cygwin* | mingw* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=""
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try `ln -sf' first, because the `ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
+
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name="$func_basename_result"
+	instname="$dir/$name"i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=""
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  func_source "$wrapper"
+
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if test "$finalize" = yes; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_silent || {
+	          func_quote_for_expand "$relink_command"
+		  eval "func_echo $func_quote_for_expand_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink \`$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file="$outputname"
+	      else
+	        func_warning "cannot relink \`$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
+	fi
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name="$func_basename_result"
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+      tool_oldlib=$func_to_tool_file_result
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms="${my_outputname}S.c"
+      else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist="$output_objdir/${my_outputname}.nm"
+
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
+
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
+
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+	    func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols="$output_objdir/$outputname.exp"
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
+	  else
+	    $opt_dry_run || {
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin* | *mingw* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
+	  fi
+	fi
+
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
+	  func_basename "$dlprefile"
+	  name="$func_basename_result"
+          case $host in
+	    *cygwin* | *mingw* | *cegcc* )
+	      # if an import library, we need to obtain dlname
+	      if func_win32_import_lib_p "$dlprefile"; then
+	        func_tr_sh "$dlprefile"
+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
+	        dlprefile_dlbasename=""
+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+	          # Use subshell, to avoid clobbering current variable values
+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+	          if test -n "$dlprefile_dlname" ; then
+	            func_basename "$dlprefile_dlname"
+	            dlprefile_dlbasename="$func_basename_result"
+	          else
+	            # no lafile. user explicitly requested -dlpreopen <import library>.
+	            $sharedlib_from_linklib_cmd "$dlprefile"
+	            dlprefile_dlbasename=$sharedlib_from_linklib_result
+	          fi
+	        fi
+	        $opt_dry_run || {
+	          if test -n "$dlprefile_dlbasename" ; then
+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+	          else
+	            func_warning "Could not compute DLL name from $name"
+	            eval '$ECHO ": $name " >> "$nlist"'
+	          fi
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+	        }
+	      else # not an import lib
+	        $opt_dry_run || {
+	          eval '$ECHO ": $name " >> "$nlist"'
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	        }
+	      fi
+	    ;;
+	    *)
+	      $opt_dry_run || {
+	        eval '$ECHO ": $name " >> "$nlist"'
+	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	      }
+	    ;;
+          esac
+	done
+
+	$opt_dry_run || {
+	  # Make sure we have at least an empty file.
+	  test -f "$nlist" || : > "$nlist"
+
+	  if test -n "$exclude_expsyms"; then
+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	    $MV "$nlist"T "$nlist"
+	  fi
+
+	  # Try sorting and uniquifying the output.
+	  if $GREP -v "^: " < "$nlist" |
+	      if sort -k 3 </dev/null >/dev/null 2>&1; then
+		sort -k 3
+	      else
+		sort +2
+	      fi |
+	      uniq > "$nlist"S; then
+	    :
+	  else
+	    $GREP -v "^: " < "$nlist" > "$nlist"S
+	  fi
+
+	  if test -f "$nlist"S; then
+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+	  else
+	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
+
+	  echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+  { \"$my_originator\", (void *) 0 },"
+
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  echo >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
+	  *)
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
+	    ;;
+	  esac
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) func_append symtab_cflags " $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
+	case $host in
+	*cygwin* | *mingw* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	  else
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
+	;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
+
+      # Nullify the symbol file.
+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+    fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+  $opt_debug
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	$SED -n -e '
+	    1,100{
+		/ I /{
+		    s,.*,import,
+		    p
+		    q
+		}
+	    }'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $opt_debug
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $opt_debug
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[	 ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1" ; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=""
+  fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    if test "$lock_old_archive_extraction" = yes; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+		   'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test "$lock_old_archive_extraction" = yes; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $opt_debug
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib="$func_basename_result"
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
+	esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir="$my_gentop/$my_xlib_u"
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`basename "$darwin_archive"`
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+	      cd "$darwin_curdir"
+	      $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+	    done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+    done
+
+    func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=${1-no}
+
+	$ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    file=\"\$0\""
+
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=\"$qECHO\"
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
+
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  case \" \$* \" in
+  *\\ --lt-*)
+    for lt_wr_arg
+    do
+      case \$lt_wr_arg in
+      --lt-*) ;;
+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+      esac
+      shift
+    done ;;
+  esac
+  func_exec_program_core \${1+\"\$@\"}
+}
+
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+  done
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
+
+	  $ECHO "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$ECHO \"\$relink_command_output\" >&2
+	$RM \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# fixup the dll searchpath if we need to.
+	#
+	# Fix the DLL searchpath if we need to.  Do this before prepending
+	# to shlibpath, because on Windows, both are PATH and uninstalled
+	# libraries must come first.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+      func_exec_program \${1+\"\$@\"}
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+*/
+EOF
+	    cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+	    cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_path "$temp_rpath"
+	      cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test -n "$dllsearchpath"; then
+              func_to_host_path "$dllsearchpath:"
+	      cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test "$fast_install" = yes; then
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+	    else
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+	    fi
+
+
+	    cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  intptr_t rval = 127;
+
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  newargz = XMALLOC (char *, argc + 1);
+
+  /* very simple arg parsing; don't want to rely on getopt
+   * also, copy all non cwrapper options to newargz, except
+   * argz[0], which is handled differently
+   */
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], dumpscript_opt) == 0)
+	{
+EOF
+	    case "$host" in
+	      *mingw* | *cygwin* )
+		# make stdout use "unix" line endings
+		echo "          setmode(1,_O_BINARY);"
+		;;
+	      esac
+
+	    cat <<"EOF"
+	  lt_dump_script (stdout);
+	  return 0;
+	}
+      if (strcmp (argv[i], debug_opt) == 0)
+	{
+          lt_debug = 1;
+          continue;
+	}
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal (__FILE__, __LINE__,
+		    "unrecognized %s option: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
+
+EOF
+	    cat <<EOF
+  /* The GNU banner must be the first non-error debug message */
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+	    cat <<"EOF"
+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (before symlink chase) at: %s\n",
+		  tmp_pathspec);
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (after symlink chase) at: %s\n",
+		  actual_cwrapper_path);
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(main) libtool target name: %s\n",
+		  target_name);
+EOF
+
+	    cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
+
+	    cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
+
+	    case $host_os in
+	      mingw*)
+	    cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+	*p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+	*p = '/';
+      }
+  }
+EOF
+	    ;;
+	    esac
+
+	    cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+     because on Windows, both *_VARNAMEs are PATH but uninstalled
+     libraries must come first. */
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+		  nonnull (lt_argv_zero));
+  for (i = 0; i < newargc; i++)
+    {
+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+		      i, nonnull (newargz[i]));
+    }
+
+EOF
+
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      lt_debugprintf (__FILE__, __LINE__,
+		      "(main) failed to launch target \"%s\": %s\n",
+		      lt_argv_zero, nonnull (strerror (errno)));
+      return 127;
+    }
+  return rval;
+EOF
+		;;
+	      *)
+		cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+		;;
+	    esac
+
+	    cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+			  string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable (const char *path)
+{
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char *concat_name;
+
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+	return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+	{
+	  concat_name = xstrdup (wrapper);
+	  if (check_executable (concat_name))
+	    return concat_name;
+	  XFREE (concat_name);
+	}
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+    }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+	has_slash = 1;
+	break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+	{
+	  for (p = path; *p; p = p_next)
+	    {
+	      const char *q;
+	      size_t p_len;
+	      for (q = p; *q; q++)
+		if (IS_PATH_SEPARATOR (*q))
+		  break;
+	      p_len = q - p;
+	      p_next = (*q == '\0' ? q : q + 1);
+	      if (p_len == 0)
+		{
+		  /* empty path: current directory */
+		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
+		  tmp_len = strlen (tmp);
+		  concat_name =
+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, tmp, tmp_len);
+		  concat_name[tmp_len] = '/';
+		  strcpy (concat_name + tmp_len + 1, wrapper);
+		}
+	      else
+		{
+		  concat_name =
+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, p, p_len);
+		  concat_name[p_len] = '/';
+		  strcpy (concat_name + p_len + 1, wrapper);
+		}
+	      if (check_executable (concat_name))
+		return concat_name;
+	      XFREE (concat_name);
+	    }
+	}
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      lt_debugprintf (__FILE__, __LINE__,
+		      "checking path component for symlinks: %s\n",
+		      tmp_pathspec);
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
+
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  lt_fatal (__FILE__, __LINE__,
+		    "error accessing file \"%s\": %s",
+		    tmp_pathspec, nonnull (strerror (errno)));
+	}
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal (__FILE__, __LINE__,
+		"could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert (str != NULL);
+  assert (pat != NULL);
+
+  len = strlen (str);
+  patlen = strlen (pat);
+
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (strcmp (str, pat) == 0)
+	*str = '\0';
+    }
+  return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+	       int line, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+  va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    int len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[len-1] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+EOF
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+	new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+	{
+	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+	  size_t length;
+	  unsigned int backslashes;
+	  const char *s;
+	  char *quoted_string;
+	  char *p;
+
+	  length = 0;
+	  backslashes = 0;
+	  if (quote_around)
+	    length++;
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		length += backslashes + 1;
+	      length++;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    length += backslashes + 1;
+
+	  quoted_string = XMALLOC (char, length + 1);
+
+	  p = quoted_string;
+	  backslashes = 0;
+	  if (quote_around)
+	    *p++ = '"';
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		{
+		  unsigned int j;
+		  for (j = backslashes + 1; j > 0; j--)
+		    *p++ = '\\';
+		}
+	      *p++ = c;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    {
+	      unsigned int j;
+	      for (j = backslashes; j > 0; j--)
+		*p++ = '\\';
+	      *p++ = '"';
+	    }
+	  *p = '\0';
+
+	  new_argv[i] = quoted_string;
+	}
+      else
+	new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
+EOF
+		;;
+	    esac
+
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+	    func_emit_wrapper yes |
+	      $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/  fputs ("\1", f);/p
+g
+D'
+            cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+    $opt_debug
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $opt_debug
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    bindir=
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    single_module="${wl}-single_module"
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	bindir)
+	  bindir="$arg"
+	  prev=
+	  continue
+	  ;;
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append finalize_command " @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      func_append dlfiles " $arg"
+	    else
+	      func_append dlprefiles " $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file \`$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) func_append deplibs " $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      func_append moreargs " $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		func_source "$arg"
+
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
+		fi
+
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir="$func_dirname_result"
+
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
+
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      func_append dlfiles " $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    func_append dlprefiles " $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  func_append libobjs " $pic_object"
+		  arg="$pic_object"
+		fi
+
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
+
+		  # A standard non-PIC object
+		  func_append non_pic_objects " $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir="$func_dirname_result"
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "\`$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file \`$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "only absolute run-paths are allowed"
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) func_append rpath " $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) func_append xrpath " $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  func_append weak_libs " $arg"
+	  prev=
+	  continue
+	  ;;
+	xcclinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -bindir)
+	prev=bindir
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework)
+	prev=framework
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname "-L" '' "$arg"
+	if test -z "$func_stripname_result"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between \`-L' and \`$1'"
+	  else
+	    func_fatal_error "need path for \`-L' option"
+	  fi
+	fi
+	func_resolve_sysroot "$func_stripname_result"
+	dir=$func_resolve_sysroot_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "* | *" $arg "*)
+	  # Will only happen for absolute or sysroot arguments
+	  ;;
+	*)
+	  # Preserve sysroot, but never include relative directories
+	  case $dir in
+	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+	    *) func_append deplibs " -L$dir" ;;
+	  esac
+	  func_append lib_search_path " $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) func_append dllsearchpath ":$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    func_append deplibs " System.ltframework"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	func_append deplibs " $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot|--sysroot)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	prev=xcompiler
+	continue
+	;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	case "$new_inherited_linker_flags " in
+	    *" $arg "*) ;;
+	    * ) func_append new_inherited_linker_flags " $arg" ;;
+	esac
+	continue
+	;;
+
+      -multi_module)
+	single_module="${wl}-multi_module"
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	func_stripname '-R' '' "$arg"
+	dir=$func_stripname_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	=*)
+	  func_stripname '=' '' "$dir"
+	  dir=$lt_sysroot$func_stripname_result
+	  ;;
+	*)
+	  func_fatal_error "only absolute run-paths are allowed"
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) func_append xrpath " $dir" ;;
+	esac
+	continue
+	;;
+
+      -shared)
+	# The effects of -shared are defined in a previous loop.
+	continue
+	;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -static | -static-libtool-libs)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -weak)
+        prev=weak
+	continue
+	;;
+
+      -Wc,*)
+	func_stripname '-Wc,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $func_quote_for_eval_result"
+	  func_append compiler_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Wl,*)
+	func_stripname '-Wl,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $wl$func_quote_for_eval_result"
+	  func_append compiler_flags " $wl$func_quote_for_eval_result"
+	  func_append linker_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # -msg_* for osf cc
+      -msg_*)
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      # Flags to be passed through unchanged, with rationale:
+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
+      # -r[0-9][0-9]*        specify processor for the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+      # +DA*, +DD*           enable 64-bit mode for the HP compiler
+      # -q*                  compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+      # -F/path              path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
+      # @file                GCC response files
+      # -tp=*                Portland pgcc target processor selection
+      # --sysroot=*          for sysroot support
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        func_append compiler_flags " $arg"
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      *.$objext)
+	# A standard object.
+	func_append objs " $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if func_lalib_unsafe_p "$arg"; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  func_source "$arg"
+
+	  if test -z "$pic_object" ||
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  func_dirname "$arg" "/" ""
+	  xdir="$func_dirname_result"
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		func_append dlfiles " $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      func_append dlprefiles " $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    func_append libobjs " $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    func_append non_pic_objects " $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if $opt_dry_run; then
+	    # Extract subdirectory from the argument.
+	    func_dirname "$arg" "/" ""
+	    xdir="$func_dirname_result"
+
+	    func_lo2o "$arg"
+	    pic_object=$xdir$objdir/$func_lo2o_result
+	    non_pic_object=$xdir$func_lo2o_result
+	    func_append libobjs " $pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  else
+	    func_fatal_error "\`$arg' is not a valid libtool object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	func_append deplibs " $arg"
+	func_append old_deplibs " $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	func_resolve_sysroot "$arg"
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  func_append dlfiles " $func_resolve_sysroot_result"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  func_append dlprefiles " $func_resolve_sysroot_result"
+	  prev=
+	else
+	  func_append deplibs " $func_resolve_sysroot_result"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prevarg' option requires an argument"
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    func_dirname "$output" "/" ""
+    output_objdir="$func_dirname_result$objdir"
+    func_to_tool_file "$output_objdir/"
+    tool_output_objdir=$func_to_tool_file_result
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if $opt_preserve_dup_deps ; then
+	case "$libs " in
+	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	esac
+      fi
+      func_append libs " $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if $opt_duplicate_compiler_generated_deps; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+	  esac
+	  func_append pre_post_deps " $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+	passes="conv dlpreopen link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+
+    for pass in $passes; do
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test "$linkmode,$pass" = "lib,link"; then
+	## FIXME: Find the place where the list is rebuilt in the wrong
+	##        order, and fix it there properly
+        tmp_deplibs=
+	for deplib in $deplibs; do
+	  tmp_deplibs="$deplib $tmp_deplibs"
+	done
+	deplibs="$tmp_deplibs"
+      fi
+
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link)
+	  libs="$deplibs %DEPLIBS%"
+	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+	  ;;
+	esac
+      fi
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
+	# Collect and forward deplibs of preopened libtool libs
+	for lib in $dlprefiles; do
+	  # Ignore non-libtool-libs
+	  dependency_libs=
+	  func_resolve_sysroot "$lib"
+	  case $lib in
+	  *.la)	func_source "$func_resolve_sysroot_result" ;;
+	  esac
+
+	  # Collect preopened libtool deplibs, except any this library
+	  # has declared as weak libs
+	  for deplib in $dependency_libs; do
+	    func_basename "$deplib"
+            deplib_base=$func_basename_result
+	    case " $weak_libs " in
+	    *" $deplib_base "*) ;;
+	    *) func_append deplibs " $deplib" ;;
+	    esac
+	  done
+	done
+	libs="$dlprefiles"
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    func_append compiler_flags " $deplib"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
+	    continue
+	  fi
+	  func_stripname '-l' '' "$deplib"
+	  name=$func_stripname_result
+	  if test "$linkmode" = lib; then
+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+	  else
+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+	  fi
+	  for searchdir in $searchdirs; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if func_lalib_p "$lib"; then
+		  library_names=
+		  old_library=
+		  func_source "$lib"
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    func_dirname "$lib" "" "."
+		    ladir="$func_dirname_result"
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+		;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	*.ltframework)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    deplibs="$deplib $deplibs"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  *)
+	    func_warning "\`-L' is ignored for archives/objects"
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    func_stripname '-R' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    dir=$func_resolve_sysroot_result
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) func_append xrpath " $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la)
+	  func_resolve_sysroot "$deplib"
+	  lib=$func_resolve_sysroot_result
+	  ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    # Linking convenience modules into shared libraries is allowed,
+	    # but linking other static libraries is non-portable.
+	    case " $dlpreconveniencelibs " in
+	    *" $deplib "*) ;;
+	    *)
+	      valid_a_lib=no
+	      case $deplibs_check_method in
+		match_pattern*)
+		  set dummy $deplibs_check_method; shift
+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		    valid_a_lib=yes
+		  fi
+		;;
+		pass_all)
+		  valid_a_lib=yes
+		;;
+	      esac
+	      if test "$valid_a_lib" != yes; then
+		echo
+		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because the file extensions .$libext of this argument makes me believe"
+		echo "*** that it is just a static archive that I should not use here."
+	      else
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
+	      fi
+	      ;;
+	    esac
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      func_append newdlprefiles " $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      func_append newdlfiles " $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$lib" \
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+	func_dirname "$lib" "" "."
+	ladir="$func_dirname_result"
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	inherited_linker_flags=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	func_source "$lib"
+
+	# Convert "-framework foo" to "foo.ltframework"
+	if test -n "$inherited_linker_flags"; then
+	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+	    case " $new_inherited_linker_flags " in
+	      *" $tmp_inherited_linker_flag "*) ;;
+	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+	    esac
+	  done
+	fi
+	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && func_append dlfiles " $dlopen"
+	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      func_fatal_error "cannot find name of link library for \`$lib'"
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    func_append convenience " $ladir/$objdir/$old_library"
+	    func_append old_convenience " $ladir/$objdir/$old_library"
+	    tmp_libs=
+	    for deplib in $dependency_libs; do
+	      deplibs="$deplib $deplibs"
+	      if $opt_preserve_dup_deps ; then
+		case "$tmp_libs " in
+		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+		esac
+	      fi
+	      func_append tmp_libs " $deplib"
+	    done
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
+	  fi
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	if test -n "$old_library" &&
+	   { test "$prefer_static_libs" = yes ||
+	     test "$prefer_static_libs,$installed" = "built,no"; }; then
+	  linklib=$old_library
+	else
+	  for l in $old_library $library_names; do
+	    linklib="$l"
+	  done
+	fi
+	if test -z "$linklib"; then
+	  func_fatal_error "cannot find name of link library for \`$lib'"
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  fi
+	  if test -z "$dlname" ||
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    func_append dlprefiles " $lib $dependency_libs"
+	  else
+	    func_append newdlfiles " $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
+	    func_warning "passing it literally to the linker, although it might fail"
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	func_basename "$lib"
+	laname="$func_basename_result"
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$lt_sysroot$libdir"
+	    absdir="$lt_sysroot$libdir"
+	  fi
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  fi
+	fi # $installed = yes
+	func_stripname 'lib' '.la' "$laname"
+	name=$func_stripname_result
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+	  fi
+	  case "$host" in
+	    # special handling for platforms with PE-DLLs.
+	    *cygwin* | *mingw* | *cegcc* )
+	      # Linker will automatically link against shared library if both
+	      # static and shared are present.  Therefore, ensure we extract
+	      # symbols from the import library if a shared library is present
+	      # (otherwise, the dlopen module name will be incorrect).  We do
+	      # this by putting the import library name into $newdlprefiles.
+	      # We recover the dlopen module name by 'saving' the la file
+	      # name in a special purpose variable, and (later) extracting the
+	      # dlname from the la file.
+	      if test -n "$dlname"; then
+	        func_tr_sh "$dir/$linklib"
+	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+	        func_append newdlprefiles " $dir/$linklib"
+	      else
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      fi
+	    ;;
+	    * )
+	      # Prefer using a static library (so that no silly _DYNAMIC symbols
+	      # are required to link).
+	      if test -n "$old_library"; then
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      # Otherwise, use the dlname, so that lt_dlopen finds it.
+	      elif test -n "$dlname"; then
+	        func_append newdlprefiles " $dir/$dlname"
+	      else
+	        func_append newdlprefiles " $dir/$linklib"
+	      fi
+	    ;;
+	  esac
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  func_append newlib_search_path " $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) func_stripname '-L' '' "$deplib"
+	         func_resolve_sysroot "$func_stripname_result"
+	         func_append newlib_search_path " $func_resolve_sysroot_result"
+		 ;;
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { { test "$prefer_static_libs" = no ||
+	         test "$prefer_static_libs,$installed" = "built,yes"; } ||
+	       test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath:" in
+	      *"$absdir:"*) ;;
+	      *) func_append temp_rpath "$absdir:" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc*)
+	      # No point in relinking DLLs because paths are not encoded
+	      func_append notinst_deplibs " $lib"
+	      need_relink=no
+	    ;;
+	  *)
+	    if test "$installed" = no; then
+	      func_append notinst_deplibs " $lib"
+	      need_relink=yes
+	    fi
+	    ;;
+	  esac
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on some
+	  # systems (darwin).  Don't bleat about dlopened modules though!
+	  dlopenmodule=""
+	  for dlpremoduletest in $dlprefiles; do
+	    if test "X$dlpremoduletest" = "X$lib"; then
+	      dlopenmodule="$dlpremoduletest"
+	      break
+	    fi
+	  done
+	  if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+	    echo
+	    if test "$linkmode" = prog; then
+	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $ECHO "*** $linklib is not portable!"
+	  fi
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    shift
+	    realname="$1"
+	    shift
+	    libname=`eval "\\$ECHO \"$libname_spec\""`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw* | *cegcc*)
+	        func_arith $current - $age
+		major=$func_arith_result
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    func_basename "$soroot"
+	    soname="$func_basename_result"
+	    func_stripname 'lib' '.dll' "$soname"
+	    newlib=libimp-$func_stripname_result.a
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      func_verbose "extracting exported symbol list from \`$soname'"
+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      func_verbose "generating import library for \`$soname'"
+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$opt_mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a (non-dlopened) module then we can not
+		    # link against it, someone is ignoring the earlier warnings
+		    if /usr/bin/file -L $add 2> /dev/null |
+			 $GREP ": [^:]* bundle" >/dev/null ; then
+		      if test "X$dlopenmodule" != "X$lib"; then
+			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
+			if test -z "$old_library" ; then
+			  echo
+			  echo "*** And there doesn't seem to be a static archive available"
+			  echo "*** The link will probably fail, sorry"
+			else
+			  add="$dir/$old_library"
+			fi
+		      elif test -n "$old_library"; then
+			add="$dir/$old_library"
+		      fi
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$absdir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      func_append add_dir " -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      func_fatal_configuration "unsupported hardcode properties"
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes &&
+		 test "$hardcode_minus_L" != yes &&
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) func_append finalize_shlibpath "$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$opt_mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) func_append finalize_shlibpath "$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+		add="$inst_prefix_dir$libdir/$linklib"
+	      else
+		add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    func_append add_dir " -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    echo
+	    $ECHO "*** Warning: This system can not link to static lib archive $lib."
+	    echo "*** I have the capability to make that library automatically link in when"
+	    echo "*** you link to this library.  But I can only do this if you have a"
+	    echo "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      echo "*** But as you try to build a module library, libtool will still create "
+	      echo "*** a static module, that should work as long as the dlopening application"
+	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		echo
+		echo "*** However, this would only work if libtool was able to extract symbol"
+		echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		echo "*** not find such a program.  So, this module is probably useless."
+		echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test "$linkmode" = lib; then
+	  if test -n "$dependency_libs" &&
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) func_stripname '-R' '' "$libdir"
+	           temp_xrpath=$func_stripname_result
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) func_append xrpath " $temp_xrpath";;
+		   esac;;
+	      *) func_append temp_deplibs " $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  func_append newlib_search_path " $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    case $deplib in
+              -L*) func_stripname '-L' '' "$deplib"
+                   func_resolve_sysroot "$func_stripname_result";;
+              *) func_resolve_sysroot "$deplib" ;;
+            esac
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $func_resolve_sysroot_result "*)
+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $func_resolve_sysroot_result"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      path=
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+	        func_resolve_sysroot "$deplib"
+	        deplib=$func_resolve_sysroot_result
+	        func_dirname "$deplib" "" "."
+		dir=$func_dirname_result
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if $GREP "^installed=no" $deplib > /dev/null; then
+		case $host in
+		*-*-darwin*)
+		  depdepl=
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+		      func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+		      path=
+		    fi
+		  fi
+		  ;;
+		*)
+		  path="-L$absdir/$objdir"
+		  ;;
+		esac
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  test -z "$libdir" && \
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
+		  test "$absdir" != "$libdir" && \
+		    func_warning "\`$deplib' seems to be moved"
+
+		  path="-L$absdir"
+		fi
+		;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+	else
+	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	fi
+      fi
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) func_append lib_search_path " $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) func_append tmp_libs " $deplib" ;;
+	      esac
+	      ;;
+	    *) func_append tmp_libs " $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=""
+	  ;;
+	esac
+	if test -n "$i" ; then
+	  func_append tmp_libs " $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+    fi
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+	func_warning "\`-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      func_append objs "$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	func_stripname 'lib' '.la' "$outputname"
+	name=$func_stripname_result
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  func_stripname '' '.la' "$outputname"
+	  name=$func_stripname_result
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  func_stripname '' '.la' "$outputname"
+	  libname=$func_stripname_result
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+	else
+	  echo
+	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+	  $ECHO "*** objects $objs is not portable!"
+	  func_append libobjs " $objs"
+	fi
+      fi
+
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+      install_libdir="$1"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a `.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	test -n "$vinfo" && \
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+	test -n "$release" && \
+	  func_warning "\`-release' is ignored for convenience libraries"
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	shift
+	IFS="$save_ifs"
+
+	test -n "$7" && \
+	  func_fatal_help "too many parameters to \`-version-info'"
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major="$1"
+	  number_minor="$2"
+	  number_revision="$3"
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # which has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  # correct linux to gnu/linux during the next big refactor
+	  darwin|linux|osf|windows|none)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|qnx|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_minor"
+	    lt_irix_increment=no
+	    ;;
+	  *)
+	    func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$1"
+	  revision="$2"
+	  age="$3"
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  func_arith $current + 1
+	  minor_current=$func_arith_result
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	irix | nonstopux)
+	  if test "X$lt_irix_increment" = "Xno"; then
+	    func_arith $current - $age
+	  else
+	    func_arith $current - $age + 1
+	  fi
+	  major=$func_arith_result
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring="$verstring_prefix$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test "$loop" -ne 0; do
+	    func_arith $revision - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux) # correct to gnu/linux during the next big refactor
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test "$loop" -ne 0; do
+	    func_arith $current - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  func_append verstring ":${current}.0"
+	  ;;
+
+	qnx)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  func_arith $current - $age
+	  major=$func_arith_result
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  func_fatal_configuration "unknown library version type \`$version_type'"
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" "yes"
+      func_append libobjs " $symfileobj"
+      test "X$libobjs" = "X " && libobjs=
+
+      if test "$opt_mode" != relink; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$ECHO "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext | *.gcno)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
+		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+		 then
+		   continue
+		 fi
+	       fi
+	       func_append removelist " $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	test -n "$removelist" && \
+	  func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	func_append oldlibs " $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+      #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+      #	dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  func_replace_sysroot "$libdir"
+	  func_append temp_xrpath " -R$func_replace_sysroot_result"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) func_append dlfiles " $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) func_append dlprefiles " $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    func_append deplibs " System.ltframework"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      func_append deplibs " -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $opt_dry_run || $RM conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $opt_dry_run || $RM conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    func_append newdeplibs " $i"
+		    i=""
+		    ;;
+		  esac
+		fi
+		if test -n "$i" ; then
+		  libname=`eval "\\$ECHO \"$libname_spec\""`
+		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		  set dummy $deplib_matches; shift
+		  deplib_match=$1
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    func_append newdeplibs " $i"
+		  else
+		    droppeddeps=yes
+		    echo
+		    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		    echo "*** I have the capability to make that library automatically link in when"
+		    echo "*** you link to this library.  But I can only do this if you have a"
+		    echo "*** shared version of the library, which I believe you do not have"
+		    echo "*** because a test_compile did reveal that the linker did not use it for"
+		    echo "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		$opt_dry_run || $RM conftest
+		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+		  ldd_output=`ldd conftest`
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      func_append newdeplibs " $i"
+		      i=""
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i" ; then
+		    libname=`eval "\\$ECHO \"$libname_spec\""`
+		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		    set dummy $deplib_matches; shift
+		    deplib_match=$1
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      func_append newdeplibs " $i"
+		    else
+		      droppeddeps=yes
+		      echo
+		      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		      echo "*** I have the capability to make that library automatically link in when"
+		      echo "*** you link to this library.  But I can only do this if you have a"
+		      echo "*** shared version of the library, which you do not appear to have"
+		      echo "*** because a test_compile did reveal that the linker did not use this one"
+		      echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  echo
+		  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
+		  echo "*** make it link in!  You will probably need to install it or some"
+		  echo "*** library that it depends on before this library will be fully"
+		  echo "*** functional.  Installing it before continuing would be even better."
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method; shift
+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		if test -n "$file_magic_glob"; then
+		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+		else
+		  libnameglob=$libname
+		fi
+		test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  if test "$want_nocaseglob" = yes; then
+		    shopt -s nocaseglob
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		    $nocaseglob
+		  else
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		  fi
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null |
+			 $GREP " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+			 $SED -e 10q |
+			 $EGREP "$file_magic_regex" > /dev/null; then
+			func_append newdeplibs " $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method; shift
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
+		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+		       $EGREP "$match_pattern_regex" > /dev/null; then
+		      func_append newdeplibs " $a_deplib"
+		      a_deplib=""
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+	    done
+	  fi
+	  case $tmp_deplibs in
+	  *[!\	\ ]*)
+	    echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	    ;;
+	  esac
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library with the System framework
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+	  ;;
+	esac
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    echo
+	    echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
+	    echo "*** a static module, that should work as long as the dlopening"
+	    echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      echo
+	      echo "*** However, this would only work if libtool was able to extract symbol"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      echo "*** not find such a program.  So, this module is probably useless."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    echo "*** The inter-library dependencies that have been dropped here will be"
+	    echo "*** automatically added whenever a program is linked with this library"
+	    echo "*** or is declared to -dlopen it."
+
+	    if test "$allow_undefined" = no; then
+	      echo
+	      echo "*** Since this library must not contain undefined symbols,"
+	      echo "*** because either the platform does not support them or"
+	      echo "*** it was explicitly requested with -no-undefined,"
+	      echo "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+	*-*-darwin*)
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  ;;
+      esac
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      deplibs="$new_libs"
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	# Remove ${wl} instances when linking with ld.
+	# FIXME: should test the right _cmds variable.
+	case $archive_cmds in
+	  *\$LD\ *) wl= ;;
+        esac
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		func_replace_sysroot "$libdir"
+		libdir=$func_replace_sysroot_result
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		func_append dep_rpath " $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append perm_rpath " $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      func_append rpath "$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath="$finalize_shlibpath"
+	test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	shift
+	realname="$1"
+	shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib="$output_objdir/$realname"
+	linknames=
+	for link
+	do
+	  func_append linknames " $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	test "X$libobjs" = "X " && libobjs=
+
+	delfiles=
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+	  export_symbols="$output_objdir/$libname.uexp"
+	  func_append delfiles " $export_symbols"
+	fi
+
+	orig_export_symbols=
+	case $host_os in
+	cygwin* | mingw* | cegcc*)
+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+	    # exporting using user supplied symfile
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+	      # and it's NOT already a .def file. Must figure out
+	      # which of the given symbols are data symbols and tag
+	      # them as such. So, trigger use of export_symbols_cmds.
+	      # export_symbols gets reassigned inside the "prepare
+	      # the list of exported symbols" if statement, so the
+	      # include_expsyms logic still works.
+	      orig_export_symbols="$export_symbols"
+	      export_symbols=
+	      always_export_symbols=yes
+	    fi
+	  fi
+	  ;;
+	esac
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $opt_dry_run || $RM $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd1 in $cmds; do
+	      IFS="$save_ifs"
+	      # Take the normal branch if the nm_file_list_spec branch
+	      # doesn't work or if tool conversion is not needed.
+	      case $nm_file_list_spec~$to_tool_file_cmd in
+		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+		  try_normal_branch=yes
+		  eval cmd=\"$cmd1\"
+		  func_len " $cmd"
+		  len=$func_len_result
+		  ;;
+		*)
+		  try_normal_branch=no
+		  ;;
+	      esac
+	      if test "$try_normal_branch" = yes \
+		 && { test "$len" -lt "$max_cmd_len" \
+		      || test "$max_cmd_len" -le -1; }
+	      then
+		func_show_eval "$cmd" 'exit $?'
+		skipped_export=false
+	      elif test -n "$nm_file_list_spec"; then
+		func_basename "$output"
+		output_la=$func_basename_result
+		save_libobjs=$libobjs
+		save_output=$output
+		output=${output_objdir}/${output_la}.nm
+		func_to_tool_file "$output"
+		libobjs=$nm_file_list_spec$func_to_tool_file_result
+		func_append delfiles " $output"
+		func_verbose "creating $NM input file list: $output"
+		for obj in $save_libobjs; do
+		  func_to_tool_file "$obj"
+		  $ECHO "$func_to_tool_file_result"
+		done > "$output"
+		eval cmd=\"$cmd1\"
+		func_show_eval "$cmd" 'exit $?'
+		output=$save_output
+		libobjs=$save_libobjs
+		skipped_export=false
+	      else
+		# The command line is too long to execute in one step.
+		func_verbose "using reloadable object file for export list..."
+		skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	fi
+
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+	  # The given exports_symbols file has to be filtered, so filter it.
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	  # 's' commands which not all seds can handle. GNU sed should be fine
+	  # though. Also, the filter scales superlinearly with the number of
+	  # global variables. join(1) would be nice here, but unfortunately
+	  # isn't a blessed tool.
+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	  export_symbols=$output_objdir/$libname.def
+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+	  case " $convenience " in
+	  *" $test_deplib "*) ;;
+	  *)
+	    func_append tmp_deplibs " $test_deplib"
+	    ;;
+	  esac
+	done
+	deplibs="$tmp_deplibs"
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec" &&
+	    test "$compiler_needs_object" = yes &&
+	    test -z "$libobjs"; then
+	    # extract the archives, so we have objects to list.
+	    # TODO: could optimize this to just extract one archive.
+	    whole_archive_flag_spec=
+	  fi
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    func_append generated " $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    func_append libobjs " $func_extract_archives_result"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  func_append linker_flags " $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$opt_mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test "$module" = yes && test -n "$module_cmds" ; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
+	else
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    eval test_cmds=\"$archive_expsym_cmds\"
+	    cmds=$archive_expsym_cmds
+	  else
+	    eval test_cmds=\"$archive_cmds\"
+	    cmds=$archive_cmds
+	  fi
+	fi
+
+	if test "X$skipped_export" != "X:" &&
+	   func_len " $test_cmds" &&
+	   len=$func_len_result &&
+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise
+	  # or, if using GNU ld and skipped_export is not :, use a linker
+	  # script.
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  func_basename "$output"
+	  output_la=$func_basename_result
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  last_robj=
+	  k=1
+
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    echo 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    echo ')' >> $output
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$func_to_tool_file_result
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
+	    func_verbose "creating linker input file list: $output"
+	    : > $output
+	    set x $save_libobjs
+	    shift
+	    firstobj=
+	    if test "$compiler_needs_object" = yes; then
+	      firstobj="$1 "
+	      shift
+	    fi
+	    for obj
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+	  else
+	    if test -n "$save_libobjs"; then
+	      func_verbose "creating reloadable object files..."
+	      output=$output_objdir/$output_la-${k}.$objext
+	      eval test_cmds=\"$reload_cmds\"
+	      func_len " $test_cmds"
+	      len0=$func_len_result
+	      len=$len0
+
+	      # Loop over the list of objects to be linked.
+	      for obj in $save_libobjs
+	      do
+		func_len " $obj"
+		func_arith $len + $func_len_result
+		len=$func_arith_result
+		if test "X$objlist" = X ||
+		   test "$len" -lt "$max_cmd_len"; then
+		  func_append objlist " $obj"
+		else
+		  # The command $test_cmds is almost too long, add a
+		  # command to the queue.
+		  if test "$k" -eq 1 ; then
+		    # The first file doesn't have a previous command to add.
+		    reload_objs=$objlist
+		    eval concat_cmds=\"$reload_cmds\"
+		  else
+		    # All subsequent reloadable object files will link in
+		    # the last one created.
+		    reload_objs="$objlist $last_robj"
+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+		  fi
+		  last_robj=$output_objdir/$output_la-${k}.$objext
+		  func_arith $k + 1
+		  k=$func_arith_result
+		  output=$output_objdir/$output_la-${k}.$objext
+		  objlist=" $obj"
+		  func_len " $last_robj"
+		  func_arith $len0 + $func_len_result
+		  len=$func_arith_result
+		fi
+	      done
+	      # Handle the remaining objects by creating one last
+	      # reloadable object file.  All subsequent reloadable object
+	      # files will link in the last one created.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      reload_objs="$objlist $last_robj"
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+	      if test -n "$last_robj"; then
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+	      fi
+	      func_append delfiles " $output"
+
+	    else
+	      output=
+	    fi
+
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
+	      $opt_dry_run || $RM $export_symbols
+	      libobjs=$output
+	      # Append the command to create the export file.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+	      if test -n "$last_robj"; then
+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	    fi
+
+	    test -n "$save_libobjs" &&
+	      func_verbose "creating a temporary reloadable object file: $output"
+
+	    # Loop through the commands generated above and execute them.
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $concat_cmds; do
+	      IFS="$save_ifs"
+	      $opt_silent || {
+		  func_quote_for_expand "$cmd"
+		  eval "func_echo $func_quote_for_expand_result"
+	      }
+	      $opt_dry_run || eval "$cmd" || {
+		lt_exit=$?
+
+		# Restore the uninstalled library and exit
+		if test "$opt_mode" = relink; then
+		  ( cd "$output_objdir" && \
+		    $RM "${realname}T" && \
+		    $MV "${realname}U" "$realname" )
+		fi
+
+		exit $lt_exit
+	      }
+	    done
+	    IFS="$save_ifs"
+
+	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+
+          if ${skipped_export-false}; then
+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	    fi
+
+	    if test -n "$orig_export_symbols"; then
+	      # The given exports_symbols file has to be filtered, so filter it.
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	      # 's' commands which not all seds can handle. GNU sed should be fine
+	      # though. Also, the filter scales superlinearly with the number of
+	      # global variables. join(1) would be nice here, but unfortunately
+	      # isn't a blessed tool.
+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	      export_symbols=$output_objdir/$libname.def
+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	    fi
+	  fi
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test "$module" = yes && test -n "$module_cmds" ; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
+	  else
+	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	      cmds=$archive_expsym_cmds
+	    else
+	      cmds=$archive_cmds
+	    fi
+	  fi
+	fi
+
+	if test -n "$delfiles"; then
+	  # Append the command to remove temporary files to $cmds.
+	  eval cmds=\"\$cmds~\$RM $delfiles\"
+	fi
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append libobjs " $func_extract_archives_result"
+	  test "X$libobjs" = "X " && libobjs=
+	fi
+
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $opt_silent || {
+	    func_quote_for_expand "$cmd"
+	    eval "func_echo $func_quote_for_expand_result"
+	  }
+	  $opt_dry_run || eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test "$opt_mode" = relink; then
+	      ( cd "$output_objdir" && \
+	        $RM "${realname}T" && \
+		$MV "${realname}U" "$realname" )
+	    fi
+
+	    exit $lt_exit
+	  }
+	done
+	IFS="$save_ifs"
+
+	# Restore the uninstalled library and exit
+	if test "$opt_mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      func_show_eval '${RM}r "$gentop"'
+	    fi
+	  fi
+
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for objects"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for objects"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for objects"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+	test -n "$objs$old_deplibs" && \
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+	libobj=$output
+	func_lo2o "$libobj"
+	obj=$func_lo2o_result
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $opt_dry_run || $RM $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+	  reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+	else
+	  gentop="$output_objdir/${obj}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # If we're not building shared, we need to use non_pic_objs
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+	func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) func_stripname '' '.exe' "$output"
+	          output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for programs"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for programs"
+
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	;;
+      esac
+
+      case $host in
+      *-*-darwin*)
+	# Don't allow lazy linking, it breaks C++ global constructors
+	# But is supposedly fixed on 10.4 or later (yay!).
+	if test "$tagname" = CXX ; then
+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+	    10.[0123])
+	      func_append compile_command " ${wl}-bind_at_load"
+	      func_append finalize_command " ${wl}-bind_at_load"
+	    ;;
+	  esac
+	fi
+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append perm_rpath " $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  ::) dllsearchpath=$libdir;;
+	  *) func_append dllsearchpath ":$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_perm_rpath " $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+      fi
+
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+	func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
+
+      wrappers_required=yes
+      case $host in
+      *cegcc* | *mingw32ce*)
+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+        wrappers_required=no
+        ;;
+      *cygwin* | *mingw* )
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      *)
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      esac
+      if test "$wrappers_required" = no; then
+	# Replace the output file specification.
+	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	exit_status=0
+	func_show_eval "$link_command" 'exit_status=$?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	# Delete the generated files.
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+	fi
+
+	exit $exit_status
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$opt_dry_run || $RM $output
+	# Link the executable and exit
+	func_show_eval "$link_command" 'exit $?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      func_show_eval "$link_command" 'exit $?'
+
+      if test -n "$postlink_cmds"; then
+	func_to_tool_file "$output_objdir/$outputname"
+	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	func_execute_cmds "$postlink_cmds" 'exit $?'
+      fi
+
+      # Now create the wrapper script.
+      func_verbose "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    func_quote_for_eval "$var_value"
+	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) func_stripname '' '.exe' "$output"
+	         output=$func_stripname_result ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    func_stripname '' '.exe' "$outputname"
+	    outputname=$func_stripname_result ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    func_dirname_and_basename "$output" "" "."
+	    output_name=$func_basename_result
+	    output_path=$func_dirname_result
+	    cwrappersource="$output_path/$objdir/lt-$output_name.c"
+	    cwrapper="$output_path/$output_name.exe"
+	    $RM $cwrappersource $cwrapper
+	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_cwrapperexe_src > $cwrappersource
+
+	    # The wrapper executable is built using the $host compiler,
+	    # because it contains $host paths and files. If cross-
+	    # compiling, it, like the target executable, must be
+	    # executed on the $host or under an emulation environment.
+	    $opt_dry_run || {
+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+	      $STRIP $cwrapper
+	    }
+
+	    # Now, create the wrapper script for func_source use:
+	    func_ltwrapper_scriptname $cwrapper
+	    $RM $func_ltwrapper_scriptname_result
+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+	    $opt_dry_run || {
+	      # note: this script will not be executed, so do not chmod.
+	      if test "x$build" = "x$host" ; then
+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+	      else
+		func_emit_wrapper no > $func_ltwrapper_scriptname_result
+	      fi
+	    }
+	  ;;
+	  * )
+	    $RM $output
+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_wrapper no > $output
+	    chmod +x $output
+	  ;;
+	esac
+      }
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save $symfileobj"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$old_deplibs $non_pic_objects"
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    func_append oldobjs " $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	func_append generated " $gentop"
+
+	func_extract_archives $gentop $addlibs
+	func_append oldobjs " $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	cmds=$old_archive_from_new_cmds
+      else
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append oldobjs " $func_extract_archives_result"
+	fi
+
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      func_basename "$obj"
+	      $ECHO "$func_basename_result"
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  echo "copying selected object files to avoid basename conflicts..."
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+	  func_mkdir_p "$gentop"
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    func_basename "$obj"
+	    objbase="$func_basename_result"
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		func_arith $counter + 1
+		counter=$func_arith_result
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      func_append oldobjs " $gentop/$newobj"
+	      ;;
+	    *) func_append oldobjs " $obj" ;;
+	    esac
+	  done
+	fi
+	func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+	tool_oldlib=$func_to_tool_file_result
+	eval cmds=\"$old_archive_cmds\"
+
+	func_len " $cmds"
+	len=$func_len_result
+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	elif test -n "$archiver_list_spec"; then
+	  func_verbose "using command file archive linking..."
+	  for obj in $oldobjs
+	  do
+	    func_to_tool_file "$obj"
+	    $ECHO "$func_to_tool_file_result"
+	  done > $output_objdir/$libname.libcmd
+	  func_to_tool_file "$output_objdir/$libname.libcmd"
+	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  func_verbose "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  eval test_cmds=\"$old_archive_cmds\"
+	  func_len " $test_cmds"
+	  len0=$func_len_result
+	  len=$len0
+	  for obj in $save_oldobjs
+	  do
+	    func_len " $obj"
+	    func_arith $len + $func_len_result
+	    len=$func_arith_result
+	    func_append objlist " $obj"
+	    if test "$len" -lt "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj" ; then
+		RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+	      objlist=
+	      len=$len0
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test "X$oldobjs" = "X" ; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      func_execute_cmds "$cmds" 'exit $?'
+    done
+
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      func_verbose "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  func_quote_for_eval "$var_value"
+	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+	relink_command=
+      fi
+
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		func_basename "$deplib"
+		name="$func_basename_result"
+		func_resolve_sysroot "$deplib"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
+		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      -L*)
+		func_stripname -L '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -L$func_replace_sysroot_result"
+		;;
+	      -R*)
+		func_stripname -R '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -R$func_replace_sysroot_result"
+		;;
+	      *) func_append newdependency_libs " $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+
+	    for lib in $dlfiles; do
+	      case $lib in
+	      *.la)
+	        func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      *) func_append newdlfiles " $lib" ;;
+	      esac
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+	      *.la)
+		# Only pass preopened files to the pseudo-archive (for
+		# eventual linking with the app. that links it) if we
+		# didn't already link the preopened objects directly into
+		# the library:
+		func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      esac
+	    done
+	    dlprefiles="$newdlprefiles"
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlfiles " $abs"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlprefiles " $abs"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $RM $output
+	  # place dlname in correct position for cygwin
+	  # In fact, it would be nice if we could use this code for all target
+	  # systems that can't hard-code library paths into their executables
+	  # and that have no shared library path variable independent of PATH,
+	  # but it turns out we can't easily determine that from inspecting
+	  # libtool variables, so we have to hard-code the OSs to which it
+	  # applies here; at the moment, that means platforms that use the PE
+	  # object format with DLL files.  See the long comment at the top of
+	  # tests/bindir.at for full details.
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+	      # If a -bindir argument was supplied, place the dll there.
+	      if test "x$bindir" != x ;
+	      then
+		func_relative_path "$install_libdir" "$bindir"
+		tdlname=$func_relative_path_result$dlname
+	      else
+		# Otherwise fall back on heuristic.
+		tdlname=../bin/$dlname
+	      fi
+	      ;;
+	  esac
+	  $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test "$need_relink" = yes; then
+	    $ECHO >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      }
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+    func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $opt_debug
+    RM="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) func_append RM " $arg"; rmforce=yes ;;
+      -*) func_append RM " $arg" ;;
+      *) func_append files " $arg" ;;
+      esac
+    done
+
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
+
+    rmdirs=
+
+    for file in $files; do
+      func_dirname "$file" "" "."
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	odir="$objdir"
+      else
+	odir="$dir/$objdir"
+      fi
+      func_basename "$file"
+      name="$func_basename_result"
+      test "$opt_mode" = uninstall && odir="$dir"
+
+      # Remember odir for removal later, being careful to avoid duplicates
+      if test "$opt_mode" = clean; then
+	case " $rmdirs " in
+	  *" $odir "*) ;;
+	  *) func_append rmdirs " $odir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if { test -L "$file"; } >/dev/null 2>&1 ||
+	 { test -h "$file"; } >/dev/null 2>&1 ||
+	 test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif test "$rmforce" = yes; then
+	continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if func_lalib_p "$file"; then
+	  func_source $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    func_append rmfiles " $odir/$n"
+	  done
+	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+	  case "$opt_mode" in
+	  clean)
+	    case " $library_names " in
+	    *" $dlname "*) ;;
+	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+	    esac
+	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if func_lalib_p "$file"; then
+
+	  # Read the .lo file
+	  func_source $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
+	    func_append rmfiles " $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" &&
+	     test "$non_pic_object" != none; then
+	    func_append rmfiles " $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test "$opt_mode" = clean ; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    func_stripname '' '.exe' "$file"
+	    file=$func_stripname_result
+	    func_stripname '' '.exe' "$name"
+	    noexename=$func_stripname_result
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    func_append rmfiles " $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if func_ltwrapper_p "$file"; then
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      relink_command=
+	      func_source $func_ltwrapper_scriptname_result
+	      func_append rmfiles " $func_ltwrapper_scriptname_result"
+	    else
+	      relink_command=
+	      func_source $dir/$noexename
+	    fi
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
+	      func_append rmfiles " $odir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name" ; then
+	      func_append rmfiles " $odir/lt-${noexename}.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
+    done
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	func_show_eval "rmdir $dir >/dev/null 2>&1"
+      fi
+    done
+
+    exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+  help="$generic_help"
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+  eval exec "$exec_cmd"
+  exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/protobuf/gtest/build-aux/missing b/protobuf/gtest/build-aux/missing
new file mode 100755
index 0000000..db98974
--- /dev/null
+++ b/protobuf/gtest/build-aux/missing
@@ -0,0 +1,215 @@
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2013-10-28.13; # UTC
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try '$0 --help' for more information"
+  exit 1
+fi
+
+case $1 in
+
+  --is-lightweight)
+    # Used by our autoconf macros to check whether the available missing
+    # script is modern enough.
+    exit 0
+    ;;
+
+  --run)
+    # Back-compat with the calling convention used by older automake.
+    shift
+    ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal   autoconf  autoheader   autom4te  automake  makeinfo
+  bison     yacc      flex         lex       help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: unknown '$1' option"
+    echo 1>&2 "Try '$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch.  This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+  msg="probably too old"
+elif test $st -eq 127; then
+  # Program was missing.
+  msg="missing on your system"
+else
+  # Program was found and executed, but failed.  Give up.
+  exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+  case $1 in
+    aclocal|automake)
+      echo "The '$1' program is part of the GNU Automake package:"
+      echo "<$gnu_software_URL/automake>"
+      echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/autoconf>"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+    autoconf|autom4te|autoheader)
+      echo "The '$1' program is part of the GNU Autoconf package:"
+      echo "<$gnu_software_URL/autoconf/>"
+      echo "It also requires GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+  esac
+}
+
+give_advice ()
+{
+  # Normalize program name to check for.
+  normalized_program=`echo "$1" | sed '
+    s/^gnu-//; t
+    s/^gnu//; t
+    s/^g//; t'`
+
+  printf '%s\n' "'$1' is $msg."
+
+  configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+  case $normalized_program in
+    autoconf*)
+      echo "You should only need it if you modified 'configure.ac',"
+      echo "or m4 files included by it."
+      program_details 'autoconf'
+      ;;
+    autoheader*)
+      echo "You should only need it if you modified 'acconfig.h' or"
+      echo "$configure_deps."
+      program_details 'autoheader'
+      ;;
+    automake*)
+      echo "You should only need it if you modified 'Makefile.am' or"
+      echo "$configure_deps."
+      program_details 'automake'
+      ;;
+    aclocal*)
+      echo "You should only need it if you modified 'acinclude.m4' or"
+      echo "$configure_deps."
+      program_details 'aclocal'
+      ;;
+   autom4te*)
+      echo "You might have modified some maintainer files that require"
+      echo "the 'autom4te' program to be rebuilt."
+      program_details 'autom4te'
+      ;;
+    bison*|yacc*)
+      echo "You should only need it if you modified a '.y' file."
+      echo "You may want to install the GNU Bison package:"
+      echo "<$gnu_software_URL/bison/>"
+      ;;
+    lex*|flex*)
+      echo "You should only need it if you modified a '.l' file."
+      echo "You may want to install the Fast Lexical Analyzer package:"
+      echo "<$flex_URL>"
+      ;;
+    help2man*)
+      echo "You should only need it if you modified a dependency" \
+           "of a man page."
+      echo "You may want to install the GNU Help2man package:"
+      echo "<$gnu_software_URL/help2man/>"
+    ;;
+    makeinfo*)
+      echo "You should only need it if you modified a '.texi' file, or"
+      echo "any other file indirectly affecting the aspect of the manual."
+      echo "You might want to install the Texinfo package:"
+      echo "<$gnu_software_URL/texinfo/>"
+      echo "The spurious makeinfo call might also be the consequence of"
+      echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+      echo "want to install GNU make:"
+      echo "<$gnu_software_URL/make/>"
+      ;;
+    *)
+      echo "You might have modified some files without having the proper"
+      echo "tools for further handling them.  Check the 'README' file, it"
+      echo "often tells you about the needed prerequisites for installing"
+      echo "this package.  You may also peek at any GNU archive site, in"
+      echo "case some other package contains this missing '$1' program."
+      ;;
+  esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+                       -e '2,$s/^/         /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/protobuf/gtest/build-aux/test-driver b/protobuf/gtest/build-aux/test-driver
new file mode 100755
index 0000000..d306056
--- /dev/null
+++ b/protobuf/gtest/build-aux/test-driver
@@ -0,0 +1,139 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2013-07-13.22; # UTC
+
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error.  This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+  echo "$0: $*" >&2
+  print_usage >&2
+  exit 2
+}
+
+print_usage ()
+{
+  cat <<END
+Usage:
+  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+              [--expect-failure={yes|no}] [--color-tests={yes|no}]
+              [--enable-hard-errors={yes|no}] [--]
+              TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+test_name= # Used for reporting.
+log_file=  # Where to save the output of the test script.
+trs_file=  # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+  case $1 in
+  --help) print_usage; exit $?;;
+  --version) echo "test-driver $scriptversion"; exit $?;;
+  --test-name) test_name=$2; shift;;
+  --log-file) log_file=$2; shift;;
+  --trs-file) trs_file=$2; shift;;
+  --color-tests) color_tests=$2; shift;;
+  --expect-failure) expect_failure=$2; shift;;
+  --enable-hard-errors) enable_hard_errors=$2; shift;;
+  --) shift; break;;
+  -*) usage_error "invalid option: '$1'";;
+   *) break;;
+  esac
+  shift
+done
+
+missing_opts=
+test x"$test_name" = x && missing_opts="$missing_opts --test-name"
+test x"$log_file"  = x && missing_opts="$missing_opts --log-file"
+test x"$trs_file"  = x && missing_opts="$missing_opts --trs-file"
+if test x"$missing_opts" != x; then
+  usage_error "the following mandatory options are missing:$missing_opts"
+fi
+
+if test $# -eq 0; then
+  usage_error "missing argument"
+fi
+
+if test $color_tests = yes; then
+  # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+  red='' # Red.
+  grn='' # Green.
+  lgn='' # Light green.
+  blu='' # Blue.
+  mgn='' # Magenta.
+  std=''     # No color.
+else
+  red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+  estatus=1
+fi
+
+case $estatus:$expect_failure in
+  0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+  0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
+  77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
+  99:*)  col=$mgn res=ERROR recheck=yes gcopy=yes;;
+  *:yes) col=$lgn res=XFAIL recheck=no  gcopy=yes;;
+  *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;
+esac
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/protobuf/gtest/codegear/gtest.cbproj b/protobuf/gtest/codegear/gtest.cbproj
new file mode 100644
index 0000000..95c3054
--- /dev/null
+++ b/protobuf/gtest/codegear/gtest.cbproj
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <PropertyGroup>

+    <ProjectGuid>{bca37a72-5b07-46cf-b44e-89f8e06451a2}</ProjectGuid>

+    <Config Condition="'$(Config)'==''">Release</Config>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">

+    <Base>true</Base>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">

+    <Base>true</Base>

+    <Cfg_1>true</Cfg_1>

+    <CfgParent>Base</CfgParent>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">

+    <Base>true</Base>

+    <Cfg_2>true</Cfg_2>

+    <CfgParent>Base</CfgParent>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Base)'!=''">

+    <BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>

+    <OutputExt>lib</OutputExt>

+    <DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput>

+    <Defines>NO_STRICT</Defines>

+    <DynamicRTL>true</DynamicRTL>

+    <UsePackages>true</UsePackages>

+    <ProjectType>CppStaticLibrary</ProjectType>

+    <BCC_CPPCompileAlways>true</BCC_CPPCompileAlways>

+    <PackageImports>rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi</PackageImports>

+    <BCC_wpar>false</BCC_wpar>

+    <IncludePath>$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</IncludePath>

+    <AllPackageLibs>rtl.lib;vcl.lib</AllPackageLibs>

+    <TLIB_PageSize>32</TLIB_PageSize>

+    <ILINK_LibraryPath>$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk</ILINK_LibraryPath>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Cfg_1)'!=''">

+    <BCC_OptimizeForSpeed>false</BCC_OptimizeForSpeed>

+    <DCC_Optimize>false</DCC_Optimize>

+    <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>

+    <Defines>_DEBUG;$(Defines)</Defines>

+    <ILINK_FullDebugInfo>true</ILINK_FullDebugInfo>

+    <BCC_InlineFunctionExpansion>false</BCC_InlineFunctionExpansion>

+    <ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>

+    <BCC_UseRegisterVariables>None</BCC_UseRegisterVariables>

+    <DCC_Define>DEBUG</DCC_Define>

+    <BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>

+    <IntermediateOutputDir>Debug</IntermediateOutputDir>

+    <TASM_DisplaySourceLines>true</TASM_DisplaySourceLines>

+    <BCC_StackFrames>true</BCC_StackFrames>

+    <BCC_DisableOptimizations>true</BCC_DisableOptimizations>

+    <ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>

+    <TASM_Debugging>Full</TASM_Debugging>

+    <BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Cfg_2)'!=''">

+    <Defines>NDEBUG;$(Defines)</Defines>

+    <IntermediateOutputDir>Release</IntermediateOutputDir>

+    <ILINK_LibraryPath>$(BDS)\lib\release;$(ILINK_LibraryPath)</ILINK_LibraryPath>

+    <TASM_Debugging>None</TASM_Debugging>

+  </PropertyGroup>

+  <ProjectExtensions>

+    <Borland.Personality>CPlusPlusBuilder.Personality</Borland.Personality>

+    <Borland.ProjectType>CppStaticLibrary</Borland.ProjectType>

+    <BorlandProject>

+<BorlandProject><CPlusPlusBuilder.Personality><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1033</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Debugging><Debugging Name="DebugSourceDirs"></Debugging></Debugging><Parameters><Parameters Name="RunParams"></Parameters><Parameters Name="Launcher"></Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="DebugCWD"></Parameters><Parameters Name="HostApplication"></Parameters><Parameters Name="RemoteHost"></Parameters><Parameters Name="RemotePath"></Parameters><Parameters Name="RemoteParams"></Parameters><Parameters Name="RemoteLauncher"></Parameters><Parameters Name="UseRemoteLauncher">False</Parameters><Parameters Name="RemoteCWD"></Parameters><Parameters Name="RemoteDebug">False</Parameters><Parameters Name="Debug Symbols Search Path"></Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><Excluded_Packages>

+      

+      

+      <Excluded_Packages Name="$(BDS)\bin\bcboffice2k100.bpl">CodeGear C++Builder Office 2000 Servers Package</Excluded_Packages>

+      <Excluded_Packages Name="$(BDS)\bin\bcbofficexp100.bpl">CodeGear C++Builder Office XP Servers Package</Excluded_Packages>

+    </Excluded_Packages><Linker><Linker Name="LibPrefix"></Linker><Linker Name="LibSuffix"></Linker><Linker Name="LibVersion"></Linker></Linker><ProjectProperties><ProjectProperties Name="AutoShowDeps">False</ProjectProperties><ProjectProperties Name="ManagePaths">True</ProjectProperties><ProjectProperties Name="VerifyPackages">True</ProjectProperties></ProjectProperties><HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Count">3</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item0">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item1">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item2">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include</HistoryLists_hlIncludePath></HistoryLists_hlIncludePath><HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Count">1</HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Item0">$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk</HistoryLists_hlILINK_LibraryPath></HistoryLists_hlILINK_LibraryPath><HistoryLists_hlDefines><HistoryLists_hlDefines Name="Count">1</HistoryLists_hlDefines><HistoryLists_hlDefines Name="Item0">NO_STRICT</HistoryLists_hlDefines></HistoryLists_hlDefines><HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Count">1</HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Item0">32</HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Item1">16</HistoryLists_hlTLIB_PageSize></HistoryLists_hlTLIB_PageSize></CPlusPlusBuilder.Personality></BorlandProject></BorlandProject>

+  </ProjectExtensions>

+  <Import Project="$(MSBuildBinPath)\Borland.Cpp.Targets" />

+  <ItemGroup>

+    <None Include="..\include\gtest\gtest-death-test.h">

+      <BuildOrder>3</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\gtest-message.h">

+      <BuildOrder>4</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\gtest-param-test.h">

+      <BuildOrder>5</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\gtest-spi.h">

+      <BuildOrder>6</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\gtest-test-part.h">

+      <BuildOrder>7</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\gtest-typed-test.h">

+      <BuildOrder>8</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\gtest.h">

+      <BuildOrder>0</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\gtest_pred_impl.h">

+      <BuildOrder>1</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\gtest_prod.h">

+      <BuildOrder>2</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\internal\gtest-death-test-internal.h">

+      <BuildOrder>9</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\internal\gtest-filepath.h">

+      <BuildOrder>10</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\internal\gtest-internal.h">

+      <BuildOrder>11</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\internal\gtest-linked_ptr.h">

+      <BuildOrder>12</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\internal\gtest-param-util-generated.h">

+      <BuildOrder>14</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\internal\gtest-param-util.h">

+      <BuildOrder>13</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\internal\gtest-port.h">

+      <BuildOrder>15</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\internal\gtest-string.h">

+      <BuildOrder>16</BuildOrder>

+    </None>

+    <None Include="..\include\gtest\internal\gtest-type-util.h">

+      <BuildOrder>17</BuildOrder>

+    </None>

+    <CppCompile Include="gtest_all.cc">

+      <BuildOrder>18</BuildOrder>

+    </CppCompile>

+    <BuildConfiguration Include="Debug">

+      <Key>Cfg_1</Key>

+    </BuildConfiguration>

+    <BuildConfiguration Include="Release">

+      <Key>Cfg_2</Key>

+    </BuildConfiguration>

+  </ItemGroup>

+</Project>
\ No newline at end of file
diff --git a/protobuf/gtest/codegear/gtest.groupproj b/protobuf/gtest/codegear/gtest.groupproj
new file mode 100644
index 0000000..faf31ca
--- /dev/null
+++ b/protobuf/gtest/codegear/gtest.groupproj
@@ -0,0 +1,54 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <PropertyGroup>

+    <ProjectGuid>{c1d923e0-6cba-4332-9b6f-3420acbf5091}</ProjectGuid>

+  </PropertyGroup>

+  <ItemGroup />

+  <ItemGroup>

+    <Projects Include="gtest.cbproj" />

+    <Projects Include="gtest_main.cbproj" />

+    <Projects Include="gtest_unittest.cbproj" />

+  </ItemGroup>

+  <ProjectExtensions>

+    <Borland.Personality>Default.Personality</Borland.Personality>

+    <Borland.ProjectType />

+    <BorlandProject>

+<BorlandProject xmlns=""><Default.Personality></Default.Personality></BorlandProject></BorlandProject>

+  </ProjectExtensions>

+  <Target Name="gtest">

+    <MSBuild Projects="gtest.cbproj" Targets="" />

+  </Target>

+  <Target Name="gtest:Clean">

+    <MSBuild Projects="gtest.cbproj" Targets="Clean" />

+  </Target>

+  <Target Name="gtest:Make">

+    <MSBuild Projects="gtest.cbproj" Targets="Make" />

+  </Target>

+  <Target Name="gtest_main">

+    <MSBuild Projects="gtest_main.cbproj" Targets="" />

+  </Target>

+  <Target Name="gtest_main:Clean">

+    <MSBuild Projects="gtest_main.cbproj" Targets="Clean" />

+  </Target>

+  <Target Name="gtest_main:Make">

+    <MSBuild Projects="gtest_main.cbproj" Targets="Make" />

+  </Target>

+  <Target Name="gtest_unittest">

+    <MSBuild Projects="gtest_unittest.cbproj" Targets="" />

+  </Target>

+  <Target Name="gtest_unittest:Clean">

+    <MSBuild Projects="gtest_unittest.cbproj" Targets="Clean" />

+  </Target>

+  <Target Name="gtest_unittest:Make">

+    <MSBuild Projects="gtest_unittest.cbproj" Targets="Make" />

+  </Target>

+  <Target Name="Build">

+    <CallTarget Targets="gtest;gtest_main;gtest_unittest" />

+  </Target>

+  <Target Name="Clean">

+    <CallTarget Targets="gtest:Clean;gtest_main:Clean;gtest_unittest:Clean" />

+  </Target>

+  <Target Name="Make">

+    <CallTarget Targets="gtest:Make;gtest_main:Make;gtest_unittest:Make" />

+  </Target>

+  <Import Condition="Exists('$(MSBuildBinPath)\Borland.Group.Targets')" Project="$(MSBuildBinPath)\Borland.Group.Targets" />

+</Project>
\ No newline at end of file
diff --git a/protobuf/gtest/codegear/gtest_all.cc b/protobuf/gtest/codegear/gtest_all.cc
new file mode 100644
index 0000000..121b2d8
--- /dev/null
+++ b/protobuf/gtest/codegear/gtest_all.cc
@@ -0,0 +1,38 @@
+// Copyright 2009, 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: Josh Kelley (joshkel@gmail.com)

+//

+// Google C++ Testing Framework (Google Test)

+//

+// C++Builder's IDE cannot build a static library from files with hyphens

+// in their name.  See http://qc.codegear.com/wc/qcmain.aspx?d=70977 .

+// This file serves as a workaround.

+

+#include "src/gtest-all.cc"

diff --git a/protobuf/gtest/codegear/gtest_link.cc b/protobuf/gtest/codegear/gtest_link.cc
new file mode 100644
index 0000000..918eccd
--- /dev/null
+++ b/protobuf/gtest/codegear/gtest_link.cc
@@ -0,0 +1,40 @@
+// Copyright 2009, 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: Josh Kelley (joshkel@gmail.com)

+//

+// Google C++ Testing Framework (Google Test)

+//

+// Links gtest.lib and gtest_main.lib into the current project in C++Builder.

+// This means that these libraries can't be renamed, but it's the only way to

+// ensure that Debug versus Release test builds are linked against the

+// appropriate Debug or Release build of the libraries.

+

+#pragma link "gtest.lib"

+#pragma link "gtest_main.lib"

diff --git a/protobuf/gtest/codegear/gtest_main.cbproj b/protobuf/gtest/codegear/gtest_main.cbproj
new file mode 100644
index 0000000..d76ce13
--- /dev/null
+++ b/protobuf/gtest/codegear/gtest_main.cbproj
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <PropertyGroup>

+    <ProjectGuid>{bca37a72-5b07-46cf-b44e-89f8e06451a2}</ProjectGuid>

+    <Config Condition="'$(Config)'==''">Release</Config>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">

+    <Base>true</Base>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">

+    <Base>true</Base>

+    <Cfg_1>true</Cfg_1>

+    <CfgParent>Base</CfgParent>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">

+    <Base>true</Base>

+    <Cfg_2>true</Cfg_2>

+    <CfgParent>Base</CfgParent>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Base)'!=''">

+    <BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>

+    <OutputExt>lib</OutputExt>

+    <DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput>

+    <Defines>NO_STRICT</Defines>

+    <DynamicRTL>true</DynamicRTL>

+    <UsePackages>true</UsePackages>

+    <ProjectType>CppStaticLibrary</ProjectType>

+    <BCC_CPPCompileAlways>true</BCC_CPPCompileAlways>

+    <PackageImports>rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;dclZipForged11.bpi;vclZipForged11.bpi;GR32_BDS2006.bpi;GR32_DSGN_BDS2006.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi;CExceptionExpert11.bpi</PackageImports>

+    <BCC_wpar>false</BCC_wpar>

+    <IncludePath>$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</IncludePath>

+    <AllPackageLibs>rtl.lib;vcl.lib</AllPackageLibs>

+    <TLIB_PageSize>32</TLIB_PageSize>

+    <ILINK_LibraryPath>$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk</ILINK_LibraryPath>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Cfg_1)'!=''">

+    <BCC_OptimizeForSpeed>false</BCC_OptimizeForSpeed>

+    <DCC_Optimize>false</DCC_Optimize>

+    <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>

+    <Defines>_DEBUG;$(Defines)</Defines>

+    <ILINK_FullDebugInfo>true</ILINK_FullDebugInfo>

+    <BCC_InlineFunctionExpansion>false</BCC_InlineFunctionExpansion>

+    <ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>

+    <BCC_UseRegisterVariables>None</BCC_UseRegisterVariables>

+    <DCC_Define>DEBUG</DCC_Define>

+    <BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>

+    <IntermediateOutputDir>Debug</IntermediateOutputDir>

+    <TASM_DisplaySourceLines>true</TASM_DisplaySourceLines>

+    <BCC_StackFrames>true</BCC_StackFrames>

+    <BCC_DisableOptimizations>true</BCC_DisableOptimizations>

+    <ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>

+    <TASM_Debugging>Full</TASM_Debugging>

+    <BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Cfg_2)'!=''">

+    <Defines>NDEBUG;$(Defines)</Defines>

+    <IntermediateOutputDir>Release</IntermediateOutputDir>

+    <ILINK_LibraryPath>$(BDS)\lib\release;$(ILINK_LibraryPath)</ILINK_LibraryPath>

+    <TASM_Debugging>None</TASM_Debugging>

+  </PropertyGroup>

+  <ProjectExtensions>

+    <Borland.Personality>CPlusPlusBuilder.Personality</Borland.Personality>

+    <Borland.ProjectType>CppStaticLibrary</Borland.ProjectType>

+    <BorlandProject>

+<BorlandProject><CPlusPlusBuilder.Personality><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1033</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Debugging><Debugging Name="DebugSourceDirs"></Debugging></Debugging><Parameters><Parameters Name="RunParams"></Parameters><Parameters Name="Launcher"></Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="DebugCWD"></Parameters><Parameters Name="HostApplication"></Parameters><Parameters Name="RemoteHost"></Parameters><Parameters Name="RemotePath"></Parameters><Parameters Name="RemoteParams"></Parameters><Parameters Name="RemoteLauncher"></Parameters><Parameters Name="UseRemoteLauncher">False</Parameters><Parameters Name="RemoteCWD"></Parameters><Parameters Name="RemoteDebug">False</Parameters><Parameters Name="Debug Symbols Search Path"></Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><Excluded_Packages>

+      <Excluded_Packages Name="$(BDS)\bin\bcboffice2k100.bpl">CodeGear C++Builder Office 2000 Servers Package</Excluded_Packages>

+      <Excluded_Packages Name="$(BDS)\bin\bcbofficexp100.bpl">CodeGear C++Builder Office XP Servers Package</Excluded_Packages>

+    </Excluded_Packages><Linker><Linker Name="LibPrefix"></Linker><Linker Name="LibSuffix"></Linker><Linker Name="LibVersion"></Linker></Linker><ProjectProperties><ProjectProperties Name="AutoShowDeps">False</ProjectProperties><ProjectProperties Name="ManagePaths">True</ProjectProperties><ProjectProperties Name="VerifyPackages">True</ProjectProperties></ProjectProperties><HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Count">3</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item0">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item1">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\include;..</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item2">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\src;..\src;..\include</HistoryLists_hlIncludePath></HistoryLists_hlIncludePath><HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Count">1</HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Item0">$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk</HistoryLists_hlILINK_LibraryPath></HistoryLists_hlILINK_LibraryPath><HistoryLists_hlDefines><HistoryLists_hlDefines Name="Count">1</HistoryLists_hlDefines><HistoryLists_hlDefines Name="Item0">NO_STRICT</HistoryLists_hlDefines></HistoryLists_hlDefines><HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Count">1</HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Item0">32</HistoryLists_hlTLIB_PageSize><HistoryLists_hlTLIB_PageSize Name="Item1">16</HistoryLists_hlTLIB_PageSize></HistoryLists_hlTLIB_PageSize></CPlusPlusBuilder.Personality></BorlandProject></BorlandProject>

+  </ProjectExtensions>

+  <Import Project="$(MSBuildBinPath)\Borland.Cpp.Targets" />

+  <ItemGroup>

+    <CppCompile Include="..\src\gtest_main.cc">

+      <BuildOrder>0</BuildOrder>

+    </CppCompile>

+    <BuildConfiguration Include="Debug">

+      <Key>Cfg_1</Key>

+    </BuildConfiguration>

+    <BuildConfiguration Include="Release">

+      <Key>Cfg_2</Key>

+    </BuildConfiguration>

+  </ItemGroup>

+</Project>

diff --git a/protobuf/gtest/codegear/gtest_unittest.cbproj b/protobuf/gtest/codegear/gtest_unittest.cbproj
new file mode 100644
index 0000000..dc5db8e
--- /dev/null
+++ b/protobuf/gtest/codegear/gtest_unittest.cbproj
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

+  <PropertyGroup>

+    <ProjectGuid>{eea63393-5ac5-4b9c-8909-d75fef2daa41}</ProjectGuid>

+    <Config Condition="'$(Config)'==''">Release</Config>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">

+    <Base>true</Base>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">

+    <Base>true</Base>

+    <Cfg_1>true</Cfg_1>

+    <CfgParent>Base</CfgParent>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">

+    <Base>true</Base>

+    <Cfg_2>true</Cfg_2>

+    <CfgParent>Base</CfgParent>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Base)'!=''">

+    <OutputExt>exe</OutputExt>

+    <BCC_OptimizeForSpeed>true</BCC_OptimizeForSpeed>

+    <Defines>NO_STRICT</Defines>

+    <DCC_CBuilderOutput>JPHNE</DCC_CBuilderOutput>

+    <DynamicRTL>true</DynamicRTL>

+    <ILINK_ObjectSearchPath>..\test</ILINK_ObjectSearchPath>

+    <UsePackages>true</UsePackages>

+    <ProjectType>CppConsoleApplication</ProjectType>

+    <NoVCL>true</NoVCL>

+    <BCC_CPPCompileAlways>true</BCC_CPPCompileAlways>

+    <PackageImports>rtl.bpi;vcl.bpi;bcbie.bpi;vclx.bpi;vclactnband.bpi;xmlrtl.bpi;bcbsmp.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;dsnap.bpi;dsnapcon.bpi;vclib.bpi;ibxpress.bpi;adortl.bpi;dbxcds.bpi;dbexpress.bpi;DbxCommonDriver.bpi;websnap.bpi;vclie.bpi;webdsnap.bpi;inet.bpi;inetdbbde.bpi;inetdbxpress.bpi;soaprtl.bpi;Rave75VCL.bpi;teeUI.bpi;tee.bpi;teedb.bpi;IndyCore.bpi;IndySystem.bpi;IndyProtocols.bpi;IntrawebDB_90_100.bpi;Intraweb_90_100.bpi;Jcl.bpi;JclVcl.bpi;JvCoreD11R.bpi;JvSystemD11R.bpi;JvStdCtrlsD11R.bpi;JvAppFrmD11R.bpi;JvBandsD11R.bpi;JvDBD11R.bpi;JvDlgsD11R.bpi;JvBDED11R.bpi;JvCmpD11R.bpi;JvCryptD11R.bpi;JvCtrlsD11R.bpi;JvCustomD11R.bpi;JvDockingD11R.bpi;JvDotNetCtrlsD11R.bpi;JvEDID11R.bpi;JvGlobusD11R.bpi;JvHMID11R.bpi;JvInterpreterD11R.bpi;JvJansD11R.bpi;JvManagedThreadsD11R.bpi;JvMMD11R.bpi;JvNetD11R.bpi;JvPageCompsD11R.bpi;JvPluginD11R.bpi;JvPrintPreviewD11R.bpi;JvRuntimeDesignD11R.bpi;JvTimeFrameworkD11R.bpi;JvValidatorsD11R.bpi;JvWizardD11R.bpi;JvXPCtrlsD11R.bpi;VclSmp.bpi</PackageImports>

+    <BCC_wpar>false</BCC_wpar>

+    <IncludePath>$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..</IncludePath>

+    <ILINK_LibraryPath>$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test</ILINK_LibraryPath>

+    <Multithreaded>true</Multithreaded>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Cfg_1)'!=''">

+    <BCC_OptimizeForSpeed>false</BCC_OptimizeForSpeed>

+    <DCC_Optimize>false</DCC_Optimize>

+    <DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>

+    <Defines>_DEBUG;$(Defines)</Defines>

+    <ILINK_FullDebugInfo>true</ILINK_FullDebugInfo>

+    <BCC_InlineFunctionExpansion>false</BCC_InlineFunctionExpansion>

+    <ILINK_DisableIncrementalLinking>true</ILINK_DisableIncrementalLinking>

+    <BCC_UseRegisterVariables>None</BCC_UseRegisterVariables>

+    <DCC_Define>DEBUG</DCC_Define>

+    <BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>

+    <IntermediateOutputDir>Debug</IntermediateOutputDir>

+    <TASM_DisplaySourceLines>true</TASM_DisplaySourceLines>

+    <BCC_StackFrames>true</BCC_StackFrames>

+    <BCC_DisableOptimizations>true</BCC_DisableOptimizations>

+    <ILINK_LibraryPath>$(BDS)\lib\debug;$(ILINK_LibraryPath)</ILINK_LibraryPath>

+    <TASM_Debugging>Full</TASM_Debugging>

+    <BCC_SourceDebuggingOn>true</BCC_SourceDebuggingOn>

+  </PropertyGroup>

+  <PropertyGroup Condition="'$(Cfg_2)'!=''">

+    <Defines>NDEBUG;$(Defines)</Defines>

+    <IntermediateOutputDir>Release</IntermediateOutputDir>

+    <ILINK_LibraryPath>$(BDS)\lib\release;$(ILINK_LibraryPath)</ILINK_LibraryPath>

+    <TASM_Debugging>None</TASM_Debugging>

+  </PropertyGroup>

+  <ProjectExtensions>

+    <Borland.Personality>CPlusPlusBuilder.Personality</Borland.Personality>

+    <Borland.ProjectType>CppConsoleApplication</Borland.ProjectType>

+    <BorlandProject>

+<BorlandProject><CPlusPlusBuilder.Personality><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1033</VersionInfo><VersionInfo Name="CodePage">1252</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Debugging><Debugging Name="DebugSourceDirs"></Debugging></Debugging><Parameters><Parameters Name="RunParams"></Parameters><Parameters Name="Launcher"></Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="DebugCWD"></Parameters><Parameters Name="HostApplication"></Parameters><Parameters Name="RemoteHost"></Parameters><Parameters Name="RemotePath"></Parameters><Parameters Name="RemoteParams"></Parameters><Parameters Name="RemoteLauncher"></Parameters><Parameters Name="UseRemoteLauncher">False</Parameters><Parameters Name="RemoteCWD"></Parameters><Parameters Name="RemoteDebug">False</Parameters><Parameters Name="Debug Symbols Search Path"></Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><Excluded_Packages>

+      

+      

+      <Excluded_Packages Name="$(BDS)\bin\bcboffice2k100.bpl">CodeGear C++Builder Office 2000 Servers Package</Excluded_Packages>

+      <Excluded_Packages Name="$(BDS)\bin\bcbofficexp100.bpl">CodeGear C++Builder Office XP Servers Package</Excluded_Packages>

+    </Excluded_Packages><Linker><Linker Name="LibPrefix"></Linker><Linker Name="LibSuffix"></Linker><Linker Name="LibVersion"></Linker></Linker><ProjectProperties><ProjectProperties Name="AutoShowDeps">False</ProjectProperties><ProjectProperties Name="ManagePaths">True</ProjectProperties><ProjectProperties Name="VerifyPackages">True</ProjectProperties></ProjectProperties><HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Count">3</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item0">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test;..</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item1">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include;..\test</HistoryLists_hlIncludePath><HistoryLists_hlIncludePath Name="Item2">$(BDS)\include;$(BDS)\include\dinkumware;$(BDS)\include\vcl;..\include</HistoryLists_hlIncludePath></HistoryLists_hlIncludePath><HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Count">1</HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Item0">$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test</HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Item1">$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;..\test</HistoryLists_hlILINK_LibraryPath><HistoryLists_hlILINK_LibraryPath Name="Item2">$(BDS)\lib;$(BDS)\lib\obj;$(BDS)\lib\psdk;$(OUTPUTDIR);..\test</HistoryLists_hlILINK_LibraryPath></HistoryLists_hlILINK_LibraryPath><HistoryLists_hlDefines><HistoryLists_hlDefines Name="Count">2</HistoryLists_hlDefines><HistoryLists_hlDefines Name="Item0">NO_STRICT</HistoryLists_hlDefines><HistoryLists_hlDefines Name="Item1">STRICT</HistoryLists_hlDefines></HistoryLists_hlDefines></CPlusPlusBuilder.Personality></BorlandProject></BorlandProject>

+  </ProjectExtensions>

+  <Import Project="$(MSBuildBinPath)\Borland.Cpp.Targets" />

+  <ItemGroup>

+    <CppCompile Include="..\test\gtest_unittest.cc">

+      <BuildOrder>0</BuildOrder>

+    </CppCompile>

+    <CppCompile Include="gtest_link.cc">

+      <BuildOrder>1</BuildOrder>

+    </CppCompile>

+    <BuildConfiguration Include="Debug">

+      <Key>Cfg_1</Key>

+    </BuildConfiguration>

+    <BuildConfiguration Include="Release">

+      <Key>Cfg_2</Key>

+    </BuildConfiguration>

+  </ItemGroup>

+</Project>
\ No newline at end of file
diff --git a/protobuf/gtest/configure b/protobuf/gtest/configure
new file mode 100755
index 0000000..7d4daf9
--- /dev/null
+++ b/protobuf/gtest/configure
@@ -0,0 +1,18381 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for Google C++ Testing Framework 1.5.0.
+#
+# Report bugs to <googletestframework@googlegroups.com>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: googletestframework@googlegroups.com about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='Google C++ Testing Framework'
+PACKAGE_TARNAME='gtest'
+PACKAGE_VERSION='1.5.0'
+PACKAGE_STRING='Google C++ Testing Framework 1.5.0'
+PACKAGE_BUGREPORT='googletestframework@googlegroups.com'
+PACKAGE_URL=''
+
+ac_unique_file="./COPYING"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+HAVE_PTHREADS_FALSE
+HAVE_PTHREADS_TRUE
+PTHREAD_CFLAGS
+PTHREAD_LIBS
+PTHREAD_CC
+acx_pthread_config
+HAVE_PYTHON_FALSE
+HAVE_PYTHON_TRUE
+PYTHON
+CXXCPP
+CPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+MANIFEST_TOOL
+RANLIB
+ac_ct_AR
+AR
+DLLTOOL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+EGREP
+GREP
+SED
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+LIBTOOL
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_silent_rules
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+with_sysroot
+enable_libtool_lock
+with_pthreads
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CPP
+CXXCPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures Google C++ Testing Framework 1.5.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/gtest]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of Google C++ Testing Framework 1.5.0:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
+  --with-pthreads         use pthreads (default is yes)
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
+  CXXCPP      C++ preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <googletestframework@googlegroups.com>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+Google C++ Testing Framework configure 1.5.0
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by Google C++ Testing Framework $as_me 1.5.0, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Provide various options to initialize the Autoconf and configure processes.
+
+
+ac_aux_dir=
+for ac_dir in build-aux "$srcdir"/build-aux; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+ac_config_headers="$ac_config_headers build-aux/config.h"
+
+ac_config_files="$ac_config_files Makefile"
+
+ac_config_files="$ac_config_files scripts/gtest-config"
+
+
+# Initialize Automake with various options. We require at least v1.9, prevent
+# pedantic complaints about package files, and enable various distribution
+# targets.
+am__api_version='1.14'
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$*" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$*" != "X $srcdir/configure conftest.file" \
+	&& test "$*" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment" "$LINENO" 5
+     fi
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if ${ac_cv_path_mkdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='gtest'
+ VERSION='1.5.0'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar  pax cpio none'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake@gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+  fi
+fi
+
+# Check for programs used in building Google Test.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CXX"  am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CXX_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CXX_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.4.2'
+macro_revision='1.3337'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_SED" || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if ${ac_cv_path_FGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_FGREP" || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if ${lt_cv_path_NM+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in dumpbin "link -dump"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if ${lt_cv_nm_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if ${lt_cv_sys_max_cmd_len+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[	 ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len" && \
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if ${lt_cv_ld_reload_flag+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if ${lt_cv_deplibs_check_method+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DLLTOOL" = x; then
+    DLLTOOL="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DLLTOOL=$ac_ct_DLLTOOL
+  fi
+else
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    case `/usr/bin/file conftest.o` in
+	      *x86-64*)
+		LD="${LD-ld} -m elf32_x86_64"
+		;;
+	      *)
+		LD="${LD-ld} -m elf_i386"
+		;;
+	    esac
+	    ;;
+	  powerpc64le-*)
+	    LD="${LD-ld} -m elf32lppclinux"
+	    ;;
+	  powerpc64-*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  powerpcle-*)
+	    LD="${LD-ld} -m elf64lppc"
+	    ;;
+	  powerpc-*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if ${lt_cv_cc_needs_belf+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
+else
+  lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_MANIFEST_TOOL="mt"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_NMEDIT="nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_LIPO="lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OTOOL="otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OTOOL64="otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if ${lt_cv_apple_cc_single_mod+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&5
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&5
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=no
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+  # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if ${lt_cv_objdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='--shared'
+	lt_prog_compiler_static='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	lt_prog_compiler_wl='-Wl,-Wl,,'
+	lt_prog_compiler_pic='-PIC'
+	lt_prog_compiler_static='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+        *Intel*\ [CF]*Compiler*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fPIC'
+	  lt_prog_compiler_static='-static'
+	  ;;
+	*Portland\ Group*)
+	  lt_prog_compiler_wl='-Wl,'
+	  lt_prog_compiler_pic='-fpic'
+	  lt_prog_compiler_static='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+	  *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec=
+	  tmp_sharedflag='--shared' ;;
+	xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	link_all_deplibs=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      export_dynamic_flag_spec='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
+
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec='$convenience'
+	  fi
+	  archive_cmds_need_lc=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	always_export_symbols=yes
+	file_list_spec='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+	enable_shared_with_static_runtimes=yes
+	exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	old_postinstall_cmds='chmod 644 $oldlib'
+	postlink_cmds='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	hardcode_libdir_flag_spec=' '
+	allow_undefined_flag=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	old_archive_from_new_cmds='true'
+	# FIXME: Should let the user specify the lib program.
+	old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	enable_shared_with_static_runtimes=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
+  link_all_deplibs=yes
+  allow_undefined_flag="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+	hardcode_direct=yes
+	hardcode_direct_absolute=yes
+	export_dynamic_flag_spec='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  hardcode_direct_absolute=yes
+	  export_dynamic_flag_spec='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo (void) { return 0; }
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+           LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	hardcode_direct_absolute=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$lt_prog_compiler_wl
+	  pic_flag=$lt_prog_compiler_pic
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag
+	  allow_undefined_flag=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	  then
+	    lt_cv_archive_cmds_need_lc=no
+	  else
+	    lt_cv_archive_cmds_need_lc=yes
+	  fi
+	  allow_undefined_flag=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = xyes; then :
+  lt_cv_dlopen="shl_load"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if ${ac_cv_lib_svld_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if ${ac_cv_lib_dld_dld_link+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if ${lt_cv_dlopen_self_static+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report which library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+CC="$lt_save_CC"
+
+      if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+else
+  _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+  # save warnings/boilerplate of simple test code
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  compiler_CXX=$CC
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+    else
+      lt_prog_compiler_no_builtin_flag_CXX=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if ${lt_cv_path_LD+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if ${lt_cv_prog_gnu_ld+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          whole_archive_flag_spec_CXX=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+    ld_shlibs_CXX=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+      aix[4-9]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        archive_cmds_CXX=''
+        hardcode_direct_CXX=yes
+        hardcode_direct_absolute_CXX=yes
+        hardcode_libdir_separator_CXX=':'
+        link_all_deplibs_CXX=yes
+        file_list_spec_CXX='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[012]|aix4.[012].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    hardcode_direct_CXX=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    hardcode_minus_L_CXX=yes
+	    hardcode_libdir_flag_spec_CXX='-L$libdir'
+	    hardcode_libdir_separator_CXX=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        export_dynamic_flag_spec_CXX='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        always_export_symbols_CXX=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          allow_undefined_flag_CXX='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	    allow_undefined_flag_CXX="-z nodefs"
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath__CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }'
+  lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  if test -z "$lt_cv_aix_libpath__CXX"; then
+    lt_cv_aix_libpath__CXX="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath__CXX
+fi
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    no_undefined_flag_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      whole_archive_flag_spec_CXX='$convenience'
+	    fi
+	    archive_cmds_need_lc_CXX=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  allow_undefined_flag_CXX=unsupported
+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX=' '
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=yes
+	  file_list_spec_CXX='@'
+	  # Tell ltmain to make .lib files, not .a files.
+	  libext=lib
+	  # Tell ltmain to make .dll files, not .so files.
+	  shrext_cmds=".dll"
+	  # FIXME: Setting linknames here is a bad hack.
+	  archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true'
+	  enable_shared_with_static_runtimes_CXX=yes
+	  # Don't use ranlib
+	  old_postinstall_cmds_CXX='chmod 644 $oldlib'
+	  postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  hardcode_libdir_flag_spec_CXX='-L$libdir'
+	  export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+	  allow_undefined_flag_CXX=unsupported
+	  always_export_symbols_CXX=no
+	  enable_shared_with_static_runtimes_CXX=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	  else
+	    ld_shlibs_CXX=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_CXX=no
+  hardcode_direct_CXX=no
+  hardcode_automatic_CXX=yes
+  hardcode_shlibpath_var_CXX=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec_CXX=''
+  fi
+  link_all_deplibs_CXX=yes
+  allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+
+  else
+  ld_shlibs_CXX=no
+  fi
+
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        ld_shlibs_CXX=no
+        ;;
+
+      freebsd-elf*)
+        archive_cmds_need_lc_CXX=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        ld_shlibs_CXX=yes
+        ;;
+
+      haiku*)
+        archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        link_all_deplibs_CXX=yes
+        ;;
+
+      hpux9*)
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        export_dynamic_flag_spec_CXX='${wl}-E'
+        hardcode_direct_CXX=yes
+        hardcode_minus_L_CXX=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            ld_shlibs_CXX=no
+            ;;
+          aCC*)
+            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              ld_shlibs_CXX=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      export_dynamic_flag_spec_CXX='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct_CXX=no
+            hardcode_shlibpath_var_CXX=no
+            ;;
+          *)
+            hardcode_direct_CXX=yes
+            hardcode_direct_absolute_CXX=yes
+            hardcode_minus_L_CXX=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[3-9]*)
+	hardcode_direct_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    link_all_deplibs_CXX=yes
+	    ;;
+        esac
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        inherit_rpath_CXX=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    archive_cmds_need_lc_CXX=no
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+	      prelink_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      old_archive_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      archive_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      no_undefined_flag_CXX=' -zdefs'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      hardcode_libdir_flag_spec_CXX='-R$libdir'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      compiler_needs_object_CXX=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='func_echo_all'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  hardcode_libdir_flag_spec_CXX='-R$libdir'
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        ld_shlibs_CXX=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	  hardcode_direct_absolute_CXX=yes
+	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        allow_undefined_flag_CXX=' -expect_unresolved \*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+		;;
+	    esac
+
+	    hardcode_libdir_separator_CXX=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	      hardcode_libdir_separator_CXX=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            archive_cmds_need_lc_CXX=yes
+	    no_undefined_flag_CXX=' -zdefs'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    hardcode_libdir_flag_spec_CXX='-R$libdir'
+	    hardcode_shlibpath_var_CXX=no
+	    case $host_os in
+	      solaris2.[0-5] | solaris2.[0-5].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    link_all_deplibs_CXX=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[0-5] | solaris2.[0-5].*) ;;
+		*)
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_CXX='${wl}-z,text'
+      archive_cmds_need_lc_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
+	archive_cmds_need_lc_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+	hardcode_libdir_separator_CXX=':'
+	link_all_deplibs_CXX=yes
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+	      '"$old_archive_cmds_CXX"
+	    reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+	      '"$reload_cmds_CXX"
+	    ;;
+	  *)
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+    GCC_CXX="$GXX"
+    LD_CXX="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case ${prev}${p} in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
+	 -L | -R)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_CXX='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_CXX='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static_CXX=
+      ;;
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_CXX=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	lt_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_CXX='-fPIC -shared'
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[4-9]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  lt_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      mingw* | cygwin* | os2* | pw32* | cegcc*)
+	# This hack is so that the source file can tell whether it is being
+	# built for inclusion in a dll (and should export symbols for example).
+	lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fpic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-qpic'
+	    lt_prog_compiler_static_CXX='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      lt_prog_compiler_pic_CXX='-KPIC'
+	      lt_prog_compiler_static_CXX='-Bstatic'
+	      lt_prog_compiler_wl_CXX='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd* | netbsdelf*-gnu)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        lt_prog_compiler_pic_CXX='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; }
+lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_CXX=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works_CXX=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if ${lt_cv_prog_compiler_static_works_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_CXX=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works_CXX=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+fi
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if ${lt_cv_prog_compiler_c_o_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  case $host_os in
+  aix[4-9]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
+      ;;
+    esac
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    link_all_deplibs_CXX=no
+    ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$lt_prog_compiler_wl_CXX
+	  pic_flag=$lt_prog_compiler_pic_CXX
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+	  allow_undefined_flag_CXX=
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+	  then
+	    lt_cv_archive_cmds_need_lc_CXX=no
+	  else
+	    lt_cv_archive_cmds_need_lc_CXX=yes
+	  fi
+	  allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+      archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[23].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[3-9]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+	 LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+   test -n "$runpath_var_CXX" ||
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_CXX" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+# TODO(chandlerc@google.com): Currently we aren't running the Python tests
+# against the interpreter detected by AM_PATH_PYTHON, and so we condition
+# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's
+# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env"
+# hashbang.
+PYTHON=  # We *do not* allow the user to specify a python interpreter
+# Extract the first word of "python", so it can be a program name with args.
+set dummy python; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PYTHON+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PYTHON in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_PYTHON" && ac_cv_path_PYTHON=":"
+  ;;
+esac
+fi
+PYTHON=$ac_cv_path_PYTHON
+if test -n "$PYTHON"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+$as_echo "$PYTHON" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+if test "$PYTHON" != ":"; then :
+  prog="import sys
+# split strings by '.' and convert to numeric.  Append some zeros
+# because we need at least 4 digits for the hex conversion.
+# map returns an iterator in Python 3.0 and a list in 2.x
+minver = list(map(int, '2.3'.split('.'))) + [0, 0, 0]
+minverhex = 0
+# xrange is not present in Python 3.0 and range returns an iterator
+for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i]
+sys.exit(sys.hexversion < minverhex)"
+  if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5
+   ($PYTHON -c "$prog") >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }; then :
+  :
+else
+  PYTHON=":"
+fi
+fi
+ if test "$PYTHON" != ":"; then
+  HAVE_PYTHON_TRUE=
+  HAVE_PYTHON_FALSE='#'
+else
+  HAVE_PYTHON_TRUE='#'
+  HAVE_PYTHON_FALSE=
+fi
+
+
+# Configure pthreads.
+
+# Check whether --with-pthreads was given.
+if test "${with_pthreads+set}" = set; then :
+  withval=$with_pthreads; with_pthreads=$withval
+else
+  with_pthreads=check
+fi
+
+
+have_pthreads=no
+if test "x$with_pthreads" != "xno"; then :
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
+$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+$as_echo_n "checking whether pthreads work without any flags... " >&6; }
+                ;;
+
+                -*)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
+$as_echo_n "checking whether pthreads work with $flag... " >&6; }
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+		pthread-config)
+		# Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_acx_pthread_config+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$acx_pthread_config"; then
+  ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_acx_pthread_config="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no"
+fi
+fi
+acx_pthread_config=$ac_cv_prog_acx_pthread_config
+if test -n "$acx_pthread_config"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5
+$as_echo "$acx_pthread_config" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+		if test x"$acx_pthread_config" = xno; then continue; fi
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
+
+                *)
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
+$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  acx_pthread_ok=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
+$as_echo "$acx_pthread_ok" >&6; }
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+$as_echo_n "checking for joinable pthread attribute... " >&6; }
+	attr_name=unknown
+	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+int attr=$attr; return attr;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  attr_name=$attr; break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	done
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5
+$as_echo "$attr_name" >&6; }
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $attr_name
+_ACEOF
+
+        fi
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
+$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5
+$as_echo "${flag}" >&6; }
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+        # More AIX lossage: must compile with xlc_r or cc_r
+	if test x"$GCC" != xyes; then
+          for ac_prog in xlc_r cc_r
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_PTHREAD_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$PTHREAD_CC"; then
+  ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PTHREAD_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
+$as_echo "$PTHREAD_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$PTHREAD_CC" && break
+done
+test -n "$PTHREAD_CC" || PTHREAD_CC="${CC}"
+
+        else
+          PTHREAD_CC=$CC
+	fi
+
+	# The next part tries to detect GCC inconsistency with -shared on some
+	# architectures and systems. The problem is that in certain
+	# configurations, when -shared is specified, GCC "forgets" to
+	# internally use various flags which are still necessary.
+
+	#
+	# Prepare the flags
+	#
+	save_CFLAGS="$CFLAGS"
+	save_LIBS="$LIBS"
+	save_CC="$CC"
+
+	# Try with the flags determined by the earlier checks.
+	#
+	# -Wl,-z,defs forces link-time symbol resolution, so that the
+	# linking checks with -shared actually have any value
+	#
+	# FIXME: -fPIC is required for -shared on many architectures,
+	# so we specify it here, but the right way would probably be to
+	# properly detect whether it is actually required.
+	CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+	CC="$PTHREAD_CC"
+
+	# In order not to create several levels of indentation, we test
+	# the value of "$done" until we find the cure or run out of ideas.
+	done="no"
+
+	# First, make sure the CFLAGS we added are actually accepted by our
+	# compiler.  If not (and OS X's ld, for instance, does not accept -z),
+	# then we can't do this test.
+	if test x"$done" = xno; then
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to check for GCC pthread/shared inconsistencies" >&5
+$as_echo_n "checking whether to check for GCC pthread/shared inconsistencies... " >&6; }
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+  done=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	   if test "x$done" = xyes ; then
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	   else
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	   fi
+	fi
+
+	if test x"$done" = xno; then
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -pthread is sufficient with -shared" >&5
+$as_echo_n "checking whether -pthread is sufficient with -shared... " >&6; }
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  done=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	   if test "x$done" = xyes; then
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	   else
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	   fi
+	fi
+
+	#
+	# Linux gcc on some architectures such as mips/mipsel forgets
+	# about -lpthread
+	#
+	if test x"$done" = xno; then
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lpthread fixes that" >&5
+$as_echo_n "checking whether -lpthread fixes that... " >&6; }
+	   LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  done=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	   if test "x$done" = xyes; then
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	      PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
+	   else
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	   fi
+	fi
+	#
+	# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
+	#
+	if test x"$done" = xno; then
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc_r fixes that" >&5
+$as_echo_n "checking whether -lc_r fixes that... " >&6; }
+	   LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
+	   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+	        pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	        pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  done=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+	   if test "x$done" = xyes; then
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	      PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
+	   else
+	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	   fi
+	fi
+	if test x"$done" = xno; then
+	   # OK, we have run out of ideas
+	   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Impossible to determine how to use pthreads with shared libraries" >&5
+$as_echo "$as_me: WARNING: Impossible to determine how to use pthreads with shared libraries" >&2;}
+
+	   # so it's not safe to assume that we may use pthreads
+	   acx_pthread_ok=no
+	fi
+
+	CFLAGS="$save_CFLAGS"
+	LIBS="$save_LIBS"
+	CC="$save_CC"
+else
+        PTHREAD_CC="$CC"
+fi
+
+
+
+
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+
+$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+        :
+else
+        acx_pthread_ok=no
+        if test "x$with_pthreads" != "xcheck"; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-pthreads was specified, but unable to be used
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+       have_pthreads="$acx_pthread_ok"
+fi
+ if test "x$have_pthreads" == "xyes"; then
+  HAVE_PTHREADS_TRUE=
+  HAVE_PTHREADS_FALSE='#'
+else
+  HAVE_PTHREADS_TRUE='#'
+  HAVE_PTHREADS_FALSE=
+fi
+
+
+
+
+# TODO(chandlerc@google.com) Check for the necessary system headers.
+
+# TODO(chandlerc@google.com) Check the types, structures, and other compiler
+# and architecture characteristics.
+
+# Output the generated files. No further autoconf macros may be used.
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_PYTHON_TRUE}" && test -z "${HAVE_PYTHON_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_PYTHON\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_PTHREADS_TRUE}" && test -z "${HAVE_PTHREADS_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_PTHREADS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by Google C++ Testing Framework $as_me 1.5.0, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <googletestframework@googlegroups.com>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+Google C++ Testing Framework config.status 1.5.0
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+DLLTOOL \
+sharedlib_from_linklib_cmd \
+AR \
+AR_FLAGS \
+archiver_list_spec \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+nm_file_list_spec \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_pic \
+lt_prog_compiler_wl \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+MANIFEST_TOOL \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_separator \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_separator_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postlink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX \
+postlink_cmds_CXX; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "build-aux/config.h") CONFIG_HEADERS="$CONFIG_HEADERS build-aux/config.h" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "scripts/gtest-config") CONFIG_FILES="$CONFIG_FILES scripts/gtest-config" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "scripts/gtest-config":F) chmod +x scripts/gtest-config ;;
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method = "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# DLL creation program.
+DLLTOOL=$lt_DLLTOOL
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
+# The archiver.
+AR=$lt_AR
+
+# Flags to create an archive.
+AR_FLAGS=$lt_AR_FLAGS
+
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
+
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\    # positional parameters, so assign one to ordinary parameter first.\
+\    func_stripname_result=${3}\
+\    func_stripname_result=${func_stripname_result#"${1}"}\
+\    func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/protobuf/gtest/configure.ac b/protobuf/gtest/configure.ac
new file mode 100644
index 0000000..1b91237
--- /dev/null
+++ b/protobuf/gtest/configure.ac
@@ -0,0 +1,67 @@
+m4_include(m4/acx_pthread.m4)
+
+# At this point, the Xcode project assumes the version string will be three
+# integers separated by periods and surrounded by square brackets (e.g.
+# "[1.0.1]"). It also asumes that there won't be any closing parenthesis
+# between "AC_INIT(" and the closing ")" including comments and strings.
+AC_INIT([Google C++ Testing Framework],
+        [1.5.0],
+        [googletestframework@googlegroups.com],
+        [gtest])
+
+# Provide various options to initialize the Autoconf and configure processes.
+AC_PREREQ([2.59])
+AC_CONFIG_SRCDIR([./COPYING])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_HEADERS([build-aux/config.h])
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_FILES([scripts/gtest-config], [chmod +x scripts/gtest-config])
+
+# Initialize Automake with various options. We require at least v1.9, prevent
+# pedantic complaints about package files, and enable various distribution
+# targets.
+AM_INIT_AUTOMAKE([1.9 dist-bzip2 dist-zip foreign subdir-objects])
+
+# Check for programs used in building Google Test.
+AC_PROG_CC
+AC_PROG_CXX
+AC_LANG([C++])
+AC_PROG_LIBTOOL
+
+# TODO(chandlerc@google.com): Currently we aren't running the Python tests
+# against the interpreter detected by AM_PATH_PYTHON, and so we condition
+# HAVE_PYTHON by requiring "python" to be in the PATH, and that interpreter's
+# version to be >= 2.3. This will allow the scripts to use a "/usr/bin/env"
+# hashbang.
+PYTHON=  # We *do not* allow the user to specify a python interpreter
+AC_PATH_PROG([PYTHON],[python],[:])
+AS_IF([test "$PYTHON" != ":"],
+      [AM_PYTHON_CHECK_VERSION([$PYTHON],[2.3],[:],[PYTHON=":"])])
+AM_CONDITIONAL([HAVE_PYTHON],[test "$PYTHON" != ":"])
+
+# Configure pthreads.
+AC_ARG_WITH([pthreads],
+            [AS_HELP_STRING([--with-pthreads],
+               [use pthreads (default is yes)])],
+            [with_pthreads=$withval],
+            [with_pthreads=check])
+
+have_pthreads=no
+AS_IF([test "x$with_pthreads" != "xno"],
+      [ACX_PTHREAD(
+        [],
+        [AS_IF([test "x$with_pthreads" != "xcheck"],
+               [AC_MSG_FAILURE(
+                 [--with-pthreads was specified, but unable to be used])])])
+       have_pthreads="$acx_pthread_ok"])
+AM_CONDITIONAL([HAVE_PTHREADS],[test "x$have_pthreads" == "xyes"])
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_LIBS)
+
+# TODO(chandlerc@google.com) Check for the necessary system headers.
+
+# TODO(chandlerc@google.com) Check the types, structures, and other compiler
+# and architecture characteristics.
+
+# Output the generated files. No further autoconf macros may be used.
+AC_OUTPUT
diff --git a/protobuf/gtest/fused-src/gtest/gtest-all.cc b/protobuf/gtest/fused-src/gtest/gtest-all.cc
new file mode 100644
index 0000000..644479a
--- /dev/null
+++ b/protobuf/gtest/fused-src/gtest/gtest-all.cc
@@ -0,0 +1,8510 @@
+// 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: mheule@google.com (Markus Heule)
+//
+// Google C++ Testing Framework (Google Test)
+//
+// Sometimes it's desirable to build Google Test by compiling a single file.
+// This file serves this purpose.
+
+// This line ensures that gtest.h can be compiled on its own, even
+// when it's fused.
+#include <gtest/gtest.h>
+
+// The following lines pull in the real gtest *.cc files.
+// 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)
+
+// 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_
+
+
+namespace testing {
+
+// 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. It can either intercept only failures that are
+// generated in the same thread that created this object or it can intercept
+// all generated failures. The scope of this mock object can be controlled with
+// the second argument to the two arguments constructor.
+class GTEST_API_ ScopedFakeTestPartResultReporter
+    : public TestPartResultReporterInterface {
+ public:
+  // The two possible mocking modes of this object.
+  enum InterceptMode {
+    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures.
+    INTERCEPT_ALL_THREADS           // Intercepts all failures.
+  };
+
+  // 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. This reporter will only catch failures generated in the current
+  // thread. DEPRECATED
+  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
+
+  // Same as above, but you can choose the interception scope of this object.
+  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
+                                   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:
+  void Init();
+
+  const InterceptMode intercept_mode_;
+  TestPartResultReporterInterface* 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 GTEST_API_ SingleFailureChecker {
+ public:
+  // The constructor remembers the arguments.
+  SingleFailureChecker(const TestPartResultArray* results,
+                       TestPartResult::Type type,
+                       const char* substr);
+  ~SingleFailureChecker();
+ private:
+  const TestPartResultArray* const results_;
+  const TestPartResult::Type type_;
+  const String substr_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
+};
+
+}  // namespace internal
+
+}  // namespace testing
+
+// A set of macros 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.
+//
+// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
+// affects and considers failures generated in the current thread and
+// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
+//
+// The verification of the assertion is done correctly even when the statement
+// throws an exception or aborts the current function.
+//
+// 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.
+//
+// Note that even though the implementations of the following two
+// macros are much alike, we cannot refactor them to use a common
+// helper macro, due to some peculiarity in how the preprocessor
+// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in
+// gtest_unittest.cc will fail to compile if we do that.
+#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::TestPartResult::kFatalFailure, (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
+      GTestExpectFatalFailureHelper::Execute();\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
+  do { \
+    class GTestExpectFatalFailureHelper {\
+     public:\
+      static void Execute() { statement; }\
+    };\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ALL_THREADS, &gtest_failures);\
+      GTestExpectFatalFailureHelper::Execute();\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+// 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.
+//
+// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
+// affects and considers failures generated in the current thread and
+// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
+//
+// 'statement' is allowed to reference local variables and members of
+// the current object.
+//
+// The verification of the assertion is done correctly even when the statement
+// throws an exception or aborts the current function.
+//
+// Known restrictions:
+//   - You cannot stream a failure message to this macro.
+//
+// Note that even though the implementations of the following two
+// macros are much alike, we cannot refactor them to use a common
+// helper macro, due to some peculiarity in how the preprocessor
+// works.  If we do that, the code won't compile when the user gives
+// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
+// expands to code containing an unprotected comma.  The
+// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
+// catches that.
+//
+// For the same reason, we have to write
+//   if (::testing::internal::AlwaysTrue()) { statement; }
+// instead of
+//   GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
+// to avoid an MSVC warning on unreachable code.
+#define EXPECT_NONFATAL_FAILURE(statement, substr) \
+  do {\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
+        (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
+      if (::testing::internal::AlwaysTrue()) { statement; }\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
+  do {\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
+        (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\
+          &gtest_failures);\
+      if (::testing::internal::AlwaysTrue()) { statement; }\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
+
+#include <ctype.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <wctype.h>
+
+#include <algorithm>
+#include <ostream>
+#include <sstream>
+#include <vector>
+
+#if GTEST_OS_LINUX
+
+// TODO(kenton@google.com): Use autoconf to detect availability of
+// gettimeofday().
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+
+#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 GTEST_OS_SYMBIAN
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h>  // NOLINT
+
+#elif GTEST_OS_ZOS
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h>  // NOLINT
+
+// On z/OS we additionally need strings.h for strcasecmp.
+#include <strings.h>  // NOLINT
+
+#elif GTEST_OS_WINDOWS_MOBILE  // We are on Windows CE.
+
+#include <windows.h>  // NOLINT
+
+#elif GTEST_OS_WINDOWS  // 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 GTEST_OS_WINDOWS_MINGW
+// MinGW has gettimeofday() but not _ftime64().
+// TODO(kenton@google.com): Use autoconf to detect availability of
+//   gettimeofday().
+// TODO(kenton@google.com): There are other ways to get the time on
+//   Windows, like GetTickCount() or GetSystemTimeAsFileTime().  MinGW
+//   supports these.  consider using them instead.
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h>  // NOLINT
+#endif  // GTEST_OS_WINDOWS_MINGW
+
+// 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@google.com): Use autoconf to detect availability of
+//   gettimeofday().
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+
+// cpplint thinks that the header is already included, so we want to
+// silence it.
+#include <sys/time.h>  // NOLINT
+#include <unistd.h>  // NOLINT
+
+#endif  // GTEST_OS_LINUX
+
+#if GTEST_HAS_EXCEPTIONS
+#include <stdexcept>
+#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_ 1
+// 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 to 1 iff the current translation unit is
+// part of Google Test's implementation; otherwise it's undefined.
+#if !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_
+
+#ifndef _WIN32_WCE
+#include <errno.h>
+#endif  // !_WIN32_WCE
+#include <stddef.h>
+#include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.
+#include <string.h>  // For memmove.
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+
+#if GTEST_OS_WINDOWS
+#include <windows.h>  // For DWORD.
+#endif  // GTEST_OS_WINDOWS
+
+
+namespace testing {
+
+// Declares the flags.
+//
+// We don't want the users to modify this flag in the code, but want
+// Google Test's own unit tests to be able to access it. Therefore we
+// declare it here as opposed to in gtest.h.
+GTEST_DECLARE_bool_(death_test_use_fork);
+
+namespace internal {
+
+// The value of GetTestTypeId() as seen from within the Google Test
+// library.  This is solely for testing GetTestTypeId().
+GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
+const char kBreakOnFailureFlag[] = "break_on_failure";
+const char kCatchExceptionsFlag[] = "catch_exceptions";
+const char kColorFlag[] = "color";
+const char kFilterFlag[] = "filter";
+const char kListTestsFlag[] = "list_tests";
+const char kOutputFlag[] = "output";
+const char kPrintTimeFlag[] = "print_time";
+const char kRandomSeedFlag[] = "random_seed";
+const char kRepeatFlag[] = "repeat";
+const char kShuffleFlag[] = "shuffle";
+const char kStackTraceDepthFlag[] = "stack_trace_depth";
+const char kThrowOnFailureFlag[] = "throw_on_failure";
+
+// A valid random seed must be in [1, kMaxRandomSeed].
+const int kMaxRandomSeed = 99999;
+
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+GTEST_API_ extern bool g_help_flag;
+
+// Returns the current time in milliseconds.
+GTEST_API_ TimeInMillis GetTimeInMillis();
+
+// Returns true iff Google Test should use colors in the output.
+GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
+
+// Formats the given time in milliseconds as seconds.
+GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
+
+// 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.
+GTEST_API_ bool ParseInt32Flag(
+    const char* str, const char* flag, Int32* value);
+
+// Returns a random seed in range [1, kMaxRandomSeed] based on the
+// given --gtest_random_seed flag value.
+inline int GetRandomSeedFromFlag(Int32 random_seed_flag) {
+  const unsigned int raw_seed = (random_seed_flag == 0) ?
+      static_cast<unsigned int>(GetTimeInMillis()) :
+      static_cast<unsigned int>(random_seed_flag);
+
+  // Normalizes the actual seed to range [1, kMaxRandomSeed] such that
+  // it's easy to type.
+  const int normalized_seed =
+      static_cast<int>((raw_seed - 1U) %
+                       static_cast<unsigned int>(kMaxRandomSeed)) + 1;
+  return normalized_seed;
+}
+
+// Returns the first valid random seed after 'seed'.  The behavior is
+// undefined if 'seed' is invalid.  The seed after kMaxRandomSeed is
+// considered to be 1.
+inline int GetNextRandomSeed(int seed) {
+  GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)
+      << "Invalid random seed " << seed << " - must be in [1, "
+      << kMaxRandomSeed << "].";
+  const int next_seed = seed + 1;
+  return (next_seed > kMaxRandomSeed) ? 1 : next_seed;
+}
+
+// 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() {
+    also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);
+    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);
+    death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
+    filter_ = GTEST_FLAG(filter);
+    internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
+    list_tests_ = GTEST_FLAG(list_tests);
+    output_ = GTEST_FLAG(output);
+    print_time_ = GTEST_FLAG(print_time);
+    random_seed_ = GTEST_FLAG(random_seed);
+    repeat_ = GTEST_FLAG(repeat);
+    shuffle_ = GTEST_FLAG(shuffle);
+    stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
+    throw_on_failure_ = GTEST_FLAG(throw_on_failure);
+  }
+
+  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS.
+  ~GTestFlagSaver() {
+    GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;
+    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(death_test_use_fork) = death_test_use_fork_;
+    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(print_time) = print_time_;
+    GTEST_FLAG(random_seed) = random_seed_;
+    GTEST_FLAG(repeat) = repeat_;
+    GTEST_FLAG(shuffle) = shuffle_;
+    GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
+    GTEST_FLAG(throw_on_failure) = throw_on_failure_;
+  }
+ private:
+  // Fields for saving the original values of flags.
+  bool also_run_disabled_tests_;
+  bool break_on_failure_;
+  bool catch_exceptions_;
+  String color_;
+  String death_test_style_;
+  bool death_test_use_fork_;
+  String filter_;
+  String internal_run_death_test_;
+  bool list_tests_;
+  String output_;
+  bool print_time_;
+  bool pretty_;
+  internal::Int32 random_seed_;
+  internal::Int32 repeat_;
+  bool shuffle_;
+  internal::Int32 stack_trace_depth_;
+  bool throw_on_failure_;
+} GTEST_ATTRIBUTE_UNUSED_;
+
+// Converts a Unicode code point to a narrow string in UTF-8 encoding.
+// code_point parameter is of type UInt32 because wchar_t may not be
+// wide enough to contain a code point.
+// The output buffer str must containt at least 32 characters.
+// The function returns the address of the output buffer.
+// If the code_point is not a valid Unicode code point
+// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'.
+GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str);
+
+// Converts a wide string to a narrow string in UTF-8 encoding.
+// The wide string is assumed to have the following encoding:
+//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
+// Parameter str points to a null-terminated wide string.
+// Parameter num_chars may additionally limit the number
+// of wchar_t characters processed. -1 is used when the entire string
+// should be processed.
+// If the string contains code points that are not valid Unicode code points
+// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
+// and contains invalid UTF-16 surrogate pairs, values in those pairs
+// will be encoded as individual Unicode characters from Basic Normal Plane.
+GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars);
+
+// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
+// if the variable is present. If a file already exists at this location, this
+// function will write over it. If the variable is present, but the file cannot
+// be created, prints an error and exits.
+void WriteToShardStatusFileIfNeeded();
+
+// Checks whether sharding is enabled by examining the relevant
+// environment variable values. If the variables are present,
+// but inconsistent (e.g., shard_index >= total_shards), prints
+// an error and exits. If in_subprocess_for_death_test, sharding is
+// disabled because it must only be applied to the original test
+// process. Otherwise, we could filter out death tests we intended to execute.
+GTEST_API_ bool ShouldShard(const char* total_shards_str,
+                            const char* shard_index_str,
+                            bool in_subprocess_for_death_test);
+
+// Parses the environment variable var as an Int32. If it is unset,
+// returns default_val. If it is not an Int32, prints an error and
+// and aborts.
+GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
+
+// Given the total number of shards, the shard index, and the test id,
+// returns true iff the test should be run on this shard. The test id is
+// some arbitrary but unique non-negative integer assigned to each test
+// method. Assumes that 0 <= shard_index < total_shards.
+GTEST_API_ bool ShouldRunTestOnShard(
+    int total_shards, int shard_index, int test_id);
+
+// STL container utilities.
+
+// Returns the number of elements in the given container that satisfy
+// the given predicate.
+template <class Container, typename Predicate>
+inline int CountIf(const Container& c, Predicate predicate) {
+  return static_cast<int>(std::count_if(c.begin(), c.end(), predicate));
+}
+
+// Applies a function/functor to each element in the container.
+template <class Container, typename Functor>
+void ForEach(const Container& c, Functor functor) {
+  std::for_each(c.begin(), c.end(), functor);
+}
+
+// Returns the i-th element of the vector, or default_value if i is not
+// in range [0, v.size()).
+template <typename E>
+inline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
+  return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];
+}
+
+// Performs an in-place shuffle of a range of the vector's elements.
+// 'begin' and 'end' are element indices as an STL-style range;
+// i.e. [begin, end) are shuffled, where 'end' == size() means to
+// shuffle to the end of the vector.
+template <typename E>
+void ShuffleRange(internal::Random* random, int begin, int end,
+                  std::vector<E>* v) {
+  const int size = static_cast<int>(v->size());
+  GTEST_CHECK_(0 <= begin && begin <= size)
+      << "Invalid shuffle range start " << begin << ": must be in range [0, "
+      << size << "].";
+  GTEST_CHECK_(begin <= end && end <= size)
+      << "Invalid shuffle range finish " << end << ": must be in range ["
+      << begin << ", " << size << "].";
+
+  // Fisher-Yates shuffle, from
+  // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
+  for (int range_width = end - begin; range_width >= 2; range_width--) {
+    const int last_in_range = begin + range_width - 1;
+    const int selected = begin + random->Generate(range_width);
+    std::swap((*v)[selected], (*v)[last_in_range]);
+  }
+}
+
+// Performs an in-place shuffle of the vector's elements.
+template <typename E>
+inline void Shuffle(internal::Random* random, std::vector<E>* v) {
+  ShuffleRange(random, 0, static_cast<int>(v->size()), v);
+}
+
+// A function for deleting an object.  Handy for being used as a
+// functor.
+template <typename T>
+static void Delete(T* x) {
+  delete x;
+}
+
+// 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_;
+};
+
+class TestInfoImpl {
+ public:
+  TestInfoImpl(TestInfo* parent, const char* test_case_name,
+               const char* name, const char* test_case_comment,
+               const char* comment, TypeId fixture_class_id,
+               internal::TestFactoryBase* factory);
+  ~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 true if this test matches the filter specified by the user.
+  bool matches_filter() const { return matches_filter_; }
+
+  // Sets the matches_filter member.
+  void set_matches_filter(bool matches) { matches_filter_ = matches; }
+
+  // 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 test case comment.
+  const char* test_case_comment() const { return test_case_comment_.c_str(); }
+
+  // Returns the test comment.
+  const char* comment() const { return comment_.c_str(); }
+
+  // Returns the ID of the test fixture class.
+  TypeId fixture_class_id() const { return fixture_class_id_; }
+
+  // Returns the test result.
+  TestResult* result() { return &result_; }
+  const TestResult* result() const { return &result_; }
+
+  // Creates the test object, runs it, records its result, and then
+  // deletes it.
+  void 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 String test_case_comment_;  // Test case comment
+  const String comment_;            // Test comment
+  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
+  bool matches_filter_;             // True if this test matches the
+                                    // user-specified filter.
+  internal::TestFactoryBase* const factory_;  // The factory that creates
+                                              // the test object
+
+  // This field is mutable and needs to be reset before running the
+  // test for the second time.
+  TestResult result_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl);
+};
+
+// 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 GTEST_API_ UnitTestOptions {
+ public:
+  // Functions for processing the gtest_output flag.
+
+  // Returns the output format, or "" for normal printed output.
+  static String GetOutputFormat();
+
+  // Returns the absolute path of the requested output file, or the
+  // default (test_detail.xml in the original working directory) if
+  // none was explicitly specified.
+  static String GetAbsolutePathToOutputFile();
+
+  // 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);
+
+#if 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
+
+  // 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.
+GTEST_API_ 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 implementation of the OsStackTraceGetterInterface interface.
+class OsStackTraceGetter : public OsStackTraceGetterInterface {
+ public:
+  OsStackTraceGetter() : caller_frame_(NULL) {}
+  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;
+};
+
+// This is the default global test part result reporter used in UnitTestImpl.
+// This class should only be used by UnitTestImpl.
+class DefaultGlobalTestPartResultReporter
+  : public TestPartResultReporterInterface {
+ public:
+  explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
+  // Implements the TestPartResultReporterInterface. Reports the test part
+  // result in the current test.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+
+ private:
+  UnitTestImpl* const unit_test_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter);
+};
+
+// This is the default per thread test part result reporter used in
+// UnitTestImpl. This class should only be used by UnitTestImpl.
+class DefaultPerThreadTestPartResultReporter
+    : public TestPartResultReporterInterface {
+ public:
+  explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);
+  // Implements the TestPartResultReporterInterface. The implementation just
+  // delegates to the current global test part result reporter of *unit_test_.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+
+ private:
+  UnitTestImpl* const unit_test_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter);
+};
+
+// 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 GTEST_API_ UnitTestImpl {
+ public:
+  explicit UnitTestImpl(UnitTest* parent);
+  virtual ~UnitTestImpl();
+
+  // There are two different ways to register your own TestPartResultReporter.
+  // You can register your own repoter to listen either only for test results
+  // from the current thread or for results from all threads.
+  // By default, each per-thread test result repoter just passes a new
+  // TestPartResult to the global test result reporter, which registers the
+  // test part result for the currently running test.
+
+  // Returns the global test part result reporter.
+  TestPartResultReporterInterface* GetGlobalTestPartResultReporter();
+
+  // Sets the global test part result reporter.
+  void SetGlobalTestPartResultReporter(
+      TestPartResultReporterInterface* reporter);
+
+  // Returns the test part result reporter for the current thread.
+  TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();
+
+  // Sets the test part result reporter for the current thread.
+  void SetTestPartResultReporterForCurrentThread(
+      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();
+  }
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  const TestCase* GetTestCase(int i) const {
+    const int index = GetElementOr(test_case_indices_, i, -1);
+    return index < 0 ? NULL : test_cases_[i];
+  }
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  TestCase* GetMutableTestCase(int i) {
+    const int index = GetElementOr(test_case_indices_, i, -1);
+    return index < 0 ? NULL : test_cases_[index];
+  }
+
+  // Provides access to the event listener list.
+  TestEventListeners* listeners() { return &listeners_; }
+
+  // Returns the TestResult for the test that's currently running, or
+  // the TestResult for the ad hoc test if no test is running.
+  TestResult* current_test_result();
+
+  // Returns the TestResult for the ad hoc test.
+  const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
+
+  // 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,
+                        const char* comment,
+                        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) {
+    // In order to support thread-safe death tests, we need to
+    // remember the original working directory when the test program
+    // was first invoked.  We cannot do this in RUN_ALL_TESTS(), as
+    // the user may have changed the current directory before calling
+    // RUN_ALL_TESTS().  Therefore we capture the current directory in
+    // AddTestInfo(), which is called to register a TEST or TEST_F
+    // before main() is reached.
+    if (original_working_dir_.IsEmpty()) {
+      original_working_dir_.Set(FilePath::GetCurrentDir());
+      GTEST_CHECK_(!original_working_dir_.IsEmpty())
+          << "Failed to get the current working directory.";
+    }
+
+    GetTestCase(test_info->test_case_name(),
+                test_info->test_case_comment(),
+                set_up_tc,
+                tear_down_tc)->AddTestInfo(test_info);
+  }
+
+#if GTEST_HAS_PARAM_TEST
+  // Returns ParameterizedTestCaseRegistry object used to keep track of
+  // value-parameterized tests and instantiate and register them.
+  internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {
+    return parameterized_test_registry_;
+  }
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // Sets the TestCase object for the test that's currently running.
+  void set_current_test_case(TestCase* a_current_test_case) {
+    current_test_case_ = a_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* a_current_test_info) {
+    current_test_info_ = a_current_test_info;
+  }
+
+  // Registers all parameterized tests defined using TEST_P and
+  // INSTANTIATE_TEST_P, creating regular tests for each test/parameter
+  // combination. This method can be called more then once; it has
+  // guards protecting from registering the tests more then once.
+  // If value-parameterized tests are disabled, RegisterParameterizedTests
+  // is present but does nothing.
+  void RegisterParameterizedTests();
+
+  // 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() {
+    ForEach(test_cases_, TestCase::ClearTestCaseResult);
+    ad_hoc_test_result_.Clear();
+  }
+
+  enum ReactionToSharding {
+    HONOR_SHARDING_PROTOCOL,
+    IGNORE_SHARDING_PROTOCOL
+  };
+
+  // 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.
+  // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests
+  // based on sharding variables in the environment.
+  // Returns the number of tests that should run.
+  int FilterTests(ReactionToSharding shard_tests);
+
+  // Prints the names of the tests matching the user-specified filter flag.
+  void ListTestsMatchingFilter();
+
+  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 vector of environments that need to be set-up/torn-down
+  // before/after the tests are run.
+  std::vector<Environment*>& environments() { return environments_; }
+
+  // Getters for the per-thread Google Test trace stack.
+  std::vector<TraceInfo>& gtest_trace_stack() {
+    return *(gtest_trace_stack_.pointer());
+  }
+  const std::vector<TraceInfo>& gtest_trace_stack() const {
+    return gtest_trace_stack_.get();
+  }
+
+#if GTEST_HAS_DEATH_TEST
+  void InitDeathTestSubprocessControlInfo() {
+    internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
+  }
+  // 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.
+  // Must not be called before a call to InitGoogleTest.
+  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();
+  }
+
+  void SuppressTestEventsIfInSubprocess();
+
+  friend class ReplaceDeathTestFactory;
+#endif  // GTEST_HAS_DEATH_TEST
+
+  // Initializes the event listener performing XML output as specified by
+  // UnitTestOptions. Must not be called before InitGoogleTest.
+  void ConfigureXmlOutput();
+
+  // Performs initialization dependent upon flag values obtained in
+  // ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to
+  // ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest
+  // this function is also called from RunAllTests.  Since this function can be
+  // called more than once, it has to be idempotent.
+  void PostFlagParsingInit();
+
+  // Gets the random seed used at the start of the current test iteration.
+  int random_seed() const { return random_seed_; }
+
+  // Gets the random number generator.
+  internal::Random* random() { return &random_; }
+
+  // Shuffles all test cases, and the tests within each test case,
+  // making sure that death tests are still run first.
+  void ShuffleTests();
+
+  // Restores the test cases and tests to their order before the first shuffle.
+  void UnshuffleTests();
+
+ private:
+  friend class ::testing::UnitTest;
+
+  // The UnitTest object that owns this implementation object.
+  UnitTest* const parent_;
+
+  // The working directory when the first TEST() or TEST_F() was
+  // executed.
+  internal::FilePath original_working_dir_;
+
+  // The default test part result reporters.
+  DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;
+  DefaultPerThreadTestPartResultReporter
+      default_per_thread_test_part_result_reporter_;
+
+  // Points to (but doesn't own) the global test part result reporter.
+  TestPartResultReporterInterface* global_test_part_result_repoter_;
+
+  // Protects read and write access to global_test_part_result_reporter_.
+  internal::Mutex global_test_part_result_reporter_mutex_;
+
+  // Points to (but doesn't own) the per-thread test part result reporter.
+  internal::ThreadLocal<TestPartResultReporterInterface*>
+      per_thread_test_part_result_reporter_;
+
+  // The vector of environments that need to be set-up/torn-down
+  // before/after the tests are run.
+  std::vector<Environment*> environments_;
+
+  // The vector of TestCases in their original order.  It owns the
+  // elements in the vector.
+  std::vector<TestCase*> test_cases_;
+
+  // Provides a level of indirection for the test case list to allow
+  // easy shuffling and restoring the test case order.  The i-th
+  // element of this vector is the index of the i-th test case in the
+  // shuffled order.
+  std::vector<int> test_case_indices_;
+
+#if GTEST_HAS_PARAM_TEST
+  // ParameterizedTestRegistry object used to register value-parameterized
+  // tests.
+  internal::ParameterizedTestCaseRegistry parameterized_test_registry_;
+
+  // Indicates whether RegisterParameterizedTests() has been called already.
+  bool parameterized_tests_registered_;
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // Index of the last death test case registered.  Initially -1.
+  int 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_.  Initially 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_.
+  TestResult ad_hoc_test_result_;
+
+  // The list of event listeners that can be used to track events inside
+  // Google Test.
+  TestEventListeners listeners_;
+
+  // 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_;
+
+  // True iff PostFlagParsingInit() has been called.
+  bool post_flag_parse_init_performed_;
+
+  // The random number seed used at the beginning of the test run.
+  int random_seed_;
+
+  // Our random number generator.
+  internal::Random random_;
+
+  // How long the test took to run, in milliseconds.
+  TimeInMillis elapsed_time_;
+
+#if 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<std::vector<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();
+}
+
+// Internal helper functions for implementing the simple regular
+// expression matcher.
+GTEST_API_ bool IsInSet(char ch, const char* str);
+GTEST_API_ bool IsDigit(char ch);
+GTEST_API_ bool IsPunct(char ch);
+GTEST_API_ bool IsRepeat(char ch);
+GTEST_API_ bool IsWhiteSpace(char ch);
+GTEST_API_ bool IsWordChar(char ch);
+GTEST_API_ bool IsValidEscape(char ch);
+GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
+GTEST_API_ bool ValidateRegex(const char* regex);
+GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
+GTEST_API_ bool MatchRepetitionAndRegexAtHead(
+    bool escaped, char ch, char repeat, const char* regex, const char* str);
+GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
+
+#if GTEST_HAS_DEATH_TEST
+
+// Returns the message describing the last system error, regardless of the
+// platform.
+String GetLastErrnoDescription();
+
+#if GTEST_OS_WINDOWS
+// Provides leak-safe Windows kernel handle ownership.
+class AutoHandle {
+ public:
+  AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}
+  explicit AutoHandle(HANDLE handle) : handle_(handle) {}
+
+  ~AutoHandle() { Reset(); }
+
+  HANDLE Get() const { return handle_; }
+  void Reset() { Reset(INVALID_HANDLE_VALUE); }
+  void Reset(HANDLE handle) {
+    if (handle != handle_) {
+      if (handle_ != INVALID_HANDLE_VALUE)
+        ::CloseHandle(handle_);
+      handle_ = handle;
+    }
+  }
+
+ private:
+  HANDLE handle_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
+};
+#endif  // GTEST_OS_WINDOWS
+
+// Attempts to parse a string into a positive integer pointed to by the
+// number parameter.  Returns true if that is possible.
+// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use
+// it here.
+template <typename Integer>
+bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
+  // Fail fast if the given string does not begin with a digit;
+  // this bypasses strtoXXX's "optional leading whitespace and plus
+  // or minus sign" semantics, which are undesirable here.
+  if (str.empty() || !isdigit(str[0])) {
+    return false;
+  }
+  errno = 0;
+
+  char* end;
+  // BiggestConvertible is the largest integer type that system-provided
+  // string-to-number conversion routines can return.
+#if GTEST_OS_WINDOWS && !defined(__GNUC__)
+  // MSVC and C++ Builder define __int64 instead of the standard long long.
+  typedef unsigned __int64 BiggestConvertible;
+  const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10);
+#else
+  typedef unsigned long long BiggestConvertible;  // NOLINT
+  const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);
+#endif  // GTEST_OS_WINDOWS && !defined(__GNUC__)
+  const bool parse_success = *end == '\0' && errno == 0;
+
+  // TODO(vladl@google.com): Convert this to compile time assertion when it is
+  // available.
+  GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
+
+  const Integer result = static_cast<Integer>(parsed);
+  if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {
+    *number = result;
+    return true;
+  }
+  return false;
+}
+#endif  // GTEST_HAS_DEATH_TEST
+
+// TestResult contains some private methods that should be hidden from
+// Google Test user but are required for testing. This class allow our tests
+// to access them.
+//
+// This class is supplied only for the purpose of testing Google Test's own
+// constructs. Do not use it in user tests, either directly or indirectly.
+class TestResultAccessor {
+ public:
+  static void RecordProperty(TestResult* test_result,
+                             const TestProperty& property) {
+    test_result->RecordProperty(property);
+  }
+
+  static void ClearTestPartResults(TestResult* test_result) {
+    test_result->ClearTestPartResults();
+  }
+
+  static const std::vector<testing::TestPartResult>& test_part_results(
+      const TestResult& test_result) {
+    return test_result.test_part_results();
+  }
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_SRC_GTEST_INTERNAL_INL_H_
+#undef GTEST_IMPLEMENTATION_
+
+#if GTEST_OS_WINDOWS
+#define vsnprintf _vsnprintf
+#endif  // GTEST_OS_WINDOWS
+
+namespace testing {
+
+using internal::CountIf;
+using internal::ForEach;
+using internal::GetElementOr;
+using internal::Shuffle;
+
+// Constants.
+
+// A test whose test case name or test name matches this filter is
+// disabled and not run.
+static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*";
+
+// A test case whose name matches this filter is considered a death
+// test case and will be run before test cases whose name doesn't
+// match this filter.
+static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
+
+// A test filter that matches everything.
+static const char kUniversalFilter[] = "*";
+
+// The default output file for XML output.
+static const char kDefaultOutputFile[] = "test_detail.xml";
+
+// The environment variable name for the test shard index.
+static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
+// The environment variable name for the total number of test shards.
+static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
+// The environment variable name for the test shard status file.
+static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
+
+namespace internal {
+
+// The text used in failure messages to indicate the start of the
+// stack trace.
+const char kStackTraceMarker[] = "\nStack trace:\n";
+
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+bool g_help_flag = false;
+
+}  // namespace internal
+
+GTEST_DEFINE_bool_(
+    also_run_disabled_tests,
+    internal::BoolFromGTestEnv("also_run_disabled_tests", false),
+    "Run disabled tests too, in addition to the tests normally being run.");
+
+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, xterm-color, xterm-256color, linux or cygwin.");
+
+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_bool_(
+    print_time,
+    internal::BoolFromGTestEnv("print_time", true),
+    "True iff " GTEST_NAME_
+    " should display elapsed time in text output.");
+
+GTEST_DEFINE_int32_(
+    random_seed,
+    internal::Int32FromGTestEnv("random_seed", 0),
+    "Random number seed to use when shuffling test orders.  Must be in range "
+    "[1, 99999], or 0 to use a seed based on the current time.");
+
+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_bool_(
+    show_internal_stack_frames, false,
+    "True iff " GTEST_NAME_ " should include internal stack frames when "
+    "printing test failure stack traces.");
+
+GTEST_DEFINE_bool_(
+    shuffle,
+    internal::BoolFromGTestEnv("shuffle", false),
+    "True iff " GTEST_NAME_
+    " should randomize tests' order on every run.");
+
+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_(
+    throw_on_failure,
+    internal::BoolFromGTestEnv("throw_on_failure", false),
+    "When this flag is specified, a failed assertion will throw an exception "
+    "if exceptions are enabled or exit the program with a non-zero code "
+    "otherwise.");
+
+namespace internal {
+
+// Generates a random number from [0, range), using a Linear
+// Congruential Generator (LCG).  Crashes if 'range' is 0 or greater
+// than kMaxRange.
+UInt32 Random::Generate(UInt32 range) {
+  // These constants are the same as are used in glibc's rand(3).
+  state_ = (1103515245U*state_ + 12345U) % kMaxRange;
+
+  GTEST_CHECK_(range > 0)
+      << "Cannot generate a number in the range [0, 0).";
+  GTEST_CHECK_(range <= kMaxRange)
+      << "Generation of a number in [0, " << range << ") was requested, "
+      << "but this can only generate numbers in [0, " << kMaxRange << ").";
+
+  // Converting via modulus introduces a bit of downward bias, but
+  // it's simple, and a linear congruential generator isn't too good
+  // to begin with.
+  return state_ % range;
+}
+
+// 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::InitGoogleTest() to initialize Google
+// Test.  g_init_gtest_count is set to the number of times
+// InitGoogleTest() has been called.  We don't protect this variable
+// under a mutex as it is only accessed in the main thread.
+int g_init_gtest_count = 0;
+static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
+
+// Iterates over a vector 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 std::vector<TestCase*>& case_list,
+                               int (TestCase::*method)() const) {
+  int sum = 0;
+  for (size_t i = 0; i < case_list.size(); i++) {
+    sum += (case_list[i]->*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();
+}
+
+// AssertHelper constructor.
+AssertHelper::AssertHelper(TestPartResult::Type type,
+                           const char* file,
+                           int line,
+                           const char* message)
+    : data_(new AssertHelperData(type, file, line, message)) {
+}
+
+AssertHelper::~AssertHelper() {
+  delete data_;
+}
+
+// Message assignment, for assertion streaming support.
+void AssertHelper::operator=(const Message& message) const {
+  UnitTest::GetInstance()->
+    AddTestPartResult(data_->type, data_->file, data_->line,
+                      AppendUserMessage(data_->message, message),
+                      UnitTest::GetInstance()->impl()
+                      ->CurrentOsStackTraceExceptTop(1)
+                      // Skips the stack frame for this function itself.
+                      );  // NOLINT
+}
+
+// Mutex for linked pointers.
+GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
+
+// Application pathname gotten in InitGoogleTest.
+String g_executable_path;
+
+// Returns the current application's name, removing directory path if that
+// is present.
+FilePath GetCurrentExecutableName() {
+  FilePath result;
+
+#if GTEST_OS_WINDOWS
+  result.Set(FilePath(g_executable_path).RemoveExtension("exe"));
+#else
+  result.Set(FilePath(g_executable_path));
+#endif  // GTEST_OS_WINDOWS
+
+  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::GetAbsolutePathToOutputFile() {
+  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(internal::FilePath::ConcatPaths(
+               internal::FilePath(
+                   UnitTest::GetInstance()->original_working_dir()),
+               internal::FilePath(kDefaultOutputFile)).ToString() );
+
+  internal::FilePath output_name(colon + 1);
+  if (!output_name.IsAbsolutePath())
+    // TODO(wan@google.com): on Windows \some\path is not an absolute
+    // path (as its meaning depends on the current drive), yet the
+    // following logic for turning it into an absolute path is wrong.
+    // Fix it.
+    output_name = internal::FilePath::ConcatPaths(
+        internal::FilePath(UnitTest::GetInstance()->original_working_dir()),
+        internal::FilePath(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;
+  for (;;) {
+    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 = String(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()));
+}
+
+#if 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 c'tor sets this object as the test part result reporter used by
+// Google Test.  The 'result' parameter specifies where to report the
+// results. Intercepts only failures from the current thread.
+ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
+    TestPartResultArray* result)
+    : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD),
+      result_(result) {
+  Init();
+}
+
+// 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(
+    InterceptMode intercept_mode, TestPartResultArray* result)
+    : intercept_mode_(intercept_mode),
+      result_(result) {
+  Init();
+}
+
+void ScopedFakeTestPartResultReporter::Init() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
+    old_reporter_ = impl->GetGlobalTestPartResultReporter();
+    impl->SetGlobalTestPartResultReporter(this);
+  } else {
+    old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();
+    impl->SetTestPartResultReporterForCurrentThread(this);
+  }
+}
+
+// The d'tor restores the test part result reporter used by Google Test
+// before.
+ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
+    impl->SetGlobalTestPartResultReporter(old_reporter_);
+  } else {
+    impl->SetTestPartResultReporterForCurrentThread(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 {
+
+// Returns the type ID of ::testing::Test.  We should always call this
+// instead of GetTypeId< ::testing::Test>() to get the type ID of
+// testing::Test.  This is to work around a suspected linker bug when
+// using Google Test as a framework on Mac OS X.  The bug causes
+// GetTypeId< ::testing::Test>() to return different values depending
+// on whether the call is from the Google Test framework itself or
+// from user test code.  GetTestTypeId() is guaranteed to always
+// return the same value, as it always calls GetTypeId<>() from the
+// gtest.cc, which is within the Google Test framework.
+TypeId GetTestTypeId() {
+  return GetTypeId<Test>();
+}
+
+// The value of GetTestTypeId() as seen from within the Google Test
+// library.  This is solely for testing GetTestTypeId().
+extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();
+
+// 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,
+                              TestPartResult::Type type,
+                              const char* substr) {
+  const String expected(type == TestPartResult::kFatalFailure ?
+                        "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,
+    TestPartResult::Type 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());
+}
+
+DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
+    UnitTestImpl* unit_test) : unit_test_(unit_test) {}
+
+void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  unit_test_->current_test_result()->AddTestPartResult(result);
+  unit_test_->listeners()->repeater()->OnTestPartResult(result);
+}
+
+DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
+    UnitTestImpl* unit_test) : unit_test_(unit_test) {}
+
+void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);
+}
+
+// Returns the global test part result reporter.
+TestPartResultReporterInterface*
+UnitTestImpl::GetGlobalTestPartResultReporter() {
+  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
+  return global_test_part_result_repoter_;
+}
+
+// Sets the global test part result reporter.
+void UnitTestImpl::SetGlobalTestPartResultReporter(
+    TestPartResultReporterInterface* reporter) {
+  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
+  global_test_part_result_repoter_ = reporter;
+}
+
+// Returns the test part result reporter for the current thread.
+TestPartResultReporterInterface*
+UnitTestImpl::GetTestPartResultReporterForCurrentThread() {
+  return per_thread_test_part_result_reporter_.get();
+}
+
+// Sets the test part result reporter for the current thread.
+void UnitTestImpl::SetTestPartResultReporterForCurrentThread(
+    TestPartResultReporterInterface* reporter) {
+  per_thread_test_part_result_reporter_.set(reporter);
+}
+
+// Gets the number of successful test cases.
+int UnitTestImpl::successful_test_case_count() const {
+  return CountIf(test_cases_, TestCasePassed);
+}
+
+// Gets the number of failed test cases.
+int UnitTestImpl::failed_test_case_count() const {
+  return CountIf(test_cases_, TestCaseFailed);
+}
+
+// Gets the number of all test cases.
+int UnitTestImpl::total_test_case_count() const {
+  return static_cast<int>(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 CountIf(test_cases_, 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("");
+}
+
+// Returns the current time in milliseconds.
+TimeInMillis GetTimeInMillis() {
+#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__)
+  // Difference between 1970-01-01 and 1601-01-01 in milliseconds.
+  // http://analogous.blogspot.com/2005/04/epoch.html
+  const TimeInMillis kJavaEpochToWinFileTimeDelta =
+    static_cast<TimeInMillis>(116444736UL) * 100000UL;
+  const DWORD kTenthMicrosInMilliSecond = 10000;
+
+  SYSTEMTIME now_systime;
+  FILETIME now_filetime;
+  ULARGE_INTEGER now_int64;
+  // TODO(kenton@google.com): 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 GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_
+  __timeb64 now;
+#ifdef _MSC_VER
+  // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
+  // (deprecated function) there.
+  // TODO(kenton@google.com): 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 GTEST_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."
+#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];
+    posix::StrNCpy(clone, str, length);
+    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));
+}
+
+#if GTEST_OS_WINDOWS_MOBILE
+// Creates a UTF-16 wide string from the given ANSI string, allocating
+// memory using new. The caller is responsible for deleting the return
+// value using delete[]. Returns the wide string, or NULL if the
+// input is NULL.
+LPCWSTR String::AnsiToUtf16(const char* ansi) {
+  if (!ansi) return NULL;
+  const int length = strlen(ansi);
+  const int unicode_length =
+      MultiByteToWideChar(CP_ACP, 0, ansi, length,
+                          NULL, 0);
+  WCHAR* unicode = new WCHAR[unicode_length + 1];
+  MultiByteToWideChar(CP_ACP, 0, ansi, length,
+                      unicode, unicode_length);
+  unicode[unicode_length] = 0;
+  return unicode;
+}
+
+// Creates an ANSI string from the given wide string, allocating
+// memory using new. The caller is responsible for deleting the return
+// value using delete[]. Returns the ANSI string, or NULL if the
+// input is NULL.
+const char* String::Utf16ToAnsi(LPCWSTR utf16_str)  {
+  if (!utf16_str) return NULL;
+  const int ansi_length =
+      WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
+                          NULL, 0, NULL, NULL);
+  char* ansi = new char[ansi_length + 1];
+  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
+                      ansi, ansi_length, NULL, NULL);
+  ansi[ansi_length] = 0;
+  return ansi;
+}
+
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+// 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 length,
+                                     Message* msg) {
+  // 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).
+  for (size_t i = 0; i != length; ) {  // NOLINT
+    if (wstr[i] != L'\0') {
+      *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));
+      while (i != length && wstr[i] != L'\0')
+        i++;
+    } else {
+      *msg << '\0';
+      i++;
+    }
+  }
+}
+
+#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'.
+  char buffer[32];  // CodePointToUtf8 requires a buffer that big.
+  msg << "L'"
+      << (wchar ? CodePointToUtf8(static_cast<UInt32>(wchar), buffer) : "\\0")
+      << "' (" << wchar_as_uint64 << ", 0x" << ::std::setbase(16)
+      << wchar_as_uint64 << ")";
+  return msg.GetString();
+}
+
+}  // namespace internal
+
+// AssertionResult constructors.
+// Used in EXPECT_TRUE/FALSE(assertion_result).
+AssertionResult::AssertionResult(const AssertionResult& other)
+    : success_(other.success_),
+      message_(other.message_.get() != NULL ?
+               new internal::String(*other.message_) :
+               static_cast<internal::String*>(NULL)) {
+}
+
+// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+AssertionResult AssertionResult::operator!() const {
+  AssertionResult negation(!success_);
+  if (message_.get() != NULL)
+    negation << *message_;
+  return negation;
+}
+
+// Makes a successful assertion result.
+AssertionResult AssertionSuccess() {
+  return AssertionResult(true);
+}
+
+// Makes a failed assertion result.
+AssertionResult AssertionFailure() {
+  return AssertionResult(false);
+}
+
+// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << message.
+AssertionResult AssertionFailure(const Message& message) {
+  return AssertionFailure() << message;
+}
+
+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);
+}
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result,
+                                      const char* expression_text,
+                                      const char* actual_predicate_value,
+                                      const char* expected_predicate_value) {
+  const char* actual_message = assertion_result.message();
+  Message msg;
+  msg << "Value of: " << expression_text
+      << "\n  Actual: " << actual_predicate_value;
+  if (actual_message[0] != '\0')
+    msg << " (" << actual_message << ")";
+  msg << "\nExpected: " << expected_predicate_value;
+  return msg.GetString();
+}
+
+// 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);
+}
+
+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);
+}
+
+#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 {
+
+#if GTEST_OS_WINDOWS
+
+namespace {
+
+// Helper function for IsHRESULT{SuccessFailure} predicates
+AssertionResult HRESULTFailureHelper(const char* expr,
+                                     const char* expected,
+                                     long hr) {  // NOLINT
+#if GTEST_OS_WINDOWS_MOBILE
+  // 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  // GTEST_OS_WINDOWS_MOBILE
+
+  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 a narrow string in UTF-8 encoding.
+// code_point parameter is of type UInt32 because wchar_t may not be
+// wide enough to contain a code point.
+// The output buffer str must containt at least 32 characters.
+// The function returns the address of the output buffer.
+// If the code_point is not a valid Unicode code point
+// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'.
+char* CodePointToUtf8(UInt32 code_point, char* str) {
+  if (code_point <= kMaxCodePoint1) {
+    str[1] = '\0';
+    str[0] = static_cast<char>(code_point);                          // 0xxxxxxx
+  } else if (code_point <= kMaxCodePoint2) {
+    str[2] = '\0';
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xC0 | code_point);                   // 110xxxxx
+  } else if (code_point <= kMaxCodePoint3) {
+    str[3] = '\0';
+    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xE0 | code_point);                   // 1110xxxx
+  } else if (code_point <= kMaxCodePoint4) {
+    str[4] = '\0';
+    str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xF0 | code_point);                   // 11110xxx
+  } else {
+    // The longest string String::Format can produce when invoked
+    // with these parameters is 28 character long (not including
+    // the terminating nul character). We are asking for 32 character
+    // buffer just in case. This is also enough for strncpy to
+    // null-terminate the destination string.
+    posix::StrNCpy(
+        str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32);
+    str[31] = '\0';  // Makes sure no change in the format to strncpy leaves
+                     // the result unterminated.
+  }
+  return str;
+}
+
+// The following two functions only make sense if the the system
+// uses UTF-16 for wide string encoding. All supported systems
+// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16.
+
+// Determines if the arguments constitute UTF-16 surrogate pair
+// and thus should be combined into a single Unicode code point
+// using CreateCodePointFromUtf16SurrogatePair.
+inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
+  return sizeof(wchar_t) == 2 &&
+      (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00;
+}
+
+// Creates a Unicode code point from UTF16 surrogate pair.
+inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,
+                                                    wchar_t second) {
+  const UInt32 mask = (1 << 10) - 1;
+  return (sizeof(wchar_t) == 2) ?
+      (((first & mask) << 10) | (second & mask)) + 0x10000 :
+      // This function should not be called when the condition is
+      // false, but we provide a sensible default in case it is.
+      static_cast<UInt32>(first);
+}
+
+// Converts a wide string to a narrow string in UTF-8 encoding.
+// The wide string is assumed to have the following encoding:
+//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
+// Parameter str points to a null-terminated wide string.
+// Parameter num_chars may additionally limit the number
+// of wchar_t characters processed. -1 is used when the entire string
+// should be processed.
+// If the string contains code points that are not valid Unicode code points
+// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
+// and contains invalid UTF-16 surrogate pairs, values in those pairs
+// will be encoded as individual Unicode characters from Basic Normal Plane.
+String WideStringToUtf8(const wchar_t* str, int num_chars) {
+  if (num_chars == -1)
+    num_chars = static_cast<int>(wcslen(str));
+
+  StrStream stream;
+  for (int i = 0; i < num_chars; ++i) {
+    UInt32 unicode_code_point;
+
+    if (str[i] == L'\0') {
+      break;
+    } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {
+      unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i],
+                                                                 str[i + 1]);
+      i++;
+    } else {
+      unicode_code_point = static_cast<UInt32>(str[i]);
+    }
+
+    char buffer[32];  // CodePointToUtf8 requires a buffer this big.
+    stream << CodePointToUtf8(unicode_code_point, buffer);
+  }
+  return StrStreamToString(&stream);
+}
+
+// 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)");
+
+  return String(internal::WideStringToUtf8(wide_c_str, -1).c_str());
+}
+
+// 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;
+  return posix::StrCaseCmp(lhs, rhs) == 0;
+}
+
+  // Compares two wide C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike wcscasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL wide C string,
+  // including the empty string.
+  // NB: The implementations on different platforms slightly differ.
+  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+  // environment variable. On GNU platform this method uses wcscasecmp
+  // which compares according to LC_CTYPE category of the current locale.
+  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+  // current locale.
+bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
+                                              const wchar_t* rhs) {
+  if ( lhs == NULL ) return rhs == NULL;
+
+  if ( rhs == NULL ) return false;
+
+#if GTEST_OS_WINDOWS
+  return _wcsicmp(lhs, rhs) == 0;
+#elif GTEST_OS_LINUX
+  return wcscasecmp(lhs, rhs) == 0;
+#else
+  // Mac OS X and Cygwin don't define wcscasecmp.  Other unknown OSes
+  // may not define it either.
+  wint_t left, right;
+  do {
+    left = towlower(*lhs++);
+    right = towlower(*rhs++);
+  } while (left && left == right);
+  return left == right;
+#endif  // OS selector
+}
+
+// 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 {
+  const char* const lhs_c_str = c_str();
+  const char* const rhs_c_str = rhs.c_str();
+
+  if (lhs_c_str == NULL) {
+    return rhs_c_str == NULL ? 0 : -1;  // NULL < anything except NULL
+  } else if (rhs_c_str == NULL) {
+    return 1;
+  }
+
+  const size_t shorter_str_len =
+      length() <= rhs.length() ? length() : rhs.length();
+  for (size_t i = 0; i != shorter_str_len; i++) {
+    if (lhs_c_str[i] < rhs_c_str[i]) {
+      return -1;
+    } else if (lhs_c_str[i] > rhs_c_str[i]) {
+      return 1;
+    }
+  }
+  return (length() < rhs.length()) ? -1 :
+      (length() > rhs.length()) ? 1 : 0;
+}
+
+// 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);
+}
+
+// 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, or if
+// there's an error, "<formatting error or buffer exceeded>" is
+// returned.
+String String::Format(const char * format, ...) {
+  va_list args;
+  va_start(args, format);
+
+  char buffer[4096];
+  const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]);
+
+  // MSVC 8 deprecates vsnprintf(), so we want to suppress warning
+  // 4996 (deprecated function) there.
+#ifdef _MSC_VER  // We are using MSVC.
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4996)  // Temporarily disables warning 4996.
+  const int size = vsnprintf(buffer, kBufferSize, format, args);
+#pragma warning(pop)           // Restores the warning state.
+#else  // We are not using MSVC.
+  const int size = vsnprintf(buffer, kBufferSize, format, args);
+#endif  // _MSC_VER
+  va_end(args);
+
+  // vsnprintf()'s behavior is not portable.  When the buffer is not
+  // big enough, it returns a negative value in MSVC, and returns the
+  // needed buffer size on Linux.  When there is an output error, it
+  // always returns a negative value.  For simplicity, we lump the two
+  // error cases together.
+  if (size < 0 || size >= kBufferSize) {
+    return String("<formatting error or buffer exceeded>");
+  } else {
+    return String(buffer, size);
+  }
+}
+
+// Converts the buffer in a StrStream to a String, converting NUL
+// bytes to "\\0" along the way.
+String StrStreamToString(StrStream* ss) {
+  const ::std::string& str = ss->str();
+  const char* const start = str.c_str();
+  const char* const end = start + str.length();
+
+  // 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);
+    }
+  }
+
+  return String(helper.str().c_str());
+}
+
+// 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
+
+// class TestResult
+
+// Creates an empty TestResult.
+TestResult::TestResult()
+    : death_test_count_(0),
+      elapsed_time_(0) {
+}
+
+// D'tor.
+TestResult::~TestResult() {
+}
+
+// Returns the i-th test part result among all the results. i can
+// range from 0 to total_part_count() - 1. If i is not in that range,
+// aborts the program.
+const TestPartResult& TestResult::GetTestPartResult(int i) const {
+  if (i < 0 || i >= total_part_count())
+    internal::posix::Abort();
+  return test_part_results_.at(i);
+}
+
+// Returns the i-th test property. i can range from 0 to
+// test_property_count() - 1. If i is not in that range, aborts the
+// program.
+const TestProperty& TestResult::GetTestProperty(int i) const {
+  if (i < 0 || i >= test_property_count())
+    internal::posix::Abort();
+  return test_properties_.at(i);
+}
+
+// Clears the test part results.
+void TestResult::ClearTestPartResults() {
+  test_part_results_.clear();
+}
+
+// Adds a test part result to the list.
+void TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
+  test_part_results_.push_back(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;
+  }
+  internal::MutexLock lock(&test_properites_mutex_);
+  const std::vector<TestProperty>::iterator property_with_matching_key =
+      std::find_if(test_properties_.begin(), test_properties_.end(),
+                   internal::TestPropertyKeyIs(test_property.key()));
+  if (property_with_matching_key == test_properties_.end()) {
+    test_properties_.push_back(test_property);
+    return;
+  }
+  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) {
+  internal::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 failed.
+bool TestResult::Failed() const {
+  for (int i = 0; i < total_part_count(); ++i) {
+    if (GetTestPartResult(i).failed())
+      return true;
+  }
+  return false;
+}
+
+// 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 CountIf(test_part_results_, TestPartFatallyFailed) > 0;
+}
+
+// Returns true iff the test part non-fatally failed.
+static bool TestPartNonfatallyFailed(const TestPartResult& result) {
+  return result.nonfatally_failed();
+}
+
+// Returns true iff the test has a non-fatal failure.
+bool TestResult::HasNonfatalFailure() const {
+  return CountIf(test_part_results_, TestPartNonfatallyFailed) > 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 static_cast<int>(test_part_results_.size());
+}
+
+// Returns the number of the test properties.
+int TestResult::test_property_count() const {
+  return static_cast<int>(test_properties_.size());
+}
+
+// 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());
+}
+
+namespace internal {
+
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
+                                    const String& message) {
+  // This function is a friend of UnitTest and as such has access to
+  // AddTestPartResult.
+  UnitTest::GetInstance()->AddTestPartResult(
+      result_type,
+      NULL,  // No info about the source file where the exception occurred.
+      -1,    // We have no info on which line caused the exception.
+      message,
+      String());  // No stack trace, either.
+}
+
+}  // namespace internal
+
+#if 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 << ".";
+
+  internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure,
+                                           message.GetString());
+}
+
+#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()[0]->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::GetTestTypeId();
+    // Is this test defined using TEST?
+    const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();
+
+    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();
+#if GTEST_HAS_SEH
+  // Catch SEH-style exceptions.
+  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 a compiler or platform that doesn't support SEH.
+  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_HAS_SEH
+}
+
+
+// Returns true iff the current test has a fatal failure.
+bool Test::HasFatalFailure() {
+  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();
+}
+
+// Returns true iff the current test has a non-fatal failure.
+bool Test::HasNonfatalFailure() {
+  return internal::GetUnitTestImpl()->current_test_result()->
+      HasNonfatalFailure();
+}
+
+// class TestInfo
+
+// Constructs a TestInfo object. It assumes ownership of the test factory
+// object via impl_.
+TestInfo::TestInfo(const char* a_test_case_name,
+                   const char* a_name,
+                   const char* a_test_case_comment,
+                   const char* a_comment,
+                   internal::TypeId fixture_class_id,
+                   internal::TestFactoryBase* factory) {
+  impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name,
+                                     a_test_case_comment, a_comment,
+                                     fixture_class_id, factory);
+}
+
+// Destructs a TestInfo object.
+TestInfo::~TestInfo() {
+  delete impl_;
+}
+
+namespace internal {
+
+// Creates a new TestInfo object and registers it with Google Test;
+// returns the created object.
+//
+// Arguments:
+//
+//   test_case_name:   name of the test case
+//   name:             name of the test
+//   test_case_comment: a comment on the test case that will be included in
+//                      the test output
+//   comment:          a comment on the test that will be included in the
+//                     test output
+//   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
+//   factory:          pointer to the factory that creates a test object.
+//                     The newly created TestInfo instance will assume
+//                     ownership of the factory object.
+TestInfo* MakeAndRegisterTestInfo(
+    const char* test_case_name, const char* name,
+    const char* test_case_comment, const char* comment,
+    TypeId fixture_class_id,
+    SetUpTestCaseFunc set_up_tc,
+    TearDownTestCaseFunc tear_down_tc,
+    TestFactoryBase* factory) {
+  TestInfo* const test_info =
+      new TestInfo(test_case_name, name, test_case_comment, comment,
+                   fixture_class_id, factory);
+  GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
+  return test_info;
+}
+
+#if GTEST_HAS_PARAM_TEST
+void ReportInvalidTestCaseType(const char* test_case_name,
+                               const char* file, int line) {
+  Message errors;
+  errors
+      << "Attempted redefinition of test case " << test_case_name << ".\n"
+      << "All tests in the same test case must use the same test fixture\n"
+      << "class.  However, in test case " << test_case_name << ", you tried\n"
+      << "to define a test using a fixture class different from the one\n"
+      << "used earlier. This can happen if the two fixture classes are\n"
+      << "from different namespaces and have the same name. You should\n"
+      << "probably rename one of the classes to put the tests into different\n"
+      << "test cases.";
+
+  fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
+          errors.GetString().c_str());
+}
+#endif  // GTEST_HAS_PARAM_TEST
+
+}  // namespace internal
+
+// 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 the test case comment.
+const char* TestInfo::test_case_comment() const {
+  return impl_->test_case_comment();
+}
+
+// Returns the test comment.
+const char* TestInfo::comment() const {
+  return impl_->comment();
+}
+
+// Returns true if this test should run.
+bool TestInfo::should_run() const { return impl_->should_run(); }
+
+// Returns true if this test matches the user-specified filter.
+bool TestInfo::matches_filter() const { return impl_->matches_filter(); }
+
+// Returns the result of the test.
+const 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
+
+namespace internal {
+
+// This method expands all parameterized tests registered with macros TEST_P
+// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.
+// This will be done just once during the program runtime.
+void UnitTestImpl::RegisterParameterizedTests() {
+#if GTEST_HAS_PARAM_TEST
+  if (!parameterized_tests_registered_) {
+    parameterized_test_registry_.RegisterTests();
+    parameterized_tests_registered_ = true;
+  }
+#endif
+}
+
+// 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_);
+
+  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+  // Notifies the unit test event listeners that a test is about to start.
+  repeater->OnTestStart(*parent_);
+
+  const TimeInMillis start = GetTimeInMillis();
+
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+#if GTEST_HAS_SEH
+  // Catch SEH-style exceptions.
+  Test* test = NULL;
+
+  __try {
+    // Creates the test object.
+    test = factory_->CreateTest();
+  } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+      GetExceptionCode())) {
+    AddExceptionThrownFailure(GetExceptionCode(),
+                              "the test fixture's constructor");
+    return;
+  }
+#else  // We are on a compiler or platform that doesn't support SEH.
+
+  // 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 = factory_->CreateTest();
+#endif  // GTEST_HAS_SEH
+
+  // 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.
+  repeater->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 CountIf(test_info_list_, TestPassed);
+}
+
+// Gets the number of failed tests in this test case.
+int TestCase::failed_test_count() const {
+  return CountIf(test_info_list_, TestFailed);
+}
+
+int TestCase::disabled_test_count() const {
+  return CountIf(test_info_list_, TestDisabled);
+}
+
+// Get the number of tests in this test case that should run.
+int TestCase::test_to_run_count() const {
+  return CountIf(test_info_list_, ShouldRunTest);
+}
+
+// Gets the number of all tests.
+int TestCase::total_test_count() const {
+  return static_cast<int>(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* a_name, const char* a_comment,
+                   Test::SetUpTestCaseFunc set_up_tc,
+                   Test::TearDownTestCaseFunc tear_down_tc)
+    : name_(a_name),
+      comment_(a_comment),
+      set_up_tc_(set_up_tc),
+      tear_down_tc_(tear_down_tc),
+      should_run_(false),
+      elapsed_time_(0) {
+}
+
+// Destructor of TestCase.
+TestCase::~TestCase() {
+  // Deletes every Test in the collection.
+  ForEach(test_info_list_, internal::Delete<TestInfo>);
+}
+
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+const TestInfo* TestCase::GetTestInfo(int i) const {
+  const int index = GetElementOr(test_indices_, i, -1);
+  return index < 0 ? NULL : test_info_list_[index];
+}
+
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+TestInfo* TestCase::GetMutableTestInfo(int i) {
+  const int index = GetElementOr(test_indices_, i, -1);
+  return index < 0 ? NULL : test_info_list_[index];
+}
+
+// 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_.push_back(test_info);
+  test_indices_.push_back(static_cast<int>(test_indices_.size()));
+}
+
+// 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);
+
+  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+  repeater->OnTestCaseStart(*this);
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  set_up_tc_();
+
+  const internal::TimeInMillis start = internal::GetTimeInMillis();
+  for (int i = 0; i < total_test_count(); i++) {
+    GetMutableTestInfo(i)->impl()->Run();
+  }
+  elapsed_time_ = internal::GetTimeInMillis() - start;
+
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  tear_down_tc_();
+  repeater->OnTestCaseEnd(*this);
+  impl->set_current_test_case(NULL);
+}
+
+// Clears the results of all tests in this test case.
+void TestCase::ClearResult() {
+  ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult);
+}
+
+// Returns true iff test passed.
+bool TestCase::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.
+bool TestCase::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.
+bool TestCase::TestDisabled(const TestInfo * test_info) {
+  return test_info->impl()->is_disabled();
+}
+
+// Returns true if the given test should run.
+bool TestCase::ShouldRunTest(const TestInfo *test_info) {
+  return test_info->impl()->should_run();
+}
+
+// Shuffles the tests in this test case.
+void TestCase::ShuffleTests(internal::Random* random) {
+  Shuffle(random, &test_indices_);
+}
+
+// Restores the test order to before the first shuffle.
+void TestCase::UnshuffleTests() {
+  for (size_t i = 0; i < test_indices_.size(); i++) {
+    test_indices_[i] = static_cast<int>(i);
+  }
+}
+
+// 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 TestPartResult::Type enum to human-friendly string
+// representation.  Both kNonFatalFailure and kFatalFailure 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(TestPartResult::Type type) {
+  switch (type) {
+    case TestPartResult::kSuccess:
+      return "Success";
+
+    case TestPartResult::kNonFatalFailure:
+    case TestPartResult::kFatalFailure:
+#ifdef _MSC_VER
+      return "error: ";
+#else
+      return "Failure\n";
+#endif
+  }
+
+  return "Unknown result type";
+}
+
+// Prints a TestPartResult to a String.
+static internal::String PrintTestPartResultToString(
+    const TestPartResult& test_part_result) {
+  return (Message()
+          << internal::FormatFileLocation(test_part_result.file_name(),
+                                          test_part_result.line_number())
+          << " " << TestPartResultTypeToString(test_part_result.type())
+          << test_part_result.message()).GetString();
+}
+
+// Prints a TestPartResult.
+static void PrintTestPartResult(const TestPartResult& test_part_result) {
+  const internal::String& result =
+      PrintTestPartResultToString(test_part_result);
+  printf("%s\n", result.c_str());
+  fflush(stdout);
+  // If the test program runs in Visual Studio or a debugger, the
+  // following statements add the test part result message to the Output
+  // window such that the user can double-click on it to jump to the
+  // corresponding source code location; otherwise they do nothing.
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  // We don't call OutputDebugString*() on Windows Mobile, as printing
+  // to stdout is done by OutputDebugString() there already - we don't
+  // want the same message printed twice.
+  ::OutputDebugStringA(result.c_str());
+  ::OutputDebugStringA("\n");
+#endif
+}
+
+// class PrettyUnitTestResultPrinter
+
+namespace internal {
+
+enum GTestColor {
+  COLOR_DEFAULT,
+  COLOR_RED,
+  COLOR_GREEN,
+  COLOR_YELLOW
+};
+
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+
+// 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;
+    default:           return 0;
+  }
+}
+
+#else
+
+// Returns the ANSI color code for the given color.  COLOR_DEFAULT is
+// an invalid input.
+const char* GetAnsiColorCode(GTestColor color) {
+  switch (color) {
+    case COLOR_RED:     return "1";
+    case COLOR_GREEN:   return "2";
+    case COLOR_YELLOW:  return "3";
+    default:            return NULL;
+  };
+}
+
+#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+
+// 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")) {
+#if GTEST_OS_WINDOWS
+    // 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 = posix::GetEnv("TERM");
+    const bool term_supports_color =
+        String::CStringEquals(term, "xterm") ||
+        String::CStringEquals(term, "xterm-color") ||
+        String::CStringEquals(term, "xterm-256color") ||
+        String::CStringEquals(term, "linux") ||
+        String::CStringEquals(term, "cygwin");
+    return stdout_is_tty && term_supports_color;
+#endif  // GTEST_OS_WINDOWS
+  }
+
+  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);
+
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+  const bool use_color = false;
+#else
+  static const bool in_color_mode =
+      ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
+  const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
+#endif  // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+  // The '!= 0' comparison is necessary to satisfy MSVC 7.1.
+
+  if (!use_color) {
+    vprintf(fmt, args);
+    va_end(args);
+    return;
+  }
+
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  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;
+
+  // We need to flush the stream buffers into the console before each
+  // SetConsoleTextAttribute call lest it affect the text that is already
+  // printed but has not yet reached the console.
+  fflush(stdout);
+  SetConsoleTextAttribute(stdout_handle,
+                          GetColorAttribute(color) | FOREGROUND_INTENSITY);
+  vprintf(fmt, args);
+
+  fflush(stdout);
+  // 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  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  va_end(args);
+}
+
+// This class implements the TestEventListener interface.
+//
+// Class PrettyUnitTestResultPrinter is copyable.
+class PrettyUnitTestResultPrinter : public TestEventListener {
+ 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 TestEventListener class.
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestCaseStart(const TestCase& test_case);
+  virtual void OnTestStart(const TestInfo& test_info);
+  virtual void OnTestPartResult(const TestPartResult& result);
+  virtual void OnTestEnd(const TestInfo& test_info);
+  virtual void OnTestCaseEnd(const TestCase& test_case);
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+
+ private:
+  static void PrintFailedTests(const UnitTest& unit_test);
+
+  internal::String test_case_name_;
+};
+
+  // Fired before each iteration of tests starts.
+void PrettyUnitTestResultPrinter::OnTestIterationStart(
+    const UnitTest& unit_test, int iteration) {
+  if (GTEST_FLAG(repeat) != 1)
+    printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1);
+
+  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);
+  }
+
+  if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: This is test shard %s of %s.\n",
+                  internal::posix::GetEnv(kTestShardIndex),
+                  internal::posix::GetEnv(kTestTotalShards));
+  }
+
+  if (GTEST_FLAG(shuffle)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: Randomizing tests' orders with a seed of %d .\n",
+                  unit_test.random_seed());
+  }
+
+  ColoredPrintf(COLOR_GREEN,  "[==========] ");
+  printf("Running %s from %s.\n",
+         FormatTestCount(unit_test.test_to_run_count()).c_str(),
+         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
+    const UnitTest& /*unit_test*/) {
+  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", counts.c_str(), test_case_name_.c_str());
+  if (test_case.comment()[0] == '\0') {
+    printf("\n");
+  } else {
+    printf(", where %s\n", test_case.comment());
+  }
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
+  ColoredPrintf(COLOR_GREEN,  "[ RUN      ] ");
+  PrintTestName(test_case_name_.c_str(), test_info.name());
+  if (test_info.comment()[0] == '\0') {
+    printf("\n");
+  } else {
+    printf(", where %s\n", test_info.comment());
+  }
+  fflush(stdout);
+}
+
+// Called after an assertion failure.
+void PrettyUnitTestResultPrinter::OnTestPartResult(
+    const TestPartResult& result) {
+  // If the test part succeeded, we don't need to do anything.
+  if (result.type() == TestPartResult::kSuccess)
+    return;
+
+  // Print failure message from the assertion (e.g. expected this and got that).
+  PrintTestPartResult(result);
+  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());
+  if (GTEST_FLAG(print_time)) {
+    printf(" (%s ms)\n", internal::StreamableToString(
+           test_info.result()->elapsed_time()).c_str());
+  } else {
+    printf("\n");
+  }
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
+  if (!GTEST_FLAG(print_time)) return;
+
+  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 (%s ms total)\n\n",
+         counts.c_str(), test_case_name_.c_str(),
+         internal::StreamableToString(test_case.elapsed_time()).c_str());
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
+    const UnitTest& /*unit_test*/) {
+  ColoredPrintf(COLOR_GREEN,  "[----------] ");
+  printf("Global test environment tear-down\n");
+  fflush(stdout);
+}
+
+// Internal helper for printing the list of failed tests.
+void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {
+  const int failed_test_count = unit_test.failed_test_count();
+  if (failed_test_count == 0) {
+    return;
+  }
+
+  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
+    const TestCase& test_case = *unit_test.GetTestCase(i);
+    if (!test_case.should_run() || (test_case.failed_test_count() == 0)) {
+      continue;
+    }
+    for (int j = 0; j < test_case.total_test_count(); ++j) {
+      const TestInfo& test_info = *test_case.GetTestInfo(j);
+      if (!test_info.should_run() || test_info.result()->Passed()) {
+        continue;
+      }
+      ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+      printf("%s.%s", test_case.name(), test_info.name());
+      if (test_case.comment()[0] != '\0' ||
+          test_info.comment()[0] != '\0') {
+        printf(", where %s", test_case.comment());
+        if (test_case.comment()[0] != '\0' &&
+            test_info.comment()[0] != '\0') {
+          printf(" and ");
+        }
+      }
+      printf("%s\n", test_info.comment());
+    }
+  }
+}
+
+ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+                                                      int /*iteration*/) {
+  ColoredPrintf(COLOR_GREEN,  "[==========] ");
+  printf("%s from %s ran.",
+         FormatTestCount(unit_test.test_to_run_count()).c_str(),
+         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+  if (GTEST_FLAG(print_time)) {
+    printf(" (%s ms total)",
+           internal::StreamableToString(unit_test.elapsed_time()).c_str());
+  }
+  printf("\n");
+  ColoredPrintf(COLOR_GREEN,  "[  PASSED  ] ");
+  printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
+
+  int num_failures = unit_test.failed_test_count();
+  if (!unit_test.Passed()) {
+    const int failed_test_count = unit_test.failed_test_count();
+    ColoredPrintf(COLOR_RED,  "[  FAILED  ] ");
+    printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str());
+    PrintFailedTests(unit_test);
+    printf("\n%2d FAILED %s\n", num_failures,
+                        num_failures == 1 ? "TEST" : "TESTS");
+  }
+
+  int num_disabled = unit_test.disabled_test_count();
+  if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
+    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 TestEventRepeater
+//
+// This class forwards events to other event listeners.
+class TestEventRepeater : public TestEventListener {
+ public:
+  TestEventRepeater() : forwarding_enabled_(true) {}
+  virtual ~TestEventRepeater();
+  void Append(TestEventListener *listener);
+  TestEventListener* Release(TestEventListener* listener);
+
+  // Controls whether events will be forwarded to listeners_. Set to false
+  // in death test child processes.
+  bool forwarding_enabled() const { return forwarding_enabled_; }
+  void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
+
+  virtual void OnTestProgramStart(const UnitTest& unit_test);
+  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);
+  virtual void OnTestCaseStart(const TestCase& test_case);
+  virtual void OnTestStart(const TestInfo& test_info);
+  virtual void OnTestPartResult(const TestPartResult& result);
+  virtual void OnTestEnd(const TestInfo& test_info);
+  virtual void OnTestCaseEnd(const TestCase& test_case);
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+  virtual void OnTestProgramEnd(const UnitTest& unit_test);
+
+ private:
+  // Controls whether events will be forwarded to listeners_. Set to false
+  // in death test child processes.
+  bool forwarding_enabled_;
+  // The list of listeners that receive events.
+  std::vector<TestEventListener*> listeners_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);
+};
+
+TestEventRepeater::~TestEventRepeater() {
+  ForEach(listeners_, Delete<TestEventListener>);
+}
+
+void TestEventRepeater::Append(TestEventListener *listener) {
+  listeners_.push_back(listener);
+}
+
+// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
+TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
+  for (size_t i = 0; i < listeners_.size(); ++i) {
+    if (listeners_[i] == listener) {
+      listeners_.erase(listeners_.begin() + i);
+      return listener;
+    }
+  }
+
+  return NULL;
+}
+
+// Since most methods are very similar, use macros to reduce boilerplate.
+// This defines a member that forwards the call to all listeners.
+#define GTEST_REPEATER_METHOD_(Name, Type) \
+void TestEventRepeater::Name(const Type& parameter) { \
+  if (forwarding_enabled_) { \
+    for (size_t i = 0; i < listeners_.size(); i++) { \
+      listeners_[i]->Name(parameter); \
+    } \
+  } \
+}
+// This defines a member that forwards the call to all listeners in reverse
+// order.
+#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \
+void TestEventRepeater::Name(const Type& parameter) { \
+  if (forwarding_enabled_) { \
+    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \
+      listeners_[i]->Name(parameter); \
+    } \
+  } \
+}
+
+GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)
+GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)
+GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase)
+GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
+GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
+GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
+
+#undef GTEST_REPEATER_METHOD_
+#undef GTEST_REVERSE_REPEATER_METHOD_
+
+void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,
+                                             int iteration) {
+  if (forwarding_enabled_) {
+    for (size_t i = 0; i < listeners_.size(); i++) {
+      listeners_[i]->OnTestIterationStart(unit_test, iteration);
+    }
+  }
+}
+
+void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
+                                           int iteration) {
+  if (forwarding_enabled_) {
+    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {
+      listeners_[i]->OnTestIterationEnd(unit_test, iteration);
+    }
+  }
+}
+
+// End TestEventRepeater
+
+// This class generates an XML output file.
+class XmlUnitTestResultPrinter : public EmptyTestEventListener {
+ public:
+  explicit XmlUnitTestResultPrinter(const char* output_file);
+
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+
+ 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 String EscapeXml(const char* str, bool is_attribute);
+
+  // Returns the given string with all characters invalid in XML removed.
+  static String RemoveInvalidXmlCharacters(const char* str);
+
+  // Convenience wrapper around EscapeXml when str is an attribute value.
+  static String EscapeXmlAttribute(const char* str) {
+    return EscapeXml(str, true);
+  }
+
+  // Convenience wrapper around EscapeXml when str is not an attribute value.
+  static String EscapeXmlText(const char* str) { return EscapeXml(str, false); }
+
+  // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+  static void OutputXmlCDataSection(::std::ostream* stream, const char* data);
+
+  // Streams an XML representation of a TestInfo object.
+  static void OutputXmlTestInfo(::std::ostream* stream,
+                                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 String TestPropertiesAsXmlAttributes(const TestResult& result);
+
+  // The output file.
+  const 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::OnTestIterationEnd(const UnitTest& unit_test,
+                                                  int /*iteration*/) {
+  FILE* xmlout = NULL;
+  FilePath output_file(output_file_);
+  FilePath output_dir(output_file.RemoveFileName());
+
+  if (output_dir.CreateDirectoriesRecursively()) {
+    xmlout = posix::FOpen(output_file_.c_str(), "w");
+  }
+  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.
+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 << String::Format("&#x%02X;", unsigned(*src));
+            else
+              m << *src;
+          }
+          break;
+      }
+    }
+  }
+
+  return m.GetString();
+}
+
+// Returns the given string with all characters invalid in XML removed.
+// Currently invalid characters are dropped from the string. An
+// alternative is to replace them with certain characters such as . or ?.
+String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) {
+  char* const output = new char[strlen(str) + 1];
+  char* appender = output;
+  for (char ch = *str; ch != '\0'; ch = *++str)
+    if (IsValidXmlCharacter(ch))
+      *appender++ = ch;
+  *appender = '\0';
+
+  String ret_value(output);
+  delete[] output;
+  return ret_value;
+}
+
+// The following routines generate an XML representation of a UnitTest
+// object.
+//
+// This is how Google Test concepts map to the DTD:
+//
+// <testsuites 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>
+//       <failure message="...">...</failure>
+//       <failure message="...">...</failure>
+//                                     <-- individual assertion failures
+//     </testcase>
+//   </testsuite>
+// </testsuites>
+
+// Formats the given time in milliseconds as seconds.
+std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
+  ::std::stringstream ss;
+  ss << ms/1000.0;
+  return ss.str();
+}
+
+// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
+                                                     const char* data) {
+  const char* segment = data;
+  *stream << "<![CDATA[";
+  for (;;) {
+    const char* const next_segment = strstr(segment, "]]>");
+    if (next_segment != NULL) {
+      stream->write(
+          segment, static_cast<std::streamsize>(next_segment - segment));
+      *stream << "]]>]]&gt;<![CDATA[";
+      segment = next_segment + strlen("]]>");
+    } else {
+      *stream << segment;
+      break;
+    }
+  }
+  *stream << "]]>";
+}
+
+// Prints an XML representation of a TestInfo object.
+// TODO(wan): There is also value in printing properties with the plain printer.
+void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
+                                                 const char* test_case_name,
+                                                 const TestInfo& test_info) {
+  const TestResult& result = *test_info.result();
+  *stream << "    <testcase name=\""
+          << EscapeXmlAttribute(test_info.name()).c_str()
+          << "\" status=\""
+          << (test_info.should_run() ? "run" : "notrun")
+          << "\" time=\""
+          << FormatTimeInMillisAsSeconds(result.elapsed_time())
+          << "\" classname=\"" << EscapeXmlAttribute(test_case_name).c_str()
+          << "\"" << TestPropertiesAsXmlAttributes(result).c_str();
+
+  int failures = 0;
+  for (int i = 0; i < result.total_part_count(); ++i) {
+    const TestPartResult& part = result.GetTestPartResult(i);
+    if (part.failed()) {
+      if (++failures == 1)
+        *stream << ">\n";
+      *stream << "      <failure message=\""
+              << EscapeXmlAttribute(part.summary()).c_str()
+              << "\" type=\"\">";
+      const String message = RemoveInvalidXmlCharacters(String::Format(
+          "%s:%d\n%s",
+          part.file_name(), part.line_number(),
+          part.message()).c_str());
+      OutputXmlCDataSection(stream, message.c_str());
+      *stream << "</failure>\n";
+    }
+  }
+
+  if (failures == 0)
+    *stream << " />\n";
+  else
+    *stream << "    </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",
+          FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str());
+  for (int i = 0; i < test_case.total_test_count(); ++i) {
+    StrStream stream;
+    OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i));
+    fprintf(out, "%s", StrStreamToString(&stream).c_str());
+  }
+  fprintf(out, "  </testsuite>\n");
+}
+
+// Prints an XML summary of unit_test to output stream out.
+void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
+                                                const UnitTest& unit_test) {
+  fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+  fprintf(out,
+          "<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
+          "errors=\"0\" time=\"%s\" ",
+          unit_test.total_test_count(),
+          unit_test.failed_test_count(),
+          unit_test.disabled_test_count(),
+          FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str());
+  if (GTEST_FLAG(shuffle)) {
+    fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
+  }
+  fprintf(out, "name=\"AllTests\">\n");
+  for (int i = 0; i < unit_test.total_test_case_count(); ++i)
+    PrintXmlTestCase(out, *unit_test.GetTestCase(i));
+  fprintf(out, "</testsuites>\n");
+}
+
+// Produces a string representing the test properties in a result as space
+// delimited XML attributes based on the property key="value" pairs.
+String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
+    const TestResult& result) {
+  Message attributes;
+  for (int i = 0; i < result.test_property_count(); ++i) {
+    const TestProperty& property = result.GetTestProperty(i);
+    attributes << " " << property.key() << "="
+        << "\"" << EscapeXmlAttribute(property.value()) << "\"";
+  }
+  return attributes.GetString();
+}
+
+// End XmlUnitTestResultPrinter
+
+// 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 TestEventListeners
+
+TestEventListeners::TestEventListeners()
+    : repeater_(new internal::TestEventRepeater()),
+      default_result_printer_(NULL),
+      default_xml_generator_(NULL) {
+}
+
+TestEventListeners::~TestEventListeners() { delete repeater_; }
+
+// Returns the standard listener responsible for the default console
+// output.  Can be removed from the listeners list to shut down default
+// console output.  Note that removing this object from the listener list
+// with Release transfers its ownership to the user.
+void TestEventListeners::Append(TestEventListener* listener) {
+  repeater_->Append(listener);
+}
+
+// Removes the given event listener from the list and returns it.  It then
+// becomes the caller's responsibility to delete the listener. Returns
+// NULL if the listener is not found in the list.
+TestEventListener* TestEventListeners::Release(TestEventListener* listener) {
+  if (listener == default_result_printer_)
+    default_result_printer_ = NULL;
+  else if (listener == default_xml_generator_)
+    default_xml_generator_ = NULL;
+  return repeater_->Release(listener);
+}
+
+// Returns repeater that broadcasts the TestEventListener events to all
+// subscribers.
+TestEventListener* TestEventListeners::repeater() { return repeater_; }
+
+// Sets the default_result_printer attribute to the provided listener.
+// The listener is also added to the listener list and previous
+// default_result_printer is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
+  if (default_result_printer_ != listener) {
+    // It is an error to pass this method a listener that is already in the
+    // list.
+    delete Release(default_result_printer_);
+    default_result_printer_ = listener;
+    if (listener != NULL)
+      Append(listener);
+  }
+}
+
+// Sets the default_xml_generator attribute to the provided listener.  The
+// listener is also added to the listener list and previous
+// default_xml_generator is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {
+  if (default_xml_generator_ != listener) {
+    // It is an error to pass this method a listener that is already in the
+    // list.
+    delete Release(default_xml_generator_);
+    default_xml_generator_ = listener;
+    if (listener != NULL)
+      Append(listener);
+  }
+}
+
+// Controls whether events will be forwarded by the repeater to the
+// listeners in the list.
+bool TestEventListeners::EventForwardingEnabled() const {
+  return repeater_->forwarding_enabled();
+}
+
+void TestEventListeners::SuppressEventForwarding() {
+  repeater_->set_forwarding_enabled(false);
+}
+
+// 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.
+
+  // CodeGear C++Builder insists on a public destructor for the
+  // default implementation.  Use this implementation to keep good OO
+  // design with private destructor.
+
+#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+  static UnitTest* const instance = new UnitTest;
+  return instance;
+#else
+  static UnitTest instance;
+  return &instance;
+#endif  // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+}
+
+// Gets the number of successful test cases.
+int UnitTest::successful_test_case_count() const {
+  return impl()->successful_test_case_count();
+}
+
+// Gets the number of failed test cases.
+int UnitTest::failed_test_case_count() const {
+  return impl()->failed_test_case_count();
+}
+
+// Gets the number of all test cases.
+int UnitTest::total_test_case_count() const {
+  return impl()->total_test_case_count();
+}
+
+// Gets the number of all test cases that contain at least one test
+// that should run.
+int UnitTest::test_case_to_run_count() const {
+  return impl()->test_case_to_run_count();
+}
+
+// Gets the number of successful tests.
+int UnitTest::successful_test_count() const {
+  return impl()->successful_test_count();
+}
+
+// Gets the number of failed tests.
+int UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
+
+// Gets the number of disabled tests.
+int UnitTest::disabled_test_count() const {
+  return impl()->disabled_test_count();
+}
+
+// Gets the number of all tests.
+int UnitTest::total_test_count() const { return impl()->total_test_count(); }
+
+// Gets the number of tests that should run.
+int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
+
+// Gets the elapsed time, in milliseconds.
+internal::TimeInMillis UnitTest::elapsed_time() const {
+  return impl()->elapsed_time();
+}
+
+// Returns true iff the unit test passed (i.e. all test cases passed).
+bool UnitTest::Passed() const { return impl()->Passed(); }
+
+// Returns true iff the unit test failed (i.e. some test case failed
+// or something outside of all tests failed).
+bool UnitTest::Failed() const { return impl()->Failed(); }
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+const TestCase* UnitTest::GetTestCase(int i) const {
+  return impl()->GetTestCase(i);
+}
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+TestCase* UnitTest::GetMutableTestCase(int i) {
+  return impl()->GetMutableTestCase(i);
+}
+
+// Returns the list of event listeners that can be used to track events
+// inside Google Test.
+TestEventListeners& UnitTest::listeners() {
+  return *impl()->listeners();
+}
+
+// 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().push_back(env);
+  return env;
+}
+
+#if GTEST_HAS_EXCEPTIONS
+// A failed Google Test assertion will throw an exception of this type
+// when exceptions are enabled.  We derive it from std::runtime_error,
+// which is for errors presumably detectable only at run time.  Since
+// std::runtime_error inherits from std::exception, many testing
+// frameworks know how to extract and print the message inside it.
+class GoogleTestFailureException : public ::std::runtime_error {
+ public:
+  explicit GoogleTestFailureException(const TestPartResult& failure)
+      : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}
+};
+#endif
+
+// 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(TestPartResult::Type 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 (int i = static_cast<int>(impl_->gtest_trace_stack().size());
+         i > 0; --i) {
+      const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
+      msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
+          << " " << trace.message;
+    }
+  }
+
+  if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {
+    msg << internal::kStackTraceMarker << os_stack_trace;
+  }
+
+  const TestPartResult result =
+    TestPartResult(result_type, file_name, line_number,
+                   msg.GetString().c_str());
+  impl_->GetTestPartResultReporterForCurrentThread()->
+      ReportTestPartResult(result);
+
+  if (result_type != TestPartResult::kSuccess) {
+    // gtest_break_on_failure takes precedence over
+    // gtest_throw_on_failure.  This allows a user to set the latter
+    // in the code (perhaps in order to use Google Test assertions
+    // with another testing framework) and specify the former on the
+    // command line for debugging.
+    if (GTEST_FLAG(break_on_failure)) {
+#if GTEST_OS_WINDOWS
+      // Using DebugBreak on Windows allows gtest to still break into a debugger
+      // when a failure happens and both the --gtest_break_on_failure and
+      // the --gtest_catch_exceptions flags are specified.
+      DebugBreak();
+#else
+      *static_cast<int*>(NULL) = 1;
+#endif  // GTEST_OS_WINDOWS
+    } else if (GTEST_FLAG(throw_on_failure)) {
+#if GTEST_HAS_EXCEPTIONS
+      throw GoogleTestFailureException(result);
+#else
+      // We cannot call abort() as it generates a pop-up in debug mode
+      // that cannot be suppressed in VC 7.1 or below.
+      exit(1);
+#endif
+    }
+  }
+}
+
+// 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 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() {
+#if GTEST_HAS_SEH
+  // Catch SEH-style exceptions.
+
+  const bool in_death_test_child_process =
+      internal::GTEST_FLAG(internal_run_death_test).length() > 0;
+
+  // Either the user wants Google Test to catch exceptions thrown by the
+  // tests or this is executing in the context of death test child
+  // process. In either case the user does not want to see pop-up dialogs
+  // about crashes - they are expected..
+  if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) {
+#if !GTEST_OS_WINDOWS_MOBILE
+    // SetErrorMode doesn't exist on CE.
+    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
+                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
+#endif  // !GTEST_OS_WINDOWS_MOBILE
+
+#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE
+    // Death test children can be terminated with _abort().  On Windows,
+    // _abort() can show a dialog with a warning message.  This forces the
+    // abort message to go to stderr instead.
+    _set_error_mode(_OUT_TO_STDERR);
+#endif
+
+#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
+    // In the debug version, Visual Studio pops up a separate dialog
+    // offering a choice to debug the aborted program. We need to suppress
+    // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
+    // executed. Google Test will notify the user of any unexpected
+    // failure via stderr.
+    //
+    // VC++ doesn't define _set_abort_behavior() prior to the version 8.0.
+    // Users of prior VC versions shall suffer the agony and pain of
+    // clicking through the countless debug dialogs.
+    // TODO(vladl@google.com): find a way to suppress the abort dialog() in the
+    // debug mode when compiled with VC 7.1 or lower.
+    if (!GTEST_FLAG(break_on_failure))
+      _set_abort_behavior(
+          0x0,                                    // Clear the following flags:
+          _WRITE_ABORT_MSG | _CALL_REPORTFAULT);  // pop-up window, core dump.
+#endif
+  }
+
+  __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 a compiler or platform that doesn't support SEH.
+
+  return impl_->RunAllTests();
+#endif  // GTEST_HAS_SEH
+}
+
+// Returns the working directory when the first TEST() or TEST_F() was
+// executed.
+const char* UnitTest::original_working_dir() const {
+  return impl_->original_working_dir_.c_str();
+}
+
+// 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();
+}
+
+// Returns the random seed used at the start of the current test run.
+int UnitTest::random_seed() const { return impl_->random_seed(); }
+
+#if GTEST_HAS_PARAM_TEST
+// Returns ParameterizedTestCaseRegistry object used to keep track of
+// value-parameterized tests and instantiate and register them.
+// L < mutex_
+internal::ParameterizedTestCaseRegistry&
+    UnitTest::parameterized_test_registry() {
+  return impl_->parameterized_test_registry();
+}
+#endif  // GTEST_HAS_PARAM_TEST
+
+// 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().push_back(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().pop_back();
+}
+
+namespace internal {
+
+UnitTestImpl::UnitTestImpl(UnitTest* parent)
+    : parent_(parent),
+#ifdef _MSC_VER
+#pragma warning(push)                    // Saves the current warning state.
+#pragma warning(disable:4355)            // Temporarily disables warning 4355
+                                         // (using this in initializer).
+      default_global_test_part_result_reporter_(this),
+      default_per_thread_test_part_result_reporter_(this),
+#pragma warning(pop)                     // Restores the warning state again.
+#else
+      default_global_test_part_result_reporter_(this),
+      default_per_thread_test_part_result_reporter_(this),
+#endif  // _MSC_VER
+      global_test_part_result_repoter_(
+          &default_global_test_part_result_reporter_),
+      per_thread_test_part_result_reporter_(
+          &default_per_thread_test_part_result_reporter_),
+#if GTEST_HAS_PARAM_TEST
+      parameterized_test_registry_(),
+      parameterized_tests_registered_(false),
+#endif  // GTEST_HAS_PARAM_TEST
+      last_death_test_case_(-1),
+      current_test_case_(NULL),
+      current_test_info_(NULL),
+      ad_hoc_test_result_(),
+      os_stack_trace_getter_(NULL),
+      post_flag_parse_init_performed_(false),
+      random_seed_(0),  // Will be overridden by the flag before first use.
+      random_(0),  // Will be reseeded before first use.
+#if 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
+  listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
+}
+
+UnitTestImpl::~UnitTestImpl() {
+  // Deletes every TestCase.
+  ForEach(test_cases_, internal::Delete<TestCase>);
+
+  // Deletes every Environment.
+  ForEach(environments_, internal::Delete<Environment>);
+
+  delete os_stack_trace_getter_;
+}
+
+#if GTEST_HAS_DEATH_TEST
+// Disables event forwarding if the control is currently in a death test
+// subprocess. Must not be called before InitGoogleTest.
+void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
+  if (internal_run_death_test_flag_.get() != NULL)
+    listeners()->SuppressEventForwarding();
+}
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Initializes event listeners performing XML output as specified by
+// UnitTestOptions. Must not be called before InitGoogleTest.
+void UnitTestImpl::ConfigureXmlOutput() {
+  const String& output_format = UnitTestOptions::GetOutputFormat();
+  if (output_format == "xml") {
+    listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
+        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
+  } else if (output_format != "") {
+    printf("WARNING: unrecognized output format \"%s\" ignored.\n",
+           output_format.c_str());
+    fflush(stdout);
+  }
+}
+
+// Performs initialization dependent upon flag values obtained in
+// ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to
+// ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest
+// this function is also called from RunAllTests.  Since this function can be
+// called more than once, it has to be idempotent.
+void UnitTestImpl::PostFlagParsingInit() {
+  // Ensures that this function does not execute more than once.
+  if (!post_flag_parse_init_performed_) {
+    post_flag_parse_init_performed_ = true;
+
+#if GTEST_HAS_DEATH_TEST
+    InitDeathTestSubprocessControlInfo();
+    SuppressTestEventsIfInSubprocess();
+#endif  // GTEST_HAS_DEATH_TEST
+
+    // Registers parameterized tests. This makes parameterized tests
+    // available to the UnitTest reflection API without running
+    // RUN_ALL_TESTS.
+    RegisterParameterizedTests();
+
+    // Configures listeners for XML output. This makes it possible for users
+    // to shut down the default XML output before invoking RUN_ALL_TESTS.
+    ConfigureXmlOutput();
+  }
+}
+
+// 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.  It's the CALLER'S
+// RESPONSIBILITY to ensure that this function is only called WHEN THE
+// TESTS ARE NOT SHUFFLED.
+//
+// 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,
+                                    const char* comment,
+                                    Test::SetUpTestCaseFunc set_up_tc,
+                                    Test::TearDownTestCaseFunc tear_down_tc) {
+  // Can we find a TestCase with the given name?
+  const std::vector<TestCase*>::const_iterator test_case =
+      std::find_if(test_cases_.begin(), test_cases_.end(),
+                   TestCaseNameIs(test_case_name));
+
+  if (test_case != test_cases_.end())
+    return *test_case;
+
+  // No.  Let's create one.
+  TestCase* const new_test_case =
+      new TestCase(test_case_name, comment, set_up_tc, tear_down_tc);
+
+  // Is this a death test case?
+  if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),
+                                               kDeathTestCaseFilter)) {
+    // Yes.  Inserts the test case after the last death test case
+    // defined so far.  This only works when the test cases haven't
+    // been shuffled.  Otherwise we may end up running a death test
+    // after a non-death test.
+    ++last_death_test_case_;
+    test_cases_.insert(test_cases_.begin() + last_death_test_case_,
+                       new_test_case);
+  } else {
+    // No.  Appends to the end of the list.
+    test_cases_.push_back(new_test_case);
+  }
+
+  test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));
+  return new_test_case;
+}
+
+// Helpers for setting up / tearing down the given environment.  They
+// are for use in the ForEach() function.
+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.)
+// When parameterized tests are enabled, it expands and registers
+// parameterized tests first in RegisterParameterizedTests().
+// All other functions called from RunAllTests() may safely assume that
+// parameterized tests are ready to be counted and run.
+int UnitTestImpl::RunAllTests() {
+  // Makes sure InitGoogleTest() was called.
+  if (!GTestIsInitialized()) {
+    printf("%s",
+           "\nThis test program did NOT call ::testing::InitGoogleTest "
+           "before calling RUN_ALL_TESTS().  Please fix it.\n");
+    return 1;
+  }
+
+  // Do not run any test if the --help flag was specified.
+  if (g_help_flag)
+    return 0;
+
+  // Repeats the call to the post-flag parsing initialization in case the
+  // user didn't call InitGoogleTest.
+  PostFlagParsingInit();
+
+  // Even if sharding is not on, test runners may want to use the
+  // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
+  // protocol.
+  internal::WriteToShardStatusFileIfNeeded();
+
+  // True iff we are in a subprocess for running a thread-safe-style
+  // death test.
+  bool in_subprocess_for_death_test = false;
+
+#if GTEST_HAS_DEATH_TEST
+  in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
+#endif  // GTEST_HAS_DEATH_TEST
+
+  const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
+                                        in_subprocess_for_death_test);
+
+  // Compares the full test names with the filter to decide which
+  // tests to run.
+  const bool has_tests_to_run = FilterTests(should_shard
+                                              ? HONOR_SHARDING_PROTOCOL
+                                              : IGNORE_SHARDING_PROTOCOL) > 0;
+
+  // Lists the tests and exits if the --gtest_list_tests flag was specified.
+  if (GTEST_FLAG(list_tests)) {
+    // This must be called *after* FilterTests() has been called.
+    ListTestsMatchingFilter();
+    return 0;
+  }
+
+  random_seed_ = GTEST_FLAG(shuffle) ?
+      GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;
+
+  // True iff at least one test has failed.
+  bool failed = false;
+
+  TestEventListener* repeater = listeners()->repeater();
+
+  repeater->OnTestProgramStart(*parent_);
+
+  // 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++) {
+    ClearResult();
+
+    const TimeInMillis start = GetTimeInMillis();
+
+    // Shuffles test cases and tests if requested.
+    if (has_tests_to_run && GTEST_FLAG(shuffle)) {
+      random()->Reseed(random_seed_);
+      // This should be done before calling OnTestIterationStart(),
+      // such that a test event listener can see the actual test order
+      // in the event.
+      ShuffleTests();
+    }
+
+    // Tells the unit test event listeners that the tests are about to start.
+    repeater->OnTestIterationStart(*parent_, i);
+
+    // Runs each test case if there is at least one test to run.
+    if (has_tests_to_run) {
+      // Sets up all environments beforehand.
+      repeater->OnEnvironmentsSetUpStart(*parent_);
+      ForEach(environments_, SetUpEnvironment);
+      repeater->OnEnvironmentsSetUpEnd(*parent_);
+
+      // Runs the tests only if there was no fatal failure during global
+      // set-up.
+      if (!Test::HasFatalFailure()) {
+        for (int test_index = 0; test_index < total_test_case_count();
+             test_index++) {
+          GetMutableTestCase(test_index)->Run();
+        }
+      }
+
+      // Tears down all environments in reverse order afterwards.
+      repeater->OnEnvironmentsTearDownStart(*parent_);
+      std::for_each(environments_.rbegin(), environments_.rend(),
+                    TearDownEnvironment);
+      repeater->OnEnvironmentsTearDownEnd(*parent_);
+    }
+
+    elapsed_time_ = GetTimeInMillis() - start;
+
+    // Tells the unit test event listener that the tests have just finished.
+    repeater->OnTestIterationEnd(*parent_, i);
+
+    // Gets the result and clears it.
+    if (!Passed()) {
+      failed = true;
+    }
+
+    // Restores the original test order after the iteration.  This
+    // allows the user to quickly repro a failure that happens in the
+    // N-th iteration without repeating the first (N - 1) iterations.
+    // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in
+    // case the user somehow changes the value of the flag somewhere
+    // (it's always safe to unshuffle the tests).
+    UnshuffleTests();
+
+    if (GTEST_FLAG(shuffle)) {
+      // Picks a new random seed for each iteration.
+      random_seed_ = GetNextRandomSeed(random_seed_);
+    }
+  }
+
+  repeater->OnTestProgramEnd(*parent_);
+
+  // Returns 0 if all tests passed, or 1 other wise.
+  return failed ? 1 : 0;
+}
+
+// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
+// if the variable is present. If a file already exists at this location, this
+// function will write over it. If the variable is present, but the file cannot
+// be created, prints an error and exits.
+void WriteToShardStatusFileIfNeeded() {
+  const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);
+  if (test_shard_file != NULL) {
+    FILE* const file = posix::FOpen(test_shard_file, "w");
+    if (file == NULL) {
+      ColoredPrintf(COLOR_RED,
+                    "Could not write to the test shard status file \"%s\" "
+                    "specified by the %s environment variable.\n",
+                    test_shard_file, kTestShardStatusFile);
+      fflush(stdout);
+      exit(EXIT_FAILURE);
+    }
+    fclose(file);
+  }
+}
+
+// Checks whether sharding is enabled by examining the relevant
+// environment variable values. If the variables are present,
+// but inconsistent (i.e., shard_index >= total_shards), prints
+// an error and exits. If in_subprocess_for_death_test, sharding is
+// disabled because it must only be applied to the original test
+// process. Otherwise, we could filter out death tests we intended to execute.
+bool ShouldShard(const char* total_shards_env,
+                 const char* shard_index_env,
+                 bool in_subprocess_for_death_test) {
+  if (in_subprocess_for_death_test) {
+    return false;
+  }
+
+  const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1);
+  const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1);
+
+  if (total_shards == -1 && shard_index == -1) {
+    return false;
+  } else if (total_shards == -1 && shard_index != -1) {
+    const Message msg = Message()
+      << "Invalid environment variables: you have "
+      << kTestShardIndex << " = " << shard_index
+      << ", but have left " << kTestTotalShards << " unset.\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  } else if (total_shards != -1 && shard_index == -1) {
+    const Message msg = Message()
+      << "Invalid environment variables: you have "
+      << kTestTotalShards << " = " << total_shards
+      << ", but have left " << kTestShardIndex << " unset.\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  } else if (shard_index < 0 || shard_index >= total_shards) {
+    const Message msg = Message()
+      << "Invalid environment variables: we require 0 <= "
+      << kTestShardIndex << " < " << kTestTotalShards
+      << ", but you have " << kTestShardIndex << "=" << shard_index
+      << ", " << kTestTotalShards << "=" << total_shards << ".\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  }
+
+  return total_shards > 1;
+}
+
+// Parses the environment variable var as an Int32. If it is unset,
+// returns default_val. If it is not an Int32, prints an error
+// and aborts.
+Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) {
+  const char* str_val = posix::GetEnv(var);
+  if (str_val == NULL) {
+    return default_val;
+  }
+
+  Int32 result;
+  if (!ParseInt32(Message() << "The value of environment variable " << var,
+                  str_val, &result)) {
+    exit(EXIT_FAILURE);
+  }
+  return result;
+}
+
+// Given the total number of shards, the shard index, and the test id,
+// returns true iff the test should be run on this shard. The test id is
+// some arbitrary but unique non-negative integer assigned to each test
+// method. Assumes that 0 <= shard_index < total_shards.
+bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
+  return (test_id % total_shards) == shard_index;
+}
+
+// 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.
+// If shard_tests == true, further filters tests based on sharding
+// variables in the environment - see
+// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide.
+// Returns the number of tests that should run.
+int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
+  const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
+      Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
+  const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ?
+      Int32FromEnvOrDie(kTestShardIndex, -1) : -1;
+
+  // num_runnable_tests are the number of tests that will
+  // run across all shards (i.e., match filter and are not disabled).
+  // num_selected_tests are the number of tests to be run on
+  // this shard.
+  int num_runnable_tests = 0;
+  int num_selected_tests = 0;
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    TestCase* const test_case = test_cases_[i];
+    const String &test_case_name = test_case->name();
+    test_case->set_should_run(false);
+
+    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+      TestInfo* const test_info = test_case->test_info_list()[j];
+      const String test_name(test_info->name());
+      // A test is disabled if test case name or test name matches
+      // kDisableTestFilter.
+      const bool is_disabled =
+          internal::UnitTestOptions::MatchesFilter(test_case_name,
+                                                   kDisableTestFilter) ||
+          internal::UnitTestOptions::MatchesFilter(test_name,
+                                                   kDisableTestFilter);
+      test_info->impl()->set_is_disabled(is_disabled);
+
+      const bool matches_filter =
+          internal::UnitTestOptions::FilterMatchesTest(test_case_name,
+                                                       test_name);
+      test_info->impl()->set_matches_filter(matches_filter);
+
+      const bool is_runnable =
+          (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
+          matches_filter;
+
+      const bool is_selected = is_runnable &&
+          (shard_tests == IGNORE_SHARDING_PROTOCOL ||
+           ShouldRunTestOnShard(total_shards, shard_index,
+                                num_runnable_tests));
+
+      num_runnable_tests += is_runnable;
+      num_selected_tests += is_selected;
+
+      test_info->impl()->set_should_run(is_selected);
+      test_case->set_should_run(test_case->should_run() || is_selected);
+    }
+  }
+  return num_selected_tests;
+}
+
+// Prints the names of the tests matching the user-specified filter flag.
+void UnitTestImpl::ListTestsMatchingFilter() {
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    const TestCase* const test_case = test_cases_[i];
+    bool printed_test_case_name = false;
+
+    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+      const TestInfo* const test_info =
+          test_case->test_info_list()[j];
+      if (test_info->matches_filter()) {
+        if (!printed_test_case_name) {
+          printed_test_case_name = true;
+          printf("%s.\n", test_case->name());
+        }
+        printf("  %s\n", test_info->name());
+      }
+    }
+  }
+  fflush(stdout);
+}
+
+// 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.
+TestResult* UnitTestImpl::current_test_result() {
+  return current_test_info_ ?
+    current_test_info_->impl()->result() : &ad_hoc_test_result_;
+}
+
+// Shuffles all test cases, and the tests within each test case,
+// making sure that death tests are still run first.
+void UnitTestImpl::ShuffleTests() {
+  // Shuffles the death test cases.
+  ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);
+
+  // Shuffles the non-death test cases.
+  ShuffleRange(random(), last_death_test_case_ + 1,
+               static_cast<int>(test_cases_.size()), &test_case_indices_);
+
+  // Shuffles the tests inside each test case.
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    test_cases_[i]->ShuffleTests(random());
+  }
+}
+
+// Restores the test cases and tests to their order before the first shuffle.
+void UnitTestImpl::UnshuffleTests() {
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    // Unshuffles the tests in each test case.
+    test_cases_[i]->UnshuffleTests();
+    // Resets the index of each test case.
+    test_case_indices_[i] = static_cast<int>(i);
+  }
+}
+
+// TestInfoImpl constructor. The new instance assumes ownership of the test
+// factory object.
+TestInfoImpl::TestInfoImpl(TestInfo* parent,
+                           const char* a_test_case_name,
+                           const char* a_name,
+                           const char* a_test_case_comment,
+                           const char* a_comment,
+                           TypeId a_fixture_class_id,
+                           internal::TestFactoryBase* factory) :
+    parent_(parent),
+    test_case_name_(String(a_test_case_name)),
+    name_(String(a_name)),
+    test_case_comment_(String(a_test_case_comment)),
+    comment_(String(a_comment)),
+    fixture_class_id_(a_fixture_class_id),
+    should_run_(false),
+    is_disabled_(false),
+    matches_filter_(false),
+    factory_(factory) {
+}
+
+// TestInfoImpl destructor.
+TestInfoImpl::~TestInfoImpl() {
+  delete factory_;
+}
+
+// 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
+// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
+// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
+String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/,
+                                       int skip_count) {
+  // We pass skip_count + 1 to skip this wrapper function in addition
+  // to what the user really wants to skip.
+  return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
+}
+
+// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable
+// code warnings.
+namespace {
+class ClassUniqueToAlwaysTrue {};
+}
+
+bool IsTrue(bool condition) { return condition; }
+
+bool AlwaysTrue() {
+#if GTEST_HAS_EXCEPTIONS
+  // This condition is always false so AlwaysTrue() never actually throws,
+  // but it makes the compiler think that it may throw.
+  if (IsTrue(false))
+    throw ClassUniqueToAlwaysTrue();
+#endif  // GTEST_HAS_EXCEPTIONS
+  return true;
+}
+
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false.  None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr) {
+  const size_t prefix_len = strlen(prefix);
+  if (strncmp(*pstr, prefix, prefix_len) == 0) {
+    *pstr += prefix_len;
+    return true;
+  }
+  return false;
+}
+
+// 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.length();
+  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;
+}
+
+// Determines whether a string has a prefix that Google Test uses for its
+// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.
+// If Google Test detects that a command line flag has its prefix but is not
+// recognized, it will print its help message. Flags starting with
+// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test
+// internal flags and do not trigger the help message.
+static bool HasGoogleTestFlagPrefix(const char* str) {
+  return (SkipPrefix("--", &str) ||
+          SkipPrefix("-", &str) ||
+          SkipPrefix("/", &str)) &&
+         !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) &&
+         (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||
+          SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));
+}
+
+// Prints a string containing code-encoded text.  The following escape
+// sequences can be used in the string to control the text color:
+//
+//   @@    prints a single '@' character.
+//   @R    changes the color to red.
+//   @G    changes the color to green.
+//   @Y    changes the color to yellow.
+//   @D    changes to the default terminal text color.
+//
+// TODO(wan@google.com): Write tests for this once we add stdout
+// capturing to Google Test.
+static void PrintColorEncoded(const char* str) {
+  GTestColor color = COLOR_DEFAULT;  // The current color.
+
+  // Conceptually, we split the string into segments divided by escape
+  // sequences.  Then we print one segment at a time.  At the end of
+  // each iteration, the str pointer advances to the beginning of the
+  // next segment.
+  for (;;) {
+    const char* p = strchr(str, '@');
+    if (p == NULL) {
+      ColoredPrintf(color, "%s", str);
+      return;
+    }
+
+    ColoredPrintf(color, "%s", String(str, p - str).c_str());
+
+    const char ch = p[1];
+    str = p + 2;
+    if (ch == '@') {
+      ColoredPrintf(color, "@");
+    } else if (ch == 'D') {
+      color = COLOR_DEFAULT;
+    } else if (ch == 'R') {
+      color = COLOR_RED;
+    } else if (ch == 'G') {
+      color = COLOR_GREEN;
+    } else if (ch == 'Y') {
+      color = COLOR_YELLOW;
+    } else {
+      --str;
+    }
+  }
+}
+
+static const char kColorEncodedHelpMessage[] =
+"This program contains tests written using " GTEST_NAME_ ". You can use the\n"
+"following command line flags to control its behavior:\n"
+"\n"
+"Test Selection:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n"
+"      List the names of all tests instead of running them. The name of\n"
+"      TEST(Foo, Bar) is \"Foo.Bar\".\n"
+"  @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS"
+    "[@G-@YNEGATIVE_PATTERNS]@D\n"
+"      Run only the tests whose name matches one of the positive patterns but\n"
+"      none of the negative patterns. '?' matches any single character; '*'\n"
+"      matches any substring; ':' separates two patterns.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n"
+"      Run all disabled tests too.\n"
+"\n"
+"Test Execution:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n"
+"      Run the tests repeatedly; use a negative count to repeat forever.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n"
+"      Randomize tests' orders on every iteration.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n"
+"      Random number seed to use for shuffling test orders (between 1 and\n"
+"      99999, or 0 to use a seed based on the current time).\n"
+"\n"
+"Test Output:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
+"      Enable/disable colored output. The default is @Gauto@D.\n"
+"  -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
+"      Don't print the elapsed time of each test.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G"
+    GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
+"      Generate an XML report in the given directory or with the given file\n"
+"      name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
+"\n"
+"Assertion Behavior:\n"
+#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
+"      Set the default death test style.\n"
+#endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
+"      Turn assertion failures into debugger break-points.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
+"      Turn assertion failures into C++ exceptions.\n"
+#if GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n"
+"      Suppress pop-ups caused by exceptions.\n"
+#endif  // GTEST_OS_WINDOWS
+"\n"
+"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set "
+    "the corresponding\n"
+"environment variable of a flag (all letters in upper-case). For example, to\n"
+"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_
+    "color=no@D or set\n"
+"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n"
+"\n"
+"For more information, please read the " GTEST_NAME_ " documentation at\n"
+"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n"
+"(not one in your own code or tests), please report it to\n"
+"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.  The type parameter CharType can be
+// instantiated to either char or wchar_t.
+template <typename CharType>
+void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
+  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, kAlsoRunDisabledTestsFlag,
+                      &GTEST_FLAG(also_run_disabled_tests)) ||
+        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)) ||
+        ParseBoolFlag(arg, kDeathTestUseFork,
+                      &GTEST_FLAG(death_test_use_fork)) ||
+        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)) ||
+        ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
+        ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
+        ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
+        ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
+        ParseInt32Flag(arg, kStackTraceDepthFlag,
+                       &GTEST_FLAG(stack_trace_depth)) ||
+        ParseBoolFlag(arg, kThrowOnFailureFlag, &GTEST_FLAG(throw_on_failure))
+        ) {
+      // 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--;
+    } else if (arg_string == "--help" || arg_string == "-h" ||
+               arg_string == "-?" || arg_string == "/?" ||
+               HasGoogleTestFlagPrefix(arg)) {
+      // Both help flag and unrecognized Google Test flags (excluding
+      // internal ones) trigger help display.
+      g_help_flag = true;
+    }
+  }
+
+  if (g_help_flag) {
+    // We print the help here instead of in RUN_ALL_TESTS(), as the
+    // latter may not be called at all if the user is using Google
+    // Test with another testing framework.
+    PrintColorEncoded(kColorEncodedHelpMessage);
+  }
+}
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.
+void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
+  ParseGoogleTestFlagsOnlyImpl(argc, argv);
+}
+void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
+  ParseGoogleTestFlagsOnlyImpl(argc, argv);
+}
+
+// The internal implementation of InitGoogleTest().
+//
+// The type parameter CharType can be instantiated to either char or
+// wchar_t.
+template <typename CharType>
+void InitGoogleTestImpl(int* argc, CharType** argv) {
+  g_init_gtest_count++;
+
+  // We don't want to run the initialization code twice.
+  if (g_init_gtest_count != 1) return;
+
+  if (*argc <= 0) return;
+
+  internal::g_executable_path = internal::StreamableToString(argv[0]);
+
+#if 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
+
+  ParseGoogleTestFlagsOnly(argc, argv);
+  GetUnitTestImpl()->PostFlagParsingInit();
+}
+
+}  // namespace internal
+
+// Initializes Google Test.  This must be called before calling
+// RUN_ALL_TESTS().  In particular, it 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.
+//
+// Calling the function for the second time has no user-visible effect.
+void InitGoogleTest(int* argc, char** argv) {
+  internal::InitGoogleTestImpl(argc, argv);
+}
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+void InitGoogleTest(int* argc, wchar_t** argv) {
+  internal::InitGoogleTestImpl(argc, argv);
+}
+
+}  // namespace testing
+// 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), vladl@google.com (Vlad Losev)
+//
+// This file implements death tests.
+
+
+#if GTEST_HAS_DEATH_TEST
+
+#if GTEST_OS_MAC
+#include <crt_externs.h>
+#endif  // GTEST_OS_MAC
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#if GTEST_OS_WINDOWS
+#include <windows.h>
+#else
+#include <sys/mman.h>
+#include <sys/wait.h>
+#endif  // GTEST_OS_WINDOWS
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+
+// 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_ 1
+#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).");
+
+GTEST_DEFINE_bool_(
+    death_test_use_fork,
+    internal::BoolFromGTestEnv("death_test_use_fork", false),
+    "Instructs to use fork()/_exit() instead of clone() in death tests. "
+    "Ignored and always uses fork() on POSIX systems where clone() is not "
+    "implemented. Useful when running under valgrind or similar tools if "
+    "those do not support clone(). Valgrind 3.3.1 will just fail if "
+    "it sees an unsupported combination of clone() flags. "
+    "It is not recommended to use this flag w/o valgrind though it will "
+    "work in 99% of the cases. Once valgrind is fixed, this flag will "
+    "most likely be removed.");
+
+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
+
+#if 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 {
+#if GTEST_OS_WINDOWS
+  return exit_status == exit_code_;
+#else
+  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
+#endif  // GTEST_OS_WINDOWS
+}
+
+#if !GTEST_OS_WINDOWS
+// 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_;
+}
+#endif  // !GTEST_OS_WINDOWS
+
+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 GTEST_OS_WINDOWS
+  m << "Exited with exit status " << exit_code;
+#else
+  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
+#endif  // GTEST_OS_WINDOWS
+  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);
+}
+
+#if !GTEST_OS_WINDOWS
+// 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();
+}
+#endif  // !GTEST_OS_WINDOWS
+
+// 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 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 String& message) {
+  // On a POSIX system, 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-minuscule memory requirements.
+  const InternalRunDeathTestFlag* const flag =
+      GetUnitTestImpl()->internal_run_death_test_flag();
+  if (flag != NULL) {
+    FILE* parent = posix::FDOpen(flag->write_fd(), "w");
+    fputc(kDeathTestInternalError, parent);
+    fprintf(parent, "%s", message.c_str());
+    fflush(parent);
+    _exit(1);
+  } else {
+    fprintf(stderr, "%s", message.c_str());
+    fflush(stderr);
+    abort();
+  }
+}
+
+// A replacement for CHECK that calls DeathTestAbort if the assertion
+// fails.
+#define GTEST_DEATH_TEST_CHECK_(expression) \
+  do { \
+    if (!::testing::internal::IsTrue(expression)) { \
+      DeathTestAbort(::testing::internal::String::Format( \
+          "CHECK failed: File %s, line %d: %s", \
+          __FILE__, __LINE__, #expression)); \
+    } \
+  } while (::testing::internal::AlwaysFalse())
+
+// 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 gtest_retval; \
+    do { \
+      gtest_retval = (expression); \
+    } while (gtest_retval == -1 && errno == EINTR); \
+    if (gtest_retval == -1) { \
+      DeathTestAbort(::testing::internal::String::Format( \
+          "CHECK failed: File %s, line %d: %s != -1", \
+          __FILE__, __LINE__, #expression)); \
+    } \
+  } while (::testing::internal::AlwaysFalse())
+
+// Returns the message describing the last system error in errno.
+String GetLastErrnoDescription() {
+    return String(errno == 0 ? "" : posix::StrError(errno));
+}
+
+// This is called from a death test parent process to read a failure
+// message from the death test child process and log it with the FATAL
+// severity. On Windows, the message is read from a pipe handle. On other
+// platforms, it is read from a file descriptor.
+static void FailFromInternalError(int fd) {
+  Message error;
+  char buffer[256];
+  int num_read;
+
+  do {
+    while ((num_read = posix::Read(fd, buffer, 255)) > 0) {
+      buffer[num_read] = '\0';
+      error << buffer;
+    }
+  } while (num_read == -1 && errno == EINTR);
+
+  if (num_read == 0) {
+    GTEST_LOG_(FATAL) << error.GetString();
+  } else {
+    const int last_error = errno;
+    GTEST_LOG_(FATAL) << "Error while reading death test internal: "
+                      << GetLastErrnoDescription() << " [" << last_error << "]";
+  }
+}
+
+// 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();
+}
+
+void DeathTest::set_last_death_test_message(const String& message) {
+  last_death_test_message_ = message;
+}
+
+String DeathTest::last_death_test_message_;
+
+// Provides cross platform implementation for some death functionality.
+class DeathTestImpl : public DeathTest {
+ protected:
+  DeathTestImpl(const char* a_statement, const RE* a_regex)
+      : statement_(a_statement),
+        regex_(a_regex),
+        spawned_(false),
+        status_(-1),
+        outcome_(IN_PROGRESS),
+        read_fd_(-1),
+        write_fd_(-1) {}
+
+  // read_fd_ is expected to be closed and cleared by a derived class.
+  ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
+
+  void Abort(AbortReason reason);
+  virtual bool Passed(bool status_ok);
+
+  const char* statement() const { return statement_; }
+  const RE* regex() const { return regex_; }
+  bool spawned() const { return spawned_; }
+  void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
+  int status() const { return status_; }
+  void set_status(int a_status) { status_ = a_status; }
+  DeathTestOutcome outcome() const { return outcome_; }
+  void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }
+  int read_fd() const { return read_fd_; }
+  void set_read_fd(int fd) { read_fd_ = fd; }
+  int write_fd() const { return write_fd_; }
+  void set_write_fd(int fd) { write_fd_ = fd; }
+
+  // Called in the parent process only. Reads the result code of the death
+  // test child process via a pipe, interprets it to set the outcome_
+  // member, and closes read_fd_.  Outputs diagnostics and terminates in
+  // case of unexpected codes.
+  void ReadAndInterpretStatusByte();
+
+ private:
+  // The textual content of the code this object is testing.  This class
+  // doesn't own this string and should not attempt to delete it.
+  const char* const statement_;
+  // The regular expression which test output must match.  DeathTestImpl
+  // doesn't own this object and should not attempt to delete it.
+  const RE* const regex_;
+  // True if the death test child process has been successfully spawned.
+  bool spawned_;
+  // The exit status of the child process.
+  int status_;
+  // How the death test concluded.
+  DeathTestOutcome outcome_;
+  // Descriptor to the read end of the pipe to the child process.  It is
+  // always -1 in the child process.  The child keeps its write end of the
+  // pipe in write_fd_.
+  int read_fd_;
+  // Descriptor to the child's write end of the pipe to the parent process.
+  // It is always -1 in the parent process.  The parent keeps its end of the
+  // pipe in read_fd_.
+  int write_fd_;
+};
+
+// Called in the parent process only. Reads the result code of the death
+// test child process via a pipe, interprets it to set the outcome_
+// member, and closes read_fd_.  Outputs diagnostics and terminates in
+// case of unexpected codes.
+void DeathTestImpl::ReadAndInterpretStatusByte() {
+  char flag;
+  int bytes_read;
+
+  // 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.
+  do {
+    bytes_read = posix::Read(read_fd(), &flag, 1);
+  } while (bytes_read == -1 && errno == EINTR);
+
+  if (bytes_read == 0) {
+    set_outcome(DIED);
+  } else if (bytes_read == 1) {
+    switch (flag) {
+      case kDeathTestReturned:
+        set_outcome(RETURNED);
+        break;
+      case kDeathTestLived:
+        set_outcome(LIVED);
+        break;
+      case kDeathTestInternalError:
+        FailFromInternalError(read_fd());  // Does not return.
+        break;
+      default:
+        GTEST_LOG_(FATAL) << "Death test child process reported "
+                          << "unexpected status byte ("
+                          << static_cast<unsigned int>(flag) << ")";
+    }
+  } else {
+    GTEST_LOG_(FATAL) << "Read from death test child process failed: "
+                      << GetLastErrnoDescription();
+  }
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));
+  set_read_fd(-1);
+}
+
+// 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 descriptor, then
+// calls _exit(1).
+void DeathTestImpl::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 status_ch =
+      reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned;
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(write_fd()));
+  _exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash)
+}
+
+// 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. On *nix, it is in the
+//             in the format specified by wait(2). On Windows, this is the
+//             value supplied to the ExitProcess() API or a numeric code
+//             of the exception that terminated the program.
+//   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 last death test message string.
+bool DeathTestImpl::Passed(bool status_ok) {
+  if (!spawned())
+    return false;
+
+  const String error_message = GetCapturedStderr();
+
+  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) {
+        const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
+        if (matched) {
+          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;
+    case IN_PROGRESS:
+    default:
+      GTEST_LOG_(FATAL)
+          << "DeathTest::Passed somehow called before conclusion of test";
+  }
+
+  DeathTest::set_last_death_test_message(buffer.GetString());
+  return success;
+}
+
+#if GTEST_OS_WINDOWS
+// WindowsDeathTest implements death tests on Windows. Due to the
+// specifics of starting new processes on Windows, death tests there are
+// always threadsafe, and Google Test considers the
+// --gtest_death_test_style=fast setting to be equivalent to
+// --gtest_death_test_style=threadsafe there.
+//
+// A few implementation notes:  Like the Linux version, the Windows
+// implementation uses pipes for child-to-parent communication. But due to
+// the specifics of pipes on Windows, some extra steps are required:
+//
+// 1. The parent creates a communication pipe and stores handles to both
+//    ends of it.
+// 2. The parent starts the child and provides it with the information
+//    necessary to acquire the handle to the write end of the pipe.
+// 3. The child acquires the write end of the pipe and signals the parent
+//    using a Windows event.
+// 4. Now the parent can release the write end of the pipe on its side. If
+//    this is done before step 3, the object's reference count goes down to
+//    0 and it is destroyed, preventing the child from acquiring it. The
+//    parent now has to release it, or read operations on the read end of
+//    the pipe will not return when the child terminates.
+// 5. The parent reads child's output through the pipe (outcome code and
+//    any possible error messages) from the pipe, and its stderr and then
+//    determines whether to fail the test.
+//
+// Note: to distinguish Win32 API calls from the local method and function
+// calls, the former are explicitly resolved in the global namespace.
+//
+class WindowsDeathTest : public DeathTestImpl {
+ public:
+  WindowsDeathTest(const char* statement,
+                   const RE* regex,
+                   const char* file,
+                   int line)
+      : DeathTestImpl(statement, regex), file_(file), line_(line) {}
+
+  // All of these virtual functions are inherited from DeathTest.
+  virtual int Wait();
+  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_;
+  // Handle to the write end of the pipe to the child process.
+  AutoHandle write_handle_;
+  // Child process handle.
+  AutoHandle child_handle_;
+  // Event the child process uses to signal the parent that it has
+  // acquired the handle to the write end of the pipe. After seeing this
+  // event the parent can release its own handles to make sure its
+  // ReadFile() calls return when the child terminates.
+  AutoHandle event_handle_;
+};
+
+// 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 WindowsDeathTest::Wait() {
+  if (!spawned())
+    return 0;
+
+  // Wait until the child either signals that it has acquired the write end
+  // of the pipe or it dies.
+  const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() };
+  switch (::WaitForMultipleObjects(2,
+                                   wait_handles,
+                                   FALSE,  // Waits for any of the handles.
+                                   INFINITE)) {
+    case WAIT_OBJECT_0:
+    case WAIT_OBJECT_0 + 1:
+      break;
+    default:
+      GTEST_DEATH_TEST_CHECK_(false);  // Should not get here.
+  }
+
+  // The child has acquired the write end of the pipe or exited.
+  // We release the handle on our side and continue.
+  write_handle_.Reset();
+  event_handle_.Reset();
+
+  ReadAndInterpretStatusByte();
+
+  // Waits for the child process to exit if it haven't already. This
+  // returns immediately if the child has already exited, regardless of
+  // whether previous calls to WaitForMultipleObjects synchronized on this
+  // handle or not.
+  GTEST_DEATH_TEST_CHECK_(
+      WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),
+                                             INFINITE));
+  DWORD status;
+  GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status)
+                          != FALSE);
+  child_handle_.Reset();
+  set_status(static_cast<int>(status));
+  return this->status();
+}
+
+// The AssumeRole process for a Windows death test.  It creates a child
+// process with the same executable as the current process to run the
+// death test.  The child process is given the --gtest_filter and
+// --gtest_internal_run_death_test flags such that it knows to run the
+// current death test only.
+DeathTest::TestRole WindowsDeathTest::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) {
+    // ParseInternalRunDeathTestFlag() has performed all the necessary
+    // processing.
+    set_write_fd(flag->write_fd());
+    return EXECUTE_TEST;
+  }
+
+  // WindowsDeathTest uses an anonymous pipe to communicate results of
+  // a death test.
+  SECURITY_ATTRIBUTES handles_are_inheritable = {
+    sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
+  HANDLE read_handle, write_handle;
+  GTEST_DEATH_TEST_CHECK_(
+      ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
+                   0)  // Default buffer size.
+      != FALSE);
+  set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle),
+                                O_RDONLY));
+  write_handle_.Reset(write_handle);
+  event_handle_.Reset(::CreateEvent(
+      &handles_are_inheritable,
+      TRUE,    // The event will automatically reset to non-signaled state.
+      FALSE,   // The initial state is non-signalled.
+      NULL));  // The even is unnamed.
+  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);
+  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|%u|%Iu|%Iu",
+      GTEST_FLAG_PREFIX_,
+      kInternalRunDeathTestFlag,
+      file_, line_,
+      death_test_index,
+      static_cast<unsigned int>(::GetCurrentProcessId()),
+      // size_t has the same with as pointers on both 32-bit and 64-bit
+      // Windows platforms.
+      // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
+      reinterpret_cast<size_t>(write_handle),
+      reinterpret_cast<size_t>(event_handle_.Get()));
+
+  char executable_path[_MAX_PATH + 1];  // NOLINT
+  GTEST_DEATH_TEST_CHECK_(
+      _MAX_PATH + 1 != ::GetModuleFileNameA(NULL,
+                                            executable_path,
+                                            _MAX_PATH));
+
+  String command_line = String::Format("%s %s \"%s\"",
+                                       ::GetCommandLineA(),
+                                       filter_flag.c_str(),
+                                       internal_flag.c_str());
+
+  DeathTest::set_last_death_test_message("");
+
+  CaptureStderr();
+  // Flush the log buffers since the log streams are shared with the child.
+  FlushInfoLog();
+
+  // The child process will share the standard handles with the parent.
+  STARTUPINFOA startup_info;
+  memset(&startup_info, 0, sizeof(STARTUPINFO));
+  startup_info.dwFlags = STARTF_USESTDHANDLES;
+  startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
+  startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
+  startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
+
+  PROCESS_INFORMATION process_info;
+  GTEST_DEATH_TEST_CHECK_(::CreateProcessA(
+      executable_path,
+      const_cast<char*>(command_line.c_str()),
+      NULL,   // Retuned process handle is not inheritable.
+      NULL,   // Retuned thread handle is not inheritable.
+      TRUE,   // Child inherits all inheritable handles (for write_handle_).
+      0x0,    // Default creation flags.
+      NULL,   // Inherit the parent's environment.
+      UnitTest::GetInstance()->original_working_dir(),
+      &startup_info,
+      &process_info) != FALSE);
+  child_handle_.Reset(process_info.hProcess);
+  ::CloseHandle(process_info.hThread);
+  set_spawned(true);
+  return OVERSEE_TEST;
+}
+#else  // We are not on Windows.
+
+// ForkingDeathTest provides implementations for most of the abstract
+// methods of the DeathTest interface.  Only the AssumeRole method is
+// left undefined.
+class ForkingDeathTest : public DeathTestImpl {
+ public:
+  ForkingDeathTest(const char* statement, const RE* regex);
+
+  // All of these virtual functions are inherited from DeathTest.
+  virtual int Wait();
+
+ protected:
+  void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
+
+ private:
+  // PID of child process during death test; 0 in the child process itself.
+  pid_t child_pid_;
+};
+
+// Constructs a ForkingDeathTest.
+ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)
+    : DeathTestImpl(a_statement, a_regex),
+      child_pid_(-1) {}
+
+// 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 (!spawned())
+    return 0;
+
+  ReadAndInterpretStatusByte();
+
+  int status_value;
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));
+  set_status(status_value);
+  return status_value;
+}
+
+// A concrete death test class that forks, then immediately runs the test
+// in the child process.
+class NoExecDeathTest : public ForkingDeathTest {
+ public:
+  NoExecDeathTest(const char* a_statement, const RE* a_regex) :
+      ForkingDeathTest(a_statement, a_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);
+
+  DeathTest::set_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();
+    // Event forwarding to the listeners of event listener API mush be shut
+    // down in death test subprocesses.
+    GetUnitTestImpl()->listeners()->SuppressEventForwarding();
+    return EXECUTE_TEST;
+  } else {
+    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
+    set_read_fd(pipe_fd[0]);
+    set_spawned(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* a_statement, const RE* a_regex,
+                const char* file, int line) :
+      ForkingDeathTest(a_statement, a_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 != args_.end();
+         ++i) {
+      free(*i);
+    }
+  }
+  void AddArgument(const char* argument) {
+    args_.insert(args_.end() - 1, posix::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, posix::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
+};
+
+#if GTEST_OS_MAC
+inline char** GetEnviron() {
+  // When Google Test is built as a framework on MacOS X, the environ variable
+  // is unavailable. Apple's documentation (man environ) recommends using
+  // _NSGetEnviron() instead.
+  return *_NSGetEnviron();
+}
+#else
+// Some POSIX platforms expect you to declare environ. extern "C" makes
+// it reside in the global namespace.
+extern "C" char** environ;
+inline char** GetEnviron() { return environ; }
+#endif  // GTEST_OS_MAC
+
+// The main function for a threadsafe-style death test child process.
+// This function is called in a clone()-ed process and thus must avoid
+// any potentially unsafe operations like malloc or libc functions.
+static int ExecDeathTestChildMain(void* child_arg) {
+  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));
+
+  // We need to execute the test program in the same environment where
+  // it was originally invoked.  Therefore we change to the original
+  // working directory first.
+  const char* const original_dir =
+      UnitTest::GetInstance()->original_working_dir();
+  // We can safely call chdir() as it's a direct system call.
+  if (chdir(original_dir) != 0) {
+    DeathTestAbort(String::Format("chdir(\"%s\") failed: %s",
+                                  original_dir,
+                                  GetLastErrnoDescription().c_str()));
+    return EXIT_FAILURE;
+  }
+
+  // We can safely call execve() as it's a direct system call.  We
+  // cannot use execvp() as it's a libc function and thus potentially
+  // unsafe.  Since execve() doesn't search the PATH, the user must
+  // invoke the test program via a valid path that contains at least
+  // one path separator.
+  execve(args->argv[0], args->argv, GetEnviron());
+  DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s",
+                                args->argv[0],
+                                original_dir,
+                                GetLastErrnoDescription().c_str()));
+  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.
+bool StackLowerThanAddress(const void* ptr) {
+  int dummy;
+  return &dummy < ptr;
+}
+
+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) {
+  ExecDeathTestArgs args = { argv, close_fd };
+  pid_t child_pid = -1;
+
+#if GTEST_HAS_CLONE
+  const bool use_fork = GTEST_FLAG(death_test_use_fork);
+
+  if (!use_fork) {
+    static const bool stack_grows_down = StackGrowsDown();
+    const size_t stack_size = getpagesize();
+    // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
+    void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
+                             MAP_ANON | 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);
+
+    child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
+
+    GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
+  }
+#else
+  const bool use_fork = true;
+#endif  // GTEST_HAS_CLONE
+
+  if (use_fork && (child_pid = fork()) == 0) {
+      ExecDeathTestChildMain(&args);
+      _exit(0);
+  }
+
+  GTEST_DEATH_TEST_CHECK_(child_pid != -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->write_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(filter_flag.c_str());
+  args.AddArgument(internal_flag.c_str());
+
+  DeathTest::set_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_spawned(true);
+  return OVERSEE_TEST;
+}
+
+#endif  // !GTEST_OS_WINDOWS
+
+// 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()) {
+      DeathTest::set_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_OS_WINDOWS
+  if (GTEST_FLAG(death_test_style) == "threadsafe" ||
+      GTEST_FLAG(death_test_style) == "fast") {
+    *test = new WindowsDeathTest(statement, regex, file, line);
+  }
+#else
+  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);
+  }
+#endif  // GTEST_OS_WINDOWS
+  else {  // NOLINT - this is more readable than unbalanced brackets inside #if.
+    DeathTest::set_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 (::testing::internal::AlwaysTrue()) {
+    const ::std::string::size_type colon = str.find(delimiter, 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);
+}
+
+#if GTEST_OS_WINDOWS
+// Recreates the pipe and event handles from the provided parameters,
+// signals the event, and returns a file descriptor wrapped around the pipe
+// handle. This function is called in the child process only.
+int GetStatusFileDescriptor(unsigned int parent_process_id,
+                            size_t write_handle_as_size_t,
+                            size_t event_handle_as_size_t) {
+  AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
+                                                   FALSE,  // Non-inheritable.
+                                                   parent_process_id));
+  if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {
+    DeathTestAbort(String::Format("Unable to open parent process %u",
+                                  parent_process_id));
+  }
+
+  // TODO(vladl@google.com): Replace the following check with a
+  // compile-time assertion when available.
+  GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
+
+  const HANDLE write_handle =
+      reinterpret_cast<HANDLE>(write_handle_as_size_t);
+  HANDLE dup_write_handle;
+
+  // The newly initialized handle is accessible only in in the parent
+  // process. To obtain one accessible within the child, we need to use
+  // DuplicateHandle.
+  if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
+                         ::GetCurrentProcess(), &dup_write_handle,
+                         0x0,    // Requested privileges ignored since
+                                 // DUPLICATE_SAME_ACCESS is used.
+                         FALSE,  // Request non-inheritable handler.
+                         DUPLICATE_SAME_ACCESS)) {
+    DeathTestAbort(String::Format(
+        "Unable to duplicate the pipe handle %Iu from the parent process %u",
+        write_handle_as_size_t, parent_process_id));
+  }
+
+  const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);
+  HANDLE dup_event_handle;
+
+  if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,
+                         ::GetCurrentProcess(), &dup_event_handle,
+                         0x0,
+                         FALSE,
+                         DUPLICATE_SAME_ACCESS)) {
+    DeathTestAbort(String::Format(
+        "Unable to duplicate the event handle %Iu from the parent process %u",
+        event_handle_as_size_t, parent_process_id));
+  }
+
+  const int write_fd =
+      ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);
+  if (write_fd == -1) {
+    DeathTestAbort(String::Format(
+        "Unable to convert pipe handle %Iu to a file descriptor",
+        write_handle_as_size_t));
+  }
+
+  // Signals the parent that the write end of the pipe has been acquired
+  // so the parent can release its own write end.
+  ::SetEvent(dup_event_handle);
+
+  return write_fd;
+}
+#endif  // GTEST_OS_WINDOWS
+
+// 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;
+
+  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
+  // can use it here.
+  int line = -1;
+  int index = -1;
+  ::std::vector< ::std::string> fields;
+  SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);
+  int write_fd = -1;
+
+#if GTEST_OS_WINDOWS
+  unsigned int parent_process_id = 0;
+  size_t write_handle_as_size_t = 0;
+  size_t event_handle_as_size_t = 0;
+
+  if (fields.size() != 6
+      || !ParseNaturalNumber(fields[1], &line)
+      || !ParseNaturalNumber(fields[2], &index)
+      || !ParseNaturalNumber(fields[3], &parent_process_id)
+      || !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
+      || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
+    DeathTestAbort(String::Format(
+        "Bad --gtest_internal_run_death_test flag: %s",
+        GTEST_FLAG(internal_run_death_test).c_str()));
+  }
+  write_fd = GetStatusFileDescriptor(parent_process_id,
+                                     write_handle_as_size_t,
+                                     event_handle_as_size_t);
+#else
+  if (fields.size() != 4
+      || !ParseNaturalNumber(fields[1], &line)
+      || !ParseNaturalNumber(fields[2], &index)
+      || !ParseNaturalNumber(fields[3], &write_fd)) {
+    DeathTestAbort(String::Format(
+        "Bad --gtest_internal_run_death_test flag: %s",
+        GTEST_FLAG(internal_run_death_test).c_str()));
+  }
+#endif  // GTEST_OS_WINDOWS
+  return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);
+}
+
+}  // namespace internal
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace testing
+// 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 <stdlib.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h>
+#elif GTEST_OS_WINDOWS
+#include <direct.h>
+#include <io.h>
+#elif GTEST_OS_SYMBIAN
+// Symbian OpenC has PATH_MAX in sys/syslimits.h
+#include <sys/syslimits.h>
+#else
+#include <limits.h>
+#include <climits>  // Some Linux distributions define PATH_MAX here.
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#if GTEST_OS_WINDOWS
+#define GTEST_PATH_MAX_ _MAX_PATH
+#elif defined(PATH_MAX)
+#define GTEST_PATH_MAX_ PATH_MAX
+#elif defined(_XOPEN_PATH_MAX)
+#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
+#else
+#define GTEST_PATH_MAX_ _POSIX_PATH_MAX
+#endif  // GTEST_OS_WINDOWS
+
+
+namespace testing {
+namespace internal {
+
+#if GTEST_OS_WINDOWS
+// On Windows, '\\' is the standard path separator, but many tools and the
+// Windows API also accept '/' as an alternate path separator. Unless otherwise
+// noted, a file path can contain either kind of path separators, or a mixture
+// of them.
+const char kPathSeparator = '\\';
+const char kAlternatePathSeparator = '/';
+const char kPathSeparatorString[] = "\\";
+const char kAlternatePathSeparatorString[] = "/";
+#if GTEST_OS_WINDOWS_MOBILE
+// Windows CE doesn't have a current directory. You should not use
+// the current directory in tests on Windows CE, but this at least
+// provides a reasonable fallback.
+const char kCurrentDirectoryString[] = "\\";
+// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
+const DWORD kInvalidFileAttributes = 0xffffffff;
+#else
+const char kCurrentDirectoryString[] = ".\\";
+#endif  // GTEST_OS_WINDOWS_MOBILE
+#else
+const char kPathSeparator = '/';
+const char kPathSeparatorString[] = "/";
+const char kCurrentDirectoryString[] = "./";
+#endif  // GTEST_OS_WINDOWS
+
+// Returns whether the given character is a valid path separator.
+static bool IsPathSeparator(char c) {
+#if GTEST_HAS_ALT_PATH_SEP_
+  return (c == kPathSeparator) || (c == kAlternatePathSeparator);
+#else
+  return c == kPathSeparator;
+#endif
+}
+
+// Returns the current working directory, or "" if unsuccessful.
+FilePath FilePath::GetCurrentDir() {
+#if GTEST_OS_WINDOWS_MOBILE
+  // Windows CE doesn't have a current directory, so we just return
+  // something reasonable.
+  return FilePath(kCurrentDirectoryString);
+#elif GTEST_OS_WINDOWS
+  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
+  return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+#else
+  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
+  return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+}
+
+// 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_.length() - 4));
+  }
+  return *this;
+}
+
+// Returns a pointer to the last occurence of a valid path separator in
+// the FilePath. On Windows, for example, both '/' and '\' are valid path
+// separators. Returns NULL if no path separator was found.
+const char* FilePath::FindLastPathSeparator() const {
+  const char* const last_sep = strrchr(c_str(), kPathSeparator);
+#if GTEST_HAS_ALT_PATH_SEP_
+  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
+  // Comparing two pointers of which only one is NULL is undefined.
+  if (last_alt_sep != NULL &&
+      (last_sep == NULL || last_alt_sep > last_sep)) {
+    return last_alt_sep;
+  }
+#endif
+  return last_sep;
+}
+
+// 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 = FindLastPathSeparator();
+  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 = FindLastPathSeparator();
+  String dir;
+  if (last_sep) {
+    dir = String(c_str(), last_sep + 1 - c_str());
+  } else {
+    dir = kCurrentDirectoryString;
+  }
+  return FilePath(dir);
+}
+
+// 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) {
+  String file;
+  if (number == 0) {
+    file = String::Format("%s.%s", base_name.c_str(), extension);
+  } else {
+    file = String::Format("%s_%d.%s", base_name.c_str(), number, extension);
+  }
+  return ConcatPaths(directory, FilePath(file));
+}
+
+// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
+// On Windows, uses \ as the separator rather than /.
+FilePath FilePath::ConcatPaths(const FilePath& directory,
+                               const FilePath& relative_path) {
+  if (directory.IsEmpty())
+    return relative_path;
+  const FilePath dir(directory.RemoveTrailingPathSeparator());
+  return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator,
+                                 relative_path.c_str()));
+}
+
+// Returns true if pathname describes something findable in the file-system,
+// either a file, directory, or whatever.
+bool FilePath::FileOrDirectoryExists() const {
+#if GTEST_OS_WINDOWS_MOBILE
+  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
+  const DWORD attributes = GetFileAttributes(unicode);
+  delete [] unicode;
+  return attributes != kInvalidFileAttributes;
+#else
+  posix::StatStruct file_stat;
+  return posix::Stat(pathname_.c_str(), &file_stat) == 0;
+#endif  // GTEST_OS_WINDOWS_MOBILE
+}
+
+// Returns true if pathname describes a directory in the file-system
+// that exists.
+bool FilePath::DirectoryExists() const {
+  bool result = false;
+#if GTEST_OS_WINDOWS
+  // Don't strip off trailing separator if path is a root directory on
+  // Windows (like "C:\\").
+  const FilePath& path(IsRootDirectory() ? *this :
+                                           RemoveTrailingPathSeparator());
+#else
+  const FilePath& path(*this);
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
+  const DWORD attributes = GetFileAttributes(unicode);
+  delete [] unicode;
+  if ((attributes != kInvalidFileAttributes) &&
+      (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
+    result = true;
+  }
+#else
+  posix::StatStruct file_stat;
+  result = posix::Stat(path.c_str(), &file_stat) == 0 &&
+      posix::IsDir(file_stat);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+  return result;
+}
+
+// Returns true if pathname describes a root directory. (Windows has one
+// root directory per disk drive.)
+bool FilePath::IsRootDirectory() const {
+#if GTEST_OS_WINDOWS
+  // TODO(wan@google.com): on Windows a network share like
+  // \\server\share can be a root directory, although it cannot be the
+  // current directory.  Handle this properly.
+  return pathname_.length() == 3 && IsAbsolutePath();
+#else
+  return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
+#endif
+}
+
+// Returns true if pathname describes an absolute path.
+bool FilePath::IsAbsolutePath() const {
+  const char* const name = pathname_.c_str();
+#if GTEST_OS_WINDOWS
+  return pathname_.length() >= 3 &&
+     ((name[0] >= 'a' && name[0] <= 'z') ||
+      (name[0] >= 'A' && name[0] <= 'Z')) &&
+     name[1] == ':' &&
+     IsPathSeparator(name[2]);
+#else
+  return IsPathSeparator(name[0]);
+#endif
+}
+
+// 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_.empty() &&
+         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
+}
+
+// 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_.length() == 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 {
+#if GTEST_OS_WINDOWS_MOBILE
+  FilePath removed_sep(this->RemoveTrailingPathSeparator());
+  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
+  int result = CreateDirectory(unicode, NULL) ? 0 : -1;
+  delete [] unicode;
+#elif GTEST_OS_WINDOWS
+  int result = _mkdir(pathname_.c_str());
+#else
+  int result = mkdir(pathname_.c_str(), 0777);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+  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 IsDirectory()
+      ? FilePath(String(pathname_.c_str(), pathname_.length() - 1))
+      : *this;
+}
+
+// Removes any redundant separators that might be in the pathname.
+// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
+// redundancies that might be in a pathname involving "." or "..".
+// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
+void FilePath::Normalize() {
+  if (pathname_.c_str() == NULL) {
+    pathname_ = "";
+    return;
+  }
+  const char* src = pathname_.c_str();
+  char* const dest = new char[pathname_.length() + 1];
+  char* dest_ptr = dest;
+  memset(dest_ptr, 0, pathname_.length() + 1);
+
+  while (*src != '\0') {
+    *dest_ptr = *src;
+    if (!IsPathSeparator(*src)) {
+      src++;
+    } else {
+#if GTEST_HAS_ALT_PATH_SEP_
+      if (*dest_ptr == kAlternatePathSeparator) {
+        *dest_ptr = kPathSeparator;
+      }
+#endif
+      while (IsPathSeparator(*src))
+        src++;
+    }
+    dest_ptr++;
+  }
+  *dest_ptr = '\0';
+  pathname_ = dest;
+  delete[] dest;
+}
+
+}  // namespace internal
+}  // namespace testing
+// 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 <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h>  // For TerminateProcess()
+#elif GTEST_OS_WINDOWS
+#include <io.h>
+#include <sys/stat.h>
+#else
+#include <unistd.h>
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#if GTEST_OS_MAC
+#include <mach/mach_init.h>
+#include <mach/task.h>
+#include <mach/vm_map.h>
+#endif  // GTEST_OS_MAC
+
+
+// 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_ 1
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+namespace internal {
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
+const int kStdOutFileno = 1;
+const int kStdErrFileno = 2;
+#else
+const int kStdOutFileno = STDOUT_FILENO;
+const int kStdErrFileno = STDERR_FILENO;
+#endif  // _MSC_VER
+
+#if GTEST_OS_MAC
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+size_t GetThreadCount() {
+  const task_t task = mach_task_self();
+  mach_msg_type_number_t thread_count;
+  thread_act_array_t thread_list;
+  const kern_return_t status = task_threads(task, &thread_list, &thread_count);
+  if (status == KERN_SUCCESS) {
+    // task_threads allocates resources in thread_list and we need to free them
+    // to avoid leaks.
+    vm_deallocate(task,
+                  reinterpret_cast<vm_address_t>(thread_list),
+                  sizeof(thread_t) * thread_count);
+    return static_cast<size_t>(thread_count);
+  } else {
+    return 0;
+  }
+}
+
+#else
+
+size_t GetThreadCount() {
+  // There's no portable way to detect the number of threads, so we just
+  // return 0 to indicate that we cannot detect it.
+  return 0;
+}
+
+#endif  // GTEST_OS_MAC
+
+#if GTEST_USES_POSIX_RE
+
+// Implements RE.  Currently only needed for death tests.
+
+RE::~RE() {
+  if (is_valid_) {
+    // regfree'ing an invalid regex might crash because the content
+    // of the regex is undefined. Since the regex's are essentially
+    // the same, one cannot be valid (or invalid) without the other
+    // being so too.
+    regfree(&partial_regex_);
+    regfree(&full_regex_);
+  }
+  free(const_cast<char*>(pattern_));
+}
+
+// Returns true iff regular expression re matches the entire str.
+bool RE::FullMatch(const char* str, const RE& re) {
+  if (!re.is_valid_) return false;
+
+  regmatch_t match;
+  return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
+}
+
+// Returns true iff regular expression re matches a substring of str
+// (including str itself).
+bool RE::PartialMatch(const char* str, const RE& re) {
+  if (!re.is_valid_) return false;
+
+  regmatch_t match;
+  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+  pattern_ = posix::StrDup(regex);
+
+  // Reserves enough bytes to hold the regular expression used for a
+  // full match.
+  const size_t full_regex_len = strlen(regex) + 10;
+  char* const full_pattern = new char[full_regex_len];
+
+  snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
+  is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
+  // We want to call regcomp(&partial_regex_, ...) even if the
+  // previous expression returns false.  Otherwise partial_regex_ may
+  // not be properly initialized can may cause trouble when it's
+  // freed.
+  //
+  // Some implementation of POSIX regex (e.g. on at least some
+  // versions of Cygwin) doesn't accept the empty string as a valid
+  // regex.  We change it to an equivalent form "()" to be safe.
+  if (is_valid_) {
+    const char* const partial_regex = (*regex == '\0') ? "()" : regex;
+    is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
+  }
+  EXPECT_TRUE(is_valid_)
+      << "Regular expression \"" << regex
+      << "\" is not a valid POSIX Extended regular expression.";
+
+  delete[] full_pattern;
+}
+
+#elif GTEST_USES_SIMPLE_RE
+
+// Returns true iff ch appears anywhere in str (excluding the
+// terminating '\0' character).
+bool IsInSet(char ch, const char* str) {
+  return ch != '\0' && strchr(str, ch) != NULL;
+}
+
+// Returns true iff ch belongs to the given classification.  Unlike
+// similar functions in <ctype.h>, these aren't affected by the
+// current locale.
+bool IsDigit(char ch) { return '0' <= ch && ch <= '9'; }
+bool IsPunct(char ch) {
+  return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
+}
+bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
+bool IsWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
+bool IsWordChar(char ch) {
+  return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
+      ('0' <= ch && ch <= '9') || ch == '_';
+}
+
+// Returns true iff "\\c" is a supported escape sequence.
+bool IsValidEscape(char c) {
+  return (IsPunct(c) || IsInSet(c, "dDfnrsStvwW"));
+}
+
+// Returns true iff the given atom (specified by escaped and pattern)
+// matches ch.  The result is undefined if the atom is invalid.
+bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
+  if (escaped) {  // "\\p" where p is pattern_char.
+    switch (pattern_char) {
+      case 'd': return IsDigit(ch);
+      case 'D': return !IsDigit(ch);
+      case 'f': return ch == '\f';
+      case 'n': return ch == '\n';
+      case 'r': return ch == '\r';
+      case 's': return IsWhiteSpace(ch);
+      case 'S': return !IsWhiteSpace(ch);
+      case 't': return ch == '\t';
+      case 'v': return ch == '\v';
+      case 'w': return IsWordChar(ch);
+      case 'W': return !IsWordChar(ch);
+    }
+    return IsPunct(pattern_char) && pattern_char == ch;
+  }
+
+  return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
+}
+
+// Helper function used by ValidateRegex() to format error messages.
+String FormatRegexSyntaxError(const char* regex, int index) {
+  return (Message() << "Syntax error at index " << index
+          << " in simple regular expression \"" << regex << "\": ").GetString();
+}
+
+// Generates non-fatal failures and returns false if regex is invalid;
+// otherwise returns true.
+bool ValidateRegex(const char* regex) {
+  if (regex == NULL) {
+    // TODO(wan@google.com): fix the source file location in the
+    // assertion failures to match where the regex is used in user
+    // code.
+    ADD_FAILURE() << "NULL is not a valid simple regular expression.";
+    return false;
+  }
+
+  bool is_valid = true;
+
+  // True iff ?, *, or + can follow the previous atom.
+  bool prev_repeatable = false;
+  for (int i = 0; regex[i]; i++) {
+    if (regex[i] == '\\') {  // An escape sequence
+      i++;
+      if (regex[i] == '\0') {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
+                      << "'\\' cannot appear at the end.";
+        return false;
+      }
+
+      if (!IsValidEscape(regex[i])) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
+                      << "invalid escape sequence \"\\" << regex[i] << "\".";
+        is_valid = false;
+      }
+      prev_repeatable = true;
+    } else {  // Not an escape sequence.
+      const char ch = regex[i];
+
+      if (ch == '^' && i > 0) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'^' can only appear at the beginning.";
+        is_valid = false;
+      } else if (ch == '$' && regex[i + 1] != '\0') {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'$' can only appear at the end.";
+        is_valid = false;
+      } else if (IsInSet(ch, "()[]{}|")) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'" << ch << "' is unsupported.";
+        is_valid = false;
+      } else if (IsRepeat(ch) && !prev_repeatable) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'" << ch << "' can only follow a repeatable token.";
+        is_valid = false;
+      }
+
+      prev_repeatable = !IsInSet(ch, "^$?*+");
+    }
+  }
+
+  return is_valid;
+}
+
+// Matches a repeated regex atom followed by a valid simple regular
+// expression.  The regex atom is defined as c if escaped is false,
+// or \c otherwise.  repeat is the repetition meta character (?, *,
+// or +).  The behavior is undefined if str contains too many
+// characters to be indexable by size_t, in which case the test will
+// probably time out anyway.  We are fine with this limitation as
+// std::string has it too.
+bool MatchRepetitionAndRegexAtHead(
+    bool escaped, char c, char repeat, const char* regex,
+    const char* str) {
+  const size_t min_count = (repeat == '+') ? 1 : 0;
+  const size_t max_count = (repeat == '?') ? 1 :
+      static_cast<size_t>(-1) - 1;
+  // We cannot call numeric_limits::max() as it conflicts with the
+  // max() macro on Windows.
+
+  for (size_t i = 0; i <= max_count; ++i) {
+    // We know that the atom matches each of the first i characters in str.
+    if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
+      // We have enough matches at the head, and the tail matches too.
+      // Since we only care about *whether* the pattern matches str
+      // (as opposed to *how* it matches), there is no need to find a
+      // greedy match.
+      return true;
+    }
+    if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
+      return false;
+  }
+  return false;
+}
+
+// Returns true iff regex matches a prefix of str.  regex must be a
+// valid simple regular expression and not start with "^", or the
+// result is undefined.
+bool MatchRegexAtHead(const char* regex, const char* str) {
+  if (*regex == '\0')  // An empty regex matches a prefix of anything.
+    return true;
+
+  // "$" only matches the end of a string.  Note that regex being
+  // valid guarantees that there's nothing after "$" in it.
+  if (*regex == '$')
+    return *str == '\0';
+
+  // Is the first thing in regex an escape sequence?
+  const bool escaped = *regex == '\\';
+  if (escaped)
+    ++regex;
+  if (IsRepeat(regex[1])) {
+    // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
+    // here's an indirect recursion.  It terminates as the regex gets
+    // shorter in each recursion.
+    return MatchRepetitionAndRegexAtHead(
+        escaped, regex[0], regex[1], regex + 2, str);
+  } else {
+    // regex isn't empty, isn't "$", and doesn't start with a
+    // repetition.  We match the first atom of regex with the first
+    // character of str and recurse.
+    return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
+        MatchRegexAtHead(regex + 1, str + 1);
+  }
+}
+
+// Returns true iff regex matches any substring of str.  regex must be
+// a valid simple regular expression, or the result is undefined.
+//
+// The algorithm is recursive, but the recursion depth doesn't exceed
+// the regex length, so we won't need to worry about running out of
+// stack space normally.  In rare cases the time complexity can be
+// exponential with respect to the regex length + the string length,
+// but usually it's must faster (often close to linear).
+bool MatchRegexAnywhere(const char* regex, const char* str) {
+  if (regex == NULL || str == NULL)
+    return false;
+
+  if (*regex == '^')
+    return MatchRegexAtHead(regex + 1, str);
+
+  // A successful match can be anywhere in str.
+  do {
+    if (MatchRegexAtHead(regex, str))
+      return true;
+  } while (*str++ != '\0');
+  return false;
+}
+
+// Implements the RE class.
+
+RE::~RE() {
+  free(const_cast<char*>(pattern_));
+  free(const_cast<char*>(full_pattern_));
+}
+
+// Returns true iff regular expression re matches the entire str.
+bool RE::FullMatch(const char* str, const RE& re) {
+  return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
+}
+
+// Returns true iff regular expression re matches a substring of str
+// (including str itself).
+bool RE::PartialMatch(const char* str, const RE& re) {
+  return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+  pattern_ = full_pattern_ = NULL;
+  if (regex != NULL) {
+    pattern_ = posix::StrDup(regex);
+  }
+
+  is_valid_ = ValidateRegex(regex);
+  if (!is_valid_) {
+    // No need to calculate the full pattern when the regex is invalid.
+    return;
+  }
+
+  const size_t len = strlen(regex);
+  // Reserves enough bytes to hold the regular expression used for a
+  // full match: we need space to prepend a '^', append a '$', and
+  // terminate the string with '\0'.
+  char* buffer = static_cast<char*>(malloc(len + 3));
+  full_pattern_ = buffer;
+
+  if (*regex != '^')
+    *buffer++ = '^';  // Makes sure full_pattern_ starts with '^'.
+
+  // We don't use snprintf or strncpy, as they trigger a warning when
+  // compiled with VC++ 8.0.
+  memcpy(buffer, regex, len);
+  buffer += len;
+
+  if (len == 0 || regex[len - 1] != '$')
+    *buffer++ = '$';  // Makes sure full_pattern_ ends with '$'.
+
+  *buffer = '\0';
+}
+
+#endif  // GTEST_USES_POSIX_RE
+
+
+GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
+    : severity_(severity) {
+  const char* const marker =
+      severity == GTEST_INFO ?    "[  INFO ]" :
+      severity == GTEST_WARNING ? "[WARNING]" :
+      severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]";
+  GetStream() << ::std::endl << marker << " "
+              << FormatFileLocation(file, line).c_str() << ": ";
+}
+
+// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+GTestLog::~GTestLog() {
+  GetStream() << ::std::endl;
+  if (severity_ == GTEST_FATAL) {
+    fflush(stderr);
+    posix::Abort();
+  }
+}
+// Disable Microsoft deprecation warnings for POSIX functions called from
+// this class (creat, dup, dup2, and close)
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4996)
+#endif  // _MSC_VER
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+
+// Object that captures an output stream (stdout/stderr).
+class CapturedStream {
+ public:
+  // The ctor redirects the stream to a temporary file.
+  CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
+#if GTEST_OS_WINDOWS
+    char temp_dir_path[MAX_PATH + 1] = { '\0' };  // NOLINT
+    char temp_file_path[MAX_PATH + 1] = { '\0' };  // NOLINT
+
+    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
+    const UINT success = ::GetTempFileNameA(temp_dir_path,
+                                            "gtest_redir",
+                                            0,  // Generate unique file name.
+                                            temp_file_path);
+    GTEST_CHECK_(success != 0)
+        << "Unable to create a temporary file in " << temp_dir_path;
+    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
+    GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
+                                    << temp_file_path;
+    filename_ = temp_file_path;
+#else
+    // There's no guarantee that a test has write access to the
+    // current directory, so we create the temporary file in the /tmp
+    // directory instead.
+    char name_template[] = "/tmp/captured_stream.XXXXXX";
+    const int captured_fd = mkstemp(name_template);
+    filename_ = name_template;
+#endif  // GTEST_OS_WINDOWS
+    fflush(NULL);
+    dup2(captured_fd, fd_);
+    close(captured_fd);
+  }
+
+  ~CapturedStream() {
+    remove(filename_.c_str());
+  }
+
+  String GetCapturedString() {
+    if (uncaptured_fd_ != -1) {
+      // Restores the original stream.
+      fflush(NULL);
+      dup2(uncaptured_fd_, fd_);
+      close(uncaptured_fd_);
+      uncaptured_fd_ = -1;
+    }
+
+    FILE* const file = posix::FOpen(filename_.c_str(), "r");
+    const String content = ReadEntireFile(file);
+    posix::FClose(file);
+    return content;
+  }
+
+ private:
+  // Reads the entire content of a file as a String.
+  static String ReadEntireFile(FILE* file);
+
+  // Returns the size (in bytes) of a file.
+  static size_t GetFileSize(FILE* file);
+
+  const int fd_;  // A stream to capture.
+  int uncaptured_fd_;
+  // Name of the temporary file holding the stderr output.
+  ::std::string filename_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
+};
+
+// Returns the size (in bytes) of a file.
+size_t CapturedStream::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.
+String CapturedStream::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 String content(buffer, bytes_read);
+  delete[] buffer;
+
+  return content;
+}
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif  // _MSC_VER
+
+static CapturedStream* g_captured_stderr = NULL;
+static CapturedStream* g_captured_stdout = NULL;
+
+// Starts capturing an output stream (stdout/stderr).
+void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
+  if (*stream != NULL) {
+    GTEST_LOG_(FATAL) << "Only one " << stream_name
+                      << " capturer can exist at a time.";
+  }
+  *stream = new CapturedStream(fd);
+}
+
+// Stops capturing the output stream and returns the captured string.
+String GetCapturedStream(CapturedStream** captured_stream) {
+  const String content = (*captured_stream)->GetCapturedString();
+
+  delete *captured_stream;
+  *captured_stream = NULL;
+
+  return content;
+}
+
+// Starts capturing stdout.
+void CaptureStdout() {
+  CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
+}
+
+// Starts capturing stderr.
+void CaptureStderr() {
+  CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
+}
+
+// Stops capturing stdout and returns the captured string.
+String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
+
+// Stops capturing stderr and returns the captured string.
+String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
+
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
+#if GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments.  Set by InitGoogleTest().
+::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
+
+#if GTEST_OS_WINDOWS_MOBILE
+namespace posix {
+void Abort() {
+  DebugBreak();
+  TerminateProcess(GetCurrentProcess(), 1);
+}
+}  // namespace posix
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+// 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 (size_t i = 0; i != full_flag.length(); i++) {
+    env_var << static_cast<char>(toupper(full_flag.c_str()[i]));
+  }
+
+  return env_var.GetString();
+}
+
+// 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 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 = posix::GetEnv(env_var.c_str());
+  return string_value == NULL ?
+      default_value : strcmp(string_value, "0") != 0;
+}
+
+// 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 = posix::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 = posix::GetEnv(env_var.c_str());
+  return value == NULL ? default_value : value;
+}
+
+}  // namespace internal
+}  // namespace testing
+// 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: mheule@google.com (Markus Heule)
+//
+// The Google C++ Testing Framework (Google Test)
+
+
+// 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_ 1
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+
+using internal::GetUnitTestImpl;
+
+// Gets the summary of the failure message by omitting the stack trace
+// in it.
+internal::String TestPartResult::ExtractSummary(const char* message) {
+  const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
+  return stack_trace == NULL ? internal::String(message) :
+      internal::String(message, stack_trace - message);
+}
+
+// Prints a TestPartResult object.
+std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
+  return os
+      << result.file_name() << ":" << result.line_number() << ": "
+      << (result.type() == TestPartResult::kSuccess ? "Success" :
+          result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
+          "Non-fatal failure") << ":\n"
+      << result.message() << std::endl;
+}
+
+// Appends a TestPartResult to the array.
+void TestPartResultArray::Append(const TestPartResult& result) {
+  array_.push_back(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);
+    internal::posix::Abort();
+  }
+
+  return array_[index];
+}
+
+// Returns the number of TestPartResult objects in the array.
+int TestPartResultArray::size() const {
+  return static_cast<int>(array_.size());
+}
+
+namespace internal {
+
+HasNewFatalFailureHelper::HasNewFatalFailureHelper()
+    : has_new_fatal_failure_(false),
+      original_reporter_(GetUnitTestImpl()->
+                         GetTestPartResultReporterForCurrentThread()) {
+  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
+}
+
+HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
+  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
+      original_reporter_);
+}
+
+void HasNewFatalFailureHelper::ReportTestPartResult(
+    const TestPartResult& result) {
+  if (result.fatally_failed())
+    has_new_fatal_failure_ = true;
+  original_reporter_->ReportTestPartResult(result);
+}
+
+}  // namespace internal
+
+}  // namespace testing
+// 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)
+
+
+namespace testing {
+namespace internal {
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// Skips to the first non-space char in str. Returns an empty string if str
+// contains only whitespace characters.
+static const char* SkipSpaces(const char* str) {
+  while (isspace(*str))
+    str++;
+  return str;
+}
+
+// Verifies that registered_tests match the test names in
+// defined_test_names_; returns registered_tests if successful, or
+// aborts the program otherwise.
+const char* TypedTestCasePState::VerifyRegisteredTestNames(
+    const char* file, int line, const char* registered_tests) {
+  typedef ::std::set<const char*>::const_iterator DefinedTestIter;
+  registered_ = true;
+
+  // Skip initial whitespace in registered_tests since some
+  // preprocessors prefix stringizied literals with whitespace.
+  registered_tests = SkipSpaces(registered_tests);
+
+  Message errors;
+  ::std::set<String> tests;
+  for (const char* names = registered_tests; names != NULL;
+       names = SkipComma(names)) {
+    const String name = GetPrefixUntilComma(names);
+    if (tests.count(name) != 0) {
+      errors << "Test " << name << " is listed more than once.\n";
+      continue;
+    }
+
+    bool found = false;
+    for (DefinedTestIter it = defined_test_names_.begin();
+         it != defined_test_names_.end();
+         ++it) {
+      if (name == *it) {
+        found = true;
+        break;
+      }
+    }
+
+    if (found) {
+      tests.insert(name);
+    } else {
+      errors << "No test named " << name
+             << " can be found in this test case.\n";
+    }
+  }
+
+  for (DefinedTestIter it = defined_test_names_.begin();
+       it != defined_test_names_.end();
+       ++it) {
+    if (tests.count(*it) == 0) {
+      errors << "You forgot to list test " << *it << ".\n";
+    }
+  }
+
+  const String& errors_str = errors.GetString();
+  if (errors_str != "") {
+    fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
+            errors_str.c_str());
+    fflush(stderr);
+    posix::Abort();
+  }
+
+  return registered_tests;
+}
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+}  // namespace internal
+}  // namespace testing
diff --git a/protobuf/gtest/fused-src/gtest/gtest.h b/protobuf/gtest/fused-src/gtest/gtest.h
new file mode 100644
index 0000000..c0a1902
--- /dev/null
+++ b/protobuf/gtest/fused-src/gtest/gtest.h
@@ -0,0 +1,18007 @@
+// 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_
+
+#include <limits>
+#include <vector>
+
+// 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_
+
+// 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_
+
+// The user can define the following macros in the build script to
+// control Google Test's behavior.  If the user doesn't define a macro
+// in this list, Google Test will define it.
+//
+//   GTEST_HAS_CLONE          - Define it to 1/0 to indicate that clone(2)
+//                              is/isn't available.
+//   GTEST_HAS_EXCEPTIONS     - Define it to 1/0 to indicate that exceptions
+//                              are enabled.
+//   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).
+//   GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string
+//                              is/isn't available (some systems define
+//                              ::wstring, which is different to std::wstring).
+//   GTEST_HAS_PTHREAD        - Define it to 1/0 to indicate that <pthread.h>
+//                              is/isn't available.
+//   GTEST_HAS_RTTI           - Define it to 1/0 to indicate that RTTI is/isn't
+//                              enabled.
+//   GTEST_HAS_STD_WSTRING    - Define it to 1/0 to indicate that
+//                              std::wstring does/doesn't work (Google Test can
+//                              be used where std::wstring is unavailable).
+//   GTEST_HAS_TR1_TUPLE      - Define it to 1/0 to indicate tr1::tuple
+//                              is/isn't available.
+//   GTEST_HAS_SEH            - Define it to 1/0 to indicate whether the
+//                              compiler supports Microsoft's "Structured
+//                              Exception Handling".
+//   GTEST_USE_OWN_TR1_TUPLE  - Define it to 1/0 to indicate whether Google
+//                              Test's own tr1 tuple implementation should be
+//                              used.  Unused when the user sets
+//                              GTEST_HAS_TR1_TUPLE to 0.
+//   GTEST_LINKED_AS_SHARED_LIBRARY
+//                            - Define to 1 when compiling tests that use
+//                              Google Test as a shared library (known as
+//                              DLL on Windows).
+//   GTEST_CREATE_SHARED_LIBRARY
+//                            - Define to 1 when compiling Google Test itself
+//                              as a shared library.
+
+// This header defines the following utilities:
+//
+// Macros indicating the current platform (defined to 1 if compiled on
+// the given platform; otherwise undefined):
+//   GTEST_OS_AIX      - IBM AIX
+//   GTEST_OS_CYGWIN   - Cygwin
+//   GTEST_OS_LINUX    - Linux
+//   GTEST_OS_MAC      - Mac OS X
+//   GTEST_OS_SOLARIS  - Sun Solaris
+//   GTEST_OS_SYMBIAN  - Symbian
+//   GTEST_OS_WINDOWS  - Windows (Desktop, MinGW, or Mobile)
+//     GTEST_OS_WINDOWS_DESKTOP  - Windows Desktop
+//     GTEST_OS_WINDOWS_MINGW    - MinGW
+//     GTEST_OS_WINDOWS_MOBILE   - Windows Mobile
+//   GTEST_OS_ZOS      - z/OS
+//
+// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
+// most stable support.  Since core members of the Google Test project
+// don't have access to other platforms, support for them may be less
+// stable.  If you notice any problems on your platform, please notify
+// googletestframework@googlegroups.com (patches for fixing them are
+// even more welcome!).
+//
+// Note that it is possible that none of the GTEST_OS_* macros are defined.
+//
+// Macros indicating available Google Test features (defined to 1 if
+// the corresponding feature is supported; otherwise undefined):
+//   GTEST_HAS_COMBINE      - the Combine() function (for value-parameterized
+//                            tests)
+//   GTEST_HAS_DEATH_TEST   - death tests
+//   GTEST_HAS_PARAM_TEST   - value-parameterized tests
+//   GTEST_HAS_TYPED_TEST   - typed tests
+//   GTEST_HAS_TYPED_TEST_P - type-parameterized tests
+//   GTEST_USES_POSIX_RE    - enhanced POSIX regex is used.
+//   GTEST_USES_SIMPLE_RE   - our own simple regex is used;
+//                            the above two are mutually exclusive.
+//   GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
+//
+// Macros for basic C++ coding:
+//   GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
+//   GTEST_ATTRIBUTE_UNUSED_  - declares that a class' instances or a
+//                              variable don't have to be used.
+//   GTEST_DISALLOW_ASSIGN_   - disables operator=.
+//   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.
+//   GTEST_IS_THREADSAFE - defined to 1 to indicate that the above
+//                         synchronization primitives have real implementations
+//                         and Google Test is thread-safe; or 0 otherwise.
+//
+// Template meta programming:
+//   is_pointer     - as in TR1; needed on Symbian and IBM XL C/C++ 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.
+//
+// Stdout and stderr capturing:
+//   CaptureStdout()     - starts capturing stdout.
+//   GetCapturedStdout() - stops capturing stdout and returns the captured
+//                         string.
+//   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 <stddef.h>  // For ptrdiff_t
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef _WIN32_WCE
+#include <sys/stat.h>
+#endif  // !_WIN32_WCE
+
+#include <iostream>  // NOLINT
+#include <sstream>  // NOLINT
+#include <string>  // NOLINT
+
+#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
+#define GTEST_FLAG_PREFIX_ "gtest_"
+#define GTEST_FLAG_PREFIX_DASH_ "gtest-"
+#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_"
+#define GTEST_NAME_ "Google Test"
+#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/"
+
+// Determines the version of gcc that is used to compile this.
+#ifdef __GNUC__
+// 40302 means version 4.3.2.
+#define GTEST_GCC_VER_ \
+    (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
+#endif  // __GNUC__
+
+// Determines the platform on which Google Test is compiled.
+#ifdef __CYGWIN__
+#define GTEST_OS_CYGWIN 1
+#elif defined __SYMBIAN32__
+#define GTEST_OS_SYMBIAN 1
+#elif defined _WIN32
+#define GTEST_OS_WINDOWS 1
+#ifdef _WIN32_WCE
+#define GTEST_OS_WINDOWS_MOBILE 1
+#elif defined(__MINGW__) || defined(__MINGW32__)
+#define GTEST_OS_WINDOWS_MINGW 1
+#else
+#define GTEST_OS_WINDOWS_DESKTOP 1
+#endif  // _WIN32_WCE
+#elif defined __APPLE__
+#define GTEST_OS_MAC 1
+#elif defined __linux__
+#define GTEST_OS_LINUX 1
+#elif defined __MVS__
+#define GTEST_OS_ZOS 1
+#elif defined(__sun) && defined(__SVR4)
+#define GTEST_OS_SOLARIS 1
+#elif defined(_AIX)
+#define GTEST_OS_AIX 1
+#endif  // __CYGWIN__
+
+#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SYMBIAN || \
+    GTEST_OS_SOLARIS || GTEST_OS_AIX
+
+// On some platforms, <regex.h> needs someone to define size_t, and
+// won't compile otherwise.  We can #include it here as we already
+// included <stdlib.h>, which is guaranteed to define size_t through
+// <stddef.h>.
+#include <regex.h>  // NOLINT
+#include <strings.h>  // NOLINT
+#include <sys/types.h>  // NOLINT
+#include <time.h>  // NOLINT
+#include <unistd.h>  // NOLINT
+
+#define GTEST_USES_POSIX_RE 1
+
+#elif GTEST_OS_WINDOWS
+
+#if !GTEST_OS_WINDOWS_MOBILE
+#include <direct.h>  // NOLINT
+#include <io.h>  // NOLINT
+#endif
+
+// <regex.h> is not available on Windows.  Use our own simple regex
+// implementation instead.
+#define GTEST_USES_SIMPLE_RE 1
+
+#else
+
+// <regex.h> may not be available on this platform.  Use our own
+// simple regex implementation instead.
+#define GTEST_USES_SIMPLE_RE 1
+
+#endif  // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC ||
+        // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX
+
+#ifndef GTEST_HAS_EXCEPTIONS
+// The user didn't tell us whether exceptions are enabled, so we need
+// to figure it out.
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
+// macro to enable exceptions, so we'll do the same.
+// Assumes that exceptions are enabled by default.
+#ifndef _HAS_EXCEPTIONS
+#define _HAS_EXCEPTIONS 1
+#endif  // _HAS_EXCEPTIONS
+#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
+#elif defined(__GNUC__) && __EXCEPTIONS
+// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__SUNPRO_CC)
+// Sun Pro CC supports exceptions.  However, there is no compile-time way of
+// detecting whether they are enabled or not.  Therefore, we assume that
+// they are enabled unless the user tells us otherwise.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__IBMCPP__) && __EXCEPTIONS
+// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#define GTEST_HAS_EXCEPTIONS 1
+#else
+// For other compilers, we assume exceptions are disabled to be
+// conservative.
+#define GTEST_HAS_EXCEPTIONS 0
+#endif  // defined(_MSC_VER) || defined(__BORLANDC__)
+#endif  // GTEST_HAS_EXCEPTIONS
+
+#if !defined(GTEST_HAS_STD_STRING)
+// Even though we don't use this macro any longer, we keep it in case
+// some clients still depend on it.
+#define GTEST_HAS_STD_STRING 1
+#elif !GTEST_HAS_STD_STRING
+// The user told us that ::std::string isn't available.
+#error "Google Test cannot be used where ::std::string isn't available."
+#endif  // !defined(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
+
+#ifndef GTEST_HAS_STD_WSTRING
+// The user didn't tell us whether ::std::wstring is available, so we need
+// to figure it out.
+// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring
+//   is available.
+
+// Cygwin 1.5 and below doesn't support ::std::wstring.
+// Cygwin 1.7 might add wstring support; this should be updated when clear.
+// Solaris' libc++ doesn't support it either.
+#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS))
+
+#endif  // GTEST_HAS_STD_WSTRING
+
+#ifndef GTEST_HAS_GLOBAL_WSTRING
+// The user didn't tell us whether ::wstring is available, so we need
+// to figure it out.
+#define GTEST_HAS_GLOBAL_WSTRING \
+    (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING)
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+// Determines whether RTTI is available.
+#ifndef GTEST_HAS_RTTI
+// The user didn't tell us whether RTTI is enabled, so we need to
+// figure it out.
+
+#ifdef _MSC_VER
+
+#ifdef _CPPRTTI  // MSVC defines this macro iff RTTI is enabled.
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif
+
+// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.
+#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)
+
+#ifdef __GXX_RTTI
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif  // __GXX_RTTI
+
+// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if
+// both the typeid and dynamic_cast features are present.
+#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)
+
+#ifdef __RTTI_ALL__
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif
+
+#else
+
+// For all other compilers, we assume RTTI is enabled.
+#define GTEST_HAS_RTTI 1
+
+#endif  // _MSC_VER
+
+#endif  // GTEST_HAS_RTTI
+
+// It's this header's responsibility to #include <typeinfo> when RTTI
+// is enabled.
+#if GTEST_HAS_RTTI
+#include <typeinfo>
+#endif
+
+// Determines whether Google Test can use the pthreads library.
+#ifndef GTEST_HAS_PTHREAD
+// The user didn't tell us explicitly, so we assume pthreads support is
+// available on Linux and Mac.
+//
+// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
+// to your compiler flags.
+#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC)
+#endif  // GTEST_HAS_PTHREAD
+
+// Determines whether Google Test can use tr1/tuple.  You can define
+// this macro to 0 to prevent Google Test from using tuple (any
+// feature depending on tuple with be disabled in this mode).
+#ifndef GTEST_HAS_TR1_TUPLE
+// The user didn't tell us not to do it, so we assume it's OK.
+#define GTEST_HAS_TR1_TUPLE 1
+#endif  // GTEST_HAS_TR1_TUPLE
+
+// Determines whether Google Test's own tr1 tuple implementation
+// should be used.
+#ifndef GTEST_USE_OWN_TR1_TUPLE
+// The user didn't tell us, so we need to figure it out.
+
+// We use our own TR1 tuple if we aren't sure the user has an
+// implementation of it already.  At this time, GCC 4.0.0+ and MSVC
+// 2010 are the only mainstream compilers that come with a TR1 tuple
+// implementation.  NVIDIA's CUDA NVCC compiler pretends to be GCC by
+// defining __GNUC__ and friends, but cannot compile GCC's tuple
+// implementation.  MSVC 2008 (9.0) provides TR1 tuple in a 323 MB
+// Feature Pack download, which we cannot assume the user has.
+#if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \
+    || _MSC_VER >= 1600
+#define GTEST_USE_OWN_TR1_TUPLE 0
+#else
+#define GTEST_USE_OWN_TR1_TUPLE 1
+#endif
+
+#endif  // GTEST_USE_OWN_TR1_TUPLE
+
+// To avoid conditional compilation everywhere, we make it
+// gtest-port.h's responsibility to #include the header implementing
+// tr1/tuple.
+#if GTEST_HAS_TR1_TUPLE
+
+#if GTEST_USE_OWN_TR1_TUPLE
+// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+
+// Copyright 2009 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)
+
+// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+
+#include <utility>  // For ::std::pair.
+
+// The compiler used in Symbian has a bug that prevents us from declaring the
+// tuple template as a friend (it complains that tuple is redefined).  This
+// hack bypasses the bug by declaring the members that should otherwise be
+// private as public.
+// Sun Studio versions < 12 also have the above bug.
+#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
+#else
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
+    template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
+   private:
+#endif
+
+// GTEST_n_TUPLE_(T) is the type of an n-tuple.
+#define GTEST_0_TUPLE_(T) tuple<>
+#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
+    void, void, void>
+#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
+    void, void, void>
+#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
+    void, void, void>
+#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
+    void, void, void>
+#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
+    void, void, void>
+#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
+    void, void, void>
+#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    void, void, void>
+#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, void, void>
+#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, T##8, void>
+#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, T##8, T##9>
+
+// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
+#define GTEST_0_TYPENAMES_(T)
+#define GTEST_1_TYPENAMES_(T) typename T##0
+#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1
+#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2
+#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3
+#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4
+#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5
+#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6
+#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, typename T##7
+#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, \
+    typename T##7, typename T##8
+#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, \
+    typename T##7, typename T##8, typename T##9
+
+// In theory, defining stuff in the ::std namespace is undefined
+// behavior.  We can do this as we are playing the role of a standard
+// library vendor.
+namespace std {
+namespace tr1 {
+
+template <typename T0 = void, typename T1 = void, typename T2 = void,
+    typename T3 = void, typename T4 = void, typename T5 = void,
+    typename T6 = void, typename T7 = void, typename T8 = void,
+    typename T9 = void>
+class tuple;
+
+// Anything in namespace gtest_internal is Google Test's INTERNAL
+// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
+namespace gtest_internal {
+
+// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
+template <typename T>
+struct ByRef { typedef const T& type; };  // NOLINT
+template <typename T>
+struct ByRef<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper for ByRef.
+#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
+
+// AddRef<T>::type is T if T is a reference; otherwise it's T&.  This
+// is the same as tr1::add_reference<T>::type.
+template <typename T>
+struct AddRef { typedef T& type; };  // NOLINT
+template <typename T>
+struct AddRef<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper for AddRef.
+#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
+
+// A helper for implementing get<k>().
+template <int k> class Get;
+
+// A helper for implementing tuple_element<k, T>.  kIndexValid is true
+// iff k < the number of fields in tuple type T.
+template <bool kIndexValid, int kIndex, class Tuple>
+struct TupleElement;
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; };
+
+}  // namespace gtest_internal
+
+template <>
+class tuple<> {
+ public:
+  tuple() {}
+  tuple(const tuple& /* t */)  {}
+  tuple& operator=(const tuple& /* t */) { return *this; }
+};
+
+template <GTEST_1_TYPENAMES_(T)>
+class GTEST_1_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
+
+  tuple(const tuple& t) : f0_(t.f0_) {}
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_1_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    return *this;
+  }
+
+  T0 f0_;
+};
+
+template <GTEST_2_TYPENAMES_(T)>
+class GTEST_2_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
+      f1_(f1) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}
+  template <typename U0, typename U1>
+  tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_2_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+  template <typename U0, typename U1>
+  tuple& operator=(const ::std::pair<U0, U1>& p) {
+    f0_ = p.first;
+    f1_ = p.second;
+    return *this;
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+};
+
+template <GTEST_3_TYPENAMES_(T)>
+class GTEST_3_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_3_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+};
+
+template <GTEST_4_TYPENAMES_(T)>
+class GTEST_4_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_4_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+};
+
+template <GTEST_5_TYPENAMES_(T)>
+class GTEST_5_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
+      GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_) {}
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_5_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+};
+
+template <GTEST_6_TYPENAMES_(T)>
+class GTEST_6_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_) {}
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_6_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+};
+
+template <GTEST_7_TYPENAMES_(T)>
+class GTEST_7_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_7_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+};
+
+template <GTEST_8_TYPENAMES_(T)>
+class GTEST_8_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,
+      GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5), f6_(f6), f7_(f7) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_8_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+};
+
+template <GTEST_9_TYPENAMES_(T)>
+class GTEST_9_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
+      GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_9_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    f8_ = t.f8_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+  T8 f8_;
+};
+
+template <GTEST_10_TYPENAMES_(T)>
+class tuple {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),
+      f9_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
+      GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),
+      f9_(t.f9_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_10_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    f8_ = t.f8_;
+    f9_ = t.f9_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+  T8 f8_;
+  T9 f9_;
+};
+
+// 6.1.3.2 Tuple creation functions.
+
+// Known limitations: we don't support passing an
+// std::tr1::reference_wrapper<T> to make_tuple().  And we don't
+// implement tie().
+
+inline tuple<> make_tuple() { return tuple<>(); }
+
+template <GTEST_1_TYPENAMES_(T)>
+inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {
+  return GTEST_1_TUPLE_(T)(f0);
+}
+
+template <GTEST_2_TYPENAMES_(T)>
+inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {
+  return GTEST_2_TUPLE_(T)(f0, f1);
+}
+
+template <GTEST_3_TYPENAMES_(T)>
+inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {
+  return GTEST_3_TUPLE_(T)(f0, f1, f2);
+}
+
+template <GTEST_4_TYPENAMES_(T)>
+inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3) {
+  return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);
+}
+
+template <GTEST_5_TYPENAMES_(T)>
+inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4) {
+  return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);
+}
+
+template <GTEST_6_TYPENAMES_(T)>
+inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5) {
+  return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);
+}
+
+template <GTEST_7_TYPENAMES_(T)>
+inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6) {
+  return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);
+}
+
+template <GTEST_8_TYPENAMES_(T)>
+inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {
+  return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);
+}
+
+template <GTEST_9_TYPENAMES_(T)>
+inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
+    const T8& f8) {
+  return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);
+}
+
+template <GTEST_10_TYPENAMES_(T)>
+inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
+    const T8& f8, const T9& f9) {
+  return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
+}
+
+// 6.1.3.3 Tuple helper classes.
+
+template <typename Tuple> struct tuple_size;
+
+template <GTEST_0_TYPENAMES_(T)>
+struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; };
+
+template <GTEST_1_TYPENAMES_(T)>
+struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; };
+
+template <GTEST_2_TYPENAMES_(T)>
+struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; };
+
+template <GTEST_3_TYPENAMES_(T)>
+struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; };
+
+template <GTEST_4_TYPENAMES_(T)>
+struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; };
+
+template <GTEST_5_TYPENAMES_(T)>
+struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; };
+
+template <GTEST_6_TYPENAMES_(T)>
+struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; };
+
+template <GTEST_7_TYPENAMES_(T)>
+struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; };
+
+template <GTEST_8_TYPENAMES_(T)>
+struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; };
+
+template <GTEST_9_TYPENAMES_(T)>
+struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; };
+
+template <int k, class Tuple>
+struct tuple_element {
+  typedef typename gtest_internal::TupleElement<
+      k < (tuple_size<Tuple>::value), k, Tuple>::type type;
+};
+
+#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
+
+// 6.1.3.4 Element access.
+
+namespace gtest_internal {
+
+template <>
+class Get<0> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
+  Field(Tuple& t) { return t.f0_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
+  ConstField(const Tuple& t) { return t.f0_; }
+};
+
+template <>
+class Get<1> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
+  Field(Tuple& t) { return t.f1_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
+  ConstField(const Tuple& t) { return t.f1_; }
+};
+
+template <>
+class Get<2> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
+  Field(Tuple& t) { return t.f2_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
+  ConstField(const Tuple& t) { return t.f2_; }
+};
+
+template <>
+class Get<3> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
+  Field(Tuple& t) { return t.f3_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
+  ConstField(const Tuple& t) { return t.f3_; }
+};
+
+template <>
+class Get<4> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
+  Field(Tuple& t) { return t.f4_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
+  ConstField(const Tuple& t) { return t.f4_; }
+};
+
+template <>
+class Get<5> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
+  Field(Tuple& t) { return t.f5_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
+  ConstField(const Tuple& t) { return t.f5_; }
+};
+
+template <>
+class Get<6> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
+  Field(Tuple& t) { return t.f6_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
+  ConstField(const Tuple& t) { return t.f6_; }
+};
+
+template <>
+class Get<7> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
+  Field(Tuple& t) { return t.f7_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
+  ConstField(const Tuple& t) { return t.f7_; }
+};
+
+template <>
+class Get<8> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
+  Field(Tuple& t) { return t.f8_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
+  ConstField(const Tuple& t) { return t.f8_; }
+};
+
+template <>
+class Get<9> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
+  Field(Tuple& t) { return t.f9_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
+  ConstField(const Tuple& t) { return t.f9_; }
+};
+
+}  // namespace gtest_internal
+
+template <int k, GTEST_10_TYPENAMES_(T)>
+GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
+get(GTEST_10_TUPLE_(T)& t) {
+  return gtest_internal::Get<k>::Field(t);
+}
+
+template <int k, GTEST_10_TYPENAMES_(T)>
+GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k,  GTEST_10_TUPLE_(T)))
+get(const GTEST_10_TUPLE_(T)& t) {
+  return gtest_internal::Get<k>::ConstField(t);
+}
+
+// 6.1.3.5 Relational operators
+
+// We only implement == and !=, as we don't have a need for the rest yet.
+
+namespace gtest_internal {
+
+// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
+// first k fields of t1 equals the first k fields of t2.
+// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
+// k1 != k2.
+template <int kSize1, int kSize2>
+struct SameSizeTuplePrefixComparator;
+
+template <>
+struct SameSizeTuplePrefixComparator<0, 0> {
+  template <class Tuple1, class Tuple2>
+  static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
+    return true;
+  }
+};
+
+template <int k>
+struct SameSizeTuplePrefixComparator<k, k> {
+  template <class Tuple1, class Tuple2>
+  static bool Eq(const Tuple1& t1, const Tuple2& t2) {
+    return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
+        ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
+  }
+};
+
+}  // namespace gtest_internal
+
+template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+inline bool operator==(const GTEST_10_TUPLE_(T)& t,
+                       const GTEST_10_TUPLE_(U)& u) {
+  return gtest_internal::SameSizeTuplePrefixComparator<
+      tuple_size<GTEST_10_TUPLE_(T)>::value,
+      tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u);
+}
+
+template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
+                       const GTEST_10_TUPLE_(U)& u) { return !(t == u); }
+
+// 6.1.4 Pairs.
+// Unimplemented.
+
+}  // namespace tr1
+}  // namespace std
+
+#undef GTEST_0_TUPLE_
+#undef GTEST_1_TUPLE_
+#undef GTEST_2_TUPLE_
+#undef GTEST_3_TUPLE_
+#undef GTEST_4_TUPLE_
+#undef GTEST_5_TUPLE_
+#undef GTEST_6_TUPLE_
+#undef GTEST_7_TUPLE_
+#undef GTEST_8_TUPLE_
+#undef GTEST_9_TUPLE_
+#undef GTEST_10_TUPLE_
+
+#undef GTEST_0_TYPENAMES_
+#undef GTEST_1_TYPENAMES_
+#undef GTEST_2_TYPENAMES_
+#undef GTEST_3_TYPENAMES_
+#undef GTEST_4_TYPENAMES_
+#undef GTEST_5_TYPENAMES_
+#undef GTEST_6_TYPENAMES_
+#undef GTEST_7_TYPENAMES_
+#undef GTEST_8_TYPENAMES_
+#undef GTEST_9_TYPENAMES_
+#undef GTEST_10_TYPENAMES_
+
+#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
+#undef GTEST_BY_REF_
+#undef GTEST_ADD_REF_
+#undef GTEST_TUPLE_ELEMENT_
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+#elif GTEST_OS_SYMBIAN
+
+// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to
+// use STLport's tuple implementation, which unfortunately doesn't
+// work as the copy of STLport distributed with Symbian is incomplete.
+// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to
+// use its own tuple implementation.
+#ifdef BOOST_HAS_TR1_TUPLE
+#undef BOOST_HAS_TR1_TUPLE
+#endif  // BOOST_HAS_TR1_TUPLE
+
+// This prevents <boost/tr1/detail/config.hpp>, which defines
+// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.
+#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
+#include <tuple>
+
+#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
+// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header.  This does
+// not conform to the TR1 spec, which requires the header to be <tuple>.
+
+#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
+// Until version 4.3.2, gcc has a bug that causes <tr1/functional>,
+// which is #included by <tr1/tuple>, to not compile when RTTI is
+// disabled.  _TR1_FUNCTIONAL is the header guard for
+// <tr1/functional>.  Hence the following #define is a hack to prevent
+// <tr1/functional> from being included.
+#define _TR1_FUNCTIONAL 1
+#include <tr1/tuple>
+#undef _TR1_FUNCTIONAL  // Allows the user to #include
+                        // <tr1/functional> if he chooses to.
+#else
+#include <tr1/tuple>  // NOLINT
+#endif  // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
+
+#else
+// If the compiler is not GCC 4.0+, we assume the user is using a
+// spec-conforming TR1 implementation.
+#include <tuple>  // NOLINT
+#endif  // GTEST_USE_OWN_TR1_TUPLE
+
+#endif  // GTEST_HAS_TR1_TUPLE
+
+// Determines whether clone(2) is supported.
+// Usually it will only be available on Linux, excluding
+// Linux on the Itanium architecture.
+// Also see http://linux.die.net/man/2/clone.
+#ifndef GTEST_HAS_CLONE
+// The user didn't tell us, so we need to figure it out.
+
+#if GTEST_OS_LINUX && !defined(__ia64__)
+#define GTEST_HAS_CLONE 1
+#else
+#define GTEST_HAS_CLONE 0
+#endif  // GTEST_OS_LINUX && !defined(__ia64__)
+
+#endif  // GTEST_HAS_CLONE
+
+// Determines whether to support stream redirection. This is used to test
+// output correctness and to implement death tests.
+#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+#define GTEST_HAS_STREAM_REDIRECTION_ 1
+#endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+
+// Determines whether to support death tests.
+// Google Test does not support death tests for VC 7.1 and earlier as
+// abort() in a VC 7.1 application compiled as GUI in debug config
+// pops up a dialog window that cannot be suppressed programmatically.
+#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
+     (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
+     GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX)
+#define GTEST_HAS_DEATH_TEST 1
+#include <vector>  // NOLINT
+#endif
+
+// We don't support MSVC 7.1 with exceptions disabled now.  Therefore
+// all the compilers we care about are adequate for supporting
+// value-parameterized tests.
+#define GTEST_HAS_PARAM_TEST 1
+
+// Determines whether to support type-driven tests.
+
+// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
+// Sun Pro CC, and IBM Visual Age support.
+#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \
+    defined(__IBMCPP__)
+#define GTEST_HAS_TYPED_TEST 1
+#define GTEST_HAS_TYPED_TEST_P 1
+#endif
+
+// Determines whether to support Combine(). This only makes sense when
+// value-parameterized tests are enabled.  The implementation doesn't
+// work on Sun Studio since it doesn't understand templated conversion
+// operators.
+#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)
+#define GTEST_HAS_COMBINE 1
+#endif
+
+// Determines whether the system compiler uses UTF-16 for encoding wide strings.
+#define GTEST_WIDE_STRING_USES_UTF16_ \
+    (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX)
+
+// 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_;
+//
+// Also use it after a variable or parameter declaration to tell the
+// compiler the variable/parameter does not have to be used.
+#if defined(__GNUC__) && !defined(COMPILER_ICC)
+#define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused))
+#else
+#define GTEST_ATTRIBUTE_UNUSED_
+#endif
+
+// A macro to disallow operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_ASSIGN_(type)\
+  void operator=(type const &)
+
+// A macro to disallow copy constructor and operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\
+  type(type const &);\
+  GTEST_DISALLOW_ASSIGN_(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__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC)
+#define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result))
+#else
+#define GTEST_MUST_USE_RESULT_
+#endif  // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC
+
+// Determine whether the compiler supports Microsoft's Structured Exception
+// Handling.  This is supported by several Windows compilers but generally
+// does not exist on any other system.
+#ifndef GTEST_HAS_SEH
+// The user didn't tell us, so we need to figure it out.
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// These two compilers are known to support SEH.
+#define GTEST_HAS_SEH 1
+#else
+// Assume no SEH.
+#define GTEST_HAS_SEH 0
+#endif
+
+#endif  // GTEST_HAS_SEH
+
+#ifdef _MSC_VER
+
+#if GTEST_LINKED_AS_SHARED_LIBRARY
+#define GTEST_API_ __declspec(dllimport)
+#elif GTEST_CREATE_SHARED_LIBRARY
+#define GTEST_API_ __declspec(dllexport)
+#endif
+
+#endif  // _MSC_VER
+
+#ifndef GTEST_API_
+#define GTEST_API_
+#endif
+
+namespace testing {
+
+class Message;
+
+namespace internal {
+
+class String;
+
+typedef ::std::stringstream StrStream;
+
+// A helper for suppressing warnings on constant condition.  It just
+// returns 'condition'.
+GTEST_API_ bool IsTrue(bool condition);
+
+// 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:
+  typedef T element_type;
+
+  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 (IsTrue(sizeof(T) > 0)) {  // Makes sure T is a complete type.
+        delete ptr_;
+      }
+      ptr_ = p;
+    }
+  }
+ private:
+  T* ptr_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr);
+};
+
+// Defines RE.
+
+// A simple C++ wrapper for <regex.h>.  It uses the POSIX Extended
+// Regular Expression syntax.
+class GTEST_API_ RE {
+ public:
+  // A copy constructor is required by the Standard to initialize object
+  // references from r-values.
+  RE(const RE& other) { Init(other.pattern()); }
+
+  // Constructs an RE from a string.
+  RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT
+
+#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_; }
+
+  // FullMatch(str, re) returns true iff regular expression re matches
+  // the entire str.
+  // PartialMatch(str, re) returns true iff regular expression re
+  // matches a substring of str (including str itself).
+  //
+  // TODO(wan@google.com): make FullMatch() and PartialMatch() work
+  // when str contains NUL characters.
+  static bool FullMatch(const ::std::string& str, const RE& re) {
+    return FullMatch(str.c_str(), re);
+  }
+  static bool PartialMatch(const ::std::string& str, const RE& re) {
+    return PartialMatch(str.c_str(), re);
+  }
+
+#if GTEST_HAS_GLOBAL_STRING
+  static bool FullMatch(const ::string& str, const RE& re) {
+    return FullMatch(str.c_str(), re);
+  }
+  static bool PartialMatch(const ::string& str, const RE& re) {
+    return PartialMatch(str.c_str(), re);
+  }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  static bool FullMatch(const char* str, const RE& re);
+  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_;
+  bool is_valid_;
+#if GTEST_USES_POSIX_RE
+  regex_t full_regex_;     // For FullMatch().
+  regex_t partial_regex_;  // For PartialMatch().
+#else  // GTEST_USES_SIMPLE_RE
+  const char* full_pattern_;  // For FullMatch();
+#endif
+
+  GTEST_DISALLOW_ASSIGN_(RE);
+};
+
+// Defines logging utilities:
+//   GTEST_LOG_(severity) - logs messages at the specified severity level. The
+//                          message itself is streamed into the macro.
+//   LogToStderr()  - directs all log messages to stderr.
+//   FlushInfoLog() - flushes informational log messages.
+
+enum GTestLogSeverity {
+  GTEST_INFO,
+  GTEST_WARNING,
+  GTEST_ERROR,
+  GTEST_FATAL
+};
+
+// Formats log entry severity, provides a stream object for streaming the
+// log message, and terminates the message with a newline when going out of
+// scope.
+class GTEST_API_ GTestLog {
+ public:
+  GTestLog(GTestLogSeverity severity, const char* file, int line);
+
+  // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+  ~GTestLog();
+
+  ::std::ostream& GetStream() { return ::std::cerr; }
+
+ private:
+  const GTestLogSeverity severity_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog);
+};
+
+#define GTEST_LOG_(severity) \
+    ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
+                                  __FILE__, __LINE__).GetStream()
+
+inline void LogToStderr() {}
+inline void FlushInfoLog() { fflush(NULL); }
+
+// INTERNAL IMPLEMENTATION - DO NOT USE.
+//
+// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
+// is not satisfied.
+//  Synopsys:
+//    GTEST_CHECK_(boolean_condition);
+//     or
+//    GTEST_CHECK_(boolean_condition) << "Additional message";
+//
+//    This checks the condition and if the condition is not satisfied
+//    it prints message about the condition violation, including the
+//    condition itself, plus additional message streamed into it, if any,
+//    and then it aborts the program. It aborts the program irrespective of
+//    whether it is built in the debug mode or not.
+#define GTEST_CHECK_(condition) \
+    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+    if (::testing::internal::IsTrue(condition)) \
+      ; \
+    else \
+      GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
+
+// An all-mode assert to verify that the given POSIX-style function
+// call returns 0 (indicating success).  Known limitation: this
+// doesn't expand to a balanced 'if' statement, so enclose the macro
+// in {} if you need to use it as the only statement in an 'if'
+// branch.
+#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \
+  if (const int gtest_error = (posix_call)) \
+    GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
+                      << gtest_error
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Downcasts the pointer of type Base to Derived.
+// Derived must be a subclass of Base. The parameter MUST
+// point to a class of type Derived, not any subclass of it.
+// When RTTI is available, the function performs a runtime
+// check to enforce this.
+template <class Derived, class Base>
+Derived* CheckedDowncastToActualType(Base* base) {
+#if GTEST_HAS_RTTI
+  GTEST_CHECK_(typeid(*base) == typeid(Derived));
+  return dynamic_cast<Derived*>(base);  // NOLINT
+#else
+  return static_cast<Derived*>(base);  // Poor man's downcast.
+#endif
+}
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+
+// Defines the stderr capturer:
+//   CaptureStdout     - starts capturing stdout.
+//   GetCapturedStdout - stops capturing stdout and returns the captured string.
+//   CaptureStderr     - starts capturing stderr.
+//   GetCapturedStderr - stops capturing stderr and returns the captured string.
+//
+GTEST_API_ void CaptureStdout();
+GTEST_API_ String GetCapturedStdout();
+GTEST_API_ void CaptureStderr();
+GTEST_API_ String GetCapturedStderr();
+
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
+
+#if GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments.  Set by InitGoogleTest().
+extern ::std::vector<String> g_argvs;
+
+// GTEST_HAS_DEATH_TEST implies we have ::std::string.
+const ::std::vector<String>& GetArgvs();
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Defines synchronization primitives.
+
+#if GTEST_HAS_PTHREAD
+
+// Sleeps for (roughly) n milli-seconds.  This function is only for
+// testing Google Test's own constructs.  Don't use it in user tests,
+// either directly or indirectly.
+inline void SleepMilliseconds(int n) {
+  const timespec time = {
+    0,                  // 0 seconds.
+    n * 1000L * 1000L,  // And n ms.
+  };
+  nanosleep(&time, NULL);
+}
+
+// Allows a controller thread to pause execution of newly created
+// threads until notified.  Instances of this class must be created
+// and destroyed in the controller thread.
+//
+// This class is only for testing Google Test's own constructs. Do not
+// use it in user tests, either directly or indirectly.
+class Notification {
+ public:
+  Notification() : notified_(false) {}
+
+  // Notifies all threads created with this notification to start. Must
+  // be called from the controller thread.
+  void Notify() { notified_ = true; }
+
+  // Blocks until the controller thread notifies. Must be called from a test
+  // thread.
+  void WaitForNotification() {
+    while(!notified_) {
+      SleepMilliseconds(10);
+    }
+  }
+
+ private:
+  volatile bool notified_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
+};
+
+// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.
+// Consequently, it cannot select a correct instantiation of ThreadWithParam
+// in order to call its Run(). Introducing ThreadWithParamBase as a
+// non-templated base class for ThreadWithParam allows us to bypass this
+// problem.
+class ThreadWithParamBase {
+ public:
+  virtual ~ThreadWithParamBase() {}
+  virtual void Run() = 0;
+};
+
+// pthread_create() accepts a pointer to a function type with the C linkage.
+// According to the Standard (7.5/1), function types with different linkages
+// are different even if they are otherwise identical.  Some compilers (for
+// example, SunStudio) treat them as different types.  Since class methods
+// cannot be defined with C-linkage we need to define a free C-function to
+// pass into pthread_create().
+extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
+  static_cast<ThreadWithParamBase*>(thread)->Run();
+  return NULL;
+}
+
+// Helper class for testing Google Test's multi-threading constructs.
+// To use it, write:
+//
+//   void ThreadFunc(int param) { /* Do things with param */ }
+//   Notification thread_can_start;
+//   ...
+//   // The thread_can_start parameter is optional; you can supply NULL.
+//   ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);
+//   thread_can_start.Notify();
+//
+// These classes are only for testing Google Test's own constructs. Do
+// not use them in user tests, either directly or indirectly.
+template <typename T>
+class ThreadWithParam : public ThreadWithParamBase {
+ public:
+  typedef void (*UserThreadFunc)(T);
+
+  ThreadWithParam(
+      UserThreadFunc func, T param, Notification* thread_can_start)
+      : func_(func),
+        param_(param),
+        thread_can_start_(thread_can_start),
+        finished_(false) {
+    ThreadWithParamBase* const base = this;
+    // The thread can be created only after all fields except thread_
+    // have been initialized.
+    GTEST_CHECK_POSIX_SUCCESS_(
+        pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base));
+  }
+  ~ThreadWithParam() { Join(); }
+
+  void Join() {
+    if (!finished_) {
+      GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
+      finished_ = true;
+    }
+  }
+
+  virtual void Run() {
+    if (thread_can_start_ != NULL)
+      thread_can_start_->WaitForNotification();
+    func_(param_);
+  }
+
+ private:
+  const UserThreadFunc func_;  // User-supplied thread function.
+  const T param_;  // User-supplied parameter to the thread function.
+  // When non-NULL, used to block execution until the controller thread
+  // notifies.
+  Notification* const thread_can_start_;
+  bool finished_;  // true iff we know that the thread function has finished.
+  pthread_t thread_;  // The native thread object.
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
+};
+
+// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is
+// true.
+#include <pthread.h>
+
+// MutexBase and Mutex implement mutex on pthreads-based platforms. They
+// are used in conjunction with class MutexLock:
+//
+//   Mutex mutex;
+//   ...
+//   MutexLock lock(&mutex);  // Acquires the mutex and releases it at the end
+//                            // of the current scope.
+//
+// MutexBase implements behavior for both statically and dynamically
+// allocated mutexes.  Do not use MutexBase directly.  Instead, write
+// the following to define a static mutex:
+//
+//   GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
+//
+// You can forward declare a static mutex like this:
+//
+//   GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
+//
+// To create a dynamic mutex, just define an object of type Mutex.
+class MutexBase {
+ public:
+  // Acquires this mutex.
+  void Lock() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
+    owner_ = pthread_self();
+  }
+
+  // Releases this mutex.
+  void Unlock() {
+    // We don't protect writing to owner_ here, as it's the caller's
+    // responsibility to ensure that the current thread holds the
+    // mutex when this is called.
+    owner_ = 0;
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
+  }
+
+  // Does nothing if the current thread holds the mutex. Otherwise, crashes
+  // with high probability.
+  void AssertHeld() const {
+    GTEST_CHECK_(owner_ == pthread_self())
+        << "The current thread is not holding the mutex @" << this;
+  }
+
+  // A static mutex may be used before main() is entered.  It may even
+  // be used before the dynamic initialization stage.  Therefore we
+  // must be able to initialize a static mutex object at link time.
+  // This means MutexBase has to be a POD and its member variables
+  // have to be public.
+ public:
+  pthread_mutex_t mutex_;  // The underlying pthread mutex.
+  pthread_t owner_;  // The thread holding the mutex; 0 means no one holds it.
+};
+
+// Forward-declares a static mutex.
+#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+    extern ::testing::internal::MutexBase mutex
+
+// Defines and statically (i.e. at link time) initializes a static mutex.
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
+    ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }
+
+// The Mutex class can only be used for mutexes created at runtime. It
+// shares its API with MutexBase otherwise.
+class Mutex : public MutexBase {
+ public:
+  Mutex() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
+    owner_ = 0;
+  }
+  ~Mutex() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
+};
+
+// We cannot name this class MutexLock 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(MutexBase* mutex)
+      : mutex_(mutex) { mutex_->Lock(); }
+
+  ~GTestMutexLock() { mutex_->Unlock(); }
+
+ private:
+  MutexBase* const mutex_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock);
+};
+
+typedef GTestMutexLock MutexLock;
+
+// Helpers for ThreadLocal.
+
+// pthread_key_create() requires DeleteThreadLocalValue() to have
+// C-linkage.  Therefore it cannot be templatized to access
+// ThreadLocal<T>.  Hence the need for class
+// ThreadLocalValueHolderBase.
+class ThreadLocalValueHolderBase {
+ public:
+  virtual ~ThreadLocalValueHolderBase() {}
+};
+
+// Called by pthread to delete thread-local data stored by
+// pthread_setspecific().
+extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
+  delete static_cast<ThreadLocalValueHolderBase*>(value_holder);
+}
+
+// Implements thread-local storage on pthreads-based systems.
+//
+//   // Thread 1
+//   ThreadLocal<int> tl(100);  // 100 is the default value for each thread.
+//
+//   // Thread 2
+//   tl.set(150);  // Changes the value for thread 2 only.
+//   EXPECT_EQ(150, tl.get());
+//
+//   // Thread 1
+//   EXPECT_EQ(100, tl.get());  // In thread 1, tl has the original value.
+//   tl.set(200);
+//   EXPECT_EQ(200, tl.get());
+//
+// The template type argument T must have a public copy constructor.
+// In addition, the default ThreadLocal constructor requires T to have
+// a public default constructor.
+//
+// An object managed for a thread by a ThreadLocal instance is deleted
+// when the thread exits.  Or, if the ThreadLocal instance dies in
+// that thread, when the ThreadLocal dies.  It's the user's
+// responsibility to ensure that all other threads using a ThreadLocal
+// have exited when it dies, or the per-thread objects for those
+// threads will not be deleted.
+//
+// Google Test only uses global ThreadLocal objects.  That means they
+// will die after main() has returned.  Therefore, no per-thread
+// object managed by Google Test will be leaked as long as all threads
+// using Google Test have exited when main() returns.
+template <typename T>
+class ThreadLocal {
+ public:
+  ThreadLocal() : key_(CreateKey()),
+                  default_() {}
+  explicit ThreadLocal(const T& value) : key_(CreateKey()),
+                                         default_(value) {}
+
+  ~ThreadLocal() {
+    // Destroys the managed object for the current thread, if any.
+    DeleteThreadLocalValue(pthread_getspecific(key_));
+
+    // Releases resources associated with the key.  This will *not*
+    // delete managed objects for other threads.
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));
+  }
+
+  T* pointer() { return GetOrCreateValue(); }
+  const T* pointer() const { return GetOrCreateValue(); }
+  const T& get() const { return *pointer(); }
+  void set(const T& value) { *pointer() = value; }
+
+ private:
+  // Holds a value of type T.
+  class ValueHolder : public ThreadLocalValueHolderBase {
+   public:
+    explicit ValueHolder(const T& value) : value_(value) {}
+
+    T* pointer() { return &value_; }
+
+   private:
+    T value_;
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);
+  };
+
+  static pthread_key_t CreateKey() {
+    pthread_key_t key;
+    // When a thread exits, DeleteThreadLocalValue() will be called on
+    // the object managed for that thread.
+    GTEST_CHECK_POSIX_SUCCESS_(
+        pthread_key_create(&key, &DeleteThreadLocalValue));
+    return key;
+  }
+
+  T* GetOrCreateValue() const {
+    ThreadLocalValueHolderBase* const holder =
+        static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));
+    if (holder != NULL) {
+      return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
+    }
+
+    ValueHolder* const new_holder = new ValueHolder(default_);
+    ThreadLocalValueHolderBase* const holder_base = new_holder;
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));
+    return new_holder->pointer();
+  }
+
+  // A key pthreads uses for looking up per-thread values.
+  const pthread_key_t key_;
+  const T default_;  // The default value for each thread.
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
+};
+
+#define GTEST_IS_THREADSAFE 1
+
+#else  // GTEST_HAS_PTHREAD
+
+// 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() {}
+  void AssertHeld() const {}
+};
+
+#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+  extern ::testing::internal::Mutex mutex
+
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex
+
+class GTestMutexLock {
+ public:
+  explicit GTestMutexLock(Mutex*) {}  // NOLINT
+};
+
+typedef GTestMutexLock MutexLock;
+
+template <typename T>
+class ThreadLocal {
+ public:
+  ThreadLocal() : value_() {}
+  explicit ThreadLocal(const T& value) : value_(value) {}
+  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_;
+};
+
+// The above synchronization primitives have dummy implementations.
+// Therefore Google Test is not thread-safe.
+#define GTEST_IS_THREADSAFE 0
+
+#endif  // GTEST_HAS_PTHREAD
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+GTEST_API_ size_t GetThreadCount();
+
+// Passing non-POD classes through ellipsis (...) crashes the ARM
+// compiler and generates a warning in Sun Studio.  The Nokia Symbian
+// and the IBM XL C/C++ compiler try to instantiate a copy constructor
+// for objects passed through ellipsis (...), failing for uncopyable
+// objects.  We define this to ensure that only POD is passed through
+// ellipsis on these systems.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+#define GTEST_ELLIPSIS_NEEDS_POD_ 1
+#else
+#define GTEST_CAN_COMPARE_NULL 1
+#endif
+
+// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between
+// const T& and const T* in a function template.  These compilers
+// _can_ decide between class template specializations for T and T*,
+// so a tr1::type_traits-like is_pointer works.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__)
+#define GTEST_NEEDS_IS_POINTER_ 1
+#endif
+
+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 {};
+
+#if GTEST_OS_WINDOWS
+#define GTEST_PATH_SEP_ "\\"
+#define GTEST_HAS_ALT_PATH_SEP_ 1
+// The biggest signed integer type the compiler supports.
+typedef __int64 BiggestInt;
+#else
+#define GTEST_PATH_SEP_ "/"
+#define GTEST_HAS_ALT_PATH_SEP_ 0
+typedef long long BiggestInt;  // NOLINT
+#endif  // GTEST_OS_WINDOWS
+
+// The testing::internal::posix namespace holds wrappers for common
+// POSIX functions.  These wrappers hide the differences between
+// Windows/MSVC and POSIX systems.  Since some compilers define these
+// standard functions as macros, the wrapper cannot have the same name
+// as the wrapped function.
+
+namespace posix {
+
+// Functions with a different name on Windows.
+
+#if GTEST_OS_WINDOWS
+
+typedef struct _stat StatStruct;
+
+#ifdef __BORLANDC__
+inline int IsATTY(int fd) { return isatty(fd); }
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return stricmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return strdup(src); }
+#else  // !__BORLANDC__
+#if GTEST_OS_WINDOWS_MOBILE
+inline int IsATTY(int /* fd */) { return 0; }
+#else
+inline int IsATTY(int fd) { return _isatty(fd); }
+#endif  // GTEST_OS_WINDOWS_MOBILE
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return _stricmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return _strdup(src); }
+#endif  // __BORLANDC__
+
+#if GTEST_OS_WINDOWS_MOBILE
+inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
+// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this
+// time and thus not defined there.
+#else
+inline int FileNo(FILE* file) { return _fileno(file); }
+inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
+inline int RmDir(const char* dir) { return _rmdir(dir); }
+inline bool IsDir(const StatStruct& st) {
+  return (_S_IFDIR & st.st_mode) != 0;
+}
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#else
+
+typedef struct stat StatStruct;
+
+inline int FileNo(FILE* file) { return fileno(file); }
+inline int IsATTY(int fd) { return isatty(fd); }
+inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return strcasecmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return strdup(src); }
+inline int RmDir(const char* dir) { return rmdir(dir); }
+inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
+
+#endif  // GTEST_OS_WINDOWS
+
+// Functions deprecated by MSVC 8.0.
+
+#ifdef _MSC_VER
+// Temporarily disable warning 4996 (deprecated function).
+#pragma warning(push)
+#pragma warning(disable:4996)
+#endif
+
+inline const char* StrNCpy(char* dest, const char* src, size_t n) {
+  return strncpy(dest, src, n);
+}
+
+// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
+// StrError() aren't needed on Windows CE at this time and thus not
+// defined there.
+
+#if !GTEST_OS_WINDOWS_MOBILE
+inline int ChDir(const char* dir) { return chdir(dir); }
+#endif
+inline FILE* FOpen(const char* path, const char* mode) {
+  return fopen(path, mode);
+}
+#if !GTEST_OS_WINDOWS_MOBILE
+inline FILE *FReopen(const char* path, const char* mode, FILE* stream) {
+  return freopen(path, mode, stream);
+}
+inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
+#endif
+inline int FClose(FILE* fp) { return fclose(fp); }
+#if !GTEST_OS_WINDOWS_MOBILE
+inline int Read(int fd, void* buf, unsigned int count) {
+  return static_cast<int>(read(fd, buf, count));
+}
+inline int Write(int fd, const void* buf, unsigned int count) {
+  return static_cast<int>(write(fd, buf, count));
+}
+inline int Close(int fd) { return close(fd); }
+inline const char* StrError(int errnum) { return strerror(errnum); }
+#endif
+inline const char* GetEnv(const char* name) {
+#if GTEST_OS_WINDOWS_MOBILE
+  // We are on Windows CE, which has no environment variables.
+  return NULL;
+#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
+  // Environment variables which we programmatically clear will be set to the
+  // empty string rather than unset (NULL).  Handle that case.
+  const char* const env = getenv(name);
+  return (env != NULL && env[0] != '\0') ? env : NULL;
+#else
+  return getenv(name);
+#endif
+}
+
+#ifdef _MSC_VER
+#pragma warning(pop)  // Restores the warning state.
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+// 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.
+void Abort();
+#else
+inline void Abort() { abort(); }
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+}  // namespace posix
+
+// 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:
+#if 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.
+
+// Macro for referencing flags.
+#define GTEST_FLAG(name) FLAGS_gtest_##name
+
+// Macros for declaring flags.
+#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
+#define GTEST_DECLARE_int32_(name) \
+    GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
+#define GTEST_DECLARE_string_(name) \
+    GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name)
+
+// Macros for defining flags.
+#define GTEST_DEFINE_bool_(name, default_val, doc) \
+    GTEST_API_ bool GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_int32_(name, default_val, doc) \
+    GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_string_(name, default_val, doc) \
+    GTEST_API_ ::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);
+GTEST_API_ 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_
+
+#if GTEST_OS_LINUX
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#endif  // GTEST_OS_LINUX
+
+#include <ctype.h>
+#include <string.h>
+#include <iomanip>
+#include <limits>
+#include <set>
+
+// 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 <gtest/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_
+
+#ifdef __BORLANDC__
+// string.h is not guaranteed to provide strcpy on C++ Builder.
+#include <mem.h>
+#endif
+
+#include <string.h>
+
+#include <string>
+
+namespace testing {
+namespace internal {
+
+// String - a UTF-8 string class.
+//
+// For historic reasons, we don't use std::string.
+//
+// TODO(wan@google.com): replace this class with std::string or
+// implement it in terms of the latter.
+//
+// Note that String 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 GTEST_API_ String {
+ public:
+  // Static utility methods
+
+  // 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);
+
+#if GTEST_OS_WINDOWS_MOBILE
+  // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
+  // able to pass strings to Win32 APIs on CE we need to convert them
+  // to 'Unicode', UTF-16.
+
+  // Creates a UTF-16 wide string from the given ANSI string, allocating
+  // memory using new. The caller is responsible for deleting the return
+  // value using delete[]. Returns the wide string, or NULL if the
+  // input is NULL.
+  //
+  // The wide string is created using the ANSI codepage (CP_ACP) to
+  // match the behaviour of the ANSI versions of Win32 calls and the
+  // C runtime.
+  static LPCWSTR AnsiToUtf16(const char* c_str);
+
+  // Creates an ANSI string from the given wide string, allocating
+  // memory using new. The caller is responsible for deleting the return
+  // value using delete[]. Returns the ANSI string, or NULL if the
+  // input is NULL.
+  //
+  // The returned string is created using the ANSI codepage (CP_ACP) to
+  // match the behaviour of the ANSI versions of Win32 calls and the
+  // C runtime.
+  static const char* Utf16ToAnsi(LPCWSTR utf16_str);
+#endif
+
+  // 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);
+
+  // Compares two wide C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike wcscasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL wide C string,
+  // including the empty string.
+  // NB: The implementations on different platforms slightly differ.
+  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+  // environment variable. On GNU platform this method uses wcscasecmp
+  // which compares according to LC_CTYPE category of the current locale.
+  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+  // current locale.
+  static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
+                                               const wchar_t* 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), length_(0) {}
+
+  // Constructs a String by cloning a 0-terminated C string.
+  String(const char* a_c_str) {  // NOLINT
+    if (a_c_str == NULL) {
+      c_str_ = NULL;
+      length_ = 0;
+    } else {
+      ConstructNonNull(a_c_str, strlen(a_c_str));
+    }
+  }
+
+  // Constructs a String by copying a given number of chars from a
+  // buffer.  E.g. String("hello", 3) creates the string "hel",
+  // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "",
+  // and String(NULL, 1) results in access violation.
+  String(const char* buffer, size_t a_length) {
+    ConstructNonNull(buffer, a_length);
+  }
+
+  // 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), length_(0) { *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_; }
+
+  // Allows a String to be implicitly converted to an ::std::string or
+  // ::string, and vice versa.  Converting a String containing a NULL
+  // pointer to ::std::string or ::string is undefined behavior.
+  // Converting a ::std::string or ::string containing an embedded NUL
+  // character to a String will result in the prefix up to the first
+  // NUL character.
+  String(const ::std::string& str) {
+    ConstructNonNull(str.c_str(), str.length());
+  }
+
+  operator ::std::string() const { return ::std::string(c_str(), length()); }
+
+#if GTEST_HAS_GLOBAL_STRING
+  String(const ::string& str) {
+    ConstructNonNull(str.c_str(), str.length());
+  }
+
+  operator ::string() const { return ::string(c_str(), length()); }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  // Returns true iff this is an empty string (i.e. "").
+  bool empty() const { return (c_str() != NULL) && (length() == 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* a_c_str) const { return Compare(a_c_str) == 0; }
+
+  // Returns true iff this String is less than the given String.  A
+  // NULL string is considered less than "".
+  bool operator<(const String& rhs) const { return Compare(rhs) < 0; }
+
+  // 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* a_c_str) const { return !(*this == a_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 0 if the
+  // string is NULL.
+  size_t length() const { return length_; }
+
+  // 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_; }
+
+  // Assigns a C string to this object.  Self-assignment works.
+  const String& operator=(const char* a_c_str) {
+    return *this = String(a_c_str);
+  }
+
+  // Assigns a String object to this object.  Self-assignment works.
+  const String& operator=(const String& rhs) {
+    if (this != &rhs) {
+      delete[] c_str_;
+      if (rhs.c_str() == NULL) {
+        c_str_ = NULL;
+        length_ = 0;
+      } else {
+        ConstructNonNull(rhs.c_str(), rhs.length());
+      }
+    }
+
+    return *this;
+  }
+
+ private:
+  // Constructs a non-NULL String from the given content.  This
+  // function can only be called when data_ has not been allocated.
+  // ConstructNonNull(NULL, 0) results in an empty string ("").
+  // ConstructNonNull(NULL, non_zero) is undefined behavior.
+  void ConstructNonNull(const char* buffer, size_t a_length) {
+    char* const str = new char[a_length + 1];
+    memcpy(str, buffer, a_length);
+    str[a_length] = '\0';
+    c_str_ = str;
+    length_ = a_length;
+  }
+
+  const char* c_str_;
+  size_t length_;
+};  // class String
+
+// Streams a String to an ostream.  Each '\0' character in the String
+// is replaced with "\\0".
+inline ::std::ostream& operator<<(::std::ostream& os, const String& str) {
+  if (str.c_str() == NULL) {
+    os << "(null)";
+  } else {
+    const char* const c_str = str.c_str();
+    for (size_t i = 0; i != str.length(); i++) {
+      if (c_str[i] == '\0') {
+        os << "\\0";
+      } else {
+        os << c_str[i];
+      }
+    }
+  }
+  return os;
+}
+
+// Gets the content of the StrStream's buffer as a String.  Each '\0'
+// character in the buffer is replaced with "\\0".
+GTEST_API_ 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_
+// 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 <gtest/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_
+
+
+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 GTEST_API_ FilePath {
+ public:
+  FilePath() : pathname_("") { }
+  FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
+
+  explicit FilePath(const char* pathname) : pathname_(pathname) {
+    Normalize();
+  }
+
+  explicit FilePath(const String& pathname) : pathname_(pathname) {
+    Normalize();
+  }
+
+  FilePath& operator=(const FilePath& rhs) {
+    Set(rhs);
+    return *this;
+  }
+
+  void Set(const FilePath& rhs) {
+    pathname_ = rhs.pathname_;
+  }
+
+  String ToString() const { return pathname_; }
+  const char* c_str() const { return pathname_.c_str(); }
+
+  // Returns the current working directory, or "" if unsuccessful.
+  static FilePath GetCurrentDir();
+
+  // 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);
+
+  // Given directory = "dir", relative_path = "test.xml",
+  // returns "dir/test.xml".
+  // On Windows, uses \ as the separator rather than /.
+  static FilePath ConcatPaths(const FilePath& directory,
+                              const FilePath& relative_path);
+
+  // 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);
+
+  // Returns true iff the path is NULL or "".
+  bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; }
+
+  // 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;
+
+  // Returns true if pathname describes a root directory. (Windows has one
+  // root directory per disk drive.)
+  bool IsRootDirectory() const;
+
+  // Returns true if pathname describes an absolute path.
+  bool IsAbsolutePath() const;
+
+ private:
+  // Replaces multiple consecutive separators with a single separator.
+  // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
+  // redundancies that might be in a pathname involving "." or "..".
+  //
+  // A pathname with multiple consecutive separators may occur either through
+  // user error or as a result of some scripts or APIs that generate a pathname
+  // with a trailing separator. On other platforms the same API or script
+  // may NOT generate a pathname with a trailing "/". Then elsewhere that
+  // pathname may have another "/" and pathname components added to it,
+  // without checking for the separator already being there.
+  // The script language and operating system may allow paths like "foo//bar"
+  // but some of the functions in FilePath will not handle that correctly. In
+  // particular, RemoveTrailingPathSeparator() only removes one separator, and
+  // it is called in CreateDirectoriesRecursively() assuming that it will change
+  // a pathname from directory syntax (trailing separator) to filename syntax.
+  //
+  // On Windows this method also replaces the alternate path separator '/' with
+  // the primary path separator '\\', so that for example "bar\\/\\foo" becomes
+  // "bar\\foo".
+
+  void Normalize();
+
+  // Returns a pointer to the last occurence of a valid path separator in
+  // the FilePath. On Windows, for example, both '/' and '\' are valid path
+  // separators. Returns NULL if no path separator was found.
+  const char* FindLastPathSeparator() const;
+
+  String pathname_;
+};  // class FilePath
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
+// This file was GENERATED by command:
+//     pump.py gtest-type-util.h.pump
+// DO NOT EDIT BY HAND!!!
+
+// 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)
+
+// Type utilities needed for implementing typed and type-parameterized
+// tests.  This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// Currently we support at most 50 types in a list, and at most 50
+// type-parameterized tests in one type-parameterized test case.
+// Please contact googletestframework@googlegroups.com if you need
+// more.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// #ifdef __GNUC__ is too general here.  It is possible to use gcc without using
+// libstdc++ (which is where cxxabi.h comes from).
+#ifdef __GLIBCXX__
+#include <cxxabi.h>
+#endif  // __GLIBCXX__
+
+namespace testing {
+namespace internal {
+
+// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
+// type.  This can be used as a compile-time assertion to ensure that
+// two types are equal.
+
+template <typename T1, typename T2>
+struct AssertTypeEq;
+
+template <typename T>
+struct AssertTypeEq<T, T> {
+  typedef bool type;
+};
+
+// GetTypeName<T>() returns a human-readable name of type T.
+template <typename T>
+String GetTypeName() {
+#if GTEST_HAS_RTTI
+
+  const char* const name = typeid(T).name();
+#ifdef __GLIBCXX__
+  int status = 0;
+  // gcc's implementation of typeid(T).name() mangles the type name,
+  // so we have to demangle it.
+  char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status);
+  const String name_str(status == 0 ? readable_name : name);
+  free(readable_name);
+  return name_str;
+#else
+  return name;
+#endif  // __GLIBCXX__
+
+#else
+  return "<type>";
+#endif  // GTEST_HAS_RTTI
+}
+
+// A unique type used as the default value for the arguments of class
+// template Types.  This allows us to simulate variadic templates
+// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
+// support directly.
+struct None {};
+
+// The following family of struct and struct templates are used to
+// represent type lists.  In particular, TypesN<T1, T2, ..., TN>
+// represents a type list with N types (T1, T2, ..., and TN) in it.
+// Except for Types0, every struct in the family has two member types:
+// Head for the first type in the list, and Tail for the rest of the
+// list.
+
+// The empty type list.
+struct Types0 {};
+
+// Type lists of length 1, 2, 3, and so on.
+
+template <typename T1>
+struct Types1 {
+  typedef T1 Head;
+  typedef Types0 Tail;
+};
+template <typename T1, typename T2>
+struct Types2 {
+  typedef T1 Head;
+  typedef Types1<T2> Tail;
+};
+
+template <typename T1, typename T2, typename T3>
+struct Types3 {
+  typedef T1 Head;
+  typedef Types2<T2, T3> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+struct Types4 {
+  typedef T1 Head;
+  typedef Types3<T2, T3, T4> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+struct Types5 {
+  typedef T1 Head;
+  typedef Types4<T2, T3, T4, T5> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+struct Types6 {
+  typedef T1 Head;
+  typedef Types5<T2, T3, T4, T5, T6> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+struct Types7 {
+  typedef T1 Head;
+  typedef Types6<T2, T3, T4, T5, T6, T7> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+struct Types8 {
+  typedef T1 Head;
+  typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+struct Types9 {
+  typedef T1 Head;
+  typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+struct Types10 {
+  typedef T1 Head;
+  typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+struct Types11 {
+  typedef T1 Head;
+  typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+struct Types12 {
+  typedef T1 Head;
+  typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+struct Types13 {
+  typedef T1 Head;
+  typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+struct Types14 {
+  typedef T1 Head;
+  typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+struct Types15 {
+  typedef T1 Head;
+  typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+struct Types16 {
+  typedef T1 Head;
+  typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+struct Types17 {
+  typedef T1 Head;
+  typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+struct Types18 {
+  typedef T1 Head;
+  typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+struct Types19 {
+  typedef T1 Head;
+  typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+struct Types20 {
+  typedef T1 Head;
+  typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+struct Types21 {
+  typedef T1 Head;
+  typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+struct Types22 {
+  typedef T1 Head;
+  typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+struct Types23 {
+  typedef T1 Head;
+  typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+struct Types24 {
+  typedef T1 Head;
+  typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+struct Types25 {
+  typedef T1 Head;
+  typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+struct Types26 {
+  typedef T1 Head;
+  typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+struct Types27 {
+  typedef T1 Head;
+  typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+struct Types28 {
+  typedef T1 Head;
+  typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+struct Types29 {
+  typedef T1 Head;
+  typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+struct Types30 {
+  typedef T1 Head;
+  typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+struct Types31 {
+  typedef T1 Head;
+  typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+struct Types32 {
+  typedef T1 Head;
+  typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+struct Types33 {
+  typedef T1 Head;
+  typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+struct Types34 {
+  typedef T1 Head;
+  typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+struct Types35 {
+  typedef T1 Head;
+  typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+struct Types36 {
+  typedef T1 Head;
+  typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+struct Types37 {
+  typedef T1 Head;
+  typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+struct Types38 {
+  typedef T1 Head;
+  typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+struct Types39 {
+  typedef T1 Head;
+  typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+struct Types40 {
+  typedef T1 Head;
+  typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+struct Types41 {
+  typedef T1 Head;
+  typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+struct Types42 {
+  typedef T1 Head;
+  typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+struct Types43 {
+  typedef T1 Head;
+  typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+struct Types44 {
+  typedef T1 Head;
+  typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+struct Types45 {
+  typedef T1 Head;
+  typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+struct Types46 {
+  typedef T1 Head;
+  typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+struct Types47 {
+  typedef T1 Head;
+  typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+struct Types48 {
+  typedef T1 Head;
+  typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+struct Types49 {
+  typedef T1 Head;
+  typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48, T49> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+struct Types50 {
+  typedef T1 Head;
+  typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48, T49, T50> Tail;
+};
+
+
+}  // namespace internal
+
+// We don't want to require the users to write TypesN<...> directly,
+// as that would require them to count the length.  Types<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Types<int>
+// will appear as Types<int, None, None, ..., None> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Types<T1, ..., TN>, and Google Test will translate
+// that to TypesN<T1, ..., TN> internally to make error messages
+// readable.  The translation is done by the 'type' member of the
+// Types template.
+template <typename T1 = internal::None, typename T2 = internal::None,
+    typename T3 = internal::None, typename T4 = internal::None,
+    typename T5 = internal::None, typename T6 = internal::None,
+    typename T7 = internal::None, typename T8 = internal::None,
+    typename T9 = internal::None, typename T10 = internal::None,
+    typename T11 = internal::None, typename T12 = internal::None,
+    typename T13 = internal::None, typename T14 = internal::None,
+    typename T15 = internal::None, typename T16 = internal::None,
+    typename T17 = internal::None, typename T18 = internal::None,
+    typename T19 = internal::None, typename T20 = internal::None,
+    typename T21 = internal::None, typename T22 = internal::None,
+    typename T23 = internal::None, typename T24 = internal::None,
+    typename T25 = internal::None, typename T26 = internal::None,
+    typename T27 = internal::None, typename T28 = internal::None,
+    typename T29 = internal::None, typename T30 = internal::None,
+    typename T31 = internal::None, typename T32 = internal::None,
+    typename T33 = internal::None, typename T34 = internal::None,
+    typename T35 = internal::None, typename T36 = internal::None,
+    typename T37 = internal::None, typename T38 = internal::None,
+    typename T39 = internal::None, typename T40 = internal::None,
+    typename T41 = internal::None, typename T42 = internal::None,
+    typename T43 = internal::None, typename T44 = internal::None,
+    typename T45 = internal::None, typename T46 = internal::None,
+    typename T47 = internal::None, typename T48 = internal::None,
+    typename T49 = internal::None, typename T50 = internal::None>
+struct Types {
+  typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type;
+};
+
+template <>
+struct Types<internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types0 type;
+};
+template <typename T1>
+struct Types<T1, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types1<T1> type;
+};
+template <typename T1, typename T2>
+struct Types<T1, T2, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types2<T1, T2> type;
+};
+template <typename T1, typename T2, typename T3>
+struct Types<T1, T2, T3, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types3<T1, T2, T3> type;
+};
+template <typename T1, typename T2, typename T3, typename T4>
+struct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types4<T1, T2, T3, T4> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+struct Types<T1, T2, T3, T4, T5, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types5<T1, T2, T3, T4, T5> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+struct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types6<T1, T2, T3, T4, T5, T6> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+struct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, internal::None, internal::None, internal::None> {
+  typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, T48, internal::None, internal::None> {
+  typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, T48, T49, internal::None> {
+  typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49> type;
+};
+
+namespace internal {
+
+#define GTEST_TEMPLATE_ template <typename T> class
+
+// The template "selector" struct TemplateSel<Tmpl> is used to
+// represent Tmpl, which must be a class template with one type
+// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined
+// as the type Tmpl<T>.  This allows us to actually instantiate the
+// template "selected" by TemplateSel<Tmpl>.
+//
+// This trick is necessary for simulating typedef for class templates,
+// which C++ doesn't support directly.
+template <GTEST_TEMPLATE_ Tmpl>
+struct TemplateSel {
+  template <typename T>
+  struct Bind {
+    typedef Tmpl<T> type;
+  };
+};
+
+#define GTEST_BIND_(TmplSel, T) \
+  TmplSel::template Bind<T>::type
+
+// A unique struct template used as the default value for the
+// arguments of class template Templates.  This allows us to simulate
+// variadic templates (e.g. Templates<int>, Templates<int, double>,
+// and etc), which C++ doesn't support directly.
+template <typename T>
+struct NoneT {};
+
+// The following family of struct and struct templates are used to
+// represent template lists.  In particular, TemplatesN<T1, T2, ...,
+// TN> represents a list of N templates (T1, T2, ..., and TN).  Except
+// for Templates0, every struct in the family has two member types:
+// Head for the selector of the first template in the list, and Tail
+// for the rest of the list.
+
+// The empty template list.
+struct Templates0 {};
+
+// Template lists of length 1, 2, 3, and so on.
+
+template <GTEST_TEMPLATE_ T1>
+struct Templates1 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates0 Tail;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>
+struct Templates2 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates1<T2> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>
+struct Templates3 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates2<T2, T3> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4>
+struct Templates4 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates3<T2, T3, T4> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>
+struct Templates5 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates4<T2, T3, T4, T5> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>
+struct Templates6 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates5<T2, T3, T4, T5, T6> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7>
+struct Templates7 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates6<T2, T3, T4, T5, T6, T7> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>
+struct Templates8 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>
+struct Templates9 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10>
+struct Templates10 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>
+struct Templates11 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>
+struct Templates12 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13>
+struct Templates13 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>
+struct Templates14 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>
+struct Templates15 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16>
+struct Templates16 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>
+struct Templates17 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>
+struct Templates18 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19>
+struct Templates19 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>
+struct Templates20 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>
+struct Templates21 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22>
+struct Templates22 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>
+struct Templates23 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>
+struct Templates24 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25>
+struct Templates25 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>
+struct Templates26 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>
+struct Templates27 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28>
+struct Templates28 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>
+struct Templates29 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>
+struct Templates30 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31>
+struct Templates31 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>
+struct Templates32 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>
+struct Templates33 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34>
+struct Templates34 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>
+struct Templates35 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>
+struct Templates36 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37>
+struct Templates37 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>
+struct Templates38 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>
+struct Templates39 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40>
+struct Templates40 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>
+struct Templates41 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>
+struct Templates42 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43>
+struct Templates43 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>
+struct Templates44 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>
+struct Templates45 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46>
+struct Templates46 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>
+struct Templates47 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>
+struct Templates48 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49>
+struct Templates49 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48, T49> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50>
+struct Templates50 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48, T49, T50> Tail;
+};
+
+
+// We don't want to require the users to write TemplatesN<...> directly,
+// as that would require them to count the length.  Templates<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Templates<list>
+// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Templates<T1, ..., TN>, and Google Test will translate
+// that to TemplatesN<T1, ..., TN> internally to make error messages
+// readable.  The translation is done by the 'type' member of the
+// Templates template.
+template <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT,
+    GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT,
+    GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT,
+    GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT,
+    GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT,
+    GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT,
+    GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT,
+    GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT,
+    GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT,
+    GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT,
+    GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT,
+    GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT,
+    GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT,
+    GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT,
+    GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT,
+    GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT,
+    GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT,
+    GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT,
+    GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT,
+    GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT,
+    GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT,
+    GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT,
+    GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT,
+    GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT,
+    GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT>
+struct Templates {
+  typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48, T49, T50> type;
+};
+
+template <>
+struct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates0 type;
+};
+template <GTEST_TEMPLATE_ T1>
+struct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates1<T1> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>
+struct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates2<T1, T2> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>
+struct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates3<T1, T2, T3> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4>
+struct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates4<T1, T2, T3, T4> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>
+struct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates5<T1, T2, T3, T4, T5> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>
+struct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates6<T1, T2, T3, T4, T5, T6> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, NoneT, NoneT, NoneT> {
+  typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, T48, NoneT, NoneT> {
+  typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, T48, T49, NoneT> {
+  typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48, T49> type;
+};
+
+// The TypeList template makes it possible to use either a single type
+// or a Types<...> list in TYPED_TEST_CASE() and
+// INSTANTIATE_TYPED_TEST_CASE_P().
+
+template <typename T>
+struct TypeList { typedef Types1<T> type; };
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+struct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49, T50> > {
+  typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type;
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+
+// 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 AssertionResult;                 // Result of an assertion.
+class Message;                         // Represents a failure message.
+class Test;                            // Represents a test.
+class TestInfo;                        // Information about a test.
+class TestPartResult;                  // Result of a test part.
+class UnitTest;                        // A collection of test cases.
+
+namespace internal {
+
+struct TraceInfo;                      // Information about a trace point.
+class ScopedTrace;                     // Implements scoped trace.
+class TestInfoImpl;                    // Opaque implementation of TestInfo
+class UnitTestImpl;                    // Opaque implementation of UnitTest
+
+// How many times InitGoogleTest() has been called.
+extern int g_init_gtest_count;
+
+// The text used in failure messages to indicate the start of the
+// stack trace.
+GTEST_API_ extern const char kStackTraceMarker[];
+
+// 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 GTEST_ELLIPSIS_NEEDS_POD_
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+#define GTEST_IS_NULL_LITERAL_(x) false
+#else
+#define GTEST_IS_NULL_LITERAL_(x) \
+    (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)
+#endif  // GTEST_ELLIPSIS_NEEDS_POD_
+
+// Appends the user-supplied message to the Google-Test-generated message.
+GTEST_API_ String AppendUserMessage(const String& gtest_msg,
+                                    const Message& user_msg);
+
+// A helper class for creating scoped traces in user programs.
+class GTEST_API_ 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 GTEST_NEEDS_IS_POINTER_
+
+// These are needed as the Nokia Symbian and IBM XL C/C++ compilers
+// cannot decide between const T& and const T* in a function template.
+// These compilers _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
+
+// These are needed as the above solution using is_pointer has the
+// limitation that T cannot be a type without external linkage, when
+// compiled using MSVC.
+
+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  // GTEST_NEEDS_IS_POINTER_
+
+// These overloaded versions handle narrow and wide characters.
+GTEST_API_ String FormatForFailureMessage(char ch);
+GTEST_API_ 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);\
+}
+
+GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted)
+#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.
+GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
+                                     const char* actual_expression,
+                                     const String& expected_value,
+                                     const String& actual_value,
+                                     bool ignoring_case);
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+GTEST_API_ String GetBoolAssertionFailureMessage(
+    const AssertionResult& assertion_result,
+    const char* expression_text,
+    const char* actual_predicate_value,
+    const char* expected_predicate_value);
+
+// 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) { u_.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.u_.bits_ = bits;
+    return fp.u_.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 u_.bits_; }
+
+  // Returns the exponent bits of this number.
+  Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
+
+  // Returns the fraction bits of this number.
+  Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
+
+  // Returns the sign bit of this number.
+  Bits sign_bit() const { return kSignBitMask & u_.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(u_.bits_, rhs.u_.bits_)
+        <= kMaxUlps;
+  }
+
+ private:
+  // The data type used to store the actual floating-point number.
+  union FloatingPointUnion {
+    RawType value_;  // The raw floating-point number.
+    Bits bits_;      // The bits that represent the number.
+  };
+
+  // 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);
+  }
+
+  FloatingPointUnion u_;
+};
+
+// 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 const void* TypeId;
+
+template <typename T>
+class TypeIdHelper {
+ public:
+  // dummy_ must not have a const type.  Otherwise an overly eager
+  // compiler (e.g. MSVC 7.1 & 8.0) may try to merge
+  // TypeIdHelper<T>::dummy_ for different Ts as an "optimization".
+  static bool dummy_;
+};
+
+template <typename T>
+bool TypeIdHelper<T>::dummy_ = false;
+
+// 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>
+TypeId GetTypeId() {
+  // The compiler is required to allocate a different
+  // TypeIdHelper<T>::dummy_ variable for each T used to instantiate
+  // the template.  Therefore, the address of dummy_ is guaranteed to
+  // be unique.
+  return &(TypeIdHelper<T>::dummy_);
+}
+
+// Returns the type ID of ::testing::Test.  Always call this instead
+// of GetTypeId< ::testing::Test>() to get the type ID of
+// ::testing::Test, as the latter may give the wrong result due to a
+// suspected linker bug when compiling Google Test as a Mac OS X
+// framework.
+GTEST_API_ TypeId GetTestTypeId();
+
+// Defines the abstract factory interface that creates instances
+// of a Test object.
+class TestFactoryBase {
+ public:
+  virtual ~TestFactoryBase() {}
+
+  // Creates a test instance to run. The instance is both created and destroyed
+  // within TestInfoImpl::Run()
+  virtual Test* CreateTest() = 0;
+
+ protected:
+  TestFactoryBase() {}
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase);
+};
+
+// This class provides implementation of TeastFactoryBase interface.
+// It is used in TEST and TEST_F macros.
+template <class TestClass>
+class TestFactoryImpl : public TestFactoryBase {
+ public:
+  virtual Test* CreateTest() { return new TestClass; }
+};
+
+#if 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.
+GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,
+                                            long hr);  // NOLINT
+GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
+                                            long hr);  // NOLINT
+
+#endif  // GTEST_OS_WINDOWS
+
+// Formats a source file path and a line number as they would appear
+// in a compiler error message.
+inline String FormatFileLocation(const char* file, int line) {
+  const char* const file_name = file == NULL ? "unknown file" : file;
+  if (line < 0) {
+    return String::Format("%s:", file_name);
+  }
+#ifdef _MSC_VER
+  return String::Format("%s(%d):", file_name, line);
+#else
+  return String::Format("%s:%d:", file_name, line);
+#endif  // _MSC_VER
+}
+
+// Types of SetUpTestCase() and TearDownTestCase() functions.
+typedef void (*SetUpTestCaseFunc)();
+typedef void (*TearDownTestCaseFunc)();
+
+// Creates a new TestInfo object and registers it with Google Test;
+// returns the created object.
+//
+// Arguments:
+//
+//   test_case_name:   name of the test case
+//   name:             name of the test
+//   test_case_comment: a comment on the test case that will be included in
+//                      the test output
+//   comment:          a comment on the test that will be included in the
+//                     test output
+//   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
+//   factory:          pointer to the factory that creates a test object.
+//                     The newly created TestInfo instance will assume
+//                     ownership of the factory object.
+GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
+    const char* test_case_name, const char* name,
+    const char* test_case_comment, const char* comment,
+    TypeId fixture_class_id,
+    SetUpTestCaseFunc set_up_tc,
+    TearDownTestCaseFunc tear_down_tc,
+    TestFactoryBase* factory);
+
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false.  None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr);
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// State of the definition of a type-parameterized test case.
+class GTEST_API_ TypedTestCasePState {
+ public:
+  TypedTestCasePState() : registered_(false) {}
+
+  // Adds the given test name to defined_test_names_ and return true
+  // if the test case hasn't been registered; otherwise aborts the
+  // program.
+  bool AddTestName(const char* file, int line, const char* case_name,
+                   const char* test_name) {
+    if (registered_) {
+      fprintf(stderr, "%s Test %s must be defined before "
+              "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
+              FormatFileLocation(file, line).c_str(), test_name, case_name);
+      fflush(stderr);
+      posix::Abort();
+    }
+    defined_test_names_.insert(test_name);
+    return true;
+  }
+
+  // Verifies that registered_tests match the test names in
+  // defined_test_names_; returns registered_tests if successful, or
+  // aborts the program otherwise.
+  const char* VerifyRegisteredTestNames(
+      const char* file, int line, const char* registered_tests);
+
+ private:
+  bool registered_;
+  ::std::set<const char*> defined_test_names_;
+};
+
+// Skips to the first non-space char after the first comma in 'str';
+// returns NULL if no comma is found in 'str'.
+inline const char* SkipComma(const char* str) {
+  const char* comma = strchr(str, ',');
+  if (comma == NULL) {
+    return NULL;
+  }
+  while (isspace(*(++comma))) {}
+  return comma;
+}
+
+// Returns the prefix of 'str' before the first comma in it; returns
+// the entire string if it contains no comma.
+inline String GetPrefixUntilComma(const char* str) {
+  const char* comma = strchr(str, ',');
+  return comma == NULL ? String(str) : String(str, comma - str);
+}
+
+// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
+// registers a list of type-parameterized tests with Google Test.  The
+// return value is insignificant - we just need to return something
+// such that we can call this function in a namespace scope.
+//
+// Implementation note: The GTEST_TEMPLATE_ macro declares a template
+// template parameter.  It's defined in gtest-type-util.h.
+template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
+class TypeParameterizedTest {
+ public:
+  // 'index' is the index of the test in the type list 'Types'
+  // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
+  // Types).  Valid values for 'index' are [0, N - 1] where N is the
+  // length of Types.
+  static bool Register(const char* prefix, const char* case_name,
+                       const char* test_names, int index) {
+    typedef typename Types::Head Type;
+    typedef Fixture<Type> FixtureClass;
+    typedef typename GTEST_BIND_(TestSel, Type) TestClass;
+
+    // First, registers the first type-parameterized test in the type
+    // list.
+    MakeAndRegisterTestInfo(
+        String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/",
+                       case_name, index).c_str(),
+        GetPrefixUntilComma(test_names).c_str(),
+        String::Format("TypeParam = %s", GetTypeName<Type>().c_str()).c_str(),
+        "",
+        GetTypeId<FixtureClass>(),
+        TestClass::SetUpTestCase,
+        TestClass::TearDownTestCase,
+        new TestFactoryImpl<TestClass>);
+
+    // Next, recurses (at compile time) with the tail of the type list.
+    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
+        ::Register(prefix, case_name, test_names, index + 1);
+  }
+};
+
+// The base case for the compile time recursion.
+template <GTEST_TEMPLATE_ Fixture, class TestSel>
+class TypeParameterizedTest<Fixture, TestSel, Types0> {
+ public:
+  static bool Register(const char* /*prefix*/, const char* /*case_name*/,
+                       const char* /*test_names*/, int /*index*/) {
+    return true;
+  }
+};
+
+// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()
+// registers *all combinations* of 'Tests' and 'Types' with Google
+// Test.  The return value is insignificant - we just need to return
+// something such that we can call this function in a namespace scope.
+template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
+class TypeParameterizedTestCase {
+ public:
+  static bool Register(const char* prefix, const char* case_name,
+                       const char* test_names) {
+    typedef typename Tests::Head Head;
+
+    // First, register the first test in 'Test' for each type in 'Types'.
+    TypeParameterizedTest<Fixture, Head, Types>::Register(
+        prefix, case_name, test_names, 0);
+
+    // Next, recurses (at compile time) with the tail of the test list.
+    return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
+        ::Register(prefix, case_name, SkipComma(test_names));
+  }
+};
+
+// The base case for the compile time recursion.
+template <GTEST_TEMPLATE_ Fixture, typename Types>
+class TypeParameterizedTestCase<Fixture, Templates0, Types> {
+ public:
+  static bool Register(const char* /*prefix*/, const char* /*case_name*/,
+                       const char* /*test_names*/) {
+    return true;
+  }
+};
+
+#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// 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
+// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
+// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
+GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,
+                                                  int skip_count);
+
+// Helpers for suppressing warnings on unreachable code or constant
+// condition.
+
+// Always returns true.
+GTEST_API_ bool AlwaysTrue();
+
+// Always returns false.
+inline bool AlwaysFalse() { return !AlwaysTrue(); }
+
+// A simple Linear Congruential Generator for generating random
+// numbers with a uniform distribution.  Unlike rand() and srand(), it
+// doesn't use global state (and therefore can't interfere with user
+// code).  Unlike rand_r(), it's portable.  An LCG isn't very random,
+// but it's good enough for our purposes.
+class GTEST_API_ Random {
+ public:
+  static const UInt32 kMaxRange = 1u << 31;
+
+  explicit Random(UInt32 seed) : state_(seed) {}
+
+  void Reseed(UInt32 seed) { state_ = seed; }
+
+  // Generates a random number from [0, range).  Crashes if 'range' is
+  // 0 or greater than kMaxRange.
+  UInt32 Generate(UInt32 range);
+
+ private:
+  UInt32 state_;
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
+};
+
+}  // 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::TestPartResult::kFatalFailure)
+
+#define GTEST_NONFATAL_FAILURE_(message) \
+  GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
+
+#define GTEST_SUCCESS_(message) \
+  GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
+
+// Suppresses MSVC warnings 4072 (unreachable code) for the code following
+// statement if it returns or throws (or doesn't return or throw in some
+// situations).
+#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
+  if (::testing::internal::AlwaysTrue()) { statement; }
+
+#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    bool gtest_caught_expected = false; \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (expected_exception const&) { \
+      gtest_caught_expected = true; \
+    } \
+    catch (...) { \
+      gtest_msg = "Expected: " #statement " throws an exception of type " \
+                  #expected_exception ".\n  Actual: it throws a different " \
+                  "type."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
+    } \
+    if (!gtest_caught_expected) { \
+      gtest_msg = "Expected: " #statement " throws an exception of type " \
+                  #expected_exception ".\n  Actual: it throws nothing."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
+      fail(gtest_msg)
+
+#define GTEST_TEST_NO_THROW_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (...) { \
+      gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \
+                  "  Actual: it throws."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \
+      fail(gtest_msg)
+
+#define GTEST_TEST_ANY_THROW_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    bool gtest_caught_any = false; \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (...) { \
+      gtest_caught_any = true; \
+    } \
+    if (!gtest_caught_any) { \
+      gtest_msg = "Expected: " #statement " throws an exception.\n" \
+                  "  Actual: it doesn't."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \
+      fail(gtest_msg)
+
+
+// Implements Boolean test assertions such as EXPECT_TRUE. expression can be
+// either a boolean expression or an AssertionResult. text is a textual
+// represenation of expression as it was passed into the EXPECT_TRUE.
+#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const ::testing::AssertionResult gtest_ar_ = \
+      ::testing::AssertionResult(expression)) \
+    ; \
+  else \
+    fail(::testing::internal::GetBoolAssertionFailureMessage(\
+        gtest_ar_, text, #actual, #expected).c_str())
+
+#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \
+    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
+      gtest_msg = "Expected: " #statement " doesn't generate new fatal " \
+                  "failures in the current thread.\n" \
+                  "  Actual: it does."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \
+      fail(gtest_msg)
+
+// Expands to the name of the class that implements the given test.
+#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+  test_case_name##_##test_name##_Test
+
+// Helper macro for defining tests.
+#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
+class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
+ public:\
+  GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
+ private:\
+  virtual void TestBody();\
+  static ::testing::TestInfo* const test_info_;\
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+      GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
+};\
+\
+::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
+  ::test_info_ =\
+    ::testing::internal::MakeAndRegisterTestInfo(\
+        #test_case_name, #test_name, "", "", \
+        (parent_id), \
+        parent_class::SetUpTestCase, \
+        parent_class::TearDownTestCase, \
+        new ::testing::internal::TestFactoryImpl<\
+            GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
+void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
+// 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_
+
+// 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_
+
+
+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 kDeathTestUseFork[] = "death_test_use_fork";
+const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
+
+#if 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 GTEST_API_ 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();
+
+  static void set_last_death_test_message(const String& message);
+
+ private:
+  // A string containing a description of the outcome of the last death test.
+  static String last_death_test_message_;
+
+  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.
+GTEST_API_ 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 (::testing::internal::AlwaysTrue()) { \
+    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); \
+          GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(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 class representing the parsed contents of the
+// --gtest_internal_run_death_test flag, as it existed when
+// RUN_ALL_TESTS was called.
+class InternalRunDeathTestFlag {
+ public:
+  InternalRunDeathTestFlag(const String& a_file,
+                           int a_line,
+                           int an_index,
+                           int a_write_fd)
+      : file_(a_file), line_(a_line), index_(an_index),
+        write_fd_(a_write_fd) {}
+
+  ~InternalRunDeathTestFlag() {
+    if (write_fd_ >= 0)
+      posix::Close(write_fd_);
+  }
+
+  String file() const { return file_; }
+  int line() const { return line_; }
+  int index() const { return index_; }
+  int write_fd() const { return write_fd_; }
+
+ private:
+  String file_;
+  int line_;
+  int index_;
+  int write_fd_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
+};
+
+// 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();
+
+#else  // GTEST_HAS_DEATH_TEST
+
+// This macro is used for implementing macros such as
+// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
+// death tests are not supported. Those macros must compile on such systems
+// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
+// systems that support death tests. This allows one to write such a macro
+// on a system that does not support death tests and be sure that it will
+// compile on a death-test supporting system.
+//
+// Parameters:
+//   statement -  A statement that a macro such as EXPECT_DEATH would test
+//                for program termination. This macro has to make sure this
+//                statement is compiled but not executed, to ensure that
+//                EXPECT_DEATH_IF_SUPPORTED compiles with a certain
+//                parameter iff EXPECT_DEATH compiles with it.
+//   regex     -  A regex that a macro such as EXPECT_DEATH would use to test
+//                the output of statement.  This parameter has to be
+//                compiled but not evaluated by this macro, to ensure that
+//                this macro only accepts expressions that a macro such as
+//                EXPECT_DEATH would accept.
+//   terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
+//                and a return statement for ASSERT_DEATH_IF_SUPPORTED.
+//                This ensures that ASSERT_DEATH_IF_SUPPORTED will not
+//                compile inside functions where ASSERT_DEATH doesn't
+//                compile.
+//
+//  The branch that has an always false condition is used to ensure that
+//  statement and regex are compiled (and thus syntactically correct) but
+//  never executed. The unreachable code macro protects the terminator
+//  statement from generating an 'unreachable code' warning in case
+//  statement unconditionally returns or throws. The Message constructor at
+//  the end allows the syntax of streaming additional messages into the
+//  macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
+#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
+    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+    if (::testing::internal::AlwaysTrue()) { \
+      GTEST_LOG_(WARNING) \
+          << "Death tests are not supported on this platform.\n" \
+          << "Statement '" #statement "' cannot be verified."; \
+    } else if (::testing::internal::AlwaysFalse()) { \
+      ::testing::internal::RE::PartialMatch(".*", (regex)); \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+      terminator; \
+    } else \
+      ::testing::Message()
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_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);
+
+#if 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. It generates a warning if there is more than one active
+//   thread.  This is because it's safe to fork() or clone() only
+//   when there is a single thread.
+//
+//   2. The parent process clone()s 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.
+//
+// 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!");
+//
+// On the regular expressions used in death tests:
+//
+//   On POSIX-compliant systems (*nix), we use the <regex.h> library,
+//   which uses the POSIX extended regex syntax.
+//
+//   On other platforms (e.g. Windows), we only support a simple regex
+//   syntax implemented as part of Google Test.  This limited
+//   implementation should be enough most of the time when writing
+//   death tests; though it lacks many features you can find in PCRE
+//   or POSIX extended regex syntax.  For example, we don't support
+//   union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
+//   repetition count ("x{5,7}"), among others.
+//
+//   Below is the syntax that we do support.  We chose it to be a
+//   subset of both PCRE and POSIX extended regex, so it's easy to
+//   learn wherever you come from.  In the following: 'A' denotes a
+//   literal character, period (.), or a single \\ escape sequence;
+//   'x' and 'y' denote regular expressions; 'm' and 'n' are for
+//   natural numbers.
+//
+//     c     matches any literal character c
+//     \\d   matches any decimal digit
+//     \\D   matches any character that's not a decimal digit
+//     \\f   matches \f
+//     \\n   matches \n
+//     \\r   matches \r
+//     \\s   matches any ASCII whitespace, including \n
+//     \\S   matches any character that's not a whitespace
+//     \\t   matches \t
+//     \\v   matches \v
+//     \\w   matches any letter, _, or decimal digit
+//     \\W   matches any character that \\w doesn't match
+//     \\c   matches any literal character c, which must be a punctuation
+//     .     matches any single character except \n
+//     A?    matches 0 or 1 occurrences of A
+//     A*    matches 0 or many occurrences of A
+//     A+    matches 1 or many occurrences of A
+//     ^     matches the beginning of a string (not that of each line)
+//     $     matches the end of a string (not that of each line)
+//     xy    matches x followed by y
+//
+//   If you accidentally use PCRE or POSIX extended regex features
+//   not implemented by us, you will get a run-time failure.  In that
+//   case, please try to rewrite your regular expression within the
+//   above syntax.
+//
+//   This implementation is *not* meant to be as highly tuned or robust
+//   as a compiled regex library, but should perform well enough for a
+//   death test, which already incurs significant overhead by launching
+//   a child process.
+//
+// Known caveats:
+//
+//   A "threadsafe" style death test obtains the path to the test
+//   program from argv[0] and re-executes it in the sub-process.  For
+//   simplicity, the current implementation doesn't search the PATH
+//   when launching the sub-process.  This means that the user must
+//   invoke the test program via a path that contains at least one
+//   path separator (e.g. path/to/foo_test and
+//   /absolute/path/to/bar_test are fine, but foo_test is not).  This
+//   is rarely a problem as people usually don't put the test binary
+//   directory in PATH.
+//
+// TODO(wan@google.com): make thread-safe death tests search the PATH.
+
+// 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 GTEST_API_ ExitedWithCode {
+ public:
+  explicit ExitedWithCode(int exit_code);
+  bool operator()(int exit_status) const;
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ExitedWithCode& other);
+
+  const int exit_code_;
+};
+
+#if !GTEST_OS_WINDOWS
+// Tests that an exit code describes an exit due to termination by a
+// given signal.
+class GTEST_API_ KilledBySignal {
+ public:
+  explicit KilledBySignal(int signum);
+  bool operator()(int exit_status) const;
+ private:
+  const int signum_;
+};
+#endif  // !GTEST_OS_WINDOWS
+
+// 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 (::testing::internal::AlwaysFalse())
+
+#define ASSERT_DEBUG_DEATH(statement, regex) \
+  do { statement; } while (::testing::internal::AlwaysFalse())
+
+#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
+
+// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
+// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
+// death tests are supported; otherwise they just issue a warning.  This is
+// useful when you are combining death test assertions with normal test
+// assertions in one test.
+#if GTEST_HAS_DEATH_TEST
+#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+    EXPECT_DEATH(statement, regex)
+#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+    ASSERT_DEATH(statement, regex)
+#else
+#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
+#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
+#endif
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
+// 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_
+
+#include <limits>
+
+
+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 GTEST_API_ 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) {
+    // By default, we want there to be enough precision when printing
+    // a double to a Message.
+    *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
+  }
+
+  // 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_; }
+#if GTEST_OS_SYMBIAN
+  // 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  // GTEST_OS_SYMBIAN
+
+  // 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:
+#if GTEST_OS_SYMBIAN
+  // 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  // GTEST_OS_SYMBIAN
+
+  // 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_
+// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+
+// 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: vladl@google.com (Vlad Losev)
+//
+// Macros and functions for implementing parameterized tests
+// in Google C++ Testing Framework (Google Test)
+//
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+
+
+// Value-parameterized tests allow you to test your code with different
+// parameters without writing multiple copies of the same test.
+//
+// Here is how you use value-parameterized tests:
+
+#if 0
+
+// To write value-parameterized tests, first you should define a fixture
+// class. It must be derived from testing::TestWithParam<T>, where T is
+// the type of your parameter values. TestWithParam<T> is itself derived
+// from testing::Test. T can be any copyable type. If it's a raw pointer,
+// you are responsible for managing the lifespan of the pointed values.
+
+class FooTest : public ::testing::TestWithParam<const char*> {
+  // You can implement all the usual class fixture members here.
+};
+
+// Then, use the TEST_P macro to define as many parameterized tests
+// for this fixture as you want. The _P suffix is for "parameterized"
+// or "pattern", whichever you prefer to think.
+
+TEST_P(FooTest, DoesBlah) {
+  // Inside a test, access the test parameter with the GetParam() method
+  // of the TestWithParam<T> class:
+  EXPECT_TRUE(foo.Blah(GetParam()));
+  ...
+}
+
+TEST_P(FooTest, HasBlahBlah) {
+  ...
+}
+
+// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
+// case with any set of parameters you want. Google Test defines a number
+// of functions for generating test parameters. They return what we call
+// (surprise!) parameter generators. Here is a  summary of them, which
+// are all in the testing namespace:
+//
+//
+//  Range(begin, end [, step]) - Yields values {begin, begin+step,
+//                               begin+step+step, ...}. The values do not
+//                               include end. step defaults to 1.
+//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.
+//  ValuesIn(container)        - Yields values from a C-style array, an STL
+//  ValuesIn(begin,end)          container, or an iterator range [begin, end).
+//  Bool()                     - Yields sequence {false, true}.
+//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product
+//                               for the math savvy) of the values generated
+//                               by the N generators.
+//
+// For more details, see comments at the definitions of these functions below
+// in this file.
+//
+// The following statement will instantiate tests from the FooTest test case
+// each with parameter values "meeny", "miny", and "moe".
+
+INSTANTIATE_TEST_CASE_P(InstantiationName,
+                        FooTest,
+                        Values("meeny", "miny", "moe"));
+
+// To distinguish different instances of the pattern, (yes, you
+// can instantiate it more then once) the first argument to the
+// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
+// actual test case name. Remember to pick unique prefixes for different
+// instantiations. The tests from the instantiation above will have
+// these names:
+//
+//    * InstantiationName/FooTest.DoesBlah/0 for "meeny"
+//    * InstantiationName/FooTest.DoesBlah/1 for "miny"
+//    * InstantiationName/FooTest.DoesBlah/2 for "moe"
+//    * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
+//    * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
+//    * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
+//
+// You can use these names in --gtest_filter.
+//
+// This statement will instantiate all tests from FooTest again, each
+// with parameter values "cat" and "dog":
+
+const char* pets[] = {"cat", "dog"};
+INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
+
+// The tests from the instantiation above will have these names:
+//
+//    * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
+//
+// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
+// in the given test case, whether their definitions come before or
+// AFTER the INSTANTIATE_TEST_CASE_P statement.
+//
+// Please also note that generator expressions (including parameters to the
+// generators) are evaluated in InitGoogleTest(), after main() has started.
+// This allows the user on one hand, to adjust generator parameters in order
+// to dynamically determine a set of tests to run and on the other hand,
+// give the user a chance to inspect the generated tests with Google Test
+// reflection API before RUN_ALL_TESTS() is executed.
+//
+// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
+// for more examples.
+//
+// In the future, we plan to publish the API for defining new parameter
+// generators. But for now this interface remains part of the internal
+// implementation and is subject to change.
+
+#endif  // 0
+
+
+#if !GTEST_OS_SYMBIAN
+#include <utility>
+#endif
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+// 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: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+
+#include <iterator>
+#include <utility>
+#include <vector>
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+// Copyright 2003 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: Dan Egnor (egnor@google.com)
+//
+// A "smart" pointer type with reference tracking.  Every pointer to a
+// particular object is kept on a circular linked list.  When the last pointer
+// to an object is destroyed or reassigned, the object is deleted.
+//
+// Used properly, this deletes the object when the last reference goes away.
+// There are several caveats:
+// - Like all reference counting schemes, cycles lead to leaks.
+// - Each smart pointer is actually two pointers (8 bytes instead of 4).
+// - Every time a pointer is assigned, the entire list of pointers to that
+//   object is traversed.  This class is therefore NOT SUITABLE when there
+//   will often be more than two or three pointers to a particular object.
+// - References are only tracked as long as linked_ptr<> objects are copied.
+//   If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
+//   will happen (double deletion).
+//
+// A good use of this class is storing object references in STL containers.
+// You can safely put linked_ptr<> in a vector<>.
+// Other uses may not be as good.
+//
+// Note: If you use an incomplete type with linked_ptr<>, the class
+// *containing* linked_ptr<> must have a constructor and destructor (even
+// if they do nothing!).
+//
+// Bill Gibbons suggested we use something like this.
+//
+// Thread Safety:
+//   Unlike other linked_ptr implementations, in this implementation
+//   a linked_ptr object is thread-safe in the sense that:
+//     - it's safe to copy linked_ptr objects concurrently,
+//     - it's safe to copy *from* a linked_ptr and read its underlying
+//       raw pointer (e.g. via get()) concurrently, and
+//     - it's safe to write to two linked_ptrs that point to the same
+//       shared object concurrently.
+// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
+// confusion with normal linked_ptr.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+
+#include <stdlib.h>
+#include <assert.h>
+
+
+namespace testing {
+namespace internal {
+
+// Protects copying of all linked_ptr objects.
+GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
+
+// This is used internally by all instances of linked_ptr<>.  It needs to be
+// a non-template class because different types of linked_ptr<> can refer to
+// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
+// So, it needs to be possible for different types of linked_ptr to participate
+// in the same circular linked list, so we need a single class type here.
+//
+// DO NOT USE THIS CLASS DIRECTLY YOURSELF.  Use linked_ptr<T>.
+class linked_ptr_internal {
+ public:
+  // Create a new circle that includes only this instance.
+  void join_new() {
+    next_ = this;
+  }
+
+  // Many linked_ptr operations may change p.link_ for some linked_ptr
+  // variable p in the same circle as this object.  Therefore we need
+  // to prevent two such operations from occurring concurrently.
+  //
+  // Note that different types of linked_ptr objects can coexist in a
+  // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
+  // linked_ptr<Derived2>).  Therefore we must use a single mutex to
+  // protect all linked_ptr objects.  This can create serious
+  // contention in production code, but is acceptable in a testing
+  // framework.
+
+  // Join an existing circle.
+  // L < g_linked_ptr_mutex
+  void join(linked_ptr_internal const* ptr) {
+    MutexLock lock(&g_linked_ptr_mutex);
+
+    linked_ptr_internal const* p = ptr;
+    while (p->next_ != ptr) p = p->next_;
+    p->next_ = this;
+    next_ = ptr;
+  }
+
+  // Leave whatever circle we're part of.  Returns true if we were the
+  // last member of the circle.  Once this is done, you can join() another.
+  // L < g_linked_ptr_mutex
+  bool depart() {
+    MutexLock lock(&g_linked_ptr_mutex);
+
+    if (next_ == this) return true;
+    linked_ptr_internal const* p = next_;
+    while (p->next_ != this) p = p->next_;
+    p->next_ = next_;
+    return false;
+  }
+
+ private:
+  mutable linked_ptr_internal const* next_;
+};
+
+template <typename T>
+class linked_ptr {
+ public:
+  typedef T element_type;
+
+  // Take over ownership of a raw pointer.  This should happen as soon as
+  // possible after the object is created.
+  explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
+  ~linked_ptr() { depart(); }
+
+  // Copy an existing linked_ptr<>, adding ourselves to the list of references.
+  template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
+  linked_ptr(linked_ptr const& ptr) {  // NOLINT
+    assert(&ptr != this);
+    copy(&ptr);
+  }
+
+  // Assignment releases the old value and acquires the new.
+  template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
+    depart();
+    copy(&ptr);
+    return *this;
+  }
+
+  linked_ptr& operator=(linked_ptr const& ptr) {
+    if (&ptr != this) {
+      depart();
+      copy(&ptr);
+    }
+    return *this;
+  }
+
+  // Smart pointer members.
+  void reset(T* ptr = NULL) {
+    depart();
+    capture(ptr);
+  }
+  T* get() const { return value_; }
+  T* operator->() const { return value_; }
+  T& operator*() const { return *value_; }
+  // Release ownership of the pointed object and returns it.
+  // Sole ownership by this linked_ptr object is required.
+  T* release() {
+    bool last = link_.depart();
+    assert(last);
+    T* v = value_;
+    value_ = NULL;
+    return v;
+  }
+
+  bool operator==(T* p) const { return value_ == p; }
+  bool operator!=(T* p) const { return value_ != p; }
+  template <typename U>
+  bool operator==(linked_ptr<U> const& ptr) const {
+    return value_ == ptr.get();
+  }
+  template <typename U>
+  bool operator!=(linked_ptr<U> const& ptr) const {
+    return value_ != ptr.get();
+  }
+
+ private:
+  template <typename U>
+  friend class linked_ptr;
+
+  T* value_;
+  linked_ptr_internal link_;
+
+  void depart() {
+    if (link_.depart()) delete value_;
+  }
+
+  void capture(T* ptr) {
+    value_ = ptr;
+    link_.join_new();
+  }
+
+  template <typename U> void copy(linked_ptr<U> const* ptr) {
+    value_ = ptr->get();
+    if (value_)
+      link_.join(&ptr->link_);
+    else
+      link_.join_new();
+  }
+};
+
+template<typename T> inline
+bool operator==(T* ptr, const linked_ptr<T>& x) {
+  return ptr == x.get();
+}
+
+template<typename T> inline
+bool operator!=(T* ptr, const linked_ptr<T>& x) {
+  return ptr != x.get();
+}
+
+// A function to convert T* into linked_ptr<T>
+// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
+// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
+template <typename T>
+linked_ptr<T> make_linked_ptr(T* ptr) {
+  return linked_ptr<T>(ptr);
+}
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+namespace internal {
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Outputs a message explaining invalid registration of different
+// fixture class for the same test case. This may happen when
+// TEST_P macro is used to define two tests with the same name
+// but in different namespaces.
+GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
+                                          const char* file, int line);
+
+template <typename> class ParamGeneratorInterface;
+template <typename> class ParamGenerator;
+
+// Interface for iterating over elements provided by an implementation
+// of ParamGeneratorInterface<T>.
+template <typename T>
+class ParamIteratorInterface {
+ public:
+  virtual ~ParamIteratorInterface() {}
+  // A pointer to the base generator instance.
+  // Used only for the purposes of iterator comparison
+  // to make sure that two iterators belong to the same generator.
+  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
+  // Advances iterator to point to the next element
+  // provided by the generator. The caller is responsible
+  // for not calling Advance() on an iterator equal to
+  // BaseGenerator()->End().
+  virtual void Advance() = 0;
+  // Clones the iterator object. Used for implementing copy semantics
+  // of ParamIterator<T>.
+  virtual ParamIteratorInterface* Clone() const = 0;
+  // Dereferences the current iterator and provides (read-only) access
+  // to the pointed value. It is the caller's responsibility not to call
+  // Current() on an iterator equal to BaseGenerator()->End().
+  // Used for implementing ParamGenerator<T>::operator*().
+  virtual const T* Current() const = 0;
+  // Determines whether the given iterator and other point to the same
+  // element in the sequence generated by the generator.
+  // Used for implementing ParamGenerator<T>::operator==().
+  virtual bool Equals(const ParamIteratorInterface& other) const = 0;
+};
+
+// Class iterating over elements provided by an implementation of
+// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
+// and implements the const forward iterator concept.
+template <typename T>
+class ParamIterator {
+ public:
+  typedef T value_type;
+  typedef const T& reference;
+  typedef ptrdiff_t difference_type;
+
+  // ParamIterator assumes ownership of the impl_ pointer.
+  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
+  ParamIterator& operator=(const ParamIterator& other) {
+    if (this != &other)
+      impl_.reset(other.impl_->Clone());
+    return *this;
+  }
+
+  const T& operator*() const { return *impl_->Current(); }
+  const T* operator->() const { return impl_->Current(); }
+  // Prefix version of operator++.
+  ParamIterator& operator++() {
+    impl_->Advance();
+    return *this;
+  }
+  // Postfix version of operator++.
+  ParamIterator operator++(int /*unused*/) {
+    ParamIteratorInterface<T>* clone = impl_->Clone();
+    impl_->Advance();
+    return ParamIterator(clone);
+  }
+  bool operator==(const ParamIterator& other) const {
+    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
+  }
+  bool operator!=(const ParamIterator& other) const {
+    return !(*this == other);
+  }
+
+ private:
+  friend class ParamGenerator<T>;
+  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
+  scoped_ptr<ParamIteratorInterface<T> > impl_;
+};
+
+// ParamGeneratorInterface<T> is the binary interface to access generators
+// defined in other translation units.
+template <typename T>
+class ParamGeneratorInterface {
+ public:
+  typedef T ParamType;
+
+  virtual ~ParamGeneratorInterface() {}
+
+  // Generator interface definition
+  virtual ParamIteratorInterface<T>* Begin() const = 0;
+  virtual ParamIteratorInterface<T>* End() const = 0;
+};
+
+// Wraps ParamGeneratorInterface<T> and provides general generator syntax
+// compatible with the STL Container concept.
+// This class implements copy initialization semantics and the contained
+// ParamGeneratorInterface<T> instance is shared among all copies
+// of the original object. This is possible because that instance is immutable.
+template<typename T>
+class ParamGenerator {
+ public:
+  typedef ParamIterator<T> iterator;
+
+  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
+  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
+
+  ParamGenerator& operator=(const ParamGenerator& other) {
+    impl_ = other.impl_;
+    return *this;
+  }
+
+  iterator begin() const { return iterator(impl_->Begin()); }
+  iterator end() const { return iterator(impl_->End()); }
+
+ private:
+  ::testing::internal::linked_ptr<const ParamGeneratorInterface<T> > impl_;
+};
+
+// Generates values from a range of two comparable values. Can be used to
+// generate sequences of user-defined types that implement operator+() and
+// operator<().
+// This class is used in the Range() function.
+template <typename T, typename IncrementT>
+class RangeGenerator : public ParamGeneratorInterface<T> {
+ public:
+  RangeGenerator(T begin, T end, IncrementT step)
+      : begin_(begin), end_(end),
+        step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
+  virtual ~RangeGenerator() {}
+
+  virtual ParamIteratorInterface<T>* Begin() const {
+    return new Iterator(this, begin_, 0, step_);
+  }
+  virtual ParamIteratorInterface<T>* End() const {
+    return new Iterator(this, end_, end_index_, step_);
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<T> {
+   public:
+    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
+             IncrementT step)
+        : base_(base), value_(value), index_(index), step_(step) {}
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+      return base_;
+    }
+    virtual void Advance() {
+      value_ = value_ + step_;
+      index_++;
+    }
+    virtual ParamIteratorInterface<T>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const T* Current() const { return &value_; }
+    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const int other_index =
+          CheckedDowncastToActualType<const Iterator>(&other)->index_;
+      return index_ == other_index;
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : ParamIteratorInterface<T>(),
+          base_(other.base_), value_(other.value_), index_(other.index_),
+          step_(other.step_) {}
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<T>* const base_;
+    T value_;
+    int index_;
+    const IncrementT step_;
+  };  // class RangeGenerator::Iterator
+
+  static int CalculateEndIndex(const T& begin,
+                               const T& end,
+                               const IncrementT& step) {
+    int end_index = 0;
+    for (T i = begin; i < end; i = i + step)
+      end_index++;
+    return end_index;
+  }
+
+  // No implementation - assignment is unsupported.
+  void operator=(const RangeGenerator& other);
+
+  const T begin_;
+  const T end_;
+  const IncrementT step_;
+  // The index for the end() iterator. All the elements in the generated
+  // sequence are indexed (0-based) to aid iterator comparison.
+  const int end_index_;
+};  // class RangeGenerator
+
+
+// Generates values from a pair of STL-style iterators. Used in the
+// ValuesIn() function. The elements are copied from the source range
+// since the source can be located on the stack, and the generator
+// is likely to persist beyond that stack frame.
+template <typename T>
+class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
+ public:
+  template <typename ForwardIterator>
+  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
+      : container_(begin, end) {}
+  virtual ~ValuesInIteratorRangeGenerator() {}
+
+  virtual ParamIteratorInterface<T>* Begin() const {
+    return new Iterator(this, container_.begin());
+  }
+  virtual ParamIteratorInterface<T>* End() const {
+    return new Iterator(this, container_.end());
+  }
+
+ private:
+  typedef typename ::std::vector<T> ContainerType;
+
+  class Iterator : public ParamIteratorInterface<T> {
+   public:
+    Iterator(const ParamGeneratorInterface<T>* base,
+             typename ContainerType::const_iterator iterator)
+        :  base_(base), iterator_(iterator) {}
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+      return base_;
+    }
+    virtual void Advance() {
+      ++iterator_;
+      value_.reset();
+    }
+    virtual ParamIteratorInterface<T>* Clone() const {
+      return new Iterator(*this);
+    }
+    // We need to use cached value referenced by iterator_ because *iterator_
+    // can return a temporary object (and of type other then T), so just
+    // having "return &*iterator_;" doesn't work.
+    // value_ is updated here and not in Advance() because Advance()
+    // can advance iterator_ beyond the end of the range, and we cannot
+    // detect that fact. The client code, on the other hand, is
+    // responsible for not calling Current() on an out-of-range iterator.
+    virtual const T* Current() const {
+      if (value_.get() == NULL)
+        value_.reset(new T(*iterator_));
+      return value_.get();
+    }
+    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      return iterator_ ==
+          CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
+    }
+
+   private:
+    Iterator(const Iterator& other)
+          // The explicit constructor call suppresses a false warning
+          // emitted by gcc when supplied with the -Wextra option.
+        : ParamIteratorInterface<T>(),
+          base_(other.base_),
+          iterator_(other.iterator_) {}
+
+    const ParamGeneratorInterface<T>* const base_;
+    typename ContainerType::const_iterator iterator_;
+    // A cached value of *iterator_. We keep it here to allow access by
+    // pointer in the wrapping iterator's operator->().
+    // value_ needs to be mutable to be accessed in Current().
+    // Use of scoped_ptr helps manage cached value's lifetime,
+    // which is bound by the lifespan of the iterator itself.
+    mutable scoped_ptr<const T> value_;
+  };  // class ValuesInIteratorRangeGenerator::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const ValuesInIteratorRangeGenerator& other);
+
+  const ContainerType container_;
+};  // class ValuesInIteratorRangeGenerator
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Stores a parameter value and later creates tests parameterized with that
+// value.
+template <class TestClass>
+class ParameterizedTestFactory : public TestFactoryBase {
+ public:
+  typedef typename TestClass::ParamType ParamType;
+  explicit ParameterizedTestFactory(ParamType parameter) :
+      parameter_(parameter) {}
+  virtual Test* CreateTest() {
+    TestClass::SetParam(&parameter_);
+    return new TestClass();
+  }
+
+ private:
+  const ParamType parameter_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// TestMetaFactoryBase is a base class for meta-factories that create
+// test factories for passing into MakeAndRegisterTestInfo function.
+template <class ParamType>
+class TestMetaFactoryBase {
+ public:
+  virtual ~TestMetaFactoryBase() {}
+
+  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// TestMetaFactory creates test factories for passing into
+// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
+// ownership of test factory pointer, same factory object cannot be passed
+// into that method twice. But ParameterizedTestCaseInfo is going to call
+// it for each Test/Parameter value combination. Thus it needs meta factory
+// creator class.
+template <class TestCase>
+class TestMetaFactory
+    : public TestMetaFactoryBase<typename TestCase::ParamType> {
+ public:
+  typedef typename TestCase::ParamType ParamType;
+
+  TestMetaFactory() {}
+
+  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
+    return new ParameterizedTestFactory<TestCase>(parameter);
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseInfoBase is a generic interface
+// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
+// accumulates test information provided by TEST_P macro invocations
+// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
+// and uses that information to register all resulting test instances
+// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
+// a collection of pointers to the ParameterizedTestCaseInfo objects
+// and calls RegisterTests() on each of them when asked.
+class ParameterizedTestCaseInfoBase {
+ public:
+  virtual ~ParameterizedTestCaseInfoBase() {}
+
+  // Base part of test case name for display purposes.
+  virtual const String& GetTestCaseName() const = 0;
+  // Test case id to verify identity.
+  virtual TypeId GetTestCaseTypeId() const = 0;
+  // UnitTest class invokes this method to register tests in this
+  // test case right before running them in RUN_ALL_TESTS macro.
+  // This method should not be called more then once on any single
+  // instance of a ParameterizedTestCaseInfoBase derived class.
+  virtual void RegisterTests() = 0;
+
+ protected:
+  ParameterizedTestCaseInfoBase() {}
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
+// macro invocations for a particular test case and generators
+// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
+// test case. It registers tests with all values generated by all
+// generators when asked.
+template <class TestCase>
+class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
+ public:
+  // ParamType and GeneratorCreationFunc are private types but are required
+  // for declarations of public methods AddTestPattern() and
+  // AddTestCaseInstantiation().
+  typedef typename TestCase::ParamType ParamType;
+  // A function that returns an instance of appropriate generator type.
+  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
+
+  explicit ParameterizedTestCaseInfo(const char* name)
+      : test_case_name_(name) {}
+
+  // Test case base name for display purposes.
+  virtual const String& GetTestCaseName() const { return test_case_name_; }
+  // Test case id to verify identity.
+  virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
+  // TEST_P macro uses AddTestPattern() to record information
+  // about a single test in a LocalTestInfo structure.
+  // test_case_name is the base name of the test case (without invocation
+  // prefix). test_base_name is the name of an individual test without
+  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
+  // test case base name and DoBar is test base name.
+  void AddTestPattern(const char* test_case_name,
+                      const char* test_base_name,
+                      TestMetaFactoryBase<ParamType>* meta_factory) {
+    tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
+                                                       test_base_name,
+                                                       meta_factory)));
+  }
+  // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
+  // about a generator.
+  int AddTestCaseInstantiation(const char* instantiation_name,
+                               GeneratorCreationFunc* func,
+                               const char* /* file */,
+                               int /* line */) {
+    instantiations_.push_back(::std::make_pair(instantiation_name, func));
+    return 0;  // Return value used only to run this method in namespace scope.
+  }
+  // UnitTest class invokes this method to register tests in this test case
+  // test cases right before running tests in RUN_ALL_TESTS macro.
+  // This method should not be called more then once on any single
+  // instance of a ParameterizedTestCaseInfoBase derived class.
+  // UnitTest has a guard to prevent from calling this method more then once.
+  virtual void RegisterTests() {
+    for (typename TestInfoContainer::iterator test_it = tests_.begin();
+         test_it != tests_.end(); ++test_it) {
+      linked_ptr<TestInfo> test_info = *test_it;
+      for (typename InstantiationContainer::iterator gen_it =
+               instantiations_.begin(); gen_it != instantiations_.end();
+               ++gen_it) {
+        const String& instantiation_name = gen_it->first;
+        ParamGenerator<ParamType> generator((*gen_it->second)());
+
+        Message test_case_name_stream;
+        if ( !instantiation_name.empty() )
+          test_case_name_stream << instantiation_name.c_str() << "/";
+        test_case_name_stream << test_info->test_case_base_name.c_str();
+
+        int i = 0;
+        for (typename ParamGenerator<ParamType>::iterator param_it =
+                 generator.begin();
+             param_it != generator.end(); ++param_it, ++i) {
+          Message test_name_stream;
+          test_name_stream << test_info->test_base_name.c_str() << "/" << i;
+          ::testing::internal::MakeAndRegisterTestInfo(
+              test_case_name_stream.GetString().c_str(),
+              test_name_stream.GetString().c_str(),
+              "",  // test_case_comment
+              "",  // comment; TODO(vladl@google.com): provide parameter value
+                   //                                  representation.
+              GetTestCaseTypeId(),
+              TestCase::SetUpTestCase,
+              TestCase::TearDownTestCase,
+              test_info->test_meta_factory->CreateTestFactory(*param_it));
+        }  // for param_it
+      }  // for gen_it
+    }  // for test_it
+  }  // RegisterTests
+
+ private:
+  // LocalTestInfo structure keeps information about a single test registered
+  // with TEST_P macro.
+  struct TestInfo {
+    TestInfo(const char* a_test_case_base_name,
+             const char* a_test_base_name,
+             TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
+        test_case_base_name(a_test_case_base_name),
+        test_base_name(a_test_base_name),
+        test_meta_factory(a_test_meta_factory) {}
+
+    const String test_case_base_name;
+    const String test_base_name;
+    const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
+  };
+  typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
+  // Keeps pairs of <Instantiation name, Sequence generator creation function>
+  // received from INSTANTIATE_TEST_CASE_P macros.
+  typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> >
+      InstantiationContainer;
+
+  const String test_case_name_;
+  TestInfoContainer tests_;
+  InstantiationContainer instantiations_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
+};  // class ParameterizedTestCaseInfo
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
+// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
+// macros use it to locate their corresponding ParameterizedTestCaseInfo
+// descriptors.
+class ParameterizedTestCaseRegistry {
+ public:
+  ParameterizedTestCaseRegistry() {}
+  ~ParameterizedTestCaseRegistry() {
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      delete *it;
+    }
+  }
+
+  // Looks up or creates and returns a structure containing information about
+  // tests and instantiations of a particular test case.
+  template <class TestCase>
+  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
+      const char* test_case_name,
+      const char* file,
+      int line) {
+    ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      if ((*it)->GetTestCaseName() == test_case_name) {
+        if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
+          // Complain about incorrect usage of Google Test facilities
+          // and terminate the program since we cannot guaranty correct
+          // test case setup and tear-down in this case.
+          ReportInvalidTestCaseType(test_case_name,  file, line);
+          abort();
+        } else {
+          // At this point we are sure that the object we found is of the same
+          // type we are looking for, so we downcast it to that type
+          // without further checks.
+          typed_test_info = CheckedDowncastToActualType<
+              ParameterizedTestCaseInfo<TestCase> >(*it);
+        }
+        break;
+      }
+    }
+    if (typed_test_info == NULL) {
+      typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
+      test_case_infos_.push_back(typed_test_info);
+    }
+    return typed_test_info;
+  }
+  void RegisterTests() {
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      (*it)->RegisterTests();
+    }
+  }
+
+ private:
+  typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
+
+  TestCaseInfoContainer test_case_infos_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  //  GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+
+// 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: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// Currently Google Test supports at most 50 arguments in Values,
+// and at most 10 arguments in Combine. Please contact
+// googletestframework@googlegroups.com if you need more.
+// Please note that the number of arguments to Combine is limited
+// by the maximum arity of the implementation of tr1::tuple which is
+// currently set at 10.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Forward declarations of ValuesIn(), which is implemented in
+// include/gtest/gtest-param-test.h.
+template <typename ForwardIterator>
+internal::ParamGenerator<
+    typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+        ForwardIterator begin, ForwardIterator end);
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+    const Container& container);
+
+namespace internal {
+
+// Used in the Values() function to provide polymorphic capabilities.
+template <typename T1>
+class ValueArray1 {
+ public:
+  explicit ValueArray1(T1 v1) : v1_(v1) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray1& other);
+
+  const T1 v1_;
+};
+
+template <typename T1, typename T2>
+class ValueArray2 {
+ public:
+  ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray2& other);
+
+  const T1 v1_;
+  const T2 v2_;
+};
+
+template <typename T1, typename T2, typename T3>
+class ValueArray3 {
+ public:
+  ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray3& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+class ValueArray4 {
+ public:
+  ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray4& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class ValueArray5 {
+ public:
+  ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray5& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+class ValueArray6 {
+ public:
+  ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray6& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+class ValueArray7 {
+ public:
+  ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray7& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+class ValueArray8 {
+ public:
+  ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+      T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray8& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+class ValueArray9 {
+ public:
+  ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+      T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray9& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+class ValueArray10 {
+ public:
+  ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray10& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+class ValueArray11 {
+ public:
+  ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray11& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+class ValueArray12 {
+ public:
+  ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray12& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+class ValueArray13 {
+ public:
+  ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray13& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+class ValueArray14 {
+ public:
+  ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray14& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+class ValueArray15 {
+ public:
+  ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray15& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+class ValueArray16 {
+ public:
+  ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray16& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+class ValueArray17 {
+ public:
+  ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+      T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray17& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+class ValueArray18 {
+ public:
+  ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray18& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+class ValueArray19 {
+ public:
+  ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray19& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+class ValueArray20 {
+ public:
+  ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray20& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+class ValueArray21 {
+ public:
+  ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray21& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+class ValueArray22 {
+ public:
+  ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray22& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+class ValueArray23 {
+ public:
+  ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_,
+        v23_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray23& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+class ValueArray24 {
+ public:
+  ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray24& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+class ValueArray25 {
+ public:
+  ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+      T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray25& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+class ValueArray26 {
+ public:
+  ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray26& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+class ValueArray27 {
+ public:
+  ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray27& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+class ValueArray28 {
+ public:
+  ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray28& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+class ValueArray29 {
+ public:
+  ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray29& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+class ValueArray30 {
+ public:
+  ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray30& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+class ValueArray31 {
+ public:
+  ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray31& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+class ValueArray32 {
+ public:
+  ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray32& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+class ValueArray33 {
+ public:
+  ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
+      T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray33& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+class ValueArray34 {
+ public:
+  ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray34& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+class ValueArray35 {
+ public:
+  ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
+      v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_,
+        v35_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray35& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+class ValueArray36 {
+ public:
+  ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
+      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray36& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+class ValueArray37 {
+ public:
+  ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
+      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
+      v36_(v36), v37_(v37) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray37& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+class ValueArray38 {
+ public:
+  ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray38& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+class ValueArray39 {
+ public:
+  ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray39& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+class ValueArray40 {
+ public:
+  ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
+      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
+      v40_(v40) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray40& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+class ValueArray41 {
+ public:
+  ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
+      T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray41& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+class ValueArray42 {
+ public:
+  ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray42& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+class ValueArray43 {
+ public:
+  ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
+      v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),
+      v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray43& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+class ValueArray44 {
+ public:
+  ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
+      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),
+      v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),
+      v43_(v43), v44_(v44) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray44& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+class ValueArray45 {
+ public:
+  ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
+      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
+      v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),
+      v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray45& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+class ValueArray46 {
+ public:
+  ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
+      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray46& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+class ValueArray47 {
+ public:
+  ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
+      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),
+      v47_(v47) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_,
+        v47_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray47& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+class ValueArray48 {
+ public:
+  ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
+      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
+      v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),
+      v46_(v46), v47_(v47), v48_(v48) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray48& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+class ValueArray49 {
+ public:
+  ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,
+      T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
+      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_, v49_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray49& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+  const T49 v49_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+class ValueArray50 {
+ public:
+  ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,
+      T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
+      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_, v49_, v50_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray50& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+  const T49 v49_;
+  const T50 v50_;
+};
+
+#if GTEST_HAS_COMBINE
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Generates values from the Cartesian product of values produced
+// by the argument generators.
+//
+template <typename T1, typename T2>
+class CartesianProductGenerator2
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2> ParamType;
+
+  CartesianProductGenerator2(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2)
+      : g1_(g1), g2_(g2) {}
+  virtual ~CartesianProductGenerator2() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current2_;
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator2::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator2& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+};  // class CartesianProductGenerator2
+
+
+template <typename T1, typename T2, typename T3>
+class CartesianProductGenerator3
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3> ParamType;
+
+  CartesianProductGenerator3(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
+      : g1_(g1), g2_(g2), g3_(g3) {}
+  virtual ~CartesianProductGenerator3() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current3_;
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator3::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator3& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+};  // class CartesianProductGenerator3
+
+
+template <typename T1, typename T2, typename T3, typename T4>
+class CartesianProductGenerator4
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType;
+
+  CartesianProductGenerator4(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
+  virtual ~CartesianProductGenerator4() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current4_;
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator4::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator4& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+};  // class CartesianProductGenerator4
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class CartesianProductGenerator5
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType;
+
+  CartesianProductGenerator5(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
+  virtual ~CartesianProductGenerator5() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current5_;
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator5::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator5& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+};  // class CartesianProductGenerator5
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+class CartesianProductGenerator6
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5,
+        T6> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType;
+
+  CartesianProductGenerator6(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
+  virtual ~CartesianProductGenerator6() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current6_;
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator6::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator6& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+};  // class CartesianProductGenerator6
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+class CartesianProductGenerator7
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
+
+  CartesianProductGenerator7(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
+  virtual ~CartesianProductGenerator7() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current7_;
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator7::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator7& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+};  // class CartesianProductGenerator7
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+class CartesianProductGenerator8
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
+
+  CartesianProductGenerator8(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
+          g8_(g8) {}
+  virtual ~CartesianProductGenerator8() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current8_;
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator8::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator8& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+};  // class CartesianProductGenerator8
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+class CartesianProductGenerator9
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8, T9> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
+
+  CartesianProductGenerator9(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9) {}
+  virtual ~CartesianProductGenerator9() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end(), g9_, g9_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8,
+      const ParamGenerator<T9>& g9,
+      const typename ParamGenerator<T9>::iterator& current9)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
+          begin9_(g9.begin()), end9_(g9.end()), current9_(current9)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current9_;
+      if (current9_ == end9_) {
+        current9_ = begin9_;
+        ++current8_;
+      }
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_ &&
+          current9_ == typed_other->current9_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_),
+        begin9_(other.begin9_),
+        end9_(other.end9_),
+        current9_(other.current9_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_,
+            *current9_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_ ||
+          current9_ == end9_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    const typename ParamGenerator<T9>::iterator begin9_;
+    const typename ParamGenerator<T9>::iterator end9_;
+    typename ParamGenerator<T9>::iterator current9_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator9::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator9& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+  const ParamGenerator<T9> g9_;
+};  // class CartesianProductGenerator9
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+class CartesianProductGenerator10
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8, T9, T10> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
+
+  CartesianProductGenerator10(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,
+      const ParamGenerator<T10>& g10)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9), g10_(g10) {}
+  virtual ~CartesianProductGenerator10() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end(), g9_, g9_.end(), g10_, g10_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8,
+      const ParamGenerator<T9>& g9,
+      const typename ParamGenerator<T9>::iterator& current9,
+      const ParamGenerator<T10>& g10,
+      const typename ParamGenerator<T10>::iterator& current10)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
+          begin9_(g9.begin()), end9_(g9.end()), current9_(current9),
+          begin10_(g10.begin()), end10_(g10.end()), current10_(current10)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current10_;
+      if (current10_ == end10_) {
+        current10_ = begin10_;
+        ++current9_;
+      }
+      if (current9_ == end9_) {
+        current9_ = begin9_;
+        ++current8_;
+      }
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_ &&
+          current9_ == typed_other->current9_ &&
+          current10_ == typed_other->current10_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_),
+        begin9_(other.begin9_),
+        end9_(other.end9_),
+        current9_(other.current9_),
+        begin10_(other.begin10_),
+        end10_(other.end10_),
+        current10_(other.current10_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_,
+            *current9_, *current10_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_ ||
+          current9_ == end9_ ||
+          current10_ == end10_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    const typename ParamGenerator<T9>::iterator begin9_;
+    const typename ParamGenerator<T9>::iterator end9_;
+    typename ParamGenerator<T9>::iterator current9_;
+    const typename ParamGenerator<T10>::iterator begin10_;
+    const typename ParamGenerator<T10>::iterator end10_;
+    typename ParamGenerator<T10>::iterator current10_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator10::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator10& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+  const ParamGenerator<T9> g9_;
+  const ParamGenerator<T10> g10_;
+};  // class CartesianProductGenerator10
+
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Helper classes providing Combine() with polymorphic features. They allow
+// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
+// convertible to U.
+//
+template <class Generator1, class Generator2>
+class CartesianProductHolder2 {
+ public:
+CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
+      : g1_(g1), g2_(g2) {}
+  template <typename T1, typename T2>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2> >(
+        new CartesianProductGenerator2<T1, T2>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder2& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+};  // class CartesianProductHolder2
+
+template <class Generator1, class Generator2, class Generator3>
+class CartesianProductHolder3 {
+ public:
+CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3)
+      : g1_(g1), g2_(g2), g3_(g3) {}
+  template <typename T1, typename T2, typename T3>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >(
+        new CartesianProductGenerator3<T1, T2, T3>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder3& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+};  // class CartesianProductHolder3
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4>
+class CartesianProductHolder4 {
+ public:
+CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
+  template <typename T1, typename T2, typename T3, typename T4>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >(
+        new CartesianProductGenerator4<T1, T2, T3, T4>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder4& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+};  // class CartesianProductHolder4
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5>
+class CartesianProductHolder5 {
+ public:
+CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >(
+        new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder5& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+};  // class CartesianProductHolder5
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6>
+class CartesianProductHolder6 {
+ public:
+CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >(
+        new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder6& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+};  // class CartesianProductHolder6
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7>
+class CartesianProductHolder7 {
+ public:
+CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+      T7> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >(
+        new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder7& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+};  // class CartesianProductHolder7
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8>
+class CartesianProductHolder8 {
+ public:
+CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
+          g8_(g8) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7,
+      T8> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
+        new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder8& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+};  // class CartesianProductHolder8
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8, class Generator9>
+class CartesianProductHolder9 {
+ public:
+CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8,
+    const Generator9& g9)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8, typename T9>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+      T9> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+        T9> >(
+        new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_),
+        static_cast<ParamGenerator<T9> >(g9_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder9& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+  const Generator9 g9_;
+};  // class CartesianProductHolder9
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8, class Generator9, class Generator10>
+class CartesianProductHolder10 {
+ public:
+CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8,
+    const Generator9& g9, const Generator10& g10)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9), g10_(g10) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8, typename T9, typename T10>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+      T9, T10> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+        T9, T10> >(
+        new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
+            T10>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_),
+        static_cast<ParamGenerator<T9> >(g9_),
+        static_cast<ParamGenerator<T10> >(g10_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder10& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+  const Generator9 g9_;
+  const Generator10 g10_;
+};  // class CartesianProductHolder10
+
+#endif  // GTEST_HAS_COMBINE
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  //  GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Functions producing parameter generators.
+//
+// Google Test uses these generators to produce parameters for value-
+// parameterized tests. When a parameterized test case is instantiated
+// with a particular generator, Google Test creates and runs tests
+// for each element in the sequence produced by the generator.
+//
+// In the following sample, tests from test case FooTest are instantiated
+// each three times with parameter values 3, 5, and 8:
+//
+// class FooTest : public TestWithParam<int> { ... };
+//
+// TEST_P(FooTest, TestThis) {
+// }
+// TEST_P(FooTest, TestThat) {
+// }
+// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
+//
+
+// Range() returns generators providing sequences of values in a range.
+//
+// Synopsis:
+// Range(start, end)
+//   - returns a generator producing a sequence of values {start, start+1,
+//     start+2, ..., }.
+// Range(start, end, step)
+//   - returns a generator producing a sequence of values {start, start+step,
+//     start+step+step, ..., }.
+// Notes:
+//   * The generated sequences never include end. For example, Range(1, 5)
+//     returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
+//     returns a generator producing {1, 3, 5, 7}.
+//   * start and end must have the same type. That type may be any integral or
+//     floating-point type or a user defined type satisfying these conditions:
+//     * It must be assignable (have operator=() defined).
+//     * It must have operator+() (operator+(int-compatible type) for
+//       two-operand version).
+//     * It must have operator<() defined.
+//     Elements in the resulting sequences will also have that type.
+//   * Condition start < end must be satisfied in order for resulting sequences
+//     to contain any elements.
+//
+template <typename T, typename IncrementT>
+internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
+  return internal::ParamGenerator<T>(
+      new internal::RangeGenerator<T, IncrementT>(start, end, step));
+}
+
+template <typename T>
+internal::ParamGenerator<T> Range(T start, T end) {
+  return Range(start, end, 1);
+}
+
+// ValuesIn() function allows generation of tests with parameters coming from
+// a container.
+//
+// Synopsis:
+// ValuesIn(const T (&array)[N])
+//   - returns a generator producing sequences with elements from
+//     a C-style array.
+// ValuesIn(const Container& container)
+//   - returns a generator producing sequences with elements from
+//     an STL-style container.
+// ValuesIn(Iterator begin, Iterator end)
+//   - returns a generator producing sequences with elements from
+//     a range [begin, end) defined by a pair of STL-style iterators. These
+//     iterators can also be plain C pointers.
+//
+// Please note that ValuesIn copies the values from the containers
+// passed in and keeps them to generate tests in RUN_ALL_TESTS().
+//
+// Examples:
+//
+// This instantiates tests from test case StringTest
+// each with C-string values of "foo", "bar", and "baz":
+//
+// const char* strings[] = {"foo", "bar", "baz"};
+// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
+//
+// This instantiates tests from test case StlStringTest
+// each with STL strings with values "a" and "b":
+//
+// ::std::vector< ::std::string> GetParameterStrings() {
+//   ::std::vector< ::std::string> v;
+//   v.push_back("a");
+//   v.push_back("b");
+//   return v;
+// }
+//
+// INSTANTIATE_TEST_CASE_P(CharSequence,
+//                         StlStringTest,
+//                         ValuesIn(GetParameterStrings()));
+//
+//
+// This will also instantiate tests from CharTest
+// each with parameter values 'a' and 'b':
+//
+// ::std::list<char> GetParameterChars() {
+//   ::std::list<char> list;
+//   list.push_back('a');
+//   list.push_back('b');
+//   return list;
+// }
+// ::std::list<char> l = GetParameterChars();
+// INSTANTIATE_TEST_CASE_P(CharSequence2,
+//                         CharTest,
+//                         ValuesIn(l.begin(), l.end()));
+//
+template <typename ForwardIterator>
+internal::ParamGenerator<
+    typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+  ForwardIterator begin,
+  ForwardIterator end) {
+  typedef typename ::std::iterator_traits<ForwardIterator>::value_type
+      ParamType;
+  return internal::ParamGenerator<ParamType>(
+      new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
+}
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
+  return ValuesIn(array, array + N);
+}
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+    const Container& container) {
+  return ValuesIn(container.begin(), container.end());
+}
+
+// Values() allows generating tests from explicitly specified list of
+// parameters.
+//
+// Synopsis:
+// Values(T v1, T v2, ..., T vN)
+//   - returns a generator producing sequences with elements v1, v2, ..., vN.
+//
+// For example, this instantiates tests from test case BarTest each
+// with values "one", "two", and "three":
+//
+// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
+//
+// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
+// The exact type of values will depend on the type of parameter in BazTest.
+//
+// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
+//
+// Currently, Values() supports from 1 to 50 parameters.
+//
+template <typename T1>
+internal::ValueArray1<T1> Values(T1 v1) {
+  return internal::ValueArray1<T1>(v1);
+}
+
+template <typename T1, typename T2>
+internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) {
+  return internal::ValueArray2<T1, T2>(v1, v2);
+}
+
+template <typename T1, typename T2, typename T3>
+internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) {
+  return internal::ValueArray3<T1, T2, T3>(v1, v2, v3);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) {
+  return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5) {
+  return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6) {
+  return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7) {
+  return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5,
+      v6, v7);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+  return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4,
+      v5, v6, v7, v8);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+  return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+  return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
+    T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11) {
+  return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
+      T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+    T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12) {
+  return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+    T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13) {
+  return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+  return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+  return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16) {
+  return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17) {
+  return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18) {
+  return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) {
+  return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) {
+  return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) {
+  return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22) {
+  return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23) {
+  return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24) {
+  return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2,
+      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
+      v19, v20, v21, v22, v23, v24);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
+    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
+    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) {
+  return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
+      v18, v19, v20, v21, v22, v23, v24, v25);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+    T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26) {
+  return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
+      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+    T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27) {
+  return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
+      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+    T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28) {
+  return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
+      v28);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29) {
+  return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
+      v27, v28, v29);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) {
+  return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
+      v26, v27, v28, v29, v30);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) {
+  return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
+      v25, v26, v27, v28, v29, v30, v31);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32) {
+  return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33) {
+  return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
+    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
+    T31 v31, T32 v32, T33 v33, T34 v34) {
+  return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
+      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) {
+  return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
+      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) {
+  return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37) {
+  return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36, v37);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37, T38 v38) {
+  return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2,
+      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
+      v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32,
+      v33, v34, v35, v36, v37, v38);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37, T38 v38, T39 v39) {
+  return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
+      v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
+      v32, v33, v34, v35, v36, v37, v38, v39);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
+    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
+    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27,
+    T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35,
+    T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) {
+  return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
+      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
+      v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+    T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) {
+  return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
+      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28,
+      v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+    T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42) {
+  return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
+      v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41,
+      v42);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+    T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42, T43 v43) {
+  return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
+      v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40,
+      v41, v42, v43);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42, T43 v43, T44 v44) {
+  return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
+      v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
+      v40, v41, v42, v43, v44);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
+    T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
+    T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) {
+  return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
+      v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38,
+      v39, v40, v41, v42, v43, v44, v45);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) {
+  return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
+      v38, v39, v40, v41, v42, v43, v44, v45, v46);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) {
+  return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
+      v38, v39, v40, v41, v42, v43, v44, v45, v46, v47);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47,
+    T48 v48) {
+  return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
+      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36,
+      v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
+    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
+    T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38,
+    T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46,
+    T47 v47, T48 v48, T49 v49) {
+  return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
+      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35,
+      v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37,
+    T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45,
+    T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) {
+  return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,
+      v48, v49, v50);
+}
+
+// Bool() allows generating tests with parameters in a set of (false, true).
+//
+// Synopsis:
+// Bool()
+//   - returns a generator producing sequences with elements {false, true}.
+//
+// It is useful when testing code that depends on Boolean flags. Combinations
+// of multiple flags can be tested when several Bool()'s are combined using
+// Combine() function.
+//
+// In the following example all tests in the test case FlagDependentTest
+// will be instantiated twice with parameters false and true.
+//
+// class FlagDependentTest : public testing::TestWithParam<bool> {
+//   virtual void SetUp() {
+//     external_flag = GetParam();
+//   }
+// }
+// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
+//
+inline internal::ParamGenerator<bool> Bool() {
+  return Values(false, true);
+}
+
+#if GTEST_HAS_COMBINE
+// Combine() allows the user to combine two or more sequences to produce
+// values of a Cartesian product of those sequences' elements.
+//
+// Synopsis:
+// Combine(gen1, gen2, ..., genN)
+//   - returns a generator producing sequences with elements coming from
+//     the Cartesian product of elements from the sequences generated by
+//     gen1, gen2, ..., genN. The sequence elements will have a type of
+//     tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
+//     of elements from sequences produces by gen1, gen2, ..., genN.
+//
+// Combine can have up to 10 arguments. This number is currently limited
+// by the maximum number of elements in the tuple implementation used by Google
+// Test.
+//
+// Example:
+//
+// This will instantiate tests in test case AnimalTest each one with
+// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
+// tuple("dog", BLACK), and tuple("dog", WHITE):
+//
+// enum Color { BLACK, GRAY, WHITE };
+// class AnimalTest
+//     : public testing::TestWithParam<tuple<const char*, Color> > {...};
+//
+// TEST_P(AnimalTest, AnimalLooksNice) {...}
+//
+// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
+//                         Combine(Values("cat", "dog"),
+//                                 Values(BLACK, WHITE)));
+//
+// This will instantiate tests in FlagDependentTest with all variations of two
+// Boolean flags:
+//
+// class FlagDependentTest
+//     : public testing::TestWithParam<tuple(bool, bool)> > {
+//   virtual void SetUp() {
+//     // Assigns external_flag_1 and external_flag_2 values from the tuple.
+//     tie(external_flag_1, external_flag_2) = GetParam();
+//   }
+// };
+//
+// TEST_P(FlagDependentTest, TestFeature1) {
+//   // Test your code using external_flag_1 and external_flag_2 here.
+// }
+// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
+//                         Combine(Bool(), Bool()));
+//
+template <typename Generator1, typename Generator2>
+internal::CartesianProductHolder2<Generator1, Generator2> Combine(
+    const Generator1& g1, const Generator2& g2) {
+  return internal::CartesianProductHolder2<Generator1, Generator2>(
+      g1, g2);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3>
+internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3) {
+  return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>(
+      g1, g2, g3);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4>
+internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
+    Generator4> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4) {
+  return internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
+      Generator4>(
+      g1, g2, g3, g4);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5>
+internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
+    Generator4, Generator5> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5) {
+  return internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
+      Generator4, Generator5>(
+      g1, g2, g3, g4, g5);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6>
+internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6) {
+  return internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6>(
+      g1, g2, g3, g4, g5, g6);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7>
+internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7) {
+  return internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7>(
+      g1, g2, g3, g4, g5, g6, g7);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8>
+internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8) {
+  return internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8>(
+      g1, g2, g3, g4, g5, g6, g7, g8);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8, typename Generator9>
+internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8,
+    Generator9> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8, const Generator9& g9) {
+  return internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>(
+      g1, g2, g3, g4, g5, g6, g7, g8, g9);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8, typename Generator9,
+    typename Generator10>
+internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
+    Generator10> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8, const Generator9& g9,
+        const Generator10& g10) {
+  return internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
+      Generator10>(
+      g1, g2, g3, g4, g5, g6, g7, g8, g9, g10);
+}
+#endif  // GTEST_HAS_COMBINE
+
+
+
+#define TEST_P(test_case_name, test_name) \
+  class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+      : public test_case_name { \
+   public: \
+    GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
+    virtual void TestBody(); \
+   private: \
+    static int AddToRegistry() { \
+      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+          GetTestCasePatternHolder<test_case_name>(\
+              #test_case_name, __FILE__, __LINE__)->AddTestPattern(\
+                  #test_case_name, \
+                  #test_name, \
+                  new ::testing::internal::TestMetaFactory< \
+                      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
+      return 0; \
+    } \
+    static int gtest_registering_dummy_; \
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+        GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
+  }; \
+  int GTEST_TEST_CLASS_NAME_(test_case_name, \
+                             test_name)::gtest_registering_dummy_ = \
+      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
+  void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
+  ::testing::internal::ParamGenerator<test_case_name::ParamType> \
+      gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
+  int gtest_##prefix##test_case_name##_dummy_ = \
+      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+          GetTestCasePatternHolder<test_case_name>(\
+              #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
+                  #prefix, \
+                  &gtest_##prefix##test_case_name##_EvalGenerator_, \
+                  __FILE__, __LINE__)
+
+}  // namespace testing
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+// 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_
+// 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: mheule@google.com (Markus Heule)
+//
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+
+#include <iosfwd>
+#include <vector>
+
+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 GTEST_API_ TestPartResult {
+ public:
+  // The possible outcomes of a test part (i.e. an assertion or an
+  // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
+  enum Type {
+    kSuccess,          // Succeeded.
+    kNonFatalFailure,  // Failed but the test can continue.
+    kFatalFailure      // Failed and the test should be terminated.
+  };
+
+  // C'tor.  TestPartResult does NOT have a default constructor.
+  // Always use this constructor (with parameters) to create a
+  // TestPartResult object.
+  TestPartResult(Type a_type,
+                 const char* a_file_name,
+                 int a_line_number,
+                 const char* a_message)
+      : type_(a_type),
+        file_name_(a_file_name),
+        line_number_(a_line_number),
+        summary_(ExtractSummary(a_message)),
+        message_(a_message) {
+  }
+
+  // Gets the outcome of the test part.
+  Type 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 summary of the failure message.
+  const char* summary() const { return summary_.c_str(); }
+
+  // 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_ == kSuccess; }
+
+  // Returns true iff the test part failed.
+  bool failed() const { return type_ != kSuccess; }
+
+  // Returns true iff the test part non-fatally failed.
+  bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
+
+  // Returns true iff the test part fatally failed.
+  bool fatally_failed() const { return type_ == kFatalFailure; }
+ private:
+  Type type_;
+
+  // Gets the summary of the failure message by omitting the stack
+  // trace in it.
+  static internal::String ExtractSummary(const char* message);
+
+  // 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 summary_;  // The test failure summary.
+  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.
+//
+// Don't inherit from TestPartResultArray as its destructor is not
+// virtual.
+class GTEST_API_ TestPartResultArray {
+ public:
+  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:
+  std::vector<TestPartResult> array_;
+
+  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;
+};
+
+namespace internal {
+
+// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
+// statement generates new fatal failures. To do so it registers itself as the
+// current test part result reporter. Besides checking if fatal failures were
+// reported, it only delegates the reporting to the former result reporter.
+// The original result reporter is restored in the destructor.
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+class GTEST_API_ HasNewFatalFailureHelper
+    : public TestPartResultReporterInterface {
+ public:
+  HasNewFatalFailureHelper();
+  virtual ~HasNewFatalFailureHelper();
+  virtual void ReportTestPartResult(const TestPartResult& result);
+  bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
+ private:
+  bool has_new_fatal_failure_;
+  TestPartResultReporterInterface* original_reporter_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
+};
+
+}  // namespace internal
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+// 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)
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+
+// This header implements typed tests and type-parameterized tests.
+
+// Typed (aka type-driven) tests repeat the same test for types in a
+// list.  You must know which types you want to test with when writing
+// typed tests. Here's how you do it:
+
+#if 0
+
+// First, define a fixture class template.  It should be parameterized
+// by a type.  Remember to derive it from testing::Test.
+template <typename T>
+class FooTest : public testing::Test {
+ public:
+  ...
+  typedef std::list<T> List;
+  static T shared_;
+  T value_;
+};
+
+// Next, associate a list of types with the test case, which will be
+// repeated for each type in the list.  The typedef is necessary for
+// the macro to parse correctly.
+typedef testing::Types<char, int, unsigned int> MyTypes;
+TYPED_TEST_CASE(FooTest, MyTypes);
+
+// If the type list contains only one type, you can write that type
+// directly without Types<...>:
+//   TYPED_TEST_CASE(FooTest, int);
+
+// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
+// tests for this test case as you want.
+TYPED_TEST(FooTest, DoesBlah) {
+  // Inside a test, refer to TypeParam to get the type parameter.
+  // Since we are inside a derived class template, C++ requires use to
+  // visit the members of FooTest via 'this'.
+  TypeParam n = this->value_;
+
+  // To visit static members of the fixture, add the TestFixture::
+  // prefix.
+  n += TestFixture::shared_;
+
+  // To refer to typedefs in the fixture, add the "typename
+  // TestFixture::" prefix.
+  typename TestFixture::List values;
+  values.push_back(n);
+  ...
+}
+
+TYPED_TEST(FooTest, HasPropertyA) { ... }
+
+#endif  // 0
+
+// Type-parameterized tests are abstract test patterns parameterized
+// by a type.  Compared with typed tests, type-parameterized tests
+// allow you to define the test pattern without knowing what the type
+// parameters are.  The defined pattern can be instantiated with
+// different types any number of times, in any number of translation
+// units.
+//
+// If you are designing an interface or concept, you can define a
+// suite of type-parameterized tests to verify properties that any
+// valid implementation of the interface/concept should have.  Then,
+// each implementation can easily instantiate the test suite to verify
+// that it conforms to the requirements, without having to write
+// similar tests repeatedly.  Here's an example:
+
+#if 0
+
+// First, define a fixture class template.  It should be parameterized
+// by a type.  Remember to derive it from testing::Test.
+template <typename T>
+class FooTest : public testing::Test {
+  ...
+};
+
+// Next, declare that you will define a type-parameterized test case
+// (the _P suffix is for "parameterized" or "pattern", whichever you
+// prefer):
+TYPED_TEST_CASE_P(FooTest);
+
+// Then, use TYPED_TEST_P() to define as many type-parameterized tests
+// for this type-parameterized test case as you want.
+TYPED_TEST_P(FooTest, DoesBlah) {
+  // Inside a test, refer to TypeParam to get the type parameter.
+  TypeParam n = 0;
+  ...
+}
+
+TYPED_TEST_P(FooTest, HasPropertyA) { ... }
+
+// Now the tricky part: you need to register all test patterns before
+// you can instantiate them.  The first argument of the macro is the
+// test case name; the rest are the names of the tests in this test
+// case.
+REGISTER_TYPED_TEST_CASE_P(FooTest,
+                           DoesBlah, HasPropertyA);
+
+// Finally, you are free to instantiate the pattern with the types you
+// want.  If you put the above code in a header file, you can #include
+// it in multiple C++ source files and instantiate it multiple times.
+//
+// To distinguish different instances of the pattern, the first
+// argument to the INSTANTIATE_* macro is a prefix that will be added
+// to the actual test case name.  Remember to pick unique prefixes for
+// different instances.
+typedef testing::Types<char, int, unsigned int> MyTypes;
+INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
+
+// If the type list contains only one type, you can write that type
+// directly without Types<...>:
+//   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
+
+#endif  // 0
+
+
+// Implements typed tests.
+
+#if GTEST_HAS_TYPED_TEST
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the name of the typedef for the type parameters of the
+// given test case.
+#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
+
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
+#define TYPED_TEST_CASE(CaseName, Types) \
+  typedef ::testing::internal::TypeList< Types >::type \
+      GTEST_TYPE_PARAMS_(CaseName)
+
+#define TYPED_TEST(CaseName, TestName) \
+  template <typename gtest_TypeParam_> \
+  class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
+      : public CaseName<gtest_TypeParam_> { \
+   private: \
+    typedef CaseName<gtest_TypeParam_> TestFixture; \
+    typedef gtest_TypeParam_ TypeParam; \
+    virtual void TestBody(); \
+  }; \
+  bool gtest_##CaseName##_##TestName##_registered_ = \
+      ::testing::internal::TypeParameterizedTest< \
+          CaseName, \
+          ::testing::internal::TemplateSel< \
+              GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
+          GTEST_TYPE_PARAMS_(CaseName)>::Register(\
+              "", #CaseName, #TestName, 0); \
+  template <typename gtest_TypeParam_> \
+  void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
+
+#endif  // GTEST_HAS_TYPED_TEST
+
+// Implements type-parameterized tests.
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the namespace name that the type-parameterized tests for
+// the given type-parameterized test case are defined in.  The exact
+// name of the namespace is subject to change without notice.
+#define GTEST_CASE_NAMESPACE_(TestCaseName) \
+  gtest_case_##TestCaseName##_
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the name of the variable used to remember the names of
+// the defined tests in the given test case.
+#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
+  gtest_typed_test_case_p_state_##TestCaseName##_
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
+//
+// Expands to the name of the variable used to remember the names of
+// the registered tests in the given test case.
+#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
+  gtest_registered_test_names_##TestCaseName##_
+
+// The variables defined in the type-parameterized test macros are
+// static as typically these macros are used in a .h file that can be
+// #included in multiple translation units linked together.
+#define TYPED_TEST_CASE_P(CaseName) \
+  static ::testing::internal::TypedTestCasePState \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
+
+#define TYPED_TEST_P(CaseName, TestName) \
+  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
+  template <typename gtest_TypeParam_> \
+  class TestName : public CaseName<gtest_TypeParam_> { \
+   private: \
+    typedef CaseName<gtest_TypeParam_> TestFixture; \
+    typedef gtest_TypeParam_ TypeParam; \
+    virtual void TestBody(); \
+  }; \
+  static bool gtest_##TestName##_defined_ = \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
+          __FILE__, __LINE__, #CaseName, #TestName); \
+  } \
+  template <typename gtest_TypeParam_> \
+  void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
+
+#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
+  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
+  typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
+  } \
+  static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
+          __FILE__, __LINE__, #__VA_ARGS__)
+
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
+#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
+  bool gtest_##Prefix##_##CaseName = \
+      ::testing::internal::TypeParameterizedTestCase<CaseName, \
+          GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
+          ::testing::internal::TypeList< Types >::type>::Register(\
+              #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+
+// Depending on the platform, different string classes are available.
+// 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 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_GLOBAL_STRING to 0.
+//
+// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined
+// heuristically.
+
+namespace testing {
+
+// Declares the flags.
+
+// This flag temporary enables the disabled tests.
+GTEST_DECLARE_bool_(also_run_disabled_tests);
+
+// This flag brings the debugger on an assertion failure.
+GTEST_DECLARE_bool_(break_on_failure);
+
+// This flag controls whether Google Test catches all test-thrown exceptions
+// and logs them as failures.
+GTEST_DECLARE_bool_(catch_exceptions);
+
+// This flag enables using colors in terminal output. Available values are
+// "yes" to enable colors, "no" (disable colors), or "auto" (the default)
+// to let Google Test decide.
+GTEST_DECLARE_string_(color);
+
+// This flag sets up the filter to select by name using a glob pattern
+// the tests to run. If the filter is not given all tests are executed.
+GTEST_DECLARE_string_(filter);
+
+// This flag causes the Google Test to list tests. None of the tests listed
+// are actually run if the flag is provided.
+GTEST_DECLARE_bool_(list_tests);
+
+// This flag controls whether Google Test emits a detailed XML report to a file
+// in addition to its normal textual output.
+GTEST_DECLARE_string_(output);
+
+// This flags control whether Google Test prints the elapsed time for each
+// test.
+GTEST_DECLARE_bool_(print_time);
+
+// This flag specifies the random number seed.
+GTEST_DECLARE_int32_(random_seed);
+
+// This flag sets how many times the tests are repeated. The default value
+// is 1. If the value is -1 the tests are repeating forever.
+GTEST_DECLARE_int32_(repeat);
+
+// This flag controls whether Google Test includes Google Test internal
+// stack frames in failure stack traces.
+GTEST_DECLARE_bool_(show_internal_stack_frames);
+
+// When this flag is specified, tests' order is randomized on every iteration.
+GTEST_DECLARE_bool_(shuffle);
+
+// This flag specifies the maximum number of stack frames to be
+// printed in a failure message.
+GTEST_DECLARE_int32_(stack_trace_depth);
+
+// When this flag is specified, a failed assertion will throw an
+// exception if exceptions are enabled, or exit the program with a
+// non-zero code otherwise.
+GTEST_DECLARE_bool_(throw_on_failure);
+
+// The upper limit for valid stack trace depths.
+const int kMaxStackTraceDepth = 100;
+
+namespace internal {
+
+class AssertHelper;
+class DefaultGlobalTestPartResultReporter;
+class ExecDeathTest;
+class NoExecDeathTest;
+class FinalSuccessChecker;
+class GTestFlagSaver;
+class TestInfoImpl;
+class TestResultAccessor;
+class TestEventListenersAccessor;
+class TestEventRepeater;
+class WindowsDeathTest;
+class UnitTestImpl* GetUnitTestImpl();
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
+                                    const String& message);
+class PrettyUnitTestResultPrinter;
+class XmlUnitTestResultPrinter;
+
+// 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 describes how it failed.
+//
+// To create an instance of this class, use one of the factory functions
+// (AssertionSuccess() and AssertionFailure()).
+//
+// This class is useful for two purposes:
+//   1. Defining predicate functions to be used with Boolean test assertions
+//      EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
+//   2. Defining predicate-format functions to be
+//      used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
+//
+// For example, if you define IsEven predicate:
+//
+//   testing::AssertionResult IsEven(int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess();
+//     else
+//       return testing::AssertionFailure() << n << " is odd";
+//   }
+//
+// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
+// will print the message
+//
+//   Value of: IsEven(Fib(5))
+//     Actual: false (5 is odd)
+//   Expected: true
+//
+// instead of a more opaque
+//
+//   Value of: IsEven(Fib(5))
+//     Actual: false
+//   Expected: true
+//
+// in case IsEven is a simple Boolean predicate.
+//
+// If you expect your predicate to be reused and want to support informative
+// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
+// about half as often as positive ones in our tests), supply messages for
+// both success and failure cases:
+//
+//   testing::AssertionResult IsEven(int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess() << n << " is even";
+//     else
+//       return testing::AssertionFailure() << n << " is odd";
+//   }
+//
+// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
+//
+//   Value of: IsEven(Fib(6))
+//     Actual: true (8 is even)
+//   Expected: false
+//
+// NB: Predicates that support negative Boolean assertions have reduced
+// performance in positive ones so be careful not to use them in tests
+// that have lots (tens of thousands) of positive Boolean assertions.
+//
+// To use this class with EXPECT_PRED_FORMAT assertions such as:
+//
+//   // Verifies that Foo() returns an even number.
+//   EXPECT_PRED_FORMAT1(IsEven, Foo());
+//
+// you need to define:
+//
+//   testing::AssertionResult IsEven(const char* expr, int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess();
+//     else
+//       return testing::AssertionFailure()
+//         << "Expected: " << expr << " is even\n  Actual: it's " << n;
+//   }
+//
+// If Foo() returns 5, you will see the following message:
+//
+//   Expected: Foo() is even
+//     Actual: it's 5
+//
+class GTEST_API_ AssertionResult {
+ public:
+  // Copy constructor.
+  // Used in EXPECT_TRUE/FALSE(assertion_result).
+  AssertionResult(const AssertionResult& other);
+  // Used in the EXPECT_TRUE/FALSE(bool_expression).
+  explicit AssertionResult(bool success) : success_(success) {}
+
+  // Returns true iff the assertion succeeded.
+  operator bool() const { return success_; }  // NOLINT
+
+  // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+  AssertionResult operator!() const;
+
+  // Returns the text streamed into this AssertionResult. Test assertions
+  // use it when they fail (i.e., the predicate's outcome doesn't match the
+  // assertion's expectation). When nothing has been streamed into the
+  // object, returns an empty string.
+  const char* message() const {
+    return message_.get() != NULL && message_->c_str() != NULL ?
+           message_->c_str() : "";
+  }
+  // TODO(vladl@google.com): Remove this after making sure no clients use it.
+  // Deprecated; please use message() instead.
+  const char* failure_message() const { return message(); }
+
+  // Streams a custom failure message into this object.
+  template <typename T> AssertionResult& operator<<(const T& value);
+
+ private:
+  // No implementation - we want AssertionResult to be
+  // copy-constructible but not assignable.
+  void operator=(const AssertionResult& other);
+
+  // Stores result of the assertion predicate.
+  bool success_;
+  // Stores the message describing the condition in case the expectation
+  // construct is not satisfied with the predicate's outcome.
+  // Referenced via a pointer to avoid taking too much stack frame space
+  // with test assertions.
+  internal::scoped_ptr<internal::String> message_;
+};  // class AssertionResult
+
+// Streams a custom failure message into this object.
+template <typename T>
+AssertionResult& AssertionResult::operator<<(const T& value) {
+  Message msg;
+  if (message_.get() != NULL)
+    msg << *message_;
+  msg << value;
+  message_.reset(new internal::String(msg.GetString()));
+  return *this;
+}
+
+// Makes a successful assertion result.
+GTEST_API_ AssertionResult AssertionSuccess();
+
+// Makes a failed assertion result.
+GTEST_API_ AssertionResult AssertionFailure();
+
+// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << msg.
+GTEST_API_ 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 GTEST_API_ Test {
+ public:
+  friend class internal::TestInfoImpl;
+
+  // Defines types for pointers to functions that set up and tear down
+  // a test case.
+  typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;
+  typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;
+
+  // The d'tor is virtual as we intend to inherit from Test.
+  virtual ~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() {}
+
+  // Returns true iff the current test has a fatal failure.
+  static bool HasFatalFailure();
+
+  // Returns true iff the current test has a non-fatal failure.
+  static bool HasNonfatalFailure();
+
+  // Returns true iff the current test has a (either fatal or
+  // non-fatal) failure.
+  static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
+
+  // 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 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);
+};
+
+typedef internal::TimeInMillis TimeInMillis;
+
+// 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* a_key, const char* a_value) :
+    key_(a_key), value_(a_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.
+  internal::String key_;
+  // The value supplied by the user.
+  internal::String value_;
+};
+
+// 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 GTEST_API_ TestResult {
+ public:
+  // Creates an empty TestResult.
+  TestResult();
+
+  // D'tor.  Do not inherit from TestResult.
+  ~TestResult();
+
+  // 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 the number of the test properties.
+  int test_property_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;
+
+  // Returns true iff the test fatally failed.
+  bool HasFatalFailure() const;
+
+  // Returns true iff the test has a non-fatal failure.
+  bool HasNonfatalFailure() const;
+
+  // Returns the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns the i-th test part result among all the results. i can range
+  // from 0 to test_property_count() - 1. If i is not in that range, aborts
+  // the program.
+  const TestPartResult& GetTestPartResult(int i) const;
+
+  // Returns the i-th test property. i can range from 0 to
+  // test_property_count() - 1. If i is not in that range, aborts the
+  // program.
+  const TestProperty& GetTestProperty(int i) const;
+
+ private:
+  friend class TestInfo;
+  friend class UnitTest;
+  friend class internal::DefaultGlobalTestPartResultReporter;
+  friend class internal::ExecDeathTest;
+  friend class internal::TestInfoImpl;
+  friend class internal::TestResultAccessor;
+  friend class internal::UnitTestImpl;
+  friend class internal::WindowsDeathTest;
+
+  // Gets the vector of TestPartResults.
+  const std::vector<TestPartResult>& test_part_results() const {
+    return test_part_results_;
+  }
+
+  // Gets the vector of TestProperties.
+  const std::vector<TestProperty>& test_properties() const {
+    return test_properties_;
+  }
+
+  // Sets the elapsed time.
+  void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
+
+  // 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 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 TestProperty& test_property);
+
+  // Adds a test part result to the list.
+  void AddTestPartResult(const TestPartResult& test_part_result);
+
+  // 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 test part results.
+  void ClearTestPartResults();
+
+  // Clears the object.
+  void Clear();
+
+  // Protects mutable state of the property vector and of owned
+  // properties, whose values may be updated.
+  internal::Mutex test_properites_mutex_;
+
+  // The vector of TestPartResults
+  std::vector<TestPartResult> test_part_results_;
+  // The vector of TestProperties
+  std::vector<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
+
+// 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 GTEST_API_ TestInfo {
+ public:
+  // Destructs a TestInfo object.  This function is not virtual, so
+  // don't inherit from TestInfo.
+  ~TestInfo();
+
+  // Returns the test case name.
+  const char* test_case_name() const;
+
+  // Returns the test name.
+  const char* name() const;
+
+  // Returns the test case comment.
+  const char* test_case_comment() const;
+
+  // Returns the test comment.
+  const char* comment() const;
+
+  // Returns true if this test should run, that is if the test is not disabled
+  // (or it is disabled but the also_run_disabled_tests flag has been specified)
+  // and its full name matches the user-specified filter.
+  //
+  // 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 TestResult* result() const;
+
+ private:
+#if GTEST_HAS_DEATH_TEST
+  friend class internal::DefaultDeathTestFactory;
+#endif  // GTEST_HAS_DEATH_TEST
+  friend class Test;
+  friend class TestCase;
+  friend class internal::TestInfoImpl;
+  friend class internal::UnitTestImpl;
+  friend TestInfo* internal::MakeAndRegisterTestInfo(
+      const char* test_case_name, const char* name,
+      const char* test_case_comment, const char* comment,
+      internal::TypeId fixture_class_id,
+      Test::SetUpTestCaseFunc set_up_tc,
+      Test::TearDownTestCaseFunc tear_down_tc,
+      internal::TestFactoryBase* factory);
+
+  // Returns true if this test matches the user-specified filter.
+  bool matches_filter() const;
+
+  // 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. The newly constructed instance assumes
+  // ownership of the factory object.
+  TestInfo(const char* test_case_name, const char* name,
+           const char* test_case_comment, const char* comment,
+           internal::TypeId fixture_class_id,
+           internal::TestFactoryBase* factory);
+
+  // An opaque implementation object.
+  internal::TestInfoImpl* impl_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);
+};
+
+// A test case, which consists of a vector of TestInfos.
+//
+// TestCase is not copyable.
+class GTEST_API_ 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, const char* comment,
+           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 the test case comment.
+  const char* comment() const { return comment_.c_str(); }
+
+  // Returns true if any test in this test case should run.
+  bool should_run() const { return should_run_; }
+
+  // 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.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns the i-th test among all the tests. i can range from 0 to
+  // total_test_count() - 1. If i is not in that range, returns NULL.
+  const TestInfo* GetTestInfo(int i) const;
+
+ private:
+  friend class Test;
+  friend class internal::UnitTestImpl;
+
+  // Gets the (mutable) vector of TestInfos in this TestCase.
+  std::vector<TestInfo*>& test_info_list() { return test_info_list_; }
+
+  // Gets the (immutable) vector of TestInfos in this TestCase.
+  const std::vector<TestInfo*>& test_info_list() const {
+    return test_info_list_;
+  }
+
+  // Returns the i-th test among all the tests. i can range from 0 to
+  // total_test_count() - 1. If i is not in that range, returns NULL.
+  TestInfo* GetMutableTestInfo(int i);
+
+  // Sets the should_run member.
+  void set_should_run(bool should) { should_run_ = should; }
+
+  // Adds a TestInfo to this test case.  Will delete the TestInfo upon
+  // destruction of the TestCase object.
+  void AddTestInfo(TestInfo * test_info);
+
+  // 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();
+
+  // Returns true iff test passed.
+  static bool TestPassed(const TestInfo * test_info);
+
+  // Returns true iff test failed.
+  static bool TestFailed(const TestInfo * test_info);
+
+  // Returns true iff test is disabled.
+  static bool TestDisabled(const TestInfo * test_info);
+
+  // Returns true if the given test should run.
+  static bool ShouldRunTest(const TestInfo *test_info);
+
+  // Shuffles the tests in this test case.
+  void ShuffleTests(internal::Random* random);
+
+  // Restores the test order to before the first shuffle.
+  void UnshuffleTests();
+
+  // Name of the test case.
+  internal::String name_;
+  // Comment on the test case.
+  internal::String comment_;
+  // The vector of TestInfos in their original order.  It owns the
+  // elements in the vector.
+  std::vector<TestInfo*> test_info_list_;
+  // Provides a level of indirection for the test list to allow easy
+  // shuffling and restoring the test order.  The i-th element in this
+  // vector is the index of the i-th test in the shuffled test list.
+  std::vector<int> test_indices_;
+  // 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.
+  TimeInMillis elapsed_time_;
+
+  // We disallow copying TestCases.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);
+};
+
+// 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; }
+};
+
+// The interface for tracing execution of tests. The methods are organized in
+// the order the corresponding events are fired.
+class TestEventListener {
+ public:
+  virtual ~TestEventListener() {}
+
+  // Fired before any test activity starts.
+  virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;
+
+  // Fired before each iteration of tests starts.  There may be more than
+  // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration
+  // index, starting from 0.
+  virtual void OnTestIterationStart(const UnitTest& unit_test,
+                                    int iteration) = 0;
+
+  // Fired before environment set-up for each iteration of tests starts.
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;
+
+  // Fired after environment set-up for each iteration of tests ends.
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
+
+  // Fired before the test case starts.
+  virtual void OnTestCaseStart(const TestCase& test_case) = 0;
+
+  // Fired before the test starts.
+  virtual void OnTestStart(const TestInfo& test_info) = 0;
+
+  // Fired after a failed assertion or a SUCCESS().
+  virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
+
+  // Fired after the test ends.
+  virtual void OnTestEnd(const TestInfo& test_info) = 0;
+
+  // Fired after the test case ends.
+  virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
+
+  // Fired before environment tear-down for each iteration of tests starts.
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
+
+  // Fired after environment tear-down for each iteration of tests ends.
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;
+
+  // Fired after each iteration of tests finishes.
+  virtual void OnTestIterationEnd(const UnitTest& unit_test,
+                                  int iteration) = 0;
+
+  // Fired after all test activities have ended.
+  virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;
+};
+
+// The convenience class for users who need to override just one or two
+// methods and are not concerned that a possible change to a signature of
+// the methods they override will not be caught during the build.  For
+// comments about each method please see the definition of TestEventListener
+// above.
+class EmptyTestEventListener : public TestEventListener {
+ public:
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
+                                    int /*iteration*/) {}
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
+  virtual void OnTestStart(const TestInfo& /*test_info*/) {}
+  virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
+  virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
+  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
+                                  int /*iteration*/) {}
+  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+};
+
+// TestEventListeners lets users add listeners to track events in Google Test.
+class GTEST_API_ TestEventListeners {
+ public:
+  TestEventListeners();
+  ~TestEventListeners();
+
+  // Appends an event listener to the end of the list. Google Test assumes
+  // the ownership of the listener (i.e. it will delete the listener when
+  // the test program finishes).
+  void Append(TestEventListener* listener);
+
+  // Removes the given event listener from the list and returns it.  It then
+  // becomes the caller's responsibility to delete the listener. Returns
+  // NULL if the listener is not found in the list.
+  TestEventListener* Release(TestEventListener* listener);
+
+  // Returns the standard listener responsible for the default console
+  // output.  Can be removed from the listeners list to shut down default
+  // console output.  Note that removing this object from the listener list
+  // with Release transfers its ownership to the caller and makes this
+  // function return NULL the next time.
+  TestEventListener* default_result_printer() const {
+    return default_result_printer_;
+  }
+
+  // Returns the standard listener responsible for the default XML output
+  // controlled by the --gtest_output=xml flag.  Can be removed from the
+  // listeners list by users who want to shut down the default XML output
+  // controlled by this flag and substitute it with custom one.  Note that
+  // removing this object from the listener list with Release transfers its
+  // ownership to the caller and makes this function return NULL the next
+  // time.
+  TestEventListener* default_xml_generator() const {
+    return default_xml_generator_;
+  }
+
+ private:
+  friend class TestCase;
+  friend class internal::DefaultGlobalTestPartResultReporter;
+  friend class internal::NoExecDeathTest;
+  friend class internal::TestEventListenersAccessor;
+  friend class internal::TestInfoImpl;
+  friend class internal::UnitTestImpl;
+
+  // Returns repeater that broadcasts the TestEventListener events to all
+  // subscribers.
+  TestEventListener* repeater();
+
+  // Sets the default_result_printer attribute to the provided listener.
+  // The listener is also added to the listener list and previous
+  // default_result_printer is removed from it and deleted. The listener can
+  // also be NULL in which case it will not be added to the list. Does
+  // nothing if the previous and the current listener objects are the same.
+  void SetDefaultResultPrinter(TestEventListener* listener);
+
+  // Sets the default_xml_generator attribute to the provided listener.  The
+  // listener is also added to the listener list and previous
+  // default_xml_generator is removed from it and deleted. The listener can
+  // also be NULL in which case it will not be added to the list. Does
+  // nothing if the previous and the current listener objects are the same.
+  void SetDefaultXmlGenerator(TestEventListener* listener);
+
+  // Controls whether events will be forwarded by the repeater to the
+  // listeners in the list.
+  bool EventForwardingEnabled() const;
+  void SuppressEventForwarding();
+
+  // The actual list of listeners.
+  internal::TestEventRepeater* repeater_;
+  // Listener responsible for the standard result output.
+  TestEventListener* default_result_printer_;
+  // Listener responsible for the creation of the XML output file.
+  TestEventListener* default_xml_generator_;
+
+  // We disallow copying TestEventListeners.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners);
+};
+
+// A UnitTest consists of a vector 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 GTEST_API_ 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();
+
+  // 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 working directory when the first TEST() or TEST_F()
+  // was executed.  The UnitTest object owns the string.
+  const char* original_working_dir() const;
+
+  // 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;
+
+  // Returns the random seed used at the start of the current test run.
+  int random_seed() const;
+
+#if GTEST_HAS_PARAM_TEST
+  // Returns the ParameterizedTestCaseRegistry object used to keep track of
+  // value-parameterized tests and instantiate and register them.
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  internal::ParameterizedTestCaseRegistry& parameterized_test_registry();
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // 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;
+
+  // Returns true iff the unit test passed (i.e. all test cases passed).
+  bool Passed() const;
+
+  // Returns true iff the unit test failed (i.e. some test case failed
+  // or something outside of all tests failed).
+  bool Failed() const;
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  const TestCase* GetTestCase(int i) const;
+
+  // Returns the list of event listeners that can be used to track events
+  // inside Google Test.
+  TestEventListeners& listeners();
+
+ private:
+  // 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.
+  void AddTestPartResult(TestPartResult::Type 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);
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  TestCase* GetMutableTestCase(int i);
+
+  // Accessors for the implementation object.
+  internal::UnitTestImpl* impl() { return impl_; }
+  const internal::UnitTestImpl* impl() const { return impl_; }
+
+  // These classes and funcions are friends as they need to access private
+  // members of UnitTest.
+  friend class Test;
+  friend class internal::AssertHelper;
+  friend class internal::ScopedTrace;
+  friend Environment* AddGlobalTestEnvironment(Environment* env);
+  friend internal::UnitTestImpl* internal::GetUnitTestImpl();
+  friend void internal::ReportFailureInUnknownLocation(
+      TestPartResult::Type result_type,
+      const internal::String& message);
+
+  // 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);
+}
+
+// Initializes Google Test.  This must be called before calling
+// RUN_ALL_TESTS().  In particular, it 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.
+//
+// Calling the function for the second time has no user-visible effect.
+GTEST_API_ void InitGoogleTest(int* argc, char** argv);
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
+
+namespace internal {
+
+// These overloaded versions handle ::std::string and ::std::wstring.
+GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) {
+  return (Message() << '"' << str << '"').GetString();
+}
+
+#if GTEST_HAS_STD_WSTRING
+GTEST_API_ 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
+GTEST_API_ inline String FormatForFailureMessage(const ::string& str) {
+  return (Message() << '"' << str << '"').GetString();
+}
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+GTEST_API_ 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) {
+#ifdef _MSC_VER
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4389)  // Temporarily disables warning on
+                               // signed/unsigned mismatch.
+#endif
+
+  if (expected == actual) {
+    return AssertionSuccess();
+  }
+
+#ifdef _MSC_VER
+#pragma warning(pop)          // Restores the warning state.
+#endif
+
+  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.
+GTEST_API_ 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);\
+  }\
+}\
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack);
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack);
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack);
+
+#if GTEST_HAS_STD_WSTRING
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack);
+GTEST_API_ 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.
+GTEST_API_ 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 GTEST_API_ AssertHelper {
+ public:
+  // Constructor.
+  AssertHelper(TestPartResult::Type type,
+               const char* file,
+               int line,
+               const char* message);
+  ~AssertHelper();
+
+  // Message assignment is a semantic trick to enable assertion
+  // streaming; see the GTEST_MESSAGE_ macro below.
+  void operator=(const Message& message) const;
+
+ private:
+  // We put our data in a struct so that the size of the AssertHelper class can
+  // be as small as possible.  This is important because gcc is incapable of
+  // re-using stack space even for temporary variables, so every EXPECT_EQ
+  // reserves stack space for another AssertHelper.
+  struct AssertHelperData {
+    AssertHelperData(TestPartResult::Type t,
+                     const char* srcfile,
+                     int line_num,
+                     const char* msg)
+        : type(t), file(srcfile), line(line_num), message(msg) { }
+
+    TestPartResult::Type const type;
+    const char*        const file;
+    int                const line;
+    String             const message;
+
+   private:
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);
+  };
+
+  AssertHelperData* const data_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
+};
+
+}  // namespace internal
+
+#if GTEST_HAS_PARAM_TEST
+// The abstract base class that all value-parameterized tests inherit from.
+//
+// This class adds support for accessing the test parameter value via
+// the GetParam() method.
+//
+// Use it with one of the parameter generator defining functions, like Range(),
+// Values(), ValuesIn(), Bool(), and Combine().
+//
+// class FooTest : public ::testing::TestWithParam<int> {
+//  protected:
+//   FooTest() {
+//     // Can use GetParam() here.
+//   }
+//   virtual ~FooTest() {
+//     // Can use GetParam() here.
+//   }
+//   virtual void SetUp() {
+//     // Can use GetParam() here.
+//   }
+//   virtual void TearDown {
+//     // Can use GetParam() here.
+//   }
+// };
+// TEST_P(FooTest, DoesBar) {
+//   // Can use GetParam() method here.
+//   Foo foo;
+//   ASSERT_TRUE(foo.DoesBar(GetParam()));
+// }
+// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
+
+template <typename T>
+class TestWithParam : public Test {
+ public:
+  typedef T ParamType;
+
+  // The current parameter value. Is also available in the test fixture's
+  // constructor.
+  const ParamType& GetParam() const { return *parameter_; }
+
+ private:
+  // Sets parameter value. The caller is responsible for making sure the value
+  // remains alive and unchanged throughout the current test.
+  static void SetParam(const ParamType* parameter) {
+    parameter_ = parameter;
+  }
+
+  // Static value used for accessing parameter during a test lifetime.
+  static const ParamType* parameter_;
+
+  // TestClass must be a subclass of TestWithParam<T>.
+  template <class TestClass> friend class internal::ParameterizedTestFactory;
+};
+
+template <typename T>
+const T* TestWithParam<T>::parameter_ = NULL;
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+// 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 GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
+
+// Define this macro to 1 to omit the definition of FAIL(), which is a
+// generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_FAIL
+#define FAIL() GTEST_FAIL()
+#endif
+
+// Generates a success with a generic message.
+#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded")
+
+// Define this macro to 1 to omit the definition of SUCCEED(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_SUCCEED
+#define SUCCEED() GTEST_SUCCEED()
+#endif
+
+// Macros for testing exceptions.
+//
+//    * {ASSERT|EXPECT}_THROW(statement, expected_exception):
+//         Tests that the statement throws the expected exception.
+//    * {ASSERT|EXPECT}_NO_THROW(statement):
+//         Tests that the statement doesn't throw any exception.
+//    * {ASSERT|EXPECT}_ANY_THROW(statement):
+//         Tests that the statement throws an exception.
+
+#define EXPECT_THROW(statement, expected_exception) \
+  GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_NO_THROW(statement) \
+  GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_ANY_THROW(statement) \
+  GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_THROW(statement, expected_exception) \
+  GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)
+#define ASSERT_NO_THROW(statement) \
+  GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)
+#define ASSERT_ANY_THROW(statement) \
+  GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)
+
+// Boolean assertions. Condition can be either a Boolean expression or an
+// AssertionResult. For more information on how to use AssertionResult with
+// these macros see comments on that class.
+#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.
+// 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 10/02/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_
+
+// 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.
+GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,
+                                   float val1, float val2);
+GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
+                                    double val1, double val2);
+
+
+#if 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
+
+// Macros that execute statement and check that it doesn't generate new fatal
+// failures in the current thread.
+//
+//   * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);
+//
+// Examples:
+//
+//   EXPECT_NO_FATAL_FAILURE(Process());
+//   ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed";
+//
+#define ASSERT_NO_FATAL_FAILURE(statement) \
+    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_)
+#define EXPECT_NO_FATAL_FAILURE(statement) \
+    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
+
+// 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))
+
+namespace internal {
+
+// This template is declared, but intentionally undefined.
+template <typename T1, typename T2>
+struct StaticAssertTypeEqHelper;
+
+template <typename T>
+struct StaticAssertTypeEqHelper<T, T> {};
+
+}  // namespace internal
+
+// Compile-time assertion for type equality.
+// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
+// the same type.  The value it returns is not interesting.
+//
+// Instead of making StaticAssertTypeEq a class template, we make it a
+// function template that invokes a helper class template.  This
+// prevents a user from misusing StaticAssertTypeEq<T1, T2> by
+// defining objects of that type.
+//
+// CAVEAT:
+//
+// When used inside a method of a class template,
+// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is
+// instantiated.  For example, given:
+//
+//   template <typename T> class Foo {
+//    public:
+//     void Bar() { testing::StaticAssertTypeEq<int, T>(); }
+//   };
+//
+// the code:
+//
+//   void Test1() { Foo<bool> foo; }
+//
+// will NOT generate a compiler error, as Foo<bool>::Bar() is never
+// actually instantiated.  Instead, you need:
+//
+//   void Test2() { Foo<bool> foo; foo.Bar(); }
+//
+// to cause a compiler error.
+template <typename T1, typename T2>
+bool StaticAssertTypeEq() {
+  internal::StaticAssertTypeEqHelper<T1, T2>();
+  return true;
+}
+
+// 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());
+//   }
+
+// Note that we call GetTestTypeId() instead of GetTypeId<
+// ::testing::Test>() here to get the type ID of testing::Test.  This
+// is to work around a suspected linker bug when using Google Test as
+// a framework on Mac OS X.  The bug causes GetTypeId<
+// ::testing::Test>() to return different values depending on whether
+// the call is from the Google Test framework itself or from user test
+// code.  GetTestTypeId() is guaranteed to always return the same
+// value, as it always calls GetTypeId<>() from the Google Test
+// framework.
+#define GTEST_TEST(test_case_name, test_name)\
+  GTEST_TEST_(test_case_name, test_name, \
+              ::testing::Test, ::testing::internal::GetTestTypeId())
+
+// Define this macro to 1 to omit the definition of TEST(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_TEST
+#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)
+#endif
+
+// 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, \
+              ::testing::internal::GetTypeId<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 InitGoogleTest().
+
+#define RUN_ALL_TESTS()\
+  (::testing::UnitTest::GetInstance()->Run())
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_H_
diff --git a/protobuf/gtest/fused-src/gtest/gtest_main.cc b/protobuf/gtest/fused-src/gtest/gtest_main.cc
new file mode 100644
index 0000000..d20c02f
--- /dev/null
+++ b/protobuf/gtest/fused-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::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/include/gtest/gtest-death-test.h b/protobuf/gtest/include/gtest/gtest-death-test.h
new file mode 100644
index 0000000..121dc1f
--- /dev/null
+++ b/protobuf/gtest/include/gtest/gtest-death-test.h
@@ -0,0 +1,283 @@
+// 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);
+
+#if 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. It generates a warning if there is more than one active
+//   thread.  This is because it's safe to fork() or clone() only
+//   when there is a single thread.
+//
+//   2. The parent process clone()s 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.
+//
+// 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!");
+//
+// On the regular expressions used in death tests:
+//
+//   On POSIX-compliant systems (*nix), we use the <regex.h> library,
+//   which uses the POSIX extended regex syntax.
+//
+//   On other platforms (e.g. Windows), we only support a simple regex
+//   syntax implemented as part of Google Test.  This limited
+//   implementation should be enough most of the time when writing
+//   death tests; though it lacks many features you can find in PCRE
+//   or POSIX extended regex syntax.  For example, we don't support
+//   union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
+//   repetition count ("x{5,7}"), among others.
+//
+//   Below is the syntax that we do support.  We chose it to be a
+//   subset of both PCRE and POSIX extended regex, so it's easy to
+//   learn wherever you come from.  In the following: 'A' denotes a
+//   literal character, period (.), or a single \\ escape sequence;
+//   'x' and 'y' denote regular expressions; 'm' and 'n' are for
+//   natural numbers.
+//
+//     c     matches any literal character c
+//     \\d   matches any decimal digit
+//     \\D   matches any character that's not a decimal digit
+//     \\f   matches \f
+//     \\n   matches \n
+//     \\r   matches \r
+//     \\s   matches any ASCII whitespace, including \n
+//     \\S   matches any character that's not a whitespace
+//     \\t   matches \t
+//     \\v   matches \v
+//     \\w   matches any letter, _, or decimal digit
+//     \\W   matches any character that \\w doesn't match
+//     \\c   matches any literal character c, which must be a punctuation
+//     .     matches any single character except \n
+//     A?    matches 0 or 1 occurrences of A
+//     A*    matches 0 or many occurrences of A
+//     A+    matches 1 or many occurrences of A
+//     ^     matches the beginning of a string (not that of each line)
+//     $     matches the end of a string (not that of each line)
+//     xy    matches x followed by y
+//
+//   If you accidentally use PCRE or POSIX extended regex features
+//   not implemented by us, you will get a run-time failure.  In that
+//   case, please try to rewrite your regular expression within the
+//   above syntax.
+//
+//   This implementation is *not* meant to be as highly tuned or robust
+//   as a compiled regex library, but should perform well enough for a
+//   death test, which already incurs significant overhead by launching
+//   a child process.
+//
+// Known caveats:
+//
+//   A "threadsafe" style death test obtains the path to the test
+//   program from argv[0] and re-executes it in the sub-process.  For
+//   simplicity, the current implementation doesn't search the PATH
+//   when launching the sub-process.  This means that the user must
+//   invoke the test program via a path that contains at least one
+//   path separator (e.g. path/to/foo_test and
+//   /absolute/path/to/bar_test are fine, but foo_test is not).  This
+//   is rarely a problem as people usually don't put the test binary
+//   directory in PATH.
+//
+// TODO(wan@google.com): make thread-safe death tests search the PATH.
+
+// 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 GTEST_API_ ExitedWithCode {
+ public:
+  explicit ExitedWithCode(int exit_code);
+  bool operator()(int exit_status) const;
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ExitedWithCode& other);
+
+  const int exit_code_;
+};
+
+#if !GTEST_OS_WINDOWS
+// Tests that an exit code describes an exit due to termination by a
+// given signal.
+class GTEST_API_ KilledBySignal {
+ public:
+  explicit KilledBySignal(int signum);
+  bool operator()(int exit_status) const;
+ private:
+  const int signum_;
+};
+#endif  // !GTEST_OS_WINDOWS
+
+// 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 (::testing::internal::AlwaysFalse())
+
+#define ASSERT_DEBUG_DEATH(statement, regex) \
+  do { statement; } while (::testing::internal::AlwaysFalse())
+
+#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
+
+// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
+// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
+// death tests are supported; otherwise they just issue a warning.  This is
+// useful when you are combining death test assertions with normal test
+// assertions in one test.
+#if GTEST_HAS_DEATH_TEST
+#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+    EXPECT_DEATH(statement, regex)
+#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+    ASSERT_DEATH(statement, regex)
+#else
+#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
+    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
+#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
+    GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
+#endif
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
diff --git a/protobuf/gtest/include/gtest/gtest-message.h b/protobuf/gtest/include/gtest/gtest-message.h
new file mode 100644
index 0000000..f135b69
--- /dev/null
+++ b/protobuf/gtest/include/gtest/gtest-message.h
@@ -0,0 +1,230 @@
+// 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_
+
+#include <limits>
+
+#include <gtest/internal/gtest-string.h>
+#include <gtest/internal/gtest-internal.h>
+
+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 GTEST_API_ 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) {
+    // By default, we want there to be enough precision when printing
+    // a double to a Message.
+    *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
+  }
+
+  // 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_; }
+#if GTEST_OS_SYMBIAN
+  // 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  // GTEST_OS_SYMBIAN
+
+  // 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:
+#if GTEST_OS_SYMBIAN
+  // 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  // GTEST_OS_SYMBIAN
+
+  // 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/protobuf/gtest/include/gtest/gtest-param-test.h b/protobuf/gtest/include/gtest/gtest-param-test.h
new file mode 100644
index 0000000..8100696
--- /dev/null
+++ b/protobuf/gtest/include/gtest/gtest-param-test.h
@@ -0,0 +1,1392 @@
+// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+
+// 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: vladl@google.com (Vlad Losev)
+//
+// Macros and functions for implementing parameterized tests
+// in Google C++ Testing Framework (Google Test)
+//
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+
+
+// Value-parameterized tests allow you to test your code with different
+// parameters without writing multiple copies of the same test.
+//
+// Here is how you use value-parameterized tests:
+
+#if 0
+
+// To write value-parameterized tests, first you should define a fixture
+// class. It must be derived from testing::TestWithParam<T>, where T is
+// the type of your parameter values. TestWithParam<T> is itself derived
+// from testing::Test. T can be any copyable type. If it's a raw pointer,
+// you are responsible for managing the lifespan of the pointed values.
+
+class FooTest : public ::testing::TestWithParam<const char*> {
+  // You can implement all the usual class fixture members here.
+};
+
+// Then, use the TEST_P macro to define as many parameterized tests
+// for this fixture as you want. The _P suffix is for "parameterized"
+// or "pattern", whichever you prefer to think.
+
+TEST_P(FooTest, DoesBlah) {
+  // Inside a test, access the test parameter with the GetParam() method
+  // of the TestWithParam<T> class:
+  EXPECT_TRUE(foo.Blah(GetParam()));
+  ...
+}
+
+TEST_P(FooTest, HasBlahBlah) {
+  ...
+}
+
+// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
+// case with any set of parameters you want. Google Test defines a number
+// of functions for generating test parameters. They return what we call
+// (surprise!) parameter generators. Here is a  summary of them, which
+// are all in the testing namespace:
+//
+//
+//  Range(begin, end [, step]) - Yields values {begin, begin+step,
+//                               begin+step+step, ...}. The values do not
+//                               include end. step defaults to 1.
+//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.
+//  ValuesIn(container)        - Yields values from a C-style array, an STL
+//  ValuesIn(begin,end)          container, or an iterator range [begin, end).
+//  Bool()                     - Yields sequence {false, true}.
+//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product
+//                               for the math savvy) of the values generated
+//                               by the N generators.
+//
+// For more details, see comments at the definitions of these functions below
+// in this file.
+//
+// The following statement will instantiate tests from the FooTest test case
+// each with parameter values "meeny", "miny", and "moe".
+
+INSTANTIATE_TEST_CASE_P(InstantiationName,
+                        FooTest,
+                        Values("meeny", "miny", "moe"));
+
+// To distinguish different instances of the pattern, (yes, you
+// can instantiate it more then once) the first argument to the
+// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
+// actual test case name. Remember to pick unique prefixes for different
+// instantiations. The tests from the instantiation above will have
+// these names:
+//
+//    * InstantiationName/FooTest.DoesBlah/0 for "meeny"
+//    * InstantiationName/FooTest.DoesBlah/1 for "miny"
+//    * InstantiationName/FooTest.DoesBlah/2 for "moe"
+//    * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
+//    * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
+//    * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
+//
+// You can use these names in --gtest_filter.
+//
+// This statement will instantiate all tests from FooTest again, each
+// with parameter values "cat" and "dog":
+
+const char* pets[] = {"cat", "dog"};
+INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
+
+// The tests from the instantiation above will have these names:
+//
+//    * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
+//
+// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
+// in the given test case, whether their definitions come before or
+// AFTER the INSTANTIATE_TEST_CASE_P statement.
+//
+// Please also note that generator expressions (including parameters to the
+// generators) are evaluated in InitGoogleTest(), after main() has started.
+// This allows the user on one hand, to adjust generator parameters in order
+// to dynamically determine a set of tests to run and on the other hand,
+// give the user a chance to inspect the generated tests with Google Test
+// reflection API before RUN_ALL_TESTS() is executed.
+//
+// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
+// for more examples.
+//
+// In the future, we plan to publish the API for defining new parameter
+// generators. But for now this interface remains part of the internal
+// implementation and is subject to change.
+
+#endif  // 0
+
+#include <gtest/internal/gtest-port.h>
+
+#if !GTEST_OS_SYMBIAN
+#include <utility>
+#endif
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-internal.h>
+#include <gtest/internal/gtest-param-util.h>
+#include <gtest/internal/gtest-param-util-generated.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Functions producing parameter generators.
+//
+// Google Test uses these generators to produce parameters for value-
+// parameterized tests. When a parameterized test case is instantiated
+// with a particular generator, Google Test creates and runs tests
+// for each element in the sequence produced by the generator.
+//
+// In the following sample, tests from test case FooTest are instantiated
+// each three times with parameter values 3, 5, and 8:
+//
+// class FooTest : public TestWithParam<int> { ... };
+//
+// TEST_P(FooTest, TestThis) {
+// }
+// TEST_P(FooTest, TestThat) {
+// }
+// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
+//
+
+// Range() returns generators providing sequences of values in a range.
+//
+// Synopsis:
+// Range(start, end)
+//   - returns a generator producing a sequence of values {start, start+1,
+//     start+2, ..., }.
+// Range(start, end, step)
+//   - returns a generator producing a sequence of values {start, start+step,
+//     start+step+step, ..., }.
+// Notes:
+//   * The generated sequences never include end. For example, Range(1, 5)
+//     returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
+//     returns a generator producing {1, 3, 5, 7}.
+//   * start and end must have the same type. That type may be any integral or
+//     floating-point type or a user defined type satisfying these conditions:
+//     * It must be assignable (have operator=() defined).
+//     * It must have operator+() (operator+(int-compatible type) for
+//       two-operand version).
+//     * It must have operator<() defined.
+//     Elements in the resulting sequences will also have that type.
+//   * Condition start < end must be satisfied in order for resulting sequences
+//     to contain any elements.
+//
+template <typename T, typename IncrementT>
+internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
+  return internal::ParamGenerator<T>(
+      new internal::RangeGenerator<T, IncrementT>(start, end, step));
+}
+
+template <typename T>
+internal::ParamGenerator<T> Range(T start, T end) {
+  return Range(start, end, 1);
+}
+
+// ValuesIn() function allows generation of tests with parameters coming from
+// a container.
+//
+// Synopsis:
+// ValuesIn(const T (&array)[N])
+//   - returns a generator producing sequences with elements from
+//     a C-style array.
+// ValuesIn(const Container& container)
+//   - returns a generator producing sequences with elements from
+//     an STL-style container.
+// ValuesIn(Iterator begin, Iterator end)
+//   - returns a generator producing sequences with elements from
+//     a range [begin, end) defined by a pair of STL-style iterators. These
+//     iterators can also be plain C pointers.
+//
+// Please note that ValuesIn copies the values from the containers
+// passed in and keeps them to generate tests in RUN_ALL_TESTS().
+//
+// Examples:
+//
+// This instantiates tests from test case StringTest
+// each with C-string values of "foo", "bar", and "baz":
+//
+// const char* strings[] = {"foo", "bar", "baz"};
+// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
+//
+// This instantiates tests from test case StlStringTest
+// each with STL strings with values "a" and "b":
+//
+// ::std::vector< ::std::string> GetParameterStrings() {
+//   ::std::vector< ::std::string> v;
+//   v.push_back("a");
+//   v.push_back("b");
+//   return v;
+// }
+//
+// INSTANTIATE_TEST_CASE_P(CharSequence,
+//                         StlStringTest,
+//                         ValuesIn(GetParameterStrings()));
+//
+//
+// This will also instantiate tests from CharTest
+// each with parameter values 'a' and 'b':
+//
+// ::std::list<char> GetParameterChars() {
+//   ::std::list<char> list;
+//   list.push_back('a');
+//   list.push_back('b');
+//   return list;
+// }
+// ::std::list<char> l = GetParameterChars();
+// INSTANTIATE_TEST_CASE_P(CharSequence2,
+//                         CharTest,
+//                         ValuesIn(l.begin(), l.end()));
+//
+template <typename ForwardIterator>
+internal::ParamGenerator<
+    typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+  ForwardIterator begin,
+  ForwardIterator end) {
+  typedef typename ::std::iterator_traits<ForwardIterator>::value_type
+      ParamType;
+  return internal::ParamGenerator<ParamType>(
+      new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
+}
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
+  return ValuesIn(array, array + N);
+}
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+    const Container& container) {
+  return ValuesIn(container.begin(), container.end());
+}
+
+// Values() allows generating tests from explicitly specified list of
+// parameters.
+//
+// Synopsis:
+// Values(T v1, T v2, ..., T vN)
+//   - returns a generator producing sequences with elements v1, v2, ..., vN.
+//
+// For example, this instantiates tests from test case BarTest each
+// with values "one", "two", and "three":
+//
+// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
+//
+// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
+// The exact type of values will depend on the type of parameter in BazTest.
+//
+// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
+//
+// Currently, Values() supports from 1 to 50 parameters.
+//
+template <typename T1>
+internal::ValueArray1<T1> Values(T1 v1) {
+  return internal::ValueArray1<T1>(v1);
+}
+
+template <typename T1, typename T2>
+internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) {
+  return internal::ValueArray2<T1, T2>(v1, v2);
+}
+
+template <typename T1, typename T2, typename T3>
+internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) {
+  return internal::ValueArray3<T1, T2, T3>(v1, v2, v3);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) {
+  return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5) {
+  return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6) {
+  return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7) {
+  return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5,
+      v6, v7);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
+  return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4,
+      v5, v6, v7, v8);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
+  return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
+  return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
+    T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11) {
+  return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
+      T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+    T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12) {
+  return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+    T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13) {
+  return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
+  return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
+  return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16) {
+  return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17) {
+  return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18) {
+  return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) {
+  return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) {
+  return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) {
+  return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22) {
+  return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23) {
+  return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24) {
+  return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2,
+      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
+      v19, v20, v21, v22, v23, v24);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
+    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
+    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) {
+  return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
+      v18, v19, v20, v21, v22, v23, v24, v25);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+    T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26) {
+  return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
+      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+    T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27) {
+  return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
+      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+    T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28) {
+  return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
+      v28);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29) {
+  return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
+      v27, v28, v29);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) {
+  return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
+      v26, v27, v28, v29, v30);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) {
+  return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
+      v25, v26, v27, v28, v29, v30, v31);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32) {
+  return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33) {
+  return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
+    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
+    T31 v31, T32 v32, T33 v33, T34 v34) {
+  return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
+      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) {
+  return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
+      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) {
+  return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3,
+    T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37) {
+  return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3,
+      v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36, v37);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37, T38 v38) {
+  return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2,
+      v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
+      v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32,
+      v33, v34, v35, v36, v37, v38);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2,
+    T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
+    T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
+    T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
+    T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
+    T37 v37, T38 v38, T39 v39) {
+  return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1,
+      v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
+      v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
+      v32, v33, v34, v35, v36, v37, v38, v39);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1,
+    T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
+    T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
+    T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27,
+    T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35,
+    T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) {
+  return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
+      v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
+      v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+    T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) {
+  return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
+      v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28,
+      v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+    T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42) {
+  return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
+      v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
+      v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41,
+      v42);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+    T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42, T43 v43) {
+  return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
+      v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
+      v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40,
+      v41, v42, v43);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+    T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+    T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+    T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+    T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+    T42 v42, T43 v43, T44 v44) {
+  return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
+      v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
+      v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
+      v40, v41, v42, v43, v44);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+    T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+    T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+    T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
+    T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
+    T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) {
+  return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
+      v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
+      v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38,
+      v39, v40, v41, v42, v43, v44, v45);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) {
+  return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
+      v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
+      v38, v39, v40, v41, v42, v43, v44, v45, v46);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+    T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) {
+  return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8,
+      v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
+      v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
+      v38, v39, v40, v41, v42, v43, v44, v45, v46, v47);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
+    T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
+    T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
+    T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
+    T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
+    T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47,
+    T48 v48) {
+  return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7,
+      v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
+      v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36,
+      v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
+    T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
+    T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
+    T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
+    T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38,
+    T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46,
+    T47 v47, T48 v48, T49 v49) {
+  return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6,
+      v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
+      v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35,
+      v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49);
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4,
+    T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
+    T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
+    T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
+    T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37,
+    T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45,
+    T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) {
+  return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4,
+      v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+      v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
+      v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,
+      v48, v49, v50);
+}
+
+// Bool() allows generating tests with parameters in a set of (false, true).
+//
+// Synopsis:
+// Bool()
+//   - returns a generator producing sequences with elements {false, true}.
+//
+// It is useful when testing code that depends on Boolean flags. Combinations
+// of multiple flags can be tested when several Bool()'s are combined using
+// Combine() function.
+//
+// In the following example all tests in the test case FlagDependentTest
+// will be instantiated twice with parameters false and true.
+//
+// class FlagDependentTest : public testing::TestWithParam<bool> {
+//   virtual void SetUp() {
+//     external_flag = GetParam();
+//   }
+// }
+// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
+//
+inline internal::ParamGenerator<bool> Bool() {
+  return Values(false, true);
+}
+
+#if GTEST_HAS_COMBINE
+// Combine() allows the user to combine two or more sequences to produce
+// values of a Cartesian product of those sequences' elements.
+//
+// Synopsis:
+// Combine(gen1, gen2, ..., genN)
+//   - returns a generator producing sequences with elements coming from
+//     the Cartesian product of elements from the sequences generated by
+//     gen1, gen2, ..., genN. The sequence elements will have a type of
+//     tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
+//     of elements from sequences produces by gen1, gen2, ..., genN.
+//
+// Combine can have up to 10 arguments. This number is currently limited
+// by the maximum number of elements in the tuple implementation used by Google
+// Test.
+//
+// Example:
+//
+// This will instantiate tests in test case AnimalTest each one with
+// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
+// tuple("dog", BLACK), and tuple("dog", WHITE):
+//
+// enum Color { BLACK, GRAY, WHITE };
+// class AnimalTest
+//     : public testing::TestWithParam<tuple<const char*, Color> > {...};
+//
+// TEST_P(AnimalTest, AnimalLooksNice) {...}
+//
+// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
+//                         Combine(Values("cat", "dog"),
+//                                 Values(BLACK, WHITE)));
+//
+// This will instantiate tests in FlagDependentTest with all variations of two
+// Boolean flags:
+//
+// class FlagDependentTest
+//     : public testing::TestWithParam<tuple(bool, bool)> > {
+//   virtual void SetUp() {
+//     // Assigns external_flag_1 and external_flag_2 values from the tuple.
+//     tie(external_flag_1, external_flag_2) = GetParam();
+//   }
+// };
+//
+// TEST_P(FlagDependentTest, TestFeature1) {
+//   // Test your code using external_flag_1 and external_flag_2 here.
+// }
+// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
+//                         Combine(Bool(), Bool()));
+//
+template <typename Generator1, typename Generator2>
+internal::CartesianProductHolder2<Generator1, Generator2> Combine(
+    const Generator1& g1, const Generator2& g2) {
+  return internal::CartesianProductHolder2<Generator1, Generator2>(
+      g1, g2);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3>
+internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3) {
+  return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>(
+      g1, g2, g3);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4>
+internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
+    Generator4> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4) {
+  return internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
+      Generator4>(
+      g1, g2, g3, g4);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5>
+internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
+    Generator4, Generator5> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5) {
+  return internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
+      Generator4, Generator5>(
+      g1, g2, g3, g4, g5);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6>
+internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6) {
+  return internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6>(
+      g1, g2, g3, g4, g5, g6);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7>
+internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7) {
+  return internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7>(
+      g1, g2, g3, g4, g5, g6, g7);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8>
+internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8) {
+  return internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8>(
+      g1, g2, g3, g4, g5, g6, g7, g8);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8, typename Generator9>
+internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8,
+    Generator9> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8, const Generator9& g9) {
+  return internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>(
+      g1, g2, g3, g4, g5, g6, g7, g8, g9);
+}
+
+template <typename Generator1, typename Generator2, typename Generator3,
+    typename Generator4, typename Generator5, typename Generator6,
+    typename Generator7, typename Generator8, typename Generator9,
+    typename Generator10>
+internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
+    Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
+    Generator10> Combine(
+    const Generator1& g1, const Generator2& g2, const Generator3& g3,
+        const Generator4& g4, const Generator5& g5, const Generator6& g6,
+        const Generator7& g7, const Generator8& g8, const Generator9& g9,
+        const Generator10& g10) {
+  return internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
+      Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
+      Generator10>(
+      g1, g2, g3, g4, g5, g6, g7, g8, g9, g10);
+}
+#endif  // GTEST_HAS_COMBINE
+
+
+
+#define TEST_P(test_case_name, test_name) \
+  class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+      : public test_case_name { \
+   public: \
+    GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
+    virtual void TestBody(); \
+   private: \
+    static int AddToRegistry() { \
+      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+          GetTestCasePatternHolder<test_case_name>(\
+              #test_case_name, __FILE__, __LINE__)->AddTestPattern(\
+                  #test_case_name, \
+                  #test_name, \
+                  new ::testing::internal::TestMetaFactory< \
+                      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
+      return 0; \
+    } \
+    static int gtest_registering_dummy_; \
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+        GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
+  }; \
+  int GTEST_TEST_CLASS_NAME_(test_case_name, \
+                             test_name)::gtest_registering_dummy_ = \
+      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
+  void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
+  ::testing::internal::ParamGenerator<test_case_name::ParamType> \
+      gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
+  int gtest_##prefix##test_case_name##_dummy_ = \
+      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+          GetTestCasePatternHolder<test_case_name>(\
+              #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
+                  #prefix, \
+                  &gtest_##prefix##test_case_name##_EvalGenerator_, \
+                  __FILE__, __LINE__)
+
+}  // namespace testing
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
diff --git a/protobuf/gtest/include/gtest/gtest-param-test.h.pump b/protobuf/gtest/include/gtest/gtest-param-test.h.pump
new file mode 100644
index 0000000..a231188
--- /dev/null
+++ b/protobuf/gtest/include/gtest/gtest-param-test.h.pump
@@ -0,0 +1,457 @@
+$$ -*- mode: c++; -*-
+$var n = 50  $$ Maximum length of Values arguments we want to support.
+$var maxtuple = 10  $$ Maximum number of Combine arguments we want to support.
+// 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: vladl@google.com (Vlad Losev)
+//
+// Macros and functions for implementing parameterized tests
+// in Google C++ Testing Framework (Google Test)
+//
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
+
+
+// Value-parameterized tests allow you to test your code with different
+// parameters without writing multiple copies of the same test.
+//
+// Here is how you use value-parameterized tests:
+
+#if 0
+
+// To write value-parameterized tests, first you should define a fixture
+// class. It must be derived from testing::TestWithParam<T>, where T is
+// the type of your parameter values. TestWithParam<T> is itself derived
+// from testing::Test. T can be any copyable type. If it's a raw pointer,
+// you are responsible for managing the lifespan of the pointed values.
+
+class FooTest : public ::testing::TestWithParam<const char*> {
+  // You can implement all the usual class fixture members here.
+};
+
+// Then, use the TEST_P macro to define as many parameterized tests
+// for this fixture as you want. The _P suffix is for "parameterized"
+// or "pattern", whichever you prefer to think.
+
+TEST_P(FooTest, DoesBlah) {
+  // Inside a test, access the test parameter with the GetParam() method
+  // of the TestWithParam<T> class:
+  EXPECT_TRUE(foo.Blah(GetParam()));
+  ...
+}
+
+TEST_P(FooTest, HasBlahBlah) {
+  ...
+}
+
+// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
+// case with any set of parameters you want. Google Test defines a number
+// of functions for generating test parameters. They return what we call
+// (surprise!) parameter generators. Here is a  summary of them, which
+// are all in the testing namespace:
+//
+//
+//  Range(begin, end [, step]) - Yields values {begin, begin+step,
+//                               begin+step+step, ...}. The values do not
+//                               include end. step defaults to 1.
+//  Values(v1, v2, ..., vN)    - Yields values {v1, v2, ..., vN}.
+//  ValuesIn(container)        - Yields values from a C-style array, an STL
+//  ValuesIn(begin,end)          container, or an iterator range [begin, end).
+//  Bool()                     - Yields sequence {false, true}.
+//  Combine(g1, g2, ..., gN)   - Yields all combinations (the Cartesian product
+//                               for the math savvy) of the values generated
+//                               by the N generators.
+//
+// For more details, see comments at the definitions of these functions below
+// in this file.
+//
+// The following statement will instantiate tests from the FooTest test case
+// each with parameter values "meeny", "miny", and "moe".
+
+INSTANTIATE_TEST_CASE_P(InstantiationName,
+                        FooTest,
+                        Values("meeny", "miny", "moe"));
+
+// To distinguish different instances of the pattern, (yes, you
+// can instantiate it more then once) the first argument to the
+// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
+// actual test case name. Remember to pick unique prefixes for different
+// instantiations. The tests from the instantiation above will have
+// these names:
+//
+//    * InstantiationName/FooTest.DoesBlah/0 for "meeny"
+//    * InstantiationName/FooTest.DoesBlah/1 for "miny"
+//    * InstantiationName/FooTest.DoesBlah/2 for "moe"
+//    * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
+//    * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
+//    * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
+//
+// You can use these names in --gtest_filter.
+//
+// This statement will instantiate all tests from FooTest again, each
+// with parameter values "cat" and "dog":
+
+const char* pets[] = {"cat", "dog"};
+INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
+
+// The tests from the instantiation above will have these names:
+//
+//    * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
+//    * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
+//
+// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
+// in the given test case, whether their definitions come before or
+// AFTER the INSTANTIATE_TEST_CASE_P statement.
+//
+// Please also note that generator expressions are evaluated in
+// RUN_ALL_TESTS(), after main() has started. This allows evaluation of
+// parameter list based on command line parameters.
+//
+// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
+// for more examples.
+//
+// In the future, we plan to publish the API for defining new parameter
+// generators. But for now this interface remains part of the internal
+// implementation and is subject to change.
+
+#endif  // 0
+
+#include <gtest/internal/gtest-port.h>
+
+#if !GTEST_OS_SYMBIAN
+#include <utility>
+#endif
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-internal.h>
+#include <gtest/internal/gtest-param-util.h>
+#include <gtest/internal/gtest-param-util-generated.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Functions producing parameter generators.
+//
+// Google Test uses these generators to produce parameters for value-
+// parameterized tests. When a parameterized test case is instantiated
+// with a particular generator, Google Test creates and runs tests
+// for each element in the sequence produced by the generator.
+//
+// In the following sample, tests from test case FooTest are instantiated
+// each three times with parameter values 3, 5, and 8:
+//
+// class FooTest : public TestWithParam<int> { ... };
+//
+// TEST_P(FooTest, TestThis) {
+// }
+// TEST_P(FooTest, TestThat) {
+// }
+// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
+//
+
+// Range() returns generators providing sequences of values in a range.
+//
+// Synopsis:
+// Range(start, end)
+//   - returns a generator producing a sequence of values {start, start+1,
+//     start+2, ..., }.
+// Range(start, end, step)
+//   - returns a generator producing a sequence of values {start, start+step,
+//     start+step+step, ..., }.
+// Notes:
+//   * The generated sequences never include end. For example, Range(1, 5)
+//     returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
+//     returns a generator producing {1, 3, 5, 7}.
+//   * start and end must have the same type. That type may be any integral or
+//     floating-point type or a user defined type satisfying these conditions:
+//     * It must be assignable (have operator=() defined).
+//     * It must have operator+() (operator+(int-compatible type) for
+//       two-operand version).
+//     * It must have operator<() defined.
+//     Elements in the resulting sequences will also have that type.
+//   * Condition start < end must be satisfied in order for resulting sequences
+//     to contain any elements.
+//
+template <typename T, typename IncrementT>
+internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
+  return internal::ParamGenerator<T>(
+      new internal::RangeGenerator<T, IncrementT>(start, end, step));
+}
+
+template <typename T>
+internal::ParamGenerator<T> Range(T start, T end) {
+  return Range(start, end, 1);
+}
+
+// ValuesIn() function allows generation of tests with parameters coming from
+// a container.
+//
+// Synopsis:
+// ValuesIn(const T (&array)[N])
+//   - returns a generator producing sequences with elements from
+//     a C-style array.
+// ValuesIn(const Container& container)
+//   - returns a generator producing sequences with elements from
+//     an STL-style container.
+// ValuesIn(Iterator begin, Iterator end)
+//   - returns a generator producing sequences with elements from
+//     a range [begin, end) defined by a pair of STL-style iterators. These
+//     iterators can also be plain C pointers.
+//
+// Please note that ValuesIn copies the values from the containers
+// passed in and keeps them to generate tests in RUN_ALL_TESTS().
+//
+// Examples:
+//
+// This instantiates tests from test case StringTest
+// each with C-string values of "foo", "bar", and "baz":
+//
+// const char* strings[] = {"foo", "bar", "baz"};
+// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
+//
+// This instantiates tests from test case StlStringTest
+// each with STL strings with values "a" and "b":
+//
+// ::std::vector< ::std::string> GetParameterStrings() {
+//   ::std::vector< ::std::string> v;
+//   v.push_back("a");
+//   v.push_back("b");
+//   return v;
+// }
+//
+// INSTANTIATE_TEST_CASE_P(CharSequence,
+//                         StlStringTest,
+//                         ValuesIn(GetParameterStrings()));
+//
+//
+// This will also instantiate tests from CharTest
+// each with parameter values 'a' and 'b':
+//
+// ::std::list<char> GetParameterChars() {
+//   ::std::list<char> list;
+//   list.push_back('a');
+//   list.push_back('b');
+//   return list;
+// }
+// ::std::list<char> l = GetParameterChars();
+// INSTANTIATE_TEST_CASE_P(CharSequence2,
+//                         CharTest,
+//                         ValuesIn(l.begin(), l.end()));
+//
+template <typename ForwardIterator>
+internal::ParamGenerator<
+    typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+  ForwardIterator begin,
+  ForwardIterator end) {
+  typedef typename ::std::iterator_traits<ForwardIterator>::value_type
+      ParamType;
+  return internal::ParamGenerator<ParamType>(
+      new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
+}
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
+  return ValuesIn(array, array + N);
+}
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+    const Container& container) {
+  return ValuesIn(container.begin(), container.end());
+}
+
+// Values() allows generating tests from explicitly specified list of
+// parameters.
+//
+// Synopsis:
+// Values(T v1, T v2, ..., T vN)
+//   - returns a generator producing sequences with elements v1, v2, ..., vN.
+//
+// For example, this instantiates tests from test case BarTest each
+// with values "one", "two", and "three":
+//
+// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
+//
+// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
+// The exact type of values will depend on the type of parameter in BazTest.
+//
+// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
+//
+// Currently, Values() supports from 1 to $n parameters.
+//
+$range i 1..n
+$for i [[
+$range j 1..i
+
+template <$for j, [[typename T$j]]>
+internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) {
+  return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]);
+}
+
+]]
+
+// Bool() allows generating tests with parameters in a set of (false, true).
+//
+// Synopsis:
+// Bool()
+//   - returns a generator producing sequences with elements {false, true}.
+//
+// It is useful when testing code that depends on Boolean flags. Combinations
+// of multiple flags can be tested when several Bool()'s are combined using
+// Combine() function.
+//
+// In the following example all tests in the test case FlagDependentTest
+// will be instantiated twice with parameters false and true.
+//
+// class FlagDependentTest : public testing::TestWithParam<bool> {
+//   virtual void SetUp() {
+//     external_flag = GetParam();
+//   }
+// }
+// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
+//
+inline internal::ParamGenerator<bool> Bool() {
+  return Values(false, true);
+}
+
+#if GTEST_HAS_COMBINE
+// Combine() allows the user to combine two or more sequences to produce
+// values of a Cartesian product of those sequences' elements.
+//
+// Synopsis:
+// Combine(gen1, gen2, ..., genN)
+//   - returns a generator producing sequences with elements coming from
+//     the Cartesian product of elements from the sequences generated by
+//     gen1, gen2, ..., genN. The sequence elements will have a type of
+//     tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
+//     of elements from sequences produces by gen1, gen2, ..., genN.
+//
+// Combine can have up to $maxtuple arguments. This number is currently limited
+// by the maximum number of elements in the tuple implementation used by Google
+// Test.
+//
+// Example:
+//
+// This will instantiate tests in test case AnimalTest each one with
+// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
+// tuple("dog", BLACK), and tuple("dog", WHITE):
+//
+// enum Color { BLACK, GRAY, WHITE };
+// class AnimalTest
+//     : public testing::TestWithParam<tuple<const char*, Color> > {...};
+//
+// TEST_P(AnimalTest, AnimalLooksNice) {...}
+//
+// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
+//                         Combine(Values("cat", "dog"),
+//                                 Values(BLACK, WHITE)));
+//
+// This will instantiate tests in FlagDependentTest with all variations of two
+// Boolean flags:
+//
+// class FlagDependentTest
+//     : public testing::TestWithParam<tuple(bool, bool)> > {
+//   virtual void SetUp() {
+//     // Assigns external_flag_1 and external_flag_2 values from the tuple.
+//     tie(external_flag_1, external_flag_2) = GetParam();
+//   }
+// };
+//
+// TEST_P(FlagDependentTest, TestFeature1) {
+//   // Test your code using external_flag_1 and external_flag_2 here.
+// }
+// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
+//                         Combine(Bool(), Bool()));
+//
+$range i 2..maxtuple
+$for i [[
+$range j 1..i
+
+template <$for j, [[typename Generator$j]]>
+internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
+    $for j, [[const Generator$j& g$j]]) {
+  return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>(
+      $for j, [[g$j]]);
+}
+
+]]
+#endif  // GTEST_HAS_COMBINE
+
+
+
+#define TEST_P(test_case_name, test_name) \
+  class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+      : public test_case_name { \
+   public: \
+    GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
+    virtual void TestBody(); \
+   private: \
+    static int AddToRegistry() { \
+      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+          GetTestCasePatternHolder<test_case_name>(\
+              #test_case_name, __FILE__, __LINE__)->AddTestPattern(\
+                  #test_case_name, \
+                  #test_name, \
+                  new ::testing::internal::TestMetaFactory< \
+                      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
+      return 0; \
+    } \
+    static int gtest_registering_dummy_; \
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+        GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
+  }; \
+  int GTEST_TEST_CLASS_NAME_(test_case_name, \
+                             test_name)::gtest_registering_dummy_ = \
+      GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
+  void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
+  ::testing::internal::ParamGenerator<test_case_name::ParamType> \
+      gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
+  int gtest_##prefix##test_case_name##_dummy_ = \
+      ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
+          GetTestCasePatternHolder<test_case_name>(\
+              #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
+                  #prefix, \
+                  &gtest_##prefix##test_case_name##_EvalGenerator_, \
+                  __FILE__, __LINE__)
+
+}  // namespace testing
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
diff --git a/protobuf/gtest/include/gtest/gtest-spi.h b/protobuf/gtest/include/gtest/gtest-spi.h
new file mode 100644
index 0000000..c41da48
--- /dev/null
+++ b/protobuf/gtest/include/gtest/gtest-spi.h
@@ -0,0 +1,232 @@
+// 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 {
+
+// 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. It can either intercept only failures that are
+// generated in the same thread that created this object or it can intercept
+// all generated failures. The scope of this mock object can be controlled with
+// the second argument to the two arguments constructor.
+class GTEST_API_ ScopedFakeTestPartResultReporter
+    : public TestPartResultReporterInterface {
+ public:
+  // The two possible mocking modes of this object.
+  enum InterceptMode {
+    INTERCEPT_ONLY_CURRENT_THREAD,  // Intercepts only thread local failures.
+    INTERCEPT_ALL_THREADS           // Intercepts all failures.
+  };
+
+  // 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. This reporter will only catch failures generated in the current
+  // thread. DEPRECATED
+  explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result);
+
+  // Same as above, but you can choose the interception scope of this object.
+  ScopedFakeTestPartResultReporter(InterceptMode intercept_mode,
+                                   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:
+  void Init();
+
+  const InterceptMode intercept_mode_;
+  TestPartResultReporterInterface* 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 GTEST_API_ SingleFailureChecker {
+ public:
+  // The constructor remembers the arguments.
+  SingleFailureChecker(const TestPartResultArray* results,
+                       TestPartResult::Type type,
+                       const char* substr);
+  ~SingleFailureChecker();
+ private:
+  const TestPartResultArray* const results_;
+  const TestPartResult::Type type_;
+  const String substr_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
+};
+
+}  // namespace internal
+
+}  // namespace testing
+
+// A set of macros 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.
+//
+// There are two different versions of this macro. EXPECT_FATAL_FAILURE only
+// affects and considers failures generated in the current thread and
+// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
+//
+// The verification of the assertion is done correctly even when the statement
+// throws an exception or aborts the current function.
+//
+// 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.
+//
+// Note that even though the implementations of the following two
+// macros are much alike, we cannot refactor them to use a common
+// helper macro, due to some peculiarity in how the preprocessor
+// works.  The AcceptsMacroThatExpandsToUnprotectedComma test in
+// gtest_unittest.cc will fail to compile if we do that.
+#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::TestPartResult::kFatalFailure, (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
+      GTestExpectFatalFailureHelper::Execute();\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
+  do { \
+    class GTestExpectFatalFailureHelper {\
+     public:\
+      static void Execute() { statement; }\
+    };\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ALL_THREADS, &gtest_failures);\
+      GTestExpectFatalFailureHelper::Execute();\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+// 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.
+//
+// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
+// affects and considers failures generated in the current thread and
+// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads.
+//
+// 'statement' is allowed to reference local variables and members of
+// the current object.
+//
+// The verification of the assertion is done correctly even when the statement
+// throws an exception or aborts the current function.
+//
+// Known restrictions:
+//   - You cannot stream a failure message to this macro.
+//
+// Note that even though the implementations of the following two
+// macros are much alike, we cannot refactor them to use a common
+// helper macro, due to some peculiarity in how the preprocessor
+// works.  If we do that, the code won't compile when the user gives
+// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that
+// expands to code containing an unprotected comma.  The
+// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc
+// catches that.
+//
+// For the same reason, we have to write
+//   if (::testing::internal::AlwaysTrue()) { statement; }
+// instead of
+//   GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
+// to avoid an MSVC warning on unreachable code.
+#define EXPECT_NONFATAL_FAILURE(statement, substr) \
+  do {\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
+        (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter:: \
+          INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
+      if (::testing::internal::AlwaysTrue()) { statement; }\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
+  do {\
+    ::testing::TestPartResultArray gtest_failures;\
+    ::testing::internal::SingleFailureChecker gtest_checker(\
+        &gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
+        (substr));\
+    {\
+      ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
+          ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\
+          &gtest_failures);\
+      if (::testing::internal::AlwaysTrue()) { statement; }\
+    }\
+  } while (::testing::internal::AlwaysFalse())
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
diff --git a/protobuf/gtest/include/gtest/gtest-test-part.h b/protobuf/gtest/include/gtest/gtest-test-part.h
new file mode 100644
index 0000000..f714759
--- /dev/null
+++ b/protobuf/gtest/include/gtest/gtest-test-part.h
@@ -0,0 +1,176 @@
+// 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: mheule@google.com (Markus Heule)
+//
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
+
+#include <iosfwd>
+#include <vector>
+#include <gtest/internal/gtest-internal.h>
+#include <gtest/internal/gtest-string.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 GTEST_API_ TestPartResult {
+ public:
+  // The possible outcomes of a test part (i.e. an assertion or an
+  // explicit SUCCEED(), FAIL(), or ADD_FAILURE()).
+  enum Type {
+    kSuccess,          // Succeeded.
+    kNonFatalFailure,  // Failed but the test can continue.
+    kFatalFailure      // Failed and the test should be terminated.
+  };
+
+  // C'tor.  TestPartResult does NOT have a default constructor.
+  // Always use this constructor (with parameters) to create a
+  // TestPartResult object.
+  TestPartResult(Type a_type,
+                 const char* a_file_name,
+                 int a_line_number,
+                 const char* a_message)
+      : type_(a_type),
+        file_name_(a_file_name),
+        line_number_(a_line_number),
+        summary_(ExtractSummary(a_message)),
+        message_(a_message) {
+  }
+
+  // Gets the outcome of the test part.
+  Type 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 summary of the failure message.
+  const char* summary() const { return summary_.c_str(); }
+
+  // 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_ == kSuccess; }
+
+  // Returns true iff the test part failed.
+  bool failed() const { return type_ != kSuccess; }
+
+  // Returns true iff the test part non-fatally failed.
+  bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
+
+  // Returns true iff the test part fatally failed.
+  bool fatally_failed() const { return type_ == kFatalFailure; }
+ private:
+  Type type_;
+
+  // Gets the summary of the failure message by omitting the stack
+  // trace in it.
+  static internal::String ExtractSummary(const char* message);
+
+  // 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 summary_;  // The test failure summary.
+  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.
+//
+// Don't inherit from TestPartResultArray as its destructor is not
+// virtual.
+class GTEST_API_ TestPartResultArray {
+ public:
+  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:
+  std::vector<TestPartResult> array_;
+
+  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;
+};
+
+namespace internal {
+
+// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a
+// statement generates new fatal failures. To do so it registers itself as the
+// current test part result reporter. Besides checking if fatal failures were
+// reported, it only delegates the reporting to the former result reporter.
+// The original result reporter is restored in the destructor.
+// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+class GTEST_API_ HasNewFatalFailureHelper
+    : public TestPartResultReporterInterface {
+ public:
+  HasNewFatalFailureHelper();
+  virtual ~HasNewFatalFailureHelper();
+  virtual void ReportTestPartResult(const TestPartResult& result);
+  bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
+ private:
+  bool has_new_fatal_failure_;
+  TestPartResultReporterInterface* original_reporter_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
+};
+
+}  // namespace internal
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
diff --git a/protobuf/gtest/include/gtest/gtest-typed-test.h b/protobuf/gtest/include/gtest/gtest-typed-test.h
new file mode 100644
index 0000000..1ec8eb8
--- /dev/null
+++ b/protobuf/gtest/include/gtest/gtest-typed-test.h
@@ -0,0 +1,259 @@
+// 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)
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
+
+// This header implements typed tests and type-parameterized tests.
+
+// Typed (aka type-driven) tests repeat the same test for types in a
+// list.  You must know which types you want to test with when writing
+// typed tests. Here's how you do it:
+
+#if 0
+
+// First, define a fixture class template.  It should be parameterized
+// by a type.  Remember to derive it from testing::Test.
+template <typename T>
+class FooTest : public testing::Test {
+ public:
+  ...
+  typedef std::list<T> List;
+  static T shared_;
+  T value_;
+};
+
+// Next, associate a list of types with the test case, which will be
+// repeated for each type in the list.  The typedef is necessary for
+// the macro to parse correctly.
+typedef testing::Types<char, int, unsigned int> MyTypes;
+TYPED_TEST_CASE(FooTest, MyTypes);
+
+// If the type list contains only one type, you can write that type
+// directly without Types<...>:
+//   TYPED_TEST_CASE(FooTest, int);
+
+// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
+// tests for this test case as you want.
+TYPED_TEST(FooTest, DoesBlah) {
+  // Inside a test, refer to TypeParam to get the type parameter.
+  // Since we are inside a derived class template, C++ requires use to
+  // visit the members of FooTest via 'this'.
+  TypeParam n = this->value_;
+
+  // To visit static members of the fixture, add the TestFixture::
+  // prefix.
+  n += TestFixture::shared_;
+
+  // To refer to typedefs in the fixture, add the "typename
+  // TestFixture::" prefix.
+  typename TestFixture::List values;
+  values.push_back(n);
+  ...
+}
+
+TYPED_TEST(FooTest, HasPropertyA) { ... }
+
+#endif  // 0
+
+// Type-parameterized tests are abstract test patterns parameterized
+// by a type.  Compared with typed tests, type-parameterized tests
+// allow you to define the test pattern without knowing what the type
+// parameters are.  The defined pattern can be instantiated with
+// different types any number of times, in any number of translation
+// units.
+//
+// If you are designing an interface or concept, you can define a
+// suite of type-parameterized tests to verify properties that any
+// valid implementation of the interface/concept should have.  Then,
+// each implementation can easily instantiate the test suite to verify
+// that it conforms to the requirements, without having to write
+// similar tests repeatedly.  Here's an example:
+
+#if 0
+
+// First, define a fixture class template.  It should be parameterized
+// by a type.  Remember to derive it from testing::Test.
+template <typename T>
+class FooTest : public testing::Test {
+  ...
+};
+
+// Next, declare that you will define a type-parameterized test case
+// (the _P suffix is for "parameterized" or "pattern", whichever you
+// prefer):
+TYPED_TEST_CASE_P(FooTest);
+
+// Then, use TYPED_TEST_P() to define as many type-parameterized tests
+// for this type-parameterized test case as you want.
+TYPED_TEST_P(FooTest, DoesBlah) {
+  // Inside a test, refer to TypeParam to get the type parameter.
+  TypeParam n = 0;
+  ...
+}
+
+TYPED_TEST_P(FooTest, HasPropertyA) { ... }
+
+// Now the tricky part: you need to register all test patterns before
+// you can instantiate them.  The first argument of the macro is the
+// test case name; the rest are the names of the tests in this test
+// case.
+REGISTER_TYPED_TEST_CASE_P(FooTest,
+                           DoesBlah, HasPropertyA);
+
+// Finally, you are free to instantiate the pattern with the types you
+// want.  If you put the above code in a header file, you can #include
+// it in multiple C++ source files and instantiate it multiple times.
+//
+// To distinguish different instances of the pattern, the first
+// argument to the INSTANTIATE_* macro is a prefix that will be added
+// to the actual test case name.  Remember to pick unique prefixes for
+// different instances.
+typedef testing::Types<char, int, unsigned int> MyTypes;
+INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
+
+// If the type list contains only one type, you can write that type
+// directly without Types<...>:
+//   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
+
+#endif  // 0
+
+#include <gtest/internal/gtest-port.h>
+#include <gtest/internal/gtest-type-util.h>
+
+// Implements typed tests.
+
+#if GTEST_HAS_TYPED_TEST
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the name of the typedef for the type parameters of the
+// given test case.
+#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
+
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
+#define TYPED_TEST_CASE(CaseName, Types) \
+  typedef ::testing::internal::TypeList< Types >::type \
+      GTEST_TYPE_PARAMS_(CaseName)
+
+#define TYPED_TEST(CaseName, TestName) \
+  template <typename gtest_TypeParam_> \
+  class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
+      : public CaseName<gtest_TypeParam_> { \
+   private: \
+    typedef CaseName<gtest_TypeParam_> TestFixture; \
+    typedef gtest_TypeParam_ TypeParam; \
+    virtual void TestBody(); \
+  }; \
+  bool gtest_##CaseName##_##TestName##_registered_ = \
+      ::testing::internal::TypeParameterizedTest< \
+          CaseName, \
+          ::testing::internal::TemplateSel< \
+              GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
+          GTEST_TYPE_PARAMS_(CaseName)>::Register(\
+              "", #CaseName, #TestName, 0); \
+  template <typename gtest_TypeParam_> \
+  void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
+
+#endif  // GTEST_HAS_TYPED_TEST
+
+// Implements type-parameterized tests.
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the namespace name that the type-parameterized tests for
+// the given type-parameterized test case are defined in.  The exact
+// name of the namespace is subject to change without notice.
+#define GTEST_CASE_NAMESPACE_(TestCaseName) \
+  gtest_case_##TestCaseName##_
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Expands to the name of the variable used to remember the names of
+// the defined tests in the given test case.
+#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
+  gtest_typed_test_case_p_state_##TestCaseName##_
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
+//
+// Expands to the name of the variable used to remember the names of
+// the registered tests in the given test case.
+#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
+  gtest_registered_test_names_##TestCaseName##_
+
+// The variables defined in the type-parameterized test macros are
+// static as typically these macros are used in a .h file that can be
+// #included in multiple translation units linked together.
+#define TYPED_TEST_CASE_P(CaseName) \
+  static ::testing::internal::TypedTestCasePState \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
+
+#define TYPED_TEST_P(CaseName, TestName) \
+  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
+  template <typename gtest_TypeParam_> \
+  class TestName : public CaseName<gtest_TypeParam_> { \
+   private: \
+    typedef CaseName<gtest_TypeParam_> TestFixture; \
+    typedef gtest_TypeParam_ TypeParam; \
+    virtual void TestBody(); \
+  }; \
+  static bool gtest_##TestName##_defined_ = \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
+          __FILE__, __LINE__, #CaseName, #TestName); \
+  } \
+  template <typename gtest_TypeParam_> \
+  void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
+
+#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
+  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
+  typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
+  } \
+  static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
+      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
+          __FILE__, __LINE__, #__VA_ARGS__)
+
+// The 'Types' template argument below must have spaces around it
+// since some compilers may choke on '>>' when passing a template
+// instance (e.g. Types<int>)
+#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
+  bool gtest_##Prefix##_##CaseName = \
+      ::testing::internal::TypeParameterizedTestCase<CaseName, \
+          GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
+          ::testing::internal::TypeList< Types >::type>::Register(\
+              #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
diff --git a/protobuf/gtest/include/gtest/gtest.h b/protobuf/gtest/include/gtest/gtest.h
new file mode 100644
index 0000000..921fad1
--- /dev/null
+++ b/protobuf/gtest/include/gtest/gtest.h
@@ -0,0 +1,2052 @@
+// 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_
+
+#include <limits>
+#include <vector>
+
+#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-param-test.h>
+#include <gtest/gtest_prod.h>
+#include <gtest/gtest-test-part.h>
+#include <gtest/gtest-typed-test.h>
+
+// Depending on the platform, different string classes are available.
+// 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 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_GLOBAL_STRING to 0.
+//
+// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined
+// heuristically.
+
+namespace testing {
+
+// Declares the flags.
+
+// This flag temporary enables the disabled tests.
+GTEST_DECLARE_bool_(also_run_disabled_tests);
+
+// This flag brings the debugger on an assertion failure.
+GTEST_DECLARE_bool_(break_on_failure);
+
+// This flag controls whether Google Test catches all test-thrown exceptions
+// and logs them as failures.
+GTEST_DECLARE_bool_(catch_exceptions);
+
+// This flag enables using colors in terminal output. Available values are
+// "yes" to enable colors, "no" (disable colors), or "auto" (the default)
+// to let Google Test decide.
+GTEST_DECLARE_string_(color);
+
+// This flag sets up the filter to select by name using a glob pattern
+// the tests to run. If the filter is not given all tests are executed.
+GTEST_DECLARE_string_(filter);
+
+// This flag causes the Google Test to list tests. None of the tests listed
+// are actually run if the flag is provided.
+GTEST_DECLARE_bool_(list_tests);
+
+// This flag controls whether Google Test emits a detailed XML report to a file
+// in addition to its normal textual output.
+GTEST_DECLARE_string_(output);
+
+// This flags control whether Google Test prints the elapsed time for each
+// test.
+GTEST_DECLARE_bool_(print_time);
+
+// This flag specifies the random number seed.
+GTEST_DECLARE_int32_(random_seed);
+
+// This flag sets how many times the tests are repeated. The default value
+// is 1. If the value is -1 the tests are repeating forever.
+GTEST_DECLARE_int32_(repeat);
+
+// This flag controls whether Google Test includes Google Test internal
+// stack frames in failure stack traces.
+GTEST_DECLARE_bool_(show_internal_stack_frames);
+
+// When this flag is specified, tests' order is randomized on every iteration.
+GTEST_DECLARE_bool_(shuffle);
+
+// This flag specifies the maximum number of stack frames to be
+// printed in a failure message.
+GTEST_DECLARE_int32_(stack_trace_depth);
+
+// When this flag is specified, a failed assertion will throw an
+// exception if exceptions are enabled, or exit the program with a
+// non-zero code otherwise.
+GTEST_DECLARE_bool_(throw_on_failure);
+
+// The upper limit for valid stack trace depths.
+const int kMaxStackTraceDepth = 100;
+
+namespace internal {
+
+class AssertHelper;
+class DefaultGlobalTestPartResultReporter;
+class ExecDeathTest;
+class NoExecDeathTest;
+class FinalSuccessChecker;
+class GTestFlagSaver;
+class TestInfoImpl;
+class TestResultAccessor;
+class TestEventListenersAccessor;
+class TestEventRepeater;
+class WindowsDeathTest;
+class UnitTestImpl* GetUnitTestImpl();
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
+                                    const String& message);
+class PrettyUnitTestResultPrinter;
+class XmlUnitTestResultPrinter;
+
+// 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 describes how it failed.
+//
+// To create an instance of this class, use one of the factory functions
+// (AssertionSuccess() and AssertionFailure()).
+//
+// This class is useful for two purposes:
+//   1. Defining predicate functions to be used with Boolean test assertions
+//      EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
+//   2. Defining predicate-format functions to be
+//      used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
+//
+// For example, if you define IsEven predicate:
+//
+//   testing::AssertionResult IsEven(int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess();
+//     else
+//       return testing::AssertionFailure() << n << " is odd";
+//   }
+//
+// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
+// will print the message
+//
+//   Value of: IsEven(Fib(5))
+//     Actual: false (5 is odd)
+//   Expected: true
+//
+// instead of a more opaque
+//
+//   Value of: IsEven(Fib(5))
+//     Actual: false
+//   Expected: true
+//
+// in case IsEven is a simple Boolean predicate.
+//
+// If you expect your predicate to be reused and want to support informative
+// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
+// about half as often as positive ones in our tests), supply messages for
+// both success and failure cases:
+//
+//   testing::AssertionResult IsEven(int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess() << n << " is even";
+//     else
+//       return testing::AssertionFailure() << n << " is odd";
+//   }
+//
+// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
+//
+//   Value of: IsEven(Fib(6))
+//     Actual: true (8 is even)
+//   Expected: false
+//
+// NB: Predicates that support negative Boolean assertions have reduced
+// performance in positive ones so be careful not to use them in tests
+// that have lots (tens of thousands) of positive Boolean assertions.
+//
+// To use this class with EXPECT_PRED_FORMAT assertions such as:
+//
+//   // Verifies that Foo() returns an even number.
+//   EXPECT_PRED_FORMAT1(IsEven, Foo());
+//
+// you need to define:
+//
+//   testing::AssertionResult IsEven(const char* expr, int n) {
+//     if ((n % 2) == 0)
+//       return testing::AssertionSuccess();
+//     else
+//       return testing::AssertionFailure()
+//         << "Expected: " << expr << " is even\n  Actual: it's " << n;
+//   }
+//
+// If Foo() returns 5, you will see the following message:
+//
+//   Expected: Foo() is even
+//     Actual: it's 5
+//
+class GTEST_API_ AssertionResult {
+ public:
+  // Copy constructor.
+  // Used in EXPECT_TRUE/FALSE(assertion_result).
+  AssertionResult(const AssertionResult& other);
+  // Used in the EXPECT_TRUE/FALSE(bool_expression).
+  explicit AssertionResult(bool success) : success_(success) {}
+
+  // Returns true iff the assertion succeeded.
+  operator bool() const { return success_; }  // NOLINT
+
+  // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+  AssertionResult operator!() const;
+
+  // Returns the text streamed into this AssertionResult. Test assertions
+  // use it when they fail (i.e., the predicate's outcome doesn't match the
+  // assertion's expectation). When nothing has been streamed into the
+  // object, returns an empty string.
+  const char* message() const {
+    return message_.get() != NULL && message_->c_str() != NULL ?
+           message_->c_str() : "";
+  }
+  // TODO(vladl@google.com): Remove this after making sure no clients use it.
+  // Deprecated; please use message() instead.
+  const char* failure_message() const { return message(); }
+
+  // Streams a custom failure message into this object.
+  template <typename T> AssertionResult& operator<<(const T& value);
+
+ private:
+  // No implementation - we want AssertionResult to be
+  // copy-constructible but not assignable.
+  void operator=(const AssertionResult& other);
+
+  // Stores result of the assertion predicate.
+  bool success_;
+  // Stores the message describing the condition in case the expectation
+  // construct is not satisfied with the predicate's outcome.
+  // Referenced via a pointer to avoid taking too much stack frame space
+  // with test assertions.
+  internal::scoped_ptr<internal::String> message_;
+};  // class AssertionResult
+
+// Streams a custom failure message into this object.
+template <typename T>
+AssertionResult& AssertionResult::operator<<(const T& value) {
+  Message msg;
+  if (message_.get() != NULL)
+    msg << *message_;
+  msg << value;
+  message_.reset(new internal::String(msg.GetString()));
+  return *this;
+}
+
+// Makes a successful assertion result.
+GTEST_API_ AssertionResult AssertionSuccess();
+
+// Makes a failed assertion result.
+GTEST_API_ AssertionResult AssertionFailure();
+
+// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << msg.
+GTEST_API_ 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 GTEST_API_ Test {
+ public:
+  friend class internal::TestInfoImpl;
+
+  // Defines types for pointers to functions that set up and tear down
+  // a test case.
+  typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;
+  typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;
+
+  // The d'tor is virtual as we intend to inherit from Test.
+  virtual ~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() {}
+
+  // Returns true iff the current test has a fatal failure.
+  static bool HasFatalFailure();
+
+  // Returns true iff the current test has a non-fatal failure.
+  static bool HasNonfatalFailure();
+
+  // Returns true iff the current test has a (either fatal or
+  // non-fatal) failure.
+  static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
+
+  // 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 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);
+};
+
+typedef internal::TimeInMillis TimeInMillis;
+
+// 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* a_key, const char* a_value) :
+    key_(a_key), value_(a_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.
+  internal::String key_;
+  // The value supplied by the user.
+  internal::String value_;
+};
+
+// 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 GTEST_API_ TestResult {
+ public:
+  // Creates an empty TestResult.
+  TestResult();
+
+  // D'tor.  Do not inherit from TestResult.
+  ~TestResult();
+
+  // 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 the number of the test properties.
+  int test_property_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;
+
+  // Returns true iff the test fatally failed.
+  bool HasFatalFailure() const;
+
+  // Returns true iff the test has a non-fatal failure.
+  bool HasNonfatalFailure() const;
+
+  // Returns the elapsed time, in milliseconds.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns the i-th test part result among all the results. i can range
+  // from 0 to test_property_count() - 1. If i is not in that range, aborts
+  // the program.
+  const TestPartResult& GetTestPartResult(int i) const;
+
+  // Returns the i-th test property. i can range from 0 to
+  // test_property_count() - 1. If i is not in that range, aborts the
+  // program.
+  const TestProperty& GetTestProperty(int i) const;
+
+ private:
+  friend class TestInfo;
+  friend class UnitTest;
+  friend class internal::DefaultGlobalTestPartResultReporter;
+  friend class internal::ExecDeathTest;
+  friend class internal::TestInfoImpl;
+  friend class internal::TestResultAccessor;
+  friend class internal::UnitTestImpl;
+  friend class internal::WindowsDeathTest;
+
+  // Gets the vector of TestPartResults.
+  const std::vector<TestPartResult>& test_part_results() const {
+    return test_part_results_;
+  }
+
+  // Gets the vector of TestProperties.
+  const std::vector<TestProperty>& test_properties() const {
+    return test_properties_;
+  }
+
+  // Sets the elapsed time.
+  void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
+
+  // 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 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 TestProperty& test_property);
+
+  // Adds a test part result to the list.
+  void AddTestPartResult(const TestPartResult& test_part_result);
+
+  // 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 test part results.
+  void ClearTestPartResults();
+
+  // Clears the object.
+  void Clear();
+
+  // Protects mutable state of the property vector and of owned
+  // properties, whose values may be updated.
+  internal::Mutex test_properites_mutex_;
+
+  // The vector of TestPartResults
+  std::vector<TestPartResult> test_part_results_;
+  // The vector of TestProperties
+  std::vector<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
+
+// 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 GTEST_API_ TestInfo {
+ public:
+  // Destructs a TestInfo object.  This function is not virtual, so
+  // don't inherit from TestInfo.
+  ~TestInfo();
+
+  // Returns the test case name.
+  const char* test_case_name() const;
+
+  // Returns the test name.
+  const char* name() const;
+
+  // Returns the test case comment.
+  const char* test_case_comment() const;
+
+  // Returns the test comment.
+  const char* comment() const;
+
+  // Returns true if this test should run, that is if the test is not disabled
+  // (or it is disabled but the also_run_disabled_tests flag has been specified)
+  // and its full name matches the user-specified filter.
+  //
+  // 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 TestResult* result() const;
+
+ private:
+#if GTEST_HAS_DEATH_TEST
+  friend class internal::DefaultDeathTestFactory;
+#endif  // GTEST_HAS_DEATH_TEST
+  friend class Test;
+  friend class TestCase;
+  friend class internal::TestInfoImpl;
+  friend class internal::UnitTestImpl;
+  friend TestInfo* internal::MakeAndRegisterTestInfo(
+      const char* test_case_name, const char* name,
+      const char* test_case_comment, const char* comment,
+      internal::TypeId fixture_class_id,
+      Test::SetUpTestCaseFunc set_up_tc,
+      Test::TearDownTestCaseFunc tear_down_tc,
+      internal::TestFactoryBase* factory);
+
+  // Returns true if this test matches the user-specified filter.
+  bool matches_filter() const;
+
+  // 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. The newly constructed instance assumes
+  // ownership of the factory object.
+  TestInfo(const char* test_case_name, const char* name,
+           const char* test_case_comment, const char* comment,
+           internal::TypeId fixture_class_id,
+           internal::TestFactoryBase* factory);
+
+  // An opaque implementation object.
+  internal::TestInfoImpl* impl_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);
+};
+
+// A test case, which consists of a vector of TestInfos.
+//
+// TestCase is not copyable.
+class GTEST_API_ 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, const char* comment,
+           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 the test case comment.
+  const char* comment() const { return comment_.c_str(); }
+
+  // Returns true if any test in this test case should run.
+  bool should_run() const { return should_run_; }
+
+  // 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.
+  TimeInMillis elapsed_time() const { return elapsed_time_; }
+
+  // Returns the i-th test among all the tests. i can range from 0 to
+  // total_test_count() - 1. If i is not in that range, returns NULL.
+  const TestInfo* GetTestInfo(int i) const;
+
+ private:
+  friend class Test;
+  friend class internal::UnitTestImpl;
+
+  // Gets the (mutable) vector of TestInfos in this TestCase.
+  std::vector<TestInfo*>& test_info_list() { return test_info_list_; }
+
+  // Gets the (immutable) vector of TestInfos in this TestCase.
+  const std::vector<TestInfo*>& test_info_list() const {
+    return test_info_list_;
+  }
+
+  // Returns the i-th test among all the tests. i can range from 0 to
+  // total_test_count() - 1. If i is not in that range, returns NULL.
+  TestInfo* GetMutableTestInfo(int i);
+
+  // Sets the should_run member.
+  void set_should_run(bool should) { should_run_ = should; }
+
+  // Adds a TestInfo to this test case.  Will delete the TestInfo upon
+  // destruction of the TestCase object.
+  void AddTestInfo(TestInfo * test_info);
+
+  // 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();
+
+  // Returns true iff test passed.
+  static bool TestPassed(const TestInfo * test_info);
+
+  // Returns true iff test failed.
+  static bool TestFailed(const TestInfo * test_info);
+
+  // Returns true iff test is disabled.
+  static bool TestDisabled(const TestInfo * test_info);
+
+  // Returns true if the given test should run.
+  static bool ShouldRunTest(const TestInfo *test_info);
+
+  // Shuffles the tests in this test case.
+  void ShuffleTests(internal::Random* random);
+
+  // Restores the test order to before the first shuffle.
+  void UnshuffleTests();
+
+  // Name of the test case.
+  internal::String name_;
+  // Comment on the test case.
+  internal::String comment_;
+  // The vector of TestInfos in their original order.  It owns the
+  // elements in the vector.
+  std::vector<TestInfo*> test_info_list_;
+  // Provides a level of indirection for the test list to allow easy
+  // shuffling and restoring the test order.  The i-th element in this
+  // vector is the index of the i-th test in the shuffled test list.
+  std::vector<int> test_indices_;
+  // 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.
+  TimeInMillis elapsed_time_;
+
+  // We disallow copying TestCases.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);
+};
+
+// 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; }
+};
+
+// The interface for tracing execution of tests. The methods are organized in
+// the order the corresponding events are fired.
+class TestEventListener {
+ public:
+  virtual ~TestEventListener() {}
+
+  // Fired before any test activity starts.
+  virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;
+
+  // Fired before each iteration of tests starts.  There may be more than
+  // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration
+  // index, starting from 0.
+  virtual void OnTestIterationStart(const UnitTest& unit_test,
+                                    int iteration) = 0;
+
+  // Fired before environment set-up for each iteration of tests starts.
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;
+
+  // Fired after environment set-up for each iteration of tests ends.
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
+
+  // Fired before the test case starts.
+  virtual void OnTestCaseStart(const TestCase& test_case) = 0;
+
+  // Fired before the test starts.
+  virtual void OnTestStart(const TestInfo& test_info) = 0;
+
+  // Fired after a failed assertion or a SUCCESS().
+  virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
+
+  // Fired after the test ends.
+  virtual void OnTestEnd(const TestInfo& test_info) = 0;
+
+  // Fired after the test case ends.
+  virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
+
+  // Fired before environment tear-down for each iteration of tests starts.
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
+
+  // Fired after environment tear-down for each iteration of tests ends.
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;
+
+  // Fired after each iteration of tests finishes.
+  virtual void OnTestIterationEnd(const UnitTest& unit_test,
+                                  int iteration) = 0;
+
+  // Fired after all test activities have ended.
+  virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;
+};
+
+// The convenience class for users who need to override just one or two
+// methods and are not concerned that a possible change to a signature of
+// the methods they override will not be caught during the build.  For
+// comments about each method please see the definition of TestEventListener
+// above.
+class EmptyTestEventListener : public TestEventListener {
+ public:
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
+                                    int /*iteration*/) {}
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
+  virtual void OnTestStart(const TestInfo& /*test_info*/) {}
+  virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
+  virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
+  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
+                                  int /*iteration*/) {}
+  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+};
+
+// TestEventListeners lets users add listeners to track events in Google Test.
+class GTEST_API_ TestEventListeners {
+ public:
+  TestEventListeners();
+  ~TestEventListeners();
+
+  // Appends an event listener to the end of the list. Google Test assumes
+  // the ownership of the listener (i.e. it will delete the listener when
+  // the test program finishes).
+  void Append(TestEventListener* listener);
+
+  // Removes the given event listener from the list and returns it.  It then
+  // becomes the caller's responsibility to delete the listener. Returns
+  // NULL if the listener is not found in the list.
+  TestEventListener* Release(TestEventListener* listener);
+
+  // Returns the standard listener responsible for the default console
+  // output.  Can be removed from the listeners list to shut down default
+  // console output.  Note that removing this object from the listener list
+  // with Release transfers its ownership to the caller and makes this
+  // function return NULL the next time.
+  TestEventListener* default_result_printer() const {
+    return default_result_printer_;
+  }
+
+  // Returns the standard listener responsible for the default XML output
+  // controlled by the --gtest_output=xml flag.  Can be removed from the
+  // listeners list by users who want to shut down the default XML output
+  // controlled by this flag and substitute it with custom one.  Note that
+  // removing this object from the listener list with Release transfers its
+  // ownership to the caller and makes this function return NULL the next
+  // time.
+  TestEventListener* default_xml_generator() const {
+    return default_xml_generator_;
+  }
+
+ private:
+  friend class TestCase;
+  friend class internal::DefaultGlobalTestPartResultReporter;
+  friend class internal::NoExecDeathTest;
+  friend class internal::TestEventListenersAccessor;
+  friend class internal::TestInfoImpl;
+  friend class internal::UnitTestImpl;
+
+  // Returns repeater that broadcasts the TestEventListener events to all
+  // subscribers.
+  TestEventListener* repeater();
+
+  // Sets the default_result_printer attribute to the provided listener.
+  // The listener is also added to the listener list and previous
+  // default_result_printer is removed from it and deleted. The listener can
+  // also be NULL in which case it will not be added to the list. Does
+  // nothing if the previous and the current listener objects are the same.
+  void SetDefaultResultPrinter(TestEventListener* listener);
+
+  // Sets the default_xml_generator attribute to the provided listener.  The
+  // listener is also added to the listener list and previous
+  // default_xml_generator is removed from it and deleted. The listener can
+  // also be NULL in which case it will not be added to the list. Does
+  // nothing if the previous and the current listener objects are the same.
+  void SetDefaultXmlGenerator(TestEventListener* listener);
+
+  // Controls whether events will be forwarded by the repeater to the
+  // listeners in the list.
+  bool EventForwardingEnabled() const;
+  void SuppressEventForwarding();
+
+  // The actual list of listeners.
+  internal::TestEventRepeater* repeater_;
+  // Listener responsible for the standard result output.
+  TestEventListener* default_result_printer_;
+  // Listener responsible for the creation of the XML output file.
+  TestEventListener* default_xml_generator_;
+
+  // We disallow copying TestEventListeners.
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners);
+};
+
+// A UnitTest consists of a vector 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 GTEST_API_ 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();
+
+  // 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 working directory when the first TEST() or TEST_F()
+  // was executed.  The UnitTest object owns the string.
+  const char* original_working_dir() const;
+
+  // 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;
+
+  // Returns the random seed used at the start of the current test run.
+  int random_seed() const;
+
+#if GTEST_HAS_PARAM_TEST
+  // Returns the ParameterizedTestCaseRegistry object used to keep track of
+  // value-parameterized tests and instantiate and register them.
+  //
+  // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
+  internal::ParameterizedTestCaseRegistry& parameterized_test_registry();
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // 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;
+
+  // Returns true iff the unit test passed (i.e. all test cases passed).
+  bool Passed() const;
+
+  // Returns true iff the unit test failed (i.e. some test case failed
+  // or something outside of all tests failed).
+  bool Failed() const;
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  const TestCase* GetTestCase(int i) const;
+
+  // Returns the list of event listeners that can be used to track events
+  // inside Google Test.
+  TestEventListeners& listeners();
+
+ private:
+  // 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.
+  void AddTestPartResult(TestPartResult::Type 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);
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  TestCase* GetMutableTestCase(int i);
+
+  // Accessors for the implementation object.
+  internal::UnitTestImpl* impl() { return impl_; }
+  const internal::UnitTestImpl* impl() const { return impl_; }
+
+  // These classes and funcions are friends as they need to access private
+  // members of UnitTest.
+  friend class Test;
+  friend class internal::AssertHelper;
+  friend class internal::ScopedTrace;
+  friend Environment* AddGlobalTestEnvironment(Environment* env);
+  friend internal::UnitTestImpl* internal::GetUnitTestImpl();
+  friend void internal::ReportFailureInUnknownLocation(
+      TestPartResult::Type result_type,
+      const internal::String& message);
+
+  // 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);
+}
+
+// Initializes Google Test.  This must be called before calling
+// RUN_ALL_TESTS().  In particular, it 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.
+//
+// Calling the function for the second time has no user-visible effect.
+GTEST_API_ void InitGoogleTest(int* argc, char** argv);
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
+
+namespace internal {
+
+// These overloaded versions handle ::std::string and ::std::wstring.
+GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) {
+  return (Message() << '"' << str << '"').GetString();
+}
+
+#if GTEST_HAS_STD_WSTRING
+GTEST_API_ 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
+GTEST_API_ inline String FormatForFailureMessage(const ::string& str) {
+  return (Message() << '"' << str << '"').GetString();
+}
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+GTEST_API_ 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) {
+#ifdef _MSC_VER
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4389)  // Temporarily disables warning on
+                               // signed/unsigned mismatch.
+#endif
+
+  if (expected == actual) {
+    return AssertionSuccess();
+  }
+
+#ifdef _MSC_VER
+#pragma warning(pop)          // Restores the warning state.
+#endif
+
+  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.
+GTEST_API_ 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);\
+  }\
+}\
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ 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.
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack);
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const char* needle, const char* haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const wchar_t* needle, const wchar_t* haystack);
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack);
+GTEST_API_ AssertionResult IsNotSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::string& needle, const ::std::string& haystack);
+
+#if GTEST_HAS_STD_WSTRING
+GTEST_API_ AssertionResult IsSubstring(
+    const char* needle_expr, const char* haystack_expr,
+    const ::std::wstring& needle, const ::std::wstring& haystack);
+GTEST_API_ 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.
+GTEST_API_ 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 GTEST_API_ AssertHelper {
+ public:
+  // Constructor.
+  AssertHelper(TestPartResult::Type type,
+               const char* file,
+               int line,
+               const char* message);
+  ~AssertHelper();
+
+  // Message assignment is a semantic trick to enable assertion
+  // streaming; see the GTEST_MESSAGE_ macro below.
+  void operator=(const Message& message) const;
+
+ private:
+  // We put our data in a struct so that the size of the AssertHelper class can
+  // be as small as possible.  This is important because gcc is incapable of
+  // re-using stack space even for temporary variables, so every EXPECT_EQ
+  // reserves stack space for another AssertHelper.
+  struct AssertHelperData {
+    AssertHelperData(TestPartResult::Type t,
+                     const char* srcfile,
+                     int line_num,
+                     const char* msg)
+        : type(t), file(srcfile), line(line_num), message(msg) { }
+
+    TestPartResult::Type const type;
+    const char*        const file;
+    int                const line;
+    String             const message;
+
+   private:
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData);
+  };
+
+  AssertHelperData* const data_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
+};
+
+}  // namespace internal
+
+#if GTEST_HAS_PARAM_TEST
+// The abstract base class that all value-parameterized tests inherit from.
+//
+// This class adds support for accessing the test parameter value via
+// the GetParam() method.
+//
+// Use it with one of the parameter generator defining functions, like Range(),
+// Values(), ValuesIn(), Bool(), and Combine().
+//
+// class FooTest : public ::testing::TestWithParam<int> {
+//  protected:
+//   FooTest() {
+//     // Can use GetParam() here.
+//   }
+//   virtual ~FooTest() {
+//     // Can use GetParam() here.
+//   }
+//   virtual void SetUp() {
+//     // Can use GetParam() here.
+//   }
+//   virtual void TearDown {
+//     // Can use GetParam() here.
+//   }
+// };
+// TEST_P(FooTest, DoesBar) {
+//   // Can use GetParam() method here.
+//   Foo foo;
+//   ASSERT_TRUE(foo.DoesBar(GetParam()));
+// }
+// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
+
+template <typename T>
+class TestWithParam : public Test {
+ public:
+  typedef T ParamType;
+
+  // The current parameter value. Is also available in the test fixture's
+  // constructor.
+  const ParamType& GetParam() const { return *parameter_; }
+
+ private:
+  // Sets parameter value. The caller is responsible for making sure the value
+  // remains alive and unchanged throughout the current test.
+  static void SetParam(const ParamType* parameter) {
+    parameter_ = parameter;
+  }
+
+  // Static value used for accessing parameter during a test lifetime.
+  static const ParamType* parameter_;
+
+  // TestClass must be a subclass of TestWithParam<T>.
+  template <class TestClass> friend class internal::ParameterizedTestFactory;
+};
+
+template <typename T>
+const T* TestWithParam<T>::parameter_ = NULL;
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+// 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 GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
+
+// Define this macro to 1 to omit the definition of FAIL(), which is a
+// generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_FAIL
+#define FAIL() GTEST_FAIL()
+#endif
+
+// Generates a success with a generic message.
+#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded")
+
+// Define this macro to 1 to omit the definition of SUCCEED(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_SUCCEED
+#define SUCCEED() GTEST_SUCCEED()
+#endif
+
+// Macros for testing exceptions.
+//
+//    * {ASSERT|EXPECT}_THROW(statement, expected_exception):
+//         Tests that the statement throws the expected exception.
+//    * {ASSERT|EXPECT}_NO_THROW(statement):
+//         Tests that the statement doesn't throw any exception.
+//    * {ASSERT|EXPECT}_ANY_THROW(statement):
+//         Tests that the statement throws an exception.
+
+#define EXPECT_THROW(statement, expected_exception) \
+  GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_NO_THROW(statement) \
+  GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)
+#define EXPECT_ANY_THROW(statement) \
+  GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)
+#define ASSERT_THROW(statement, expected_exception) \
+  GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)
+#define ASSERT_NO_THROW(statement) \
+  GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)
+#define ASSERT_ANY_THROW(statement) \
+  GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)
+
+// Boolean assertions. Condition can be either a Boolean expression or an
+// AssertionResult. For more information on how to use AssertionResult with
+// these macros see comments on that class.
+#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.
+#include <gtest/gtest_pred_impl.h>
+
+// 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.
+GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2,
+                                   float val1, float val2);
+GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2,
+                                    double val1, double val2);
+
+
+#if 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
+
+// Macros that execute statement and check that it doesn't generate new fatal
+// failures in the current thread.
+//
+//   * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement);
+//
+// Examples:
+//
+//   EXPECT_NO_FATAL_FAILURE(Process());
+//   ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed";
+//
+#define ASSERT_NO_FATAL_FAILURE(statement) \
+    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_)
+#define EXPECT_NO_FATAL_FAILURE(statement) \
+    GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
+
+// 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))
+
+namespace internal {
+
+// This template is declared, but intentionally undefined.
+template <typename T1, typename T2>
+struct StaticAssertTypeEqHelper;
+
+template <typename T>
+struct StaticAssertTypeEqHelper<T, T> {};
+
+}  // namespace internal
+
+// Compile-time assertion for type equality.
+// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
+// the same type.  The value it returns is not interesting.
+//
+// Instead of making StaticAssertTypeEq a class template, we make it a
+// function template that invokes a helper class template.  This
+// prevents a user from misusing StaticAssertTypeEq<T1, T2> by
+// defining objects of that type.
+//
+// CAVEAT:
+//
+// When used inside a method of a class template,
+// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is
+// instantiated.  For example, given:
+//
+//   template <typename T> class Foo {
+//    public:
+//     void Bar() { testing::StaticAssertTypeEq<int, T>(); }
+//   };
+//
+// the code:
+//
+//   void Test1() { Foo<bool> foo; }
+//
+// will NOT generate a compiler error, as Foo<bool>::Bar() is never
+// actually instantiated.  Instead, you need:
+//
+//   void Test2() { Foo<bool> foo; foo.Bar(); }
+//
+// to cause a compiler error.
+template <typename T1, typename T2>
+bool StaticAssertTypeEq() {
+  internal::StaticAssertTypeEqHelper<T1, T2>();
+  return true;
+}
+
+// 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());
+//   }
+
+// Note that we call GetTestTypeId() instead of GetTypeId<
+// ::testing::Test>() here to get the type ID of testing::Test.  This
+// is to work around a suspected linker bug when using Google Test as
+// a framework on Mac OS X.  The bug causes GetTypeId<
+// ::testing::Test>() to return different values depending on whether
+// the call is from the Google Test framework itself or from user test
+// code.  GetTestTypeId() is guaranteed to always return the same
+// value, as it always calls GetTypeId<>() from the Google Test
+// framework.
+#define GTEST_TEST(test_case_name, test_name)\
+  GTEST_TEST_(test_case_name, test_name, \
+              ::testing::Test, ::testing::internal::GetTestTypeId())
+
+// Define this macro to 1 to omit the definition of TEST(), which
+// is a generic name and clashes with some other libraries.
+#if !GTEST_DONT_DEFINE_TEST
+#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)
+#endif
+
+// 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, \
+              ::testing::internal::GetTypeId<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 InitGoogleTest().
+
+#define RUN_ALL_TESTS()\
+  (::testing::UnitTest::GetInstance()->Run())
+
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_GTEST_H_
diff --git a/protobuf/gtest/include/gtest/gtest_pred_impl.h b/protobuf/gtest/include/gtest/gtest_pred_impl.h
new file mode 100644
index 0000000..e1e2f8c
--- /dev/null
+++ b/protobuf/gtest/include/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 10/02/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/protobuf/gtest/include/gtest/gtest_prod.h b/protobuf/gtest/include/gtest/gtest_prod.h
new file mode 100644
index 0000000..da80ddc
--- /dev/null
+++ b/protobuf/gtest/include/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/protobuf/gtest/include/gtest/internal/gtest-death-test-internal.h b/protobuf/gtest/include/gtest/internal/gtest-death-test-internal.h
new file mode 100644
index 0000000..e433084
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-death-test-internal.h
@@ -0,0 +1,275 @@
+// 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 kDeathTestUseFork[] = "death_test_use_fork";
+const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
+
+#if 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 GTEST_API_ 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();
+
+  static void set_last_death_test_message(const String& message);
+
+ private:
+  // A string containing a description of the outcome of the last death test.
+  static String last_death_test_message_;
+
+  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.
+GTEST_API_ 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 (::testing::internal::AlwaysTrue()) { \
+    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); \
+          GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(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 class representing the parsed contents of the
+// --gtest_internal_run_death_test flag, as it existed when
+// RUN_ALL_TESTS was called.
+class InternalRunDeathTestFlag {
+ public:
+  InternalRunDeathTestFlag(const String& a_file,
+                           int a_line,
+                           int an_index,
+                           int a_write_fd)
+      : file_(a_file), line_(a_line), index_(an_index),
+        write_fd_(a_write_fd) {}
+
+  ~InternalRunDeathTestFlag() {
+    if (write_fd_ >= 0)
+      posix::Close(write_fd_);
+  }
+
+  String file() const { return file_; }
+  int line() const { return line_; }
+  int index() const { return index_; }
+  int write_fd() const { return write_fd_; }
+
+ private:
+  String file_;
+  int line_;
+  int index_;
+  int write_fd_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
+};
+
+// 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();
+
+#else  // GTEST_HAS_DEATH_TEST
+
+// This macro is used for implementing macros such as
+// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
+// death tests are not supported. Those macros must compile on such systems
+// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
+// systems that support death tests. This allows one to write such a macro
+// on a system that does not support death tests and be sure that it will
+// compile on a death-test supporting system.
+//
+// Parameters:
+//   statement -  A statement that a macro such as EXPECT_DEATH would test
+//                for program termination. This macro has to make sure this
+//                statement is compiled but not executed, to ensure that
+//                EXPECT_DEATH_IF_SUPPORTED compiles with a certain
+//                parameter iff EXPECT_DEATH compiles with it.
+//   regex     -  A regex that a macro such as EXPECT_DEATH would use to test
+//                the output of statement.  This parameter has to be
+//                compiled but not evaluated by this macro, to ensure that
+//                this macro only accepts expressions that a macro such as
+//                EXPECT_DEATH would accept.
+//   terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
+//                and a return statement for ASSERT_DEATH_IF_SUPPORTED.
+//                This ensures that ASSERT_DEATH_IF_SUPPORTED will not
+//                compile inside functions where ASSERT_DEATH doesn't
+//                compile.
+//
+//  The branch that has an always false condition is used to ensure that
+//  statement and regex are compiled (and thus syntactically correct) but
+//  never executed. The unreachable code macro protects the terminator
+//  statement from generating an 'unreachable code' warning in case
+//  statement unconditionally returns or throws. The Message constructor at
+//  the end allows the syntax of streaming additional messages into the
+//  macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
+#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
+    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+    if (::testing::internal::AlwaysTrue()) { \
+      GTEST_LOG_(WARNING) \
+          << "Death tests are not supported on this platform.\n" \
+          << "Statement '" #statement "' cannot be verified."; \
+    } else if (::testing::internal::AlwaysFalse()) { \
+      ::testing::internal::RE::PartialMatch(".*", (regex)); \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+      terminator; \
+    } else \
+      ::testing::Message()
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-filepath.h b/protobuf/gtest/include/gtest/internal/gtest-filepath.h
new file mode 100644
index 0000000..4b76d79
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-filepath.h
@@ -0,0 +1,210 @@
+// 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 <gtest/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_
+
+#include <gtest/internal/gtest-string.h>
+
+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 GTEST_API_ FilePath {
+ public:
+  FilePath() : pathname_("") { }
+  FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
+
+  explicit FilePath(const char* pathname) : pathname_(pathname) {
+    Normalize();
+  }
+
+  explicit FilePath(const String& pathname) : pathname_(pathname) {
+    Normalize();
+  }
+
+  FilePath& operator=(const FilePath& rhs) {
+    Set(rhs);
+    return *this;
+  }
+
+  void Set(const FilePath& rhs) {
+    pathname_ = rhs.pathname_;
+  }
+
+  String ToString() const { return pathname_; }
+  const char* c_str() const { return pathname_.c_str(); }
+
+  // Returns the current working directory, or "" if unsuccessful.
+  static FilePath GetCurrentDir();
+
+  // 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);
+
+  // Given directory = "dir", relative_path = "test.xml",
+  // returns "dir/test.xml".
+  // On Windows, uses \ as the separator rather than /.
+  static FilePath ConcatPaths(const FilePath& directory,
+                              const FilePath& relative_path);
+
+  // 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);
+
+  // Returns true iff the path is NULL or "".
+  bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; }
+
+  // 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;
+
+  // Returns true if pathname describes a root directory. (Windows has one
+  // root directory per disk drive.)
+  bool IsRootDirectory() const;
+
+  // Returns true if pathname describes an absolute path.
+  bool IsAbsolutePath() const;
+
+ private:
+  // Replaces multiple consecutive separators with a single separator.
+  // For example, "bar///foo" becomes "bar/foo". Does not eliminate other
+  // redundancies that might be in a pathname involving "." or "..".
+  //
+  // A pathname with multiple consecutive separators may occur either through
+  // user error or as a result of some scripts or APIs that generate a pathname
+  // with a trailing separator. On other platforms the same API or script
+  // may NOT generate a pathname with a trailing "/". Then elsewhere that
+  // pathname may have another "/" and pathname components added to it,
+  // without checking for the separator already being there.
+  // The script language and operating system may allow paths like "foo//bar"
+  // but some of the functions in FilePath will not handle that correctly. In
+  // particular, RemoveTrailingPathSeparator() only removes one separator, and
+  // it is called in CreateDirectoriesRecursively() assuming that it will change
+  // a pathname from directory syntax (trailing separator) to filename syntax.
+  //
+  // On Windows this method also replaces the alternate path separator '/' with
+  // the primary path separator '\\', so that for example "bar\\/\\foo" becomes
+  // "bar\\foo".
+
+  void Normalize();
+
+  // Returns a pointer to the last occurence of a valid path separator in
+  // the FilePath. On Windows, for example, both '/' and '\' are valid path
+  // separators. Returns NULL if no path separator was found.
+  const char* FindLastPathSeparator() const;
+
+  String pathname_;
+};  // class FilePath
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-internal.h b/protobuf/gtest/include/gtest/internal/gtest-internal.h
new file mode 100644
index 0000000..31a66e9
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-internal.h
@@ -0,0 +1,923 @@
+// 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_
+
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_OS_LINUX
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#endif  // GTEST_OS_LINUX
+
+#include <ctype.h>
+#include <string.h>
+#include <iomanip>
+#include <limits>
+#include <set>
+
+#include <gtest/internal/gtest-string.h>
+#include <gtest/internal/gtest-filepath.h>
+#include <gtest/internal/gtest-type-util.h>
+
+// 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 AssertionResult;                 // Result of an assertion.
+class Message;                         // Represents a failure message.
+class Test;                            // Represents a test.
+class TestInfo;                        // Information about a test.
+class TestPartResult;                  // Result of a test part.
+class UnitTest;                        // A collection of test cases.
+
+namespace internal {
+
+struct TraceInfo;                      // Information about a trace point.
+class ScopedTrace;                     // Implements scoped trace.
+class TestInfoImpl;                    // Opaque implementation of TestInfo
+class UnitTestImpl;                    // Opaque implementation of UnitTest
+
+// How many times InitGoogleTest() has been called.
+extern int g_init_gtest_count;
+
+// The text used in failure messages to indicate the start of the
+// stack trace.
+GTEST_API_ extern const char kStackTraceMarker[];
+
+// 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 GTEST_ELLIPSIS_NEEDS_POD_
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+#define GTEST_IS_NULL_LITERAL_(x) false
+#else
+#define GTEST_IS_NULL_LITERAL_(x) \
+    (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)
+#endif  // GTEST_ELLIPSIS_NEEDS_POD_
+
+// Appends the user-supplied message to the Google-Test-generated message.
+GTEST_API_ String AppendUserMessage(const String& gtest_msg,
+                                    const Message& user_msg);
+
+// A helper class for creating scoped traces in user programs.
+class GTEST_API_ 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 GTEST_NEEDS_IS_POINTER_
+
+// These are needed as the Nokia Symbian and IBM XL C/C++ compilers
+// cannot decide between const T& and const T* in a function template.
+// These compilers _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
+
+// These are needed as the above solution using is_pointer has the
+// limitation that T cannot be a type without external linkage, when
+// compiled using MSVC.
+
+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  // GTEST_NEEDS_IS_POINTER_
+
+// These overloaded versions handle narrow and wide characters.
+GTEST_API_ String FormatForFailureMessage(char ch);
+GTEST_API_ 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);\
+}
+
+GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted)
+#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.
+GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
+                                     const char* actual_expression,
+                                     const String& expected_value,
+                                     const String& actual_value,
+                                     bool ignoring_case);
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+GTEST_API_ String GetBoolAssertionFailureMessage(
+    const AssertionResult& assertion_result,
+    const char* expression_text,
+    const char* actual_predicate_value,
+    const char* expected_predicate_value);
+
+// 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) { u_.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.u_.bits_ = bits;
+    return fp.u_.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 u_.bits_; }
+
+  // Returns the exponent bits of this number.
+  Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
+
+  // Returns the fraction bits of this number.
+  Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
+
+  // Returns the sign bit of this number.
+  Bits sign_bit() const { return kSignBitMask & u_.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(u_.bits_, rhs.u_.bits_)
+        <= kMaxUlps;
+  }
+
+ private:
+  // The data type used to store the actual floating-point number.
+  union FloatingPointUnion {
+    RawType value_;  // The raw floating-point number.
+    Bits bits_;      // The bits that represent the number.
+  };
+
+  // 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);
+  }
+
+  FloatingPointUnion u_;
+};
+
+// 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 const void* TypeId;
+
+template <typename T>
+class TypeIdHelper {
+ public:
+  // dummy_ must not have a const type.  Otherwise an overly eager
+  // compiler (e.g. MSVC 7.1 & 8.0) may try to merge
+  // TypeIdHelper<T>::dummy_ for different Ts as an "optimization".
+  static bool dummy_;
+};
+
+template <typename T>
+bool TypeIdHelper<T>::dummy_ = false;
+
+// 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>
+TypeId GetTypeId() {
+  // The compiler is required to allocate a different
+  // TypeIdHelper<T>::dummy_ variable for each T used to instantiate
+  // the template.  Therefore, the address of dummy_ is guaranteed to
+  // be unique.
+  return &(TypeIdHelper<T>::dummy_);
+}
+
+// Returns the type ID of ::testing::Test.  Always call this instead
+// of GetTypeId< ::testing::Test>() to get the type ID of
+// ::testing::Test, as the latter may give the wrong result due to a
+// suspected linker bug when compiling Google Test as a Mac OS X
+// framework.
+GTEST_API_ TypeId GetTestTypeId();
+
+// Defines the abstract factory interface that creates instances
+// of a Test object.
+class TestFactoryBase {
+ public:
+  virtual ~TestFactoryBase() {}
+
+  // Creates a test instance to run. The instance is both created and destroyed
+  // within TestInfoImpl::Run()
+  virtual Test* CreateTest() = 0;
+
+ protected:
+  TestFactoryBase() {}
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase);
+};
+
+// This class provides implementation of TeastFactoryBase interface.
+// It is used in TEST and TEST_F macros.
+template <class TestClass>
+class TestFactoryImpl : public TestFactoryBase {
+ public:
+  virtual Test* CreateTest() { return new TestClass; }
+};
+
+#if 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.
+GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr,
+                                            long hr);  // NOLINT
+GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr,
+                                            long hr);  // NOLINT
+
+#endif  // GTEST_OS_WINDOWS
+
+// Formats a source file path and a line number as they would appear
+// in a compiler error message.
+inline String FormatFileLocation(const char* file, int line) {
+  const char* const file_name = file == NULL ? "unknown file" : file;
+  if (line < 0) {
+    return String::Format("%s:", file_name);
+  }
+#ifdef _MSC_VER
+  return String::Format("%s(%d):", file_name, line);
+#else
+  return String::Format("%s:%d:", file_name, line);
+#endif  // _MSC_VER
+}
+
+// Types of SetUpTestCase() and TearDownTestCase() functions.
+typedef void (*SetUpTestCaseFunc)();
+typedef void (*TearDownTestCaseFunc)();
+
+// Creates a new TestInfo object and registers it with Google Test;
+// returns the created object.
+//
+// Arguments:
+//
+//   test_case_name:   name of the test case
+//   name:             name of the test
+//   test_case_comment: a comment on the test case that will be included in
+//                      the test output
+//   comment:          a comment on the test that will be included in the
+//                     test output
+//   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
+//   factory:          pointer to the factory that creates a test object.
+//                     The newly created TestInfo instance will assume
+//                     ownership of the factory object.
+GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
+    const char* test_case_name, const char* name,
+    const char* test_case_comment, const char* comment,
+    TypeId fixture_class_id,
+    SetUpTestCaseFunc set_up_tc,
+    TearDownTestCaseFunc tear_down_tc,
+    TestFactoryBase* factory);
+
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false.  None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr);
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// State of the definition of a type-parameterized test case.
+class GTEST_API_ TypedTestCasePState {
+ public:
+  TypedTestCasePState() : registered_(false) {}
+
+  // Adds the given test name to defined_test_names_ and return true
+  // if the test case hasn't been registered; otherwise aborts the
+  // program.
+  bool AddTestName(const char* file, int line, const char* case_name,
+                   const char* test_name) {
+    if (registered_) {
+      fprintf(stderr, "%s Test %s must be defined before "
+              "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
+              FormatFileLocation(file, line).c_str(), test_name, case_name);
+      fflush(stderr);
+      posix::Abort();
+    }
+    defined_test_names_.insert(test_name);
+    return true;
+  }
+
+  // Verifies that registered_tests match the test names in
+  // defined_test_names_; returns registered_tests if successful, or
+  // aborts the program otherwise.
+  const char* VerifyRegisteredTestNames(
+      const char* file, int line, const char* registered_tests);
+
+ private:
+  bool registered_;
+  ::std::set<const char*> defined_test_names_;
+};
+
+// Skips to the first non-space char after the first comma in 'str';
+// returns NULL if no comma is found in 'str'.
+inline const char* SkipComma(const char* str) {
+  const char* comma = strchr(str, ',');
+  if (comma == NULL) {
+    return NULL;
+  }
+  while (isspace(*(++comma))) {}
+  return comma;
+}
+
+// Returns the prefix of 'str' before the first comma in it; returns
+// the entire string if it contains no comma.
+inline String GetPrefixUntilComma(const char* str) {
+  const char* comma = strchr(str, ',');
+  return comma == NULL ? String(str) : String(str, comma - str);
+}
+
+// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
+// registers a list of type-parameterized tests with Google Test.  The
+// return value is insignificant - we just need to return something
+// such that we can call this function in a namespace scope.
+//
+// Implementation note: The GTEST_TEMPLATE_ macro declares a template
+// template parameter.  It's defined in gtest-type-util.h.
+template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types>
+class TypeParameterizedTest {
+ public:
+  // 'index' is the index of the test in the type list 'Types'
+  // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
+  // Types).  Valid values for 'index' are [0, N - 1] where N is the
+  // length of Types.
+  static bool Register(const char* prefix, const char* case_name,
+                       const char* test_names, int index) {
+    typedef typename Types::Head Type;
+    typedef Fixture<Type> FixtureClass;
+    typedef typename GTEST_BIND_(TestSel, Type) TestClass;
+
+    // First, registers the first type-parameterized test in the type
+    // list.
+    MakeAndRegisterTestInfo(
+        String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/",
+                       case_name, index).c_str(),
+        GetPrefixUntilComma(test_names).c_str(),
+        String::Format("TypeParam = %s", GetTypeName<Type>().c_str()).c_str(),
+        "",
+        GetTypeId<FixtureClass>(),
+        TestClass::SetUpTestCase,
+        TestClass::TearDownTestCase,
+        new TestFactoryImpl<TestClass>);
+
+    // Next, recurses (at compile time) with the tail of the type list.
+    return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
+        ::Register(prefix, case_name, test_names, index + 1);
+  }
+};
+
+// The base case for the compile time recursion.
+template <GTEST_TEMPLATE_ Fixture, class TestSel>
+class TypeParameterizedTest<Fixture, TestSel, Types0> {
+ public:
+  static bool Register(const char* /*prefix*/, const char* /*case_name*/,
+                       const char* /*test_names*/, int /*index*/) {
+    return true;
+  }
+};
+
+// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()
+// registers *all combinations* of 'Tests' and 'Types' with Google
+// Test.  The return value is insignificant - we just need to return
+// something such that we can call this function in a namespace scope.
+template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
+class TypeParameterizedTestCase {
+ public:
+  static bool Register(const char* prefix, const char* case_name,
+                       const char* test_names) {
+    typedef typename Tests::Head Head;
+
+    // First, register the first test in 'Test' for each type in 'Types'.
+    TypeParameterizedTest<Fixture, Head, Types>::Register(
+        prefix, case_name, test_names, 0);
+
+    // Next, recurses (at compile time) with the tail of the test list.
+    return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
+        ::Register(prefix, case_name, SkipComma(test_names));
+  }
+};
+
+// The base case for the compile time recursion.
+template <GTEST_TEMPLATE_ Fixture, typename Types>
+class TypeParameterizedTestCase<Fixture, Templates0, Types> {
+ public:
+  static bool Register(const char* /*prefix*/, const char* /*case_name*/,
+                       const char* /*test_names*/) {
+    return true;
+  }
+};
+
+#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// 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
+// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
+// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
+GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test,
+                                                  int skip_count);
+
+// Helpers for suppressing warnings on unreachable code or constant
+// condition.
+
+// Always returns true.
+GTEST_API_ bool AlwaysTrue();
+
+// Always returns false.
+inline bool AlwaysFalse() { return !AlwaysTrue(); }
+
+// A simple Linear Congruential Generator for generating random
+// numbers with a uniform distribution.  Unlike rand() and srand(), it
+// doesn't use global state (and therefore can't interfere with user
+// code).  Unlike rand_r(), it's portable.  An LCG isn't very random,
+// but it's good enough for our purposes.
+class GTEST_API_ Random {
+ public:
+  static const UInt32 kMaxRange = 1u << 31;
+
+  explicit Random(UInt32 seed) : state_(seed) {}
+
+  void Reseed(UInt32 seed) { state_ = seed; }
+
+  // Generates a random number from [0, range).  Crashes if 'range' is
+  // 0 or greater than kMaxRange.
+  UInt32 Generate(UInt32 range);
+
+ private:
+  UInt32 state_;
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
+};
+
+}  // 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::TestPartResult::kFatalFailure)
+
+#define GTEST_NONFATAL_FAILURE_(message) \
+  GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure)
+
+#define GTEST_SUCCESS_(message) \
+  GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
+
+// Suppresses MSVC warnings 4072 (unreachable code) for the code following
+// statement if it returns or throws (or doesn't return or throw in some
+// situations).
+#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
+  if (::testing::internal::AlwaysTrue()) { statement; }
+
+#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    bool gtest_caught_expected = false; \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (expected_exception const&) { \
+      gtest_caught_expected = true; \
+    } \
+    catch (...) { \
+      gtest_msg = "Expected: " #statement " throws an exception of type " \
+                  #expected_exception ".\n  Actual: it throws a different " \
+                  "type."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
+    } \
+    if (!gtest_caught_expected) { \
+      gtest_msg = "Expected: " #statement " throws an exception of type " \
+                  #expected_exception ".\n  Actual: it throws nothing."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
+      fail(gtest_msg)
+
+#define GTEST_TEST_NO_THROW_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (...) { \
+      gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \
+                  "  Actual: it throws."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \
+      fail(gtest_msg)
+
+#define GTEST_TEST_ANY_THROW_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    bool gtest_caught_any = false; \
+    try { \
+      GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    } \
+    catch (...) { \
+      gtest_caught_any = true; \
+    } \
+    if (!gtest_caught_any) { \
+      gtest_msg = "Expected: " #statement " throws an exception.\n" \
+                  "  Actual: it doesn't."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \
+      fail(gtest_msg)
+
+
+// Implements Boolean test assertions such as EXPECT_TRUE. expression can be
+// either a boolean expression or an AssertionResult. text is a textual
+// represenation of expression as it was passed into the EXPECT_TRUE.
+#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const ::testing::AssertionResult gtest_ar_ = \
+      ::testing::AssertionResult(expression)) \
+    ; \
+  else \
+    fail(::testing::internal::GetBoolAssertionFailureMessage(\
+        gtest_ar_, text, #actual, #expected).c_str())
+
+#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \
+  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+  if (const char* gtest_msg = "") { \
+    ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \
+    GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+    if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \
+      gtest_msg = "Expected: " #statement " doesn't generate new fatal " \
+                  "failures in the current thread.\n" \
+                  "  Actual: it does."; \
+      goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \
+    } \
+  } else \
+    GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \
+      fail(gtest_msg)
+
+// Expands to the name of the class that implements the given test.
+#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
+  test_case_name##_##test_name##_Test
+
+// Helper macro for defining tests.
+#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
+class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
+ public:\
+  GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
+ private:\
+  virtual void TestBody();\
+  static ::testing::TestInfo* const test_info_;\
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(\
+      GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
+};\
+\
+::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
+  ::test_info_ =\
+    ::testing::internal::MakeAndRegisterTestInfo(\
+        #test_case_name, #test_name, "", "", \
+        (parent_id), \
+        parent_class::SetUpTestCase, \
+        parent_class::TearDownTestCase, \
+        new ::testing::internal::TestFactoryImpl<\
+            GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
+void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-linked_ptr.h b/protobuf/gtest/include/gtest/internal/gtest-linked_ptr.h
new file mode 100644
index 0000000..540ef4c
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-linked_ptr.h
@@ -0,0 +1,242 @@
+// Copyright 2003 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: Dan Egnor (egnor@google.com)
+//
+// A "smart" pointer type with reference tracking.  Every pointer to a
+// particular object is kept on a circular linked list.  When the last pointer
+// to an object is destroyed or reassigned, the object is deleted.
+//
+// Used properly, this deletes the object when the last reference goes away.
+// There are several caveats:
+// - Like all reference counting schemes, cycles lead to leaks.
+// - Each smart pointer is actually two pointers (8 bytes instead of 4).
+// - Every time a pointer is assigned, the entire list of pointers to that
+//   object is traversed.  This class is therefore NOT SUITABLE when there
+//   will often be more than two or three pointers to a particular object.
+// - References are only tracked as long as linked_ptr<> objects are copied.
+//   If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
+//   will happen (double deletion).
+//
+// A good use of this class is storing object references in STL containers.
+// You can safely put linked_ptr<> in a vector<>.
+// Other uses may not be as good.
+//
+// Note: If you use an incomplete type with linked_ptr<>, the class
+// *containing* linked_ptr<> must have a constructor and destructor (even
+// if they do nothing!).
+//
+// Bill Gibbons suggested we use something like this.
+//
+// Thread Safety:
+//   Unlike other linked_ptr implementations, in this implementation
+//   a linked_ptr object is thread-safe in the sense that:
+//     - it's safe to copy linked_ptr objects concurrently,
+//     - it's safe to copy *from* a linked_ptr and read its underlying
+//       raw pointer (e.g. via get()) concurrently, and
+//     - it's safe to write to two linked_ptrs that point to the same
+//       shared object concurrently.
+// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
+// confusion with normal linked_ptr.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include <gtest/internal/gtest-port.h>
+
+namespace testing {
+namespace internal {
+
+// Protects copying of all linked_ptr objects.
+GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
+
+// This is used internally by all instances of linked_ptr<>.  It needs to be
+// a non-template class because different types of linked_ptr<> can refer to
+// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
+// So, it needs to be possible for different types of linked_ptr to participate
+// in the same circular linked list, so we need a single class type here.
+//
+// DO NOT USE THIS CLASS DIRECTLY YOURSELF.  Use linked_ptr<T>.
+class linked_ptr_internal {
+ public:
+  // Create a new circle that includes only this instance.
+  void join_new() {
+    next_ = this;
+  }
+
+  // Many linked_ptr operations may change p.link_ for some linked_ptr
+  // variable p in the same circle as this object.  Therefore we need
+  // to prevent two such operations from occurring concurrently.
+  //
+  // Note that different types of linked_ptr objects can coexist in a
+  // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
+  // linked_ptr<Derived2>).  Therefore we must use a single mutex to
+  // protect all linked_ptr objects.  This can create serious
+  // contention in production code, but is acceptable in a testing
+  // framework.
+
+  // Join an existing circle.
+  // L < g_linked_ptr_mutex
+  void join(linked_ptr_internal const* ptr) {
+    MutexLock lock(&g_linked_ptr_mutex);
+
+    linked_ptr_internal const* p = ptr;
+    while (p->next_ != ptr) p = p->next_;
+    p->next_ = this;
+    next_ = ptr;
+  }
+
+  // Leave whatever circle we're part of.  Returns true if we were the
+  // last member of the circle.  Once this is done, you can join() another.
+  // L < g_linked_ptr_mutex
+  bool depart() {
+    MutexLock lock(&g_linked_ptr_mutex);
+
+    if (next_ == this) return true;
+    linked_ptr_internal const* p = next_;
+    while (p->next_ != this) p = p->next_;
+    p->next_ = next_;
+    return false;
+  }
+
+ private:
+  mutable linked_ptr_internal const* next_;
+};
+
+template <typename T>
+class linked_ptr {
+ public:
+  typedef T element_type;
+
+  // Take over ownership of a raw pointer.  This should happen as soon as
+  // possible after the object is created.
+  explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
+  ~linked_ptr() { depart(); }
+
+  // Copy an existing linked_ptr<>, adding ourselves to the list of references.
+  template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
+  linked_ptr(linked_ptr const& ptr) {  // NOLINT
+    assert(&ptr != this);
+    copy(&ptr);
+  }
+
+  // Assignment releases the old value and acquires the new.
+  template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
+    depart();
+    copy(&ptr);
+    return *this;
+  }
+
+  linked_ptr& operator=(linked_ptr const& ptr) {
+    if (&ptr != this) {
+      depart();
+      copy(&ptr);
+    }
+    return *this;
+  }
+
+  // Smart pointer members.
+  void reset(T* ptr = NULL) {
+    depart();
+    capture(ptr);
+  }
+  T* get() const { return value_; }
+  T* operator->() const { return value_; }
+  T& operator*() const { return *value_; }
+  // Release ownership of the pointed object and returns it.
+  // Sole ownership by this linked_ptr object is required.
+  T* release() {
+    bool last = link_.depart();
+    assert(last);
+    T* v = value_;
+    value_ = NULL;
+    return v;
+  }
+
+  bool operator==(T* p) const { return value_ == p; }
+  bool operator!=(T* p) const { return value_ != p; }
+  template <typename U>
+  bool operator==(linked_ptr<U> const& ptr) const {
+    return value_ == ptr.get();
+  }
+  template <typename U>
+  bool operator!=(linked_ptr<U> const& ptr) const {
+    return value_ != ptr.get();
+  }
+
+ private:
+  template <typename U>
+  friend class linked_ptr;
+
+  T* value_;
+  linked_ptr_internal link_;
+
+  void depart() {
+    if (link_.depart()) delete value_;
+  }
+
+  void capture(T* ptr) {
+    value_ = ptr;
+    link_.join_new();
+  }
+
+  template <typename U> void copy(linked_ptr<U> const* ptr) {
+    value_ = ptr->get();
+    if (value_)
+      link_.join(&ptr->link_);
+    else
+      link_.join_new();
+  }
+};
+
+template<typename T> inline
+bool operator==(T* ptr, const linked_ptr<T>& x) {
+  return ptr == x.get();
+}
+
+template<typename T> inline
+bool operator!=(T* ptr, const linked_ptr<T>& x) {
+  return ptr != x.get();
+}
+
+// A function to convert T* into linked_ptr<T>
+// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
+// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
+template <typename T>
+linked_ptr<T> make_linked_ptr(T* ptr) {
+  return linked_ptr<T>(ptr);
+}
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-param-util-generated.h b/protobuf/gtest/include/gtest/internal/gtest-param-util-generated.h
new file mode 100644
index 0000000..ab4ab56
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-param-util-generated.h
@@ -0,0 +1,4820 @@
+// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+
+// 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: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// Currently Google Test supports at most 50 arguments in Values,
+// and at most 10 arguments in Combine. Please contact
+// googletestframework@googlegroups.com if you need more.
+// Please note that the number of arguments to Combine is limited
+// by the maximum arity of the implementation of tr1::tuple which is
+// currently set at 10.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-param-util.h>
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Forward declarations of ValuesIn(), which is implemented in
+// include/gtest/gtest-param-test.h.
+template <typename ForwardIterator>
+internal::ParamGenerator<
+    typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+        ForwardIterator begin, ForwardIterator end);
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+    const Container& container);
+
+namespace internal {
+
+// Used in the Values() function to provide polymorphic capabilities.
+template <typename T1>
+class ValueArray1 {
+ public:
+  explicit ValueArray1(T1 v1) : v1_(v1) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray1& other);
+
+  const T1 v1_;
+};
+
+template <typename T1, typename T2>
+class ValueArray2 {
+ public:
+  ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray2& other);
+
+  const T1 v1_;
+  const T2 v2_;
+};
+
+template <typename T1, typename T2, typename T3>
+class ValueArray3 {
+ public:
+  ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray3& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+class ValueArray4 {
+ public:
+  ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray4& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class ValueArray5 {
+ public:
+  ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray5& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+class ValueArray6 {
+ public:
+  ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray6& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+class ValueArray7 {
+ public:
+  ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray7& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+class ValueArray8 {
+ public:
+  ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
+      T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray8& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+class ValueArray9 {
+ public:
+  ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
+      T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray9& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+class ValueArray10 {
+ public:
+  ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray10& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+class ValueArray11 {
+ public:
+  ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray11& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+class ValueArray12 {
+ public:
+  ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray12& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+class ValueArray13 {
+ public:
+  ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray13& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+class ValueArray14 {
+ public:
+  ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray14& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+class ValueArray15 {
+ public:
+  ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray15& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+class ValueArray16 {
+ public:
+  ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray16& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+class ValueArray17 {
+ public:
+  ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
+      T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray17& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+class ValueArray18 {
+ public:
+  ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray18& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+class ValueArray19 {
+ public:
+  ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray19& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+class ValueArray20 {
+ public:
+  ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray20& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+class ValueArray21 {
+ public:
+  ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray21& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+class ValueArray22 {
+ public:
+  ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray22& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+class ValueArray23 {
+ public:
+  ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_,
+        v23_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray23& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+class ValueArray24 {
+ public:
+  ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray24& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+class ValueArray25 {
+ public:
+  ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
+      T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray25& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+class ValueArray26 {
+ public:
+  ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray26& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+class ValueArray27 {
+ public:
+  ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray27& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+class ValueArray28 {
+ public:
+  ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray28& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+class ValueArray29 {
+ public:
+  ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray29& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+class ValueArray30 {
+ public:
+  ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray30& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+class ValueArray31 {
+ public:
+  ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray31& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+class ValueArray32 {
+ public:
+  ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray32& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+class ValueArray33 {
+ public:
+  ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
+      T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray33& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+class ValueArray34 {
+ public:
+  ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray34& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+class ValueArray35 {
+ public:
+  ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
+      v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_,
+        v35_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray35& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+class ValueArray36 {
+ public:
+  ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
+      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray36& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+class ValueArray37 {
+ public:
+  ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
+      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
+      v36_(v36), v37_(v37) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray37& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+class ValueArray38 {
+ public:
+  ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray38& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+class ValueArray39 {
+ public:
+  ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray39& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+class ValueArray40 {
+ public:
+  ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
+      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
+      v40_(v40) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray40& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+class ValueArray41 {
+ public:
+  ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
+      T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray41& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+class ValueArray42 {
+ public:
+  ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray42& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+class ValueArray43 {
+ public:
+  ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
+      v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
+      v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
+      v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
+      v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
+      v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),
+      v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray43& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+class ValueArray44 {
+ public:
+  ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
+      v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
+      v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
+      v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
+      v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
+      v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),
+      v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),
+      v43_(v43), v44_(v44) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray44& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+class ValueArray45 {
+ public:
+  ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
+      v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
+      v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
+      v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
+      v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
+      v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
+      v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),
+      v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray45& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+class ValueArray46 {
+ public:
+  ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),
+      v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
+      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray46& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+class ValueArray47 {
+ public:
+  ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),
+      v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
+      v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
+      v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
+      v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
+      v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
+      v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
+      v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),
+      v47_(v47) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_,
+        v47_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray47& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+class ValueArray48 {
+ public:
+  ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),
+      v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
+      v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
+      v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
+      v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
+      v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
+      v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
+      v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),
+      v46_(v46), v47_(v47), v48_(v48) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray48& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+class ValueArray49 {
+ public:
+  ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,
+      T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
+      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_, v49_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray49& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+  const T49 v49_;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+class ValueArray50 {
+ public:
+  ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
+      T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
+      T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
+      T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
+      T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
+      T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,
+      T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
+      v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
+      v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
+      v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
+      v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
+      v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
+      v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
+      v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_,
+        v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_,
+        v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_,
+        v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_,
+        v48_, v49_, v50_};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray50& other);
+
+  const T1 v1_;
+  const T2 v2_;
+  const T3 v3_;
+  const T4 v4_;
+  const T5 v5_;
+  const T6 v6_;
+  const T7 v7_;
+  const T8 v8_;
+  const T9 v9_;
+  const T10 v10_;
+  const T11 v11_;
+  const T12 v12_;
+  const T13 v13_;
+  const T14 v14_;
+  const T15 v15_;
+  const T16 v16_;
+  const T17 v17_;
+  const T18 v18_;
+  const T19 v19_;
+  const T20 v20_;
+  const T21 v21_;
+  const T22 v22_;
+  const T23 v23_;
+  const T24 v24_;
+  const T25 v25_;
+  const T26 v26_;
+  const T27 v27_;
+  const T28 v28_;
+  const T29 v29_;
+  const T30 v30_;
+  const T31 v31_;
+  const T32 v32_;
+  const T33 v33_;
+  const T34 v34_;
+  const T35 v35_;
+  const T36 v36_;
+  const T37 v37_;
+  const T38 v38_;
+  const T39 v39_;
+  const T40 v40_;
+  const T41 v41_;
+  const T42 v42_;
+  const T43 v43_;
+  const T44 v44_;
+  const T45 v45_;
+  const T46 v46_;
+  const T47 v47_;
+  const T48 v48_;
+  const T49 v49_;
+  const T50 v50_;
+};
+
+#if GTEST_HAS_COMBINE
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Generates values from the Cartesian product of values produced
+// by the argument generators.
+//
+template <typename T1, typename T2>
+class CartesianProductGenerator2
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2> ParamType;
+
+  CartesianProductGenerator2(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2)
+      : g1_(g1), g2_(g2) {}
+  virtual ~CartesianProductGenerator2() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current2_;
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator2::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator2& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+};  // class CartesianProductGenerator2
+
+
+template <typename T1, typename T2, typename T3>
+class CartesianProductGenerator3
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3> ParamType;
+
+  CartesianProductGenerator3(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
+      : g1_(g1), g2_(g2), g3_(g3) {}
+  virtual ~CartesianProductGenerator3() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current3_;
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator3::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator3& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+};  // class CartesianProductGenerator3
+
+
+template <typename T1, typename T2, typename T3, typename T4>
+class CartesianProductGenerator4
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType;
+
+  CartesianProductGenerator4(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
+  virtual ~CartesianProductGenerator4() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current4_;
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator4::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator4& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+};  // class CartesianProductGenerator4
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+class CartesianProductGenerator5
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType;
+
+  CartesianProductGenerator5(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
+  virtual ~CartesianProductGenerator5() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current5_;
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator5::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator5& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+};  // class CartesianProductGenerator5
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+class CartesianProductGenerator6
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5,
+        T6> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType;
+
+  CartesianProductGenerator6(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
+  virtual ~CartesianProductGenerator6() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current6_;
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator6::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator6& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+};  // class CartesianProductGenerator6
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+class CartesianProductGenerator7
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
+
+  CartesianProductGenerator7(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
+  virtual ~CartesianProductGenerator7() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current7_;
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator7::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator7& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+};  // class CartesianProductGenerator7
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+class CartesianProductGenerator8
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
+
+  CartesianProductGenerator8(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
+          g8_(g8) {}
+  virtual ~CartesianProductGenerator8() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current8_;
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator8::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator8& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+};  // class CartesianProductGenerator8
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+class CartesianProductGenerator9
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8, T9> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
+
+  CartesianProductGenerator9(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9) {}
+  virtual ~CartesianProductGenerator9() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end(), g9_, g9_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8,
+      const ParamGenerator<T9>& g9,
+      const typename ParamGenerator<T9>::iterator& current9)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
+          begin9_(g9.begin()), end9_(g9.end()), current9_(current9)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current9_;
+      if (current9_ == end9_) {
+        current9_ = begin9_;
+        ++current8_;
+      }
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_ &&
+          current9_ == typed_other->current9_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_),
+        begin9_(other.begin9_),
+        end9_(other.end9_),
+        current9_(other.current9_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_,
+            *current9_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_ ||
+          current9_ == end9_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    const typename ParamGenerator<T9>::iterator begin9_;
+    const typename ParamGenerator<T9>::iterator end9_;
+    typename ParamGenerator<T9>::iterator current9_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator9::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator9& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+  const ParamGenerator<T9> g9_;
+};  // class CartesianProductGenerator9
+
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+class CartesianProductGenerator10
+    : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+        T7, T8, T9, T10> > {
+ public:
+  typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
+
+  CartesianProductGenerator10(const ParamGenerator<T1>& g1,
+      const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
+      const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
+      const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
+      const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,
+      const ParamGenerator<T10>& g10)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9), g10_(g10) {}
+  virtual ~CartesianProductGenerator10() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
+        g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
+        g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
+        g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
+        g8_.end(), g9_, g9_.end(), g10_, g10_.end());
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base,
+      const ParamGenerator<T1>& g1,
+      const typename ParamGenerator<T1>::iterator& current1,
+      const ParamGenerator<T2>& g2,
+      const typename ParamGenerator<T2>::iterator& current2,
+      const ParamGenerator<T3>& g3,
+      const typename ParamGenerator<T3>::iterator& current3,
+      const ParamGenerator<T4>& g4,
+      const typename ParamGenerator<T4>::iterator& current4,
+      const ParamGenerator<T5>& g5,
+      const typename ParamGenerator<T5>::iterator& current5,
+      const ParamGenerator<T6>& g6,
+      const typename ParamGenerator<T6>::iterator& current6,
+      const ParamGenerator<T7>& g7,
+      const typename ParamGenerator<T7>::iterator& current7,
+      const ParamGenerator<T8>& g8,
+      const typename ParamGenerator<T8>::iterator& current8,
+      const ParamGenerator<T9>& g9,
+      const typename ParamGenerator<T9>::iterator& current9,
+      const ParamGenerator<T10>& g10,
+      const typename ParamGenerator<T10>::iterator& current10)
+        : base_(base),
+          begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
+          begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
+          begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
+          begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
+          begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
+          begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
+          begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
+          begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
+          begin9_(g9.begin()), end9_(g9.end()), current9_(current9),
+          begin10_(g10.begin()), end10_(g10.end()), current10_(current10)    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current10_;
+      if (current10_ == end10_) {
+        current10_ = begin10_;
+        ++current9_;
+      }
+      if (current9_ == end9_) {
+        current9_ = begin9_;
+        ++current8_;
+      }
+      if (current8_ == end8_) {
+        current8_ = begin8_;
+        ++current7_;
+      }
+      if (current7_ == end7_) {
+        current7_ = begin7_;
+        ++current6_;
+      }
+      if (current6_ == end6_) {
+        current6_ = begin6_;
+        ++current5_;
+      }
+      if (current5_ == end5_) {
+        current5_ = begin5_;
+        ++current4_;
+      }
+      if (current4_ == end4_) {
+        current4_ = begin4_;
+        ++current3_;
+      }
+      if (current3_ == end3_) {
+        current3_ = begin3_;
+        ++current2_;
+      }
+      if (current2_ == end2_) {
+        current2_ = begin2_;
+        ++current1_;
+      }
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         (
+          current1_ == typed_other->current1_ &&
+          current2_ == typed_other->current2_ &&
+          current3_ == typed_other->current3_ &&
+          current4_ == typed_other->current4_ &&
+          current5_ == typed_other->current5_ &&
+          current6_ == typed_other->current6_ &&
+          current7_ == typed_other->current7_ &&
+          current8_ == typed_other->current8_ &&
+          current9_ == typed_other->current9_ &&
+          current10_ == typed_other->current10_);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_),
+        begin1_(other.begin1_),
+        end1_(other.end1_),
+        current1_(other.current1_),
+        begin2_(other.begin2_),
+        end2_(other.end2_),
+        current2_(other.current2_),
+        begin3_(other.begin3_),
+        end3_(other.end3_),
+        current3_(other.current3_),
+        begin4_(other.begin4_),
+        end4_(other.end4_),
+        current4_(other.current4_),
+        begin5_(other.begin5_),
+        end5_(other.end5_),
+        current5_(other.current5_),
+        begin6_(other.begin6_),
+        end6_(other.end6_),
+        current6_(other.current6_),
+        begin7_(other.begin7_),
+        end7_(other.end7_),
+        current7_(other.current7_),
+        begin8_(other.begin8_),
+        end8_(other.end8_),
+        current8_(other.current8_),
+        begin9_(other.begin9_),
+        end9_(other.end9_),
+        current9_(other.current9_),
+        begin10_(other.begin10_),
+        end10_(other.end10_),
+        current10_(other.current10_) {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType(*current1_, *current2_, *current3_,
+            *current4_, *current5_, *current6_, *current7_, *current8_,
+            *current9_, *current10_);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+          current1_ == end1_ ||
+          current2_ == end2_ ||
+          current3_ == end3_ ||
+          current4_ == end4_ ||
+          current5_ == end5_ ||
+          current6_ == end6_ ||
+          current7_ == end7_ ||
+          current8_ == end8_ ||
+          current9_ == end9_ ||
+          current10_ == end10_;
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+    const typename ParamGenerator<T1>::iterator begin1_;
+    const typename ParamGenerator<T1>::iterator end1_;
+    typename ParamGenerator<T1>::iterator current1_;
+    const typename ParamGenerator<T2>::iterator begin2_;
+    const typename ParamGenerator<T2>::iterator end2_;
+    typename ParamGenerator<T2>::iterator current2_;
+    const typename ParamGenerator<T3>::iterator begin3_;
+    const typename ParamGenerator<T3>::iterator end3_;
+    typename ParamGenerator<T3>::iterator current3_;
+    const typename ParamGenerator<T4>::iterator begin4_;
+    const typename ParamGenerator<T4>::iterator end4_;
+    typename ParamGenerator<T4>::iterator current4_;
+    const typename ParamGenerator<T5>::iterator begin5_;
+    const typename ParamGenerator<T5>::iterator end5_;
+    typename ParamGenerator<T5>::iterator current5_;
+    const typename ParamGenerator<T6>::iterator begin6_;
+    const typename ParamGenerator<T6>::iterator end6_;
+    typename ParamGenerator<T6>::iterator current6_;
+    const typename ParamGenerator<T7>::iterator begin7_;
+    const typename ParamGenerator<T7>::iterator end7_;
+    typename ParamGenerator<T7>::iterator current7_;
+    const typename ParamGenerator<T8>::iterator begin8_;
+    const typename ParamGenerator<T8>::iterator end8_;
+    typename ParamGenerator<T8>::iterator current8_;
+    const typename ParamGenerator<T9>::iterator begin9_;
+    const typename ParamGenerator<T9>::iterator end9_;
+    typename ParamGenerator<T9>::iterator current9_;
+    const typename ParamGenerator<T10>::iterator begin10_;
+    const typename ParamGenerator<T10>::iterator end10_;
+    typename ParamGenerator<T10>::iterator current10_;
+    ParamType current_value_;
+  };  // class CartesianProductGenerator10::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator10& other);
+
+  const ParamGenerator<T1> g1_;
+  const ParamGenerator<T2> g2_;
+  const ParamGenerator<T3> g3_;
+  const ParamGenerator<T4> g4_;
+  const ParamGenerator<T5> g5_;
+  const ParamGenerator<T6> g6_;
+  const ParamGenerator<T7> g7_;
+  const ParamGenerator<T8> g8_;
+  const ParamGenerator<T9> g9_;
+  const ParamGenerator<T10> g10_;
+};  // class CartesianProductGenerator10
+
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Helper classes providing Combine() with polymorphic features. They allow
+// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
+// convertible to U.
+//
+template <class Generator1, class Generator2>
+class CartesianProductHolder2 {
+ public:
+CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
+      : g1_(g1), g2_(g2) {}
+  template <typename T1, typename T2>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2> >(
+        new CartesianProductGenerator2<T1, T2>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder2& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+};  // class CartesianProductHolder2
+
+template <class Generator1, class Generator2, class Generator3>
+class CartesianProductHolder3 {
+ public:
+CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3)
+      : g1_(g1), g2_(g2), g3_(g3) {}
+  template <typename T1, typename T2, typename T3>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >(
+        new CartesianProductGenerator3<T1, T2, T3>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder3& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+};  // class CartesianProductHolder3
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4>
+class CartesianProductHolder4 {
+ public:
+CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
+  template <typename T1, typename T2, typename T3, typename T4>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >(
+        new CartesianProductGenerator4<T1, T2, T3, T4>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder4& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+};  // class CartesianProductHolder4
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5>
+class CartesianProductHolder5 {
+ public:
+CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >(
+        new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder5& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+};  // class CartesianProductHolder5
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6>
+class CartesianProductHolder6 {
+ public:
+CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >(
+        new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder6& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+};  // class CartesianProductHolder6
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7>
+class CartesianProductHolder7 {
+ public:
+CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6,
+      T7> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >(
+        new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder7& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+};  // class CartesianProductHolder7
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8>
+class CartesianProductHolder8 {
+ public:
+CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
+          g8_(g8) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7,
+      T8> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
+        new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder8& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+};  // class CartesianProductHolder8
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8, class Generator9>
+class CartesianProductHolder9 {
+ public:
+CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8,
+    const Generator9& g9)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8, typename T9>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+      T9> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+        T9> >(
+        new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_),
+        static_cast<ParamGenerator<T9> >(g9_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder9& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+  const Generator9 g9_;
+};  // class CartesianProductHolder9
+
+template <class Generator1, class Generator2, class Generator3,
+    class Generator4, class Generator5, class Generator6, class Generator7,
+    class Generator8, class Generator9, class Generator10>
+class CartesianProductHolder10 {
+ public:
+CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
+    const Generator3& g3, const Generator4& g4, const Generator5& g5,
+    const Generator6& g6, const Generator7& g7, const Generator8& g8,
+    const Generator9& g9, const Generator10& g10)
+      : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
+          g9_(g9), g10_(g10) {}
+  template <typename T1, typename T2, typename T3, typename T4, typename T5,
+      typename T6, typename T7, typename T8, typename T9, typename T10>
+  operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+      T9, T10> >() const {
+    return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
+        T9, T10> >(
+        new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
+            T10>(
+        static_cast<ParamGenerator<T1> >(g1_),
+        static_cast<ParamGenerator<T2> >(g2_),
+        static_cast<ParamGenerator<T3> >(g3_),
+        static_cast<ParamGenerator<T4> >(g4_),
+        static_cast<ParamGenerator<T5> >(g5_),
+        static_cast<ParamGenerator<T6> >(g6_),
+        static_cast<ParamGenerator<T7> >(g7_),
+        static_cast<ParamGenerator<T8> >(g8_),
+        static_cast<ParamGenerator<T9> >(g9_),
+        static_cast<ParamGenerator<T10> >(g10_)));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder10& other);
+
+  const Generator1 g1_;
+  const Generator2 g2_;
+  const Generator3 g3_;
+  const Generator4 g4_;
+  const Generator5 g5_;
+  const Generator6 g6_;
+  const Generator7 g7_;
+  const Generator8 g8_;
+  const Generator9 g9_;
+  const Generator10 g10_;
+};  // class CartesianProductHolder10
+
+#endif  // GTEST_HAS_COMBINE
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  //  GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-param-util-generated.h.pump b/protobuf/gtest/include/gtest/internal/gtest-param-util-generated.h.pump
new file mode 100644
index 0000000..baedfbc
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-param-util-generated.h.pump
@@ -0,0 +1,301 @@
+$$ -*- mode: c++; -*-
+$var n = 50  $$ Maximum length of Values arguments we want to support.
+$var maxtuple = 10  $$ Maximum number of Combine arguments we want to support.
+// 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: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+// This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// Currently Google Test supports at most $n arguments in Values,
+// and at most $maxtuple arguments in Combine. Please contact
+// googletestframework@googlegroups.com if you need more.
+// Please note that the number of arguments to Combine is limited
+// by the maximum arity of the implementation of tr1::tuple which is
+// currently set at $maxtuple.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-param-util.h>
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+
+// Forward declarations of ValuesIn(), which is implemented in
+// include/gtest/gtest-param-test.h.
+template <typename ForwardIterator>
+internal::ParamGenerator<
+    typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
+        ForwardIterator begin, ForwardIterator end);
+
+template <typename T, size_t N>
+internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
+
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+    const Container& container);
+
+namespace internal {
+
+// Used in the Values() function to provide polymorphic capabilities.
+template <typename T1>
+class ValueArray1 {
+ public:
+  explicit ValueArray1(T1 v1) : v1_(v1) {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray1& other);
+
+  const T1 v1_;
+};
+
+$range i 2..n
+$for i [[
+$range j 1..i
+
+template <$for j, [[typename T$j]]>
+class ValueArray$i {
+ public:
+  ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
+
+  template <typename T>
+  operator ParamGenerator<T>() const {
+    const T array[] = {$for j, [[v$(j)_]]};
+    return ValuesIn(array);
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const ValueArray$i& other);
+
+$for j [[
+
+  const T$j v$(j)_;
+]]
+
+};
+
+]]
+
+#if GTEST_HAS_COMBINE
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Generates values from the Cartesian product of values produced
+// by the argument generators.
+//
+$range i 2..maxtuple
+$for i [[
+$range j 1..i
+$range k 2..i
+
+template <$for j, [[typename T$j]]>
+class CartesianProductGenerator$i
+    : public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > {
+ public:
+  typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType;
+
+  CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
+      : $for j, [[g$(j)_(g$j)]] {}
+  virtual ~CartesianProductGenerator$i() {}
+
+  virtual ParamIteratorInterface<ParamType>* Begin() const {
+    return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]);
+  }
+  virtual ParamIteratorInterface<ParamType>* End() const {
+    return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]);
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<ParamType> {
+   public:
+    Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[
+
+      const ParamGenerator<T$j>& g$j,
+      const typename ParamGenerator<T$j>::iterator& current$(j)]])
+        : base_(base),
+$for j, [[
+
+          begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j)
+]]    {
+      ComputeCurrentValue();
+    }
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
+      return base_;
+    }
+    // Advance should not be called on beyond-of-range iterators
+    // so no component iterators must be beyond end of range, either.
+    virtual void Advance() {
+      assert(!AtEnd());
+      ++current$(i)_;
+
+$for k [[
+      if (current$(i+2-k)_ == end$(i+2-k)_) {
+        current$(i+2-k)_ = begin$(i+2-k)_;
+        ++current$(i+2-k-1)_;
+      }
+
+]]
+      ComputeCurrentValue();
+    }
+    virtual ParamIteratorInterface<ParamType>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const ParamType* Current() const { return &current_value_; }
+    virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const Iterator* typed_other =
+          CheckedDowncastToActualType<const Iterator>(&other);
+      // We must report iterators equal if they both point beyond their
+      // respective ranges. That can happen in a variety of fashions,
+      // so we have to consult AtEnd().
+      return (AtEnd() && typed_other->AtEnd()) ||
+         ($for j  && [[
+
+          current$(j)_ == typed_other->current$(j)_
+]]);
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : base_(other.base_), $for j, [[
+
+        begin$(j)_(other.begin$(j)_),
+        end$(j)_(other.end$(j)_),
+        current$(j)_(other.current$(j)_)
+]] {
+      ComputeCurrentValue();
+    }
+
+    void ComputeCurrentValue() {
+      if (!AtEnd())
+        current_value_ = ParamType($for j, [[*current$(j)_]]);
+    }
+    bool AtEnd() const {
+      // We must report iterator past the end of the range when either of the
+      // component iterators has reached the end of its range.
+      return
+$for j  || [[
+
+          current$(j)_ == end$(j)_
+]];
+    }
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<ParamType>* const base_;
+    // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
+    // current[i]_ is the actual traversing iterator.
+$for j [[
+
+    const typename ParamGenerator<T$j>::iterator begin$(j)_;
+    const typename ParamGenerator<T$j>::iterator end$(j)_;
+    typename ParamGenerator<T$j>::iterator current$(j)_;
+]]
+
+    ParamType current_value_;
+  };  // class CartesianProductGenerator$i::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductGenerator$i& other);
+
+
+$for j [[
+  const ParamGenerator<T$j> g$(j)_;
+
+]]
+};  // class CartesianProductGenerator$i
+
+
+]]
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Helper classes providing Combine() with polymorphic features. They allow
+// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
+// convertible to U.
+//
+$range i 2..maxtuple
+$for i [[
+$range j 1..i
+
+template <$for j, [[class Generator$j]]>
+class CartesianProductHolder$i {
+ public:
+CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
+      : $for j, [[g$(j)_(g$j)]] {}
+  template <$for j, [[typename T$j]]>
+  operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const {
+    return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >(
+        new CartesianProductGenerator$i<$for j, [[T$j]]>(
+$for j,[[
+
+        static_cast<ParamGenerator<T$j> >(g$(j)_)
+]]));
+  }
+
+ private:
+  // No implementation - assignment is unsupported.
+  void operator=(const CartesianProductHolder$i& other);
+
+
+$for j [[
+  const Generator$j g$(j)_;
+
+]]
+};  // class CartesianProductHolder$i
+
+]]
+
+#endif  // GTEST_HAS_COMBINE
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  //  GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-param-util.h b/protobuf/gtest/include/gtest/internal/gtest-param-util.h
new file mode 100644
index 0000000..0cbb58c
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-param-util.h
@@ -0,0 +1,619 @@
+// 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: vladl@google.com (Vlad Losev)
+
+// Type and function utilities for implementing parameterized tests.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
+
+#include <iterator>
+#include <utility>
+#include <vector>
+
+// scripts/fuse_gtest.py depends on gtest's own header being #included
+// *unconditionally*.  Therefore these #includes cannot be moved
+// inside #if GTEST_HAS_PARAM_TEST.
+#include <gtest/internal/gtest-internal.h>
+#include <gtest/internal/gtest-linked_ptr.h>
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+namespace testing {
+namespace internal {
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Outputs a message explaining invalid registration of different
+// fixture class for the same test case. This may happen when
+// TEST_P macro is used to define two tests with the same name
+// but in different namespaces.
+GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
+                                          const char* file, int line);
+
+template <typename> class ParamGeneratorInterface;
+template <typename> class ParamGenerator;
+
+// Interface for iterating over elements provided by an implementation
+// of ParamGeneratorInterface<T>.
+template <typename T>
+class ParamIteratorInterface {
+ public:
+  virtual ~ParamIteratorInterface() {}
+  // A pointer to the base generator instance.
+  // Used only for the purposes of iterator comparison
+  // to make sure that two iterators belong to the same generator.
+  virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
+  // Advances iterator to point to the next element
+  // provided by the generator. The caller is responsible
+  // for not calling Advance() on an iterator equal to
+  // BaseGenerator()->End().
+  virtual void Advance() = 0;
+  // Clones the iterator object. Used for implementing copy semantics
+  // of ParamIterator<T>.
+  virtual ParamIteratorInterface* Clone() const = 0;
+  // Dereferences the current iterator and provides (read-only) access
+  // to the pointed value. It is the caller's responsibility not to call
+  // Current() on an iterator equal to BaseGenerator()->End().
+  // Used for implementing ParamGenerator<T>::operator*().
+  virtual const T* Current() const = 0;
+  // Determines whether the given iterator and other point to the same
+  // element in the sequence generated by the generator.
+  // Used for implementing ParamGenerator<T>::operator==().
+  virtual bool Equals(const ParamIteratorInterface& other) const = 0;
+};
+
+// Class iterating over elements provided by an implementation of
+// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
+// and implements the const forward iterator concept.
+template <typename T>
+class ParamIterator {
+ public:
+  typedef T value_type;
+  typedef const T& reference;
+  typedef ptrdiff_t difference_type;
+
+  // ParamIterator assumes ownership of the impl_ pointer.
+  ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
+  ParamIterator& operator=(const ParamIterator& other) {
+    if (this != &other)
+      impl_.reset(other.impl_->Clone());
+    return *this;
+  }
+
+  const T& operator*() const { return *impl_->Current(); }
+  const T* operator->() const { return impl_->Current(); }
+  // Prefix version of operator++.
+  ParamIterator& operator++() {
+    impl_->Advance();
+    return *this;
+  }
+  // Postfix version of operator++.
+  ParamIterator operator++(int /*unused*/) {
+    ParamIteratorInterface<T>* clone = impl_->Clone();
+    impl_->Advance();
+    return ParamIterator(clone);
+  }
+  bool operator==(const ParamIterator& other) const {
+    return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
+  }
+  bool operator!=(const ParamIterator& other) const {
+    return !(*this == other);
+  }
+
+ private:
+  friend class ParamGenerator<T>;
+  explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
+  scoped_ptr<ParamIteratorInterface<T> > impl_;
+};
+
+// ParamGeneratorInterface<T> is the binary interface to access generators
+// defined in other translation units.
+template <typename T>
+class ParamGeneratorInterface {
+ public:
+  typedef T ParamType;
+
+  virtual ~ParamGeneratorInterface() {}
+
+  // Generator interface definition
+  virtual ParamIteratorInterface<T>* Begin() const = 0;
+  virtual ParamIteratorInterface<T>* End() const = 0;
+};
+
+// Wraps ParamGeneratorInterface<T> and provides general generator syntax
+// compatible with the STL Container concept.
+// This class implements copy initialization semantics and the contained
+// ParamGeneratorInterface<T> instance is shared among all copies
+// of the original object. This is possible because that instance is immutable.
+template<typename T>
+class ParamGenerator {
+ public:
+  typedef ParamIterator<T> iterator;
+
+  explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
+  ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
+
+  ParamGenerator& operator=(const ParamGenerator& other) {
+    impl_ = other.impl_;
+    return *this;
+  }
+
+  iterator begin() const { return iterator(impl_->Begin()); }
+  iterator end() const { return iterator(impl_->End()); }
+
+ private:
+  ::testing::internal::linked_ptr<const ParamGeneratorInterface<T> > impl_;
+};
+
+// Generates values from a range of two comparable values. Can be used to
+// generate sequences of user-defined types that implement operator+() and
+// operator<().
+// This class is used in the Range() function.
+template <typename T, typename IncrementT>
+class RangeGenerator : public ParamGeneratorInterface<T> {
+ public:
+  RangeGenerator(T begin, T end, IncrementT step)
+      : begin_(begin), end_(end),
+        step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
+  virtual ~RangeGenerator() {}
+
+  virtual ParamIteratorInterface<T>* Begin() const {
+    return new Iterator(this, begin_, 0, step_);
+  }
+  virtual ParamIteratorInterface<T>* End() const {
+    return new Iterator(this, end_, end_index_, step_);
+  }
+
+ private:
+  class Iterator : public ParamIteratorInterface<T> {
+   public:
+    Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
+             IncrementT step)
+        : base_(base), value_(value), index_(index), step_(step) {}
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+      return base_;
+    }
+    virtual void Advance() {
+      value_ = value_ + step_;
+      index_++;
+    }
+    virtual ParamIteratorInterface<T>* Clone() const {
+      return new Iterator(*this);
+    }
+    virtual const T* Current() const { return &value_; }
+    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      const int other_index =
+          CheckedDowncastToActualType<const Iterator>(&other)->index_;
+      return index_ == other_index;
+    }
+
+   private:
+    Iterator(const Iterator& other)
+        : ParamIteratorInterface<T>(),
+          base_(other.base_), value_(other.value_), index_(other.index_),
+          step_(other.step_) {}
+
+    // No implementation - assignment is unsupported.
+    void operator=(const Iterator& other);
+
+    const ParamGeneratorInterface<T>* const base_;
+    T value_;
+    int index_;
+    const IncrementT step_;
+  };  // class RangeGenerator::Iterator
+
+  static int CalculateEndIndex(const T& begin,
+                               const T& end,
+                               const IncrementT& step) {
+    int end_index = 0;
+    for (T i = begin; i < end; i = i + step)
+      end_index++;
+    return end_index;
+  }
+
+  // No implementation - assignment is unsupported.
+  void operator=(const RangeGenerator& other);
+
+  const T begin_;
+  const T end_;
+  const IncrementT step_;
+  // The index for the end() iterator. All the elements in the generated
+  // sequence are indexed (0-based) to aid iterator comparison.
+  const int end_index_;
+};  // class RangeGenerator
+
+
+// Generates values from a pair of STL-style iterators. Used in the
+// ValuesIn() function. The elements are copied from the source range
+// since the source can be located on the stack, and the generator
+// is likely to persist beyond that stack frame.
+template <typename T>
+class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
+ public:
+  template <typename ForwardIterator>
+  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
+      : container_(begin, end) {}
+  virtual ~ValuesInIteratorRangeGenerator() {}
+
+  virtual ParamIteratorInterface<T>* Begin() const {
+    return new Iterator(this, container_.begin());
+  }
+  virtual ParamIteratorInterface<T>* End() const {
+    return new Iterator(this, container_.end());
+  }
+
+ private:
+  typedef typename ::std::vector<T> ContainerType;
+
+  class Iterator : public ParamIteratorInterface<T> {
+   public:
+    Iterator(const ParamGeneratorInterface<T>* base,
+             typename ContainerType::const_iterator iterator)
+        :  base_(base), iterator_(iterator) {}
+    virtual ~Iterator() {}
+
+    virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+      return base_;
+    }
+    virtual void Advance() {
+      ++iterator_;
+      value_.reset();
+    }
+    virtual ParamIteratorInterface<T>* Clone() const {
+      return new Iterator(*this);
+    }
+    // We need to use cached value referenced by iterator_ because *iterator_
+    // can return a temporary object (and of type other then T), so just
+    // having "return &*iterator_;" doesn't work.
+    // value_ is updated here and not in Advance() because Advance()
+    // can advance iterator_ beyond the end of the range, and we cannot
+    // detect that fact. The client code, on the other hand, is
+    // responsible for not calling Current() on an out-of-range iterator.
+    virtual const T* Current() const {
+      if (value_.get() == NULL)
+        value_.reset(new T(*iterator_));
+      return value_.get();
+    }
+    virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+      // Having the same base generator guarantees that the other
+      // iterator is of the same type and we can downcast.
+      GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+          << "The program attempted to compare iterators "
+          << "from different generators." << std::endl;
+      return iterator_ ==
+          CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
+    }
+
+   private:
+    Iterator(const Iterator& other)
+          // The explicit constructor call suppresses a false warning
+          // emitted by gcc when supplied with the -Wextra option.
+        : ParamIteratorInterface<T>(),
+          base_(other.base_),
+          iterator_(other.iterator_) {}
+
+    const ParamGeneratorInterface<T>* const base_;
+    typename ContainerType::const_iterator iterator_;
+    // A cached value of *iterator_. We keep it here to allow access by
+    // pointer in the wrapping iterator's operator->().
+    // value_ needs to be mutable to be accessed in Current().
+    // Use of scoped_ptr helps manage cached value's lifetime,
+    // which is bound by the lifespan of the iterator itself.
+    mutable scoped_ptr<const T> value_;
+  };  // class ValuesInIteratorRangeGenerator::Iterator
+
+  // No implementation - assignment is unsupported.
+  void operator=(const ValuesInIteratorRangeGenerator& other);
+
+  const ContainerType container_;
+};  // class ValuesInIteratorRangeGenerator
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Stores a parameter value and later creates tests parameterized with that
+// value.
+template <class TestClass>
+class ParameterizedTestFactory : public TestFactoryBase {
+ public:
+  typedef typename TestClass::ParamType ParamType;
+  explicit ParameterizedTestFactory(ParamType parameter) :
+      parameter_(parameter) {}
+  virtual Test* CreateTest() {
+    TestClass::SetParam(&parameter_);
+    return new TestClass();
+  }
+
+ private:
+  const ParamType parameter_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// TestMetaFactoryBase is a base class for meta-factories that create
+// test factories for passing into MakeAndRegisterTestInfo function.
+template <class ParamType>
+class TestMetaFactoryBase {
+ public:
+  virtual ~TestMetaFactoryBase() {}
+
+  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// TestMetaFactory creates test factories for passing into
+// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
+// ownership of test factory pointer, same factory object cannot be passed
+// into that method twice. But ParameterizedTestCaseInfo is going to call
+// it for each Test/Parameter value combination. Thus it needs meta factory
+// creator class.
+template <class TestCase>
+class TestMetaFactory
+    : public TestMetaFactoryBase<typename TestCase::ParamType> {
+ public:
+  typedef typename TestCase::ParamType ParamType;
+
+  TestMetaFactory() {}
+
+  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
+    return new ParameterizedTestFactory<TestCase>(parameter);
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseInfoBase is a generic interface
+// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
+// accumulates test information provided by TEST_P macro invocations
+// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
+// and uses that information to register all resulting test instances
+// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
+// a collection of pointers to the ParameterizedTestCaseInfo objects
+// and calls RegisterTests() on each of them when asked.
+class ParameterizedTestCaseInfoBase {
+ public:
+  virtual ~ParameterizedTestCaseInfoBase() {}
+
+  // Base part of test case name for display purposes.
+  virtual const String& GetTestCaseName() const = 0;
+  // Test case id to verify identity.
+  virtual TypeId GetTestCaseTypeId() const = 0;
+  // UnitTest class invokes this method to register tests in this
+  // test case right before running them in RUN_ALL_TESTS macro.
+  // This method should not be called more then once on any single
+  // instance of a ParameterizedTestCaseInfoBase derived class.
+  virtual void RegisterTests() = 0;
+
+ protected:
+  ParameterizedTestCaseInfoBase() {}
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
+};
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
+// macro invocations for a particular test case and generators
+// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
+// test case. It registers tests with all values generated by all
+// generators when asked.
+template <class TestCase>
+class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
+ public:
+  // ParamType and GeneratorCreationFunc are private types but are required
+  // for declarations of public methods AddTestPattern() and
+  // AddTestCaseInstantiation().
+  typedef typename TestCase::ParamType ParamType;
+  // A function that returns an instance of appropriate generator type.
+  typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
+
+  explicit ParameterizedTestCaseInfo(const char* name)
+      : test_case_name_(name) {}
+
+  // Test case base name for display purposes.
+  virtual const String& GetTestCaseName() const { return test_case_name_; }
+  // Test case id to verify identity.
+  virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
+  // TEST_P macro uses AddTestPattern() to record information
+  // about a single test in a LocalTestInfo structure.
+  // test_case_name is the base name of the test case (without invocation
+  // prefix). test_base_name is the name of an individual test without
+  // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
+  // test case base name and DoBar is test base name.
+  void AddTestPattern(const char* test_case_name,
+                      const char* test_base_name,
+                      TestMetaFactoryBase<ParamType>* meta_factory) {
+    tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
+                                                       test_base_name,
+                                                       meta_factory)));
+  }
+  // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
+  // about a generator.
+  int AddTestCaseInstantiation(const char* instantiation_name,
+                               GeneratorCreationFunc* func,
+                               const char* /* file */,
+                               int /* line */) {
+    instantiations_.push_back(::std::make_pair(instantiation_name, func));
+    return 0;  // Return value used only to run this method in namespace scope.
+  }
+  // UnitTest class invokes this method to register tests in this test case
+  // test cases right before running tests in RUN_ALL_TESTS macro.
+  // This method should not be called more then once on any single
+  // instance of a ParameterizedTestCaseInfoBase derived class.
+  // UnitTest has a guard to prevent from calling this method more then once.
+  virtual void RegisterTests() {
+    for (typename TestInfoContainer::iterator test_it = tests_.begin();
+         test_it != tests_.end(); ++test_it) {
+      linked_ptr<TestInfo> test_info = *test_it;
+      for (typename InstantiationContainer::iterator gen_it =
+               instantiations_.begin(); gen_it != instantiations_.end();
+               ++gen_it) {
+        const String& instantiation_name = gen_it->first;
+        ParamGenerator<ParamType> generator((*gen_it->second)());
+
+        Message test_case_name_stream;
+        if ( !instantiation_name.empty() )
+          test_case_name_stream << instantiation_name.c_str() << "/";
+        test_case_name_stream << test_info->test_case_base_name.c_str();
+
+        int i = 0;
+        for (typename ParamGenerator<ParamType>::iterator param_it =
+                 generator.begin();
+             param_it != generator.end(); ++param_it, ++i) {
+          Message test_name_stream;
+          test_name_stream << test_info->test_base_name.c_str() << "/" << i;
+          ::testing::internal::MakeAndRegisterTestInfo(
+              test_case_name_stream.GetString().c_str(),
+              test_name_stream.GetString().c_str(),
+              "",  // test_case_comment
+              "",  // comment; TODO(vladl@google.com): provide parameter value
+                   //                                  representation.
+              GetTestCaseTypeId(),
+              TestCase::SetUpTestCase,
+              TestCase::TearDownTestCase,
+              test_info->test_meta_factory->CreateTestFactory(*param_it));
+        }  // for param_it
+      }  // for gen_it
+    }  // for test_it
+  }  // RegisterTests
+
+ private:
+  // LocalTestInfo structure keeps information about a single test registered
+  // with TEST_P macro.
+  struct TestInfo {
+    TestInfo(const char* a_test_case_base_name,
+             const char* a_test_base_name,
+             TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
+        test_case_base_name(a_test_case_base_name),
+        test_base_name(a_test_base_name),
+        test_meta_factory(a_test_meta_factory) {}
+
+    const String test_case_base_name;
+    const String test_base_name;
+    const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
+  };
+  typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
+  // Keeps pairs of <Instantiation name, Sequence generator creation function>
+  // received from INSTANTIATE_TEST_CASE_P macros.
+  typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> >
+      InstantiationContainer;
+
+  const String test_case_name_;
+  TestInfoContainer tests_;
+  InstantiationContainer instantiations_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
+};  // class ParameterizedTestCaseInfo
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
+// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
+// macros use it to locate their corresponding ParameterizedTestCaseInfo
+// descriptors.
+class ParameterizedTestCaseRegistry {
+ public:
+  ParameterizedTestCaseRegistry() {}
+  ~ParameterizedTestCaseRegistry() {
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      delete *it;
+    }
+  }
+
+  // Looks up or creates and returns a structure containing information about
+  // tests and instantiations of a particular test case.
+  template <class TestCase>
+  ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
+      const char* test_case_name,
+      const char* file,
+      int line) {
+    ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      if ((*it)->GetTestCaseName() == test_case_name) {
+        if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
+          // Complain about incorrect usage of Google Test facilities
+          // and terminate the program since we cannot guaranty correct
+          // test case setup and tear-down in this case.
+          ReportInvalidTestCaseType(test_case_name,  file, line);
+          abort();
+        } else {
+          // At this point we are sure that the object we found is of the same
+          // type we are looking for, so we downcast it to that type
+          // without further checks.
+          typed_test_info = CheckedDowncastToActualType<
+              ParameterizedTestCaseInfo<TestCase> >(*it);
+        }
+        break;
+      }
+    }
+    if (typed_test_info == NULL) {
+      typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
+      test_case_infos_.push_back(typed_test_info);
+    }
+    return typed_test_info;
+  }
+  void RegisterTests() {
+    for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
+         it != test_case_infos_.end(); ++it) {
+      (*it)->RegisterTests();
+    }
+  }
+
+ private:
+  typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
+
+  TestCaseInfoContainer test_case_infos_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  //  GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-port.h b/protobuf/gtest/include/gtest/internal/gtest-port.h
new file mode 100644
index 0000000..a2a62be
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-port.h
@@ -0,0 +1,1497 @@
+// 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_
+
+// The user can define the following macros in the build script to
+// control Google Test's behavior.  If the user doesn't define a macro
+// in this list, Google Test will define it.
+//
+//   GTEST_HAS_CLONE          - Define it to 1/0 to indicate that clone(2)
+//                              is/isn't available.
+//   GTEST_HAS_EXCEPTIONS     - Define it to 1/0 to indicate that exceptions
+//                              are enabled.
+//   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).
+//   GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string
+//                              is/isn't available (some systems define
+//                              ::wstring, which is different to std::wstring).
+//   GTEST_HAS_PTHREAD        - Define it to 1/0 to indicate that <pthread.h>
+//                              is/isn't available.
+//   GTEST_HAS_RTTI           - Define it to 1/0 to indicate that RTTI is/isn't
+//                              enabled.
+//   GTEST_HAS_STD_WSTRING    - Define it to 1/0 to indicate that
+//                              std::wstring does/doesn't work (Google Test can
+//                              be used where std::wstring is unavailable).
+//   GTEST_HAS_TR1_TUPLE      - Define it to 1/0 to indicate tr1::tuple
+//                              is/isn't available.
+//   GTEST_HAS_SEH            - Define it to 1/0 to indicate whether the
+//                              compiler supports Microsoft's "Structured
+//                              Exception Handling".
+//   GTEST_USE_OWN_TR1_TUPLE  - Define it to 1/0 to indicate whether Google
+//                              Test's own tr1 tuple implementation should be
+//                              used.  Unused when the user sets
+//                              GTEST_HAS_TR1_TUPLE to 0.
+//   GTEST_LINKED_AS_SHARED_LIBRARY
+//                            - Define to 1 when compiling tests that use
+//                              Google Test as a shared library (known as
+//                              DLL on Windows).
+//   GTEST_CREATE_SHARED_LIBRARY
+//                            - Define to 1 when compiling Google Test itself
+//                              as a shared library.
+
+// This header defines the following utilities:
+//
+// Macros indicating the current platform (defined to 1 if compiled on
+// the given platform; otherwise undefined):
+//   GTEST_OS_AIX      - IBM AIX
+//   GTEST_OS_CYGWIN   - Cygwin
+//   GTEST_OS_LINUX    - Linux
+//   GTEST_OS_MAC      - Mac OS X
+//   GTEST_OS_SOLARIS  - Sun Solaris
+//   GTEST_OS_SYMBIAN  - Symbian
+//   GTEST_OS_WINDOWS  - Windows (Desktop, MinGW, or Mobile)
+//     GTEST_OS_WINDOWS_DESKTOP  - Windows Desktop
+//     GTEST_OS_WINDOWS_MINGW    - MinGW
+//     GTEST_OS_WINDOWS_MOBILE   - Windows Mobile
+//   GTEST_OS_ZOS      - z/OS
+//
+// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
+// most stable support.  Since core members of the Google Test project
+// don't have access to other platforms, support for them may be less
+// stable.  If you notice any problems on your platform, please notify
+// googletestframework@googlegroups.com (patches for fixing them are
+// even more welcome!).
+//
+// Note that it is possible that none of the GTEST_OS_* macros are defined.
+//
+// Macros indicating available Google Test features (defined to 1 if
+// the corresponding feature is supported; otherwise undefined):
+//   GTEST_HAS_COMBINE      - the Combine() function (for value-parameterized
+//                            tests)
+//   GTEST_HAS_DEATH_TEST   - death tests
+//   GTEST_HAS_PARAM_TEST   - value-parameterized tests
+//   GTEST_HAS_TYPED_TEST   - typed tests
+//   GTEST_HAS_TYPED_TEST_P - type-parameterized tests
+//   GTEST_USES_POSIX_RE    - enhanced POSIX regex is used.
+//   GTEST_USES_SIMPLE_RE   - our own simple regex is used;
+//                            the above two are mutually exclusive.
+//   GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
+//
+// Macros for basic C++ coding:
+//   GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
+//   GTEST_ATTRIBUTE_UNUSED_  - declares that a class' instances or a
+//                              variable don't have to be used.
+//   GTEST_DISALLOW_ASSIGN_   - disables operator=.
+//   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.
+//   GTEST_IS_THREADSAFE - defined to 1 to indicate that the above
+//                         synchronization primitives have real implementations
+//                         and Google Test is thread-safe; or 0 otherwise.
+//
+// Template meta programming:
+//   is_pointer     - as in TR1; needed on Symbian and IBM XL C/C++ 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.
+//
+// Stdout and stderr capturing:
+//   CaptureStdout()     - starts capturing stdout.
+//   GetCapturedStdout() - stops capturing stdout and returns the captured
+//                         string.
+//   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 <stddef.h>  // For ptrdiff_t
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef _WIN32_WCE
+#include <sys/stat.h>
+#endif  // !_WIN32_WCE
+
+#include <iostream>  // NOLINT
+#include <sstream>  // NOLINT
+#include <string>  // NOLINT
+
+#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com"
+#define GTEST_FLAG_PREFIX_ "gtest_"
+#define GTEST_FLAG_PREFIX_DASH_ "gtest-"
+#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_"
+#define GTEST_NAME_ "Google Test"
+#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/"
+
+// Determines the version of gcc that is used to compile this.
+#ifdef __GNUC__
+// 40302 means version 4.3.2.
+#define GTEST_GCC_VER_ \
+    (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__)
+#endif  // __GNUC__
+
+// Determines the platform on which Google Test is compiled.
+#ifdef __CYGWIN__
+#define GTEST_OS_CYGWIN 1
+#elif defined __SYMBIAN32__
+#define GTEST_OS_SYMBIAN 1
+#elif defined _WIN32
+#define GTEST_OS_WINDOWS 1
+#ifdef _WIN32_WCE
+#define GTEST_OS_WINDOWS_MOBILE 1
+#elif defined(__MINGW__) || defined(__MINGW32__)
+#define GTEST_OS_WINDOWS_MINGW 1
+#else
+#define GTEST_OS_WINDOWS_DESKTOP 1
+#endif  // _WIN32_WCE
+#elif defined __APPLE__
+#define GTEST_OS_MAC 1
+#elif defined __linux__
+#define GTEST_OS_LINUX 1
+#elif defined __MVS__
+#define GTEST_OS_ZOS 1
+#elif defined(__sun) && defined(__SVR4)
+#define GTEST_OS_SOLARIS 1
+#elif defined(_AIX)
+#define GTEST_OS_AIX 1
+#endif  // __CYGWIN__
+
+#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_SYMBIAN || \
+    GTEST_OS_SOLARIS || GTEST_OS_AIX
+
+// On some platforms, <regex.h> needs someone to define size_t, and
+// won't compile otherwise.  We can #include it here as we already
+// included <stdlib.h>, which is guaranteed to define size_t through
+// <stddef.h>.
+#include <regex.h>  // NOLINT
+#include <strings.h>  // NOLINT
+#include <sys/types.h>  // NOLINT
+#include <time.h>  // NOLINT
+#include <unistd.h>  // NOLINT
+
+#define GTEST_USES_POSIX_RE 1
+
+#elif GTEST_OS_WINDOWS
+
+#if !GTEST_OS_WINDOWS_MOBILE
+#include <direct.h>  // NOLINT
+#include <io.h>  // NOLINT
+#endif
+
+// <regex.h> is not available on Windows.  Use our own simple regex
+// implementation instead.
+#define GTEST_USES_SIMPLE_RE 1
+
+#else
+
+// <regex.h> may not be available on this platform.  Use our own
+// simple regex implementation instead.
+#define GTEST_USES_SIMPLE_RE 1
+
+#endif  // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC ||
+        // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX
+
+#ifndef GTEST_HAS_EXCEPTIONS
+// The user didn't tell us whether exceptions are enabled, so we need
+// to figure it out.
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
+// macro to enable exceptions, so we'll do the same.
+// Assumes that exceptions are enabled by default.
+#ifndef _HAS_EXCEPTIONS
+#define _HAS_EXCEPTIONS 1
+#endif  // _HAS_EXCEPTIONS
+#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
+#elif defined(__GNUC__) && __EXCEPTIONS
+// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__SUNPRO_CC)
+// Sun Pro CC supports exceptions.  However, there is no compile-time way of
+// detecting whether they are enabled or not.  Therefore, we assume that
+// they are enabled unless the user tells us otherwise.
+#define GTEST_HAS_EXCEPTIONS 1
+#elif defined(__IBMCPP__) && __EXCEPTIONS
+// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled.
+#define GTEST_HAS_EXCEPTIONS 1
+#else
+// For other compilers, we assume exceptions are disabled to be
+// conservative.
+#define GTEST_HAS_EXCEPTIONS 0
+#endif  // defined(_MSC_VER) || defined(__BORLANDC__)
+#endif  // GTEST_HAS_EXCEPTIONS
+
+#if !defined(GTEST_HAS_STD_STRING)
+// Even though we don't use this macro any longer, we keep it in case
+// some clients still depend on it.
+#define GTEST_HAS_STD_STRING 1
+#elif !GTEST_HAS_STD_STRING
+// The user told us that ::std::string isn't available.
+#error "Google Test cannot be used where ::std::string isn't available."
+#endif  // !defined(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
+
+#ifndef GTEST_HAS_STD_WSTRING
+// The user didn't tell us whether ::std::wstring is available, so we need
+// to figure it out.
+// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring
+//   is available.
+
+// Cygwin 1.5 and below doesn't support ::std::wstring.
+// Cygwin 1.7 might add wstring support; this should be updated when clear.
+// Solaris' libc++ doesn't support it either.
+#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS))
+
+#endif  // GTEST_HAS_STD_WSTRING
+
+#ifndef GTEST_HAS_GLOBAL_WSTRING
+// The user didn't tell us whether ::wstring is available, so we need
+// to figure it out.
+#define GTEST_HAS_GLOBAL_WSTRING \
+    (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING)
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+// Determines whether RTTI is available.
+#ifndef GTEST_HAS_RTTI
+// The user didn't tell us whether RTTI is enabled, so we need to
+// figure it out.
+
+#ifdef _MSC_VER
+
+#ifdef _CPPRTTI  // MSVC defines this macro iff RTTI is enabled.
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif
+
+// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.
+#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)
+
+#ifdef __GXX_RTTI
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif  // __GXX_RTTI
+
+// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if
+// both the typeid and dynamic_cast features are present.
+#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)
+
+#ifdef __RTTI_ALL__
+#define GTEST_HAS_RTTI 1
+#else
+#define GTEST_HAS_RTTI 0
+#endif
+
+#else
+
+// For all other compilers, we assume RTTI is enabled.
+#define GTEST_HAS_RTTI 1
+
+#endif  // _MSC_VER
+
+#endif  // GTEST_HAS_RTTI
+
+// It's this header's responsibility to #include <typeinfo> when RTTI
+// is enabled.
+#if GTEST_HAS_RTTI
+#include <typeinfo>
+#endif
+
+// Determines whether Google Test can use the pthreads library.
+#ifndef GTEST_HAS_PTHREAD
+// The user didn't tell us explicitly, so we assume pthreads support is
+// available on Linux and Mac.
+//
+// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
+// to your compiler flags.
+#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC)
+#endif  // GTEST_HAS_PTHREAD
+
+// Determines whether Google Test can use tr1/tuple.  You can define
+// this macro to 0 to prevent Google Test from using tuple (any
+// feature depending on tuple with be disabled in this mode).
+#ifndef GTEST_HAS_TR1_TUPLE
+// The user didn't tell us not to do it, so we assume it's OK.
+#define GTEST_HAS_TR1_TUPLE 1
+#endif  // GTEST_HAS_TR1_TUPLE
+
+// Determines whether Google Test's own tr1 tuple implementation
+// should be used.
+#ifndef GTEST_USE_OWN_TR1_TUPLE
+// The user didn't tell us, so we need to figure it out.
+
+// We use our own TR1 tuple if we aren't sure the user has an
+// implementation of it already.  At this time, GCC 4.0.0+ and MSVC
+// 2010 are the only mainstream compilers that come with a TR1 tuple
+// implementation.  NVIDIA's CUDA NVCC compiler pretends to be GCC by
+// defining __GNUC__ and friends, but cannot compile GCC's tuple
+// implementation.  MSVC 2008 (9.0) provides TR1 tuple in a 323 MB
+// Feature Pack download, which we cannot assume the user has.
+#if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \
+    || _MSC_VER >= 1600
+#define GTEST_USE_OWN_TR1_TUPLE 0
+#else
+#define GTEST_USE_OWN_TR1_TUPLE 1
+#endif
+
+#endif  // GTEST_USE_OWN_TR1_TUPLE
+
+// To avoid conditional compilation everywhere, we make it
+// gtest-port.h's responsibility to #include the header implementing
+// tr1/tuple.
+#if GTEST_HAS_TR1_TUPLE
+
+#if GTEST_USE_OWN_TR1_TUPLE
+#include <gtest/internal/gtest-tuple.h>
+#elif GTEST_OS_SYMBIAN
+
+// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to
+// use STLport's tuple implementation, which unfortunately doesn't
+// work as the copy of STLport distributed with Symbian is incomplete.
+// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to
+// use its own tuple implementation.
+#ifdef BOOST_HAS_TR1_TUPLE
+#undef BOOST_HAS_TR1_TUPLE
+#endif  // BOOST_HAS_TR1_TUPLE
+
+// This prevents <boost/tr1/detail/config.hpp>, which defines
+// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.
+#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
+#include <tuple>
+
+#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
+// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header.  This does
+// not conform to the TR1 spec, which requires the header to be <tuple>.
+
+#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
+// Until version 4.3.2, gcc has a bug that causes <tr1/functional>,
+// which is #included by <tr1/tuple>, to not compile when RTTI is
+// disabled.  _TR1_FUNCTIONAL is the header guard for
+// <tr1/functional>.  Hence the following #define is a hack to prevent
+// <tr1/functional> from being included.
+#define _TR1_FUNCTIONAL 1
+#include <tr1/tuple>
+#undef _TR1_FUNCTIONAL  // Allows the user to #include
+                        // <tr1/functional> if he chooses to.
+#else
+#include <tr1/tuple>  // NOLINT
+#endif  // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
+
+#else
+// If the compiler is not GCC 4.0+, we assume the user is using a
+// spec-conforming TR1 implementation.
+#include <tuple>  // NOLINT
+#endif  // GTEST_USE_OWN_TR1_TUPLE
+
+#endif  // GTEST_HAS_TR1_TUPLE
+
+// Determines whether clone(2) is supported.
+// Usually it will only be available on Linux, excluding
+// Linux on the Itanium architecture.
+// Also see http://linux.die.net/man/2/clone.
+#ifndef GTEST_HAS_CLONE
+// The user didn't tell us, so we need to figure it out.
+
+#if GTEST_OS_LINUX && !defined(__ia64__)
+#define GTEST_HAS_CLONE 1
+#else
+#define GTEST_HAS_CLONE 0
+#endif  // GTEST_OS_LINUX && !defined(__ia64__)
+
+#endif  // GTEST_HAS_CLONE
+
+// Determines whether to support stream redirection. This is used to test
+// output correctness and to implement death tests.
+#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+#define GTEST_HAS_STREAM_REDIRECTION_ 1
+#endif  // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+
+// Determines whether to support death tests.
+// Google Test does not support death tests for VC 7.1 and earlier as
+// abort() in a VC 7.1 application compiled as GUI in debug config
+// pops up a dialog window that cannot be suppressed programmatically.
+#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
+     (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
+     GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX)
+#define GTEST_HAS_DEATH_TEST 1
+#include <vector>  // NOLINT
+#endif
+
+// We don't support MSVC 7.1 with exceptions disabled now.  Therefore
+// all the compilers we care about are adequate for supporting
+// value-parameterized tests.
+#define GTEST_HAS_PARAM_TEST 1
+
+// Determines whether to support type-driven tests.
+
+// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
+// Sun Pro CC, and IBM Visual Age support.
+#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \
+    defined(__IBMCPP__)
+#define GTEST_HAS_TYPED_TEST 1
+#define GTEST_HAS_TYPED_TEST_P 1
+#endif
+
+// Determines whether to support Combine(). This only makes sense when
+// value-parameterized tests are enabled.  The implementation doesn't
+// work on Sun Studio since it doesn't understand templated conversion
+// operators.
+#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)
+#define GTEST_HAS_COMBINE 1
+#endif
+
+// Determines whether the system compiler uses UTF-16 for encoding wide strings.
+#define GTEST_WIDE_STRING_USES_UTF16_ \
+    (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX)
+
+// 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_;
+//
+// Also use it after a variable or parameter declaration to tell the
+// compiler the variable/parameter does not have to be used.
+#if defined(__GNUC__) && !defined(COMPILER_ICC)
+#define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused))
+#else
+#define GTEST_ATTRIBUTE_UNUSED_
+#endif
+
+// A macro to disallow operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_ASSIGN_(type)\
+  void operator=(type const &)
+
+// A macro to disallow copy constructor and operator=
+// This should be used in the private: declarations for a class.
+#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\
+  type(type const &);\
+  GTEST_DISALLOW_ASSIGN_(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__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC)
+#define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result))
+#else
+#define GTEST_MUST_USE_RESULT_
+#endif  // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC
+
+// Determine whether the compiler supports Microsoft's Structured Exception
+// Handling.  This is supported by several Windows compilers but generally
+// does not exist on any other system.
+#ifndef GTEST_HAS_SEH
+// The user didn't tell us, so we need to figure it out.
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// These two compilers are known to support SEH.
+#define GTEST_HAS_SEH 1
+#else
+// Assume no SEH.
+#define GTEST_HAS_SEH 0
+#endif
+
+#endif  // GTEST_HAS_SEH
+
+#ifdef _MSC_VER
+
+#if GTEST_LINKED_AS_SHARED_LIBRARY
+#define GTEST_API_ __declspec(dllimport)
+#elif GTEST_CREATE_SHARED_LIBRARY
+#define GTEST_API_ __declspec(dllexport)
+#endif
+
+#endif  // _MSC_VER
+
+#ifndef GTEST_API_
+#define GTEST_API_
+#endif
+
+namespace testing {
+
+class Message;
+
+namespace internal {
+
+class String;
+
+typedef ::std::stringstream StrStream;
+
+// A helper for suppressing warnings on constant condition.  It just
+// returns 'condition'.
+GTEST_API_ bool IsTrue(bool condition);
+
+// 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:
+  typedef T element_type;
+
+  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 (IsTrue(sizeof(T) > 0)) {  // Makes sure T is a complete type.
+        delete ptr_;
+      }
+      ptr_ = p;
+    }
+  }
+ private:
+  T* ptr_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr);
+};
+
+// Defines RE.
+
+// A simple C++ wrapper for <regex.h>.  It uses the POSIX Extended
+// Regular Expression syntax.
+class GTEST_API_ RE {
+ public:
+  // A copy constructor is required by the Standard to initialize object
+  // references from r-values.
+  RE(const RE& other) { Init(other.pattern()); }
+
+  // Constructs an RE from a string.
+  RE(const ::std::string& regex) { Init(regex.c_str()); }  // NOLINT
+
+#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_; }
+
+  // FullMatch(str, re) returns true iff regular expression re matches
+  // the entire str.
+  // PartialMatch(str, re) returns true iff regular expression re
+  // matches a substring of str (including str itself).
+  //
+  // TODO(wan@google.com): make FullMatch() and PartialMatch() work
+  // when str contains NUL characters.
+  static bool FullMatch(const ::std::string& str, const RE& re) {
+    return FullMatch(str.c_str(), re);
+  }
+  static bool PartialMatch(const ::std::string& str, const RE& re) {
+    return PartialMatch(str.c_str(), re);
+  }
+
+#if GTEST_HAS_GLOBAL_STRING
+  static bool FullMatch(const ::string& str, const RE& re) {
+    return FullMatch(str.c_str(), re);
+  }
+  static bool PartialMatch(const ::string& str, const RE& re) {
+    return PartialMatch(str.c_str(), re);
+  }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  static bool FullMatch(const char* str, const RE& re);
+  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_;
+  bool is_valid_;
+#if GTEST_USES_POSIX_RE
+  regex_t full_regex_;     // For FullMatch().
+  regex_t partial_regex_;  // For PartialMatch().
+#else  // GTEST_USES_SIMPLE_RE
+  const char* full_pattern_;  // For FullMatch();
+#endif
+
+  GTEST_DISALLOW_ASSIGN_(RE);
+};
+
+// Defines logging utilities:
+//   GTEST_LOG_(severity) - logs messages at the specified severity level. The
+//                          message itself is streamed into the macro.
+//   LogToStderr()  - directs all log messages to stderr.
+//   FlushInfoLog() - flushes informational log messages.
+
+enum GTestLogSeverity {
+  GTEST_INFO,
+  GTEST_WARNING,
+  GTEST_ERROR,
+  GTEST_FATAL
+};
+
+// Formats log entry severity, provides a stream object for streaming the
+// log message, and terminates the message with a newline when going out of
+// scope.
+class GTEST_API_ GTestLog {
+ public:
+  GTestLog(GTestLogSeverity severity, const char* file, int line);
+
+  // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+  ~GTestLog();
+
+  ::std::ostream& GetStream() { return ::std::cerr; }
+
+ private:
+  const GTestLogSeverity severity_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog);
+};
+
+#define GTEST_LOG_(severity) \
+    ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
+                                  __FILE__, __LINE__).GetStream()
+
+inline void LogToStderr() {}
+inline void FlushInfoLog() { fflush(NULL); }
+
+// INTERNAL IMPLEMENTATION - DO NOT USE.
+//
+// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
+// is not satisfied.
+//  Synopsys:
+//    GTEST_CHECK_(boolean_condition);
+//     or
+//    GTEST_CHECK_(boolean_condition) << "Additional message";
+//
+//    This checks the condition and if the condition is not satisfied
+//    it prints message about the condition violation, including the
+//    condition itself, plus additional message streamed into it, if any,
+//    and then it aborts the program. It aborts the program irrespective of
+//    whether it is built in the debug mode or not.
+#define GTEST_CHECK_(condition) \
+    GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+    if (::testing::internal::IsTrue(condition)) \
+      ; \
+    else \
+      GTEST_LOG_(FATAL) << "Condition " #condition " failed. "
+
+// An all-mode assert to verify that the given POSIX-style function
+// call returns 0 (indicating success).  Known limitation: this
+// doesn't expand to a balanced 'if' statement, so enclose the macro
+// in {} if you need to use it as the only statement in an 'if'
+// branch.
+#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \
+  if (const int gtest_error = (posix_call)) \
+    GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
+                      << gtest_error
+
+// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
+//
+// Downcasts the pointer of type Base to Derived.
+// Derived must be a subclass of Base. The parameter MUST
+// point to a class of type Derived, not any subclass of it.
+// When RTTI is available, the function performs a runtime
+// check to enforce this.
+template <class Derived, class Base>
+Derived* CheckedDowncastToActualType(Base* base) {
+#if GTEST_HAS_RTTI
+  GTEST_CHECK_(typeid(*base) == typeid(Derived));
+  return dynamic_cast<Derived*>(base);  // NOLINT
+#else
+  return static_cast<Derived*>(base);  // Poor man's downcast.
+#endif
+}
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+
+// Defines the stderr capturer:
+//   CaptureStdout     - starts capturing stdout.
+//   GetCapturedStdout - stops capturing stdout and returns the captured string.
+//   CaptureStderr     - starts capturing stderr.
+//   GetCapturedStderr - stops capturing stderr and returns the captured string.
+//
+GTEST_API_ void CaptureStdout();
+GTEST_API_ String GetCapturedStdout();
+GTEST_API_ void CaptureStderr();
+GTEST_API_ String GetCapturedStderr();
+
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
+
+#if GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments.  Set by InitGoogleTest().
+extern ::std::vector<String> g_argvs;
+
+// GTEST_HAS_DEATH_TEST implies we have ::std::string.
+const ::std::vector<String>& GetArgvs();
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Defines synchronization primitives.
+
+#if GTEST_HAS_PTHREAD
+
+// Sleeps for (roughly) n milli-seconds.  This function is only for
+// testing Google Test's own constructs.  Don't use it in user tests,
+// either directly or indirectly.
+inline void SleepMilliseconds(int n) {
+  const timespec time = {
+    0,                  // 0 seconds.
+    n * 1000L * 1000L,  // And n ms.
+  };
+  nanosleep(&time, NULL);
+}
+
+// Allows a controller thread to pause execution of newly created
+// threads until notified.  Instances of this class must be created
+// and destroyed in the controller thread.
+//
+// This class is only for testing Google Test's own constructs. Do not
+// use it in user tests, either directly or indirectly.
+class Notification {
+ public:
+  Notification() : notified_(false) {}
+
+  // Notifies all threads created with this notification to start. Must
+  // be called from the controller thread.
+  void Notify() { notified_ = true; }
+
+  // Blocks until the controller thread notifies. Must be called from a test
+  // thread.
+  void WaitForNotification() {
+    while(!notified_) {
+      SleepMilliseconds(10);
+    }
+  }
+
+ private:
+  volatile bool notified_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification);
+};
+
+// As a C-function, ThreadFuncWithCLinkage cannot be templated itself.
+// Consequently, it cannot select a correct instantiation of ThreadWithParam
+// in order to call its Run(). Introducing ThreadWithParamBase as a
+// non-templated base class for ThreadWithParam allows us to bypass this
+// problem.
+class ThreadWithParamBase {
+ public:
+  virtual ~ThreadWithParamBase() {}
+  virtual void Run() = 0;
+};
+
+// pthread_create() accepts a pointer to a function type with the C linkage.
+// According to the Standard (7.5/1), function types with different linkages
+// are different even if they are otherwise identical.  Some compilers (for
+// example, SunStudio) treat them as different types.  Since class methods
+// cannot be defined with C-linkage we need to define a free C-function to
+// pass into pthread_create().
+extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
+  static_cast<ThreadWithParamBase*>(thread)->Run();
+  return NULL;
+}
+
+// Helper class for testing Google Test's multi-threading constructs.
+// To use it, write:
+//
+//   void ThreadFunc(int param) { /* Do things with param */ }
+//   Notification thread_can_start;
+//   ...
+//   // The thread_can_start parameter is optional; you can supply NULL.
+//   ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start);
+//   thread_can_start.Notify();
+//
+// These classes are only for testing Google Test's own constructs. Do
+// not use them in user tests, either directly or indirectly.
+template <typename T>
+class ThreadWithParam : public ThreadWithParamBase {
+ public:
+  typedef void (*UserThreadFunc)(T);
+
+  ThreadWithParam(
+      UserThreadFunc func, T param, Notification* thread_can_start)
+      : func_(func),
+        param_(param),
+        thread_can_start_(thread_can_start),
+        finished_(false) {
+    ThreadWithParamBase* const base = this;
+    // The thread can be created only after all fields except thread_
+    // have been initialized.
+    GTEST_CHECK_POSIX_SUCCESS_(
+        pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base));
+  }
+  ~ThreadWithParam() { Join(); }
+
+  void Join() {
+    if (!finished_) {
+      GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
+      finished_ = true;
+    }
+  }
+
+  virtual void Run() {
+    if (thread_can_start_ != NULL)
+      thread_can_start_->WaitForNotification();
+    func_(param_);
+  }
+
+ private:
+  const UserThreadFunc func_;  // User-supplied thread function.
+  const T param_;  // User-supplied parameter to the thread function.
+  // When non-NULL, used to block execution until the controller thread
+  // notifies.
+  Notification* const thread_can_start_;
+  bool finished_;  // true iff we know that the thread function has finished.
+  pthread_t thread_;  // The native thread object.
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
+};
+
+// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is
+// true.
+#include <pthread.h>
+
+// MutexBase and Mutex implement mutex on pthreads-based platforms. They
+// are used in conjunction with class MutexLock:
+//
+//   Mutex mutex;
+//   ...
+//   MutexLock lock(&mutex);  // Acquires the mutex and releases it at the end
+//                            // of the current scope.
+//
+// MutexBase implements behavior for both statically and dynamically
+// allocated mutexes.  Do not use MutexBase directly.  Instead, write
+// the following to define a static mutex:
+//
+//   GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex);
+//
+// You can forward declare a static mutex like this:
+//
+//   GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex);
+//
+// To create a dynamic mutex, just define an object of type Mutex.
+class MutexBase {
+ public:
+  // Acquires this mutex.
+  void Lock() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
+    owner_ = pthread_self();
+  }
+
+  // Releases this mutex.
+  void Unlock() {
+    // We don't protect writing to owner_ here, as it's the caller's
+    // responsibility to ensure that the current thread holds the
+    // mutex when this is called.
+    owner_ = 0;
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
+  }
+
+  // Does nothing if the current thread holds the mutex. Otherwise, crashes
+  // with high probability.
+  void AssertHeld() const {
+    GTEST_CHECK_(owner_ == pthread_self())
+        << "The current thread is not holding the mutex @" << this;
+  }
+
+  // A static mutex may be used before main() is entered.  It may even
+  // be used before the dynamic initialization stage.  Therefore we
+  // must be able to initialize a static mutex object at link time.
+  // This means MutexBase has to be a POD and its member variables
+  // have to be public.
+ public:
+  pthread_mutex_t mutex_;  // The underlying pthread mutex.
+  pthread_t owner_;  // The thread holding the mutex; 0 means no one holds it.
+};
+
+// Forward-declares a static mutex.
+#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+    extern ::testing::internal::MutexBase mutex
+
+// Defines and statically (i.e. at link time) initializes a static mutex.
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
+    ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }
+
+// The Mutex class can only be used for mutexes created at runtime. It
+// shares its API with MutexBase otherwise.
+class Mutex : public MutexBase {
+ public:
+  Mutex() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
+    owner_ = 0;
+  }
+  ~Mutex() {
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_));
+  }
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
+};
+
+// We cannot name this class MutexLock 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(MutexBase* mutex)
+      : mutex_(mutex) { mutex_->Lock(); }
+
+  ~GTestMutexLock() { mutex_->Unlock(); }
+
+ private:
+  MutexBase* const mutex_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock);
+};
+
+typedef GTestMutexLock MutexLock;
+
+// Helpers for ThreadLocal.
+
+// pthread_key_create() requires DeleteThreadLocalValue() to have
+// C-linkage.  Therefore it cannot be templatized to access
+// ThreadLocal<T>.  Hence the need for class
+// ThreadLocalValueHolderBase.
+class ThreadLocalValueHolderBase {
+ public:
+  virtual ~ThreadLocalValueHolderBase() {}
+};
+
+// Called by pthread to delete thread-local data stored by
+// pthread_setspecific().
+extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
+  delete static_cast<ThreadLocalValueHolderBase*>(value_holder);
+}
+
+// Implements thread-local storage on pthreads-based systems.
+//
+//   // Thread 1
+//   ThreadLocal<int> tl(100);  // 100 is the default value for each thread.
+//
+//   // Thread 2
+//   tl.set(150);  // Changes the value for thread 2 only.
+//   EXPECT_EQ(150, tl.get());
+//
+//   // Thread 1
+//   EXPECT_EQ(100, tl.get());  // In thread 1, tl has the original value.
+//   tl.set(200);
+//   EXPECT_EQ(200, tl.get());
+//
+// The template type argument T must have a public copy constructor.
+// In addition, the default ThreadLocal constructor requires T to have
+// a public default constructor.
+//
+// An object managed for a thread by a ThreadLocal instance is deleted
+// when the thread exits.  Or, if the ThreadLocal instance dies in
+// that thread, when the ThreadLocal dies.  It's the user's
+// responsibility to ensure that all other threads using a ThreadLocal
+// have exited when it dies, or the per-thread objects for those
+// threads will not be deleted.
+//
+// Google Test only uses global ThreadLocal objects.  That means they
+// will die after main() has returned.  Therefore, no per-thread
+// object managed by Google Test will be leaked as long as all threads
+// using Google Test have exited when main() returns.
+template <typename T>
+class ThreadLocal {
+ public:
+  ThreadLocal() : key_(CreateKey()),
+                  default_() {}
+  explicit ThreadLocal(const T& value) : key_(CreateKey()),
+                                         default_(value) {}
+
+  ~ThreadLocal() {
+    // Destroys the managed object for the current thread, if any.
+    DeleteThreadLocalValue(pthread_getspecific(key_));
+
+    // Releases resources associated with the key.  This will *not*
+    // delete managed objects for other threads.
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_));
+  }
+
+  T* pointer() { return GetOrCreateValue(); }
+  const T* pointer() const { return GetOrCreateValue(); }
+  const T& get() const { return *pointer(); }
+  void set(const T& value) { *pointer() = value; }
+
+ private:
+  // Holds a value of type T.
+  class ValueHolder : public ThreadLocalValueHolderBase {
+   public:
+    explicit ValueHolder(const T& value) : value_(value) {}
+
+    T* pointer() { return &value_; }
+
+   private:
+    T value_;
+    GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder);
+  };
+
+  static pthread_key_t CreateKey() {
+    pthread_key_t key;
+    // When a thread exits, DeleteThreadLocalValue() will be called on
+    // the object managed for that thread.
+    GTEST_CHECK_POSIX_SUCCESS_(
+        pthread_key_create(&key, &DeleteThreadLocalValue));
+    return key;
+  }
+
+  T* GetOrCreateValue() const {
+    ThreadLocalValueHolderBase* const holder =
+        static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));
+    if (holder != NULL) {
+      return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
+    }
+
+    ValueHolder* const new_holder = new ValueHolder(default_);
+    ThreadLocalValueHolderBase* const holder_base = new_holder;
+    GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));
+    return new_holder->pointer();
+  }
+
+  // A key pthreads uses for looking up per-thread values.
+  const pthread_key_t key_;
+  const T default_;  // The default value for each thread.
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
+};
+
+#define GTEST_IS_THREADSAFE 1
+
+#else  // GTEST_HAS_PTHREAD
+
+// 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() {}
+  void AssertHeld() const {}
+};
+
+#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
+  extern ::testing::internal::Mutex mutex
+
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex
+
+class GTestMutexLock {
+ public:
+  explicit GTestMutexLock(Mutex*) {}  // NOLINT
+};
+
+typedef GTestMutexLock MutexLock;
+
+template <typename T>
+class ThreadLocal {
+ public:
+  ThreadLocal() : value_() {}
+  explicit ThreadLocal(const T& value) : value_(value) {}
+  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_;
+};
+
+// The above synchronization primitives have dummy implementations.
+// Therefore Google Test is not thread-safe.
+#define GTEST_IS_THREADSAFE 0
+
+#endif  // GTEST_HAS_PTHREAD
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+GTEST_API_ size_t GetThreadCount();
+
+// Passing non-POD classes through ellipsis (...) crashes the ARM
+// compiler and generates a warning in Sun Studio.  The Nokia Symbian
+// and the IBM XL C/C++ compiler try to instantiate a copy constructor
+// for objects passed through ellipsis (...), failing for uncopyable
+// objects.  We define this to ensure that only POD is passed through
+// ellipsis on these systems.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
+// We lose support for NULL detection where the compiler doesn't like
+// passing non-POD classes through ellipsis (...).
+#define GTEST_ELLIPSIS_NEEDS_POD_ 1
+#else
+#define GTEST_CAN_COMPARE_NULL 1
+#endif
+
+// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between
+// const T& and const T* in a function template.  These compilers
+// _can_ decide between class template specializations for T and T*,
+// so a tr1::type_traits-like is_pointer works.
+#if defined(__SYMBIAN32__) || defined(__IBMCPP__)
+#define GTEST_NEEDS_IS_POINTER_ 1
+#endif
+
+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 {};
+
+#if GTEST_OS_WINDOWS
+#define GTEST_PATH_SEP_ "\\"
+#define GTEST_HAS_ALT_PATH_SEP_ 1
+// The biggest signed integer type the compiler supports.
+typedef __int64 BiggestInt;
+#else
+#define GTEST_PATH_SEP_ "/"
+#define GTEST_HAS_ALT_PATH_SEP_ 0
+typedef long long BiggestInt;  // NOLINT
+#endif  // GTEST_OS_WINDOWS
+
+// The testing::internal::posix namespace holds wrappers for common
+// POSIX functions.  These wrappers hide the differences between
+// Windows/MSVC and POSIX systems.  Since some compilers define these
+// standard functions as macros, the wrapper cannot have the same name
+// as the wrapped function.
+
+namespace posix {
+
+// Functions with a different name on Windows.
+
+#if GTEST_OS_WINDOWS
+
+typedef struct _stat StatStruct;
+
+#ifdef __BORLANDC__
+inline int IsATTY(int fd) { return isatty(fd); }
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return stricmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return strdup(src); }
+#else  // !__BORLANDC__
+#if GTEST_OS_WINDOWS_MOBILE
+inline int IsATTY(int /* fd */) { return 0; }
+#else
+inline int IsATTY(int fd) { return _isatty(fd); }
+#endif  // GTEST_OS_WINDOWS_MOBILE
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return _stricmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return _strdup(src); }
+#endif  // __BORLANDC__
+
+#if GTEST_OS_WINDOWS_MOBILE
+inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); }
+// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this
+// time and thus not defined there.
+#else
+inline int FileNo(FILE* file) { return _fileno(file); }
+inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); }
+inline int RmDir(const char* dir) { return _rmdir(dir); }
+inline bool IsDir(const StatStruct& st) {
+  return (_S_IFDIR & st.st_mode) != 0;
+}
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#else
+
+typedef struct stat StatStruct;
+
+inline int FileNo(FILE* file) { return fileno(file); }
+inline int IsATTY(int fd) { return isatty(fd); }
+inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
+inline int StrCaseCmp(const char* s1, const char* s2) {
+  return strcasecmp(s1, s2);
+}
+inline char* StrDup(const char* src) { return strdup(src); }
+inline int RmDir(const char* dir) { return rmdir(dir); }
+inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
+
+#endif  // GTEST_OS_WINDOWS
+
+// Functions deprecated by MSVC 8.0.
+
+#ifdef _MSC_VER
+// Temporarily disable warning 4996 (deprecated function).
+#pragma warning(push)
+#pragma warning(disable:4996)
+#endif
+
+inline const char* StrNCpy(char* dest, const char* src, size_t n) {
+  return strncpy(dest, src, n);
+}
+
+// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and
+// StrError() aren't needed on Windows CE at this time and thus not
+// defined there.
+
+#if !GTEST_OS_WINDOWS_MOBILE
+inline int ChDir(const char* dir) { return chdir(dir); }
+#endif
+inline FILE* FOpen(const char* path, const char* mode) {
+  return fopen(path, mode);
+}
+#if !GTEST_OS_WINDOWS_MOBILE
+inline FILE *FReopen(const char* path, const char* mode, FILE* stream) {
+  return freopen(path, mode, stream);
+}
+inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); }
+#endif
+inline int FClose(FILE* fp) { return fclose(fp); }
+#if !GTEST_OS_WINDOWS_MOBILE
+inline int Read(int fd, void* buf, unsigned int count) {
+  return static_cast<int>(read(fd, buf, count));
+}
+inline int Write(int fd, const void* buf, unsigned int count) {
+  return static_cast<int>(write(fd, buf, count));
+}
+inline int Close(int fd) { return close(fd); }
+inline const char* StrError(int errnum) { return strerror(errnum); }
+#endif
+inline const char* GetEnv(const char* name) {
+#if GTEST_OS_WINDOWS_MOBILE
+  // We are on Windows CE, which has no environment variables.
+  return NULL;
+#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
+  // Environment variables which we programmatically clear will be set to the
+  // empty string rather than unset (NULL).  Handle that case.
+  const char* const env = getenv(name);
+  return (env != NULL && env[0] != '\0') ? env : NULL;
+#else
+  return getenv(name);
+#endif
+}
+
+#ifdef _MSC_VER
+#pragma warning(pop)  // Restores the warning state.
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+// 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.
+void Abort();
+#else
+inline void Abort() { abort(); }
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+}  // namespace posix
+
+// 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:
+#if 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.
+
+// Macro for referencing flags.
+#define GTEST_FLAG(name) FLAGS_gtest_##name
+
+// Macros for declaring flags.
+#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
+#define GTEST_DECLARE_int32_(name) \
+    GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
+#define GTEST_DECLARE_string_(name) \
+    GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name)
+
+// Macros for defining flags.
+#define GTEST_DEFINE_bool_(name, default_val, doc) \
+    GTEST_API_ bool GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_int32_(name, default_val, doc) \
+    GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
+#define GTEST_DEFINE_string_(name, default_val, doc) \
+    GTEST_API_ ::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);
+GTEST_API_ 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/protobuf/gtest/include/gtest/internal/gtest-string.h b/protobuf/gtest/include/gtest/internal/gtest-string.h
new file mode 100644
index 0000000..aff093d
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-string.h
@@ -0,0 +1,350 @@
+// 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 <gtest/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_
+
+#ifdef __BORLANDC__
+// string.h is not guaranteed to provide strcpy on C++ Builder.
+#include <mem.h>
+#endif
+
+#include <string.h>
+#include <gtest/internal/gtest-port.h>
+
+#include <string>
+
+namespace testing {
+namespace internal {
+
+// String - a UTF-8 string class.
+//
+// For historic reasons, we don't use std::string.
+//
+// TODO(wan@google.com): replace this class with std::string or
+// implement it in terms of the latter.
+//
+// Note that String 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 GTEST_API_ String {
+ public:
+  // Static utility methods
+
+  // 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);
+
+#if GTEST_OS_WINDOWS_MOBILE
+  // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
+  // able to pass strings to Win32 APIs on CE we need to convert them
+  // to 'Unicode', UTF-16.
+
+  // Creates a UTF-16 wide string from the given ANSI string, allocating
+  // memory using new. The caller is responsible for deleting the return
+  // value using delete[]. Returns the wide string, or NULL if the
+  // input is NULL.
+  //
+  // The wide string is created using the ANSI codepage (CP_ACP) to
+  // match the behaviour of the ANSI versions of Win32 calls and the
+  // C runtime.
+  static LPCWSTR AnsiToUtf16(const char* c_str);
+
+  // Creates an ANSI string from the given wide string, allocating
+  // memory using new. The caller is responsible for deleting the return
+  // value using delete[]. Returns the ANSI string, or NULL if the
+  // input is NULL.
+  //
+  // The returned string is created using the ANSI codepage (CP_ACP) to
+  // match the behaviour of the ANSI versions of Win32 calls and the
+  // C runtime.
+  static const char* Utf16ToAnsi(LPCWSTR utf16_str);
+#endif
+
+  // 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);
+
+  // Compares two wide C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike wcscasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL wide C string,
+  // including the empty string.
+  // NB: The implementations on different platforms slightly differ.
+  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+  // environment variable. On GNU platform this method uses wcscasecmp
+  // which compares according to LC_CTYPE category of the current locale.
+  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+  // current locale.
+  static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
+                                               const wchar_t* 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), length_(0) {}
+
+  // Constructs a String by cloning a 0-terminated C string.
+  String(const char* a_c_str) {  // NOLINT
+    if (a_c_str == NULL) {
+      c_str_ = NULL;
+      length_ = 0;
+    } else {
+      ConstructNonNull(a_c_str, strlen(a_c_str));
+    }
+  }
+
+  // Constructs a String by copying a given number of chars from a
+  // buffer.  E.g. String("hello", 3) creates the string "hel",
+  // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "",
+  // and String(NULL, 1) results in access violation.
+  String(const char* buffer, size_t a_length) {
+    ConstructNonNull(buffer, a_length);
+  }
+
+  // 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), length_(0) { *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_; }
+
+  // Allows a String to be implicitly converted to an ::std::string or
+  // ::string, and vice versa.  Converting a String containing a NULL
+  // pointer to ::std::string or ::string is undefined behavior.
+  // Converting a ::std::string or ::string containing an embedded NUL
+  // character to a String will result in the prefix up to the first
+  // NUL character.
+  String(const ::std::string& str) {
+    ConstructNonNull(str.c_str(), str.length());
+  }
+
+  operator ::std::string() const { return ::std::string(c_str(), length()); }
+
+#if GTEST_HAS_GLOBAL_STRING
+  String(const ::string& str) {
+    ConstructNonNull(str.c_str(), str.length());
+  }
+
+  operator ::string() const { return ::string(c_str(), length()); }
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  // Returns true iff this is an empty string (i.e. "").
+  bool empty() const { return (c_str() != NULL) && (length() == 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* a_c_str) const { return Compare(a_c_str) == 0; }
+
+  // Returns true iff this String is less than the given String.  A
+  // NULL string is considered less than "".
+  bool operator<(const String& rhs) const { return Compare(rhs) < 0; }
+
+  // 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* a_c_str) const { return !(*this == a_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 0 if the
+  // string is NULL.
+  size_t length() const { return length_; }
+
+  // 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_; }
+
+  // Assigns a C string to this object.  Self-assignment works.
+  const String& operator=(const char* a_c_str) {
+    return *this = String(a_c_str);
+  }
+
+  // Assigns a String object to this object.  Self-assignment works.
+  const String& operator=(const String& rhs) {
+    if (this != &rhs) {
+      delete[] c_str_;
+      if (rhs.c_str() == NULL) {
+        c_str_ = NULL;
+        length_ = 0;
+      } else {
+        ConstructNonNull(rhs.c_str(), rhs.length());
+      }
+    }
+
+    return *this;
+  }
+
+ private:
+  // Constructs a non-NULL String from the given content.  This
+  // function can only be called when data_ has not been allocated.
+  // ConstructNonNull(NULL, 0) results in an empty string ("").
+  // ConstructNonNull(NULL, non_zero) is undefined behavior.
+  void ConstructNonNull(const char* buffer, size_t a_length) {
+    char* const str = new char[a_length + 1];
+    memcpy(str, buffer, a_length);
+    str[a_length] = '\0';
+    c_str_ = str;
+    length_ = a_length;
+  }
+
+  const char* c_str_;
+  size_t length_;
+};  // class String
+
+// Streams a String to an ostream.  Each '\0' character in the String
+// is replaced with "\\0".
+inline ::std::ostream& operator<<(::std::ostream& os, const String& str) {
+  if (str.c_str() == NULL) {
+    os << "(null)";
+  } else {
+    const char* const c_str = str.c_str();
+    for (size_t i = 0; i != str.length(); i++) {
+      if (c_str[i] == '\0') {
+        os << "\\0";
+      } else {
+        os << c_str[i];
+      }
+    }
+  }
+  return os;
+}
+
+// Gets the content of the StrStream's buffer as a String.  Each '\0'
+// character in the buffer is replaced with "\\0".
+GTEST_API_ 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_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-tuple.h b/protobuf/gtest/include/gtest/internal/gtest-tuple.h
new file mode 100644
index 0000000..16178fc
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-tuple.h
@@ -0,0 +1,968 @@
+// This file was GENERATED by a script.  DO NOT EDIT BY HAND!!!
+
+// Copyright 2009 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)
+
+// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+
+#include <utility>  // For ::std::pair.
+
+// The compiler used in Symbian has a bug that prevents us from declaring the
+// tuple template as a friend (it complains that tuple is redefined).  This
+// hack bypasses the bug by declaring the members that should otherwise be
+// private as public.
+// Sun Studio versions < 12 also have the above bug.
+#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
+#else
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
+    template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
+   private:
+#endif
+
+// GTEST_n_TUPLE_(T) is the type of an n-tuple.
+#define GTEST_0_TUPLE_(T) tuple<>
+#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
+    void, void, void>
+#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
+    void, void, void>
+#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
+    void, void, void>
+#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
+    void, void, void>
+#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
+    void, void, void>
+#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
+    void, void, void>
+#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    void, void, void>
+#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, void, void>
+#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, T##8, void>
+#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
+    T##7, T##8, T##9>
+
+// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
+#define GTEST_0_TYPENAMES_(T)
+#define GTEST_1_TYPENAMES_(T) typename T##0
+#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1
+#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2
+#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3
+#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4
+#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5
+#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6
+#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, typename T##7
+#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, \
+    typename T##7, typename T##8
+#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
+    typename T##3, typename T##4, typename T##5, typename T##6, \
+    typename T##7, typename T##8, typename T##9
+
+// In theory, defining stuff in the ::std namespace is undefined
+// behavior.  We can do this as we are playing the role of a standard
+// library vendor.
+namespace std {
+namespace tr1 {
+
+template <typename T0 = void, typename T1 = void, typename T2 = void,
+    typename T3 = void, typename T4 = void, typename T5 = void,
+    typename T6 = void, typename T7 = void, typename T8 = void,
+    typename T9 = void>
+class tuple;
+
+// Anything in namespace gtest_internal is Google Test's INTERNAL
+// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
+namespace gtest_internal {
+
+// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
+template <typename T>
+struct ByRef { typedef const T& type; };  // NOLINT
+template <typename T>
+struct ByRef<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper for ByRef.
+#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
+
+// AddRef<T>::type is T if T is a reference; otherwise it's T&.  This
+// is the same as tr1::add_reference<T>::type.
+template <typename T>
+struct AddRef { typedef T& type; };  // NOLINT
+template <typename T>
+struct AddRef<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper for AddRef.
+#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
+
+// A helper for implementing get<k>().
+template <int k> class Get;
+
+// A helper for implementing tuple_element<k, T>.  kIndexValid is true
+// iff k < the number of fields in tuple type T.
+template <bool kIndexValid, int kIndex, class Tuple>
+struct TupleElement;
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; };
+
+}  // namespace gtest_internal
+
+template <>
+class tuple<> {
+ public:
+  tuple() {}
+  tuple(const tuple& /* t */)  {}
+  tuple& operator=(const tuple& /* t */) { return *this; }
+};
+
+template <GTEST_1_TYPENAMES_(T)>
+class GTEST_1_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
+
+  tuple(const tuple& t) : f0_(t.f0_) {}
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_1_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_1_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    return *this;
+  }
+
+  T0 f0_;
+};
+
+template <GTEST_2_TYPENAMES_(T)>
+class GTEST_2_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
+      f1_(f1) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}
+  template <typename U0, typename U1>
+  tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_2_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+  template <typename U0, typename U1>
+  tuple& operator=(const ::std::pair<U0, U1>& p) {
+    f0_ = p.first;
+    f1_ = p.second;
+    return *this;
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_2_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+};
+
+template <GTEST_3_TYPENAMES_(T)>
+class GTEST_3_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_3_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_3_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+};
+
+template <GTEST_4_TYPENAMES_(T)>
+class GTEST_4_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_4_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_4_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+};
+
+template <GTEST_5_TYPENAMES_(T)>
+class GTEST_5_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
+      GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_) {}
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_5_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_5_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+};
+
+template <GTEST_6_TYPENAMES_(T)>
+class GTEST_6_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_) {}
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_6_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_6_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+};
+
+template <GTEST_7_TYPENAMES_(T)>
+class GTEST_7_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_7_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_7_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+};
+
+template <GTEST_8_TYPENAMES_(T)>
+class GTEST_8_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,
+      GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5), f6_(f6), f7_(f7) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_8_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_8_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+};
+
+template <GTEST_9_TYPENAMES_(T)>
+class GTEST_9_TUPLE_(T) {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
+      GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
+      f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_9_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_9_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    f8_ = t.f8_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+  T8 f8_;
+};
+
+template <GTEST_10_TYPENAMES_(T)>
+class tuple {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),
+      f9_() {}
+
+  explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
+      GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
+      GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
+      GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),
+      f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}
+
+  tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
+      f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
+      f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),
+      f9_(t.f9_) {}
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_10_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_10_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
+    f0_ = t.f0_;
+    f1_ = t.f1_;
+    f2_ = t.f2_;
+    f3_ = t.f3_;
+    f4_ = t.f4_;
+    f5_ = t.f5_;
+    f6_ = t.f6_;
+    f7_ = t.f7_;
+    f8_ = t.f8_;
+    f9_ = t.f9_;
+    return *this;
+  }
+
+  T0 f0_;
+  T1 f1_;
+  T2 f2_;
+  T3 f3_;
+  T4 f4_;
+  T5 f5_;
+  T6 f6_;
+  T7 f7_;
+  T8 f8_;
+  T9 f9_;
+};
+
+// 6.1.3.2 Tuple creation functions.
+
+// Known limitations: we don't support passing an
+// std::tr1::reference_wrapper<T> to make_tuple().  And we don't
+// implement tie().
+
+inline tuple<> make_tuple() { return tuple<>(); }
+
+template <GTEST_1_TYPENAMES_(T)>
+inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {
+  return GTEST_1_TUPLE_(T)(f0);
+}
+
+template <GTEST_2_TYPENAMES_(T)>
+inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {
+  return GTEST_2_TUPLE_(T)(f0, f1);
+}
+
+template <GTEST_3_TYPENAMES_(T)>
+inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {
+  return GTEST_3_TUPLE_(T)(f0, f1, f2);
+}
+
+template <GTEST_4_TYPENAMES_(T)>
+inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3) {
+  return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);
+}
+
+template <GTEST_5_TYPENAMES_(T)>
+inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4) {
+  return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);
+}
+
+template <GTEST_6_TYPENAMES_(T)>
+inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5) {
+  return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);
+}
+
+template <GTEST_7_TYPENAMES_(T)>
+inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6) {
+  return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);
+}
+
+template <GTEST_8_TYPENAMES_(T)>
+inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {
+  return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);
+}
+
+template <GTEST_9_TYPENAMES_(T)>
+inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
+    const T8& f8) {
+  return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);
+}
+
+template <GTEST_10_TYPENAMES_(T)>
+inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
+    const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
+    const T8& f8, const T9& f9) {
+  return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
+}
+
+// 6.1.3.3 Tuple helper classes.
+
+template <typename Tuple> struct tuple_size;
+
+template <GTEST_0_TYPENAMES_(T)>
+struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; };
+
+template <GTEST_1_TYPENAMES_(T)>
+struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; };
+
+template <GTEST_2_TYPENAMES_(T)>
+struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; };
+
+template <GTEST_3_TYPENAMES_(T)>
+struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; };
+
+template <GTEST_4_TYPENAMES_(T)>
+struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; };
+
+template <GTEST_5_TYPENAMES_(T)>
+struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; };
+
+template <GTEST_6_TYPENAMES_(T)>
+struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; };
+
+template <GTEST_7_TYPENAMES_(T)>
+struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; };
+
+template <GTEST_8_TYPENAMES_(T)>
+struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; };
+
+template <GTEST_9_TYPENAMES_(T)>
+struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; };
+
+template <GTEST_10_TYPENAMES_(T)>
+struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; };
+
+template <int k, class Tuple>
+struct tuple_element {
+  typedef typename gtest_internal::TupleElement<
+      k < (tuple_size<Tuple>::value), k, Tuple>::type type;
+};
+
+#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
+
+// 6.1.3.4 Element access.
+
+namespace gtest_internal {
+
+template <>
+class Get<0> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
+  Field(Tuple& t) { return t.f0_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
+  ConstField(const Tuple& t) { return t.f0_; }
+};
+
+template <>
+class Get<1> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
+  Field(Tuple& t) { return t.f1_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
+  ConstField(const Tuple& t) { return t.f1_; }
+};
+
+template <>
+class Get<2> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
+  Field(Tuple& t) { return t.f2_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
+  ConstField(const Tuple& t) { return t.f2_; }
+};
+
+template <>
+class Get<3> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
+  Field(Tuple& t) { return t.f3_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
+  ConstField(const Tuple& t) { return t.f3_; }
+};
+
+template <>
+class Get<4> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
+  Field(Tuple& t) { return t.f4_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
+  ConstField(const Tuple& t) { return t.f4_; }
+};
+
+template <>
+class Get<5> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
+  Field(Tuple& t) { return t.f5_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
+  ConstField(const Tuple& t) { return t.f5_; }
+};
+
+template <>
+class Get<6> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
+  Field(Tuple& t) { return t.f6_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
+  ConstField(const Tuple& t) { return t.f6_; }
+};
+
+template <>
+class Get<7> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
+  Field(Tuple& t) { return t.f7_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
+  ConstField(const Tuple& t) { return t.f7_; }
+};
+
+template <>
+class Get<8> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
+  Field(Tuple& t) { return t.f8_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
+  ConstField(const Tuple& t) { return t.f8_; }
+};
+
+template <>
+class Get<9> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
+  Field(Tuple& t) { return t.f9_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
+  ConstField(const Tuple& t) { return t.f9_; }
+};
+
+}  // namespace gtest_internal
+
+template <int k, GTEST_10_TYPENAMES_(T)>
+GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
+get(GTEST_10_TUPLE_(T)& t) {
+  return gtest_internal::Get<k>::Field(t);
+}
+
+template <int k, GTEST_10_TYPENAMES_(T)>
+GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k,  GTEST_10_TUPLE_(T)))
+get(const GTEST_10_TUPLE_(T)& t) {
+  return gtest_internal::Get<k>::ConstField(t);
+}
+
+// 6.1.3.5 Relational operators
+
+// We only implement == and !=, as we don't have a need for the rest yet.
+
+namespace gtest_internal {
+
+// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
+// first k fields of t1 equals the first k fields of t2.
+// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
+// k1 != k2.
+template <int kSize1, int kSize2>
+struct SameSizeTuplePrefixComparator;
+
+template <>
+struct SameSizeTuplePrefixComparator<0, 0> {
+  template <class Tuple1, class Tuple2>
+  static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
+    return true;
+  }
+};
+
+template <int k>
+struct SameSizeTuplePrefixComparator<k, k> {
+  template <class Tuple1, class Tuple2>
+  static bool Eq(const Tuple1& t1, const Tuple2& t2) {
+    return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
+        ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
+  }
+};
+
+}  // namespace gtest_internal
+
+template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+inline bool operator==(const GTEST_10_TUPLE_(T)& t,
+                       const GTEST_10_TUPLE_(U)& u) {
+  return gtest_internal::SameSizeTuplePrefixComparator<
+      tuple_size<GTEST_10_TUPLE_(T)>::value,
+      tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u);
+}
+
+template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
+inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
+                       const GTEST_10_TUPLE_(U)& u) { return !(t == u); }
+
+// 6.1.4 Pairs.
+// Unimplemented.
+
+}  // namespace tr1
+}  // namespace std
+
+#undef GTEST_0_TUPLE_
+#undef GTEST_1_TUPLE_
+#undef GTEST_2_TUPLE_
+#undef GTEST_3_TUPLE_
+#undef GTEST_4_TUPLE_
+#undef GTEST_5_TUPLE_
+#undef GTEST_6_TUPLE_
+#undef GTEST_7_TUPLE_
+#undef GTEST_8_TUPLE_
+#undef GTEST_9_TUPLE_
+#undef GTEST_10_TUPLE_
+
+#undef GTEST_0_TYPENAMES_
+#undef GTEST_1_TYPENAMES_
+#undef GTEST_2_TYPENAMES_
+#undef GTEST_3_TYPENAMES_
+#undef GTEST_4_TYPENAMES_
+#undef GTEST_5_TYPENAMES_
+#undef GTEST_6_TYPENAMES_
+#undef GTEST_7_TYPENAMES_
+#undef GTEST_8_TYPENAMES_
+#undef GTEST_9_TYPENAMES_
+#undef GTEST_10_TYPENAMES_
+
+#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
+#undef GTEST_BY_REF_
+#undef GTEST_ADD_REF_
+#undef GTEST_TUPLE_ELEMENT_
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-tuple.h.pump b/protobuf/gtest/include/gtest/internal/gtest-tuple.h.pump
new file mode 100644
index 0000000..85ebc80
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-tuple.h.pump
@@ -0,0 +1,336 @@
+$$ -*- mode: c++; -*-
+$var n = 10  $$ Maximum number of tuple fields we want to support.
+$$ This meta comment fixes auto-indentation in Emacs. }}
+// Copyright 2009 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)
+
+// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
+
+#include <utility>  // For ::std::pair.
+
+// The compiler used in Symbian has a bug that prevents us from declaring the
+// tuple template as a friend (it complains that tuple is redefined).  This
+// hack bypasses the bug by declaring the members that should otherwise be
+// private as public.
+// Sun Studio versions < 12 also have the above bug.
+#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
+#else
+#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
+    template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \
+   private:
+#endif
+
+
+$range i 0..n-1
+$range j 0..n
+$range k 1..n
+// GTEST_n_TUPLE_(T) is the type of an n-tuple.
+#define GTEST_0_TUPLE_(T) tuple<>
+
+$for k [[
+$range m 0..k-1
+$range m2 k..n-1
+#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]>
+
+]]
+
+// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
+
+$for j [[
+$range m 0..j-1
+#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
+
+
+]]
+
+// In theory, defining stuff in the ::std namespace is undefined
+// behavior.  We can do this as we are playing the role of a standard
+// library vendor.
+namespace std {
+namespace tr1 {
+
+template <$for i, [[typename T$i = void]]>
+class tuple;
+
+// Anything in namespace gtest_internal is Google Test's INTERNAL
+// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
+namespace gtest_internal {
+
+// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
+template <typename T>
+struct ByRef { typedef const T& type; };  // NOLINT
+template <typename T>
+struct ByRef<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper for ByRef.
+#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
+
+// AddRef<T>::type is T if T is a reference; otherwise it's T&.  This
+// is the same as tr1::add_reference<T>::type.
+template <typename T>
+struct AddRef { typedef T& type; };  // NOLINT
+template <typename T>
+struct AddRef<T&> { typedef T& type; };  // NOLINT
+
+// A handy wrapper for AddRef.
+#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
+
+// A helper for implementing get<k>().
+template <int k> class Get;
+
+// A helper for implementing tuple_element<k, T>.  kIndexValid is true
+// iff k < the number of fields in tuple type T.
+template <bool kIndexValid, int kIndex, class Tuple>
+struct TupleElement;
+
+
+$for i [[
+template <GTEST_$(n)_TYPENAMES_(T)>
+struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T)> [[]]
+{ typedef T$i type; };
+
+
+]]
+}  // namespace gtest_internal
+
+template <>
+class tuple<> {
+ public:
+  tuple() {}
+  tuple(const tuple& /* t */)  {}
+  tuple& operator=(const tuple& /* t */) { return *this; }
+};
+
+
+$for k [[
+$range m 0..k-1
+template <GTEST_$(k)_TYPENAMES_(T)>
+class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
+ public:
+  template <int k> friend class gtest_internal::Get;
+
+  tuple() : $for m, [[f$(m)_()]] {}
+
+  explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
+$for m, [[f$(m)_(f$m)]] {}
+
+  tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
+
+  template <GTEST_$(k)_TYPENAMES_(U)>
+  tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
+
+$if k == 2 [[
+  template <typename U0, typename U1>
+  tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
+
+]]
+
+  tuple& operator=(const tuple& t) { return CopyFrom(t); }
+
+  template <GTEST_$(k)_TYPENAMES_(U)>
+  tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
+    return CopyFrom(t);
+  }
+
+$if k == 2 [[
+  template <typename U0, typename U1>
+  tuple& operator=(const ::std::pair<U0, U1>& p) {
+    f0_ = p.first;
+    f1_ = p.second;
+    return *this;
+  }
+
+]]
+
+  GTEST_DECLARE_TUPLE_AS_FRIEND_
+
+  template <GTEST_$(k)_TYPENAMES_(U)>
+  tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
+
+$for m [[
+    f$(m)_ = t.f$(m)_;
+
+]]
+    return *this;
+  }
+
+
+$for m [[
+  T$m f$(m)_;
+
+]]
+};
+
+
+]]
+// 6.1.3.2 Tuple creation functions.
+
+// Known limitations: we don't support passing an
+// std::tr1::reference_wrapper<T> to make_tuple().  And we don't
+// implement tie().
+
+inline tuple<> make_tuple() { return tuple<>(); }
+
+$for k [[
+$range m 0..k-1
+
+template <GTEST_$(k)_TYPENAMES_(T)>
+inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
+  return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
+}
+
+]]
+
+// 6.1.3.3 Tuple helper classes.
+
+template <typename Tuple> struct tuple_size;
+
+
+$for j [[
+template <GTEST_$(j)_TYPENAMES_(T)>
+struct tuple_size<GTEST_$(j)_TUPLE_(T)> { static const int value = $j; };
+
+
+]]
+template <int k, class Tuple>
+struct tuple_element {
+  typedef typename gtest_internal::TupleElement<
+      k < (tuple_size<Tuple>::value), k, Tuple>::type type;
+};
+
+#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
+
+// 6.1.3.4 Element access.
+
+namespace gtest_internal {
+
+
+$for i [[
+template <>
+class Get<$i> {
+ public:
+  template <class Tuple>
+  static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
+  Field(Tuple& t) { return t.f$(i)_; }  // NOLINT
+
+  template <class Tuple>
+  static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
+  ConstField(const Tuple& t) { return t.f$(i)_; }
+};
+
+
+]]
+}  // namespace gtest_internal
+
+template <int k, GTEST_$(n)_TYPENAMES_(T)>
+GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
+get(GTEST_$(n)_TUPLE_(T)& t) {
+  return gtest_internal::Get<k>::Field(t);
+}
+
+template <int k, GTEST_$(n)_TYPENAMES_(T)>
+GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k,  GTEST_$(n)_TUPLE_(T)))
+get(const GTEST_$(n)_TUPLE_(T)& t) {
+  return gtest_internal::Get<k>::ConstField(t);
+}
+
+// 6.1.3.5 Relational operators
+
+// We only implement == and !=, as we don't have a need for the rest yet.
+
+namespace gtest_internal {
+
+// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
+// first k fields of t1 equals the first k fields of t2.
+// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
+// k1 != k2.
+template <int kSize1, int kSize2>
+struct SameSizeTuplePrefixComparator;
+
+template <>
+struct SameSizeTuplePrefixComparator<0, 0> {
+  template <class Tuple1, class Tuple2>
+  static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
+    return true;
+  }
+};
+
+template <int k>
+struct SameSizeTuplePrefixComparator<k, k> {
+  template <class Tuple1, class Tuple2>
+  static bool Eq(const Tuple1& t1, const Tuple2& t2) {
+    return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
+        ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
+  }
+};
+
+}  // namespace gtest_internal
+
+template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
+inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
+                       const GTEST_$(n)_TUPLE_(U)& u) {
+  return gtest_internal::SameSizeTuplePrefixComparator<
+      tuple_size<GTEST_$(n)_TUPLE_(T)>::value,
+      tuple_size<GTEST_$(n)_TUPLE_(U)>::value>::Eq(t, u);
+}
+
+template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
+inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,
+                       const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }
+
+// 6.1.4 Pairs.
+// Unimplemented.
+
+}  // namespace tr1
+}  // namespace std
+
+
+$for j [[
+#undef GTEST_$(j)_TUPLE_
+
+]]
+
+
+$for j [[
+#undef GTEST_$(j)_TYPENAMES_
+
+]]
+
+#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
+#undef GTEST_BY_REF_
+#undef GTEST_ADD_REF_
+#undef GTEST_TUPLE_ELEMENT_
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-type-util.h b/protobuf/gtest/include/gtest/internal/gtest-type-util.h
new file mode 100644
index 0000000..093eee6
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-type-util.h
@@ -0,0 +1,3321 @@
+// This file was GENERATED by command:
+//     pump.py gtest-type-util.h.pump
+// DO NOT EDIT BY HAND!!!
+
+// 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)
+
+// Type utilities needed for implementing typed and type-parameterized
+// tests.  This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// Currently we support at most 50 types in a list, and at most 50
+// type-parameterized tests in one type-parameterized test case.
+// Please contact googletestframework@googlegroups.com if you need
+// more.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+
+#include <gtest/internal/gtest-port.h>
+#include <gtest/internal/gtest-string.h>
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// #ifdef __GNUC__ is too general here.  It is possible to use gcc without using
+// libstdc++ (which is where cxxabi.h comes from).
+#ifdef __GLIBCXX__
+#include <cxxabi.h>
+#endif  // __GLIBCXX__
+
+namespace testing {
+namespace internal {
+
+// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
+// type.  This can be used as a compile-time assertion to ensure that
+// two types are equal.
+
+template <typename T1, typename T2>
+struct AssertTypeEq;
+
+template <typename T>
+struct AssertTypeEq<T, T> {
+  typedef bool type;
+};
+
+// GetTypeName<T>() returns a human-readable name of type T.
+template <typename T>
+String GetTypeName() {
+#if GTEST_HAS_RTTI
+
+  const char* const name = typeid(T).name();
+#ifdef __GLIBCXX__
+  int status = 0;
+  // gcc's implementation of typeid(T).name() mangles the type name,
+  // so we have to demangle it.
+  char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status);
+  const String name_str(status == 0 ? readable_name : name);
+  free(readable_name);
+  return name_str;
+#else
+  return name;
+#endif  // __GLIBCXX__
+
+#else
+  return "<type>";
+#endif  // GTEST_HAS_RTTI
+}
+
+// A unique type used as the default value for the arguments of class
+// template Types.  This allows us to simulate variadic templates
+// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
+// support directly.
+struct None {};
+
+// The following family of struct and struct templates are used to
+// represent type lists.  In particular, TypesN<T1, T2, ..., TN>
+// represents a type list with N types (T1, T2, ..., and TN) in it.
+// Except for Types0, every struct in the family has two member types:
+// Head for the first type in the list, and Tail for the rest of the
+// list.
+
+// The empty type list.
+struct Types0 {};
+
+// Type lists of length 1, 2, 3, and so on.
+
+template <typename T1>
+struct Types1 {
+  typedef T1 Head;
+  typedef Types0 Tail;
+};
+template <typename T1, typename T2>
+struct Types2 {
+  typedef T1 Head;
+  typedef Types1<T2> Tail;
+};
+
+template <typename T1, typename T2, typename T3>
+struct Types3 {
+  typedef T1 Head;
+  typedef Types2<T2, T3> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4>
+struct Types4 {
+  typedef T1 Head;
+  typedef Types3<T2, T3, T4> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+struct Types5 {
+  typedef T1 Head;
+  typedef Types4<T2, T3, T4, T5> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+struct Types6 {
+  typedef T1 Head;
+  typedef Types5<T2, T3, T4, T5, T6> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+struct Types7 {
+  typedef T1 Head;
+  typedef Types6<T2, T3, T4, T5, T6, T7> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+struct Types8 {
+  typedef T1 Head;
+  typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+struct Types9 {
+  typedef T1 Head;
+  typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+struct Types10 {
+  typedef T1 Head;
+  typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+struct Types11 {
+  typedef T1 Head;
+  typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+struct Types12 {
+  typedef T1 Head;
+  typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+struct Types13 {
+  typedef T1 Head;
+  typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+struct Types14 {
+  typedef T1 Head;
+  typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+struct Types15 {
+  typedef T1 Head;
+  typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+struct Types16 {
+  typedef T1 Head;
+  typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+struct Types17 {
+  typedef T1 Head;
+  typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+struct Types18 {
+  typedef T1 Head;
+  typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+struct Types19 {
+  typedef T1 Head;
+  typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+struct Types20 {
+  typedef T1 Head;
+  typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+struct Types21 {
+  typedef T1 Head;
+  typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+struct Types22 {
+  typedef T1 Head;
+  typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+struct Types23 {
+  typedef T1 Head;
+  typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+struct Types24 {
+  typedef T1 Head;
+  typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+struct Types25 {
+  typedef T1 Head;
+  typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+struct Types26 {
+  typedef T1 Head;
+  typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+struct Types27 {
+  typedef T1 Head;
+  typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+struct Types28 {
+  typedef T1 Head;
+  typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+struct Types29 {
+  typedef T1 Head;
+  typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+struct Types30 {
+  typedef T1 Head;
+  typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+struct Types31 {
+  typedef T1 Head;
+  typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+struct Types32 {
+  typedef T1 Head;
+  typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+struct Types33 {
+  typedef T1 Head;
+  typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+struct Types34 {
+  typedef T1 Head;
+  typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+struct Types35 {
+  typedef T1 Head;
+  typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+struct Types36 {
+  typedef T1 Head;
+  typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+struct Types37 {
+  typedef T1 Head;
+  typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+struct Types38 {
+  typedef T1 Head;
+  typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+struct Types39 {
+  typedef T1 Head;
+  typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+struct Types40 {
+  typedef T1 Head;
+  typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+struct Types41 {
+  typedef T1 Head;
+  typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+struct Types42 {
+  typedef T1 Head;
+  typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+struct Types43 {
+  typedef T1 Head;
+  typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+struct Types44 {
+  typedef T1 Head;
+  typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+struct Types45 {
+  typedef T1 Head;
+  typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+struct Types46 {
+  typedef T1 Head;
+  typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+struct Types47 {
+  typedef T1 Head;
+  typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+struct Types48 {
+  typedef T1 Head;
+  typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+struct Types49 {
+  typedef T1 Head;
+  typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48, T49> Tail;
+};
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+struct Types50 {
+  typedef T1 Head;
+  typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+      T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+      T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+      T44, T45, T46, T47, T48, T49, T50> Tail;
+};
+
+
+}  // namespace internal
+
+// We don't want to require the users to write TypesN<...> directly,
+// as that would require them to count the length.  Types<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Types<int>
+// will appear as Types<int, None, None, ..., None> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Types<T1, ..., TN>, and Google Test will translate
+// that to TypesN<T1, ..., TN> internally to make error messages
+// readable.  The translation is done by the 'type' member of the
+// Types template.
+template <typename T1 = internal::None, typename T2 = internal::None,
+    typename T3 = internal::None, typename T4 = internal::None,
+    typename T5 = internal::None, typename T6 = internal::None,
+    typename T7 = internal::None, typename T8 = internal::None,
+    typename T9 = internal::None, typename T10 = internal::None,
+    typename T11 = internal::None, typename T12 = internal::None,
+    typename T13 = internal::None, typename T14 = internal::None,
+    typename T15 = internal::None, typename T16 = internal::None,
+    typename T17 = internal::None, typename T18 = internal::None,
+    typename T19 = internal::None, typename T20 = internal::None,
+    typename T21 = internal::None, typename T22 = internal::None,
+    typename T23 = internal::None, typename T24 = internal::None,
+    typename T25 = internal::None, typename T26 = internal::None,
+    typename T27 = internal::None, typename T28 = internal::None,
+    typename T29 = internal::None, typename T30 = internal::None,
+    typename T31 = internal::None, typename T32 = internal::None,
+    typename T33 = internal::None, typename T34 = internal::None,
+    typename T35 = internal::None, typename T36 = internal::None,
+    typename T37 = internal::None, typename T38 = internal::None,
+    typename T39 = internal::None, typename T40 = internal::None,
+    typename T41 = internal::None, typename T42 = internal::None,
+    typename T43 = internal::None, typename T44 = internal::None,
+    typename T45 = internal::None, typename T46 = internal::None,
+    typename T47 = internal::None, typename T48 = internal::None,
+    typename T49 = internal::None, typename T50 = internal::None>
+struct Types {
+  typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type;
+};
+
+template <>
+struct Types<internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types0 type;
+};
+template <typename T1>
+struct Types<T1, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types1<T1> type;
+};
+template <typename T1, typename T2>
+struct Types<T1, T2, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types2<T1, T2> type;
+};
+template <typename T1, typename T2, typename T3>
+struct Types<T1, T2, T3, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types3<T1, T2, T3> type;
+};
+template <typename T1, typename T2, typename T3, typename T4>
+struct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types4<T1, T2, T3, T4> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+struct Types<T1, T2, T3, T4, T5, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types5<T1, T2, T3, T4, T5> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6>
+struct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types6<T1, T2, T3, T4, T5, T6> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7>
+struct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
+      T12> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
+      T26> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
+      T40> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None, internal::None> {
+  typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None, internal::None> {
+  typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    internal::None, internal::None, internal::None, internal::None,
+    internal::None> {
+  typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, internal::None, internal::None, internal::None, internal::None> {
+  typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, internal::None, internal::None, internal::None> {
+  typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, T48, internal::None, internal::None> {
+  typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48> type;
+};
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49>
+struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15,
+    T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
+    T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45,
+    T46, T47, T48, T49, internal::None> {
+  typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49> type;
+};
+
+namespace internal {
+
+#define GTEST_TEMPLATE_ template <typename T> class
+
+// The template "selector" struct TemplateSel<Tmpl> is used to
+// represent Tmpl, which must be a class template with one type
+// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined
+// as the type Tmpl<T>.  This allows us to actually instantiate the
+// template "selected" by TemplateSel<Tmpl>.
+//
+// This trick is necessary for simulating typedef for class templates,
+// which C++ doesn't support directly.
+template <GTEST_TEMPLATE_ Tmpl>
+struct TemplateSel {
+  template <typename T>
+  struct Bind {
+    typedef Tmpl<T> type;
+  };
+};
+
+#define GTEST_BIND_(TmplSel, T) \
+  TmplSel::template Bind<T>::type
+
+// A unique struct template used as the default value for the
+// arguments of class template Templates.  This allows us to simulate
+// variadic templates (e.g. Templates<int>, Templates<int, double>,
+// and etc), which C++ doesn't support directly.
+template <typename T>
+struct NoneT {};
+
+// The following family of struct and struct templates are used to
+// represent template lists.  In particular, TemplatesN<T1, T2, ...,
+// TN> represents a list of N templates (T1, T2, ..., and TN).  Except
+// for Templates0, every struct in the family has two member types:
+// Head for the selector of the first template in the list, and Tail
+// for the rest of the list.
+
+// The empty template list.
+struct Templates0 {};
+
+// Template lists of length 1, 2, 3, and so on.
+
+template <GTEST_TEMPLATE_ T1>
+struct Templates1 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates0 Tail;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>
+struct Templates2 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates1<T2> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>
+struct Templates3 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates2<T2, T3> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4>
+struct Templates4 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates3<T2, T3, T4> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>
+struct Templates5 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates4<T2, T3, T4, T5> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>
+struct Templates6 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates5<T2, T3, T4, T5, T6> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7>
+struct Templates7 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates6<T2, T3, T4, T5, T6, T7> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>
+struct Templates8 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>
+struct Templates9 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10>
+struct Templates10 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>
+struct Templates11 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>
+struct Templates12 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13>
+struct Templates13 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>
+struct Templates14 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>
+struct Templates15 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16>
+struct Templates16 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>
+struct Templates17 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>
+struct Templates18 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19>
+struct Templates19 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>
+struct Templates20 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>
+struct Templates21 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22>
+struct Templates22 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>
+struct Templates23 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>
+struct Templates24 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25>
+struct Templates25 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>
+struct Templates26 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>
+struct Templates27 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28>
+struct Templates28 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>
+struct Templates29 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>
+struct Templates30 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31>
+struct Templates31 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>
+struct Templates32 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>
+struct Templates33 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34>
+struct Templates34 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>
+struct Templates35 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>
+struct Templates36 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37>
+struct Templates37 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>
+struct Templates38 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>
+struct Templates39 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40>
+struct Templates40 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>
+struct Templates41 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>
+struct Templates42 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43>
+struct Templates43 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>
+struct Templates44 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>
+struct Templates45 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46>
+struct Templates46 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>
+struct Templates47 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>
+struct Templates48 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49>
+struct Templates49 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48, T49> Tail;
+};
+
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50>
+struct Templates50 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+      T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+      T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
+      T43, T44, T45, T46, T47, T48, T49, T50> Tail;
+};
+
+
+// We don't want to require the users to write TemplatesN<...> directly,
+// as that would require them to count the length.  Templates<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Templates<list>
+// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Templates<T1, ..., TN>, and Google Test will translate
+// that to TemplatesN<T1, ..., TN> internally to make error messages
+// readable.  The translation is done by the 'type' member of the
+// Templates template.
+template <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT,
+    GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT,
+    GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT,
+    GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT,
+    GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT,
+    GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT,
+    GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT,
+    GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT,
+    GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT,
+    GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT,
+    GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT,
+    GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT,
+    GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT,
+    GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT,
+    GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT,
+    GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT,
+    GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT,
+    GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT,
+    GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT,
+    GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT,
+    GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT,
+    GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT,
+    GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT,
+    GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT,
+    GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT>
+struct Templates {
+  typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48, T49, T50> type;
+};
+
+template <>
+struct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates0 type;
+};
+template <GTEST_TEMPLATE_ T1>
+struct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates1<T1> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2>
+struct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates2<T1, T2> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3>
+struct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates3<T1, T2, T3> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4>
+struct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates4<T1, T2, T3, T4> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5>
+struct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates5<T1, T2, T3, T4, T5> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6>
+struct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates6<T1, T2, T3, T4, T5, T6> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT> {
+  typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT> {
+  typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT> {
+  typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, NoneT, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, NoneT, NoneT, NoneT, NoneT> {
+  typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, NoneT, NoneT, NoneT> {
+  typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, T48, NoneT, NoneT> {
+  typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48> type;
+};
+template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3,
+    GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6,
+    GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9,
+    GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12,
+    GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15,
+    GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18,
+    GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21,
+    GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24,
+    GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27,
+    GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30,
+    GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33,
+    GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36,
+    GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39,
+    GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42,
+    GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45,
+    GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48,
+    GTEST_TEMPLATE_ T49>
+struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14,
+    T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29,
+    T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44,
+    T45, T46, T47, T48, T49, NoneT> {
+  typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+      T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
+      T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
+      T42, T43, T44, T45, T46, T47, T48, T49> type;
+};
+
+// The TypeList template makes it possible to use either a single type
+// or a Types<...> list in TYPED_TEST_CASE() and
+// INSTANTIATE_TYPED_TEST_CASE_P().
+
+template <typename T>
+struct TypeList { typedef Types1<T> type; };
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+    typename T6, typename T7, typename T8, typename T9, typename T10,
+    typename T11, typename T12, typename T13, typename T14, typename T15,
+    typename T16, typename T17, typename T18, typename T19, typename T20,
+    typename T21, typename T22, typename T23, typename T24, typename T25,
+    typename T26, typename T27, typename T28, typename T29, typename T30,
+    typename T31, typename T32, typename T33, typename T34, typename T35,
+    typename T36, typename T37, typename T38, typename T39, typename T40,
+    typename T41, typename T42, typename T43, typename T44, typename T45,
+    typename T46, typename T47, typename T48, typename T49, typename T50>
+struct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
+    T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
+    T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
+    T44, T45, T46, T47, T48, T49, T50> > {
+  typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
+      T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
+      T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
+      T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type;
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
diff --git a/protobuf/gtest/include/gtest/internal/gtest-type-util.h.pump b/protobuf/gtest/include/gtest/internal/gtest-type-util.h.pump
new file mode 100644
index 0000000..5aed1e5
--- /dev/null
+++ b/protobuf/gtest/include/gtest/internal/gtest-type-util.h.pump
@@ -0,0 +1,287 @@
+$$ -*- mode: c++; -*-
+$var n = 50  $$ Maximum length of type lists we want to support.
+// 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)
+
+// Type utilities needed for implementing typed and type-parameterized
+// tests.  This file is generated by a SCRIPT.  DO NOT EDIT BY HAND!
+//
+// Currently we support at most $n types in a list, and at most $n
+// type-parameterized tests in one type-parameterized test case.
+// Please contact googletestframework@googlegroups.com if you need
+// more.
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
+
+#include <gtest/internal/gtest-port.h>
+#include <gtest/internal/gtest-string.h>
+
+#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+// #ifdef __GNUC__ is too general here.  It is possible to use gcc without using
+// libstdc++ (which is where cxxabi.h comes from).
+#ifdef __GLIBCXX__
+#include <cxxabi.h>
+#endif  // __GLIBCXX__
+
+namespace testing {
+namespace internal {
+
+// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
+// type.  This can be used as a compile-time assertion to ensure that
+// two types are equal.
+
+template <typename T1, typename T2>
+struct AssertTypeEq;
+
+template <typename T>
+struct AssertTypeEq<T, T> {
+  typedef bool type;
+};
+
+// GetTypeName<T>() returns a human-readable name of type T.
+template <typename T>
+String GetTypeName() {
+#if GTEST_HAS_RTTI
+
+  const char* const name = typeid(T).name();
+#ifdef __GLIBCXX__
+  int status = 0;
+  // gcc's implementation of typeid(T).name() mangles the type name,
+  // so we have to demangle it.
+  char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status);
+  const String name_str(status == 0 ? readable_name : name);
+  free(readable_name);
+  return name_str;
+#else
+  return name;
+#endif  // __GLIBCXX__
+
+#else
+  return "<type>";
+#endif  // GTEST_HAS_RTTI
+}
+
+// A unique type used as the default value for the arguments of class
+// template Types.  This allows us to simulate variadic templates
+// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
+// support directly.
+struct None {};
+
+// The following family of struct and struct templates are used to
+// represent type lists.  In particular, TypesN<T1, T2, ..., TN>
+// represents a type list with N types (T1, T2, ..., and TN) in it.
+// Except for Types0, every struct in the family has two member types:
+// Head for the first type in the list, and Tail for the rest of the
+// list.
+
+// The empty type list.
+struct Types0 {};
+
+// Type lists of length 1, 2, 3, and so on.
+
+template <typename T1>
+struct Types1 {
+  typedef T1 Head;
+  typedef Types0 Tail;
+};
+
+$range i 2..n
+
+$for i [[
+$range j 1..i
+$range k 2..i
+template <$for j, [[typename T$j]]>
+struct Types$i {
+  typedef T1 Head;
+  typedef Types$(i-1)<$for k, [[T$k]]> Tail;
+};
+
+
+]]
+
+}  // namespace internal
+
+// We don't want to require the users to write TypesN<...> directly,
+// as that would require them to count the length.  Types<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Types<int>
+// will appear as Types<int, None, None, ..., None> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Types<T1, ..., TN>, and Google Test will translate
+// that to TypesN<T1, ..., TN> internally to make error messages
+// readable.  The translation is done by the 'type' member of the
+// Types template.
+
+$range i 1..n
+template <$for i, [[typename T$i = internal::None]]>
+struct Types {
+  typedef internal::Types$n<$for i, [[T$i]]> type;
+};
+
+template <>
+struct Types<$for i, [[internal::None]]> {
+  typedef internal::Types0 type;
+};
+
+$range i 1..n-1
+$for i [[
+$range j 1..i
+$range k i+1..n
+template <$for j, [[typename T$j]]>
+struct Types<$for j, [[T$j]]$for k[[, internal::None]]> {
+  typedef internal::Types$i<$for j, [[T$j]]> type;
+};
+
+]]
+
+namespace internal {
+
+#define GTEST_TEMPLATE_ template <typename T> class
+
+// The template "selector" struct TemplateSel<Tmpl> is used to
+// represent Tmpl, which must be a class template with one type
+// parameter, as a type.  TemplateSel<Tmpl>::Bind<T>::type is defined
+// as the type Tmpl<T>.  This allows us to actually instantiate the
+// template "selected" by TemplateSel<Tmpl>.
+//
+// This trick is necessary for simulating typedef for class templates,
+// which C++ doesn't support directly.
+template <GTEST_TEMPLATE_ Tmpl>
+struct TemplateSel {
+  template <typename T>
+  struct Bind {
+    typedef Tmpl<T> type;
+  };
+};
+
+#define GTEST_BIND_(TmplSel, T) \
+  TmplSel::template Bind<T>::type
+
+// A unique struct template used as the default value for the
+// arguments of class template Templates.  This allows us to simulate
+// variadic templates (e.g. Templates<int>, Templates<int, double>,
+// and etc), which C++ doesn't support directly.
+template <typename T>
+struct NoneT {};
+
+// The following family of struct and struct templates are used to
+// represent template lists.  In particular, TemplatesN<T1, T2, ...,
+// TN> represents a list of N templates (T1, T2, ..., and TN).  Except
+// for Templates0, every struct in the family has two member types:
+// Head for the selector of the first template in the list, and Tail
+// for the rest of the list.
+
+// The empty template list.
+struct Templates0 {};
+
+// Template lists of length 1, 2, 3, and so on.
+
+template <GTEST_TEMPLATE_ T1>
+struct Templates1 {
+  typedef TemplateSel<T1> Head;
+  typedef Templates0 Tail;
+};
+
+$range i 2..n
+
+$for i [[
+$range j 1..i
+$range k 2..i
+template <$for j, [[GTEST_TEMPLATE_ T$j]]>
+struct Templates$i {
+  typedef TemplateSel<T1> Head;
+  typedef Templates$(i-1)<$for k, [[T$k]]> Tail;
+};
+
+
+]]
+
+// We don't want to require the users to write TemplatesN<...> directly,
+// as that would require them to count the length.  Templates<...> is much
+// easier to write, but generates horrible messages when there is a
+// compiler error, as gcc insists on printing out each template
+// argument, even if it has the default value (this means Templates<list>
+// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler
+// errors).
+//
+// Our solution is to combine the best part of the two approaches: a
+// user would write Templates<T1, ..., TN>, and Google Test will translate
+// that to TemplatesN<T1, ..., TN> internally to make error messages
+// readable.  The translation is done by the 'type' member of the
+// Templates template.
+
+$range i 1..n
+template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]>
+struct Templates {
+  typedef Templates$n<$for i, [[T$i]]> type;
+};
+
+template <>
+struct Templates<$for i, [[NoneT]]> {
+  typedef Templates0 type;
+};
+
+$range i 1..n-1
+$for i [[
+$range j 1..i
+$range k i+1..n
+template <$for j, [[GTEST_TEMPLATE_ T$j]]>
+struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> {
+  typedef Templates$i<$for j, [[T$j]]> type;
+};
+
+]]
+
+// The TypeList template makes it possible to use either a single type
+// or a Types<...> list in TYPED_TEST_CASE() and
+// INSTANTIATE_TYPED_TEST_CASE_P().
+
+template <typename T>
+struct TypeList { typedef Types1<T> type; };
+
+
+$range i 1..n
+template <$for i, [[typename T$i]]>
+struct TypeList<Types<$for i, [[T$i]]> > {
+  typedef typename Types<$for i, [[T$i]]>::type type;
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
+
+#endif  // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
diff --git a/protobuf/gtest/m4/acx_pthread.m4 b/protobuf/gtest/m4/acx_pthread.m4
new file mode 100644
index 0000000..2cf20de
--- /dev/null
+++ b/protobuf/gtest/m4/acx_pthread.m4
@@ -0,0 +1,363 @@
+# This was retrieved from
+#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
+# See also (perhaps for new versions?)
+#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
+#
+# We've rewritten the inconsistency check code (from avahi), to work
+# more broadly.  In particular, it no longer assumes ld accepts -zdefs.
+# This caused a restructing of the code, but the functionality has only
+# changed a little.
+
+dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+dnl
+dnl @summary figure out how to build C programs using POSIX threads
+dnl
+dnl This macro figures out how to build C programs using POSIX threads.
+dnl It sets the PTHREAD_LIBS output variable to the threads library and
+dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
+dnl C compiler flags that are needed. (The user can also force certain
+dnl compiler flags/libs to be tested by setting these environment
+dnl variables.)
+dnl
+dnl Also sets PTHREAD_CC to any special C compiler that is needed for
+dnl multi-threaded programs (defaults to the value of CC otherwise).
+dnl (This is necessary on AIX to use the special cc_r compiler alias.)
+dnl
+dnl NOTE: You are assumed to not only compile your program with these
+dnl flags, but also link it with them as well. e.g. you should link
+dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
+dnl $LIBS
+dnl
+dnl If you are only building threads programs, you may wish to use
+dnl these variables in your default LIBS, CFLAGS, and CC:
+dnl
+dnl        LIBS="$PTHREAD_LIBS $LIBS"
+dnl        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+dnl        CC="$PTHREAD_CC"
+dnl
+dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
+dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
+dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+dnl
+dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
+dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
+dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
+dnl default action will define HAVE_PTHREAD.
+dnl
+dnl Please let the authors know if this macro fails on any platform, or
+dnl if you have any other suggestions or comments. This macro was based
+dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
+dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
+dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
+dnl We are also grateful for the helpful feedback of numerous users.
+dnl
+dnl @category InstalledPackages
+dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
+dnl @version 2006-05-29
+dnl @license GPLWithACException
+dnl 
+dnl Checks for GCC shared/pthread inconsistency based on work by
+dnl Marcin Owsiany <marcin@owsiany.pl>
+
+
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+		pthread-config)
+		AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
+		if test x"$acx_pthread_config" = xno; then continue; fi
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_TRY_LINK([#include <pthread.h>],
+                    [pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+                    [acx_pthread_ok=yes])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	AC_MSG_CHECKING([for joinable pthread attribute])
+	attr_name=unknown
+	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+	    AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
+                        [attr_name=$attr; break])
+	done
+        AC_MSG_RESULT($attr_name)
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        AC_MSG_RESULT(${flag})
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+        # More AIX lossage: must compile with xlc_r or cc_r
+	if test x"$GCC" != xyes; then
+          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+        else
+          PTHREAD_CC=$CC
+	fi
+
+	# The next part tries to detect GCC inconsistency with -shared on some
+	# architectures and systems. The problem is that in certain
+	# configurations, when -shared is specified, GCC "forgets" to
+	# internally use various flags which are still necessary.
+	
+	#
+	# Prepare the flags
+	#
+	save_CFLAGS="$CFLAGS"
+	save_LIBS="$LIBS"
+	save_CC="$CC"
+	
+	# Try with the flags determined by the earlier checks.
+	#
+	# -Wl,-z,defs forces link-time symbol resolution, so that the
+	# linking checks with -shared actually have any value
+	#
+	# FIXME: -fPIC is required for -shared on many architectures,
+	# so we specify it here, but the right way would probably be to
+	# properly detect whether it is actually required.
+	CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+	CC="$PTHREAD_CC"
+	
+	# In order not to create several levels of indentation, we test
+	# the value of "$done" until we find the cure or run out of ideas.
+	done="no"
+	
+	# First, make sure the CFLAGS we added are actually accepted by our
+	# compiler.  If not (and OS X's ld, for instance, does not accept -z),
+	# then we can't do this test.
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
+	   AC_TRY_LINK(,, , [done=yes])
+	
+	   if test "x$done" = xyes ; then
+	      AC_MSG_RESULT([no])
+	   else
+	      AC_MSG_RESULT([yes])
+	   fi
+	fi
+	
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes])
+	   
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	
+	#
+	# Linux gcc on some architectures such as mips/mipsel forgets
+	# about -lpthread
+	#
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lpthread fixes that])
+	   LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes])
+	
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	#
+	# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
+	#
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lc_r fixes that])
+	   LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	       [pthread_t th; pthread_join(th, 0);
+	        pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	        pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	       [done=yes])
+	
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	if test x"$done" = xno; then
+	   # OK, we have run out of ideas
+	   AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
+	
+	   # so it's not safe to assume that we may use pthreads
+	   acx_pthread_ok=no
+	fi
+	
+	CFLAGS="$save_CFLAGS"
+	LIBS="$save_LIBS"
+	CC="$save_CC"
+else
+        PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        :
+else
+        acx_pthread_ok=no
+        $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD
diff --git a/protobuf/gtest/m4/gtest.m4 b/protobuf/gtest/m4/gtest.m4
new file mode 100644
index 0000000..6598ba7
--- /dev/null
+++ b/protobuf/gtest/m4/gtest.m4
@@ -0,0 +1,74 @@
+dnl GTEST_LIB_CHECK([minimum version [,
+dnl                  action if found [,action if not found]]])
+dnl
+dnl Check for the presence of the Google Test library, optionally at a minimum
+dnl version, and indicate a viable version with the HAVE_GTEST flag. It defines
+dnl standard variables for substitution including GTEST_CPPFLAGS,
+dnl GTEST_CXXFLAGS, GTEST_LDFLAGS, and GTEST_LIBS. It also defines
+dnl GTEST_VERSION as the version of Google Test found. Finally, it provides
+dnl optional custom action slots in the event GTEST is found or not.
+AC_DEFUN([GTEST_LIB_CHECK],
+[
+dnl Provide a flag to enable or disable Google Test usage.
+AC_ARG_ENABLE([gtest],
+  [AS_HELP_STRING([--enable-gtest],
+                  [Enable tests using the Google C++ Testing Framework.
+                  (Default is enabled.)])],
+  [],
+  [enable_gtest=])
+AC_ARG_VAR([GTEST_CONFIG],
+           [The exact path of Google Test's 'gtest-config' script.])
+AC_ARG_VAR([GTEST_CPPFLAGS],
+           [C-like preprocessor flags for Google Test.])
+AC_ARG_VAR([GTEST_CXXFLAGS],
+           [C++ compile flags for Google Test.])
+AC_ARG_VAR([GTEST_LDFLAGS],
+           [Linker path and option flags for Google Test.])
+AC_ARG_VAR([GTEST_LIBS],
+           [Library linking flags for Google Test.])
+AC_ARG_VAR([GTEST_VERSION],
+           [The version of Google Test available.])
+HAVE_GTEST="no"
+AS_IF([test "x${enable_gtest}" != "xno"],
+  [AC_MSG_CHECKING([for 'gtest-config'])
+   AS_IF([test "x${enable_gtest}" != "xyes"],
+     [AS_IF([test -x "${enable_gtest}/scripts/gtest-config"],
+        [GTEST_CONFIG="${enable_gtest}/scripts/gtest-config"],
+        [GTEST_CONFIG="${enable_gtest}/bin/gtest-config"])
+      AS_IF([test -x "${GTEST_CONFIG}"], [],
+        [AC_MSG_RESULT([no])
+         AC_MSG_ERROR([dnl
+Unable to locate either a built or installed Google Test.
+The specific location '${enable_gtest}' was provided for a built or installed
+Google Test, but no 'gtest-config' script could be found at this location.])
+         ])],
+     [AC_PATH_PROG([GTEST_CONFIG], [gtest-config])])
+   AS_IF([test -x "${GTEST_CONFIG}"],
+     [AC_MSG_RESULT([${GTEST_CONFIG}])
+      m4_ifval([$1],
+        [_gtest_min_version="--min-version=$1"
+         AC_MSG_CHECKING([for Google Test at least version >= $1])],
+        [_gtest_min_version="--min-version=0"
+         AC_MSG_CHECKING([for Google Test])])
+      AS_IF([${GTEST_CONFIG} ${_gtest_min_version}],
+        [AC_MSG_RESULT([yes])
+         HAVE_GTEST='yes'],
+        [AC_MSG_RESULT([no])])],
+     [AC_MSG_RESULT([no])])
+   AS_IF([test "x${HAVE_GTEST}" = "xyes"],
+     [GTEST_CPPFLAGS=`${GTEST_CONFIG} --cppflags`
+      GTEST_CXXFLAGS=`${GTEST_CONFIG} --cxxflags`
+      GTEST_LDFLAGS=`${GTEST_CONFIG} --ldflags`
+      GTEST_LIBS=`${GTEST_CONFIG} --libs`
+      GTEST_VERSION=`${GTEST_CONFIG} --version`
+      AC_DEFINE([HAVE_GTEST],[1],[Defined when Google Test is available.])],
+     [AS_IF([test "x${enable_gtest}" = "xyes"],
+        [AC_MSG_ERROR([dnl
+Google Test was enabled, but no viable version could be found.])
+         ])])])
+AC_SUBST([HAVE_GTEST])
+AM_CONDITIONAL([HAVE_GTEST],[test "x$HAVE_GTEST" = "xyes"])
+AS_IF([test "x$HAVE_GTEST" = "xyes"],
+  [m4_ifval([$2], [$2])],
+  [m4_ifval([$3], [$3])])
+])
diff --git a/protobuf/gtest/make/Makefile b/protobuf/gtest/make/Makefile
new file mode 100644
index 0000000..5b27b6a
--- /dev/null
+++ b/protobuf/gtest/make/Makefile
@@ -0,0 +1,80 @@
+# A sample Makefile for building Google Test and using it in user
+# tests.  Please tweak it to suit your environment and project.  You
+# may want to move it to your project's root directory.
+#
+# SYNOPSIS:
+#
+#   make [all]  - makes everything.
+#   make TARGET - makes the given target.
+#   make clean  - removes all files generated by make.
+
+# Please tweak the following variable definitions as needed by your
+# project, except GTEST_HEADERS, which you can use in your own targets
+# but shouldn't modify.
+
+# Points to the root of Google Test, relative to where this file is.
+# Remember to tweak this if you move this file.
+GTEST_DIR = ..
+
+# Where to find user code.
+USER_DIR = ../samples
+
+# Flags passed to the preprocessor.
+CPPFLAGS += -I$(GTEST_DIR)/include
+
+# Flags passed to the C++ compiler.
+CXXFLAGS += -g -Wall -Wextra
+
+# All tests produced by this Makefile.  Remember to add new tests you
+# created to the list.
+TESTS = sample1_unittest
+
+# All Google Test headers.  Usually you shouldn't change this
+# definition.
+GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
+                $(GTEST_DIR)/include/gtest/internal/*.h
+
+# House-keeping build targets.
+
+all : $(TESTS)
+
+clean :
+	rm -f $(TESTS) gtest.a gtest_main.a *.o
+
+# Builds gtest.a and gtest_main.a.
+
+# Usually you shouldn't tweak such internal variables, indicated by a
+# trailing _.
+GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)
+
+# For simplicity and to avoid depending on Google Test's
+# implementation details, the dependencies specified below are
+# conservative and not optimized.  This is fine as Google Test
+# compiles fast and for ordinary users its source rarely changes.
+gtest-all.o : $(GTEST_SRCS_)
+	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
+            $(GTEST_DIR)/src/gtest-all.cc
+
+gtest_main.o : $(GTEST_SRCS_)
+	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
+            $(GTEST_DIR)/src/gtest_main.cc
+
+gtest.a : gtest-all.o
+	$(AR) $(ARFLAGS) $@ $^
+
+gtest_main.a : gtest-all.o gtest_main.o
+	$(AR) $(ARFLAGS) $@ $^
+
+# Builds a sample test.  A test should link with either gtest.a or
+# gtest_main.a, depending on whether it defines its own main()
+# function.
+
+sample1.o : $(USER_DIR)/sample1.cc $(USER_DIR)/sample1.h $(GTEST_HEADERS)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1.cc
+
+sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \
+                     $(USER_DIR)/sample1.h $(GTEST_HEADERS)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc
+
+sample1_unittest : sample1.o sample1_unittest.o gtest_main.a
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@
diff --git a/protobuf/gtest/msvc/gtest-md.sln b/protobuf/gtest/msvc/gtest-md.sln
new file mode 100755
index 0000000..f7908da
--- /dev/null
+++ b/protobuf/gtest/msvc/gtest-md.sln
@@ -0,0 +1,45 @@
+Microsoft Visual Studio Solution File, Format Version 8.00

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-md", "gtest-md.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}"

+	ProjectSection(ProjectDependencies) = postProject

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main-md", "gtest_main-md.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862033}"

+	ProjectSection(ProjectDependencies) = postProject

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test-md", "gtest_prod_test-md.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}"

+	ProjectSection(ProjectDependencies) = postProject

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest-md", "gtest_unittest-md.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}"

+	ProjectSection(ProjectDependencies) = postProject

+	EndProjectSection

+EndProject

+Global

+	GlobalSection(SolutionConfiguration) = preSolution

+		Debug = Debug

+		Release = Release

+	EndGlobalSection

+	GlobalSection(ProjectConfiguration) = postSolution

+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.ActiveCfg = Debug|Win32

+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Debug.Build.0 = Debug|Win32

+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.ActiveCfg = Release|Win32

+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}.Release.Build.0 = Release|Win32

+		{3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.ActiveCfg = Debug|Win32

+		{3AF54C8A-10BF-4332-9147-F68ED9862033}.Debug.Build.0 = Debug|Win32

+		{3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.ActiveCfg = Release|Win32

+		{3AF54C8A-10BF-4332-9147-F68ED9862033}.Release.Build.0 = Release|Win32

+		{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.ActiveCfg = Debug|Win32

+		{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Debug.Build.0 = Debug|Win32

+		{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.ActiveCfg = Release|Win32

+		{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}.Release.Build.0 = Release|Win32

+		{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.ActiveCfg = Debug|Win32

+		{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Debug.Build.0 = Debug|Win32

+		{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.ActiveCfg = Release|Win32

+		{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}.Release.Build.0 = Release|Win32

+	EndGlobalSection

+	GlobalSection(ExtensibilityGlobals) = postSolution

+	EndGlobalSection

+	GlobalSection(ExtensibilityAddIns) = postSolution

+	EndGlobalSection

+EndGlobal

diff --git a/protobuf/gtest/msvc/gtest-md.vcproj b/protobuf/gtest/msvc/gtest-md.vcproj
new file mode 100755
index 0000000..c78a4a4
--- /dev/null
+++ b/protobuf/gtest/msvc/gtest-md.vcproj
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="7.10"

+	Name="gtest-md"

+	ProjectGUID="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}"

+	Keyword="Win32Proj">

+	<Platforms>

+		<Platform

+			Name="Win32"/>

+	</Platforms>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="4"

+			CharacterSet="2"

+			ReferencesPath="">

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"

+				MinimalRebuild="TRUE"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="4"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)/gtestd.lib"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="4"

+			CharacterSet="2"

+			ReferencesPath="&quot;..\include&quot;;&quot;..&quot;">

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="3"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)/gtest.lib"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">

+			<File

+				RelativePath="..\src\gtest-death-test.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\gtest-filepath.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\gtest-port.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\gtest-test-part.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\gtest-typed-test.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\gtest.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">

+			<File

+				RelativePath="..\include\gtest\internal\gtest-death-test-internal.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-death-test.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-filepath.h">

+			</File>

+			<File

+				RelativePath="..\src\gtest-internal-inl.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-internal.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-message.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-port.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-spi.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-string.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest_pred_impl.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest_prod.h">

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/protobuf/gtest/msvc/gtest.sln b/protobuf/gtest/msvc/gtest.sln
new file mode 100755
index 0000000..ef4b057
--- /dev/null
+++ b/protobuf/gtest/msvc/gtest.sln
@@ -0,0 +1,45 @@
+Microsoft Visual Studio Solution File, Format Version 8.00

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"

+	ProjectSection(ProjectDependencies) = postProject

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}"

+	ProjectSection(ProjectDependencies) = postProject

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_unittest", "gtest_unittest.vcproj", "{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}"

+	ProjectSection(ProjectDependencies) = postProject

+	EndProjectSection

+EndProject

+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_prod_test", "gtest_prod_test.vcproj", "{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}"

+	ProjectSection(ProjectDependencies) = postProject

+	EndProjectSection

+EndProject

+Global

+	GlobalSection(SolutionConfiguration) = preSolution

+		Debug = Debug

+		Release = Release

+	EndGlobalSection

+	GlobalSection(ProjectConfiguration) = postSolution

+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.ActiveCfg = Debug|Win32

+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug.Build.0 = Debug|Win32

+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.ActiveCfg = Release|Win32

+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release.Build.0 = Release|Win32

+		{3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.ActiveCfg = Debug|Win32

+		{3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug.Build.0 = Debug|Win32

+		{3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.ActiveCfg = Release|Win32

+		{3AF54C8A-10BF-4332-9147-F68ED9862032}.Release.Build.0 = Release|Win32

+		{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.ActiveCfg = Debug|Win32

+		{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Debug.Build.0 = Debug|Win32

+		{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.ActiveCfg = Release|Win32

+		{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}.Release.Build.0 = Release|Win32

+		{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.ActiveCfg = Debug|Win32

+		{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Debug.Build.0 = Debug|Win32

+		{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.ActiveCfg = Release|Win32

+		{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}.Release.Build.0 = Release|Win32

+	EndGlobalSection

+	GlobalSection(ExtensibilityGlobals) = postSolution

+	EndGlobalSection

+	GlobalSection(ExtensibilityAddIns) = postSolution

+	EndGlobalSection

+EndGlobal

diff --git a/protobuf/gtest/msvc/gtest.vcproj b/protobuf/gtest/msvc/gtest.vcproj
new file mode 100755
index 0000000..09d5b93
--- /dev/null
+++ b/protobuf/gtest/msvc/gtest.vcproj
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="7.10"

+	Name="gtest"

+	ProjectGUID="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"

+	Keyword="Win32Proj">

+	<Platforms>

+		<Platform

+			Name="Win32"/>

+	</Platforms>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="4"

+			CharacterSet="2"

+			ReferencesPath="">

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"

+				MinimalRebuild="TRUE"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="4"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)/gtestd.lib"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="4"

+			CharacterSet="2"

+			ReferencesPath="&quot;..\include&quot;;&quot;..&quot;">

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="3"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)/gtest.lib"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">

+			<File

+				RelativePath="..\src\gtest-death-test.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\gtest-filepath.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\gtest-test-part.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\gtest-port.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\gtest-typed-test.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\src\gtest.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">

+			<File

+				RelativePath="..\include\gtest\internal\gtest-death-test-internal.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-death-test.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-filepath.h">

+			</File>

+			<File

+				RelativePath="..\src\gtest-internal-inl.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-internal.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-message.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-port.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-spi.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-string.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest_pred_impl.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest_prod.h">

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/protobuf/gtest/msvc/gtest_main-md.vcproj b/protobuf/gtest/msvc/gtest_main-md.vcproj
new file mode 100755
index 0000000..321667f
--- /dev/null
+++ b/protobuf/gtest/msvc/gtest_main-md.vcproj
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="7.10"

+	Name="gtest_main-md"

+	ProjectGUID="{3AF54C8A-10BF-4332-9147-F68ED9862033}"

+	Keyword="Win32Proj">

+	<Platforms>

+		<Platform

+			Name="Win32"/>

+	</Platforms>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="4"

+			CharacterSet="2"

+			ReferencesPath="">

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"

+				MinimalRebuild="TRUE"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="4"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)/$(ProjectName)d.lib"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="4"

+			CharacterSet="2"

+			ReferencesPath="&quot;..\include&quot;;&quot;..&quot;">

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="3"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)/$(ProjectName).lib"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+	</Configurations>

+	<References>

+		<ProjectReference

+			ReferencedProjectIdentifier="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE8}"

+			Name="gtest-md"/>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">

+			<File

+				RelativePath="..\src\gtest_main.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">

+			<File

+				RelativePath="..\include\gtest\internal\gtest-death-test-internal.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-death-test.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-filepath.h">

+			</File>

+			<File

+				RelativePath="..\src\gtest-internal-inl.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-internal.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-message.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-port.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-spi.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-string.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest_pred_impl.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest_prod.h">

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/protobuf/gtest/msvc/gtest_main.vcproj b/protobuf/gtest/msvc/gtest_main.vcproj
new file mode 100755
index 0000000..1c8c58e
--- /dev/null
+++ b/protobuf/gtest/msvc/gtest_main.vcproj
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="7.10"

+	Name="gtest_main"

+	ProjectGUID="{3AF54C8A-10BF-4332-9147-F68ED9862032}"

+	Keyword="Win32Proj">

+	<Platforms>

+		<Platform

+			Name="Win32"/>

+	</Platforms>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="4"

+			CharacterSet="2"

+			ReferencesPath="">

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				PreprocessorDefinitions="WIN32;_DEBUG;_LIB"

+				MinimalRebuild="TRUE"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="4"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)/$(ProjectName)d.lib"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="4"

+			CharacterSet="2"

+			ReferencesPath="&quot;..\include&quot;;&quot;..&quot;">

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="WIN32;NDEBUG;_LIB"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="3"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLibrarianTool"

+				OutputFile="$(OutDir)/$(ProjectName).lib"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+	</Configurations>

+	<References>

+		<ProjectReference

+			ReferencedProjectIdentifier="{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"

+			Name="gtest"/>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">

+			<File

+				RelativePath="..\src\gtest_main.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">

+			<File

+				RelativePath="..\include\gtest\internal\gtest-death-test-internal.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-death-test.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-filepath.h">

+			</File>

+			<File

+				RelativePath="..\src\gtest-internal-inl.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-internal.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-message.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-port.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest-spi.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\internal\gtest-string.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest_pred_impl.h">

+			</File>

+			<File

+				RelativePath="..\include\gtest\gtest_prod.h">

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/protobuf/gtest/msvc/gtest_prod_test-md.vcproj b/protobuf/gtest/msvc/gtest_prod_test-md.vcproj
new file mode 100755
index 0000000..05b05d9
--- /dev/null
+++ b/protobuf/gtest/msvc/gtest_prod_test-md.vcproj
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="7.10"

+	Name="gtest_prod_test-md"

+	ProjectGUID="{24848551-EF4F-47E8-9A9D-EA4D49BC3ECB}"

+	Keyword="Win32Proj">

+	<Platforms>

+		<Platform

+			Name="Win32"/>

+	</Platforms>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="1"

+			CharacterSet="2">

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"

+				MinimalRebuild="TRUE"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="3"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="4"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLinkerTool"

+				OutputFile="$(OutDir)/gtest_prod_test.exe"

+				LinkIncremental="2"

+				GenerateDebugInformation="TRUE"

+				ProgramDatabaseFile="$(OutDir)/gtest_prod_test.pdb"

+				SubSystem="1"

+				TargetMachine="1"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCWebDeploymentTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="1"

+			CharacterSet="2">

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="3"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="3"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLinkerTool"

+				OutputFile="$(OutDir)/gtest_prod_test.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="TRUE"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCWebDeploymentTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+	</Configurations>

+	<References>

+		<ProjectReference

+			ReferencedProjectIdentifier="{3AF54C8A-10BF-4332-9147-F68ED9862033}"

+			Name="gtest_main-md"/>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">

+			<File

+				RelativePath="..\test\gtest_prod_test.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						UsePrecompiledHeader="0"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						UsePrecompiledHeader="0"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\test\production.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						UsePrecompiledHeader="0"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						UsePrecompiledHeader="0"/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">

+			<File

+				RelativePath="..\test\production.h">

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/protobuf/gtest/msvc/gtest_prod_test.vcproj b/protobuf/gtest/msvc/gtest_prod_test.vcproj
new file mode 100755
index 0000000..d1f6345
--- /dev/null
+++ b/protobuf/gtest/msvc/gtest_prod_test.vcproj
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="7.10"

+	Name="gtest_prod_test"

+	ProjectGUID="{24848551-EF4F-47E8-9A9D-EA4D49BC3ECA}"

+	Keyword="Win32Proj">

+	<Platforms>

+		<Platform

+			Name="Win32"/>

+	</Platforms>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="1"

+			CharacterSet="2">

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"

+				MinimalRebuild="TRUE"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="3"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="4"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLinkerTool"

+				OutputFile="$(OutDir)/gtest_prod_test.exe"

+				LinkIncremental="2"

+				GenerateDebugInformation="TRUE"

+				ProgramDatabaseFile="$(OutDir)/gtest_prod_test.pdb"

+				SubSystem="1"

+				TargetMachine="1"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCWebDeploymentTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="1"

+			CharacterSet="2">

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="3"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="3"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLinkerTool"

+				OutputFile="$(OutDir)/gtest_prod_test.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="TRUE"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCWebDeploymentTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+	</Configurations>

+	<References>

+		<ProjectReference

+			ReferencedProjectIdentifier="{3AF54C8A-10BF-4332-9147-F68ED9862032}"

+			Name="gtest_main"/>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">

+			<File

+				RelativePath="..\test\gtest_prod_test.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						UsePrecompiledHeader="0"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						UsePrecompiledHeader="0"/>

+				</FileConfiguration>

+			</File>

+			<File

+				RelativePath="..\test\production.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						UsePrecompiledHeader="0"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						UsePrecompiledHeader="0"/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">

+			<File

+				RelativePath="..\test\production.h">

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/protobuf/gtest/msvc/gtest_unittest-md.vcproj b/protobuf/gtest/msvc/gtest_unittest-md.vcproj
new file mode 100755
index 0000000..38a5e56
--- /dev/null
+++ b/protobuf/gtest/msvc/gtest_unittest-md.vcproj
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="7.10"

+	Name="gtest_unittest-md"

+	ProjectGUID="{4D9FDFB5-986A-4139-823C-F4EE0ED481A2}"

+	Keyword="Win32Proj">

+	<Platforms>

+		<Platform

+			Name="Win32"/>

+	</Platforms>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="1"

+			CharacterSet="2">

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"

+				MinimalRebuild="TRUE"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="3"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="4"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLinkerTool"

+				OutputFile="$(OutDir)/gtest_unittest.exe"

+				LinkIncremental="2"

+				GenerateDebugInformation="TRUE"

+				ProgramDatabaseFile="$(OutDir)/gtest_unittest.pdb"

+				SubSystem="1"

+				TargetMachine="1"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCWebDeploymentTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="1"

+			CharacterSet="2">

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="3"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="3"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLinkerTool"

+				OutputFile="$(OutDir)/gtest_unittest.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="TRUE"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCWebDeploymentTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+	</Configurations>

+	<References>

+		<ProjectReference

+			ReferencedProjectIdentifier="{3AF54C8A-10BF-4332-9147-F68ED9862033}"

+			Name="gtest_main-md"/>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">

+			<File

+				RelativePath="..\test\gtest_unittest.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="1"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						BasicRuntimeChecks="0"

+						UsePrecompiledHeader="0"

+						DebugInformationFormat="3"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						UsePrecompiledHeader="0"/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/protobuf/gtest/msvc/gtest_unittest.vcproj b/protobuf/gtest/msvc/gtest_unittest.vcproj
new file mode 100755
index 0000000..3c8769e
--- /dev/null
+++ b/protobuf/gtest/msvc/gtest_unittest.vcproj
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="7.10"

+	Name="gtest_unittest"

+	ProjectGUID="{4D9FDFB5-986A-4139-823C-F4EE0ED481A1}"

+	Keyword="Win32Proj">

+	<Platforms>

+		<Platform

+			Name="Win32"/>

+	</Platforms>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="1"

+			CharacterSet="2">

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"

+				MinimalRebuild="TRUE"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="3"

+				UsePrecompiledHeader="3"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="4"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLinkerTool"

+				OutputFile="$(OutDir)/gtest_unittest.exe"

+				LinkIncremental="2"

+				GenerateDebugInformation="TRUE"

+				ProgramDatabaseFile="$(OutDir)/gtest_unittest.pdb"

+				SubSystem="1"

+				TargetMachine="1"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCWebDeploymentTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="$(SolutionName)/$(ConfigurationName)"

+			IntermediateDirectory="$(OutDir)/$(ProjectName)"

+			ConfigurationType="1"

+			CharacterSet="2">

+			<Tool

+				Name="VCCLCompilerTool"

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"

+				RuntimeLibrary="2"

+				UsePrecompiledHeader="3"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="FALSE"

+				DebugInformationFormat="3"/>

+			<Tool

+				Name="VCCustomBuildTool"/>

+			<Tool

+				Name="VCLinkerTool"

+				OutputFile="$(OutDir)/gtest_unittest.exe"

+				LinkIncremental="1"

+				GenerateDebugInformation="TRUE"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				TargetMachine="1"/>

+			<Tool

+				Name="VCMIDLTool"/>

+			<Tool

+				Name="VCPostBuildEventTool"/>

+			<Tool

+				Name="VCPreBuildEventTool"/>

+			<Tool

+				Name="VCPreLinkEventTool"/>

+			<Tool

+				Name="VCResourceCompilerTool"/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"/>

+			<Tool

+				Name="VCWebDeploymentTool"/>

+			<Tool

+				Name="VCManagedWrapperGeneratorTool"/>

+			<Tool

+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

+		</Configuration>

+	</Configurations>

+	<References>

+		<ProjectReference

+			ReferencedProjectIdentifier="{3AF54C8A-10BF-4332-9147-F68ED9862032}"

+			Name="gtest_main"/>

+	</References>

+	<Files>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">

+			<File

+				RelativePath="..\test\gtest_unittest.cc">

+				<FileConfiguration

+					Name="Debug|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						Optimization="1"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						BasicRuntimeChecks="0"

+						UsePrecompiledHeader="0"

+						DebugInformationFormat="3"/>

+				</FileConfiguration>

+				<FileConfiguration

+					Name="Release|Win32">

+					<Tool

+						Name="VCCLCompilerTool"

+						AdditionalIncludeDirectories="&quot;..&quot;;&quot;..\include&quot;"

+						UsePrecompiledHeader="0"/>

+				</FileConfiguration>

+			</File>

+		</Filter>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/protobuf/gtest/samples/prime_tables.h b/protobuf/gtest/samples/prime_tables.h
new file mode 100644
index 0000000..92ce16a
--- /dev/null
+++ b/protobuf/gtest/samples/prime_tables.h
@@ -0,0 +1,123 @@
+// 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)
+// Author: vladl@google.com (Vlad Losev)
+
+// This provides interface PrimeTable that determines whether a number is a
+// prime and determines a next prime number. This interface is used
+// in Google Test samples demonstrating use of parameterized tests.
+
+#ifndef GTEST_SAMPLES_PRIME_TABLES_H_
+#define GTEST_SAMPLES_PRIME_TABLES_H_
+
+#include <algorithm>
+
+// The prime table interface.
+class PrimeTable {
+ public:
+  virtual ~PrimeTable() {}
+
+  // Returns true iff n is a prime number.
+  virtual bool IsPrime(int n) const = 0;
+
+  // Returns the smallest prime number greater than p; or returns -1
+  // if the next prime is beyond the capacity of the table.
+  virtual int GetNextPrime(int p) const = 0;
+};
+
+// Implementation #1 calculates the primes on-the-fly.
+class OnTheFlyPrimeTable : public PrimeTable {
+ public:
+  virtual bool IsPrime(int n) const {
+    if (n <= 1) return false;
+
+    for (int i = 2; i*i <= n; i++) {
+      // n is divisible by an integer other than 1 and itself.
+      if ((n % i) == 0) return false;
+    }
+
+    return true;
+  }
+
+  virtual int GetNextPrime(int p) const {
+    for (int n = p + 1; n > 0; n++) {
+      if (IsPrime(n)) return n;
+    }
+
+    return -1;
+  }
+};
+
+// Implementation #2 pre-calculates the primes and stores the result
+// in an array.
+class PreCalculatedPrimeTable : public PrimeTable {
+ public:
+  // 'max' specifies the maximum number the prime table holds.
+  explicit PreCalculatedPrimeTable(int max)
+      : is_prime_size_(max + 1), is_prime_(new bool[max + 1]) {
+    CalculatePrimesUpTo(max);
+  }
+  virtual ~PreCalculatedPrimeTable() { delete[] is_prime_; }
+
+  virtual bool IsPrime(int n) const {
+    return 0 <= n && n < is_prime_size_ && is_prime_[n];
+  }
+
+  virtual int GetNextPrime(int p) const {
+    for (int n = p + 1; n < is_prime_size_; n++) {
+      if (is_prime_[n]) return n;
+    }
+
+    return -1;
+  }
+
+ private:
+  void CalculatePrimesUpTo(int max) {
+    ::std::fill(is_prime_, is_prime_ + is_prime_size_, true);
+    is_prime_[0] = is_prime_[1] = false;
+
+    for (int i = 2; i <= max; i++) {
+      if (!is_prime_[i]) continue;
+
+      // Marks all multiples of i (except i itself) as non-prime.
+      for (int j = 2*i; j <= max; j += i) {
+        is_prime_[j] = false;
+      }
+    }
+  }
+
+  const int is_prime_size_;
+  bool* const is_prime_;
+
+  // Disables compiler warning "assignment operator could not be generated."
+  void operator=(const PreCalculatedPrimeTable& rhs);
+};
+
+#endif  // GTEST_SAMPLES_PRIME_TABLES_H_
diff --git a/protobuf/gtest/samples/sample1.cc b/protobuf/gtest/samples/sample1.cc
new file mode 100644
index 0000000..f171e26
--- /dev/null
+++ b/protobuf/gtest/samples/sample1.cc
@@ -0,0 +1,68 @@
+// 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.
+
+// A sample program demonstrating using Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#include "sample1.h"
+
+// Returns n! (the factorial of n).  For negative n, n! is defined to be 1.
+int Factorial(int n) {
+  int result = 1;
+  for (int i = 1; i <= n; i++) {
+    result *= i;
+  }
+
+  return result;
+}
+
+// Returns true iff n is a prime number.
+bool IsPrime(int n) {
+  // Trivial case 1: small numbers
+  if (n <= 1) return false;
+
+  // Trivial case 2: even numbers
+  if (n % 2 == 0) return n == 2;
+
+  // Now, we have that n is odd and n >= 3.
+
+  // Try to divide n by every odd number i, starting from 3
+  for (int i = 3; ; i += 2) {
+    // We only have to try i up to the squre root of n
+    if (i > n/i) break;
+
+    // Now, we have i <= n/i < n.
+    // If n is divisible by i, n is not prime.
+    if (n % i == 0) return false;
+  }
+
+  // n has no integer factor in the range (1, n), and thus is prime.
+  return true;
+}
diff --git a/protobuf/gtest/samples/sample1.h b/protobuf/gtest/samples/sample1.h
new file mode 100644
index 0000000..3dfeb98
--- /dev/null
+++ b/protobuf/gtest/samples/sample1.h
@@ -0,0 +1,43 @@
+// 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.
+
+// A sample program demonstrating using Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#ifndef GTEST_SAMPLES_SAMPLE1_H_
+#define GTEST_SAMPLES_SAMPLE1_H_
+
+// Returns n! (the factorial of n).  For negative n, n! is defined to be 1.
+int Factorial(int n);
+
+// Returns true iff n is a prime number.
+bool IsPrime(int n);
+
+#endif  // GTEST_SAMPLES_SAMPLE1_H_
diff --git a/protobuf/gtest/samples/sample10_unittest.cc b/protobuf/gtest/samples/sample10_unittest.cc
new file mode 100644
index 0000000..3ad6fd6
--- /dev/null
+++ b/protobuf/gtest/samples/sample10_unittest.cc
@@ -0,0 +1,145 @@
+// Copyright 2009 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: vladl@google.com (Vlad Losev)
+
+// This sample shows how to use Google Test listener API to implement
+// a primitive leak checker.
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <gtest/gtest.h>
+
+using ::testing::EmptyTestEventListener;
+using ::testing::InitGoogleTest;
+using ::testing::Test;
+using ::testing::TestCase;
+using ::testing::TestEventListeners;
+using ::testing::TestInfo;
+using ::testing::TestPartResult;
+using ::testing::UnitTest;
+
+namespace {
+
+// We will track memory used by this class.
+class Water {
+ public:
+  // Normal Water declarations go here.
+
+  // operator new and operator delete help us control water allocation.
+  void* operator new(size_t allocation_size) {
+    allocated_++;
+    return malloc(allocation_size);
+  }
+
+  void operator delete(void* block, size_t /* allocation_size */) {
+    allocated_--;
+    free(block);
+  }
+
+  static int allocated() { return allocated_; }
+
+ private:
+  static int allocated_;
+};
+
+int Water::allocated_ = 0;
+
+// This event listener monitors how many Water objects are created and
+// destroyed by each test, and reports a failure if a test leaks some Water
+// objects. It does this by comparing the number of live Water objects at
+// the beginning of a test and at the end of a test.
+class LeakChecker : public EmptyTestEventListener {
+ private:
+  // Called before a test starts.
+  virtual void OnTestStart(const TestInfo& /* test_info */) {
+    initially_allocated_ = Water::allocated();
+  }
+
+  // Called after a test ends.
+  virtual void OnTestEnd(const TestInfo& /* test_info */) {
+    int difference = Water::allocated() - initially_allocated_;
+
+    // You can generate a failure in any event handler except
+    // OnTestPartResult. Just use an appropriate Google Test assertion to do
+    // it.
+    EXPECT_TRUE(difference <= 0)
+        << "Leaked " << difference << " unit(s) of Water!";
+  }
+
+  int initially_allocated_;
+};
+
+TEST(ListenersTest, DoesNotLeak) {
+  Water* water = new Water;
+  delete water;
+}
+
+// This should fail when the --check_for_leaks command line flag is
+// specified.
+TEST(ListenersTest, LeaksWater) {
+  Water* water = new Water;
+  EXPECT_TRUE(water != NULL);
+}
+
+}  // namespace
+
+int main(int argc, char **argv) {
+  InitGoogleTest(&argc, argv);
+
+  bool check_for_leaks = false;
+  if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0 )
+    check_for_leaks = true;
+  else
+    printf("%s\n", "Run this program with --check_for_leaks to enable "
+           "custom leak checking in the tests.");
+
+  // If we are given the --check_for_leaks command line flag, installs the
+  // leak checker.
+  if (check_for_leaks) {
+    TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
+
+    // Adds the leak checker to the end of the test event listener list,
+    // after the default text output printer and the default XML report
+    // generator.
+    //
+    // The order is important - it ensures that failures generated in the
+    // leak checker's OnTestEnd() method are processed by the text and XML
+    // printers *before* their OnTestEnd() methods are called, such that
+    // they are attributed to the right test. Remember that a listener
+    // receives an OnXyzStart event *after* listeners preceding it in the
+    // list received that event, and receives an OnXyzEnd event *before*
+    // listeners preceding it.
+    //
+    // We don't need to worry about deleting the new listener later, as
+    // Google Test will do it.
+    listeners.Append(new LeakChecker);
+  }
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/samples/sample1_unittest.cc b/protobuf/gtest/samples/sample1_unittest.cc
new file mode 100644
index 0000000..01eb546
--- /dev/null
+++ b/protobuf/gtest/samples/sample1_unittest.cc
@@ -0,0 +1,153 @@
+// 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.
+
+// A sample program demonstrating using Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+
+// This sample shows how to write a simple unit test for a function,
+// using Google C++ testing framework.
+//
+// Writing a unit test using Google C++ testing framework is easy as 1-2-3:
+
+
+// Step 1. Include necessary header files such that the stuff your
+// test logic needs is declared.
+//
+// Don't forget gtest.h, which declares the testing framework.
+
+#include <limits.h>
+#include "sample1.h"
+#include <gtest/gtest.h>
+
+
+// Step 2. Use the TEST macro to define your tests.
+//
+// TEST has two parameters: the test case name and the test name.
+// After using the macro, you should define your test logic between a
+// pair of braces.  You can use a bunch of macros to indicate the
+// success or failure of a test.  EXPECT_TRUE and EXPECT_EQ are
+// examples of such macros.  For a complete list, see gtest.h.
+//
+// <TechnicalDetails>
+//
+// In Google Test, tests are grouped into test cases.  This is how we
+// keep test code organized.  You should put logically related tests
+// into the same test case.
+//
+// The test case name and the test name should both be valid C++
+// identifiers.  And you should not use underscore (_) in the names.
+//
+// Google Test guarantees that each test you define is run exactly
+// once, but it makes no guarantee on the order the tests are
+// executed.  Therefore, you should write your tests in such a way
+// that their results don't depend on their order.
+//
+// </TechnicalDetails>
+
+
+// Tests Factorial().
+
+// Tests factorial of negative numbers.
+TEST(FactorialTest, Negative) {
+  // This test is named "Negative", and belongs to the "FactorialTest"
+  // test case.
+  EXPECT_EQ(1, Factorial(-5));
+  EXPECT_EQ(1, Factorial(-1));
+  EXPECT_TRUE(Factorial(-10) > 0);
+
+  // <TechnicalDetails>
+  //
+  // EXPECT_EQ(expected, actual) is the same as
+  //
+  //   EXPECT_TRUE((expected) == (actual))
+  //
+  // except that it will print both the expected value and the actual
+  // value when the assertion fails.  This is very helpful for
+  // debugging.  Therefore in this case EXPECT_EQ is preferred.
+  //
+  // On the other hand, EXPECT_TRUE accepts any Boolean expression,
+  // and is thus more general.
+  //
+  // </TechnicalDetails>
+}
+
+// Tests factorial of 0.
+TEST(FactorialTest, Zero) {
+  EXPECT_EQ(1, Factorial(0));
+}
+
+// Tests factorial of positive numbers.
+TEST(FactorialTest, Positive) {
+  EXPECT_EQ(1, Factorial(1));
+  EXPECT_EQ(2, Factorial(2));
+  EXPECT_EQ(6, Factorial(3));
+  EXPECT_EQ(40320, Factorial(8));
+}
+
+
+// Tests IsPrime()
+
+// Tests negative input.
+TEST(IsPrimeTest, Negative) {
+  // This test belongs to the IsPrimeTest test case.
+
+  EXPECT_FALSE(IsPrime(-1));
+  EXPECT_FALSE(IsPrime(-2));
+  EXPECT_FALSE(IsPrime(INT_MIN));
+}
+
+// Tests some trivial cases.
+TEST(IsPrimeTest, Trivial) {
+  EXPECT_FALSE(IsPrime(0));
+  EXPECT_FALSE(IsPrime(1));
+  EXPECT_TRUE(IsPrime(2));
+  EXPECT_TRUE(IsPrime(3));
+}
+
+// Tests positive input.
+TEST(IsPrimeTest, Positive) {
+  EXPECT_FALSE(IsPrime(4));
+  EXPECT_TRUE(IsPrime(5));
+  EXPECT_FALSE(IsPrime(6));
+  EXPECT_TRUE(IsPrime(23));
+}
+
+// Step 3. Call RUN_ALL_TESTS() in main().
+//
+// We do this by linking in src/gtest_main.cc file, which consists of
+// a main() function which calls RUN_ALL_TESTS() for us.
+//
+// This runs all the tests you've defined, prints the result, and
+// returns 0 if successful, or 1 otherwise.
+//
+// Did you notice that we didn't register the tests?  The
+// RUN_ALL_TESTS() macro magically knows about all the tests we
+// defined.  Isn't this convenient?
diff --git a/protobuf/gtest/samples/sample2.cc b/protobuf/gtest/samples/sample2.cc
new file mode 100644
index 0000000..5f763b9
--- /dev/null
+++ b/protobuf/gtest/samples/sample2.cc
@@ -0,0 +1,56 @@
+// 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.
+
+// A sample program demonstrating using Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#include "sample2.h"
+
+#include <string.h>
+
+// Clones a 0-terminated C string, allocating memory using new.
+const char* MyString::CloneCString(const char* a_c_string) {
+  if (a_c_string == NULL) return NULL;
+
+  const size_t len = strlen(a_c_string);
+  char* const clone = new char[ len + 1 ];
+  memcpy(clone, a_c_string, len + 1);
+
+  return clone;
+}
+
+// Sets the 0-terminated C string this MyString object
+// represents.
+void MyString::Set(const char* a_c_string) {
+  // Makes sure this works when c_string == c_string_
+  const char* const temp = MyString::CloneCString(a_c_string);
+  delete[] c_string_;
+  c_string_ = temp;
+}
diff --git a/protobuf/gtest/samples/sample2.h b/protobuf/gtest/samples/sample2.h
new file mode 100644
index 0000000..5b57e60
--- /dev/null
+++ b/protobuf/gtest/samples/sample2.h
@@ -0,0 +1,86 @@
+// 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.
+
+// A sample program demonstrating using Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#ifndef GTEST_SAMPLES_SAMPLE2_H_
+#define GTEST_SAMPLES_SAMPLE2_H_
+
+#include <string.h>
+
+
+// A simple string class.
+class MyString {
+ private:
+  const char* c_string_;
+  const MyString& operator=(const MyString& rhs);
+
+ public:
+
+  // Clones a 0-terminated C string, allocating memory using new.
+  static const char* CloneCString(const char* a_c_string);
+
+  ////////////////////////////////////////////////////////////
+  //
+  // C'tors
+
+  // The default c'tor constructs a NULL string.
+  MyString() : c_string_(NULL) {}
+
+  // Constructs a MyString by cloning a 0-terminated C string.
+  explicit MyString(const char* a_c_string) : c_string_(NULL) {
+    Set(a_c_string);
+  }
+
+  // Copy c'tor
+  MyString(const MyString& string) : c_string_(NULL) {
+    Set(string.c_string_);
+  }
+
+  ////////////////////////////////////////////////////////////
+  //
+  // D'tor.  MyString is intended to be a final class, so the d'tor
+  // doesn't need to be virtual.
+  ~MyString() { delete[] c_string_; }
+
+  // Gets the 0-terminated C string this MyString object represents.
+  const char* c_string() const { return c_string_; }
+
+  size_t Length() const {
+    return c_string_ == NULL ? 0 : strlen(c_string_);
+  }
+
+  // Sets the 0-terminated C string this MyString object represents.
+  void Set(const char* c_string);
+};
+
+
+#endif  // GTEST_SAMPLES_SAMPLE2_H_
diff --git a/protobuf/gtest/samples/sample2_unittest.cc b/protobuf/gtest/samples/sample2_unittest.cc
new file mode 100644
index 0000000..32232d9
--- /dev/null
+++ b/protobuf/gtest/samples/sample2_unittest.cc
@@ -0,0 +1,109 @@
+// 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.
+
+// A sample program demonstrating using Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+
+// This sample shows how to write a more complex unit test for a class
+// that has multiple member functions.
+//
+// Usually, it's a good idea to have one test for each method in your
+// class.  You don't have to do that exactly, but it helps to keep
+// your tests organized.  You may also throw in additional tests as
+// needed.
+
+#include "sample2.h"
+#include <gtest/gtest.h>
+
+// In this example, we test the MyString class (a simple string).
+
+// Tests the default c'tor.
+TEST(MyString, DefaultConstructor) {
+  const MyString s;
+
+  // Asserts that s.c_string() returns NULL.
+  //
+  // <TechnicalDetails>
+  //
+  // If we write NULL instead of
+  //
+  //   static_cast<const char *>(NULL)
+  //
+  // in this assertion, it will generate a warning on gcc 3.4.  The
+  // reason is that EXPECT_EQ needs to know the types of its
+  // arguments in order to print them when it fails.  Since NULL is
+  // #defined as 0, the compiler will use the formatter function for
+  // int to print it.  However, gcc thinks that NULL should be used as
+  // a pointer, not an int, and therefore complains.
+  //
+  // The root of the problem is C++'s lack of distinction between the
+  // integer number 0 and the null pointer constant.  Unfortunately,
+  // we have to live with this fact.
+  //
+  // </TechnicalDetails>
+  EXPECT_STREQ(NULL, s.c_string());
+
+  EXPECT_EQ(0u, s.Length());
+}
+
+const char kHelloString[] = "Hello, world!";
+
+// Tests the c'tor that accepts a C string.
+TEST(MyString, ConstructorFromCString) {
+  const MyString s(kHelloString);
+  EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0);
+  EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1,
+            s.Length());
+}
+
+// Tests the copy c'tor.
+TEST(MyString, CopyConstructor) {
+  const MyString s1(kHelloString);
+  const MyString s2 = s1;
+  EXPECT_TRUE(strcmp(s2.c_string(), kHelloString) == 0);
+}
+
+// Tests the Set method.
+TEST(MyString, Set) {
+  MyString s;
+
+  s.Set(kHelloString);
+  EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0);
+
+  // Set should work when the input pointer is the same as the one
+  // already in the MyString object.
+  s.Set(s.c_string());
+  EXPECT_TRUE(strcmp(s.c_string(), kHelloString) == 0);
+
+  // Can we set the MyString to NULL?
+  s.Set(NULL);
+  EXPECT_STREQ(NULL, s.c_string());
+}
diff --git a/protobuf/gtest/samples/sample3-inl.h b/protobuf/gtest/samples/sample3-inl.h
new file mode 100644
index 0000000..46369a0
--- /dev/null
+++ b/protobuf/gtest/samples/sample3-inl.h
@@ -0,0 +1,173 @@
+// 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.
+
+// A sample program demonstrating using Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#ifndef GTEST_SAMPLES_SAMPLE3_INL_H_
+#define GTEST_SAMPLES_SAMPLE3_INL_H_
+
+#include <stddef.h>
+
+
+// Queue is a simple queue implemented as a singled-linked list.
+//
+// The element type must support copy constructor.
+template <typename E>  // E is the element type
+class Queue;
+
+// QueueNode is a node in a Queue, which consists of an element of
+// type E and a pointer to the next node.
+template <typename E>  // E is the element type
+class QueueNode {
+  friend class Queue<E>;
+
+ public:
+  // Gets the element in this node.
+  const E& element() const { return element_; }
+
+  // Gets the next node in the queue.
+  QueueNode* next() { return next_; }
+  const QueueNode* next() const { return next_; }
+
+ private:
+  // Creates a node with a given element value.  The next pointer is
+  // set to NULL.
+  QueueNode(const E& an_element) : element_(an_element), next_(NULL) {}
+
+  // We disable the default assignment operator and copy c'tor.
+  const QueueNode& operator = (const QueueNode&);
+  QueueNode(const QueueNode&);
+
+  E element_;
+  QueueNode* next_;
+};
+
+template <typename E>  // E is the element type.
+class Queue {
+public:
+
+  // Creates an empty queue.
+  Queue() : head_(NULL), last_(NULL), size_(0) {}
+
+  // D'tor.  Clears the queue.
+  ~Queue() { Clear(); }
+
+  // Clears the queue.
+  void Clear() {
+    if (size_ > 0) {
+      // 1. Deletes every node.
+      QueueNode<E>* node = head_;
+      QueueNode<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.
+  size_t Size() const { return size_; }
+
+  // Gets the first element of the queue, or NULL if the queue is empty.
+  QueueNode<E>* Head() { return head_; }
+  const QueueNode<E>* Head() const { return head_; }
+
+  // Gets the last element of the queue, or NULL if the queue is empty.
+  QueueNode<E>* Last() { return last_; }
+  const QueueNode<E>* Last() const { return last_; }
+
+  // Adds an element to the end of the queue.  A copy of the element is
+  // created using the copy constructor, and then stored in the queue.
+  // Changes made to the element in the queue doesn't affect the source
+  // object, and vice versa.
+  void Enqueue(const E& element) {
+    QueueNode<E>* new_node = new QueueNode<E>(element);
+
+    if (size_ == 0) {
+      head_ = last_ = new_node;
+      size_ = 1;
+    } else {
+      last_->next_ = new_node;
+      last_ = new_node;
+      size_++;
+    }
+  }
+
+  // Removes the head of the queue and returns it.  Returns NULL if
+  // the queue is empty.
+  E* Dequeue() {
+    if (size_ == 0) {
+      return NULL;
+    }
+
+    const QueueNode<E>* const old_head = head_;
+    head_ = head_->next_;
+    size_--;
+    if (size_ == 0) {
+      last_ = NULL;
+    }
+
+    E* element = new E(old_head->element());
+    delete old_head;
+
+    return element;
+  }
+
+  // Applies a function/functor on each element of the queue, and
+  // returns the result in a new queue.  The original queue is not
+  // affected.
+  template <typename F>
+  Queue* Map(F function) const {
+    Queue* new_queue = new Queue();
+    for (const QueueNode<E>* node = head_; node != NULL; node = node->next_) {
+      new_queue->Enqueue(function(node->element()));
+    }
+
+    return new_queue;
+  }
+
+ private:
+  QueueNode<E>* head_;  // The first node of the queue.
+  QueueNode<E>* last_;  // The last node of the queue.
+  size_t size_;  // The number of elements in the queue.
+
+  // We disallow copying a queue.
+  Queue(const Queue&);
+  const Queue& operator = (const Queue&);
+ };
+
+#endif  // GTEST_SAMPLES_SAMPLE3_INL_H_
diff --git a/protobuf/gtest/samples/sample3_unittest.cc b/protobuf/gtest/samples/sample3_unittest.cc
new file mode 100644
index 0000000..34c1ca8
--- /dev/null
+++ b/protobuf/gtest/samples/sample3_unittest.cc
@@ -0,0 +1,151 @@
+// 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.
+
+// A sample program demonstrating using Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+
+// In this example, we use a more advanced feature of Google Test called
+// test fixture.
+//
+// A test fixture is a place to hold objects and functions shared by
+// all tests in a test case.  Using a test fixture avoids duplicating
+// the test code necessary to initialize and cleanup those common
+// objects for each test.  It is also useful for defining sub-routines
+// that your tests need to invoke a lot.
+//
+// <TechnicalDetails>
+//
+// The tests share the test fixture in the sense of code sharing, not
+// data sharing.  Each test is given its own fresh copy of the
+// fixture.  You cannot expect the data modified by one test to be
+// passed on to another test, which is a bad idea.
+//
+// The reason for this design is that tests should be independent and
+// repeatable.  In particular, a test should not fail as the result of
+// another test's failure.  If one test depends on info produced by
+// another test, then the two tests should really be one big test.
+//
+// The macros for indicating the success/failure of a test
+// (EXPECT_TRUE, FAIL, etc) need to know what the current test is
+// (when Google Test prints the test result, it tells you which test
+// each failure belongs to).  Technically, these macros invoke a
+// member function of the Test class.  Therefore, you cannot use them
+// in a global function.  That's why you should put test sub-routines
+// in a test fixture.
+//
+// </TechnicalDetails>
+
+#include "sample3-inl.h"
+#include <gtest/gtest.h>
+
+// To use a test fixture, derive a class from testing::Test.
+class QueueTest : public testing::Test {
+ protected:  // You should make the members protected s.t. they can be
+             // accessed from sub-classes.
+
+  // virtual void SetUp() will be called before each test is run.  You
+  // should define it if you need to initialize the varaibles.
+  // Otherwise, this can be skipped.
+  virtual void SetUp() {
+    q1_.Enqueue(1);
+    q2_.Enqueue(2);
+    q2_.Enqueue(3);
+  }
+
+  // virtual void TearDown() will be called after each test is run.
+  // You should define it if there is cleanup work to do.  Otherwise,
+  // you don't have to provide it.
+  //
+  // virtual void TearDown() {
+  // }
+
+  // A helper function that some test uses.
+  static int Double(int n) {
+    return 2*n;
+  }
+
+  // A helper function for testing Queue::Map().
+  void MapTester(const Queue<int> * q) {
+    // Creates a new queue, where each element is twice as big as the
+    // corresponding one in q.
+    const Queue<int> * const new_q = q->Map(Double);
+
+    // Verifies that the new queue has the same size as q.
+    ASSERT_EQ(q->Size(), new_q->Size());
+
+    // Verifies the relationship between the elements of the two queues.
+    for ( const QueueNode<int> * n1 = q->Head(), * n2 = new_q->Head();
+          n1 != NULL; n1 = n1->next(), n2 = n2->next() ) {
+      EXPECT_EQ(2 * n1->element(), n2->element());
+    }
+
+    delete new_q;
+  }
+
+  // Declares the variables your tests want to use.
+  Queue<int> q0_;
+  Queue<int> q1_;
+  Queue<int> q2_;
+};
+
+// When you have a test fixture, you define a test using TEST_F
+// instead of TEST.
+
+// Tests the default c'tor.
+TEST_F(QueueTest, DefaultConstructor) {
+  // You can access data in the test fixture here.
+  EXPECT_EQ(0u, q0_.Size());
+}
+
+// Tests Dequeue().
+TEST_F(QueueTest, Dequeue) {
+  int * n = q0_.Dequeue();
+  EXPECT_TRUE(n == NULL);
+
+  n = q1_.Dequeue();
+  ASSERT_TRUE(n != NULL);
+  EXPECT_EQ(1, *n);
+  EXPECT_EQ(0u, q1_.Size());
+  delete n;
+
+  n = q2_.Dequeue();
+  ASSERT_TRUE(n != NULL);
+  EXPECT_EQ(2, *n);
+  EXPECT_EQ(1u, q2_.Size());
+  delete n;
+}
+
+// Tests the Queue::Map() function.
+TEST_F(QueueTest, Map) {
+  MapTester(&q0_);
+  MapTester(&q1_);
+  MapTester(&q2_);
+}
diff --git a/protobuf/gtest/samples/sample4.cc b/protobuf/gtest/samples/sample4.cc
new file mode 100644
index 0000000..ae44bda
--- /dev/null
+++ b/protobuf/gtest/samples/sample4.cc
@@ -0,0 +1,46 @@
+// 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.
+
+// A sample program demonstrating using Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#include <stdio.h>
+
+#include "sample4.h"
+
+// Returns the current counter value, and increments it.
+int Counter::Increment() {
+  return counter_++;
+}
+
+// Prints the current counter value to STDOUT.
+void Counter::Print() const {
+  printf("%d", counter_);
+}
diff --git a/protobuf/gtest/samples/sample4.h b/protobuf/gtest/samples/sample4.h
new file mode 100644
index 0000000..cd60f0d
--- /dev/null
+++ b/protobuf/gtest/samples/sample4.h
@@ -0,0 +1,53 @@
+// 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.
+
+// A sample program demonstrating using Google C++ testing framework.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#ifndef GTEST_SAMPLES_SAMPLE4_H_
+#define GTEST_SAMPLES_SAMPLE4_H_
+
+// A simple monotonic counter.
+class Counter {
+ private:
+  int counter_;
+
+ public:
+  // Creates a counter that starts at 0.
+  Counter() : counter_(0) {}
+
+  // Returns the current counter value, and increments it.
+  int Increment();
+
+  // Prints the current counter value to STDOUT.
+  void Print() const;
+};
+
+#endif  // GTEST_SAMPLES_SAMPLE4_H_
diff --git a/protobuf/gtest/samples/sample4_unittest.cc b/protobuf/gtest/samples/sample4_unittest.cc
new file mode 100644
index 0000000..b4fb373
--- /dev/null
+++ b/protobuf/gtest/samples/sample4_unittest.cc
@@ -0,0 +1,45 @@
+// 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)
+
+#include <gtest/gtest.h>
+#include "sample4.h"
+
+// Tests the Increment() method.
+TEST(Counter, Increment) {
+  Counter c;
+
+  // EXPECT_EQ() evaluates its arguments exactly once, so they
+  // can have side effects.
+
+  EXPECT_EQ(0, c.Increment());
+  EXPECT_EQ(1, c.Increment());
+  EXPECT_EQ(2, c.Increment());
+}
diff --git a/protobuf/gtest/samples/sample5_unittest.cc b/protobuf/gtest/samples/sample5_unittest.cc
new file mode 100644
index 0000000..49dae7c
--- /dev/null
+++ b/protobuf/gtest/samples/sample5_unittest.cc
@@ -0,0 +1,199 @@
+// 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 sample teaches how to reuse a test fixture in multiple test
+// cases by deriving sub-fixtures from it.
+//
+// When you define a test fixture, you specify the name of the test
+// case that will use this fixture.  Therefore, a test fixture can
+// be used by only one test case.
+//
+// Sometimes, more than one test cases may want to use the same or
+// slightly different test fixtures.  For example, you may want to
+// make sure that all tests for a GUI library don't leak important
+// system resources like fonts and brushes.  In Google Test, you do
+// this by putting the shared logic in a super (as in "super class")
+// test fixture, and then have each test case use a fixture derived
+// from this super fixture.
+
+#include <limits.h>
+#include <time.h>
+#include "sample3-inl.h"
+#include <gtest/gtest.h>
+#include "sample1.h"
+
+// In this sample, we want to ensure that every test finishes within
+// ~5 seconds.  If a test takes longer to run, we consider it a
+// failure.
+//
+// We put the code for timing a test in a test fixture called
+// "QuickTest".  QuickTest is intended to be the super fixture that
+// other fixtures derive from, therefore there is no test case with
+// the name "QuickTest".  This is OK.
+//
+// Later, we will derive multiple test fixtures from QuickTest.
+class QuickTest : public testing::Test {
+ protected:
+  // Remember that SetUp() is run immediately before a test starts.
+  // This is a good place to record the start time.
+  virtual void SetUp() {
+    start_time_ = time(NULL);
+  }
+
+  // TearDown() is invoked immediately after a test finishes.  Here we
+  // check if the test was too slow.
+  virtual void TearDown() {
+    // Gets the time when the test finishes
+    const time_t end_time = time(NULL);
+
+    // Asserts that the test took no more than ~5 seconds.  Did you
+    // know that you can use assertions in SetUp() and TearDown() as
+    // well?
+    EXPECT_TRUE(end_time - start_time_ <= 5) << "The test took too long.";
+  }
+
+  // The UTC time (in seconds) when the test starts
+  time_t start_time_;
+};
+
+
+// We derive a fixture named IntegerFunctionTest from the QuickTest
+// fixture.  All tests using this fixture will be automatically
+// required to be quick.
+class IntegerFunctionTest : public QuickTest {
+  // We don't need any more logic than already in the QuickTest fixture.
+  // Therefore the body is empty.
+};
+
+
+// Now we can write tests in the IntegerFunctionTest test case.
+
+// Tests Factorial()
+TEST_F(IntegerFunctionTest, Factorial) {
+  // Tests factorial of negative numbers.
+  EXPECT_EQ(1, Factorial(-5));
+  EXPECT_EQ(1, Factorial(-1));
+  EXPECT_TRUE(Factorial(-10) > 0);
+
+  // Tests factorial of 0.
+  EXPECT_EQ(1, Factorial(0));
+
+  // Tests factorial of positive numbers.
+  EXPECT_EQ(1, Factorial(1));
+  EXPECT_EQ(2, Factorial(2));
+  EXPECT_EQ(6, Factorial(3));
+  EXPECT_EQ(40320, Factorial(8));
+}
+
+
+// Tests IsPrime()
+TEST_F(IntegerFunctionTest, IsPrime) {
+  // Tests negative input.
+  EXPECT_TRUE(!IsPrime(-1));
+  EXPECT_TRUE(!IsPrime(-2));
+  EXPECT_TRUE(!IsPrime(INT_MIN));
+
+  // Tests some trivial cases.
+  EXPECT_TRUE(!IsPrime(0));
+  EXPECT_TRUE(!IsPrime(1));
+  EXPECT_TRUE(IsPrime(2));
+  EXPECT_TRUE(IsPrime(3));
+
+  // Tests positive input.
+  EXPECT_TRUE(!IsPrime(4));
+  EXPECT_TRUE(IsPrime(5));
+  EXPECT_TRUE(!IsPrime(6));
+  EXPECT_TRUE(IsPrime(23));
+}
+
+
+// The next test case (named "QueueTest") also needs to be quick, so
+// we derive another fixture from QuickTest.
+//
+// The QueueTest test fixture has some logic and shared objects in
+// addition to what's in QuickTest already.  We define the additional
+// stuff inside the body of the test fixture, as usual.
+class QueueTest : public QuickTest {
+ protected:
+  virtual void SetUp() {
+    // First, we need to set up the super fixture (QuickTest).
+    QuickTest::SetUp();
+
+    // Second, some additional setup for this fixture.
+    q1_.Enqueue(1);
+    q2_.Enqueue(2);
+    q2_.Enqueue(3);
+  }
+
+  // By default, TearDown() inherits the behavior of
+  // QuickTest::TearDown().  As we have no additional cleaning work
+  // for QueueTest, we omit it here.
+  //
+  // virtual void TearDown() {
+  //   QuickTest::TearDown();
+  // }
+
+  Queue<int> q0_;
+  Queue<int> q1_;
+  Queue<int> q2_;
+};
+
+
+// Now, let's write tests using the QueueTest fixture.
+
+// Tests the default constructor.
+TEST_F(QueueTest, DefaultConstructor) {
+  EXPECT_EQ(0u, q0_.Size());
+}
+
+// Tests Dequeue().
+TEST_F(QueueTest, Dequeue) {
+  int* n = q0_.Dequeue();
+  EXPECT_TRUE(n == NULL);
+
+  n = q1_.Dequeue();
+  EXPECT_TRUE(n != NULL);
+  EXPECT_EQ(1, *n);
+  EXPECT_EQ(0u, q1_.Size());
+  delete n;
+
+  n = q2_.Dequeue();
+  EXPECT_TRUE(n != NULL);
+  EXPECT_EQ(2, *n);
+  EXPECT_EQ(1u, q2_.Size());
+  delete n;
+}
+
+// If necessary, you can derive further test fixtures from a derived
+// fixture itself.  For example, you can derive another fixture from
+// QueueTest.  Google Test imposes no limit on how deep the hierarchy
+// can be.  In practice, however, you probably don't want it to be too
+// deep as to be confusing.
diff --git a/protobuf/gtest/samples/sample6_unittest.cc b/protobuf/gtest/samples/sample6_unittest.cc
new file mode 100644
index 0000000..dd0df31
--- /dev/null
+++ b/protobuf/gtest/samples/sample6_unittest.cc
@@ -0,0 +1,224 @@
+// 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)
+
+// This sample shows how to test common properties of multiple
+// implementations of the same interface (aka interface tests).
+
+// The interface and its implementations are in this header.
+#include "prime_tables.h"
+
+#include <gtest/gtest.h>
+
+// First, we define some factory functions for creating instances of
+// the implementations.  You may be able to skip this step if all your
+// implementations can be constructed the same way.
+
+template <class T>
+PrimeTable* CreatePrimeTable();
+
+template <>
+PrimeTable* CreatePrimeTable<OnTheFlyPrimeTable>() {
+  return new OnTheFlyPrimeTable;
+}
+
+template <>
+PrimeTable* CreatePrimeTable<PreCalculatedPrimeTable>() {
+  return new PreCalculatedPrimeTable(10000);
+}
+
+// Then we define a test fixture class template.
+template <class T>
+class PrimeTableTest : public testing::Test {
+ protected:
+  // The ctor calls the factory function to create a prime table
+  // implemented by T.
+  PrimeTableTest() : table_(CreatePrimeTable<T>()) {}
+
+  virtual ~PrimeTableTest() { delete table_; }
+
+  // Note that we test an implementation via the base interface
+  // instead of the actual implementation class.  This is important
+  // for keeping the tests close to the real world scenario, where the
+  // implementation is invoked via the base interface.  It avoids
+  // got-yas where the implementation class has a method that shadows
+  // a method with the same name (but slightly different argument
+  // types) in the base interface, for example.
+  PrimeTable* const table_;
+};
+
+#if GTEST_HAS_TYPED_TEST
+
+using testing::Types;
+
+// Google Test offers two ways for reusing tests for different types.
+// The first is called "typed tests".  You should use it if you
+// already know *all* the types you are gonna exercise when you write
+// the tests.
+
+// To write a typed test case, first use
+//
+//   TYPED_TEST_CASE(TestCaseName, TypeList);
+//
+// to declare it and specify the type parameters.  As with TEST_F,
+// TestCaseName must match the test fixture name.
+
+// The list of types we want to test.
+typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> Implementations;
+
+TYPED_TEST_CASE(PrimeTableTest, Implementations);
+
+// Then use TYPED_TEST(TestCaseName, TestName) to define a typed test,
+// similar to TEST_F.
+TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) {
+  // Inside the test body, you can refer to the type parameter by
+  // TypeParam, and refer to the fixture class by TestFixture.  We
+  // don't need them in this example.
+
+  // Since we are in the template world, C++ requires explicitly
+  // writing 'this->' when referring to members of the fixture class.
+  // This is something you have to learn to live with.
+  EXPECT_FALSE(this->table_->IsPrime(-5));
+  EXPECT_FALSE(this->table_->IsPrime(0));
+  EXPECT_FALSE(this->table_->IsPrime(1));
+  EXPECT_FALSE(this->table_->IsPrime(4));
+  EXPECT_FALSE(this->table_->IsPrime(6));
+  EXPECT_FALSE(this->table_->IsPrime(100));
+}
+
+TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) {
+  EXPECT_TRUE(this->table_->IsPrime(2));
+  EXPECT_TRUE(this->table_->IsPrime(3));
+  EXPECT_TRUE(this->table_->IsPrime(5));
+  EXPECT_TRUE(this->table_->IsPrime(7));
+  EXPECT_TRUE(this->table_->IsPrime(11));
+  EXPECT_TRUE(this->table_->IsPrime(131));
+}
+
+TYPED_TEST(PrimeTableTest, CanGetNextPrime) {
+  EXPECT_EQ(2, this->table_->GetNextPrime(0));
+  EXPECT_EQ(3, this->table_->GetNextPrime(2));
+  EXPECT_EQ(5, this->table_->GetNextPrime(3));
+  EXPECT_EQ(7, this->table_->GetNextPrime(5));
+  EXPECT_EQ(11, this->table_->GetNextPrime(7));
+  EXPECT_EQ(131, this->table_->GetNextPrime(128));
+}
+
+// That's it!  Google Test will repeat each TYPED_TEST for each type
+// in the type list specified in TYPED_TEST_CASE.  Sit back and be
+// happy that you don't have to define them multiple times.
+
+#endif  // GTEST_HAS_TYPED_TEST
+
+#if GTEST_HAS_TYPED_TEST_P
+
+using testing::Types;
+
+// Sometimes, however, you don't yet know all the types that you want
+// to test when you write the tests.  For example, if you are the
+// author of an interface and expect other people to implement it, you
+// might want to write a set of tests to make sure each implementation
+// conforms to some basic requirements, but you don't know what
+// implementations will be written in the future.
+//
+// How can you write the tests without committing to the type
+// parameters?  That's what "type-parameterized tests" can do for you.
+// It is a bit more involved than typed tests, but in return you get a
+// test pattern that can be reused in many contexts, which is a big
+// win.  Here's how you do it:
+
+// First, define a test fixture class template.  Here we just reuse
+// the PrimeTableTest fixture defined earlier:
+
+template <class T>
+class PrimeTableTest2 : public PrimeTableTest<T> {
+};
+
+// Then, declare the test case.  The argument is the name of the test
+// fixture, and also the name of the test case (as usual).  The _P
+// suffix is for "parameterized" or "pattern".
+TYPED_TEST_CASE_P(PrimeTableTest2);
+
+// Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test,
+// similar to what you do with TEST_F.
+TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) {
+  EXPECT_FALSE(this->table_->IsPrime(-5));
+  EXPECT_FALSE(this->table_->IsPrime(0));
+  EXPECT_FALSE(this->table_->IsPrime(1));
+  EXPECT_FALSE(this->table_->IsPrime(4));
+  EXPECT_FALSE(this->table_->IsPrime(6));
+  EXPECT_FALSE(this->table_->IsPrime(100));
+}
+
+TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) {
+  EXPECT_TRUE(this->table_->IsPrime(2));
+  EXPECT_TRUE(this->table_->IsPrime(3));
+  EXPECT_TRUE(this->table_->IsPrime(5));
+  EXPECT_TRUE(this->table_->IsPrime(7));
+  EXPECT_TRUE(this->table_->IsPrime(11));
+  EXPECT_TRUE(this->table_->IsPrime(131));
+}
+
+TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) {
+  EXPECT_EQ(2, this->table_->GetNextPrime(0));
+  EXPECT_EQ(3, this->table_->GetNextPrime(2));
+  EXPECT_EQ(5, this->table_->GetNextPrime(3));
+  EXPECT_EQ(7, this->table_->GetNextPrime(5));
+  EXPECT_EQ(11, this->table_->GetNextPrime(7));
+  EXPECT_EQ(131, this->table_->GetNextPrime(128));
+}
+
+// Type-parameterized tests involve one extra step: you have to
+// enumerate the tests you defined:
+REGISTER_TYPED_TEST_CASE_P(
+    PrimeTableTest2,  // The first argument is the test case name.
+    // The rest of the arguments are the test names.
+    ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime);
+
+// At this point the test pattern is done.  However, you don't have
+// any real test yet as you haven't said which types you want to run
+// the tests with.
+
+// To turn the abstract test pattern into real tests, you instantiate
+// it with a list of types.  Usually the test pattern will be defined
+// in a .h file, and anyone can #include and instantiate it.  You can
+// even instantiate it more than once in the same program.  To tell
+// different instances apart, you give each of them a name, which will
+// become part of the test case name and can be used in test filters.
+
+// The list of types we want to test.  Note that it doesn't have to be
+// defined at the time we write the TYPED_TEST_P()s.
+typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable>
+    PrimeTableImplementations;
+INSTANTIATE_TYPED_TEST_CASE_P(OnTheFlyAndPreCalculated,    // Instance name
+                              PrimeTableTest2,             // Test case name
+                              PrimeTableImplementations);  // Type list
+
+#endif  // GTEST_HAS_TYPED_TEST_P
diff --git a/protobuf/gtest/samples/sample7_unittest.cc b/protobuf/gtest/samples/sample7_unittest.cc
new file mode 100644
index 0000000..f455282
--- /dev/null
+++ b/protobuf/gtest/samples/sample7_unittest.cc
@@ -0,0 +1,132 @@
+// 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: vladl@google.com (Vlad Losev)
+
+// This sample shows how to test common properties of multiple
+// implementations of an interface (aka interface tests) using
+// value-parameterized tests. Each test in the test case has
+// a parameter that is an interface pointer to an implementation
+// tested.
+
+// The interface and its implementations are in this header.
+#include "prime_tables.h"
+
+#include <gtest/gtest.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+using ::testing::TestWithParam;
+using ::testing::Values;
+
+// As a general rule, tested objects should not be reused between tests.
+// Also, their constructors and destructors of tested objects can have
+// side effects. Thus you should create and destroy them for each test.
+// In this sample we will define a simple factory function for PrimeTable
+// objects. We will instantiate objects in test's SetUp() method and
+// delete them in TearDown() method.
+typedef PrimeTable* CreatePrimeTableFunc();
+
+PrimeTable* CreateOnTheFlyPrimeTable() {
+  return new OnTheFlyPrimeTable();
+}
+
+template <size_t max_precalculated>
+PrimeTable* CreatePreCalculatedPrimeTable() {
+  return new PreCalculatedPrimeTable(max_precalculated);
+}
+
+// Inside the test body, fixture constructor, SetUp(), and TearDown()
+// you can refer to the test parameter by GetParam().
+// In this case, the test parameter is a PrimeTableFactory interface pointer
+// which we use in fixture's SetUp() to create and store an instance of
+// PrimeTable.
+class PrimeTableTest : public TestWithParam<CreatePrimeTableFunc*> {
+ public:
+  virtual ~PrimeTableTest() { delete table_; }
+  virtual void SetUp() { table_ = (*GetParam())(); }
+  virtual void TearDown() {
+    delete table_;
+    table_ = NULL;
+  }
+
+ protected:
+  PrimeTable* table_;
+};
+
+TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
+  EXPECT_FALSE(table_->IsPrime(-5));
+  EXPECT_FALSE(table_->IsPrime(0));
+  EXPECT_FALSE(table_->IsPrime(1));
+  EXPECT_FALSE(table_->IsPrime(4));
+  EXPECT_FALSE(table_->IsPrime(6));
+  EXPECT_FALSE(table_->IsPrime(100));
+}
+
+TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
+  EXPECT_TRUE(table_->IsPrime(2));
+  EXPECT_TRUE(table_->IsPrime(3));
+  EXPECT_TRUE(table_->IsPrime(5));
+  EXPECT_TRUE(table_->IsPrime(7));
+  EXPECT_TRUE(table_->IsPrime(11));
+  EXPECT_TRUE(table_->IsPrime(131));
+}
+
+TEST_P(PrimeTableTest, CanGetNextPrime) {
+  EXPECT_EQ(2, table_->GetNextPrime(0));
+  EXPECT_EQ(3, table_->GetNextPrime(2));
+  EXPECT_EQ(5, table_->GetNextPrime(3));
+  EXPECT_EQ(7, table_->GetNextPrime(5));
+  EXPECT_EQ(11, table_->GetNextPrime(7));
+  EXPECT_EQ(131, table_->GetNextPrime(128));
+}
+
+// In order to run value-parameterized tests, you need to instantiate them,
+// or bind them to a list of values which will be used as test parameters.
+// You can instantiate them in a different translation module, or even
+// instantiate them several times.
+//
+// Here, we instantiate our tests with a list of two PrimeTable object
+// factory functions:
+INSTANTIATE_TEST_CASE_P(
+    OnTheFlyAndPreCalculated,
+    PrimeTableTest,
+    Values(&CreateOnTheFlyPrimeTable, &CreatePreCalculatedPrimeTable<1000>));
+
+#else
+
+// Google Test may not support value-parameterized tests with some
+// compilers. If we use conditional compilation to compile out all
+// code referring to the gtest_main library, MSVC linker will not link
+// that library at all and consequently complain about missing entry
+// point defined in that library (fatal error LNK1561: entry point
+// must be defined). This dummy test keeps gtest_main linked in.
+TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
+
+#endif  // GTEST_HAS_PARAM_TEST
diff --git a/protobuf/gtest/samples/sample8_unittest.cc b/protobuf/gtest/samples/sample8_unittest.cc
new file mode 100644
index 0000000..ccf61d9
--- /dev/null
+++ b/protobuf/gtest/samples/sample8_unittest.cc
@@ -0,0 +1,173 @@
+// 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: vladl@google.com (Vlad Losev)
+
+// This sample shows how to test code relying on some global flag variables.
+// Combine() helps with generating all possible combinations of such flags,
+// and each test is given one combination as a parameter.
+
+// Use class definitions to test from this header.
+#include "prime_tables.h"
+
+#include <gtest/gtest.h>
+
+#if GTEST_HAS_COMBINE
+
+// Suppose we want to introduce a new, improved implementation of PrimeTable
+// which combines speed of PrecalcPrimeTable and versatility of
+// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both
+// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more
+// appropriate under the circumstances. But in low memory conditions, it can be
+// told to instantiate without PrecalcPrimeTable instance at all and use only
+// OnTheFlyPrimeTable.
+class HybridPrimeTable : public PrimeTable {
+ public:
+  HybridPrimeTable(bool force_on_the_fly, int max_precalculated)
+      : on_the_fly_impl_(new OnTheFlyPrimeTable),
+        precalc_impl_(force_on_the_fly ? NULL :
+                          new PreCalculatedPrimeTable(max_precalculated)),
+        max_precalculated_(max_precalculated) {}
+  virtual ~HybridPrimeTable() {
+    delete on_the_fly_impl_;
+    delete precalc_impl_;
+  }
+
+  virtual bool IsPrime(int n) const {
+    if (precalc_impl_ != NULL && n < max_precalculated_)
+      return precalc_impl_->IsPrime(n);
+    else
+      return on_the_fly_impl_->IsPrime(n);
+  }
+
+  virtual int GetNextPrime(int p) const {
+    int next_prime = -1;
+    if (precalc_impl_ != NULL && p < max_precalculated_)
+      next_prime = precalc_impl_->GetNextPrime(p);
+
+    return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p);
+  }
+
+ private:
+  OnTheFlyPrimeTable* on_the_fly_impl_;
+  PreCalculatedPrimeTable* precalc_impl_;
+  int max_precalculated_;
+};
+
+using ::testing::TestWithParam;
+using ::testing::Bool;
+using ::testing::Values;
+using ::testing::Combine;
+
+// To test all code paths for HybridPrimeTable we must test it with numbers
+// both within and outside PreCalculatedPrimeTable's capacity and also with
+// PreCalculatedPrimeTable disabled. We do this by defining fixture which will
+// accept different combinations of parameters for instantiating a
+// HybridPrimeTable instance.
+class PrimeTableTest : public TestWithParam< ::std::tr1::tuple<bool, int> > {
+ protected:
+  virtual void SetUp() {
+    // This can be written as
+    //
+    // bool force_on_the_fly;
+    // int max_precalculated;
+    // tie(force_on_the_fly, max_precalculated) = GetParam();
+    //
+    // once the Google C++ Style Guide allows use of ::std::tr1::tie.
+    //
+    bool force_on_the_fly = ::std::tr1::get<0>(GetParam());
+    int max_precalculated = ::std::tr1::get<1>(GetParam());
+    table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);
+  }
+  virtual void TearDown() {
+    delete table_;
+    table_ = NULL;
+  }
+  HybridPrimeTable* table_;
+};
+
+TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
+  // Inside the test body, you can refer to the test parameter by GetParam().
+  // In this case, the test parameter is a PrimeTable interface pointer which
+  // we can use directly.
+  // Please note that you can also save it in the fixture's SetUp() method
+  // or constructor and use saved copy in the tests.
+
+  EXPECT_FALSE(table_->IsPrime(-5));
+  EXPECT_FALSE(table_->IsPrime(0));
+  EXPECT_FALSE(table_->IsPrime(1));
+  EXPECT_FALSE(table_->IsPrime(4));
+  EXPECT_FALSE(table_->IsPrime(6));
+  EXPECT_FALSE(table_->IsPrime(100));
+}
+
+TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
+  EXPECT_TRUE(table_->IsPrime(2));
+  EXPECT_TRUE(table_->IsPrime(3));
+  EXPECT_TRUE(table_->IsPrime(5));
+  EXPECT_TRUE(table_->IsPrime(7));
+  EXPECT_TRUE(table_->IsPrime(11));
+  EXPECT_TRUE(table_->IsPrime(131));
+}
+
+TEST_P(PrimeTableTest, CanGetNextPrime) {
+  EXPECT_EQ(2, table_->GetNextPrime(0));
+  EXPECT_EQ(3, table_->GetNextPrime(2));
+  EXPECT_EQ(5, table_->GetNextPrime(3));
+  EXPECT_EQ(7, table_->GetNextPrime(5));
+  EXPECT_EQ(11, table_->GetNextPrime(7));
+  EXPECT_EQ(131, table_->GetNextPrime(128));
+}
+
+// In order to run value-parameterized tests, you need to instantiate them,
+// or bind them to a list of values which will be used as test parameters.
+// You can instantiate them in a different translation module, or even
+// instantiate them several times.
+//
+// Here, we instantiate our tests with a list of parameters. We must combine
+// all variations of the boolean flag suppressing PrecalcPrimeTable and some
+// meaningful values for tests. We choose a small value (1), and a value that
+// will put some of the tested numbers beyond the capability of the
+// PrecalcPrimeTable instance and some inside it (10). Combine will produce all
+// possible combinations.
+INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters,
+                        PrimeTableTest,
+                        Combine(Bool(), Values(1, 10)));
+
+#else
+
+// Google Test may not support Combine() with some compilers. If we
+// use conditional compilation to compile out all code referring to
+// the gtest_main library, MSVC linker will not link that library at
+// all and consequently complain about missing entry point defined in
+// that library (fatal error LNK1561: entry point must be
+// defined). This dummy test keeps gtest_main linked in.
+TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {}
+
+#endif  // GTEST_HAS_COMBINE
diff --git a/protobuf/gtest/samples/sample9_unittest.cc b/protobuf/gtest/samples/sample9_unittest.cc
new file mode 100644
index 0000000..d828ef4
--- /dev/null
+++ b/protobuf/gtest/samples/sample9_unittest.cc
@@ -0,0 +1,160 @@
+// Copyright 2009 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: vladl@google.com (Vlad Losev)
+
+// This sample shows how to use Google Test listener API to implement
+// an alternative console output and how to use the UnitTest reflection API
+// to enumerate test cases and tests and to inspect their results.
+
+#include <stdio.h>
+
+#include <gtest/gtest.h>
+
+using ::testing::EmptyTestEventListener;
+using ::testing::InitGoogleTest;
+using ::testing::Test;
+using ::testing::TestCase;
+using ::testing::TestEventListeners;
+using ::testing::TestInfo;
+using ::testing::TestPartResult;
+using ::testing::UnitTest;
+
+namespace {
+
+// Provides alternative output mode which produces minimal amount of
+// information about tests.
+class TersePrinter : public EmptyTestEventListener {
+ private:
+  // Called before any test activity starts.
+  virtual void OnTestProgramStart(const UnitTest& /* unit_test */) {}
+
+  // Called after all test activities have ended.
+  virtual void OnTestProgramEnd(const UnitTest& unit_test) {
+    fprintf(stdout, "TEST %s\n", unit_test.Passed() ? "PASSED" : "FAILED");
+    fflush(stdout);
+  }
+
+  // Called before a test starts.
+  virtual void OnTestStart(const TestInfo& test_info) {
+    fprintf(stdout,
+            "*** Test %s.%s starting.\n",
+            test_info.test_case_name(),
+            test_info.name());
+    fflush(stdout);
+  }
+
+  // Called after a failed assertion or a SUCCESS().
+  virtual void OnTestPartResult(const TestPartResult& test_part_result) {
+    fprintf(stdout,
+            "%s in %s:%d\n%s\n",
+            test_part_result.failed() ? "*** Failure" : "Success",
+            test_part_result.file_name(),
+            test_part_result.line_number(),
+            test_part_result.summary());
+    fflush(stdout);
+  }
+
+  // Called after a test ends.
+  virtual void OnTestEnd(const TestInfo& test_info) {
+    fprintf(stdout,
+            "*** Test %s.%s ending.\n",
+            test_info.test_case_name(),
+            test_info.name());
+    fflush(stdout);
+  }
+};  // class TersePrinter
+
+TEST(CustomOutputTest, PrintsMessage) {
+  printf("Printing something from the test body...\n");
+}
+
+TEST(CustomOutputTest, Succeeds) {
+  SUCCEED() << "SUCCEED() has been invoked from here";
+}
+
+TEST(CustomOutputTest, Fails) {
+  EXPECT_EQ(1, 2)
+      << "This test fails in order to demonstrate alternative failure messages";
+}
+
+}  // namespace
+
+int main(int argc, char **argv) {
+  InitGoogleTest(&argc, argv);
+
+  bool terse_output = false;
+  if (argc > 1 && strcmp(argv[1], "--terse_output") == 0 )
+    terse_output = true;
+  else
+    printf("%s\n", "Run this program with --terse_output to change the way "
+           "it prints its output.");
+
+  UnitTest& unit_test = *UnitTest::GetInstance();
+
+  // If we are given the --terse_output command line flag, suppresses the
+  // standard output and attaches own result printer.
+  if (terse_output) {
+    TestEventListeners& listeners = unit_test.listeners();
+
+    // Removes the default console output listener from the list so it will
+    // not receive events from Google Test and won't print any output. Since
+    // this operation transfers ownership of the listener to the caller we
+    // have to delete it as well.
+    delete listeners.Release(listeners.default_result_printer());
+
+    // Adds the custom output listener to the list. It will now receive
+    // events from Google Test and print the alternative output. We don't
+    // have to worry about deleting it since Google Test assumes ownership
+    // over it after adding it to the list.
+    listeners.Append(new TersePrinter);
+  }
+  int ret_val = RUN_ALL_TESTS();
+
+  // This is an example of using the UnitTest reflection API to inspect test
+  // results. Here we discount failures from the tests we expected to fail.
+  int unexpectedly_failed_tests = 0;
+  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
+    const TestCase& test_case = *unit_test.GetTestCase(i);
+    for (int j = 0; j < test_case.total_test_count(); ++j) {
+      const TestInfo& test_info = *test_case.GetTestInfo(j);
+      // Counts failed tests that were not meant to fail (those without
+      // 'Fails' in the name).
+      if (test_info.result()->Failed() &&
+          strcmp(test_info.name(), "Fails") != 0) {
+        unexpectedly_failed_tests++;
+      }
+    }
+  }
+
+  // Test that were meant to fail should not affect the test program outcome.
+  if (unexpectedly_failed_tests == 0)
+    ret_val = 0;
+
+  return ret_val;
+}
diff --git a/protobuf/gtest/scripts/fuse_gtest_files.py b/protobuf/gtest/scripts/fuse_gtest_files.py
new file mode 100755
index 0000000..148444c
--- /dev/null
+++ b/protobuf/gtest/scripts/fuse_gtest_files.py
@@ -0,0 +1,250 @@
+#!/usr/bin/env python
+#
+# Copyright 2009, 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.
+
+"""fuse_gtest_files.py v0.2.0
+Fuses Google Test source code into a .h file and a .cc file.
+
+SYNOPSIS
+       fuse_gtest_files.py [GTEST_ROOT_DIR] OUTPUT_DIR
+
+       Scans GTEST_ROOT_DIR for Google Test source code, and generates
+       two files: OUTPUT_DIR/gtest/gtest.h and OUTPUT_DIR/gtest/gtest-all.cc.
+       Then you can build your tests by adding OUTPUT_DIR to the include
+       search path and linking with OUTPUT_DIR/gtest/gtest-all.cc.  These
+       two files contain everything you need to use Google Test.  Hence
+       you can "install" Google Test by copying them to wherever you want.
+
+       GTEST_ROOT_DIR can be omitted and defaults to the parent
+       directory of the directory holding this script.
+
+EXAMPLES
+       ./fuse_gtest_files.py fused_gtest
+       ./fuse_gtest_files.py path/to/unpacked/gtest fused_gtest
+
+This tool is experimental.  In particular, it assumes that there is no
+conditional inclusion of Google Test headers.  Please report any
+problems to googletestframework@googlegroups.com.  You can read
+http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide for
+more information.
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import re
+import sets
+import sys
+
+# We assume that this file is in the scripts/ directory in the Google
+# Test root directory.
+DEFAULT_GTEST_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..')
+
+# Regex for matching '#include <gtest/...>'.
+INCLUDE_GTEST_FILE_REGEX = re.compile(r'^\s*#\s*include\s*<(gtest/.+)>')
+
+# Regex for matching '#include "src/..."'.
+INCLUDE_SRC_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(src/.+)"')
+
+# Where to find the source seed files.
+GTEST_H_SEED = 'include/gtest/gtest.h'
+GTEST_SPI_H_SEED = 'include/gtest/gtest-spi.h'
+GTEST_ALL_CC_SEED = 'src/gtest-all.cc'
+
+# Where to put the generated files.
+GTEST_H_OUTPUT = 'gtest/gtest.h'
+GTEST_ALL_CC_OUTPUT = 'gtest/gtest-all.cc'
+
+
+def VerifyFileExists(directory, relative_path):
+  """Verifies that the given file exists; aborts on failure.
+
+  relative_path is the file path relative to the given directory.
+  """
+
+  if not os.path.isfile(os.path.join(directory, relative_path)):
+    print 'ERROR: Cannot find %s in directory %s.' % (relative_path,
+                                                      directory)
+    print ('Please either specify a valid project root directory '
+           'or omit it on the command line.')
+    sys.exit(1)
+
+
+def ValidateGTestRootDir(gtest_root):
+  """Makes sure gtest_root points to a valid gtest root directory.
+
+  The function aborts the program on failure.
+  """
+
+  VerifyFileExists(gtest_root, GTEST_H_SEED)
+  VerifyFileExists(gtest_root, GTEST_ALL_CC_SEED)
+
+
+def VerifyOutputFile(output_dir, relative_path):
+  """Verifies that the given output file path is valid.
+
+  relative_path is relative to the output_dir directory.
+  """
+
+  # Makes sure the output file either doesn't exist or can be overwritten.
+  output_file = os.path.join(output_dir, relative_path)
+  if os.path.exists(output_file):
+    # TODO(wan@google.com): The following user-interaction doesn't
+    # work with automated processes.  We should provide a way for the
+    # Makefile to force overwriting the files.
+    print ('%s already exists in directory %s - overwrite it? (y/N) ' %
+           (relative_path, output_dir))
+    answer = sys.stdin.readline().strip()
+    if answer not in ['y', 'Y']:
+      print 'ABORTED.'
+      sys.exit(1)
+
+  # Makes sure the directory holding the output file exists; creates
+  # it and all its ancestors if necessary.
+  parent_directory = os.path.dirname(output_file)
+  if not os.path.isdir(parent_directory):
+    os.makedirs(parent_directory)
+
+
+def ValidateOutputDir(output_dir):
+  """Makes sure output_dir points to a valid output directory.
+
+  The function aborts the program on failure.
+  """
+
+  VerifyOutputFile(output_dir, GTEST_H_OUTPUT)
+  VerifyOutputFile(output_dir, GTEST_ALL_CC_OUTPUT)
+
+
+def FuseGTestH(gtest_root, output_dir):
+  """Scans folder gtest_root to generate gtest/gtest.h in output_dir."""
+
+  output_file = file(os.path.join(output_dir, GTEST_H_OUTPUT), 'w')
+  processed_files = sets.Set()  # Holds all gtest headers we've processed.
+
+  def ProcessFile(gtest_header_path):
+    """Processes the given gtest header file."""
+
+    # We don't process the same header twice.
+    if gtest_header_path in processed_files:
+      return
+
+    processed_files.add(gtest_header_path)
+
+    # Reads each line in the given gtest header.
+    for line in file(os.path.join(gtest_root, gtest_header_path), 'r'):
+      m = INCLUDE_GTEST_FILE_REGEX.match(line)
+      if m:
+        # It's '#include <gtest/...>' - let's process it recursively.
+        ProcessFile('include/' + m.group(1))
+      else:
+        # Otherwise we copy the line unchanged to the output file.
+        output_file.write(line)
+
+  ProcessFile(GTEST_H_SEED)
+  output_file.close()
+
+
+def FuseGTestAllCcToFile(gtest_root, output_file):
+  """Scans folder gtest_root to generate gtest/gtest-all.cc in output_file."""
+
+  processed_files = sets.Set()
+
+  def ProcessFile(gtest_source_file):
+    """Processes the given gtest source file."""
+
+    # We don't process the same #included file twice.
+    if gtest_source_file in processed_files:
+      return
+
+    processed_files.add(gtest_source_file)
+
+    # Reads each line in the given gtest source file.
+    for line in file(os.path.join(gtest_root, gtest_source_file), 'r'):
+      m = INCLUDE_GTEST_FILE_REGEX.match(line)
+      if m:
+        if 'include/' + m.group(1) == GTEST_SPI_H_SEED:
+          # It's '#include <gtest/gtest-spi.h>'.  This file is not
+          # #included by <gtest/gtest.h>, so we need to process it.
+          ProcessFile(GTEST_SPI_H_SEED)
+        else:
+          # It's '#include <gtest/foo.h>' where foo is not gtest-spi.
+          # We treat it as '#include <gtest/gtest.h>', as all other
+          # gtest headers are being fused into gtest.h and cannot be
+          # #included directly.
+
+          # There is no need to #include <gtest/gtest.h> more than once.
+          if not GTEST_H_SEED in processed_files:
+            processed_files.add(GTEST_H_SEED)
+            output_file.write('#include <%s>\n' % (GTEST_H_OUTPUT,))
+      else:
+        m = INCLUDE_SRC_FILE_REGEX.match(line)
+        if m:
+          # It's '#include "src/foo"' - let's process it recursively.
+          ProcessFile(m.group(1))
+        else:
+          output_file.write(line)
+
+  ProcessFile(GTEST_ALL_CC_SEED)
+
+
+def FuseGTestAllCc(gtest_root, output_dir):
+  """Scans folder gtest_root to generate gtest/gtest-all.cc in output_dir."""
+
+  output_file = file(os.path.join(output_dir, GTEST_ALL_CC_OUTPUT), 'w')
+  FuseGTestAllCcToFile(gtest_root, output_file)
+  output_file.close()
+
+
+def FuseGTest(gtest_root, output_dir):
+  """Fuses gtest.h and gtest-all.cc."""
+
+  ValidateGTestRootDir(gtest_root)
+  ValidateOutputDir(output_dir)
+
+  FuseGTestH(gtest_root, output_dir)
+  FuseGTestAllCc(gtest_root, output_dir)
+
+
+def main():
+  argc = len(sys.argv)
+  if argc == 2:
+    # fuse_gtest_files.py OUTPUT_DIR
+    FuseGTest(DEFAULT_GTEST_ROOT_DIR, sys.argv[1])
+  elif argc == 3:
+    # fuse_gtest_files.py GTEST_ROOT_DIR OUTPUT_DIR
+    FuseGTest(sys.argv[1], sys.argv[2])
+  else:
+    print __doc__
+    sys.exit(1)
+
+
+if __name__ == '__main__':
+  main()
diff --git a/protobuf/gtest/scripts/gen_gtest_pred_impl.py b/protobuf/gtest/scripts/gen_gtest_pred_impl.py
new file mode 100755
index 0000000..8307134
--- /dev/null
+++ b/protobuf/gtest/scripts/gen_gtest_pred_impl.py
@@ -0,0 +1,733 @@
+#!/usr/bin/env python
+#
+# 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/protobuf/gtest/scripts/gtest-config.in b/protobuf/gtest/scripts/gtest-config.in
new file mode 100755
index 0000000..9c72638
--- /dev/null
+++ b/protobuf/gtest/scripts/gtest-config.in
@@ -0,0 +1,274 @@
+#!/bin/sh
+
+# These variables are automatically filled in by the configure script.
+name="@PACKAGE_TARNAME@"
+version="@PACKAGE_VERSION@"
+
+show_usage()
+{
+  echo "Usage: gtest-config [OPTIONS...]"
+}
+
+show_help()
+{
+  show_usage
+  cat <<\EOF
+
+The `gtest-config' script provides access to the necessary compile and linking
+flags to connect with Google C++ Testing Framework, both in a build prior to
+installation, and on the system proper after installation. The installation
+overrides may be issued in combination with any other queries, but will only
+affect installation queries if called on a built but not installed gtest. The
+installation queries may not be issued with any other types of queries, and
+only one installation query may be made at a time. The version queries and
+compiler flag queries may be combined as desired but not mixed. Different
+version queries are always combined with logical "and" semantics, and only the
+last of any particular query is used while all previous ones ignored. All
+versions must be specified as a sequence of numbers separated by periods.
+Compiler flag queries output the union of the sets of flags when combined.
+
+ Examples:
+  gtest-config --min-version=1.0 || echo "Insufficient Google Test version."
+
+  g++ $(gtest-config --cppflags --cxxflags) -o foo.o -c foo.cpp
+  g++ $(gtest-config --ldflags --libs) -o foo foo.o
+
+  # When using a built but not installed Google Test:
+  g++ $(../../my_gtest_build/scripts/gtest-config ...) ...
+
+  # When using an installed Google Test, but with installation overrides:
+  export GTEST_PREFIX="/opt"
+  g++ $(gtest-config --libdir="/opt/lib64" ...) ...
+
+ Help:
+  --usage                    brief usage information
+  --help                     display this help message
+
+ Installation Overrides:
+  --prefix=<dir>             overrides the installation prefix
+  --exec-prefix=<dir>        overrides the executable installation prefix
+  --libdir=<dir>             overrides the library installation prefix
+  --includedir=<dir>         overrides the header file installation prefix
+
+ Installation Queries:
+  --prefix                   installation prefix
+  --exec-prefix              executable installation prefix
+  --libdir                   library installation directory
+  --includedir               header file installation directory
+  --version                  the version of the Google Test installation
+
+ Version Queries:
+  --min-version=VERSION      return 0 if the version is at least VERSION
+  --exact-version=VERSION    return 0 if the version is exactly VERSION
+  --max-version=VERSION      return 0 if the version is at most VERSION
+
+ Compilation Flag Queries:
+  --cppflags                 compile flags specific to the C-like preprocessors
+  --cxxflags                 compile flags appropriate for C++ programs
+  --ldflags                  linker flags
+  --libs                     libraries for linking
+
+EOF
+}
+
+# This function bounds our version with a min and a max. It uses some clever
+# POSIX-compliant variable expansion to portably do all the work in the shell
+# and avoid any dependency on a particular "sed" or "awk" implementation.
+# Notable is that it will only ever compare the first 3 components of versions.
+# Further components will be cleanly stripped off. All versions must be
+# unadorned, so "v1.0" will *not* work. The minimum version must be in $1, and
+# the max in $2. TODO(chandlerc@google.com): If this ever breaks, we should
+# investigate expanding this via autom4te from AS_VERSION_COMPARE rather than
+# continuing to maintain our own shell version.
+check_versions()
+{
+  major_version=${version%%.*}
+  minor_version="0"
+  point_version="0"
+  if test "${version#*.}" != "${version}"; then
+    minor_version=${version#*.}
+    minor_version=${minor_version%%.*}
+  fi
+  if test "${version#*.*.}" != "${version}"; then
+    point_version=${version#*.*.}
+    point_version=${point_version%%.*}
+  fi
+
+  min_version="$1"
+  min_major_version=${min_version%%.*}
+  min_minor_version="0"
+  min_point_version="0"
+  if test "${min_version#*.}" != "${min_version}"; then
+    min_minor_version=${min_version#*.}
+    min_minor_version=${min_minor_version%%.*}
+  fi
+  if test "${min_version#*.*.}" != "${min_version}"; then
+    min_point_version=${min_version#*.*.}
+    min_point_version=${min_point_version%%.*}
+  fi
+
+  max_version="$2"
+  max_major_version=${max_version%%.*}
+  max_minor_version="0"
+  max_point_version="0"
+  if test "${max_version#*.}" != "${max_version}"; then
+    max_minor_version=${max_version#*.}
+    max_minor_version=${max_minor_version%%.*}
+  fi
+  if test "${max_version#*.*.}" != "${max_version}"; then
+    max_point_version=${max_version#*.*.}
+    max_point_version=${max_point_version%%.*}
+  fi
+
+  test $(($major_version)) -lt $(($min_major_version)) && exit 1
+  if test $(($major_version)) -eq $(($min_major_version)); then
+    test $(($minor_version)) -lt $(($min_minor_version)) && exit 1
+    if test $(($minor_version)) -eq $(($min_minor_version)); then
+      test $(($point_version)) -lt $(($min_point_version)) && exit 1
+    fi
+  fi
+
+  test $(($major_version)) -gt $(($max_major_version)) && exit 1
+  if test $(($major_version)) -eq $(($max_major_version)); then
+    test $(($minor_version)) -gt $(($max_minor_version)) && exit 1
+    if test $(($minor_version)) -eq $(($max_minor_version)); then
+      test $(($point_version)) -gt $(($max_point_version)) && exit 1
+    fi
+  fi
+
+  exit 0
+}
+
+# Show the usage line when no arguments are specified.
+if test $# -eq 0; then
+  show_usage
+  exit 1
+fi
+
+while test $# -gt 0; do
+  case $1 in
+    --usage)          show_usage;         exit 0;;
+    --help)           show_help;          exit 0;;
+
+    # Installation overrides
+    --prefix=*)       GTEST_PREFIX=${1#--prefix=};;
+    --exec-prefix=*)  GTEST_EXEC_PREFIX=${1#--exec-prefix=};;
+    --libdir=*)       GTEST_LIBDIR=${1#--libdir=};;
+    --includedir=*)   GTEST_INCLUDEDIR=${1#--includedir=};;
+
+    # Installation queries
+    --prefix|--exec-prefix|--libdir|--includedir|--version)
+      if test -n "${do_query}"; then
+        show_usage
+        exit 1
+      fi
+      do_query=${1#--}
+      ;;
+
+    # Version checking
+    --min-version=*)
+      do_check_versions=yes
+      min_version=${1#--min-version=}
+      ;;
+    --max-version=*)
+      do_check_versions=yes
+      max_version=${1#--max-version=}
+      ;;
+    --exact-version=*)
+      do_check_versions=yes
+      exact_version=${1#--exact-version=}
+      ;;
+
+    # Compiler flag output
+    --cppflags)       echo_cppflags=yes;;
+    --cxxflags)       echo_cxxflags=yes;;
+    --ldflags)        echo_ldflags=yes;;
+    --libs)           echo_libs=yes;;
+
+    # Everything else is an error
+    *)                show_usage;         exit 1;;
+  esac
+  shift
+done
+
+# These have defaults filled in by the configure script but can also be
+# overridden by environment variables or command line parameters.
+prefix="${GTEST_PREFIX:-@prefix@}"
+exec_prefix="${GTEST_EXEC_PREFIX:-@exec_prefix@}"
+libdir="${GTEST_LIBDIR:-@libdir@}"
+includedir="${GTEST_INCLUDEDIR:-@includedir@}"
+
+# We try and detect if our binary is not located at its installed location. If
+# it's not, we provide variables pointing to the source and build tree rather
+# than to the install tree. This allows building against a just-built gtest
+# rather than an installed gtest.
+bindir="@bindir@"
+this_relative_bindir=`dirname $0`
+this_bindir=`cd ${this_relative_bindir}; pwd -P`
+if test "${this_bindir}" = "${this_bindir%${bindir}}"; then
+  # The path to the script doesn't end in the bindir sequence from Autoconf,
+  # assume that we are in a build tree.
+  build_dir=`dirname ${this_bindir}`
+  src_dir=`cd ${this_bindir}/@top_srcdir@; pwd -P`
+
+  # TODO(chandlerc@google.com): This is a dangerous dependency on libtool, we
+  # should work to remove it, and/or remove libtool altogether, replacing it
+  # with direct references to the library and a link path.
+  gtest_libs="${build_dir}/lib/libgtest.la @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
+  gtest_ldflags=""
+
+  # We provide hooks to include from either the source or build dir, where the
+  # build dir is always preferred. This will potentially allow us to write
+  # build rules for generated headers and have them automatically be preferred
+  # over provided versions.
+  gtest_cppflags="-I${build_dir}/include -I${src_dir}/include"
+  gtest_cxxflags="@PTHREAD_CFLAGS@"
+else
+  # We're using an installed gtest, although it may be staged under some
+  # prefix. Assume (as our own libraries do) that we can resolve the prefix,
+  # and are present in the dynamic link paths.
+  gtest_ldflags="-L${libdir}"
+  gtest_libs="-l${name} @PTHREAD_CFLAGS@ @PTHREAD_LIBS@"
+  gtest_cppflags="-I${includedir}"
+  gtest_cxxflags="@PTHREAD_CFLAGS@"
+fi
+
+# Do an installation query if requested.
+if test -n "$do_query"; then
+  case $do_query in
+    prefix)           echo $prefix;       exit 0;;
+    exec-prefix)      echo $exec_prefix;  exit 0;;
+    libdir)           echo $libdir;       exit 0;;
+    includedir)       echo $includedir;   exit 0;;
+    version)          echo $version;      exit 0;;
+    *)                show_usage;         exit 1;;
+  esac
+fi
+
+# Do a version check if requested.
+if test "$do_check_versions" = "yes"; then
+  # Make sure we didn't receive a bad combination of parameters.
+  test "$echo_cppflags" = "yes" && show_usage && exit 1
+  test "$echo_cxxflags" = "yes" && show_usage && exit 1
+  test "$echo_ldflags" = "yes"  && show_usage && exit 1
+  test "$echo_libs" = "yes"     && show_usage && exit 1
+
+  if test "$exact_version" != ""; then
+    check_versions $exact_version $exact_version
+    # unreachable
+  else
+    check_versions ${min_version:-0.0.0} ${max_version:-9999.9999.9999}
+    # unreachable
+  fi
+fi
+
+# Do the output in the correct order so that these can be used in-line of
+# a compiler invocation.
+output=""
+test "$echo_cppflags" = "yes" && output="$output $gtest_cppflags"
+test "$echo_cxxflags" = "yes" && output="$output $gtest_cxxflags"
+test "$echo_ldflags" = "yes"  && output="$output $gtest_ldflags"
+test "$echo_libs" = "yes"     && output="$output $gtest_libs"
+echo $output
+
+exit 0
diff --git a/protobuf/gtest/scripts/pump.py b/protobuf/gtest/scripts/pump.py
new file mode 100755
index 0000000..f15c1b6
--- /dev/null
+++ b/protobuf/gtest/scripts/pump.py
@@ -0,0 +1,835 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""pump v0.1 - Pretty Useful for Meta Programming.
+
+A tool for preprocessor meta programming.  Useful for generating
+repetitive boilerplate code.  Especially useful for writing C++
+classes, functions, macros, and templates that need to work with
+various number of arguments.
+
+USAGE:
+       pump.py SOURCE_FILE
+
+EXAMPLES:
+       pump.py foo.cc.pump
+         Converts foo.cc.pump to foo.cc.
+
+GRAMMAR:
+       CODE ::= ATOMIC_CODE*
+       ATOMIC_CODE ::= $var ID = EXPRESSION
+           | $var ID = [[ CODE ]]
+           | $range ID EXPRESSION..EXPRESSION
+           | $for ID SEPARATOR [[ CODE ]]
+           | $($)
+           | $ID
+           | $(EXPRESSION)
+           | $if EXPRESSION [[ CODE ]] ELSE_BRANCH
+           | [[ CODE ]]
+           | RAW_CODE
+       SEPARATOR ::= RAW_CODE | EMPTY
+       ELSE_BRANCH ::= $else [[ CODE ]]
+           | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH
+           | EMPTY
+       EXPRESSION has Python syntax.
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import re
+import sys
+
+
+TOKEN_TABLE = [
+    (re.compile(r'\$var\s+'), '$var'),
+    (re.compile(r'\$elif\s+'), '$elif'),
+    (re.compile(r'\$else\s+'), '$else'),
+    (re.compile(r'\$for\s+'), '$for'),
+    (re.compile(r'\$if\s+'), '$if'),
+    (re.compile(r'\$range\s+'), '$range'),
+    (re.compile(r'\$[_A-Za-z]\w*'), '$id'),
+    (re.compile(r'\$\(\$\)'), '$($)'),
+    (re.compile(r'\$\$.*'), '$$'),
+    (re.compile(r'\$'), '$'),
+    (re.compile(r'\[\[\n?'), '[['),
+    (re.compile(r'\]\]\n?'), ']]'),
+    ]
+
+
+class Cursor:
+  """Represents a position (line and column) in a text file."""
+
+  def __init__(self, line=-1, column=-1):
+    self.line = line
+    self.column = column
+
+  def __eq__(self, rhs):
+    return self.line == rhs.line and self.column == rhs.column
+
+  def __ne__(self, rhs):
+    return not self == rhs
+
+  def __lt__(self, rhs):
+    return self.line < rhs.line or (
+        self.line == rhs.line and self.column < rhs.column)
+
+  def __le__(self, rhs):
+    return self < rhs or self == rhs
+
+  def __gt__(self, rhs):
+    return rhs < self
+
+  def __ge__(self, rhs):
+    return rhs <= self
+
+  def __str__(self):
+    if self == Eof():
+      return 'EOF'
+    else:
+      return '%s(%s)' % (self.line + 1, self.column)
+
+  def __add__(self, offset):
+    return Cursor(self.line, self.column + offset)
+
+  def __sub__(self, offset):
+    return Cursor(self.line, self.column - offset)
+
+  def Clone(self):
+    """Returns a copy of self."""
+
+    return Cursor(self.line, self.column)
+
+
+# Special cursor to indicate the end-of-file.
+def Eof():
+  """Returns the special cursor to denote the end-of-file."""
+  return Cursor(-1, -1)
+
+
+class Token:
+  """Represents a token in a Pump source file."""
+
+  def __init__(self, start=None, end=None, value=None, token_type=None):
+    if start is None:
+      self.start = Eof()
+    else:
+      self.start = start
+    if end is None:
+      self.end = Eof()
+    else:
+      self.end = end
+    self.value = value
+    self.token_type = token_type
+
+  def __str__(self):
+    return 'Token @%s: \'%s\' type=%s' % (
+        self.start, self.value, self.token_type)
+
+  def Clone(self):
+    """Returns a copy of self."""
+
+    return Token(self.start.Clone(), self.end.Clone(), self.value,
+                 self.token_type)
+
+
+def StartsWith(lines, pos, string):
+  """Returns True iff the given position in lines starts with 'string'."""
+
+  return lines[pos.line][pos.column:].startswith(string)
+
+
+def FindFirstInLine(line, token_table):
+  best_match_start = -1
+  for (regex, token_type) in token_table:
+    m = regex.search(line)
+    if m:
+      # We found regex in lines
+      if best_match_start < 0 or m.start() < best_match_start:
+        best_match_start = m.start()
+        best_match_length = m.end() - m.start()
+        best_match_token_type = token_type
+
+  if best_match_start < 0:
+    return None
+
+  return (best_match_start, best_match_length, best_match_token_type)
+
+
+def FindFirst(lines, token_table, cursor):
+  """Finds the first occurrence of any string in strings in lines."""
+
+  start = cursor.Clone()
+  cur_line_number = cursor.line
+  for line in lines[start.line:]:
+    if cur_line_number == start.line:
+      line = line[start.column:]
+    m = FindFirstInLine(line, token_table)
+    if m:
+      # We found a regex in line.
+      (start_column, length, token_type) = m
+      if cur_line_number == start.line:
+        start_column += start.column
+      found_start = Cursor(cur_line_number, start_column)
+      found_end = found_start + length
+      return MakeToken(lines, found_start, found_end, token_type)
+    cur_line_number += 1
+  # We failed to find str in lines
+  return None
+
+
+def SubString(lines, start, end):
+  """Returns a substring in lines."""
+
+  if end == Eof():
+    end = Cursor(len(lines) - 1, len(lines[-1]))
+
+  if start >= end:
+    return ''
+
+  if start.line == end.line:
+    return lines[start.line][start.column:end.column]
+
+  result_lines = ([lines[start.line][start.column:]] +
+                  lines[start.line + 1:end.line] +
+                  [lines[end.line][:end.column]])
+  return ''.join(result_lines)
+
+
+def MakeToken(lines, start, end, token_type):
+  """Creates a new instance of Token."""
+
+  return Token(start, end, SubString(lines, start, end), token_type)
+
+
+def ParseToken(lines, pos, regex, token_type):
+  line = lines[pos.line][pos.column:]
+  m = regex.search(line)
+  if m and not m.start():
+    return MakeToken(lines, pos, pos + m.end(), token_type)
+  else:
+    print 'ERROR: %s expected at %s.' % (token_type, pos)
+    sys.exit(1)
+
+
+ID_REGEX = re.compile(r'[_A-Za-z]\w*')
+EQ_REGEX = re.compile(r'=')
+REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)')
+OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*')
+WHITE_SPACE_REGEX = re.compile(r'\s')
+DOT_DOT_REGEX = re.compile(r'\.\.')
+
+
+def Skip(lines, pos, regex):
+  line = lines[pos.line][pos.column:]
+  m = re.search(regex, line)
+  if m and not m.start():
+    return pos + m.end()
+  else:
+    return pos
+
+
+def SkipUntil(lines, pos, regex, token_type):
+  line = lines[pos.line][pos.column:]
+  m = re.search(regex, line)
+  if m:
+    return pos + m.start()
+  else:
+    print ('ERROR: %s expected on line %s after column %s.' %
+           (token_type, pos.line + 1, pos.column))
+    sys.exit(1)
+
+
+def ParseExpTokenInParens(lines, pos):
+  def ParseInParens(pos):
+    pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX)
+    pos = Skip(lines, pos, r'\(')
+    pos = Parse(pos)
+    pos = Skip(lines, pos, r'\)')
+    return pos
+
+  def Parse(pos):
+    pos = SkipUntil(lines, pos, r'\(|\)', ')')
+    if SubString(lines, pos, pos + 1) == '(':
+      pos = Parse(pos + 1)
+      pos = Skip(lines, pos, r'\)')
+      return Parse(pos)
+    else:
+      return pos
+
+  start = pos.Clone()
+  pos = ParseInParens(pos)
+  return MakeToken(lines, start, pos, 'exp')
+
+
+def RStripNewLineFromToken(token):
+  if token.value.endswith('\n'):
+    return Token(token.start, token.end, token.value[:-1], token.token_type)
+  else:
+    return token
+
+
+def TokenizeLines(lines, pos):
+  while True:
+    found = FindFirst(lines, TOKEN_TABLE, pos)
+    if not found:
+      yield MakeToken(lines, pos, Eof(), 'code')
+      return
+
+    if found.start == pos:
+      prev_token = None
+      prev_token_rstripped = None
+    else:
+      prev_token = MakeToken(lines, pos, found.start, 'code')
+      prev_token_rstripped = RStripNewLineFromToken(prev_token)
+
+    if found.token_type == '$$':  # A meta comment.
+      if prev_token_rstripped:
+        yield prev_token_rstripped
+      pos = Cursor(found.end.line + 1, 0)
+    elif found.token_type == '$var':
+      if prev_token_rstripped:
+        yield prev_token_rstripped
+      yield found
+      id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
+      yield id_token
+      pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
+
+      eq_token = ParseToken(lines, pos, EQ_REGEX, '=')
+      yield eq_token
+      pos = Skip(lines, eq_token.end, r'\s*')
+
+      if SubString(lines, pos, pos + 2) != '[[':
+        exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp')
+        yield exp_token
+        pos = Cursor(exp_token.end.line + 1, 0)
+    elif found.token_type == '$for':
+      if prev_token_rstripped:
+        yield prev_token_rstripped
+      yield found
+      id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
+      yield id_token
+      pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX)
+    elif found.token_type == '$range':
+      if prev_token_rstripped:
+        yield prev_token_rstripped
+      yield found
+      id_token = ParseToken(lines, found.end, ID_REGEX, 'id')
+      yield id_token
+      pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX)
+
+      dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..')
+      yield MakeToken(lines, pos, dots_pos, 'exp')
+      yield MakeToken(lines, dots_pos, dots_pos + 2, '..')
+      pos = dots_pos + 2
+      new_pos = Cursor(pos.line + 1, 0)
+      yield MakeToken(lines, pos, new_pos, 'exp')
+      pos = new_pos
+    elif found.token_type == '$':
+      if prev_token:
+        yield prev_token
+      yield found
+      exp_token = ParseExpTokenInParens(lines, found.end)
+      yield exp_token
+      pos = exp_token.end
+    elif (found.token_type == ']]' or found.token_type == '$if' or
+          found.token_type == '$elif' or found.token_type == '$else'):
+      if prev_token_rstripped:
+        yield prev_token_rstripped
+      yield found
+      pos = found.end
+    else:
+      if prev_token:
+        yield prev_token
+      yield found
+      pos = found.end
+
+
+def Tokenize(s):
+  lines = s.splitlines(True)
+  return TokenizeLines(lines, Cursor(0, 0))
+
+
+class CodeNode:
+  def __init__(self, atomic_code_list=None):
+    self.atomic_code = atomic_code_list
+
+
+class VarNode:
+  def __init__(self, identifier=None, atomic_code=None):
+    self.identifier = identifier
+    self.atomic_code = atomic_code
+
+
+class RangeNode:
+  def __init__(self, identifier=None, exp1=None, exp2=None):
+    self.identifier = identifier
+    self.exp1 = exp1
+    self.exp2 = exp2
+
+
+class ForNode:
+  def __init__(self, identifier=None, sep=None, code=None):
+    self.identifier = identifier
+    self.sep = sep
+    self.code = code
+
+
+class ElseNode:
+  def __init__(self, else_branch=None):
+    self.else_branch = else_branch
+
+
+class IfNode:
+  def __init__(self, exp=None, then_branch=None, else_branch=None):
+    self.exp = exp
+    self.then_branch = then_branch
+    self.else_branch = else_branch
+
+
+class RawCodeNode:
+  def __init__(self, token=None):
+    self.raw_code = token
+
+
+class LiteralDollarNode:
+  def __init__(self, token):
+    self.token = token
+
+
+class ExpNode:
+  def __init__(self, token, python_exp):
+    self.token = token
+    self.python_exp = python_exp
+
+
+def PopFront(a_list):
+  head = a_list[0]
+  a_list[:1] = []
+  return head
+
+
+def PushFront(a_list, elem):
+  a_list[:0] = [elem]
+
+
+def PopToken(a_list, token_type=None):
+  token = PopFront(a_list)
+  if token_type is not None and token.token_type != token_type:
+    print 'ERROR: %s expected at %s' % (token_type, token.start)
+    print 'ERROR: %s found instead' % (token,)
+    sys.exit(1)
+
+  return token
+
+
+def PeekToken(a_list):
+  if not a_list:
+    return None
+
+  return a_list[0]
+
+
+def ParseExpNode(token):
+  python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value)
+  return ExpNode(token, python_exp)
+
+
+def ParseElseNode(tokens):
+  def Pop(token_type=None):
+    return PopToken(tokens, token_type)
+
+  next = PeekToken(tokens)
+  if not next:
+    return None
+  if next.token_type == '$else':
+    Pop('$else')
+    Pop('[[')
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    return code_node
+  elif next.token_type == '$elif':
+    Pop('$elif')
+    exp = Pop('code')
+    Pop('[[')
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    inner_else_node = ParseElseNode(tokens)
+    return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)])
+  elif not next.value.strip():
+    Pop('code')
+    return ParseElseNode(tokens)
+  else:
+    return None
+
+
+def ParseAtomicCodeNode(tokens):
+  def Pop(token_type=None):
+    return PopToken(tokens, token_type)
+
+  head = PopFront(tokens)
+  t = head.token_type
+  if t == 'code':
+    return RawCodeNode(head)
+  elif t == '$var':
+    id_token = Pop('id')
+    Pop('=')
+    next = PeekToken(tokens)
+    if next.token_type == 'exp':
+      exp_token = Pop()
+      return VarNode(id_token, ParseExpNode(exp_token))
+    Pop('[[')
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    return VarNode(id_token, code_node)
+  elif t == '$for':
+    id_token = Pop('id')
+    next_token = PeekToken(tokens)
+    if next_token.token_type == 'code':
+      sep_token = next_token
+      Pop('code')
+    else:
+      sep_token = None
+    Pop('[[')
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    return ForNode(id_token, sep_token, code_node)
+  elif t == '$if':
+    exp_token = Pop('code')
+    Pop('[[')
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    else_node = ParseElseNode(tokens)
+    return IfNode(ParseExpNode(exp_token), code_node, else_node)
+  elif t == '$range':
+    id_token = Pop('id')
+    exp1_token = Pop('exp')
+    Pop('..')
+    exp2_token = Pop('exp')
+    return RangeNode(id_token, ParseExpNode(exp1_token),
+                     ParseExpNode(exp2_token))
+  elif t == '$id':
+    return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id'))
+  elif t == '$($)':
+    return LiteralDollarNode(head)
+  elif t == '$':
+    exp_token = Pop('exp')
+    return ParseExpNode(exp_token)
+  elif t == '[[':
+    code_node = ParseCodeNode(tokens)
+    Pop(']]')
+    return code_node
+  else:
+    PushFront(tokens, head)
+    return None
+
+
+def ParseCodeNode(tokens):
+  atomic_code_list = []
+  while True:
+    if not tokens:
+      break
+    atomic_code_node = ParseAtomicCodeNode(tokens)
+    if atomic_code_node:
+      atomic_code_list.append(atomic_code_node)
+    else:
+      break
+  return CodeNode(atomic_code_list)
+
+
+def Convert(file_path):
+  s = file(file_path, 'r').read()
+  tokens = []
+  for token in Tokenize(s):
+    tokens.append(token)
+  code_node = ParseCodeNode(tokens)
+  return code_node
+
+
+class Env:
+  def __init__(self):
+    self.variables = []
+    self.ranges = []
+
+  def Clone(self):
+    clone = Env()
+    clone.variables = self.variables[:]
+    clone.ranges = self.ranges[:]
+    return clone
+
+  def PushVariable(self, var, value):
+    # If value looks like an int, store it as an int.
+    try:
+      int_value = int(value)
+      if ('%s' % int_value) == value:
+        value = int_value
+    except Exception:
+      pass
+    self.variables[:0] = [(var, value)]
+
+  def PopVariable(self):
+    self.variables[:1] = []
+
+  def PushRange(self, var, lower, upper):
+    self.ranges[:0] = [(var, lower, upper)]
+
+  def PopRange(self):
+    self.ranges[:1] = []
+
+  def GetValue(self, identifier):
+    for (var, value) in self.variables:
+      if identifier == var:
+        return value
+
+    print 'ERROR: meta variable %s is undefined.' % (identifier,)
+    sys.exit(1)
+
+  def EvalExp(self, exp):
+    try:
+      result = eval(exp.python_exp)
+    except Exception, e:
+      print 'ERROR: caught exception %s: %s' % (e.__class__.__name__, e)
+      print ('ERROR: failed to evaluate meta expression %s at %s' %
+             (exp.python_exp, exp.token.start))
+      sys.exit(1)
+    return result
+
+  def GetRange(self, identifier):
+    for (var, lower, upper) in self.ranges:
+      if identifier == var:
+        return (lower, upper)
+
+    print 'ERROR: range %s is undefined.' % (identifier,)
+    sys.exit(1)
+
+
+class Output:
+  def __init__(self):
+    self.string = ''
+
+  def GetLastLine(self):
+    index = self.string.rfind('\n')
+    if index < 0:
+      return ''
+
+    return self.string[index + 1:]
+
+  def Append(self, s):
+    self.string += s
+
+
+def RunAtomicCode(env, node, output):
+  if isinstance(node, VarNode):
+    identifier = node.identifier.value.strip()
+    result = Output()
+    RunAtomicCode(env.Clone(), node.atomic_code, result)
+    value = result.string
+    env.PushVariable(identifier, value)
+  elif isinstance(node, RangeNode):
+    identifier = node.identifier.value.strip()
+    lower = int(env.EvalExp(node.exp1))
+    upper = int(env.EvalExp(node.exp2))
+    env.PushRange(identifier, lower, upper)
+  elif isinstance(node, ForNode):
+    identifier = node.identifier.value.strip()
+    if node.sep is None:
+      sep = ''
+    else:
+      sep = node.sep.value
+    (lower, upper) = env.GetRange(identifier)
+    for i in range(lower, upper + 1):
+      new_env = env.Clone()
+      new_env.PushVariable(identifier, i)
+      RunCode(new_env, node.code, output)
+      if i != upper:
+        output.Append(sep)
+  elif isinstance(node, RawCodeNode):
+    output.Append(node.raw_code.value)
+  elif isinstance(node, IfNode):
+    cond = env.EvalExp(node.exp)
+    if cond:
+      RunCode(env.Clone(), node.then_branch, output)
+    elif node.else_branch is not None:
+      RunCode(env.Clone(), node.else_branch, output)
+  elif isinstance(node, ExpNode):
+    value = env.EvalExp(node)
+    output.Append('%s' % (value,))
+  elif isinstance(node, LiteralDollarNode):
+    output.Append('$')
+  elif isinstance(node, CodeNode):
+    RunCode(env.Clone(), node, output)
+  else:
+    print 'BAD'
+    print node
+    sys.exit(1)
+
+
+def RunCode(env, code_node, output):
+  for atomic_code in code_node.atomic_code:
+    RunAtomicCode(env, atomic_code, output)
+
+
+def IsComment(cur_line):
+  return '//' in cur_line
+
+
+def IsInPreprocessorDirevative(prev_lines, cur_line):
+  if cur_line.lstrip().startswith('#'):
+    return True
+  return prev_lines != [] and prev_lines[-1].endswith('\\')
+
+
+def WrapComment(line, output):
+  loc = line.find('//')
+  before_comment = line[:loc].rstrip()
+  if before_comment == '':
+    indent = loc
+  else:
+    output.append(before_comment)
+    indent = len(before_comment) - len(before_comment.lstrip())
+  prefix = indent*' ' + '// '
+  max_len = 80 - len(prefix)
+  comment = line[loc + 2:].strip()
+  segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != '']
+  cur_line = ''
+  for seg in segs:
+    if len((cur_line + seg).rstrip()) < max_len:
+      cur_line += seg
+    else:
+      if cur_line.strip() != '':
+        output.append(prefix + cur_line.rstrip())
+      cur_line = seg.lstrip()
+  if cur_line.strip() != '':
+    output.append(prefix + cur_line.strip())
+
+
+def WrapCode(line, line_concat, output):
+  indent = len(line) - len(line.lstrip())
+  prefix = indent*' '  # Prefix of the current line
+  max_len = 80 - indent - len(line_concat)  # Maximum length of the current line
+  new_prefix = prefix + 4*' '  # Prefix of a continuation line
+  new_max_len = max_len - 4  # Maximum length of a continuation line
+  # Prefers to wrap a line after a ',' or ';'.
+  segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != '']
+  cur_line = ''  # The current line without leading spaces.
+  for seg in segs:
+    # If the line is still too long, wrap at a space.
+    while cur_line == '' and len(seg.strip()) > max_len:
+      seg = seg.lstrip()
+      split_at = seg.rfind(' ', 0, max_len)
+      output.append(prefix + seg[:split_at].strip() + line_concat)
+      seg = seg[split_at + 1:]
+      prefix = new_prefix
+      max_len = new_max_len
+
+    if len((cur_line + seg).rstrip()) < max_len:
+      cur_line = (cur_line + seg).lstrip()
+    else:
+      output.append(prefix + cur_line.rstrip() + line_concat)
+      prefix = new_prefix
+      max_len = new_max_len
+      cur_line = seg.lstrip()
+  if cur_line.strip() != '':
+    output.append(prefix + cur_line.strip())
+
+
+def WrapPreprocessorDirevative(line, output):
+  WrapCode(line, ' \\', output)
+
+
+def WrapPlainCode(line, output):
+  WrapCode(line, '', output)
+
+
+def IsHeaderGuardOrInclude(line):
+  return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or
+          re.match(r'^#include\s', line))
+
+
+def WrapLongLine(line, output):
+  line = line.rstrip()
+  if len(line) <= 80:
+    output.append(line)
+  elif IsComment(line):
+    if IsHeaderGuardOrInclude(line):
+      # The style guide made an exception to allow long header guard lines
+      # and includes.
+      output.append(line)
+    else:
+      WrapComment(line, output)
+  elif IsInPreprocessorDirevative(output, line):
+    if IsHeaderGuardOrInclude(line):
+      # The style guide made an exception to allow long header guard lines
+      # and includes.
+      output.append(line)
+    else:
+      WrapPreprocessorDirevative(line, output)
+  else:
+    WrapPlainCode(line, output)
+
+
+def BeautifyCode(string):
+  lines = string.splitlines()
+  output = []
+  for line in lines:
+    WrapLongLine(line, output)
+  output2 = [line.rstrip() for line in output]
+  return '\n'.join(output2) + '\n'
+
+
+def main(argv):
+  if len(argv) == 1:
+    print __doc__
+    sys.exit(1)
+
+  file_path = argv[-1]
+  ast = Convert(file_path)
+  output = Output()
+  RunCode(Env(), ast, output)
+  output_str = BeautifyCode(output.string)
+  if file_path.endswith('.pump'):
+    output_file_path = file_path[:-5]
+  else:
+    output_file_path = '-'
+  if output_file_path == '-':
+    print output_str,
+  else:
+    output_file = file(output_file_path, 'w')
+    output_file.write('// This file was GENERATED by command:\n')
+    output_file.write('//     %s %s\n' %
+                      (os.path.basename(__file__), os.path.basename(file_path)))
+    output_file.write('// DO NOT EDIT BY HAND!!!\n\n')
+    output_file.write(output_str)
+    output_file.close()
+
+
+if __name__ == '__main__':
+  main(sys.argv)
diff --git a/protobuf/gtest/scripts/test/Makefile b/protobuf/gtest/scripts/test/Makefile
new file mode 100644
index 0000000..ffc0c90
--- /dev/null
+++ b/protobuf/gtest/scripts/test/Makefile
@@ -0,0 +1,57 @@
+# A Makefile for fusing Google Test and building a sample test against it.
+#
+# SYNOPSIS:
+#
+#   make [all]  - makes everything.
+#   make TARGET - makes the given target.
+#   make check  - makes everything and runs the built sample test.
+#   make clean  - removes all files generated by make.
+
+# Points to the root of fused Google Test, relative to where this file is.
+FUSED_GTEST_DIR = output
+
+# Paths to the fused gtest files.
+FUSED_GTEST_H = $(FUSED_GTEST_DIR)/gtest/gtest.h
+FUSED_GTEST_ALL_CC = $(FUSED_GTEST_DIR)/gtest/gtest-all.cc
+
+# Where to find the sample test.
+SAMPLE_DIR = ../../samples
+
+# Where to find gtest_main.cc.
+GTEST_MAIN_CC = ../../src/gtest_main.cc
+
+# Flags passed to the preprocessor.
+CPPFLAGS += -I$(FUSED_GTEST_DIR)
+
+# Flags passed to the C++ compiler.
+CXXFLAGS += -g
+
+all : sample1_unittest
+
+check : all
+	./sample1_unittest
+
+clean :
+	rm -rf $(FUSED_GTEST_DIR) sample1_unittest *.o
+
+$(FUSED_GTEST_H) :
+	../fuse_gtest_files.py $(FUSED_GTEST_DIR)
+
+$(FUSED_GTEST_ALL_CC) :
+	../fuse_gtest_files.py $(FUSED_GTEST_DIR)
+
+gtest-all.o : $(FUSED_GTEST_H) $(FUSED_GTEST_ALL_CC)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FUSED_GTEST_DIR)/gtest/gtest-all.cc
+
+gtest_main.o : $(FUSED_GTEST_H) $(GTEST_MAIN_CC)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(GTEST_MAIN_CC)
+
+sample1.o : $(SAMPLE_DIR)/sample1.cc $(SAMPLE_DIR)/sample1.h
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1.cc
+
+sample1_unittest.o : $(SAMPLE_DIR)/sample1_unittest.cc \
+                     $(SAMPLE_DIR)/sample1.h $(FUSED_GTEST_H)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SAMPLE_DIR)/sample1_unittest.cc
+
+sample1_unittest : sample1.o sample1_unittest.o gtest-all.o gtest_main.o
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -o $@
diff --git a/protobuf/gtest/src/gtest-all.cc b/protobuf/gtest/src/gtest-all.cc
new file mode 100644
index 0000000..fe34765
--- /dev/null
+++ b/protobuf/gtest/src/gtest-all.cc
@@ -0,0 +1,47 @@
+// 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: mheule@google.com (Markus Heule)
+//
+// Google C++ Testing Framework (Google Test)
+//
+// Sometimes it's desirable to build Google Test by compiling a single file.
+// This file serves this purpose.
+
+// This line ensures that gtest.h can be compiled on its own, even
+// when it's fused.
+#include <gtest/gtest.h>
+
+// The following lines pull in the real gtest *.cc files.
+#include "src/gtest.cc"
+#include "src/gtest-death-test.cc"
+#include "src/gtest-filepath.cc"
+#include "src/gtest-port.cc"
+#include "src/gtest-test-part.cc"
+#include "src/gtest-typed-test.cc"
diff --git a/protobuf/gtest/src/gtest-death-test.cc b/protobuf/gtest/src/gtest-death-test.cc
new file mode 100644
index 0000000..3b73b01
--- /dev/null
+++ b/protobuf/gtest/src/gtest-death-test.cc
@@ -0,0 +1,1172 @@
+// 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), vladl@google.com (Vlad Losev)
+//
+// This file implements death tests.
+
+#include <gtest/gtest-death-test.h>
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_HAS_DEATH_TEST
+
+#if GTEST_OS_MAC
+#include <crt_externs.h>
+#endif  // GTEST_OS_MAC
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#if GTEST_OS_WINDOWS
+#include <windows.h>
+#else
+#include <sys/mman.h>
+#include <sys/wait.h>
+#endif  // GTEST_OS_WINDOWS
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+#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_ 1
+#include "src/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).");
+
+GTEST_DEFINE_bool_(
+    death_test_use_fork,
+    internal::BoolFromGTestEnv("death_test_use_fork", false),
+    "Instructs to use fork()/_exit() instead of clone() in death tests. "
+    "Ignored and always uses fork() on POSIX systems where clone() is not "
+    "implemented. Useful when running under valgrind or similar tools if "
+    "those do not support clone(). Valgrind 3.3.1 will just fail if "
+    "it sees an unsupported combination of clone() flags. "
+    "It is not recommended to use this flag w/o valgrind though it will "
+    "work in 99% of the cases. Once valgrind is fixed, this flag will "
+    "most likely be removed.");
+
+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
+
+#if 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 {
+#if GTEST_OS_WINDOWS
+  return exit_status == exit_code_;
+#else
+  return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
+#endif  // GTEST_OS_WINDOWS
+}
+
+#if !GTEST_OS_WINDOWS
+// 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_;
+}
+#endif  // !GTEST_OS_WINDOWS
+
+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 GTEST_OS_WINDOWS
+  m << "Exited with exit status " << exit_code;
+#else
+  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
+#endif  // GTEST_OS_WINDOWS
+  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);
+}
+
+#if !GTEST_OS_WINDOWS
+// 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();
+}
+#endif  // !GTEST_OS_WINDOWS
+
+// 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 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 String& message) {
+  // On a POSIX system, 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-minuscule memory requirements.
+  const InternalRunDeathTestFlag* const flag =
+      GetUnitTestImpl()->internal_run_death_test_flag();
+  if (flag != NULL) {
+    FILE* parent = posix::FDOpen(flag->write_fd(), "w");
+    fputc(kDeathTestInternalError, parent);
+    fprintf(parent, "%s", message.c_str());
+    fflush(parent);
+    _exit(1);
+  } else {
+    fprintf(stderr, "%s", message.c_str());
+    fflush(stderr);
+    abort();
+  }
+}
+
+// A replacement for CHECK that calls DeathTestAbort if the assertion
+// fails.
+#define GTEST_DEATH_TEST_CHECK_(expression) \
+  do { \
+    if (!::testing::internal::IsTrue(expression)) { \
+      DeathTestAbort(::testing::internal::String::Format( \
+          "CHECK failed: File %s, line %d: %s", \
+          __FILE__, __LINE__, #expression)); \
+    } \
+  } while (::testing::internal::AlwaysFalse())
+
+// 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 gtest_retval; \
+    do { \
+      gtest_retval = (expression); \
+    } while (gtest_retval == -1 && errno == EINTR); \
+    if (gtest_retval == -1) { \
+      DeathTestAbort(::testing::internal::String::Format( \
+          "CHECK failed: File %s, line %d: %s != -1", \
+          __FILE__, __LINE__, #expression)); \
+    } \
+  } while (::testing::internal::AlwaysFalse())
+
+// Returns the message describing the last system error in errno.
+String GetLastErrnoDescription() {
+    return String(errno == 0 ? "" : posix::StrError(errno));
+}
+
+// This is called from a death test parent process to read a failure
+// message from the death test child process and log it with the FATAL
+// severity. On Windows, the message is read from a pipe handle. On other
+// platforms, it is read from a file descriptor.
+static void FailFromInternalError(int fd) {
+  Message error;
+  char buffer[256];
+  int num_read;
+
+  do {
+    while ((num_read = posix::Read(fd, buffer, 255)) > 0) {
+      buffer[num_read] = '\0';
+      error << buffer;
+    }
+  } while (num_read == -1 && errno == EINTR);
+
+  if (num_read == 0) {
+    GTEST_LOG_(FATAL) << error.GetString();
+  } else {
+    const int last_error = errno;
+    GTEST_LOG_(FATAL) << "Error while reading death test internal: "
+                      << GetLastErrnoDescription() << " [" << last_error << "]";
+  }
+}
+
+// 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();
+}
+
+void DeathTest::set_last_death_test_message(const String& message) {
+  last_death_test_message_ = message;
+}
+
+String DeathTest::last_death_test_message_;
+
+// Provides cross platform implementation for some death functionality.
+class DeathTestImpl : public DeathTest {
+ protected:
+  DeathTestImpl(const char* a_statement, const RE* a_regex)
+      : statement_(a_statement),
+        regex_(a_regex),
+        spawned_(false),
+        status_(-1),
+        outcome_(IN_PROGRESS),
+        read_fd_(-1),
+        write_fd_(-1) {}
+
+  // read_fd_ is expected to be closed and cleared by a derived class.
+  ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
+
+  void Abort(AbortReason reason);
+  virtual bool Passed(bool status_ok);
+
+  const char* statement() const { return statement_; }
+  const RE* regex() const { return regex_; }
+  bool spawned() const { return spawned_; }
+  void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
+  int status() const { return status_; }
+  void set_status(int a_status) { status_ = a_status; }
+  DeathTestOutcome outcome() const { return outcome_; }
+  void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; }
+  int read_fd() const { return read_fd_; }
+  void set_read_fd(int fd) { read_fd_ = fd; }
+  int write_fd() const { return write_fd_; }
+  void set_write_fd(int fd) { write_fd_ = fd; }
+
+  // Called in the parent process only. Reads the result code of the death
+  // test child process via a pipe, interprets it to set the outcome_
+  // member, and closes read_fd_.  Outputs diagnostics and terminates in
+  // case of unexpected codes.
+  void ReadAndInterpretStatusByte();
+
+ private:
+  // The textual content of the code this object is testing.  This class
+  // doesn't own this string and should not attempt to delete it.
+  const char* const statement_;
+  // The regular expression which test output must match.  DeathTestImpl
+  // doesn't own this object and should not attempt to delete it.
+  const RE* const regex_;
+  // True if the death test child process has been successfully spawned.
+  bool spawned_;
+  // The exit status of the child process.
+  int status_;
+  // How the death test concluded.
+  DeathTestOutcome outcome_;
+  // Descriptor to the read end of the pipe to the child process.  It is
+  // always -1 in the child process.  The child keeps its write end of the
+  // pipe in write_fd_.
+  int read_fd_;
+  // Descriptor to the child's write end of the pipe to the parent process.
+  // It is always -1 in the parent process.  The parent keeps its end of the
+  // pipe in read_fd_.
+  int write_fd_;
+};
+
+// Called in the parent process only. Reads the result code of the death
+// test child process via a pipe, interprets it to set the outcome_
+// member, and closes read_fd_.  Outputs diagnostics and terminates in
+// case of unexpected codes.
+void DeathTestImpl::ReadAndInterpretStatusByte() {
+  char flag;
+  int bytes_read;
+
+  // 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.
+  do {
+    bytes_read = posix::Read(read_fd(), &flag, 1);
+  } while (bytes_read == -1 && errno == EINTR);
+
+  if (bytes_read == 0) {
+    set_outcome(DIED);
+  } else if (bytes_read == 1) {
+    switch (flag) {
+      case kDeathTestReturned:
+        set_outcome(RETURNED);
+        break;
+      case kDeathTestLived:
+        set_outcome(LIVED);
+        break;
+      case kDeathTestInternalError:
+        FailFromInternalError(read_fd());  // Does not return.
+        break;
+      default:
+        GTEST_LOG_(FATAL) << "Death test child process reported "
+                          << "unexpected status byte ("
+                          << static_cast<unsigned int>(flag) << ")";
+    }
+  } else {
+    GTEST_LOG_(FATAL) << "Read from death test child process failed: "
+                      << GetLastErrnoDescription();
+  }
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd()));
+  set_read_fd(-1);
+}
+
+// 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 descriptor, then
+// calls _exit(1).
+void DeathTestImpl::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 status_ch =
+      reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned;
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1));
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(write_fd()));
+  _exit(1);  // Exits w/o any normal exit hooks (we were supposed to crash)
+}
+
+// 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. On *nix, it is in the
+//             in the format specified by wait(2). On Windows, this is the
+//             value supplied to the ExitProcess() API or a numeric code
+//             of the exception that terminated the program.
+//   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 last death test message string.
+bool DeathTestImpl::Passed(bool status_ok) {
+  if (!spawned())
+    return false;
+
+  const String error_message = GetCapturedStderr();
+
+  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) {
+        const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
+        if (matched) {
+          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;
+    case IN_PROGRESS:
+    default:
+      GTEST_LOG_(FATAL)
+          << "DeathTest::Passed somehow called before conclusion of test";
+  }
+
+  DeathTest::set_last_death_test_message(buffer.GetString());
+  return success;
+}
+
+#if GTEST_OS_WINDOWS
+// WindowsDeathTest implements death tests on Windows. Due to the
+// specifics of starting new processes on Windows, death tests there are
+// always threadsafe, and Google Test considers the
+// --gtest_death_test_style=fast setting to be equivalent to
+// --gtest_death_test_style=threadsafe there.
+//
+// A few implementation notes:  Like the Linux version, the Windows
+// implementation uses pipes for child-to-parent communication. But due to
+// the specifics of pipes on Windows, some extra steps are required:
+//
+// 1. The parent creates a communication pipe and stores handles to both
+//    ends of it.
+// 2. The parent starts the child and provides it with the information
+//    necessary to acquire the handle to the write end of the pipe.
+// 3. The child acquires the write end of the pipe and signals the parent
+//    using a Windows event.
+// 4. Now the parent can release the write end of the pipe on its side. If
+//    this is done before step 3, the object's reference count goes down to
+//    0 and it is destroyed, preventing the child from acquiring it. The
+//    parent now has to release it, or read operations on the read end of
+//    the pipe will not return when the child terminates.
+// 5. The parent reads child's output through the pipe (outcome code and
+//    any possible error messages) from the pipe, and its stderr and then
+//    determines whether to fail the test.
+//
+// Note: to distinguish Win32 API calls from the local method and function
+// calls, the former are explicitly resolved in the global namespace.
+//
+class WindowsDeathTest : public DeathTestImpl {
+ public:
+  WindowsDeathTest(const char* statement,
+                   const RE* regex,
+                   const char* file,
+                   int line)
+      : DeathTestImpl(statement, regex), file_(file), line_(line) {}
+
+  // All of these virtual functions are inherited from DeathTest.
+  virtual int Wait();
+  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_;
+  // Handle to the write end of the pipe to the child process.
+  AutoHandle write_handle_;
+  // Child process handle.
+  AutoHandle child_handle_;
+  // Event the child process uses to signal the parent that it has
+  // acquired the handle to the write end of the pipe. After seeing this
+  // event the parent can release its own handles to make sure its
+  // ReadFile() calls return when the child terminates.
+  AutoHandle event_handle_;
+};
+
+// 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 WindowsDeathTest::Wait() {
+  if (!spawned())
+    return 0;
+
+  // Wait until the child either signals that it has acquired the write end
+  // of the pipe or it dies.
+  const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() };
+  switch (::WaitForMultipleObjects(2,
+                                   wait_handles,
+                                   FALSE,  // Waits for any of the handles.
+                                   INFINITE)) {
+    case WAIT_OBJECT_0:
+    case WAIT_OBJECT_0 + 1:
+      break;
+    default:
+      GTEST_DEATH_TEST_CHECK_(false);  // Should not get here.
+  }
+
+  // The child has acquired the write end of the pipe or exited.
+  // We release the handle on our side and continue.
+  write_handle_.Reset();
+  event_handle_.Reset();
+
+  ReadAndInterpretStatusByte();
+
+  // Waits for the child process to exit if it haven't already. This
+  // returns immediately if the child has already exited, regardless of
+  // whether previous calls to WaitForMultipleObjects synchronized on this
+  // handle or not.
+  GTEST_DEATH_TEST_CHECK_(
+      WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(),
+                                             INFINITE));
+  DWORD status;
+  GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status)
+                          != FALSE);
+  child_handle_.Reset();
+  set_status(static_cast<int>(status));
+  return this->status();
+}
+
+// The AssumeRole process for a Windows death test.  It creates a child
+// process with the same executable as the current process to run the
+// death test.  The child process is given the --gtest_filter and
+// --gtest_internal_run_death_test flags such that it knows to run the
+// current death test only.
+DeathTest::TestRole WindowsDeathTest::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) {
+    // ParseInternalRunDeathTestFlag() has performed all the necessary
+    // processing.
+    set_write_fd(flag->write_fd());
+    return EXECUTE_TEST;
+  }
+
+  // WindowsDeathTest uses an anonymous pipe to communicate results of
+  // a death test.
+  SECURITY_ATTRIBUTES handles_are_inheritable = {
+    sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
+  HANDLE read_handle, write_handle;
+  GTEST_DEATH_TEST_CHECK_(
+      ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
+                   0)  // Default buffer size.
+      != FALSE);
+  set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle),
+                                O_RDONLY));
+  write_handle_.Reset(write_handle);
+  event_handle_.Reset(::CreateEvent(
+      &handles_are_inheritable,
+      TRUE,    // The event will automatically reset to non-signaled state.
+      FALSE,   // The initial state is non-signalled.
+      NULL));  // The even is unnamed.
+  GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);
+  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|%u|%Iu|%Iu",
+      GTEST_FLAG_PREFIX_,
+      kInternalRunDeathTestFlag,
+      file_, line_,
+      death_test_index,
+      static_cast<unsigned int>(::GetCurrentProcessId()),
+      // size_t has the same with as pointers on both 32-bit and 64-bit
+      // Windows platforms.
+      // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx.
+      reinterpret_cast<size_t>(write_handle),
+      reinterpret_cast<size_t>(event_handle_.Get()));
+
+  char executable_path[_MAX_PATH + 1];  // NOLINT
+  GTEST_DEATH_TEST_CHECK_(
+      _MAX_PATH + 1 != ::GetModuleFileNameA(NULL,
+                                            executable_path,
+                                            _MAX_PATH));
+
+  String command_line = String::Format("%s %s \"%s\"",
+                                       ::GetCommandLineA(),
+                                       filter_flag.c_str(),
+                                       internal_flag.c_str());
+
+  DeathTest::set_last_death_test_message("");
+
+  CaptureStderr();
+  // Flush the log buffers since the log streams are shared with the child.
+  FlushInfoLog();
+
+  // The child process will share the standard handles with the parent.
+  STARTUPINFOA startup_info;
+  memset(&startup_info, 0, sizeof(STARTUPINFO));
+  startup_info.dwFlags = STARTF_USESTDHANDLES;
+  startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE);
+  startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
+  startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
+
+  PROCESS_INFORMATION process_info;
+  GTEST_DEATH_TEST_CHECK_(::CreateProcessA(
+      executable_path,
+      const_cast<char*>(command_line.c_str()),
+      NULL,   // Retuned process handle is not inheritable.
+      NULL,   // Retuned thread handle is not inheritable.
+      TRUE,   // Child inherits all inheritable handles (for write_handle_).
+      0x0,    // Default creation flags.
+      NULL,   // Inherit the parent's environment.
+      UnitTest::GetInstance()->original_working_dir(),
+      &startup_info,
+      &process_info) != FALSE);
+  child_handle_.Reset(process_info.hProcess);
+  ::CloseHandle(process_info.hThread);
+  set_spawned(true);
+  return OVERSEE_TEST;
+}
+#else  // We are not on Windows.
+
+// ForkingDeathTest provides implementations for most of the abstract
+// methods of the DeathTest interface.  Only the AssumeRole method is
+// left undefined.
+class ForkingDeathTest : public DeathTestImpl {
+ public:
+  ForkingDeathTest(const char* statement, const RE* regex);
+
+  // All of these virtual functions are inherited from DeathTest.
+  virtual int Wait();
+
+ protected:
+  void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
+
+ private:
+  // PID of child process during death test; 0 in the child process itself.
+  pid_t child_pid_;
+};
+
+// Constructs a ForkingDeathTest.
+ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)
+    : DeathTestImpl(a_statement, a_regex),
+      child_pid_(-1) {}
+
+// 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 (!spawned())
+    return 0;
+
+  ReadAndInterpretStatusByte();
+
+  int status_value;
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0));
+  set_status(status_value);
+  return status_value;
+}
+
+// A concrete death test class that forks, then immediately runs the test
+// in the child process.
+class NoExecDeathTest : public ForkingDeathTest {
+ public:
+  NoExecDeathTest(const char* a_statement, const RE* a_regex) :
+      ForkingDeathTest(a_statement, a_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);
+
+  DeathTest::set_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();
+    // Event forwarding to the listeners of event listener API mush be shut
+    // down in death test subprocesses.
+    GetUnitTestImpl()->listeners()->SuppressEventForwarding();
+    return EXECUTE_TEST;
+  } else {
+    GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1]));
+    set_read_fd(pipe_fd[0]);
+    set_spawned(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* a_statement, const RE* a_regex,
+                const char* file, int line) :
+      ForkingDeathTest(a_statement, a_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 != args_.end();
+         ++i) {
+      free(*i);
+    }
+  }
+  void AddArgument(const char* argument) {
+    args_.insert(args_.end() - 1, posix::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, posix::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
+};
+
+#if GTEST_OS_MAC
+inline char** GetEnviron() {
+  // When Google Test is built as a framework on MacOS X, the environ variable
+  // is unavailable. Apple's documentation (man environ) recommends using
+  // _NSGetEnviron() instead.
+  return *_NSGetEnviron();
+}
+#else
+// Some POSIX platforms expect you to declare environ. extern "C" makes
+// it reside in the global namespace.
+extern "C" char** environ;
+inline char** GetEnviron() { return environ; }
+#endif  // GTEST_OS_MAC
+
+// The main function for a threadsafe-style death test child process.
+// This function is called in a clone()-ed process and thus must avoid
+// any potentially unsafe operations like malloc or libc functions.
+static int ExecDeathTestChildMain(void* child_arg) {
+  ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg);
+  GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd));
+
+  // We need to execute the test program in the same environment where
+  // it was originally invoked.  Therefore we change to the original
+  // working directory first.
+  const char* const original_dir =
+      UnitTest::GetInstance()->original_working_dir();
+  // We can safely call chdir() as it's a direct system call.
+  if (chdir(original_dir) != 0) {
+    DeathTestAbort(String::Format("chdir(\"%s\") failed: %s",
+                                  original_dir,
+                                  GetLastErrnoDescription().c_str()));
+    return EXIT_FAILURE;
+  }
+
+  // We can safely call execve() as it's a direct system call.  We
+  // cannot use execvp() as it's a libc function and thus potentially
+  // unsafe.  Since execve() doesn't search the PATH, the user must
+  // invoke the test program via a valid path that contains at least
+  // one path separator.
+  execve(args->argv[0], args->argv, GetEnviron());
+  DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s",
+                                args->argv[0],
+                                original_dir,
+                                GetLastErrnoDescription().c_str()));
+  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.
+bool StackLowerThanAddress(const void* ptr) {
+  int dummy;
+  return &dummy < ptr;
+}
+
+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) {
+  ExecDeathTestArgs args = { argv, close_fd };
+  pid_t child_pid = -1;
+
+#if GTEST_HAS_CLONE
+  const bool use_fork = GTEST_FLAG(death_test_use_fork);
+
+  if (!use_fork) {
+    static const bool stack_grows_down = StackGrowsDown();
+    const size_t stack_size = getpagesize();
+    // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
+    void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
+                             MAP_ANON | 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);
+
+    child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
+
+    GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1);
+  }
+#else
+  const bool use_fork = true;
+#endif  // GTEST_HAS_CLONE
+
+  if (use_fork && (child_pid = fork()) == 0) {
+      ExecDeathTestChildMain(&args);
+      _exit(0);
+  }
+
+  GTEST_DEATH_TEST_CHECK_(child_pid != -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->write_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(filter_flag.c_str());
+  args.AddArgument(internal_flag.c_str());
+
+  DeathTest::set_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_spawned(true);
+  return OVERSEE_TEST;
+}
+
+#endif  // !GTEST_OS_WINDOWS
+
+// 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()) {
+      DeathTest::set_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_OS_WINDOWS
+  if (GTEST_FLAG(death_test_style) == "threadsafe" ||
+      GTEST_FLAG(death_test_style) == "fast") {
+    *test = new WindowsDeathTest(statement, regex, file, line);
+  }
+#else
+  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);
+  }
+#endif  // GTEST_OS_WINDOWS
+  else {  // NOLINT - this is more readable than unbalanced brackets inside #if.
+    DeathTest::set_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 (::testing::internal::AlwaysTrue()) {
+    const ::std::string::size_type colon = str.find(delimiter, 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);
+}
+
+#if GTEST_OS_WINDOWS
+// Recreates the pipe and event handles from the provided parameters,
+// signals the event, and returns a file descriptor wrapped around the pipe
+// handle. This function is called in the child process only.
+int GetStatusFileDescriptor(unsigned int parent_process_id,
+                            size_t write_handle_as_size_t,
+                            size_t event_handle_as_size_t) {
+  AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
+                                                   FALSE,  // Non-inheritable.
+                                                   parent_process_id));
+  if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) {
+    DeathTestAbort(String::Format("Unable to open parent process %u",
+                                  parent_process_id));
+  }
+
+  // TODO(vladl@google.com): Replace the following check with a
+  // compile-time assertion when available.
+  GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
+
+  const HANDLE write_handle =
+      reinterpret_cast<HANDLE>(write_handle_as_size_t);
+  HANDLE dup_write_handle;
+
+  // The newly initialized handle is accessible only in in the parent
+  // process. To obtain one accessible within the child, we need to use
+  // DuplicateHandle.
+  if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
+                         ::GetCurrentProcess(), &dup_write_handle,
+                         0x0,    // Requested privileges ignored since
+                                 // DUPLICATE_SAME_ACCESS is used.
+                         FALSE,  // Request non-inheritable handler.
+                         DUPLICATE_SAME_ACCESS)) {
+    DeathTestAbort(String::Format(
+        "Unable to duplicate the pipe handle %Iu from the parent process %u",
+        write_handle_as_size_t, parent_process_id));
+  }
+
+  const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t);
+  HANDLE dup_event_handle;
+
+  if (!::DuplicateHandle(parent_process_handle.Get(), event_handle,
+                         ::GetCurrentProcess(), &dup_event_handle,
+                         0x0,
+                         FALSE,
+                         DUPLICATE_SAME_ACCESS)) {
+    DeathTestAbort(String::Format(
+        "Unable to duplicate the event handle %Iu from the parent process %u",
+        event_handle_as_size_t, parent_process_id));
+  }
+
+  const int write_fd =
+      ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND);
+  if (write_fd == -1) {
+    DeathTestAbort(String::Format(
+        "Unable to convert pipe handle %Iu to a file descriptor",
+        write_handle_as_size_t));
+  }
+
+  // Signals the parent that the write end of the pipe has been acquired
+  // so the parent can release its own write end.
+  ::SetEvent(dup_event_handle);
+
+  return write_fd;
+}
+#endif  // GTEST_OS_WINDOWS
+
+// 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;
+
+  // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
+  // can use it here.
+  int line = -1;
+  int index = -1;
+  ::std::vector< ::std::string> fields;
+  SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields);
+  int write_fd = -1;
+
+#if GTEST_OS_WINDOWS
+  unsigned int parent_process_id = 0;
+  size_t write_handle_as_size_t = 0;
+  size_t event_handle_as_size_t = 0;
+
+  if (fields.size() != 6
+      || !ParseNaturalNumber(fields[1], &line)
+      || !ParseNaturalNumber(fields[2], &index)
+      || !ParseNaturalNumber(fields[3], &parent_process_id)
+      || !ParseNaturalNumber(fields[4], &write_handle_as_size_t)
+      || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) {
+    DeathTestAbort(String::Format(
+        "Bad --gtest_internal_run_death_test flag: %s",
+        GTEST_FLAG(internal_run_death_test).c_str()));
+  }
+  write_fd = GetStatusFileDescriptor(parent_process_id,
+                                     write_handle_as_size_t,
+                                     event_handle_as_size_t);
+#else
+  if (fields.size() != 4
+      || !ParseNaturalNumber(fields[1], &line)
+      || !ParseNaturalNumber(fields[2], &index)
+      || !ParseNaturalNumber(fields[3], &write_fd)) {
+    DeathTestAbort(String::Format(
+        "Bad --gtest_internal_run_death_test flag: %s",
+        GTEST_FLAG(internal_run_death_test).c_str()));
+  }
+#endif  // GTEST_OS_WINDOWS
+  return new InternalRunDeathTestFlag(fields[0], line, index, write_fd);
+}
+
+}  // namespace internal
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+}  // namespace testing
diff --git a/protobuf/gtest/src/gtest-filepath.cc b/protobuf/gtest/src/gtest-filepath.cc
new file mode 100644
index 0000000..c1ef918
--- /dev/null
+++ b/protobuf/gtest/src/gtest-filepath.cc
@@ -0,0 +1,380 @@
+// 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>
+
+#include <stdlib.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h>
+#elif GTEST_OS_WINDOWS
+#include <direct.h>
+#include <io.h>
+#elif GTEST_OS_SYMBIAN
+// Symbian OpenC has PATH_MAX in sys/syslimits.h
+#include <sys/syslimits.h>
+#else
+#include <limits.h>
+#include <climits>  // Some Linux distributions define PATH_MAX here.
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#if GTEST_OS_WINDOWS
+#define GTEST_PATH_MAX_ _MAX_PATH
+#elif defined(PATH_MAX)
+#define GTEST_PATH_MAX_ PATH_MAX
+#elif defined(_XOPEN_PATH_MAX)
+#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
+#else
+#define GTEST_PATH_MAX_ _POSIX_PATH_MAX
+#endif  // GTEST_OS_WINDOWS
+
+#include <gtest/internal/gtest-string.h>
+
+namespace testing {
+namespace internal {
+
+#if GTEST_OS_WINDOWS
+// On Windows, '\\' is the standard path separator, but many tools and the
+// Windows API also accept '/' as an alternate path separator. Unless otherwise
+// noted, a file path can contain either kind of path separators, or a mixture
+// of them.
+const char kPathSeparator = '\\';
+const char kAlternatePathSeparator = '/';
+const char kPathSeparatorString[] = "\\";
+const char kAlternatePathSeparatorString[] = "/";
+#if GTEST_OS_WINDOWS_MOBILE
+// Windows CE doesn't have a current directory. You should not use
+// the current directory in tests on Windows CE, but this at least
+// provides a reasonable fallback.
+const char kCurrentDirectoryString[] = "\\";
+// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
+const DWORD kInvalidFileAttributes = 0xffffffff;
+#else
+const char kCurrentDirectoryString[] = ".\\";
+#endif  // GTEST_OS_WINDOWS_MOBILE
+#else
+const char kPathSeparator = '/';
+const char kPathSeparatorString[] = "/";
+const char kCurrentDirectoryString[] = "./";
+#endif  // GTEST_OS_WINDOWS
+
+// Returns whether the given character is a valid path separator.
+static bool IsPathSeparator(char c) {
+#if GTEST_HAS_ALT_PATH_SEP_
+  return (c == kPathSeparator) || (c == kAlternatePathSeparator);
+#else
+  return c == kPathSeparator;
+#endif
+}
+
+// Returns the current working directory, or "" if unsuccessful.
+FilePath FilePath::GetCurrentDir() {
+#if GTEST_OS_WINDOWS_MOBILE
+  // Windows CE doesn't have a current directory, so we just return
+  // something reasonable.
+  return FilePath(kCurrentDirectoryString);
+#elif GTEST_OS_WINDOWS
+  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
+  return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+#else
+  char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
+  return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+}
+
+// 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_.length() - 4));
+  }
+  return *this;
+}
+
+// Returns a pointer to the last occurence of a valid path separator in
+// the FilePath. On Windows, for example, both '/' and '\' are valid path
+// separators. Returns NULL if no path separator was found.
+const char* FilePath::FindLastPathSeparator() const {
+  const char* const last_sep = strrchr(c_str(), kPathSeparator);
+#if GTEST_HAS_ALT_PATH_SEP_
+  const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
+  // Comparing two pointers of which only one is NULL is undefined.
+  if (last_alt_sep != NULL &&
+      (last_sep == NULL || last_alt_sep > last_sep)) {
+    return last_alt_sep;
+  }
+#endif
+  return last_sep;
+}
+
+// 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 = FindLastPathSeparator();
+  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 = FindLastPathSeparator();
+  String dir;
+  if (last_sep) {
+    dir = String(c_str(), last_sep + 1 - c_str());
+  } else {
+    dir = kCurrentDirectoryString;
+  }
+  return FilePath(dir);
+}
+
+// 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) {
+  String file;
+  if (number == 0) {
+    file = String::Format("%s.%s", base_name.c_str(), extension);
+  } else {
+    file = String::Format("%s_%d.%s", base_name.c_str(), number, extension);
+  }
+  return ConcatPaths(directory, FilePath(file));
+}
+
+// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml".
+// On Windows, uses \ as the separator rather than /.
+FilePath FilePath::ConcatPaths(const FilePath& directory,
+                               const FilePath& relative_path) {
+  if (directory.IsEmpty())
+    return relative_path;
+  const FilePath dir(directory.RemoveTrailingPathSeparator());
+  return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator,
+                                 relative_path.c_str()));
+}
+
+// Returns true if pathname describes something findable in the file-system,
+// either a file, directory, or whatever.
+bool FilePath::FileOrDirectoryExists() const {
+#if GTEST_OS_WINDOWS_MOBILE
+  LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
+  const DWORD attributes = GetFileAttributes(unicode);
+  delete [] unicode;
+  return attributes != kInvalidFileAttributes;
+#else
+  posix::StatStruct file_stat;
+  return posix::Stat(pathname_.c_str(), &file_stat) == 0;
+#endif  // GTEST_OS_WINDOWS_MOBILE
+}
+
+// Returns true if pathname describes a directory in the file-system
+// that exists.
+bool FilePath::DirectoryExists() const {
+  bool result = false;
+#if GTEST_OS_WINDOWS
+  // Don't strip off trailing separator if path is a root directory on
+  // Windows (like "C:\\").
+  const FilePath& path(IsRootDirectory() ? *this :
+                                           RemoveTrailingPathSeparator());
+#else
+  const FilePath& path(*this);
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+  LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
+  const DWORD attributes = GetFileAttributes(unicode);
+  delete [] unicode;
+  if ((attributes != kInvalidFileAttributes) &&
+      (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
+    result = true;
+  }
+#else
+  posix::StatStruct file_stat;
+  result = posix::Stat(path.c_str(), &file_stat) == 0 &&
+      posix::IsDir(file_stat);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+  return result;
+}
+
+// Returns true if pathname describes a root directory. (Windows has one
+// root directory per disk drive.)
+bool FilePath::IsRootDirectory() const {
+#if GTEST_OS_WINDOWS
+  // TODO(wan@google.com): on Windows a network share like
+  // \\server\share can be a root directory, although it cannot be the
+  // current directory.  Handle this properly.
+  return pathname_.length() == 3 && IsAbsolutePath();
+#else
+  return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
+#endif
+}
+
+// Returns true if pathname describes an absolute path.
+bool FilePath::IsAbsolutePath() const {
+  const char* const name = pathname_.c_str();
+#if GTEST_OS_WINDOWS
+  return pathname_.length() >= 3 &&
+     ((name[0] >= 'a' && name[0] <= 'z') ||
+      (name[0] >= 'A' && name[0] <= 'Z')) &&
+     name[1] == ':' &&
+     IsPathSeparator(name[2]);
+#else
+  return IsPathSeparator(name[0]);
+#endif
+}
+
+// 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_.empty() &&
+         IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]);
+}
+
+// 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_.length() == 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 {
+#if GTEST_OS_WINDOWS_MOBILE
+  FilePath removed_sep(this->RemoveTrailingPathSeparator());
+  LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
+  int result = CreateDirectory(unicode, NULL) ? 0 : -1;
+  delete [] unicode;
+#elif GTEST_OS_WINDOWS
+  int result = _mkdir(pathname_.c_str());
+#else
+  int result = mkdir(pathname_.c_str(), 0777);
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+  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 IsDirectory()
+      ? FilePath(String(pathname_.c_str(), pathname_.length() - 1))
+      : *this;
+}
+
+// Removes any redundant separators that might be in the pathname.
+// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
+// redundancies that might be in a pathname involving "." or "..".
+// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share).
+void FilePath::Normalize() {
+  if (pathname_.c_str() == NULL) {
+    pathname_ = "";
+    return;
+  }
+  const char* src = pathname_.c_str();
+  char* const dest = new char[pathname_.length() + 1];
+  char* dest_ptr = dest;
+  memset(dest_ptr, 0, pathname_.length() + 1);
+
+  while (*src != '\0') {
+    *dest_ptr = *src;
+    if (!IsPathSeparator(*src)) {
+      src++;
+    } else {
+#if GTEST_HAS_ALT_PATH_SEP_
+      if (*dest_ptr == kAlternatePathSeparator) {
+        *dest_ptr = kPathSeparator;
+      }
+#endif
+      while (IsPathSeparator(*src))
+        src++;
+    }
+    dest_ptr++;
+  }
+  *dest_ptr = '\0';
+  pathname_ = dest;
+  delete[] dest;
+}
+
+}  // namespace internal
+}  // namespace testing
diff --git a/protobuf/gtest/src/gtest-internal-inl.h b/protobuf/gtest/src/gtest-internal-inl.h
new file mode 100644
index 0000000..855b215
--- /dev/null
+++ b/protobuf/gtest/src/gtest-internal-inl.h
@@ -0,0 +1,1074 @@
+// 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 to 1 iff the current translation unit is
+// part of Google Test's implementation; otherwise it's undefined.
+#if !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_
+
+#ifndef _WIN32_WCE
+#include <errno.h>
+#endif  // !_WIN32_WCE
+#include <stddef.h>
+#include <stdlib.h>  // For strtoll/_strtoul64/malloc/free.
+#include <string.h>  // For memmove.
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <gtest/internal/gtest-port.h>
+
+#if GTEST_OS_WINDOWS
+#include <windows.h>  // For DWORD.
+#endif  // GTEST_OS_WINDOWS
+
+#include <gtest/gtest.h>  // NOLINT
+#include <gtest/gtest-spi.h>
+
+namespace testing {
+
+// Declares the flags.
+//
+// We don't want the users to modify this flag in the code, but want
+// Google Test's own unit tests to be able to access it. Therefore we
+// declare it here as opposed to in gtest.h.
+GTEST_DECLARE_bool_(death_test_use_fork);
+
+namespace internal {
+
+// The value of GetTestTypeId() as seen from within the Google Test
+// library.  This is solely for testing GetTestTypeId().
+GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
+
+// Names of the flags (needed for parsing Google Test flags).
+const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
+const char kBreakOnFailureFlag[] = "break_on_failure";
+const char kCatchExceptionsFlag[] = "catch_exceptions";
+const char kColorFlag[] = "color";
+const char kFilterFlag[] = "filter";
+const char kListTestsFlag[] = "list_tests";
+const char kOutputFlag[] = "output";
+const char kPrintTimeFlag[] = "print_time";
+const char kRandomSeedFlag[] = "random_seed";
+const char kRepeatFlag[] = "repeat";
+const char kShuffleFlag[] = "shuffle";
+const char kStackTraceDepthFlag[] = "stack_trace_depth";
+const char kThrowOnFailureFlag[] = "throw_on_failure";
+
+// A valid random seed must be in [1, kMaxRandomSeed].
+const int kMaxRandomSeed = 99999;
+
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+GTEST_API_ extern bool g_help_flag;
+
+// Returns the current time in milliseconds.
+GTEST_API_ TimeInMillis GetTimeInMillis();
+
+// Returns true iff Google Test should use colors in the output.
+GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
+
+// Formats the given time in milliseconds as seconds.
+GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
+
+// 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.
+GTEST_API_ bool ParseInt32Flag(
+    const char* str, const char* flag, Int32* value);
+
+// Returns a random seed in range [1, kMaxRandomSeed] based on the
+// given --gtest_random_seed flag value.
+inline int GetRandomSeedFromFlag(Int32 random_seed_flag) {
+  const unsigned int raw_seed = (random_seed_flag == 0) ?
+      static_cast<unsigned int>(GetTimeInMillis()) :
+      static_cast<unsigned int>(random_seed_flag);
+
+  // Normalizes the actual seed to range [1, kMaxRandomSeed] such that
+  // it's easy to type.
+  const int normalized_seed =
+      static_cast<int>((raw_seed - 1U) %
+                       static_cast<unsigned int>(kMaxRandomSeed)) + 1;
+  return normalized_seed;
+}
+
+// Returns the first valid random seed after 'seed'.  The behavior is
+// undefined if 'seed' is invalid.  The seed after kMaxRandomSeed is
+// considered to be 1.
+inline int GetNextRandomSeed(int seed) {
+  GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed)
+      << "Invalid random seed " << seed << " - must be in [1, "
+      << kMaxRandomSeed << "].";
+  const int next_seed = seed + 1;
+  return (next_seed > kMaxRandomSeed) ? 1 : next_seed;
+}
+
+// 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() {
+    also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);
+    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);
+    death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
+    filter_ = GTEST_FLAG(filter);
+    internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
+    list_tests_ = GTEST_FLAG(list_tests);
+    output_ = GTEST_FLAG(output);
+    print_time_ = GTEST_FLAG(print_time);
+    random_seed_ = GTEST_FLAG(random_seed);
+    repeat_ = GTEST_FLAG(repeat);
+    shuffle_ = GTEST_FLAG(shuffle);
+    stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
+    throw_on_failure_ = GTEST_FLAG(throw_on_failure);
+  }
+
+  // The d'tor is not virtual.  DO NOT INHERIT FROM THIS CLASS.
+  ~GTestFlagSaver() {
+    GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;
+    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(death_test_use_fork) = death_test_use_fork_;
+    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(print_time) = print_time_;
+    GTEST_FLAG(random_seed) = random_seed_;
+    GTEST_FLAG(repeat) = repeat_;
+    GTEST_FLAG(shuffle) = shuffle_;
+    GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
+    GTEST_FLAG(throw_on_failure) = throw_on_failure_;
+  }
+ private:
+  // Fields for saving the original values of flags.
+  bool also_run_disabled_tests_;
+  bool break_on_failure_;
+  bool catch_exceptions_;
+  String color_;
+  String death_test_style_;
+  bool death_test_use_fork_;
+  String filter_;
+  String internal_run_death_test_;
+  bool list_tests_;
+  String output_;
+  bool print_time_;
+  bool pretty_;
+  internal::Int32 random_seed_;
+  internal::Int32 repeat_;
+  bool shuffle_;
+  internal::Int32 stack_trace_depth_;
+  bool throw_on_failure_;
+} GTEST_ATTRIBUTE_UNUSED_;
+
+// Converts a Unicode code point to a narrow string in UTF-8 encoding.
+// code_point parameter is of type UInt32 because wchar_t may not be
+// wide enough to contain a code point.
+// The output buffer str must containt at least 32 characters.
+// The function returns the address of the output buffer.
+// If the code_point is not a valid Unicode code point
+// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'.
+GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str);
+
+// Converts a wide string to a narrow string in UTF-8 encoding.
+// The wide string is assumed to have the following encoding:
+//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
+// Parameter str points to a null-terminated wide string.
+// Parameter num_chars may additionally limit the number
+// of wchar_t characters processed. -1 is used when the entire string
+// should be processed.
+// If the string contains code points that are not valid Unicode code points
+// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
+// and contains invalid UTF-16 surrogate pairs, values in those pairs
+// will be encoded as individual Unicode characters from Basic Normal Plane.
+GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars);
+
+// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
+// if the variable is present. If a file already exists at this location, this
+// function will write over it. If the variable is present, but the file cannot
+// be created, prints an error and exits.
+void WriteToShardStatusFileIfNeeded();
+
+// Checks whether sharding is enabled by examining the relevant
+// environment variable values. If the variables are present,
+// but inconsistent (e.g., shard_index >= total_shards), prints
+// an error and exits. If in_subprocess_for_death_test, sharding is
+// disabled because it must only be applied to the original test
+// process. Otherwise, we could filter out death tests we intended to execute.
+GTEST_API_ bool ShouldShard(const char* total_shards_str,
+                            const char* shard_index_str,
+                            bool in_subprocess_for_death_test);
+
+// Parses the environment variable var as an Int32. If it is unset,
+// returns default_val. If it is not an Int32, prints an error and
+// and aborts.
+GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
+
+// Given the total number of shards, the shard index, and the test id,
+// returns true iff the test should be run on this shard. The test id is
+// some arbitrary but unique non-negative integer assigned to each test
+// method. Assumes that 0 <= shard_index < total_shards.
+GTEST_API_ bool ShouldRunTestOnShard(
+    int total_shards, int shard_index, int test_id);
+
+// STL container utilities.
+
+// Returns the number of elements in the given container that satisfy
+// the given predicate.
+template <class Container, typename Predicate>
+inline int CountIf(const Container& c, Predicate predicate) {
+  return static_cast<int>(std::count_if(c.begin(), c.end(), predicate));
+}
+
+// Applies a function/functor to each element in the container.
+template <class Container, typename Functor>
+void ForEach(const Container& c, Functor functor) {
+  std::for_each(c.begin(), c.end(), functor);
+}
+
+// Returns the i-th element of the vector, or default_value if i is not
+// in range [0, v.size()).
+template <typename E>
+inline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
+  return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];
+}
+
+// Performs an in-place shuffle of a range of the vector's elements.
+// 'begin' and 'end' are element indices as an STL-style range;
+// i.e. [begin, end) are shuffled, where 'end' == size() means to
+// shuffle to the end of the vector.
+template <typename E>
+void ShuffleRange(internal::Random* random, int begin, int end,
+                  std::vector<E>* v) {
+  const int size = static_cast<int>(v->size());
+  GTEST_CHECK_(0 <= begin && begin <= size)
+      << "Invalid shuffle range start " << begin << ": must be in range [0, "
+      << size << "].";
+  GTEST_CHECK_(begin <= end && end <= size)
+      << "Invalid shuffle range finish " << end << ": must be in range ["
+      << begin << ", " << size << "].";
+
+  // Fisher-Yates shuffle, from
+  // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
+  for (int range_width = end - begin; range_width >= 2; range_width--) {
+    const int last_in_range = begin + range_width - 1;
+    const int selected = begin + random->Generate(range_width);
+    std::swap((*v)[selected], (*v)[last_in_range]);
+  }
+}
+
+// Performs an in-place shuffle of the vector's elements.
+template <typename E>
+inline void Shuffle(internal::Random* random, std::vector<E>* v) {
+  ShuffleRange(random, 0, static_cast<int>(v->size()), v);
+}
+
+// A function for deleting an object.  Handy for being used as a
+// functor.
+template <typename T>
+static void Delete(T* x) {
+  delete x;
+}
+
+// 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_;
+};
+
+class TestInfoImpl {
+ public:
+  TestInfoImpl(TestInfo* parent, const char* test_case_name,
+               const char* name, const char* test_case_comment,
+               const char* comment, TypeId fixture_class_id,
+               internal::TestFactoryBase* factory);
+  ~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 true if this test matches the filter specified by the user.
+  bool matches_filter() const { return matches_filter_; }
+
+  // Sets the matches_filter member.
+  void set_matches_filter(bool matches) { matches_filter_ = matches; }
+
+  // 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 test case comment.
+  const char* test_case_comment() const { return test_case_comment_.c_str(); }
+
+  // Returns the test comment.
+  const char* comment() const { return comment_.c_str(); }
+
+  // Returns the ID of the test fixture class.
+  TypeId fixture_class_id() const { return fixture_class_id_; }
+
+  // Returns the test result.
+  TestResult* result() { return &result_; }
+  const TestResult* result() const { return &result_; }
+
+  // Creates the test object, runs it, records its result, and then
+  // deletes it.
+  void 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 String test_case_comment_;  // Test case comment
+  const String comment_;            // Test comment
+  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
+  bool matches_filter_;             // True if this test matches the
+                                    // user-specified filter.
+  internal::TestFactoryBase* const factory_;  // The factory that creates
+                                              // the test object
+
+  // This field is mutable and needs to be reset before running the
+  // test for the second time.
+  TestResult result_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl);
+};
+
+// 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 GTEST_API_ UnitTestOptions {
+ public:
+  // Functions for processing the gtest_output flag.
+
+  // Returns the output format, or "" for normal printed output.
+  static String GetOutputFormat();
+
+  // Returns the absolute path of the requested output file, or the
+  // default (test_detail.xml in the original working directory) if
+  // none was explicitly specified.
+  static String GetAbsolutePathToOutputFile();
+
+  // 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);
+
+#if 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
+
+  // 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.
+GTEST_API_ 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 implementation of the OsStackTraceGetterInterface interface.
+class OsStackTraceGetter : public OsStackTraceGetterInterface {
+ public:
+  OsStackTraceGetter() : caller_frame_(NULL) {}
+  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;
+};
+
+// This is the default global test part result reporter used in UnitTestImpl.
+// This class should only be used by UnitTestImpl.
+class DefaultGlobalTestPartResultReporter
+  : public TestPartResultReporterInterface {
+ public:
+  explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
+  // Implements the TestPartResultReporterInterface. Reports the test part
+  // result in the current test.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+
+ private:
+  UnitTestImpl* const unit_test_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter);
+};
+
+// This is the default per thread test part result reporter used in
+// UnitTestImpl. This class should only be used by UnitTestImpl.
+class DefaultPerThreadTestPartResultReporter
+    : public TestPartResultReporterInterface {
+ public:
+  explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);
+  // Implements the TestPartResultReporterInterface. The implementation just
+  // delegates to the current global test part result reporter of *unit_test_.
+  virtual void ReportTestPartResult(const TestPartResult& result);
+
+ private:
+  UnitTestImpl* const unit_test_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter);
+};
+
+// 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 GTEST_API_ UnitTestImpl {
+ public:
+  explicit UnitTestImpl(UnitTest* parent);
+  virtual ~UnitTestImpl();
+
+  // There are two different ways to register your own TestPartResultReporter.
+  // You can register your own repoter to listen either only for test results
+  // from the current thread or for results from all threads.
+  // By default, each per-thread test result repoter just passes a new
+  // TestPartResult to the global test result reporter, which registers the
+  // test part result for the currently running test.
+
+  // Returns the global test part result reporter.
+  TestPartResultReporterInterface* GetGlobalTestPartResultReporter();
+
+  // Sets the global test part result reporter.
+  void SetGlobalTestPartResultReporter(
+      TestPartResultReporterInterface* reporter);
+
+  // Returns the test part result reporter for the current thread.
+  TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread();
+
+  // Sets the test part result reporter for the current thread.
+  void SetTestPartResultReporterForCurrentThread(
+      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();
+  }
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  const TestCase* GetTestCase(int i) const {
+    const int index = GetElementOr(test_case_indices_, i, -1);
+    return index < 0 ? NULL : test_cases_[i];
+  }
+
+  // Gets the i-th test case among all the test cases. i can range from 0 to
+  // total_test_case_count() - 1. If i is not in that range, returns NULL.
+  TestCase* GetMutableTestCase(int i) {
+    const int index = GetElementOr(test_case_indices_, i, -1);
+    return index < 0 ? NULL : test_cases_[index];
+  }
+
+  // Provides access to the event listener list.
+  TestEventListeners* listeners() { return &listeners_; }
+
+  // Returns the TestResult for the test that's currently running, or
+  // the TestResult for the ad hoc test if no test is running.
+  TestResult* current_test_result();
+
+  // Returns the TestResult for the ad hoc test.
+  const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; }
+
+  // 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,
+                        const char* comment,
+                        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) {
+    // In order to support thread-safe death tests, we need to
+    // remember the original working directory when the test program
+    // was first invoked.  We cannot do this in RUN_ALL_TESTS(), as
+    // the user may have changed the current directory before calling
+    // RUN_ALL_TESTS().  Therefore we capture the current directory in
+    // AddTestInfo(), which is called to register a TEST or TEST_F
+    // before main() is reached.
+    if (original_working_dir_.IsEmpty()) {
+      original_working_dir_.Set(FilePath::GetCurrentDir());
+      GTEST_CHECK_(!original_working_dir_.IsEmpty())
+          << "Failed to get the current working directory.";
+    }
+
+    GetTestCase(test_info->test_case_name(),
+                test_info->test_case_comment(),
+                set_up_tc,
+                tear_down_tc)->AddTestInfo(test_info);
+  }
+
+#if GTEST_HAS_PARAM_TEST
+  // Returns ParameterizedTestCaseRegistry object used to keep track of
+  // value-parameterized tests and instantiate and register them.
+  internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {
+    return parameterized_test_registry_;
+  }
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // Sets the TestCase object for the test that's currently running.
+  void set_current_test_case(TestCase* a_current_test_case) {
+    current_test_case_ = a_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* a_current_test_info) {
+    current_test_info_ = a_current_test_info;
+  }
+
+  // Registers all parameterized tests defined using TEST_P and
+  // INSTANTIATE_TEST_P, creating regular tests for each test/parameter
+  // combination. This method can be called more then once; it has
+  // guards protecting from registering the tests more then once.
+  // If value-parameterized tests are disabled, RegisterParameterizedTests
+  // is present but does nothing.
+  void RegisterParameterizedTests();
+
+  // 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() {
+    ForEach(test_cases_, TestCase::ClearTestCaseResult);
+    ad_hoc_test_result_.Clear();
+  }
+
+  enum ReactionToSharding {
+    HONOR_SHARDING_PROTOCOL,
+    IGNORE_SHARDING_PROTOCOL
+  };
+
+  // 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.
+  // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests
+  // based on sharding variables in the environment.
+  // Returns the number of tests that should run.
+  int FilterTests(ReactionToSharding shard_tests);
+
+  // Prints the names of the tests matching the user-specified filter flag.
+  void ListTestsMatchingFilter();
+
+  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 vector of environments that need to be set-up/torn-down
+  // before/after the tests are run.
+  std::vector<Environment*>& environments() { return environments_; }
+
+  // Getters for the per-thread Google Test trace stack.
+  std::vector<TraceInfo>& gtest_trace_stack() {
+    return *(gtest_trace_stack_.pointer());
+  }
+  const std::vector<TraceInfo>& gtest_trace_stack() const {
+    return gtest_trace_stack_.get();
+  }
+
+#if GTEST_HAS_DEATH_TEST
+  void InitDeathTestSubprocessControlInfo() {
+    internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
+  }
+  // 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.
+  // Must not be called before a call to InitGoogleTest.
+  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();
+  }
+
+  void SuppressTestEventsIfInSubprocess();
+
+  friend class ReplaceDeathTestFactory;
+#endif  // GTEST_HAS_DEATH_TEST
+
+  // Initializes the event listener performing XML output as specified by
+  // UnitTestOptions. Must not be called before InitGoogleTest.
+  void ConfigureXmlOutput();
+
+  // Performs initialization dependent upon flag values obtained in
+  // ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to
+  // ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest
+  // this function is also called from RunAllTests.  Since this function can be
+  // called more than once, it has to be idempotent.
+  void PostFlagParsingInit();
+
+  // Gets the random seed used at the start of the current test iteration.
+  int random_seed() const { return random_seed_; }
+
+  // Gets the random number generator.
+  internal::Random* random() { return &random_; }
+
+  // Shuffles all test cases, and the tests within each test case,
+  // making sure that death tests are still run first.
+  void ShuffleTests();
+
+  // Restores the test cases and tests to their order before the first shuffle.
+  void UnshuffleTests();
+
+ private:
+  friend class ::testing::UnitTest;
+
+  // The UnitTest object that owns this implementation object.
+  UnitTest* const parent_;
+
+  // The working directory when the first TEST() or TEST_F() was
+  // executed.
+  internal::FilePath original_working_dir_;
+
+  // The default test part result reporters.
+  DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;
+  DefaultPerThreadTestPartResultReporter
+      default_per_thread_test_part_result_reporter_;
+
+  // Points to (but doesn't own) the global test part result reporter.
+  TestPartResultReporterInterface* global_test_part_result_repoter_;
+
+  // Protects read and write access to global_test_part_result_reporter_.
+  internal::Mutex global_test_part_result_reporter_mutex_;
+
+  // Points to (but doesn't own) the per-thread test part result reporter.
+  internal::ThreadLocal<TestPartResultReporterInterface*>
+      per_thread_test_part_result_reporter_;
+
+  // The vector of environments that need to be set-up/torn-down
+  // before/after the tests are run.
+  std::vector<Environment*> environments_;
+
+  // The vector of TestCases in their original order.  It owns the
+  // elements in the vector.
+  std::vector<TestCase*> test_cases_;
+
+  // Provides a level of indirection for the test case list to allow
+  // easy shuffling and restoring the test case order.  The i-th
+  // element of this vector is the index of the i-th test case in the
+  // shuffled order.
+  std::vector<int> test_case_indices_;
+
+#if GTEST_HAS_PARAM_TEST
+  // ParameterizedTestRegistry object used to register value-parameterized
+  // tests.
+  internal::ParameterizedTestCaseRegistry parameterized_test_registry_;
+
+  // Indicates whether RegisterParameterizedTests() has been called already.
+  bool parameterized_tests_registered_;
+#endif  // GTEST_HAS_PARAM_TEST
+
+  // Index of the last death test case registered.  Initially -1.
+  int 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_.  Initially 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_.
+  TestResult ad_hoc_test_result_;
+
+  // The list of event listeners that can be used to track events inside
+  // Google Test.
+  TestEventListeners listeners_;
+
+  // 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_;
+
+  // True iff PostFlagParsingInit() has been called.
+  bool post_flag_parse_init_performed_;
+
+  // The random number seed used at the beginning of the test run.
+  int random_seed_;
+
+  // Our random number generator.
+  internal::Random random_;
+
+  // How long the test took to run, in milliseconds.
+  TimeInMillis elapsed_time_;
+
+#if 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<std::vector<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();
+}
+
+// Internal helper functions for implementing the simple regular
+// expression matcher.
+GTEST_API_ bool IsInSet(char ch, const char* str);
+GTEST_API_ bool IsDigit(char ch);
+GTEST_API_ bool IsPunct(char ch);
+GTEST_API_ bool IsRepeat(char ch);
+GTEST_API_ bool IsWhiteSpace(char ch);
+GTEST_API_ bool IsWordChar(char ch);
+GTEST_API_ bool IsValidEscape(char ch);
+GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
+GTEST_API_ bool ValidateRegex(const char* regex);
+GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
+GTEST_API_ bool MatchRepetitionAndRegexAtHead(
+    bool escaped, char ch, char repeat, const char* regex, const char* str);
+GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);
+GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
+
+#if GTEST_HAS_DEATH_TEST
+
+// Returns the message describing the last system error, regardless of the
+// platform.
+String GetLastErrnoDescription();
+
+#if GTEST_OS_WINDOWS
+// Provides leak-safe Windows kernel handle ownership.
+class AutoHandle {
+ public:
+  AutoHandle() : handle_(INVALID_HANDLE_VALUE) {}
+  explicit AutoHandle(HANDLE handle) : handle_(handle) {}
+
+  ~AutoHandle() { Reset(); }
+
+  HANDLE Get() const { return handle_; }
+  void Reset() { Reset(INVALID_HANDLE_VALUE); }
+  void Reset(HANDLE handle) {
+    if (handle != handle_) {
+      if (handle_ != INVALID_HANDLE_VALUE)
+        ::CloseHandle(handle_);
+      handle_ = handle;
+    }
+  }
+
+ private:
+  HANDLE handle_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle);
+};
+#endif  // GTEST_OS_WINDOWS
+
+// Attempts to parse a string into a positive integer pointed to by the
+// number parameter.  Returns true if that is possible.
+// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use
+// it here.
+template <typename Integer>
+bool ParseNaturalNumber(const ::std::string& str, Integer* number) {
+  // Fail fast if the given string does not begin with a digit;
+  // this bypasses strtoXXX's "optional leading whitespace and plus
+  // or minus sign" semantics, which are undesirable here.
+  if (str.empty() || !isdigit(str[0])) {
+    return false;
+  }
+  errno = 0;
+
+  char* end;
+  // BiggestConvertible is the largest integer type that system-provided
+  // string-to-number conversion routines can return.
+#if GTEST_OS_WINDOWS && !defined(__GNUC__)
+  // MSVC and C++ Builder define __int64 instead of the standard long long.
+  typedef unsigned __int64 BiggestConvertible;
+  const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10);
+#else
+  typedef unsigned long long BiggestConvertible;  // NOLINT
+  const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10);
+#endif  // GTEST_OS_WINDOWS && !defined(__GNUC__)
+  const bool parse_success = *end == '\0' && errno == 0;
+
+  // TODO(vladl@google.com): Convert this to compile time assertion when it is
+  // available.
+  GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
+
+  const Integer result = static_cast<Integer>(parsed);
+  if (parse_success && static_cast<BiggestConvertible>(result) == parsed) {
+    *number = result;
+    return true;
+  }
+  return false;
+}
+#endif  // GTEST_HAS_DEATH_TEST
+
+// TestResult contains some private methods that should be hidden from
+// Google Test user but are required for testing. This class allow our tests
+// to access them.
+//
+// This class is supplied only for the purpose of testing Google Test's own
+// constructs. Do not use it in user tests, either directly or indirectly.
+class TestResultAccessor {
+ public:
+  static void RecordProperty(TestResult* test_result,
+                             const TestProperty& property) {
+    test_result->RecordProperty(property);
+  }
+
+  static void ClearTestPartResults(TestResult* test_result) {
+    test_result->ClearTestPartResults();
+  }
+
+  static const std::vector<testing::TestPartResult>& test_part_results(
+      const TestResult& test_result) {
+    return test_result.test_part_results();
+  }
+};
+
+}  // namespace internal
+}  // namespace testing
+
+#endif  // GTEST_SRC_GTEST_INTERNAL_INL_H_
diff --git a/protobuf/gtest/src/gtest-port.cc b/protobuf/gtest/src/gtest-port.cc
new file mode 100644
index 0000000..b9504f5
--- /dev/null
+++ b/protobuf/gtest/src/gtest-port.cc
@@ -0,0 +1,711 @@
+// 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>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h>  // For TerminateProcess()
+#elif GTEST_OS_WINDOWS
+#include <io.h>
+#include <sys/stat.h>
+#else
+#include <unistd.h>
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#if GTEST_OS_MAC
+#include <mach/mach_init.h>
+#include <mach/task.h>
+#include <mach/vm_map.h>
+#endif  // GTEST_OS_MAC
+
+#include <gtest/gtest-spi.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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+namespace internal {
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
+const int kStdOutFileno = 1;
+const int kStdErrFileno = 2;
+#else
+const int kStdOutFileno = STDOUT_FILENO;
+const int kStdErrFileno = STDERR_FILENO;
+#endif  // _MSC_VER
+
+#if GTEST_OS_MAC
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+size_t GetThreadCount() {
+  const task_t task = mach_task_self();
+  mach_msg_type_number_t thread_count;
+  thread_act_array_t thread_list;
+  const kern_return_t status = task_threads(task, &thread_list, &thread_count);
+  if (status == KERN_SUCCESS) {
+    // task_threads allocates resources in thread_list and we need to free them
+    // to avoid leaks.
+    vm_deallocate(task,
+                  reinterpret_cast<vm_address_t>(thread_list),
+                  sizeof(thread_t) * thread_count);
+    return static_cast<size_t>(thread_count);
+  } else {
+    return 0;
+  }
+}
+
+#else
+
+size_t GetThreadCount() {
+  // There's no portable way to detect the number of threads, so we just
+  // return 0 to indicate that we cannot detect it.
+  return 0;
+}
+
+#endif  // GTEST_OS_MAC
+
+#if GTEST_USES_POSIX_RE
+
+// Implements RE.  Currently only needed for death tests.
+
+RE::~RE() {
+  if (is_valid_) {
+    // regfree'ing an invalid regex might crash because the content
+    // of the regex is undefined. Since the regex's are essentially
+    // the same, one cannot be valid (or invalid) without the other
+    // being so too.
+    regfree(&partial_regex_);
+    regfree(&full_regex_);
+  }
+  free(const_cast<char*>(pattern_));
+}
+
+// Returns true iff regular expression re matches the entire str.
+bool RE::FullMatch(const char* str, const RE& re) {
+  if (!re.is_valid_) return false;
+
+  regmatch_t match;
+  return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
+}
+
+// Returns true iff regular expression re matches a substring of str
+// (including str itself).
+bool RE::PartialMatch(const char* str, const RE& re) {
+  if (!re.is_valid_) return false;
+
+  regmatch_t match;
+  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+  pattern_ = posix::StrDup(regex);
+
+  // Reserves enough bytes to hold the regular expression used for a
+  // full match.
+  const size_t full_regex_len = strlen(regex) + 10;
+  char* const full_pattern = new char[full_regex_len];
+
+  snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
+  is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
+  // We want to call regcomp(&partial_regex_, ...) even if the
+  // previous expression returns false.  Otherwise partial_regex_ may
+  // not be properly initialized can may cause trouble when it's
+  // freed.
+  //
+  // Some implementation of POSIX regex (e.g. on at least some
+  // versions of Cygwin) doesn't accept the empty string as a valid
+  // regex.  We change it to an equivalent form "()" to be safe.
+  if (is_valid_) {
+    const char* const partial_regex = (*regex == '\0') ? "()" : regex;
+    is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
+  }
+  EXPECT_TRUE(is_valid_)
+      << "Regular expression \"" << regex
+      << "\" is not a valid POSIX Extended regular expression.";
+
+  delete[] full_pattern;
+}
+
+#elif GTEST_USES_SIMPLE_RE
+
+// Returns true iff ch appears anywhere in str (excluding the
+// terminating '\0' character).
+bool IsInSet(char ch, const char* str) {
+  return ch != '\0' && strchr(str, ch) != NULL;
+}
+
+// Returns true iff ch belongs to the given classification.  Unlike
+// similar functions in <ctype.h>, these aren't affected by the
+// current locale.
+bool IsDigit(char ch) { return '0' <= ch && ch <= '9'; }
+bool IsPunct(char ch) {
+  return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
+}
+bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
+bool IsWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
+bool IsWordChar(char ch) {
+  return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
+      ('0' <= ch && ch <= '9') || ch == '_';
+}
+
+// Returns true iff "\\c" is a supported escape sequence.
+bool IsValidEscape(char c) {
+  return (IsPunct(c) || IsInSet(c, "dDfnrsStvwW"));
+}
+
+// Returns true iff the given atom (specified by escaped and pattern)
+// matches ch.  The result is undefined if the atom is invalid.
+bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
+  if (escaped) {  // "\\p" where p is pattern_char.
+    switch (pattern_char) {
+      case 'd': return IsDigit(ch);
+      case 'D': return !IsDigit(ch);
+      case 'f': return ch == '\f';
+      case 'n': return ch == '\n';
+      case 'r': return ch == '\r';
+      case 's': return IsWhiteSpace(ch);
+      case 'S': return !IsWhiteSpace(ch);
+      case 't': return ch == '\t';
+      case 'v': return ch == '\v';
+      case 'w': return IsWordChar(ch);
+      case 'W': return !IsWordChar(ch);
+    }
+    return IsPunct(pattern_char) && pattern_char == ch;
+  }
+
+  return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
+}
+
+// Helper function used by ValidateRegex() to format error messages.
+String FormatRegexSyntaxError(const char* regex, int index) {
+  return (Message() << "Syntax error at index " << index
+          << " in simple regular expression \"" << regex << "\": ").GetString();
+}
+
+// Generates non-fatal failures and returns false if regex is invalid;
+// otherwise returns true.
+bool ValidateRegex(const char* regex) {
+  if (regex == NULL) {
+    // TODO(wan@google.com): fix the source file location in the
+    // assertion failures to match where the regex is used in user
+    // code.
+    ADD_FAILURE() << "NULL is not a valid simple regular expression.";
+    return false;
+  }
+
+  bool is_valid = true;
+
+  // True iff ?, *, or + can follow the previous atom.
+  bool prev_repeatable = false;
+  for (int i = 0; regex[i]; i++) {
+    if (regex[i] == '\\') {  // An escape sequence
+      i++;
+      if (regex[i] == '\0') {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
+                      << "'\\' cannot appear at the end.";
+        return false;
+      }
+
+      if (!IsValidEscape(regex[i])) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
+                      << "invalid escape sequence \"\\" << regex[i] << "\".";
+        is_valid = false;
+      }
+      prev_repeatable = true;
+    } else {  // Not an escape sequence.
+      const char ch = regex[i];
+
+      if (ch == '^' && i > 0) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'^' can only appear at the beginning.";
+        is_valid = false;
+      } else if (ch == '$' && regex[i + 1] != '\0') {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'$' can only appear at the end.";
+        is_valid = false;
+      } else if (IsInSet(ch, "()[]{}|")) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'" << ch << "' is unsupported.";
+        is_valid = false;
+      } else if (IsRepeat(ch) && !prev_repeatable) {
+        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
+                      << "'" << ch << "' can only follow a repeatable token.";
+        is_valid = false;
+      }
+
+      prev_repeatable = !IsInSet(ch, "^$?*+");
+    }
+  }
+
+  return is_valid;
+}
+
+// Matches a repeated regex atom followed by a valid simple regular
+// expression.  The regex atom is defined as c if escaped is false,
+// or \c otherwise.  repeat is the repetition meta character (?, *,
+// or +).  The behavior is undefined if str contains too many
+// characters to be indexable by size_t, in which case the test will
+// probably time out anyway.  We are fine with this limitation as
+// std::string has it too.
+bool MatchRepetitionAndRegexAtHead(
+    bool escaped, char c, char repeat, const char* regex,
+    const char* str) {
+  const size_t min_count = (repeat == '+') ? 1 : 0;
+  const size_t max_count = (repeat == '?') ? 1 :
+      static_cast<size_t>(-1) - 1;
+  // We cannot call numeric_limits::max() as it conflicts with the
+  // max() macro on Windows.
+
+  for (size_t i = 0; i <= max_count; ++i) {
+    // We know that the atom matches each of the first i characters in str.
+    if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
+      // We have enough matches at the head, and the tail matches too.
+      // Since we only care about *whether* the pattern matches str
+      // (as opposed to *how* it matches), there is no need to find a
+      // greedy match.
+      return true;
+    }
+    if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
+      return false;
+  }
+  return false;
+}
+
+// Returns true iff regex matches a prefix of str.  regex must be a
+// valid simple regular expression and not start with "^", or the
+// result is undefined.
+bool MatchRegexAtHead(const char* regex, const char* str) {
+  if (*regex == '\0')  // An empty regex matches a prefix of anything.
+    return true;
+
+  // "$" only matches the end of a string.  Note that regex being
+  // valid guarantees that there's nothing after "$" in it.
+  if (*regex == '$')
+    return *str == '\0';
+
+  // Is the first thing in regex an escape sequence?
+  const bool escaped = *regex == '\\';
+  if (escaped)
+    ++regex;
+  if (IsRepeat(regex[1])) {
+    // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
+    // here's an indirect recursion.  It terminates as the regex gets
+    // shorter in each recursion.
+    return MatchRepetitionAndRegexAtHead(
+        escaped, regex[0], regex[1], regex + 2, str);
+  } else {
+    // regex isn't empty, isn't "$", and doesn't start with a
+    // repetition.  We match the first atom of regex with the first
+    // character of str and recurse.
+    return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
+        MatchRegexAtHead(regex + 1, str + 1);
+  }
+}
+
+// Returns true iff regex matches any substring of str.  regex must be
+// a valid simple regular expression, or the result is undefined.
+//
+// The algorithm is recursive, but the recursion depth doesn't exceed
+// the regex length, so we won't need to worry about running out of
+// stack space normally.  In rare cases the time complexity can be
+// exponential with respect to the regex length + the string length,
+// but usually it's must faster (often close to linear).
+bool MatchRegexAnywhere(const char* regex, const char* str) {
+  if (regex == NULL || str == NULL)
+    return false;
+
+  if (*regex == '^')
+    return MatchRegexAtHead(regex + 1, str);
+
+  // A successful match can be anywhere in str.
+  do {
+    if (MatchRegexAtHead(regex, str))
+      return true;
+  } while (*str++ != '\0');
+  return false;
+}
+
+// Implements the RE class.
+
+RE::~RE() {
+  free(const_cast<char*>(pattern_));
+  free(const_cast<char*>(full_pattern_));
+}
+
+// Returns true iff regular expression re matches the entire str.
+bool RE::FullMatch(const char* str, const RE& re) {
+  return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
+}
+
+// Returns true iff regular expression re matches a substring of str
+// (including str itself).
+bool RE::PartialMatch(const char* str, const RE& re) {
+  return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
+}
+
+// Initializes an RE from its string representation.
+void RE::Init(const char* regex) {
+  pattern_ = full_pattern_ = NULL;
+  if (regex != NULL) {
+    pattern_ = posix::StrDup(regex);
+  }
+
+  is_valid_ = ValidateRegex(regex);
+  if (!is_valid_) {
+    // No need to calculate the full pattern when the regex is invalid.
+    return;
+  }
+
+  const size_t len = strlen(regex);
+  // Reserves enough bytes to hold the regular expression used for a
+  // full match: we need space to prepend a '^', append a '$', and
+  // terminate the string with '\0'.
+  char* buffer = static_cast<char*>(malloc(len + 3));
+  full_pattern_ = buffer;
+
+  if (*regex != '^')
+    *buffer++ = '^';  // Makes sure full_pattern_ starts with '^'.
+
+  // We don't use snprintf or strncpy, as they trigger a warning when
+  // compiled with VC++ 8.0.
+  memcpy(buffer, regex, len);
+  buffer += len;
+
+  if (len == 0 || regex[len - 1] != '$')
+    *buffer++ = '$';  // Makes sure full_pattern_ ends with '$'.
+
+  *buffer = '\0';
+}
+
+#endif  // GTEST_USES_POSIX_RE
+
+
+GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
+    : severity_(severity) {
+  const char* const marker =
+      severity == GTEST_INFO ?    "[  INFO ]" :
+      severity == GTEST_WARNING ? "[WARNING]" :
+      severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]";
+  GetStream() << ::std::endl << marker << " "
+              << FormatFileLocation(file, line).c_str() << ": ";
+}
+
+// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
+GTestLog::~GTestLog() {
+  GetStream() << ::std::endl;
+  if (severity_ == GTEST_FATAL) {
+    fflush(stderr);
+    posix::Abort();
+  }
+}
+// Disable Microsoft deprecation warnings for POSIX functions called from
+// this class (creat, dup, dup2, and close)
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4996)
+#endif  // _MSC_VER
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+
+// Object that captures an output stream (stdout/stderr).
+class CapturedStream {
+ public:
+  // The ctor redirects the stream to a temporary file.
+  CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
+#if GTEST_OS_WINDOWS
+    char temp_dir_path[MAX_PATH + 1] = { '\0' };  // NOLINT
+    char temp_file_path[MAX_PATH + 1] = { '\0' };  // NOLINT
+
+    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
+    const UINT success = ::GetTempFileNameA(temp_dir_path,
+                                            "gtest_redir",
+                                            0,  // Generate unique file name.
+                                            temp_file_path);
+    GTEST_CHECK_(success != 0)
+        << "Unable to create a temporary file in " << temp_dir_path;
+    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
+    GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
+                                    << temp_file_path;
+    filename_ = temp_file_path;
+#else
+    // There's no guarantee that a test has write access to the
+    // current directory, so we create the temporary file in the /tmp
+    // directory instead.
+    char name_template[] = "/tmp/captured_stream.XXXXXX";
+    const int captured_fd = mkstemp(name_template);
+    filename_ = name_template;
+#endif  // GTEST_OS_WINDOWS
+    fflush(NULL);
+    dup2(captured_fd, fd_);
+    close(captured_fd);
+  }
+
+  ~CapturedStream() {
+    remove(filename_.c_str());
+  }
+
+  String GetCapturedString() {
+    if (uncaptured_fd_ != -1) {
+      // Restores the original stream.
+      fflush(NULL);
+      dup2(uncaptured_fd_, fd_);
+      close(uncaptured_fd_);
+      uncaptured_fd_ = -1;
+    }
+
+    FILE* const file = posix::FOpen(filename_.c_str(), "r");
+    const String content = ReadEntireFile(file);
+    posix::FClose(file);
+    return content;
+  }
+
+ private:
+  // Reads the entire content of a file as a String.
+  static String ReadEntireFile(FILE* file);
+
+  // Returns the size (in bytes) of a file.
+  static size_t GetFileSize(FILE* file);
+
+  const int fd_;  // A stream to capture.
+  int uncaptured_fd_;
+  // Name of the temporary file holding the stderr output.
+  ::std::string filename_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
+};
+
+// Returns the size (in bytes) of a file.
+size_t CapturedStream::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.
+String CapturedStream::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 String content(buffer, bytes_read);
+  delete[] buffer;
+
+  return content;
+}
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif  // _MSC_VER
+
+static CapturedStream* g_captured_stderr = NULL;
+static CapturedStream* g_captured_stdout = NULL;
+
+// Starts capturing an output stream (stdout/stderr).
+void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
+  if (*stream != NULL) {
+    GTEST_LOG_(FATAL) << "Only one " << stream_name
+                      << " capturer can exist at a time.";
+  }
+  *stream = new CapturedStream(fd);
+}
+
+// Stops capturing the output stream and returns the captured string.
+String GetCapturedStream(CapturedStream** captured_stream) {
+  const String content = (*captured_stream)->GetCapturedString();
+
+  delete *captured_stream;
+  *captured_stream = NULL;
+
+  return content;
+}
+
+// Starts capturing stdout.
+void CaptureStdout() {
+  CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
+}
+
+// Starts capturing stderr.
+void CaptureStderr() {
+  CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
+}
+
+// Stops capturing stdout and returns the captured string.
+String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
+
+// Stops capturing stderr and returns the captured string.
+String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
+
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
+#if GTEST_HAS_DEATH_TEST
+
+// A copy of all command line arguments.  Set by InitGoogleTest().
+::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
+
+#if GTEST_OS_WINDOWS_MOBILE
+namespace posix {
+void Abort() {
+  DebugBreak();
+  TerminateProcess(GetCurrentProcess(), 1);
+}
+}  // namespace posix
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+// 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 (size_t i = 0; i != full_flag.length(); i++) {
+    env_var << static_cast<char>(toupper(full_flag.c_str()[i]));
+  }
+
+  return env_var.GetString();
+}
+
+// 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 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 = posix::GetEnv(env_var.c_str());
+  return string_value == NULL ?
+      default_value : strcmp(string_value, "0") != 0;
+}
+
+// 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 = posix::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 = posix::GetEnv(env_var.c_str());
+  return value == NULL ? default_value : value;
+}
+
+}  // namespace internal
+}  // namespace testing
diff --git a/protobuf/gtest/src/gtest-test-part.cc b/protobuf/gtest/src/gtest-test-part.cc
new file mode 100644
index 0000000..5d183a4
--- /dev/null
+++ b/protobuf/gtest/src/gtest-test-part.cc
@@ -0,0 +1,110 @@
+// 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: mheule@google.com (Markus Heule)
+//
+// The Google C++ Testing Framework (Google Test)
+
+#include <gtest/gtest-test-part.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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+
+using internal::GetUnitTestImpl;
+
+// Gets the summary of the failure message by omitting the stack trace
+// in it.
+internal::String TestPartResult::ExtractSummary(const char* message) {
+  const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
+  return stack_trace == NULL ? internal::String(message) :
+      internal::String(message, stack_trace - message);
+}
+
+// Prints a TestPartResult object.
+std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
+  return os
+      << result.file_name() << ":" << result.line_number() << ": "
+      << (result.type() == TestPartResult::kSuccess ? "Success" :
+          result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
+          "Non-fatal failure") << ":\n"
+      << result.message() << std::endl;
+}
+
+// Appends a TestPartResult to the array.
+void TestPartResultArray::Append(const TestPartResult& result) {
+  array_.push_back(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);
+    internal::posix::Abort();
+  }
+
+  return array_[index];
+}
+
+// Returns the number of TestPartResult objects in the array.
+int TestPartResultArray::size() const {
+  return static_cast<int>(array_.size());
+}
+
+namespace internal {
+
+HasNewFatalFailureHelper::HasNewFatalFailureHelper()
+    : has_new_fatal_failure_(false),
+      original_reporter_(GetUnitTestImpl()->
+                         GetTestPartResultReporterForCurrentThread()) {
+  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
+}
+
+HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
+  GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(
+      original_reporter_);
+}
+
+void HasNewFatalFailureHelper::ReportTestPartResult(
+    const TestPartResult& result) {
+  if (result.fatally_failed())
+    has_new_fatal_failure_ = true;
+  original_reporter_->ReportTestPartResult(result);
+}
+
+}  // namespace internal
+
+}  // namespace testing
diff --git a/protobuf/gtest/src/gtest-typed-test.cc b/protobuf/gtest/src/gtest-typed-test.cc
new file mode 100644
index 0000000..3cc4b5d
--- /dev/null
+++ b/protobuf/gtest/src/gtest-typed-test.cc
@@ -0,0 +1,110 @@
+// 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/gtest-typed-test.h>
+#include <gtest/gtest.h>
+
+namespace testing {
+namespace internal {
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// Skips to the first non-space char in str. Returns an empty string if str
+// contains only whitespace characters.
+static const char* SkipSpaces(const char* str) {
+  while (isspace(*str))
+    str++;
+  return str;
+}
+
+// Verifies that registered_tests match the test names in
+// defined_test_names_; returns registered_tests if successful, or
+// aborts the program otherwise.
+const char* TypedTestCasePState::VerifyRegisteredTestNames(
+    const char* file, int line, const char* registered_tests) {
+  typedef ::std::set<const char*>::const_iterator DefinedTestIter;
+  registered_ = true;
+
+  // Skip initial whitespace in registered_tests since some
+  // preprocessors prefix stringizied literals with whitespace.
+  registered_tests = SkipSpaces(registered_tests);
+
+  Message errors;
+  ::std::set<String> tests;
+  for (const char* names = registered_tests; names != NULL;
+       names = SkipComma(names)) {
+    const String name = GetPrefixUntilComma(names);
+    if (tests.count(name) != 0) {
+      errors << "Test " << name << " is listed more than once.\n";
+      continue;
+    }
+
+    bool found = false;
+    for (DefinedTestIter it = defined_test_names_.begin();
+         it != defined_test_names_.end();
+         ++it) {
+      if (name == *it) {
+        found = true;
+        break;
+      }
+    }
+
+    if (found) {
+      tests.insert(name);
+    } else {
+      errors << "No test named " << name
+             << " can be found in this test case.\n";
+    }
+  }
+
+  for (DefinedTestIter it = defined_test_names_.begin();
+       it != defined_test_names_.end();
+       ++it) {
+    if (tests.count(*it) == 0) {
+      errors << "You forgot to list test " << *it << ".\n";
+    }
+  }
+
+  const String& errors_str = errors.GetString();
+  if (errors_str != "") {
+    fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
+            errors_str.c_str());
+    fflush(stderr);
+    posix::Abort();
+  }
+
+  return registered_tests;
+}
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+}  // namespace internal
+}  // namespace testing
diff --git a/protobuf/gtest/src/gtest.cc b/protobuf/gtest/src/gtest.cc
new file mode 100644
index 0000000..342d458
--- /dev/null
+++ b/protobuf/gtest/src/gtest.cc
@@ -0,0 +1,4704 @@
+// 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 <wchar.h>
+#include <wctype.h>
+
+#include <algorithm>
+#include <ostream>
+#include <sstream>
+#include <vector>
+
+#if GTEST_OS_LINUX
+
+// TODO(kenton@google.com): Use autoconf to detect availability of
+// gettimeofday().
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+
+#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 GTEST_OS_SYMBIAN
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h>  // NOLINT
+
+#elif GTEST_OS_ZOS
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h>  // NOLINT
+
+// On z/OS we additionally need strings.h for strcasecmp.
+#include <strings.h>  // NOLINT
+
+#elif GTEST_OS_WINDOWS_MOBILE  // We are on Windows CE.
+
+#include <windows.h>  // NOLINT
+
+#elif GTEST_OS_WINDOWS  // 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 GTEST_OS_WINDOWS_MINGW
+// MinGW has gettimeofday() but not _ftime64().
+// TODO(kenton@google.com): Use autoconf to detect availability of
+//   gettimeofday().
+// TODO(kenton@google.com): There are other ways to get the time on
+//   Windows, like GetTickCount() or GetSystemTimeAsFileTime().  MinGW
+//   supports these.  consider using them instead.
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+#include <sys/time.h>  // NOLINT
+#endif  // GTEST_OS_WINDOWS_MINGW
+
+// 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@google.com): Use autoconf to detect availability of
+//   gettimeofday().
+#define GTEST_HAS_GETTIMEOFDAY_ 1
+
+// cpplint thinks that the header is already included, so we want to
+// silence it.
+#include <sys/time.h>  // NOLINT
+#include <unistd.h>  // NOLINT
+
+#endif  // GTEST_OS_LINUX
+
+#if GTEST_HAS_EXCEPTIONS
+#include <stdexcept>
+#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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+#if GTEST_OS_WINDOWS
+#define vsnprintf _vsnprintf
+#endif  // GTEST_OS_WINDOWS
+
+namespace testing {
+
+using internal::CountIf;
+using internal::ForEach;
+using internal::GetElementOr;
+using internal::Shuffle;
+
+// Constants.
+
+// A test whose test case name or test name matches this filter is
+// disabled and not run.
+static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*";
+
+// A test case whose name matches this filter is considered a death
+// test case and will be run before test cases whose name doesn't
+// match this filter.
+static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
+
+// A test filter that matches everything.
+static const char kUniversalFilter[] = "*";
+
+// The default output file for XML output.
+static const char kDefaultOutputFile[] = "test_detail.xml";
+
+// The environment variable name for the test shard index.
+static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
+// The environment variable name for the total number of test shards.
+static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS";
+// The environment variable name for the test shard status file.
+static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE";
+
+namespace internal {
+
+// The text used in failure messages to indicate the start of the
+// stack trace.
+const char kStackTraceMarker[] = "\nStack trace:\n";
+
+// g_help_flag is true iff the --help flag or an equivalent form is
+// specified on the command line.
+bool g_help_flag = false;
+
+}  // namespace internal
+
+GTEST_DEFINE_bool_(
+    also_run_disabled_tests,
+    internal::BoolFromGTestEnv("also_run_disabled_tests", false),
+    "Run disabled tests too, in addition to the tests normally being run.");
+
+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, xterm-color, xterm-256color, linux or cygwin.");
+
+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_bool_(
+    print_time,
+    internal::BoolFromGTestEnv("print_time", true),
+    "True iff " GTEST_NAME_
+    " should display elapsed time in text output.");
+
+GTEST_DEFINE_int32_(
+    random_seed,
+    internal::Int32FromGTestEnv("random_seed", 0),
+    "Random number seed to use when shuffling test orders.  Must be in range "
+    "[1, 99999], or 0 to use a seed based on the current time.");
+
+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_bool_(
+    show_internal_stack_frames, false,
+    "True iff " GTEST_NAME_ " should include internal stack frames when "
+    "printing test failure stack traces.");
+
+GTEST_DEFINE_bool_(
+    shuffle,
+    internal::BoolFromGTestEnv("shuffle", false),
+    "True iff " GTEST_NAME_
+    " should randomize tests' order on every run.");
+
+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_(
+    throw_on_failure,
+    internal::BoolFromGTestEnv("throw_on_failure", false),
+    "When this flag is specified, a failed assertion will throw an exception "
+    "if exceptions are enabled or exit the program with a non-zero code "
+    "otherwise.");
+
+namespace internal {
+
+// Generates a random number from [0, range), using a Linear
+// Congruential Generator (LCG).  Crashes if 'range' is 0 or greater
+// than kMaxRange.
+UInt32 Random::Generate(UInt32 range) {
+  // These constants are the same as are used in glibc's rand(3).
+  state_ = (1103515245U*state_ + 12345U) % kMaxRange;
+
+  GTEST_CHECK_(range > 0)
+      << "Cannot generate a number in the range [0, 0).";
+  GTEST_CHECK_(range <= kMaxRange)
+      << "Generation of a number in [0, " << range << ") was requested, "
+      << "but this can only generate numbers in [0, " << kMaxRange << ").";
+
+  // Converting via modulus introduces a bit of downward bias, but
+  // it's simple, and a linear congruential generator isn't too good
+  // to begin with.
+  return state_ % range;
+}
+
+// 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::InitGoogleTest() to initialize Google
+// Test.  g_init_gtest_count is set to the number of times
+// InitGoogleTest() has been called.  We don't protect this variable
+// under a mutex as it is only accessed in the main thread.
+int g_init_gtest_count = 0;
+static bool GTestIsInitialized() { return g_init_gtest_count != 0; }
+
+// Iterates over a vector 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 std::vector<TestCase*>& case_list,
+                               int (TestCase::*method)() const) {
+  int sum = 0;
+  for (size_t i = 0; i < case_list.size(); i++) {
+    sum += (case_list[i]->*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();
+}
+
+// AssertHelper constructor.
+AssertHelper::AssertHelper(TestPartResult::Type type,
+                           const char* file,
+                           int line,
+                           const char* message)
+    : data_(new AssertHelperData(type, file, line, message)) {
+}
+
+AssertHelper::~AssertHelper() {
+  delete data_;
+}
+
+// Message assignment, for assertion streaming support.
+void AssertHelper::operator=(const Message& message) const {
+  UnitTest::GetInstance()->
+    AddTestPartResult(data_->type, data_->file, data_->line,
+                      AppendUserMessage(data_->message, message),
+                      UnitTest::GetInstance()->impl()
+                      ->CurrentOsStackTraceExceptTop(1)
+                      // Skips the stack frame for this function itself.
+                      );  // NOLINT
+}
+
+// Mutex for linked pointers.
+GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
+
+// Application pathname gotten in InitGoogleTest.
+String g_executable_path;
+
+// Returns the current application's name, removing directory path if that
+// is present.
+FilePath GetCurrentExecutableName() {
+  FilePath result;
+
+#if GTEST_OS_WINDOWS
+  result.Set(FilePath(g_executable_path).RemoveExtension("exe"));
+#else
+  result.Set(FilePath(g_executable_path));
+#endif  // GTEST_OS_WINDOWS
+
+  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::GetAbsolutePathToOutputFile() {
+  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(internal::FilePath::ConcatPaths(
+               internal::FilePath(
+                   UnitTest::GetInstance()->original_working_dir()),
+               internal::FilePath(kDefaultOutputFile)).ToString() );
+
+  internal::FilePath output_name(colon + 1);
+  if (!output_name.IsAbsolutePath())
+    // TODO(wan@google.com): on Windows \some\path is not an absolute
+    // path (as its meaning depends on the current drive), yet the
+    // following logic for turning it into an absolute path is wrong.
+    // Fix it.
+    output_name = internal::FilePath::ConcatPaths(
+        internal::FilePath(UnitTest::GetInstance()->original_working_dir()),
+        internal::FilePath(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;
+  for (;;) {
+    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 = String(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()));
+}
+
+#if 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 c'tor sets this object as the test part result reporter used by
+// Google Test.  The 'result' parameter specifies where to report the
+// results. Intercepts only failures from the current thread.
+ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter(
+    TestPartResultArray* result)
+    : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD),
+      result_(result) {
+  Init();
+}
+
+// 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(
+    InterceptMode intercept_mode, TestPartResultArray* result)
+    : intercept_mode_(intercept_mode),
+      result_(result) {
+  Init();
+}
+
+void ScopedFakeTestPartResultReporter::Init() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
+    old_reporter_ = impl->GetGlobalTestPartResultReporter();
+    impl->SetGlobalTestPartResultReporter(this);
+  } else {
+    old_reporter_ = impl->GetTestPartResultReporterForCurrentThread();
+    impl->SetTestPartResultReporterForCurrentThread(this);
+  }
+}
+
+// The d'tor restores the test part result reporter used by Google Test
+// before.
+ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {
+  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
+  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
+    impl->SetGlobalTestPartResultReporter(old_reporter_);
+  } else {
+    impl->SetTestPartResultReporterForCurrentThread(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 {
+
+// Returns the type ID of ::testing::Test.  We should always call this
+// instead of GetTypeId< ::testing::Test>() to get the type ID of
+// testing::Test.  This is to work around a suspected linker bug when
+// using Google Test as a framework on Mac OS X.  The bug causes
+// GetTypeId< ::testing::Test>() to return different values depending
+// on whether the call is from the Google Test framework itself or
+// from user test code.  GetTestTypeId() is guaranteed to always
+// return the same value, as it always calls GetTypeId<>() from the
+// gtest.cc, which is within the Google Test framework.
+TypeId GetTestTypeId() {
+  return GetTypeId<Test>();
+}
+
+// The value of GetTestTypeId() as seen from within the Google Test
+// library.  This is solely for testing GetTestTypeId().
+extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId();
+
+// 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,
+                              TestPartResult::Type type,
+                              const char* substr) {
+  const String expected(type == TestPartResult::kFatalFailure ?
+                        "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,
+    TestPartResult::Type 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());
+}
+
+DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter(
+    UnitTestImpl* unit_test) : unit_test_(unit_test) {}
+
+void DefaultGlobalTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  unit_test_->current_test_result()->AddTestPartResult(result);
+  unit_test_->listeners()->repeater()->OnTestPartResult(result);
+}
+
+DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter(
+    UnitTestImpl* unit_test) : unit_test_(unit_test) {}
+
+void DefaultPerThreadTestPartResultReporter::ReportTestPartResult(
+    const TestPartResult& result) {
+  unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result);
+}
+
+// Returns the global test part result reporter.
+TestPartResultReporterInterface*
+UnitTestImpl::GetGlobalTestPartResultReporter() {
+  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
+  return global_test_part_result_repoter_;
+}
+
+// Sets the global test part result reporter.
+void UnitTestImpl::SetGlobalTestPartResultReporter(
+    TestPartResultReporterInterface* reporter) {
+  internal::MutexLock lock(&global_test_part_result_reporter_mutex_);
+  global_test_part_result_repoter_ = reporter;
+}
+
+// Returns the test part result reporter for the current thread.
+TestPartResultReporterInterface*
+UnitTestImpl::GetTestPartResultReporterForCurrentThread() {
+  return per_thread_test_part_result_reporter_.get();
+}
+
+// Sets the test part result reporter for the current thread.
+void UnitTestImpl::SetTestPartResultReporterForCurrentThread(
+    TestPartResultReporterInterface* reporter) {
+  per_thread_test_part_result_reporter_.set(reporter);
+}
+
+// Gets the number of successful test cases.
+int UnitTestImpl::successful_test_case_count() const {
+  return CountIf(test_cases_, TestCasePassed);
+}
+
+// Gets the number of failed test cases.
+int UnitTestImpl::failed_test_case_count() const {
+  return CountIf(test_cases_, TestCaseFailed);
+}
+
+// Gets the number of all test cases.
+int UnitTestImpl::total_test_case_count() const {
+  return static_cast<int>(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 CountIf(test_cases_, 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("");
+}
+
+// Returns the current time in milliseconds.
+TimeInMillis GetTimeInMillis() {
+#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__)
+  // Difference between 1970-01-01 and 1601-01-01 in milliseconds.
+  // http://analogous.blogspot.com/2005/04/epoch.html
+  const TimeInMillis kJavaEpochToWinFileTimeDelta =
+    static_cast<TimeInMillis>(116444736UL) * 100000UL;
+  const DWORD kTenthMicrosInMilliSecond = 10000;
+
+  SYSTEMTIME now_systime;
+  FILETIME now_filetime;
+  ULARGE_INTEGER now_int64;
+  // TODO(kenton@google.com): 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 GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_
+  __timeb64 now;
+#ifdef _MSC_VER
+  // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
+  // (deprecated function) there.
+  // TODO(kenton@google.com): 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 GTEST_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."
+#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];
+    posix::StrNCpy(clone, str, length);
+    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));
+}
+
+#if GTEST_OS_WINDOWS_MOBILE
+// Creates a UTF-16 wide string from the given ANSI string, allocating
+// memory using new. The caller is responsible for deleting the return
+// value using delete[]. Returns the wide string, or NULL if the
+// input is NULL.
+LPCWSTR String::AnsiToUtf16(const char* ansi) {
+  if (!ansi) return NULL;
+  const int length = strlen(ansi);
+  const int unicode_length =
+      MultiByteToWideChar(CP_ACP, 0, ansi, length,
+                          NULL, 0);
+  WCHAR* unicode = new WCHAR[unicode_length + 1];
+  MultiByteToWideChar(CP_ACP, 0, ansi, length,
+                      unicode, unicode_length);
+  unicode[unicode_length] = 0;
+  return unicode;
+}
+
+// Creates an ANSI string from the given wide string, allocating
+// memory using new. The caller is responsible for deleting the return
+// value using delete[]. Returns the ANSI string, or NULL if the
+// input is NULL.
+const char* String::Utf16ToAnsi(LPCWSTR utf16_str)  {
+  if (!utf16_str) return NULL;
+  const int ansi_length =
+      WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
+                          NULL, 0, NULL, NULL);
+  char* ansi = new char[ansi_length + 1];
+  WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
+                      ansi, ansi_length, NULL, NULL);
+  ansi[ansi_length] = 0;
+  return ansi;
+}
+
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+// 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 length,
+                                     Message* msg) {
+  // 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).
+  for (size_t i = 0; i != length; ) {  // NOLINT
+    if (wstr[i] != L'\0') {
+      *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i));
+      while (i != length && wstr[i] != L'\0')
+        i++;
+    } else {
+      *msg << '\0';
+      i++;
+    }
+  }
+}
+
+#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'.
+  char buffer[32];  // CodePointToUtf8 requires a buffer that big.
+  msg << "L'"
+      << (wchar ? CodePointToUtf8(static_cast<UInt32>(wchar), buffer) : "\\0")
+      << "' (" << wchar_as_uint64 << ", 0x" << ::std::setbase(16)
+      << wchar_as_uint64 << ")";
+  return msg.GetString();
+}
+
+}  // namespace internal
+
+// AssertionResult constructors.
+// Used in EXPECT_TRUE/FALSE(assertion_result).
+AssertionResult::AssertionResult(const AssertionResult& other)
+    : success_(other.success_),
+      message_(other.message_.get() != NULL ?
+               new internal::String(*other.message_) :
+               static_cast<internal::String*>(NULL)) {
+}
+
+// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
+AssertionResult AssertionResult::operator!() const {
+  AssertionResult negation(!success_);
+  if (message_.get() != NULL)
+    negation << *message_;
+  return negation;
+}
+
+// Makes a successful assertion result.
+AssertionResult AssertionSuccess() {
+  return AssertionResult(true);
+}
+
+// Makes a failed assertion result.
+AssertionResult AssertionFailure() {
+  return AssertionResult(false);
+}
+
+// Makes a failed assertion result with the given failure message.
+// Deprecated; use AssertionFailure() << message.
+AssertionResult AssertionFailure(const Message& message) {
+  return AssertionFailure() << message;
+}
+
+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);
+}
+
+// Constructs a failure message for Boolean assertions such as EXPECT_TRUE.
+String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result,
+                                      const char* expression_text,
+                                      const char* actual_predicate_value,
+                                      const char* expected_predicate_value) {
+  const char* actual_message = assertion_result.message();
+  Message msg;
+  msg << "Value of: " << expression_text
+      << "\n  Actual: " << actual_predicate_value;
+  if (actual_message[0] != '\0')
+    msg << " (" << actual_message << ")";
+  msg << "\nExpected: " << expected_predicate_value;
+  return msg.GetString();
+}
+
+// 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);
+}
+
+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);
+}
+
+#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 {
+
+#if GTEST_OS_WINDOWS
+
+namespace {
+
+// Helper function for IsHRESULT{SuccessFailure} predicates
+AssertionResult HRESULTFailureHelper(const char* expr,
+                                     const char* expected,
+                                     long hr) {  // NOLINT
+#if GTEST_OS_WINDOWS_MOBILE
+  // 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  // GTEST_OS_WINDOWS_MOBILE
+
+  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 a narrow string in UTF-8 encoding.
+// code_point parameter is of type UInt32 because wchar_t may not be
+// wide enough to contain a code point.
+// The output buffer str must containt at least 32 characters.
+// The function returns the address of the output buffer.
+// If the code_point is not a valid Unicode code point
+// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'.
+char* CodePointToUtf8(UInt32 code_point, char* str) {
+  if (code_point <= kMaxCodePoint1) {
+    str[1] = '\0';
+    str[0] = static_cast<char>(code_point);                          // 0xxxxxxx
+  } else if (code_point <= kMaxCodePoint2) {
+    str[2] = '\0';
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xC0 | code_point);                   // 110xxxxx
+  } else if (code_point <= kMaxCodePoint3) {
+    str[3] = '\0';
+    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xE0 | code_point);                   // 1110xxxx
+  } else if (code_point <= kMaxCodePoint4) {
+    str[4] = '\0';
+    str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6));  // 10xxxxxx
+    str[0] = static_cast<char>(0xF0 | code_point);                   // 11110xxx
+  } else {
+    // The longest string String::Format can produce when invoked
+    // with these parameters is 28 character long (not including
+    // the terminating nul character). We are asking for 32 character
+    // buffer just in case. This is also enough for strncpy to
+    // null-terminate the destination string.
+    posix::StrNCpy(
+        str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32);
+    str[31] = '\0';  // Makes sure no change in the format to strncpy leaves
+                     // the result unterminated.
+  }
+  return str;
+}
+
+// The following two functions only make sense if the the system
+// uses UTF-16 for wide string encoding. All supported systems
+// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16.
+
+// Determines if the arguments constitute UTF-16 surrogate pair
+// and thus should be combined into a single Unicode code point
+// using CreateCodePointFromUtf16SurrogatePair.
+inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) {
+  return sizeof(wchar_t) == 2 &&
+      (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00;
+}
+
+// Creates a Unicode code point from UTF16 surrogate pair.
+inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,
+                                                    wchar_t second) {
+  const UInt32 mask = (1 << 10) - 1;
+  return (sizeof(wchar_t) == 2) ?
+      (((first & mask) << 10) | (second & mask)) + 0x10000 :
+      // This function should not be called when the condition is
+      // false, but we provide a sensible default in case it is.
+      static_cast<UInt32>(first);
+}
+
+// Converts a wide string to a narrow string in UTF-8 encoding.
+// The wide string is assumed to have the following encoding:
+//   UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+//   UTF-32 if sizeof(wchar_t) == 4 (on Linux)
+// Parameter str points to a null-terminated wide string.
+// Parameter num_chars may additionally limit the number
+// of wchar_t characters processed. -1 is used when the entire string
+// should be processed.
+// If the string contains code points that are not valid Unicode code points
+// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output
+// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding
+// and contains invalid UTF-16 surrogate pairs, values in those pairs
+// will be encoded as individual Unicode characters from Basic Normal Plane.
+String WideStringToUtf8(const wchar_t* str, int num_chars) {
+  if (num_chars == -1)
+    num_chars = static_cast<int>(wcslen(str));
+
+  StrStream stream;
+  for (int i = 0; i < num_chars; ++i) {
+    UInt32 unicode_code_point;
+
+    if (str[i] == L'\0') {
+      break;
+    } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) {
+      unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i],
+                                                                 str[i + 1]);
+      i++;
+    } else {
+      unicode_code_point = static_cast<UInt32>(str[i]);
+    }
+
+    char buffer[32];  // CodePointToUtf8 requires a buffer this big.
+    stream << CodePointToUtf8(unicode_code_point, buffer);
+  }
+  return StrStreamToString(&stream);
+}
+
+// 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)");
+
+  return String(internal::WideStringToUtf8(wide_c_str, -1).c_str());
+}
+
+// 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;
+  return posix::StrCaseCmp(lhs, rhs) == 0;
+}
+
+  // Compares two wide C strings, ignoring case.  Returns true iff they
+  // have the same content.
+  //
+  // Unlike wcscasecmp(), this function can handle NULL argument(s).
+  // A NULL C string is considered different to any non-NULL wide C string,
+  // including the empty string.
+  // NB: The implementations on different platforms slightly differ.
+  // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+  // environment variable. On GNU platform this method uses wcscasecmp
+  // which compares according to LC_CTYPE category of the current locale.
+  // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+  // current locale.
+bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
+                                              const wchar_t* rhs) {
+  if ( lhs == NULL ) return rhs == NULL;
+
+  if ( rhs == NULL ) return false;
+
+#if GTEST_OS_WINDOWS
+  return _wcsicmp(lhs, rhs) == 0;
+#elif GTEST_OS_LINUX
+  return wcscasecmp(lhs, rhs) == 0;
+#else
+  // Mac OS X and Cygwin don't define wcscasecmp.  Other unknown OSes
+  // may not define it either.
+  wint_t left, right;
+  do {
+    left = towlower(*lhs++);
+    right = towlower(*rhs++);
+  } while (left && left == right);
+  return left == right;
+#endif  // OS selector
+}
+
+// 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 {
+  const char* const lhs_c_str = c_str();
+  const char* const rhs_c_str = rhs.c_str();
+
+  if (lhs_c_str == NULL) {
+    return rhs_c_str == NULL ? 0 : -1;  // NULL < anything except NULL
+  } else if (rhs_c_str == NULL) {
+    return 1;
+  }
+
+  const size_t shorter_str_len =
+      length() <= rhs.length() ? length() : rhs.length();
+  for (size_t i = 0; i != shorter_str_len; i++) {
+    if (lhs_c_str[i] < rhs_c_str[i]) {
+      return -1;
+    } else if (lhs_c_str[i] > rhs_c_str[i]) {
+      return 1;
+    }
+  }
+  return (length() < rhs.length()) ? -1 :
+      (length() > rhs.length()) ? 1 : 0;
+}
+
+// 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);
+}
+
+// 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, or if
+// there's an error, "<formatting error or buffer exceeded>" is
+// returned.
+String String::Format(const char * format, ...) {
+  va_list args;
+  va_start(args, format);
+
+  char buffer[4096];
+  const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]);
+
+  // MSVC 8 deprecates vsnprintf(), so we want to suppress warning
+  // 4996 (deprecated function) there.
+#ifdef _MSC_VER  // We are using MSVC.
+#pragma warning(push)          // Saves the current warning state.
+#pragma warning(disable:4996)  // Temporarily disables warning 4996.
+  const int size = vsnprintf(buffer, kBufferSize, format, args);
+#pragma warning(pop)           // Restores the warning state.
+#else  // We are not using MSVC.
+  const int size = vsnprintf(buffer, kBufferSize, format, args);
+#endif  // _MSC_VER
+  va_end(args);
+
+  // vsnprintf()'s behavior is not portable.  When the buffer is not
+  // big enough, it returns a negative value in MSVC, and returns the
+  // needed buffer size on Linux.  When there is an output error, it
+  // always returns a negative value.  For simplicity, we lump the two
+  // error cases together.
+  if (size < 0 || size >= kBufferSize) {
+    return String("<formatting error or buffer exceeded>");
+  } else {
+    return String(buffer, size);
+  }
+}
+
+// Converts the buffer in a StrStream to a String, converting NUL
+// bytes to "\\0" along the way.
+String StrStreamToString(StrStream* ss) {
+  const ::std::string& str = ss->str();
+  const char* const start = str.c_str();
+  const char* const end = start + str.length();
+
+  // 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);
+    }
+  }
+
+  return String(helper.str().c_str());
+}
+
+// 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
+
+// class TestResult
+
+// Creates an empty TestResult.
+TestResult::TestResult()
+    : death_test_count_(0),
+      elapsed_time_(0) {
+}
+
+// D'tor.
+TestResult::~TestResult() {
+}
+
+// Returns the i-th test part result among all the results. i can
+// range from 0 to total_part_count() - 1. If i is not in that range,
+// aborts the program.
+const TestPartResult& TestResult::GetTestPartResult(int i) const {
+  if (i < 0 || i >= total_part_count())
+    internal::posix::Abort();
+  return test_part_results_.at(i);
+}
+
+// Returns the i-th test property. i can range from 0 to
+// test_property_count() - 1. If i is not in that range, aborts the
+// program.
+const TestProperty& TestResult::GetTestProperty(int i) const {
+  if (i < 0 || i >= test_property_count())
+    internal::posix::Abort();
+  return test_properties_.at(i);
+}
+
+// Clears the test part results.
+void TestResult::ClearTestPartResults() {
+  test_part_results_.clear();
+}
+
+// Adds a test part result to the list.
+void TestResult::AddTestPartResult(const TestPartResult& test_part_result) {
+  test_part_results_.push_back(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;
+  }
+  internal::MutexLock lock(&test_properites_mutex_);
+  const std::vector<TestProperty>::iterator property_with_matching_key =
+      std::find_if(test_properties_.begin(), test_properties_.end(),
+                   internal::TestPropertyKeyIs(test_property.key()));
+  if (property_with_matching_key == test_properties_.end()) {
+    test_properties_.push_back(test_property);
+    return;
+  }
+  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) {
+  internal::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 failed.
+bool TestResult::Failed() const {
+  for (int i = 0; i < total_part_count(); ++i) {
+    if (GetTestPartResult(i).failed())
+      return true;
+  }
+  return false;
+}
+
+// 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 CountIf(test_part_results_, TestPartFatallyFailed) > 0;
+}
+
+// Returns true iff the test part non-fatally failed.
+static bool TestPartNonfatallyFailed(const TestPartResult& result) {
+  return result.nonfatally_failed();
+}
+
+// Returns true iff the test has a non-fatal failure.
+bool TestResult::HasNonfatalFailure() const {
+  return CountIf(test_part_results_, TestPartNonfatallyFailed) > 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 static_cast<int>(test_part_results_.size());
+}
+
+// Returns the number of the test properties.
+int TestResult::test_property_count() const {
+  return static_cast<int>(test_properties_.size());
+}
+
+// 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());
+}
+
+namespace internal {
+
+void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
+                                    const String& message) {
+  // This function is a friend of UnitTest and as such has access to
+  // AddTestPartResult.
+  UnitTest::GetInstance()->AddTestPartResult(
+      result_type,
+      NULL,  // No info about the source file where the exception occurred.
+      -1,    // We have no info on which line caused the exception.
+      message,
+      String());  // No stack trace, either.
+}
+
+}  // namespace internal
+
+#if 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 << ".";
+
+  internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure,
+                                           message.GetString());
+}
+
+#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()[0]->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::GetTestTypeId();
+    // Is this test defined using TEST?
+    const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();
+
+    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();
+#if GTEST_HAS_SEH
+  // Catch SEH-style exceptions.
+  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 a compiler or platform that doesn't support SEH.
+  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_HAS_SEH
+}
+
+
+// Returns true iff the current test has a fatal failure.
+bool Test::HasFatalFailure() {
+  return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();
+}
+
+// Returns true iff the current test has a non-fatal failure.
+bool Test::HasNonfatalFailure() {
+  return internal::GetUnitTestImpl()->current_test_result()->
+      HasNonfatalFailure();
+}
+
+// class TestInfo
+
+// Constructs a TestInfo object. It assumes ownership of the test factory
+// object via impl_.
+TestInfo::TestInfo(const char* a_test_case_name,
+                   const char* a_name,
+                   const char* a_test_case_comment,
+                   const char* a_comment,
+                   internal::TypeId fixture_class_id,
+                   internal::TestFactoryBase* factory) {
+  impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name,
+                                     a_test_case_comment, a_comment,
+                                     fixture_class_id, factory);
+}
+
+// Destructs a TestInfo object.
+TestInfo::~TestInfo() {
+  delete impl_;
+}
+
+namespace internal {
+
+// Creates a new TestInfo object and registers it with Google Test;
+// returns the created object.
+//
+// Arguments:
+//
+//   test_case_name:   name of the test case
+//   name:             name of the test
+//   test_case_comment: a comment on the test case that will be included in
+//                      the test output
+//   comment:          a comment on the test that will be included in the
+//                     test output
+//   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
+//   factory:          pointer to the factory that creates a test object.
+//                     The newly created TestInfo instance will assume
+//                     ownership of the factory object.
+TestInfo* MakeAndRegisterTestInfo(
+    const char* test_case_name, const char* name,
+    const char* test_case_comment, const char* comment,
+    TypeId fixture_class_id,
+    SetUpTestCaseFunc set_up_tc,
+    TearDownTestCaseFunc tear_down_tc,
+    TestFactoryBase* factory) {
+  TestInfo* const test_info =
+      new TestInfo(test_case_name, name, test_case_comment, comment,
+                   fixture_class_id, factory);
+  GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
+  return test_info;
+}
+
+#if GTEST_HAS_PARAM_TEST
+void ReportInvalidTestCaseType(const char* test_case_name,
+                               const char* file, int line) {
+  Message errors;
+  errors
+      << "Attempted redefinition of test case " << test_case_name << ".\n"
+      << "All tests in the same test case must use the same test fixture\n"
+      << "class.  However, in test case " << test_case_name << ", you tried\n"
+      << "to define a test using a fixture class different from the one\n"
+      << "used earlier. This can happen if the two fixture classes are\n"
+      << "from different namespaces and have the same name. You should\n"
+      << "probably rename one of the classes to put the tests into different\n"
+      << "test cases.";
+
+  fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
+          errors.GetString().c_str());
+}
+#endif  // GTEST_HAS_PARAM_TEST
+
+}  // namespace internal
+
+// 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 the test case comment.
+const char* TestInfo::test_case_comment() const {
+  return impl_->test_case_comment();
+}
+
+// Returns the test comment.
+const char* TestInfo::comment() const {
+  return impl_->comment();
+}
+
+// Returns true if this test should run.
+bool TestInfo::should_run() const { return impl_->should_run(); }
+
+// Returns true if this test matches the user-specified filter.
+bool TestInfo::matches_filter() const { return impl_->matches_filter(); }
+
+// Returns the result of the test.
+const 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
+
+namespace internal {
+
+// This method expands all parameterized tests registered with macros TEST_P
+// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.
+// This will be done just once during the program runtime.
+void UnitTestImpl::RegisterParameterizedTests() {
+#if GTEST_HAS_PARAM_TEST
+  if (!parameterized_tests_registered_) {
+    parameterized_test_registry_.RegisterTests();
+    parameterized_tests_registered_ = true;
+  }
+#endif
+}
+
+// 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_);
+
+  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+  // Notifies the unit test event listeners that a test is about to start.
+  repeater->OnTestStart(*parent_);
+
+  const TimeInMillis start = GetTimeInMillis();
+
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+#if GTEST_HAS_SEH
+  // Catch SEH-style exceptions.
+  Test* test = NULL;
+
+  __try {
+    // Creates the test object.
+    test = factory_->CreateTest();
+  } __except(internal::UnitTestOptions::GTestShouldProcessSEH(
+      GetExceptionCode())) {
+    AddExceptionThrownFailure(GetExceptionCode(),
+                              "the test fixture's constructor");
+    return;
+  }
+#else  // We are on a compiler or platform that doesn't support SEH.
+
+  // 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 = factory_->CreateTest();
+#endif  // GTEST_HAS_SEH
+
+  // 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.
+  repeater->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 CountIf(test_info_list_, TestPassed);
+}
+
+// Gets the number of failed tests in this test case.
+int TestCase::failed_test_count() const {
+  return CountIf(test_info_list_, TestFailed);
+}
+
+int TestCase::disabled_test_count() const {
+  return CountIf(test_info_list_, TestDisabled);
+}
+
+// Get the number of tests in this test case that should run.
+int TestCase::test_to_run_count() const {
+  return CountIf(test_info_list_, ShouldRunTest);
+}
+
+// Gets the number of all tests.
+int TestCase::total_test_count() const {
+  return static_cast<int>(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* a_name, const char* a_comment,
+                   Test::SetUpTestCaseFunc set_up_tc,
+                   Test::TearDownTestCaseFunc tear_down_tc)
+    : name_(a_name),
+      comment_(a_comment),
+      set_up_tc_(set_up_tc),
+      tear_down_tc_(tear_down_tc),
+      should_run_(false),
+      elapsed_time_(0) {
+}
+
+// Destructor of TestCase.
+TestCase::~TestCase() {
+  // Deletes every Test in the collection.
+  ForEach(test_info_list_, internal::Delete<TestInfo>);
+}
+
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+const TestInfo* TestCase::GetTestInfo(int i) const {
+  const int index = GetElementOr(test_indices_, i, -1);
+  return index < 0 ? NULL : test_info_list_[index];
+}
+
+// Returns the i-th test among all the tests. i can range from 0 to
+// total_test_count() - 1. If i is not in that range, returns NULL.
+TestInfo* TestCase::GetMutableTestInfo(int i) {
+  const int index = GetElementOr(test_indices_, i, -1);
+  return index < 0 ? NULL : test_info_list_[index];
+}
+
+// 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_.push_back(test_info);
+  test_indices_.push_back(static_cast<int>(test_indices_.size()));
+}
+
+// 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);
+
+  TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+
+  repeater->OnTestCaseStart(*this);
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  set_up_tc_();
+
+  const internal::TimeInMillis start = internal::GetTimeInMillis();
+  for (int i = 0; i < total_test_count(); i++) {
+    GetMutableTestInfo(i)->impl()->Run();
+  }
+  elapsed_time_ = internal::GetTimeInMillis() - start;
+
+  impl->os_stack_trace_getter()->UponLeavingGTest();
+  tear_down_tc_();
+  repeater->OnTestCaseEnd(*this);
+  impl->set_current_test_case(NULL);
+}
+
+// Clears the results of all tests in this test case.
+void TestCase::ClearResult() {
+  ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult);
+}
+
+// Returns true iff test passed.
+bool TestCase::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.
+bool TestCase::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.
+bool TestCase::TestDisabled(const TestInfo * test_info) {
+  return test_info->impl()->is_disabled();
+}
+
+// Returns true if the given test should run.
+bool TestCase::ShouldRunTest(const TestInfo *test_info) {
+  return test_info->impl()->should_run();
+}
+
+// Shuffles the tests in this test case.
+void TestCase::ShuffleTests(internal::Random* random) {
+  Shuffle(random, &test_indices_);
+}
+
+// Restores the test order to before the first shuffle.
+void TestCase::UnshuffleTests() {
+  for (size_t i = 0; i < test_indices_.size(); i++) {
+    test_indices_[i] = static_cast<int>(i);
+  }
+}
+
+// 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 TestPartResult::Type enum to human-friendly string
+// representation.  Both kNonFatalFailure and kFatalFailure 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(TestPartResult::Type type) {
+  switch (type) {
+    case TestPartResult::kSuccess:
+      return "Success";
+
+    case TestPartResult::kNonFatalFailure:
+    case TestPartResult::kFatalFailure:
+#ifdef _MSC_VER
+      return "error: ";
+#else
+      return "Failure\n";
+#endif
+  }
+
+  return "Unknown result type";
+}
+
+// Prints a TestPartResult to a String.
+static internal::String PrintTestPartResultToString(
+    const TestPartResult& test_part_result) {
+  return (Message()
+          << internal::FormatFileLocation(test_part_result.file_name(),
+                                          test_part_result.line_number())
+          << " " << TestPartResultTypeToString(test_part_result.type())
+          << test_part_result.message()).GetString();
+}
+
+// Prints a TestPartResult.
+static void PrintTestPartResult(const TestPartResult& test_part_result) {
+  const internal::String& result =
+      PrintTestPartResultToString(test_part_result);
+  printf("%s\n", result.c_str());
+  fflush(stdout);
+  // If the test program runs in Visual Studio or a debugger, the
+  // following statements add the test part result message to the Output
+  // window such that the user can double-click on it to jump to the
+  // corresponding source code location; otherwise they do nothing.
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  // We don't call OutputDebugString*() on Windows Mobile, as printing
+  // to stdout is done by OutputDebugString() there already - we don't
+  // want the same message printed twice.
+  ::OutputDebugStringA(result.c_str());
+  ::OutputDebugStringA("\n");
+#endif
+}
+
+// class PrettyUnitTestResultPrinter
+
+namespace internal {
+
+enum GTestColor {
+  COLOR_DEFAULT,
+  COLOR_RED,
+  COLOR_GREEN,
+  COLOR_YELLOW
+};
+
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+
+// 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;
+    default:           return 0;
+  }
+}
+
+#else
+
+// Returns the ANSI color code for the given color.  COLOR_DEFAULT is
+// an invalid input.
+const char* GetAnsiColorCode(GTestColor color) {
+  switch (color) {
+    case COLOR_RED:     return "1";
+    case COLOR_GREEN:   return "2";
+    case COLOR_YELLOW:  return "3";
+    default:            return NULL;
+  };
+}
+
+#endif  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+
+// 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")) {
+#if GTEST_OS_WINDOWS
+    // 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 = posix::GetEnv("TERM");
+    const bool term_supports_color =
+        String::CStringEquals(term, "xterm") ||
+        String::CStringEquals(term, "xterm-color") ||
+        String::CStringEquals(term, "xterm-256color") ||
+        String::CStringEquals(term, "linux") ||
+        String::CStringEquals(term, "cygwin");
+    return stdout_is_tty && term_supports_color;
+#endif  // GTEST_OS_WINDOWS
+  }
+
+  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);
+
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+  const bool use_color = false;
+#else
+  static const bool in_color_mode =
+      ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
+  const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
+#endif  // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
+  // The '!= 0' comparison is necessary to satisfy MSVC 7.1.
+
+  if (!use_color) {
+    vprintf(fmt, args);
+    va_end(args);
+    return;
+  }
+
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  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;
+
+  // We need to flush the stream buffers into the console before each
+  // SetConsoleTextAttribute call lest it affect the text that is already
+  // printed but has not yet reached the console.
+  fflush(stdout);
+  SetConsoleTextAttribute(stdout_handle,
+                          GetColorAttribute(color) | FOREGROUND_INTENSITY);
+  vprintf(fmt, args);
+
+  fflush(stdout);
+  // 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  // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
+  va_end(args);
+}
+
+// This class implements the TestEventListener interface.
+//
+// Class PrettyUnitTestResultPrinter is copyable.
+class PrettyUnitTestResultPrinter : public TestEventListener {
+ 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 TestEventListener class.
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestCaseStart(const TestCase& test_case);
+  virtual void OnTestStart(const TestInfo& test_info);
+  virtual void OnTestPartResult(const TestPartResult& result);
+  virtual void OnTestEnd(const TestInfo& test_info);
+  virtual void OnTestCaseEnd(const TestCase& test_case);
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+
+ private:
+  static void PrintFailedTests(const UnitTest& unit_test);
+
+  internal::String test_case_name_;
+};
+
+  // Fired before each iteration of tests starts.
+void PrettyUnitTestResultPrinter::OnTestIterationStart(
+    const UnitTest& unit_test, int iteration) {
+  if (GTEST_FLAG(repeat) != 1)
+    printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1);
+
+  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);
+  }
+
+  if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: This is test shard %s of %s.\n",
+                  internal::posix::GetEnv(kTestShardIndex),
+                  internal::posix::GetEnv(kTestTotalShards));
+  }
+
+  if (GTEST_FLAG(shuffle)) {
+    ColoredPrintf(COLOR_YELLOW,
+                  "Note: Randomizing tests' orders with a seed of %d .\n",
+                  unit_test.random_seed());
+  }
+
+  ColoredPrintf(COLOR_GREEN,  "[==========] ");
+  printf("Running %s from %s.\n",
+         FormatTestCount(unit_test.test_to_run_count()).c_str(),
+         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
+    const UnitTest& /*unit_test*/) {
+  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", counts.c_str(), test_case_name_.c_str());
+  if (test_case.comment()[0] == '\0') {
+    printf("\n");
+  } else {
+    printf(", where %s\n", test_case.comment());
+  }
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
+  ColoredPrintf(COLOR_GREEN,  "[ RUN      ] ");
+  PrintTestName(test_case_name_.c_str(), test_info.name());
+  if (test_info.comment()[0] == '\0') {
+    printf("\n");
+  } else {
+    printf(", where %s\n", test_info.comment());
+  }
+  fflush(stdout);
+}
+
+// Called after an assertion failure.
+void PrettyUnitTestResultPrinter::OnTestPartResult(
+    const TestPartResult& result) {
+  // If the test part succeeded, we don't need to do anything.
+  if (result.type() == TestPartResult::kSuccess)
+    return;
+
+  // Print failure message from the assertion (e.g. expected this and got that).
+  PrintTestPartResult(result);
+  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());
+  if (GTEST_FLAG(print_time)) {
+    printf(" (%s ms)\n", internal::StreamableToString(
+           test_info.result()->elapsed_time()).c_str());
+  } else {
+    printf("\n");
+  }
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
+  if (!GTEST_FLAG(print_time)) return;
+
+  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 (%s ms total)\n\n",
+         counts.c_str(), test_case_name_.c_str(),
+         internal::StreamableToString(test_case.elapsed_time()).c_str());
+  fflush(stdout);
+}
+
+void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
+    const UnitTest& /*unit_test*/) {
+  ColoredPrintf(COLOR_GREEN,  "[----------] ");
+  printf("Global test environment tear-down\n");
+  fflush(stdout);
+}
+
+// Internal helper for printing the list of failed tests.
+void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {
+  const int failed_test_count = unit_test.failed_test_count();
+  if (failed_test_count == 0) {
+    return;
+  }
+
+  for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
+    const TestCase& test_case = *unit_test.GetTestCase(i);
+    if (!test_case.should_run() || (test_case.failed_test_count() == 0)) {
+      continue;
+    }
+    for (int j = 0; j < test_case.total_test_count(); ++j) {
+      const TestInfo& test_info = *test_case.GetTestInfo(j);
+      if (!test_info.should_run() || test_info.result()->Passed()) {
+        continue;
+      }
+      ColoredPrintf(COLOR_RED, "[  FAILED  ] ");
+      printf("%s.%s", test_case.name(), test_info.name());
+      if (test_case.comment()[0] != '\0' ||
+          test_info.comment()[0] != '\0') {
+        printf(", where %s", test_case.comment());
+        if (test_case.comment()[0] != '\0' &&
+            test_info.comment()[0] != '\0') {
+          printf(" and ");
+        }
+      }
+      printf("%s\n", test_info.comment());
+    }
+  }
+}
+
+ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+                                                      int /*iteration*/) {
+  ColoredPrintf(COLOR_GREEN,  "[==========] ");
+  printf("%s from %s ran.",
+         FormatTestCount(unit_test.test_to_run_count()).c_str(),
+         FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+  if (GTEST_FLAG(print_time)) {
+    printf(" (%s ms total)",
+           internal::StreamableToString(unit_test.elapsed_time()).c_str());
+  }
+  printf("\n");
+  ColoredPrintf(COLOR_GREEN,  "[  PASSED  ] ");
+  printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
+
+  int num_failures = unit_test.failed_test_count();
+  if (!unit_test.Passed()) {
+    const int failed_test_count = unit_test.failed_test_count();
+    ColoredPrintf(COLOR_RED,  "[  FAILED  ] ");
+    printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str());
+    PrintFailedTests(unit_test);
+    printf("\n%2d FAILED %s\n", num_failures,
+                        num_failures == 1 ? "TEST" : "TESTS");
+  }
+
+  int num_disabled = unit_test.disabled_test_count();
+  if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) {
+    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 TestEventRepeater
+//
+// This class forwards events to other event listeners.
+class TestEventRepeater : public TestEventListener {
+ public:
+  TestEventRepeater() : forwarding_enabled_(true) {}
+  virtual ~TestEventRepeater();
+  void Append(TestEventListener *listener);
+  TestEventListener* Release(TestEventListener* listener);
+
+  // Controls whether events will be forwarded to listeners_. Set to false
+  // in death test child processes.
+  bool forwarding_enabled() const { return forwarding_enabled_; }
+  void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
+
+  virtual void OnTestProgramStart(const UnitTest& unit_test);
+  virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);
+  virtual void OnTestCaseStart(const TestCase& test_case);
+  virtual void OnTestStart(const TestInfo& test_info);
+  virtual void OnTestPartResult(const TestPartResult& result);
+  virtual void OnTestEnd(const TestInfo& test_info);
+  virtual void OnTestCaseEnd(const TestCase& test_case);
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+  virtual void OnTestProgramEnd(const UnitTest& unit_test);
+
+ private:
+  // Controls whether events will be forwarded to listeners_. Set to false
+  // in death test child processes.
+  bool forwarding_enabled_;
+  // The list of listeners that receive events.
+  std::vector<TestEventListener*> listeners_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater);
+};
+
+TestEventRepeater::~TestEventRepeater() {
+  ForEach(listeners_, Delete<TestEventListener>);
+}
+
+void TestEventRepeater::Append(TestEventListener *listener) {
+  listeners_.push_back(listener);
+}
+
+// TODO(vladl@google.com): Factor the search functionality into Vector::Find.
+TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
+  for (size_t i = 0; i < listeners_.size(); ++i) {
+    if (listeners_[i] == listener) {
+      listeners_.erase(listeners_.begin() + i);
+      return listener;
+    }
+  }
+
+  return NULL;
+}
+
+// Since most methods are very similar, use macros to reduce boilerplate.
+// This defines a member that forwards the call to all listeners.
+#define GTEST_REPEATER_METHOD_(Name, Type) \
+void TestEventRepeater::Name(const Type& parameter) { \
+  if (forwarding_enabled_) { \
+    for (size_t i = 0; i < listeners_.size(); i++) { \
+      listeners_[i]->Name(parameter); \
+    } \
+  } \
+}
+// This defines a member that forwards the call to all listeners in reverse
+// order.
+#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \
+void TestEventRepeater::Name(const Type& parameter) { \
+  if (forwarding_enabled_) { \
+    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \
+      listeners_[i]->Name(parameter); \
+    } \
+  } \
+}
+
+GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)
+GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)
+GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase)
+GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
+GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
+GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase)
+GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
+
+#undef GTEST_REPEATER_METHOD_
+#undef GTEST_REVERSE_REPEATER_METHOD_
+
+void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test,
+                                             int iteration) {
+  if (forwarding_enabled_) {
+    for (size_t i = 0; i < listeners_.size(); i++) {
+      listeners_[i]->OnTestIterationStart(unit_test, iteration);
+    }
+  }
+}
+
+void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
+                                           int iteration) {
+  if (forwarding_enabled_) {
+    for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {
+      listeners_[i]->OnTestIterationEnd(unit_test, iteration);
+    }
+  }
+}
+
+// End TestEventRepeater
+
+// This class generates an XML output file.
+class XmlUnitTestResultPrinter : public EmptyTestEventListener {
+ public:
+  explicit XmlUnitTestResultPrinter(const char* output_file);
+
+  virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+
+ 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 String EscapeXml(const char* str, bool is_attribute);
+
+  // Returns the given string with all characters invalid in XML removed.
+  static String RemoveInvalidXmlCharacters(const char* str);
+
+  // Convenience wrapper around EscapeXml when str is an attribute value.
+  static String EscapeXmlAttribute(const char* str) {
+    return EscapeXml(str, true);
+  }
+
+  // Convenience wrapper around EscapeXml when str is not an attribute value.
+  static String EscapeXmlText(const char* str) { return EscapeXml(str, false); }
+
+  // Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+  static void OutputXmlCDataSection(::std::ostream* stream, const char* data);
+
+  // Streams an XML representation of a TestInfo object.
+  static void OutputXmlTestInfo(::std::ostream* stream,
+                                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 String TestPropertiesAsXmlAttributes(const TestResult& result);
+
+  // The output file.
+  const 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::OnTestIterationEnd(const UnitTest& unit_test,
+                                                  int /*iteration*/) {
+  FILE* xmlout = NULL;
+  FilePath output_file(output_file_);
+  FilePath output_dir(output_file.RemoveFileName());
+
+  if (output_dir.CreateDirectoriesRecursively()) {
+    xmlout = posix::FOpen(output_file_.c_str(), "w");
+  }
+  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.
+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 << String::Format("&#x%02X;", unsigned(*src));
+            else
+              m << *src;
+          }
+          break;
+      }
+    }
+  }
+
+  return m.GetString();
+}
+
+// Returns the given string with all characters invalid in XML removed.
+// Currently invalid characters are dropped from the string. An
+// alternative is to replace them with certain characters such as . or ?.
+String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) {
+  char* const output = new char[strlen(str) + 1];
+  char* appender = output;
+  for (char ch = *str; ch != '\0'; ch = *++str)
+    if (IsValidXmlCharacter(ch))
+      *appender++ = ch;
+  *appender = '\0';
+
+  String ret_value(output);
+  delete[] output;
+  return ret_value;
+}
+
+// The following routines generate an XML representation of a UnitTest
+// object.
+//
+// This is how Google Test concepts map to the DTD:
+//
+// <testsuites 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>
+//       <failure message="...">...</failure>
+//       <failure message="...">...</failure>
+//                                     <-- individual assertion failures
+//     </testcase>
+//   </testsuite>
+// </testsuites>
+
+// Formats the given time in milliseconds as seconds.
+std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) {
+  ::std::stringstream ss;
+  ss << ms/1000.0;
+  return ss.str();
+}
+
+// Streams an XML CDATA section, escaping invalid CDATA sequences as needed.
+void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream,
+                                                     const char* data) {
+  const char* segment = data;
+  *stream << "<![CDATA[";
+  for (;;) {
+    const char* const next_segment = strstr(segment, "]]>");
+    if (next_segment != NULL) {
+      stream->write(
+          segment, static_cast<std::streamsize>(next_segment - segment));
+      *stream << "]]>]]&gt;<![CDATA[";
+      segment = next_segment + strlen("]]>");
+    } else {
+      *stream << segment;
+      break;
+    }
+  }
+  *stream << "]]>";
+}
+
+// Prints an XML representation of a TestInfo object.
+// TODO(wan): There is also value in printing properties with the plain printer.
+void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
+                                                 const char* test_case_name,
+                                                 const TestInfo& test_info) {
+  const TestResult& result = *test_info.result();
+  *stream << "    <testcase name=\""
+          << EscapeXmlAttribute(test_info.name()).c_str()
+          << "\" status=\""
+          << (test_info.should_run() ? "run" : "notrun")
+          << "\" time=\""
+          << FormatTimeInMillisAsSeconds(result.elapsed_time())
+          << "\" classname=\"" << EscapeXmlAttribute(test_case_name).c_str()
+          << "\"" << TestPropertiesAsXmlAttributes(result).c_str();
+
+  int failures = 0;
+  for (int i = 0; i < result.total_part_count(); ++i) {
+    const TestPartResult& part = result.GetTestPartResult(i);
+    if (part.failed()) {
+      if (++failures == 1)
+        *stream << ">\n";
+      *stream << "      <failure message=\""
+              << EscapeXmlAttribute(part.summary()).c_str()
+              << "\" type=\"\">";
+      const String message = RemoveInvalidXmlCharacters(String::Format(
+          "%s:%d\n%s",
+          part.file_name(), part.line_number(),
+          part.message()).c_str());
+      OutputXmlCDataSection(stream, message.c_str());
+      *stream << "</failure>\n";
+    }
+  }
+
+  if (failures == 0)
+    *stream << " />\n";
+  else
+    *stream << "    </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",
+          FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str());
+  for (int i = 0; i < test_case.total_test_count(); ++i) {
+    StrStream stream;
+    OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i));
+    fprintf(out, "%s", StrStreamToString(&stream).c_str());
+  }
+  fprintf(out, "  </testsuite>\n");
+}
+
+// Prints an XML summary of unit_test to output stream out.
+void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out,
+                                                const UnitTest& unit_test) {
+  fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+  fprintf(out,
+          "<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" "
+          "errors=\"0\" time=\"%s\" ",
+          unit_test.total_test_count(),
+          unit_test.failed_test_count(),
+          unit_test.disabled_test_count(),
+          FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str());
+  if (GTEST_FLAG(shuffle)) {
+    fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed());
+  }
+  fprintf(out, "name=\"AllTests\">\n");
+  for (int i = 0; i < unit_test.total_test_case_count(); ++i)
+    PrintXmlTestCase(out, *unit_test.GetTestCase(i));
+  fprintf(out, "</testsuites>\n");
+}
+
+// Produces a string representing the test properties in a result as space
+// delimited XML attributes based on the property key="value" pairs.
+String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
+    const TestResult& result) {
+  Message attributes;
+  for (int i = 0; i < result.test_property_count(); ++i) {
+    const TestProperty& property = result.GetTestProperty(i);
+    attributes << " " << property.key() << "="
+        << "\"" << EscapeXmlAttribute(property.value()) << "\"";
+  }
+  return attributes.GetString();
+}
+
+// End XmlUnitTestResultPrinter
+
+// 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 TestEventListeners
+
+TestEventListeners::TestEventListeners()
+    : repeater_(new internal::TestEventRepeater()),
+      default_result_printer_(NULL),
+      default_xml_generator_(NULL) {
+}
+
+TestEventListeners::~TestEventListeners() { delete repeater_; }
+
+// Returns the standard listener responsible for the default console
+// output.  Can be removed from the listeners list to shut down default
+// console output.  Note that removing this object from the listener list
+// with Release transfers its ownership to the user.
+void TestEventListeners::Append(TestEventListener* listener) {
+  repeater_->Append(listener);
+}
+
+// Removes the given event listener from the list and returns it.  It then
+// becomes the caller's responsibility to delete the listener. Returns
+// NULL if the listener is not found in the list.
+TestEventListener* TestEventListeners::Release(TestEventListener* listener) {
+  if (listener == default_result_printer_)
+    default_result_printer_ = NULL;
+  else if (listener == default_xml_generator_)
+    default_xml_generator_ = NULL;
+  return repeater_->Release(listener);
+}
+
+// Returns repeater that broadcasts the TestEventListener events to all
+// subscribers.
+TestEventListener* TestEventListeners::repeater() { return repeater_; }
+
+// Sets the default_result_printer attribute to the provided listener.
+// The listener is also added to the listener list and previous
+// default_result_printer is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
+  if (default_result_printer_ != listener) {
+    // It is an error to pass this method a listener that is already in the
+    // list.
+    delete Release(default_result_printer_);
+    default_result_printer_ = listener;
+    if (listener != NULL)
+      Append(listener);
+  }
+}
+
+// Sets the default_xml_generator attribute to the provided listener.  The
+// listener is also added to the listener list and previous
+// default_xml_generator is removed from it and deleted. The listener can
+// also be NULL in which case it will not be added to the list. Does
+// nothing if the previous and the current listener objects are the same.
+void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) {
+  if (default_xml_generator_ != listener) {
+    // It is an error to pass this method a listener that is already in the
+    // list.
+    delete Release(default_xml_generator_);
+    default_xml_generator_ = listener;
+    if (listener != NULL)
+      Append(listener);
+  }
+}
+
+// Controls whether events will be forwarded by the repeater to the
+// listeners in the list.
+bool TestEventListeners::EventForwardingEnabled() const {
+  return repeater_->forwarding_enabled();
+}
+
+void TestEventListeners::SuppressEventForwarding() {
+  repeater_->set_forwarding_enabled(false);
+}
+
+// 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.
+
+  // CodeGear C++Builder insists on a public destructor for the
+  // default implementation.  Use this implementation to keep good OO
+  // design with private destructor.
+
+#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+  static UnitTest* const instance = new UnitTest;
+  return instance;
+#else
+  static UnitTest instance;
+  return &instance;
+#endif  // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+}
+
+// Gets the number of successful test cases.
+int UnitTest::successful_test_case_count() const {
+  return impl()->successful_test_case_count();
+}
+
+// Gets the number of failed test cases.
+int UnitTest::failed_test_case_count() const {
+  return impl()->failed_test_case_count();
+}
+
+// Gets the number of all test cases.
+int UnitTest::total_test_case_count() const {
+  return impl()->total_test_case_count();
+}
+
+// Gets the number of all test cases that contain at least one test
+// that should run.
+int UnitTest::test_case_to_run_count() const {
+  return impl()->test_case_to_run_count();
+}
+
+// Gets the number of successful tests.
+int UnitTest::successful_test_count() const {
+  return impl()->successful_test_count();
+}
+
+// Gets the number of failed tests.
+int UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
+
+// Gets the number of disabled tests.
+int UnitTest::disabled_test_count() const {
+  return impl()->disabled_test_count();
+}
+
+// Gets the number of all tests.
+int UnitTest::total_test_count() const { return impl()->total_test_count(); }
+
+// Gets the number of tests that should run.
+int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); }
+
+// Gets the elapsed time, in milliseconds.
+internal::TimeInMillis UnitTest::elapsed_time() const {
+  return impl()->elapsed_time();
+}
+
+// Returns true iff the unit test passed (i.e. all test cases passed).
+bool UnitTest::Passed() const { return impl()->Passed(); }
+
+// Returns true iff the unit test failed (i.e. some test case failed
+// or something outside of all tests failed).
+bool UnitTest::Failed() const { return impl()->Failed(); }
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+const TestCase* UnitTest::GetTestCase(int i) const {
+  return impl()->GetTestCase(i);
+}
+
+// Gets the i-th test case among all the test cases. i can range from 0 to
+// total_test_case_count() - 1. If i is not in that range, returns NULL.
+TestCase* UnitTest::GetMutableTestCase(int i) {
+  return impl()->GetMutableTestCase(i);
+}
+
+// Returns the list of event listeners that can be used to track events
+// inside Google Test.
+TestEventListeners& UnitTest::listeners() {
+  return *impl()->listeners();
+}
+
+// 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().push_back(env);
+  return env;
+}
+
+#if GTEST_HAS_EXCEPTIONS
+// A failed Google Test assertion will throw an exception of this type
+// when exceptions are enabled.  We derive it from std::runtime_error,
+// which is for errors presumably detectable only at run time.  Since
+// std::runtime_error inherits from std::exception, many testing
+// frameworks know how to extract and print the message inside it.
+class GoogleTestFailureException : public ::std::runtime_error {
+ public:
+  explicit GoogleTestFailureException(const TestPartResult& failure)
+      : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {}
+};
+#endif
+
+// 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(TestPartResult::Type 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 (int i = static_cast<int>(impl_->gtest_trace_stack().size());
+         i > 0; --i) {
+      const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
+      msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
+          << " " << trace.message;
+    }
+  }
+
+  if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {
+    msg << internal::kStackTraceMarker << os_stack_trace;
+  }
+
+  const TestPartResult result =
+    TestPartResult(result_type, file_name, line_number,
+                   msg.GetString().c_str());
+  impl_->GetTestPartResultReporterForCurrentThread()->
+      ReportTestPartResult(result);
+
+  if (result_type != TestPartResult::kSuccess) {
+    // gtest_break_on_failure takes precedence over
+    // gtest_throw_on_failure.  This allows a user to set the latter
+    // in the code (perhaps in order to use Google Test assertions
+    // with another testing framework) and specify the former on the
+    // command line for debugging.
+    if (GTEST_FLAG(break_on_failure)) {
+#if GTEST_OS_WINDOWS
+      // Using DebugBreak on Windows allows gtest to still break into a debugger
+      // when a failure happens and both the --gtest_break_on_failure and
+      // the --gtest_catch_exceptions flags are specified.
+      DebugBreak();
+#else
+      *static_cast<int*>(NULL) = 1;
+#endif  // GTEST_OS_WINDOWS
+    } else if (GTEST_FLAG(throw_on_failure)) {
+#if GTEST_HAS_EXCEPTIONS
+      throw GoogleTestFailureException(result);
+#else
+      // We cannot call abort() as it generates a pop-up in debug mode
+      // that cannot be suppressed in VC 7.1 or below.
+      exit(1);
+#endif
+    }
+  }
+}
+
+// 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 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() {
+#if GTEST_HAS_SEH
+  // Catch SEH-style exceptions.
+
+  const bool in_death_test_child_process =
+      internal::GTEST_FLAG(internal_run_death_test).length() > 0;
+
+  // Either the user wants Google Test to catch exceptions thrown by the
+  // tests or this is executing in the context of death test child
+  // process. In either case the user does not want to see pop-up dialogs
+  // about crashes - they are expected..
+  if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) {
+#if !GTEST_OS_WINDOWS_MOBILE
+    // SetErrorMode doesn't exist on CE.
+    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
+                 SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
+#endif  // !GTEST_OS_WINDOWS_MOBILE
+
+#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE
+    // Death test children can be terminated with _abort().  On Windows,
+    // _abort() can show a dialog with a warning message.  This forces the
+    // abort message to go to stderr instead.
+    _set_error_mode(_OUT_TO_STDERR);
+#endif
+
+#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
+    // In the debug version, Visual Studio pops up a separate dialog
+    // offering a choice to debug the aborted program. We need to suppress
+    // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
+    // executed. Google Test will notify the user of any unexpected
+    // failure via stderr.
+    //
+    // VC++ doesn't define _set_abort_behavior() prior to the version 8.0.
+    // Users of prior VC versions shall suffer the agony and pain of
+    // clicking through the countless debug dialogs.
+    // TODO(vladl@google.com): find a way to suppress the abort dialog() in the
+    // debug mode when compiled with VC 7.1 or lower.
+    if (!GTEST_FLAG(break_on_failure))
+      _set_abort_behavior(
+          0x0,                                    // Clear the following flags:
+          _WRITE_ABORT_MSG | _CALL_REPORTFAULT);  // pop-up window, core dump.
+#endif
+  }
+
+  __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 a compiler or platform that doesn't support SEH.
+
+  return impl_->RunAllTests();
+#endif  // GTEST_HAS_SEH
+}
+
+// Returns the working directory when the first TEST() or TEST_F() was
+// executed.
+const char* UnitTest::original_working_dir() const {
+  return impl_->original_working_dir_.c_str();
+}
+
+// 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();
+}
+
+// Returns the random seed used at the start of the current test run.
+int UnitTest::random_seed() const { return impl_->random_seed(); }
+
+#if GTEST_HAS_PARAM_TEST
+// Returns ParameterizedTestCaseRegistry object used to keep track of
+// value-parameterized tests and instantiate and register them.
+// L < mutex_
+internal::ParameterizedTestCaseRegistry&
+    UnitTest::parameterized_test_registry() {
+  return impl_->parameterized_test_registry();
+}
+#endif  // GTEST_HAS_PARAM_TEST
+
+// 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().push_back(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().pop_back();
+}
+
+namespace internal {
+
+UnitTestImpl::UnitTestImpl(UnitTest* parent)
+    : parent_(parent),
+#ifdef _MSC_VER
+#pragma warning(push)                    // Saves the current warning state.
+#pragma warning(disable:4355)            // Temporarily disables warning 4355
+                                         // (using this in initializer).
+      default_global_test_part_result_reporter_(this),
+      default_per_thread_test_part_result_reporter_(this),
+#pragma warning(pop)                     // Restores the warning state again.
+#else
+      default_global_test_part_result_reporter_(this),
+      default_per_thread_test_part_result_reporter_(this),
+#endif  // _MSC_VER
+      global_test_part_result_repoter_(
+          &default_global_test_part_result_reporter_),
+      per_thread_test_part_result_reporter_(
+          &default_per_thread_test_part_result_reporter_),
+#if GTEST_HAS_PARAM_TEST
+      parameterized_test_registry_(),
+      parameterized_tests_registered_(false),
+#endif  // GTEST_HAS_PARAM_TEST
+      last_death_test_case_(-1),
+      current_test_case_(NULL),
+      current_test_info_(NULL),
+      ad_hoc_test_result_(),
+      os_stack_trace_getter_(NULL),
+      post_flag_parse_init_performed_(false),
+      random_seed_(0),  // Will be overridden by the flag before first use.
+      random_(0),  // Will be reseeded before first use.
+#if 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
+  listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter);
+}
+
+UnitTestImpl::~UnitTestImpl() {
+  // Deletes every TestCase.
+  ForEach(test_cases_, internal::Delete<TestCase>);
+
+  // Deletes every Environment.
+  ForEach(environments_, internal::Delete<Environment>);
+
+  delete os_stack_trace_getter_;
+}
+
+#if GTEST_HAS_DEATH_TEST
+// Disables event forwarding if the control is currently in a death test
+// subprocess. Must not be called before InitGoogleTest.
+void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
+  if (internal_run_death_test_flag_.get() != NULL)
+    listeners()->SuppressEventForwarding();
+}
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Initializes event listeners performing XML output as specified by
+// UnitTestOptions. Must not be called before InitGoogleTest.
+void UnitTestImpl::ConfigureXmlOutput() {
+  const String& output_format = UnitTestOptions::GetOutputFormat();
+  if (output_format == "xml") {
+    listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
+        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
+  } else if (output_format != "") {
+    printf("WARNING: unrecognized output format \"%s\" ignored.\n",
+           output_format.c_str());
+    fflush(stdout);
+  }
+}
+
+// Performs initialization dependent upon flag values obtained in
+// ParseGoogleTestFlagsOnly.  Is called from InitGoogleTest after the call to
+// ParseGoogleTestFlagsOnly.  In case a user neglects to call InitGoogleTest
+// this function is also called from RunAllTests.  Since this function can be
+// called more than once, it has to be idempotent.
+void UnitTestImpl::PostFlagParsingInit() {
+  // Ensures that this function does not execute more than once.
+  if (!post_flag_parse_init_performed_) {
+    post_flag_parse_init_performed_ = true;
+
+#if GTEST_HAS_DEATH_TEST
+    InitDeathTestSubprocessControlInfo();
+    SuppressTestEventsIfInSubprocess();
+#endif  // GTEST_HAS_DEATH_TEST
+
+    // Registers parameterized tests. This makes parameterized tests
+    // available to the UnitTest reflection API without running
+    // RUN_ALL_TESTS.
+    RegisterParameterizedTests();
+
+    // Configures listeners for XML output. This makes it possible for users
+    // to shut down the default XML output before invoking RUN_ALL_TESTS.
+    ConfigureXmlOutput();
+  }
+}
+
+// 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.  It's the CALLER'S
+// RESPONSIBILITY to ensure that this function is only called WHEN THE
+// TESTS ARE NOT SHUFFLED.
+//
+// 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,
+                                    const char* comment,
+                                    Test::SetUpTestCaseFunc set_up_tc,
+                                    Test::TearDownTestCaseFunc tear_down_tc) {
+  // Can we find a TestCase with the given name?
+  const std::vector<TestCase*>::const_iterator test_case =
+      std::find_if(test_cases_.begin(), test_cases_.end(),
+                   TestCaseNameIs(test_case_name));
+
+  if (test_case != test_cases_.end())
+    return *test_case;
+
+  // No.  Let's create one.
+  TestCase* const new_test_case =
+      new TestCase(test_case_name, comment, set_up_tc, tear_down_tc);
+
+  // Is this a death test case?
+  if (internal::UnitTestOptions::MatchesFilter(String(test_case_name),
+                                               kDeathTestCaseFilter)) {
+    // Yes.  Inserts the test case after the last death test case
+    // defined so far.  This only works when the test cases haven't
+    // been shuffled.  Otherwise we may end up running a death test
+    // after a non-death test.
+    ++last_death_test_case_;
+    test_cases_.insert(test_cases_.begin() + last_death_test_case_,
+                       new_test_case);
+  } else {
+    // No.  Appends to the end of the list.
+    test_cases_.push_back(new_test_case);
+  }
+
+  test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));
+  return new_test_case;
+}
+
+// Helpers for setting up / tearing down the given environment.  They
+// are for use in the ForEach() function.
+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.)
+// When parameterized tests are enabled, it expands and registers
+// parameterized tests first in RegisterParameterizedTests().
+// All other functions called from RunAllTests() may safely assume that
+// parameterized tests are ready to be counted and run.
+int UnitTestImpl::RunAllTests() {
+  // Makes sure InitGoogleTest() was called.
+  if (!GTestIsInitialized()) {
+    printf("%s",
+           "\nThis test program did NOT call ::testing::InitGoogleTest "
+           "before calling RUN_ALL_TESTS().  Please fix it.\n");
+    return 1;
+  }
+
+  // Do not run any test if the --help flag was specified.
+  if (g_help_flag)
+    return 0;
+
+  // Repeats the call to the post-flag parsing initialization in case the
+  // user didn't call InitGoogleTest.
+  PostFlagParsingInit();
+
+  // Even if sharding is not on, test runners may want to use the
+  // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding
+  // protocol.
+  internal::WriteToShardStatusFileIfNeeded();
+
+  // True iff we are in a subprocess for running a thread-safe-style
+  // death test.
+  bool in_subprocess_for_death_test = false;
+
+#if GTEST_HAS_DEATH_TEST
+  in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
+#endif  // GTEST_HAS_DEATH_TEST
+
+  const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex,
+                                        in_subprocess_for_death_test);
+
+  // Compares the full test names with the filter to decide which
+  // tests to run.
+  const bool has_tests_to_run = FilterTests(should_shard
+                                              ? HONOR_SHARDING_PROTOCOL
+                                              : IGNORE_SHARDING_PROTOCOL) > 0;
+
+  // Lists the tests and exits if the --gtest_list_tests flag was specified.
+  if (GTEST_FLAG(list_tests)) {
+    // This must be called *after* FilterTests() has been called.
+    ListTestsMatchingFilter();
+    return 0;
+  }
+
+  random_seed_ = GTEST_FLAG(shuffle) ?
+      GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;
+
+  // True iff at least one test has failed.
+  bool failed = false;
+
+  TestEventListener* repeater = listeners()->repeater();
+
+  repeater->OnTestProgramStart(*parent_);
+
+  // 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++) {
+    ClearResult();
+
+    const TimeInMillis start = GetTimeInMillis();
+
+    // Shuffles test cases and tests if requested.
+    if (has_tests_to_run && GTEST_FLAG(shuffle)) {
+      random()->Reseed(random_seed_);
+      // This should be done before calling OnTestIterationStart(),
+      // such that a test event listener can see the actual test order
+      // in the event.
+      ShuffleTests();
+    }
+
+    // Tells the unit test event listeners that the tests are about to start.
+    repeater->OnTestIterationStart(*parent_, i);
+
+    // Runs each test case if there is at least one test to run.
+    if (has_tests_to_run) {
+      // Sets up all environments beforehand.
+      repeater->OnEnvironmentsSetUpStart(*parent_);
+      ForEach(environments_, SetUpEnvironment);
+      repeater->OnEnvironmentsSetUpEnd(*parent_);
+
+      // Runs the tests only if there was no fatal failure during global
+      // set-up.
+      if (!Test::HasFatalFailure()) {
+        for (int test_index = 0; test_index < total_test_case_count();
+             test_index++) {
+          GetMutableTestCase(test_index)->Run();
+        }
+      }
+
+      // Tears down all environments in reverse order afterwards.
+      repeater->OnEnvironmentsTearDownStart(*parent_);
+      std::for_each(environments_.rbegin(), environments_.rend(),
+                    TearDownEnvironment);
+      repeater->OnEnvironmentsTearDownEnd(*parent_);
+    }
+
+    elapsed_time_ = GetTimeInMillis() - start;
+
+    // Tells the unit test event listener that the tests have just finished.
+    repeater->OnTestIterationEnd(*parent_, i);
+
+    // Gets the result and clears it.
+    if (!Passed()) {
+      failed = true;
+    }
+
+    // Restores the original test order after the iteration.  This
+    // allows the user to quickly repro a failure that happens in the
+    // N-th iteration without repeating the first (N - 1) iterations.
+    // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in
+    // case the user somehow changes the value of the flag somewhere
+    // (it's always safe to unshuffle the tests).
+    UnshuffleTests();
+
+    if (GTEST_FLAG(shuffle)) {
+      // Picks a new random seed for each iteration.
+      random_seed_ = GetNextRandomSeed(random_seed_);
+    }
+  }
+
+  repeater->OnTestProgramEnd(*parent_);
+
+  // Returns 0 if all tests passed, or 1 other wise.
+  return failed ? 1 : 0;
+}
+
+// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file
+// if the variable is present. If a file already exists at this location, this
+// function will write over it. If the variable is present, but the file cannot
+// be created, prints an error and exits.
+void WriteToShardStatusFileIfNeeded() {
+  const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);
+  if (test_shard_file != NULL) {
+    FILE* const file = posix::FOpen(test_shard_file, "w");
+    if (file == NULL) {
+      ColoredPrintf(COLOR_RED,
+                    "Could not write to the test shard status file \"%s\" "
+                    "specified by the %s environment variable.\n",
+                    test_shard_file, kTestShardStatusFile);
+      fflush(stdout);
+      exit(EXIT_FAILURE);
+    }
+    fclose(file);
+  }
+}
+
+// Checks whether sharding is enabled by examining the relevant
+// environment variable values. If the variables are present,
+// but inconsistent (i.e., shard_index >= total_shards), prints
+// an error and exits. If in_subprocess_for_death_test, sharding is
+// disabled because it must only be applied to the original test
+// process. Otherwise, we could filter out death tests we intended to execute.
+bool ShouldShard(const char* total_shards_env,
+                 const char* shard_index_env,
+                 bool in_subprocess_for_death_test) {
+  if (in_subprocess_for_death_test) {
+    return false;
+  }
+
+  const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1);
+  const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1);
+
+  if (total_shards == -1 && shard_index == -1) {
+    return false;
+  } else if (total_shards == -1 && shard_index != -1) {
+    const Message msg = Message()
+      << "Invalid environment variables: you have "
+      << kTestShardIndex << " = " << shard_index
+      << ", but have left " << kTestTotalShards << " unset.\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  } else if (total_shards != -1 && shard_index == -1) {
+    const Message msg = Message()
+      << "Invalid environment variables: you have "
+      << kTestTotalShards << " = " << total_shards
+      << ", but have left " << kTestShardIndex << " unset.\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  } else if (shard_index < 0 || shard_index >= total_shards) {
+    const Message msg = Message()
+      << "Invalid environment variables: we require 0 <= "
+      << kTestShardIndex << " < " << kTestTotalShards
+      << ", but you have " << kTestShardIndex << "=" << shard_index
+      << ", " << kTestTotalShards << "=" << total_shards << ".\n";
+    ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+    fflush(stdout);
+    exit(EXIT_FAILURE);
+  }
+
+  return total_shards > 1;
+}
+
+// Parses the environment variable var as an Int32. If it is unset,
+// returns default_val. If it is not an Int32, prints an error
+// and aborts.
+Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) {
+  const char* str_val = posix::GetEnv(var);
+  if (str_val == NULL) {
+    return default_val;
+  }
+
+  Int32 result;
+  if (!ParseInt32(Message() << "The value of environment variable " << var,
+                  str_val, &result)) {
+    exit(EXIT_FAILURE);
+  }
+  return result;
+}
+
+// Given the total number of shards, the shard index, and the test id,
+// returns true iff the test should be run on this shard. The test id is
+// some arbitrary but unique non-negative integer assigned to each test
+// method. Assumes that 0 <= shard_index < total_shards.
+bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
+  return (test_id % total_shards) == shard_index;
+}
+
+// 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.
+// If shard_tests == true, further filters tests based on sharding
+// variables in the environment - see
+// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide.
+// Returns the number of tests that should run.
+int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
+  const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
+      Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
+  const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ?
+      Int32FromEnvOrDie(kTestShardIndex, -1) : -1;
+
+  // num_runnable_tests are the number of tests that will
+  // run across all shards (i.e., match filter and are not disabled).
+  // num_selected_tests are the number of tests to be run on
+  // this shard.
+  int num_runnable_tests = 0;
+  int num_selected_tests = 0;
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    TestCase* const test_case = test_cases_[i];
+    const String &test_case_name = test_case->name();
+    test_case->set_should_run(false);
+
+    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+      TestInfo* const test_info = test_case->test_info_list()[j];
+      const String test_name(test_info->name());
+      // A test is disabled if test case name or test name matches
+      // kDisableTestFilter.
+      const bool is_disabled =
+          internal::UnitTestOptions::MatchesFilter(test_case_name,
+                                                   kDisableTestFilter) ||
+          internal::UnitTestOptions::MatchesFilter(test_name,
+                                                   kDisableTestFilter);
+      test_info->impl()->set_is_disabled(is_disabled);
+
+      const bool matches_filter =
+          internal::UnitTestOptions::FilterMatchesTest(test_case_name,
+                                                       test_name);
+      test_info->impl()->set_matches_filter(matches_filter);
+
+      const bool is_runnable =
+          (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
+          matches_filter;
+
+      const bool is_selected = is_runnable &&
+          (shard_tests == IGNORE_SHARDING_PROTOCOL ||
+           ShouldRunTestOnShard(total_shards, shard_index,
+                                num_runnable_tests));
+
+      num_runnable_tests += is_runnable;
+      num_selected_tests += is_selected;
+
+      test_info->impl()->set_should_run(is_selected);
+      test_case->set_should_run(test_case->should_run() || is_selected);
+    }
+  }
+  return num_selected_tests;
+}
+
+// Prints the names of the tests matching the user-specified filter flag.
+void UnitTestImpl::ListTestsMatchingFilter() {
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    const TestCase* const test_case = test_cases_[i];
+    bool printed_test_case_name = false;
+
+    for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
+      const TestInfo* const test_info =
+          test_case->test_info_list()[j];
+      if (test_info->matches_filter()) {
+        if (!printed_test_case_name) {
+          printed_test_case_name = true;
+          printf("%s.\n", test_case->name());
+        }
+        printf("  %s\n", test_info->name());
+      }
+    }
+  }
+  fflush(stdout);
+}
+
+// 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.
+TestResult* UnitTestImpl::current_test_result() {
+  return current_test_info_ ?
+    current_test_info_->impl()->result() : &ad_hoc_test_result_;
+}
+
+// Shuffles all test cases, and the tests within each test case,
+// making sure that death tests are still run first.
+void UnitTestImpl::ShuffleTests() {
+  // Shuffles the death test cases.
+  ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);
+
+  // Shuffles the non-death test cases.
+  ShuffleRange(random(), last_death_test_case_ + 1,
+               static_cast<int>(test_cases_.size()), &test_case_indices_);
+
+  // Shuffles the tests inside each test case.
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    test_cases_[i]->ShuffleTests(random());
+  }
+}
+
+// Restores the test cases and tests to their order before the first shuffle.
+void UnitTestImpl::UnshuffleTests() {
+  for (size_t i = 0; i < test_cases_.size(); i++) {
+    // Unshuffles the tests in each test case.
+    test_cases_[i]->UnshuffleTests();
+    // Resets the index of each test case.
+    test_case_indices_[i] = static_cast<int>(i);
+  }
+}
+
+// TestInfoImpl constructor. The new instance assumes ownership of the test
+// factory object.
+TestInfoImpl::TestInfoImpl(TestInfo* parent,
+                           const char* a_test_case_name,
+                           const char* a_name,
+                           const char* a_test_case_comment,
+                           const char* a_comment,
+                           TypeId a_fixture_class_id,
+                           internal::TestFactoryBase* factory) :
+    parent_(parent),
+    test_case_name_(String(a_test_case_name)),
+    name_(String(a_name)),
+    test_case_comment_(String(a_test_case_comment)),
+    comment_(String(a_comment)),
+    fixture_class_id_(a_fixture_class_id),
+    should_run_(false),
+    is_disabled_(false),
+    matches_filter_(false),
+    factory_(factory) {
+}
+
+// TestInfoImpl destructor.
+TestInfoImpl::~TestInfoImpl() {
+  delete factory_;
+}
+
+// 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
+// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
+// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
+String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/,
+                                       int skip_count) {
+  // We pass skip_count + 1 to skip this wrapper function in addition
+  // to what the user really wants to skip.
+  return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1);
+}
+
+// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable
+// code warnings.
+namespace {
+class ClassUniqueToAlwaysTrue {};
+}
+
+bool IsTrue(bool condition) { return condition; }
+
+bool AlwaysTrue() {
+#if GTEST_HAS_EXCEPTIONS
+  // This condition is always false so AlwaysTrue() never actually throws,
+  // but it makes the compiler think that it may throw.
+  if (IsTrue(false))
+    throw ClassUniqueToAlwaysTrue();
+#endif  // GTEST_HAS_EXCEPTIONS
+  return true;
+}
+
+// If *pstr starts with the given prefix, modifies *pstr to be right
+// past the prefix and returns true; otherwise leaves *pstr unchanged
+// and returns false.  None of pstr, *pstr, and prefix can be NULL.
+bool SkipPrefix(const char* prefix, const char** pstr) {
+  const size_t prefix_len = strlen(prefix);
+  if (strncmp(*pstr, prefix, prefix_len) == 0) {
+    *pstr += prefix_len;
+    return true;
+  }
+  return false;
+}
+
+// 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.length();
+  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;
+}
+
+// Determines whether a string has a prefix that Google Test uses for its
+// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_.
+// If Google Test detects that a command line flag has its prefix but is not
+// recognized, it will print its help message. Flags starting with
+// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test
+// internal flags and do not trigger the help message.
+static bool HasGoogleTestFlagPrefix(const char* str) {
+  return (SkipPrefix("--", &str) ||
+          SkipPrefix("-", &str) ||
+          SkipPrefix("/", &str)) &&
+         !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) &&
+         (SkipPrefix(GTEST_FLAG_PREFIX_, &str) ||
+          SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str));
+}
+
+// Prints a string containing code-encoded text.  The following escape
+// sequences can be used in the string to control the text color:
+//
+//   @@    prints a single '@' character.
+//   @R    changes the color to red.
+//   @G    changes the color to green.
+//   @Y    changes the color to yellow.
+//   @D    changes to the default terminal text color.
+//
+// TODO(wan@google.com): Write tests for this once we add stdout
+// capturing to Google Test.
+static void PrintColorEncoded(const char* str) {
+  GTestColor color = COLOR_DEFAULT;  // The current color.
+
+  // Conceptually, we split the string into segments divided by escape
+  // sequences.  Then we print one segment at a time.  At the end of
+  // each iteration, the str pointer advances to the beginning of the
+  // next segment.
+  for (;;) {
+    const char* p = strchr(str, '@');
+    if (p == NULL) {
+      ColoredPrintf(color, "%s", str);
+      return;
+    }
+
+    ColoredPrintf(color, "%s", String(str, p - str).c_str());
+
+    const char ch = p[1];
+    str = p + 2;
+    if (ch == '@') {
+      ColoredPrintf(color, "@");
+    } else if (ch == 'D') {
+      color = COLOR_DEFAULT;
+    } else if (ch == 'R') {
+      color = COLOR_RED;
+    } else if (ch == 'G') {
+      color = COLOR_GREEN;
+    } else if (ch == 'Y') {
+      color = COLOR_YELLOW;
+    } else {
+      --str;
+    }
+  }
+}
+
+static const char kColorEncodedHelpMessage[] =
+"This program contains tests written using " GTEST_NAME_ ". You can use the\n"
+"following command line flags to control its behavior:\n"
+"\n"
+"Test Selection:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n"
+"      List the names of all tests instead of running them. The name of\n"
+"      TEST(Foo, Bar) is \"Foo.Bar\".\n"
+"  @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS"
+    "[@G-@YNEGATIVE_PATTERNS]@D\n"
+"      Run only the tests whose name matches one of the positive patterns but\n"
+"      none of the negative patterns. '?' matches any single character; '*'\n"
+"      matches any substring; ':' separates two patterns.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n"
+"      Run all disabled tests too.\n"
+"\n"
+"Test Execution:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n"
+"      Run the tests repeatedly; use a negative count to repeat forever.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n"
+"      Randomize tests' orders on every iteration.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n"
+"      Random number seed to use for shuffling test orders (between 1 and\n"
+"      99999, or 0 to use a seed based on the current time).\n"
+"\n"
+"Test Output:\n"
+"  @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
+"      Enable/disable colored output. The default is @Gauto@D.\n"
+"  -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
+"      Don't print the elapsed time of each test.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G"
+    GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
+"      Generate an XML report in the given directory or with the given file\n"
+"      name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
+"\n"
+"Assertion Behavior:\n"
+#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
+"      Set the default death test style.\n"
+#endif  // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
+"      Turn assertion failures into debugger break-points.\n"
+"  @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
+"      Turn assertion failures into C++ exceptions.\n"
+#if GTEST_OS_WINDOWS
+"  @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n"
+"      Suppress pop-ups caused by exceptions.\n"
+#endif  // GTEST_OS_WINDOWS
+"\n"
+"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set "
+    "the corresponding\n"
+"environment variable of a flag (all letters in upper-case). For example, to\n"
+"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_
+    "color=no@D or set\n"
+"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n"
+"\n"
+"For more information, please read the " GTEST_NAME_ " documentation at\n"
+"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n"
+"(not one in your own code or tests), please report it to\n"
+"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.  The type parameter CharType can be
+// instantiated to either char or wchar_t.
+template <typename CharType>
+void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
+  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, kAlsoRunDisabledTestsFlag,
+                      &GTEST_FLAG(also_run_disabled_tests)) ||
+        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)) ||
+        ParseBoolFlag(arg, kDeathTestUseFork,
+                      &GTEST_FLAG(death_test_use_fork)) ||
+        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)) ||
+        ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
+        ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
+        ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
+        ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
+        ParseInt32Flag(arg, kStackTraceDepthFlag,
+                       &GTEST_FLAG(stack_trace_depth)) ||
+        ParseBoolFlag(arg, kThrowOnFailureFlag, &GTEST_FLAG(throw_on_failure))
+        ) {
+      // 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--;
+    } else if (arg_string == "--help" || arg_string == "-h" ||
+               arg_string == "-?" || arg_string == "/?" ||
+               HasGoogleTestFlagPrefix(arg)) {
+      // Both help flag and unrecognized Google Test flags (excluding
+      // internal ones) trigger help display.
+      g_help_flag = true;
+    }
+  }
+
+  if (g_help_flag) {
+    // We print the help here instead of in RUN_ALL_TESTS(), as the
+    // latter may not be called at all if the user is using Google
+    // Test with another testing framework.
+    PrintColorEncoded(kColorEncodedHelpMessage);
+  }
+}
+
+// Parses the command line for Google Test flags, without initializing
+// other parts of Google Test.
+void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
+  ParseGoogleTestFlagsOnlyImpl(argc, argv);
+}
+void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
+  ParseGoogleTestFlagsOnlyImpl(argc, argv);
+}
+
+// The internal implementation of InitGoogleTest().
+//
+// The type parameter CharType can be instantiated to either char or
+// wchar_t.
+template <typename CharType>
+void InitGoogleTestImpl(int* argc, CharType** argv) {
+  g_init_gtest_count++;
+
+  // We don't want to run the initialization code twice.
+  if (g_init_gtest_count != 1) return;
+
+  if (*argc <= 0) return;
+
+  internal::g_executable_path = internal::StreamableToString(argv[0]);
+
+#if 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
+
+  ParseGoogleTestFlagsOnly(argc, argv);
+  GetUnitTestImpl()->PostFlagParsingInit();
+}
+
+}  // namespace internal
+
+// Initializes Google Test.  This must be called before calling
+// RUN_ALL_TESTS().  In particular, it 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.
+//
+// Calling the function for the second time has no user-visible effect.
+void InitGoogleTest(int* argc, char** argv) {
+  internal::InitGoogleTestImpl(argc, argv);
+}
+
+// This overloaded version can be used in Windows programs compiled in
+// UNICODE mode.
+void InitGoogleTest(int* argc, wchar_t** argv) {
+  internal::InitGoogleTestImpl(argc, argv);
+}
+
+}  // namespace testing
diff --git a/protobuf/gtest/src/gtest_main.cc b/protobuf/gtest/src/gtest_main.cc
new file mode 100644
index 0000000..d20c02f
--- /dev/null
+++ b/protobuf/gtest/src/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::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/test/gtest-death-test_test.cc b/protobuf/gtest/test/gtest-death-test_test.cc
new file mode 100644
index 0000000..ed5b53b
--- /dev/null
+++ b/protobuf/gtest/test/gtest-death-test_test.cc
@@ -0,0 +1,1230 @@
+// 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)
+//
+// Tests for death tests.
+
+#include <gtest/gtest-death-test.h>
+#include <gtest/gtest.h>
+#include <gtest/internal/gtest-filepath.h>
+
+using testing::internal::AlwaysFalse;
+using testing::internal::AlwaysTrue;
+
+#if GTEST_HAS_DEATH_TEST
+
+#if GTEST_OS_WINDOWS
+#include <direct.h>          // For chdir().
+#else
+#include <unistd.h>
+#include <sys/wait.h>        // For waitpid.
+#include <limits>            // For std::numeric_limits.
+#endif  // GTEST_OS_WINDOWS
+
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include <gtest/gtest-spi.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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+namespace posix = ::testing::internal::posix;
+
+using testing::Message;
+using testing::internal::DeathTest;
+using testing::internal::DeathTestFactory;
+using testing::internal::FilePath;
+using testing::internal::GetLastErrnoDescription;
+using testing::internal::GetUnitTestImpl;
+using testing::internal::ParseNaturalNumber;
+using testing::internal::String;
+
+namespace testing {
+namespace internal {
+
+// A helper class whose objects replace the death test factory for a
+// single UnitTest object during their lifetimes.
+class ReplaceDeathTestFactory {
+ public:
+  explicit ReplaceDeathTestFactory(DeathTestFactory* new_factory)
+      : unit_test_impl_(GetUnitTestImpl()) {
+    old_factory_ = unit_test_impl_->death_test_factory_.release();
+    unit_test_impl_->death_test_factory_.reset(new_factory);
+  }
+
+  ~ReplaceDeathTestFactory() {
+    unit_test_impl_->death_test_factory_.release();
+    unit_test_impl_->death_test_factory_.reset(old_factory_);
+  }
+ private:
+  // Prevents copying ReplaceDeathTestFactory objects.
+  ReplaceDeathTestFactory(const ReplaceDeathTestFactory&);
+  void operator=(const ReplaceDeathTestFactory&);
+
+  UnitTestImpl* unit_test_impl_;
+  DeathTestFactory* old_factory_;
+};
+
+}  // namespace internal
+}  // namespace testing
+
+void DieInside(const char* function) {
+  fprintf(stderr, "death inside %s().", function);
+  fflush(stderr);
+  // We call _exit() instead of exit(), as the former is a direct
+  // system call and thus safer in the presence of threads.  exit()
+  // will invoke user-defined exit-hooks, which may do dangerous
+  // things that conflict with death tests.
+  //
+  // Some compilers can recognize that _exit() never returns and issue the
+  // 'unreachable code' warning for code following this function, unless
+  // fooled by a fake condition.
+  if (AlwaysTrue())
+    _exit(1);
+}
+
+// Tests that death tests work.
+
+class TestForDeathTest : public testing::Test {
+ protected:
+  TestForDeathTest() : original_dir_(FilePath::GetCurrentDir()) {}
+
+  virtual ~TestForDeathTest() {
+    posix::ChDir(original_dir_.c_str());
+  }
+
+  // A static member function that's expected to die.
+  static void StaticMemberFunction() { DieInside("StaticMemberFunction"); }
+
+  // A method of the test fixture that may die.
+  void MemberFunction() {
+    if (should_die_)
+      DieInside("MemberFunction");
+  }
+
+  // True iff MemberFunction() should die.
+  bool should_die_;
+  const FilePath original_dir_;
+};
+
+// A class with a member function that may die.
+class MayDie {
+ public:
+  explicit MayDie(bool should_die) : should_die_(should_die) {}
+
+  // A member function that may die.
+  void MemberFunction() const {
+    if (should_die_)
+      DieInside("MayDie::MemberFunction");
+  }
+
+ private:
+  // True iff MemberFunction() should die.
+  bool should_die_;
+};
+
+// A global function that's expected to die.
+void GlobalFunction() { DieInside("GlobalFunction"); }
+
+// A non-void function that's expected to die.
+int NonVoidFunction() {
+  DieInside("NonVoidFunction");
+  return 1;
+}
+
+// A unary function that may die.
+void DieIf(bool should_die) {
+  if (should_die)
+    DieInside("DieIf");
+}
+
+// A binary function that may die.
+bool DieIfLessThan(int x, int y) {
+  if (x < y) {
+    DieInside("DieIfLessThan");
+  }
+  return true;
+}
+
+// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture.
+void DeathTestSubroutine() {
+  EXPECT_DEATH(GlobalFunction(), "death.*GlobalFunction");
+  ASSERT_DEATH(GlobalFunction(), "death.*GlobalFunction");
+}
+
+// Death in dbg, not opt.
+int DieInDebugElse12(int* sideeffect) {
+  if (sideeffect) *sideeffect = 12;
+#ifndef NDEBUG
+  DieInside("DieInDebugElse12");
+#endif  // NDEBUG
+  return 12;
+}
+
+#if GTEST_OS_WINDOWS
+
+// Tests the ExitedWithCode predicate.
+TEST(ExitStatusPredicateTest, ExitedWithCode) {
+  // On Windows, the process's exit code is the same as its exit status,
+  // so the predicate just compares the its input with its parameter.
+  EXPECT_TRUE(testing::ExitedWithCode(0)(0));
+  EXPECT_TRUE(testing::ExitedWithCode(1)(1));
+  EXPECT_TRUE(testing::ExitedWithCode(42)(42));
+  EXPECT_FALSE(testing::ExitedWithCode(0)(1));
+  EXPECT_FALSE(testing::ExitedWithCode(1)(0));
+}
+
+#else
+
+// Returns the exit status of a process that calls _exit(2) with a
+// given exit code.  This is a helper function for the
+// ExitStatusPredicateTest test suite.
+static int NormalExitStatus(int exit_code) {
+  pid_t child_pid = fork();
+  if (child_pid == 0) {
+    _exit(exit_code);
+  }
+  int status;
+  waitpid(child_pid, &status, 0);
+  return status;
+}
+
+// Returns the exit status of a process that raises a given signal.
+// If the signal does not cause the process to die, then it returns
+// instead the exit status of a process that exits normally with exit
+// code 1.  This is a helper function for the ExitStatusPredicateTest
+// test suite.
+static int KilledExitStatus(int signum) {
+  pid_t child_pid = fork();
+  if (child_pid == 0) {
+    raise(signum);
+    _exit(1);
+  }
+  int status;
+  waitpid(child_pid, &status, 0);
+  return status;
+}
+
+// Tests the ExitedWithCode predicate.
+TEST(ExitStatusPredicateTest, ExitedWithCode) {
+  const int status0  = NormalExitStatus(0);
+  const int status1  = NormalExitStatus(1);
+  const int status42 = NormalExitStatus(42);
+  const testing::ExitedWithCode pred0(0);
+  const testing::ExitedWithCode pred1(1);
+  const testing::ExitedWithCode pred42(42);
+  EXPECT_PRED1(pred0,  status0);
+  EXPECT_PRED1(pred1,  status1);
+  EXPECT_PRED1(pred42, status42);
+  EXPECT_FALSE(pred0(status1));
+  EXPECT_FALSE(pred42(status0));
+  EXPECT_FALSE(pred1(status42));
+}
+
+// Tests the KilledBySignal predicate.
+TEST(ExitStatusPredicateTest, KilledBySignal) {
+  const int status_segv = KilledExitStatus(SIGSEGV);
+  const int status_kill = KilledExitStatus(SIGKILL);
+  const testing::KilledBySignal pred_segv(SIGSEGV);
+  const testing::KilledBySignal pred_kill(SIGKILL);
+  EXPECT_PRED1(pred_segv, status_segv);
+  EXPECT_PRED1(pred_kill, status_kill);
+  EXPECT_FALSE(pred_segv(status_kill));
+  EXPECT_FALSE(pred_kill(status_segv));
+}
+
+#endif  // GTEST_OS_WINDOWS
+
+// Tests that the death test macros expand to code which may or may not
+// be followed by operator<<, and that in either case the complete text
+// comprises only a single C++ statement.
+TEST_F(TestForDeathTest, SingleStatement) {
+  if (AlwaysFalse())
+    // This would fail if executed; this is a compilation test only
+    ASSERT_DEATH(return, "");
+
+  if (AlwaysTrue())
+    EXPECT_DEATH(_exit(1), "");
+  else
+    // This empty "else" branch is meant to ensure that EXPECT_DEATH
+    // doesn't expand into an "if" statement without an "else"
+    ;
+
+  if (AlwaysFalse())
+    ASSERT_DEATH(return, "") << "did not die";
+
+  if (AlwaysFalse())
+    ;
+  else
+    EXPECT_DEATH(_exit(1), "") << 1 << 2 << 3;
+}
+
+void DieWithEmbeddedNul() {
+  fprintf(stderr, "Hello%cmy null world.\n", '\0');
+  fflush(stderr);
+  _exit(1);
+}
+
+#if GTEST_USES_PCRE
+// Tests that EXPECT_DEATH and ASSERT_DEATH work when the error
+// message has a NUL character in it.
+TEST_F(TestForDeathTest, EmbeddedNulInMessage) {
+  // TODO(wan@google.com): <regex.h> doesn't support matching strings
+  // with embedded NUL characters - find a way to workaround it.
+  EXPECT_DEATH(DieWithEmbeddedNul(), "my null world");
+  ASSERT_DEATH(DieWithEmbeddedNul(), "my null world");
+}
+#endif  // GTEST_USES_PCRE
+
+// Tests that death test macros expand to code which interacts well with switch
+// statements.
+TEST_F(TestForDeathTest, SwitchStatement) {
+// Microsoft compiler usually complains about switch statements without
+// case labels. We suppress that warning for this test.
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4065)
+#endif  // _MSC_VER
+
+  switch (0)
+    default:
+      ASSERT_DEATH(_exit(1), "") << "exit in default switch handler";
+
+  switch (0)
+    case 0:
+      EXPECT_DEATH(_exit(1), "") << "exit in switch case";
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif  // _MSC_VER
+}
+
+// Tests that a static member function can be used in a "fast" style
+// death test.
+TEST_F(TestForDeathTest, StaticMemberFunctionFastStyle) {
+  testing::GTEST_FLAG(death_test_style) = "fast";
+  ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember");
+}
+
+// Tests that a method of the test fixture can be used in a "fast"
+// style death test.
+TEST_F(TestForDeathTest, MemberFunctionFastStyle) {
+  testing::GTEST_FLAG(death_test_style) = "fast";
+  should_die_ = true;
+  EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction");
+}
+
+void ChangeToRootDir() { posix::ChDir(GTEST_PATH_SEP_); }
+
+// Tests that death tests work even if the current directory has been
+// changed.
+TEST_F(TestForDeathTest, FastDeathTestInChangedDir) {
+  testing::GTEST_FLAG(death_test_style) = "fast";
+
+  ChangeToRootDir();
+  EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
+
+  ChangeToRootDir();
+  ASSERT_DEATH(_exit(1), "");
+}
+
+// Repeats a representative sample of death tests in the "threadsafe" style:
+
+TEST_F(TestForDeathTest, StaticMemberFunctionThreadsafeStyle) {
+  testing::GTEST_FLAG(death_test_style) = "threadsafe";
+  ASSERT_DEATH(StaticMemberFunction(), "death.*StaticMember");
+}
+
+TEST_F(TestForDeathTest, MemberFunctionThreadsafeStyle) {
+  testing::GTEST_FLAG(death_test_style) = "threadsafe";
+  should_die_ = true;
+  EXPECT_DEATH(MemberFunction(), "inside.*MemberFunction");
+}
+
+TEST_F(TestForDeathTest, ThreadsafeDeathTestInLoop) {
+  testing::GTEST_FLAG(death_test_style) = "threadsafe";
+
+  for (int i = 0; i < 3; ++i)
+    EXPECT_EXIT(_exit(i), testing::ExitedWithCode(i), "") << ": i = " << i;
+}
+
+TEST_F(TestForDeathTest, ThreadsafeDeathTestInChangedDir) {
+  testing::GTEST_FLAG(death_test_style) = "threadsafe";
+
+  ChangeToRootDir();
+  EXPECT_EXIT(_exit(1), testing::ExitedWithCode(1), "");
+
+  ChangeToRootDir();
+  ASSERT_DEATH(_exit(1), "");
+}
+
+TEST_F(TestForDeathTest, MixedStyles) {
+  testing::GTEST_FLAG(death_test_style) = "threadsafe";
+  EXPECT_DEATH(_exit(1), "");
+  testing::GTEST_FLAG(death_test_style) = "fast";
+  EXPECT_DEATH(_exit(1), "");
+}
+
+namespace {
+
+bool pthread_flag;
+
+void SetPthreadFlag() {
+  pthread_flag = true;
+}
+
+}  // namespace
+
+#if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
+
+TEST_F(TestForDeathTest, DoesNotExecuteAtforkHooks) {
+  if (!testing::GTEST_FLAG(death_test_use_fork)) {
+    testing::GTEST_FLAG(death_test_style) = "threadsafe";
+    pthread_flag = false;
+    ASSERT_EQ(0, pthread_atfork(&SetPthreadFlag, NULL, NULL));
+    ASSERT_DEATH(_exit(1), "");
+    ASSERT_FALSE(pthread_flag);
+  }
+}
+
+#endif  // GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
+
+// Tests that a method of another class can be used in a death test.
+TEST_F(TestForDeathTest, MethodOfAnotherClass) {
+  const MayDie x(true);
+  ASSERT_DEATH(x.MemberFunction(), "MayDie\\:\\:MemberFunction");
+}
+
+// Tests that a global function can be used in a death test.
+TEST_F(TestForDeathTest, GlobalFunction) {
+  EXPECT_DEATH(GlobalFunction(), "GlobalFunction");
+}
+
+// Tests that any value convertible to an RE works as a second
+// argument to EXPECT_DEATH.
+TEST_F(TestForDeathTest, AcceptsAnythingConvertibleToRE) {
+  static const char regex_c_str[] = "GlobalFunction";
+  EXPECT_DEATH(GlobalFunction(), regex_c_str);
+
+  const testing::internal::RE regex(regex_c_str);
+  EXPECT_DEATH(GlobalFunction(), regex);
+
+#if GTEST_HAS_GLOBAL_STRING
+  const string regex_str(regex_c_str);
+  EXPECT_DEATH(GlobalFunction(), regex_str);
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+  const ::std::string regex_std_str(regex_c_str);
+  EXPECT_DEATH(GlobalFunction(), regex_std_str);
+}
+
+// Tests that a non-void function can be used in a death test.
+TEST_F(TestForDeathTest, NonVoidFunction) {
+  ASSERT_DEATH(NonVoidFunction(), "NonVoidFunction");
+}
+
+// Tests that functions that take parameter(s) can be used in a death test.
+TEST_F(TestForDeathTest, FunctionWithParameter) {
+  EXPECT_DEATH(DieIf(true), "DieIf\\(\\)");
+  EXPECT_DEATH(DieIfLessThan(2, 3), "DieIfLessThan");
+}
+
+// Tests that ASSERT_DEATH can be used outside a TEST, TEST_F, or test fixture.
+TEST_F(TestForDeathTest, OutsideFixture) {
+  DeathTestSubroutine();
+}
+
+// Tests that death tests can be done inside a loop.
+TEST_F(TestForDeathTest, InsideLoop) {
+  for (int i = 0; i < 5; i++) {
+    EXPECT_DEATH(DieIfLessThan(-1, i), "DieIfLessThan") << "where i == " << i;
+  }
+}
+
+// Tests that a compound statement can be used in a death test.
+TEST_F(TestForDeathTest, CompoundStatement) {
+  EXPECT_DEATH({  // NOLINT
+    const int x = 2;
+    const int y = x + 1;
+    DieIfLessThan(x, y);
+  },
+  "DieIfLessThan");
+}
+
+// Tests that code that doesn't die causes a death test to fail.
+TEST_F(TestForDeathTest, DoesNotDie) {
+  EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(DieIf(false), "DieIf"),
+                          "failed to die");
+}
+
+// Tests that a death test fails when the error message isn't expected.
+TEST_F(TestForDeathTest, ErrorMessageMismatch) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_DEATH(DieIf(true), "DieIfLessThan") << "End of death test message.";
+  }, "died but not with expected error");
+}
+
+// On exit, *aborted will be true iff the EXPECT_DEATH() statement
+// aborted the function.
+void ExpectDeathTestHelper(bool* aborted) {
+  *aborted = true;
+  EXPECT_DEATH(DieIf(false), "DieIf");  // This assertion should fail.
+  *aborted = false;
+}
+
+// Tests that EXPECT_DEATH doesn't abort the test on failure.
+TEST_F(TestForDeathTest, EXPECT_DEATH) {
+  bool aborted = true;
+  EXPECT_NONFATAL_FAILURE(ExpectDeathTestHelper(&aborted),
+                          "failed to die");
+  EXPECT_FALSE(aborted);
+}
+
+// Tests that ASSERT_DEATH does abort the test on failure.
+TEST_F(TestForDeathTest, ASSERT_DEATH) {
+  static bool aborted;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    aborted = true;
+    ASSERT_DEATH(DieIf(false), "DieIf");  // This assertion should fail.
+    aborted = false;
+  }, "failed to die");
+  EXPECT_TRUE(aborted);
+}
+
+// Tests that EXPECT_DEATH evaluates the arguments exactly once.
+TEST_F(TestForDeathTest, SingleEvaluation) {
+  int x = 3;
+  EXPECT_DEATH(DieIf((++x) == 4), "DieIf");
+
+  const char* regex = "DieIf";
+  const char* regex_save = regex;
+  EXPECT_DEATH(DieIfLessThan(3, 4), regex++);
+  EXPECT_EQ(regex_save + 1, regex);
+}
+
+// Tests that run-away death tests are reported as failures.
+TEST_F(TestForDeathTest, Runaway) {
+  EXPECT_NONFATAL_FAILURE(EXPECT_DEATH(static_cast<void>(0), "Foo"),
+                          "failed to die.");
+
+  EXPECT_FATAL_FAILURE(ASSERT_DEATH(return, "Bar"),
+                       "illegal return in test statement.");
+}
+
+
+// Tests that EXPECT_DEBUG_DEATH works as expected,
+// that is, in debug mode, it:
+// 1. Asserts on death.
+// 2. Has no side effect.
+//
+// And in opt mode, it:
+// 1.  Has side effects but does not assert.
+TEST_F(TestForDeathTest, TestExpectDebugDeath) {
+  int sideeffect = 0;
+
+  EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect),
+                     "death.*DieInDebugElse12");
+
+#ifdef NDEBUG
+  // Checks that the assignment occurs in opt mode (sideeffect).
+  EXPECT_EQ(12, sideeffect);
+#else
+  // Checks that the assignment does not occur in dbg mode (no sideeffect).
+  EXPECT_EQ(0, sideeffect);
+#endif
+}
+
+// Tests that ASSERT_DEBUG_DEATH works as expected
+// In debug mode:
+// 1. Asserts on debug death.
+// 2. Has no side effect.
+//
+// In opt mode:
+// 1. Has side effects and returns the expected value (12).
+TEST_F(TestForDeathTest, TestAssertDebugDeath) {
+  int sideeffect = 0;
+
+  ASSERT_DEBUG_DEATH({  // NOLINT
+    // Tests that the return value is 12 in opt mode.
+    EXPECT_EQ(12, DieInDebugElse12(&sideeffect));
+    // Tests that the side effect occurred in opt mode.
+    EXPECT_EQ(12, sideeffect);
+  }, "death.*DieInDebugElse12");
+
+#ifdef NDEBUG
+  // Checks that the assignment occurs in opt mode (sideeffect).
+  EXPECT_EQ(12, sideeffect);
+#else
+  // Checks that the assignment does not occur in dbg mode (no sideeffect).
+  EXPECT_EQ(0, sideeffect);
+#endif
+}
+
+#ifndef NDEBUG
+
+void ExpectDebugDeathHelper(bool* aborted) {
+  *aborted = true;
+  EXPECT_DEBUG_DEATH(return, "") << "This is expected to fail.";
+  *aborted = false;
+}
+
+#if GTEST_OS_WINDOWS
+TEST(PopUpDeathTest, DoesNotShowPopUpOnAbort) {
+  printf("This test should be considered failing if it shows "
+         "any pop-up dialogs.\n");
+  fflush(stdout);
+
+  EXPECT_DEATH({
+    testing::GTEST_FLAG(catch_exceptions) = false;
+    abort();
+  }, "");
+}
+
+TEST(PopUpDeathTest, DoesNotShowPopUpOnThrow) {
+  printf("This test should be considered failing if it shows "
+         "any pop-up dialogs.\n");
+  fflush(stdout);
+
+  EXPECT_DEATH({
+    testing::GTEST_FLAG(catch_exceptions) = false;
+    throw 1;
+  }, "");
+}
+#endif  // GTEST_OS_WINDOWS
+
+// Tests that EXPECT_DEBUG_DEATH in debug mode does not abort
+// the function.
+TEST_F(TestForDeathTest, ExpectDebugDeathDoesNotAbort) {
+  bool aborted = true;
+  EXPECT_NONFATAL_FAILURE(ExpectDebugDeathHelper(&aborted), "");
+  EXPECT_FALSE(aborted);
+}
+
+void AssertDebugDeathHelper(bool* aborted) {
+  *aborted = true;
+  ASSERT_DEBUG_DEATH(return, "") << "This is expected to fail.";
+  *aborted = false;
+}
+
+// Tests that ASSERT_DEBUG_DEATH in debug mode aborts the function on
+// failure.
+TEST_F(TestForDeathTest, AssertDebugDeathAborts) {
+  static bool aborted;
+  aborted = false;
+  EXPECT_FATAL_FAILURE(AssertDebugDeathHelper(&aborted), "");
+  EXPECT_TRUE(aborted);
+}
+
+#endif  // _NDEBUG
+
+// Tests the *_EXIT family of macros, using a variety of predicates.
+static void TestExitMacros() {
+  EXPECT_EXIT(_exit(1),  testing::ExitedWithCode(1),  "");
+  ASSERT_EXIT(_exit(42), testing::ExitedWithCode(42), "");
+
+#if GTEST_OS_WINDOWS
+  // Of all signals effects on the process exit code, only those of SIGABRT
+  // are documented on Windows.
+  // See http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx.
+  EXPECT_EXIT(raise(SIGABRT), testing::ExitedWithCode(3), "");
+#else
+  EXPECT_EXIT(raise(SIGKILL), testing::KilledBySignal(SIGKILL), "") << "foo";
+  ASSERT_EXIT(raise(SIGUSR2), testing::KilledBySignal(SIGUSR2), "") << "bar";
+
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_EXIT(_exit(0), testing::KilledBySignal(SIGSEGV), "")
+        << "This failure is expected, too.";
+  }, "This failure is expected, too.");
+#endif  // GTEST_OS_WINDOWS
+
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_EXIT(raise(SIGSEGV), testing::ExitedWithCode(0), "")
+        << "This failure is expected.";
+  }, "This failure is expected.");
+}
+
+TEST_F(TestForDeathTest, ExitMacros) {
+  TestExitMacros();
+}
+
+TEST_F(TestForDeathTest, ExitMacrosUsingFork) {
+  testing::GTEST_FLAG(death_test_use_fork) = true;
+  TestExitMacros();
+}
+
+TEST_F(TestForDeathTest, InvalidStyle) {
+  testing::GTEST_FLAG(death_test_style) = "rococo";
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_DEATH(_exit(0), "") << "This failure is expected.";
+  }, "This failure is expected.");
+}
+
+// A DeathTestFactory that returns MockDeathTests.
+class MockDeathTestFactory : public DeathTestFactory {
+ public:
+  MockDeathTestFactory();
+  virtual bool Create(const char* statement,
+                      const ::testing::internal::RE* regex,
+                      const char* file, int line, DeathTest** test);
+
+  // Sets the parameters for subsequent calls to Create.
+  void SetParameters(bool create, DeathTest::TestRole role,
+                     int status, bool passed);
+
+  // Accessors.
+  int AssumeRoleCalls() const { return assume_role_calls_; }
+  int WaitCalls() const { return wait_calls_; }
+  int PassedCalls() const { return passed_args_.size(); }
+  bool PassedArgument(int n) const { return passed_args_[n]; }
+  int AbortCalls() const { return abort_args_.size(); }
+  DeathTest::AbortReason AbortArgument(int n) const {
+    return abort_args_[n];
+  }
+  bool TestDeleted() const { return test_deleted_; }
+
+ private:
+  friend class MockDeathTest;
+  // If true, Create will return a MockDeathTest; otherwise it returns
+  // NULL.
+  bool create_;
+  // The value a MockDeathTest will return from its AssumeRole method.
+  DeathTest::TestRole role_;
+  // The value a MockDeathTest will return from its Wait method.
+  int status_;
+  // The value a MockDeathTest will return from its Passed method.
+  bool passed_;
+
+  // Number of times AssumeRole was called.
+  int assume_role_calls_;
+  // Number of times Wait was called.
+  int wait_calls_;
+  // The arguments to the calls to Passed since the last call to
+  // SetParameters.
+  std::vector<bool> passed_args_;
+  // The arguments to the calls to Abort since the last call to
+  // SetParameters.
+  std::vector<DeathTest::AbortReason> abort_args_;
+  // True if the last MockDeathTest returned by Create has been
+  // deleted.
+  bool test_deleted_;
+};
+
+
+// A DeathTest implementation useful in testing.  It returns values set
+// at its creation from its various inherited DeathTest methods, and
+// reports calls to those methods to its parent MockDeathTestFactory
+// object.
+class MockDeathTest : public DeathTest {
+ public:
+  MockDeathTest(MockDeathTestFactory *parent,
+                TestRole role, int status, bool passed) :
+      parent_(parent), role_(role), status_(status), passed_(passed) {
+  }
+  virtual ~MockDeathTest() {
+    parent_->test_deleted_ = true;
+  }
+  virtual TestRole AssumeRole() {
+    ++parent_->assume_role_calls_;
+    return role_;
+  }
+  virtual int Wait() {
+    ++parent_->wait_calls_;
+    return status_;
+  }
+  virtual bool Passed(bool exit_status_ok) {
+    parent_->passed_args_.push_back(exit_status_ok);
+    return passed_;
+  }
+  virtual void Abort(AbortReason reason) {
+    parent_->abort_args_.push_back(reason);
+  }
+ private:
+  MockDeathTestFactory* const parent_;
+  const TestRole role_;
+  const int status_;
+  const bool passed_;
+};
+
+
+// MockDeathTestFactory constructor.
+MockDeathTestFactory::MockDeathTestFactory()
+    : create_(true),
+      role_(DeathTest::OVERSEE_TEST),
+      status_(0),
+      passed_(true),
+      assume_role_calls_(0),
+      wait_calls_(0),
+      passed_args_(),
+      abort_args_() {
+}
+
+
+// Sets the parameters for subsequent calls to Create.
+void MockDeathTestFactory::SetParameters(bool create,
+                                         DeathTest::TestRole role,
+                                         int status, bool passed) {
+  create_ = create;
+  role_ = role;
+  status_ = status;
+  passed_ = passed;
+
+  assume_role_calls_ = 0;
+  wait_calls_ = 0;
+  passed_args_.clear();
+  abort_args_.clear();
+}
+
+
+// Sets test to NULL (if create_ is false) or to the address of a new
+// MockDeathTest object with parameters taken from the last call
+// to SetParameters (if create_ is true).  Always returns true.
+bool MockDeathTestFactory::Create(const char* /*statement*/,
+                                  const ::testing::internal::RE* /*regex*/,
+                                  const char* /*file*/,
+                                  int /*line*/,
+                                  DeathTest** test) {
+  test_deleted_ = false;
+  if (create_) {
+    *test = new MockDeathTest(this, role_, status_, passed_);
+  } else {
+    *test = NULL;
+  }
+  return true;
+}
+
+// A test fixture for testing the logic of the GTEST_DEATH_TEST_ macro.
+// It installs a MockDeathTestFactory that is used for the duration
+// of the test case.
+class MacroLogicDeathTest : public testing::Test {
+ protected:
+  static testing::internal::ReplaceDeathTestFactory* replacer_;
+  static MockDeathTestFactory* factory_;
+
+  static void SetUpTestCase() {
+    factory_ = new MockDeathTestFactory;
+    replacer_ = new testing::internal::ReplaceDeathTestFactory(factory_);
+  }
+
+  static void TearDownTestCase() {
+    delete replacer_;
+    replacer_ = NULL;
+    delete factory_;
+    factory_ = NULL;
+  }
+
+  // Runs a death test that breaks the rules by returning.  Such a death
+  // test cannot be run directly from a test routine that uses a
+  // MockDeathTest, or the remainder of the routine will not be executed.
+  static void RunReturningDeathTest(bool* flag) {
+    ASSERT_DEATH({  // NOLINT
+      *flag = true;
+      return;
+    }, "");
+  }
+};
+
+testing::internal::ReplaceDeathTestFactory* MacroLogicDeathTest::replacer_
+    = NULL;
+MockDeathTestFactory* MacroLogicDeathTest::factory_ = NULL;
+
+
+// Test that nothing happens when the factory doesn't return a DeathTest:
+TEST_F(MacroLogicDeathTest, NothingHappens) {
+  bool flag = false;
+  factory_->SetParameters(false, DeathTest::OVERSEE_TEST, 0, true);
+  EXPECT_DEATH(flag = true, "");
+  EXPECT_FALSE(flag);
+  EXPECT_EQ(0, factory_->AssumeRoleCalls());
+  EXPECT_EQ(0, factory_->WaitCalls());
+  EXPECT_EQ(0, factory_->PassedCalls());
+  EXPECT_EQ(0, factory_->AbortCalls());
+  EXPECT_FALSE(factory_->TestDeleted());
+}
+
+// Test that the parent process doesn't run the death test code,
+// and that the Passed method returns false when the (simulated)
+// child process exits with status 0:
+TEST_F(MacroLogicDeathTest, ChildExitsSuccessfully) {
+  bool flag = false;
+  factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 0, true);
+  EXPECT_DEATH(flag = true, "");
+  EXPECT_FALSE(flag);
+  EXPECT_EQ(1, factory_->AssumeRoleCalls());
+  EXPECT_EQ(1, factory_->WaitCalls());
+  ASSERT_EQ(1, factory_->PassedCalls());
+  EXPECT_FALSE(factory_->PassedArgument(0));
+  EXPECT_EQ(0, factory_->AbortCalls());
+  EXPECT_TRUE(factory_->TestDeleted());
+}
+
+// Tests that the Passed method was given the argument "true" when
+// the (simulated) child process exits with status 1:
+TEST_F(MacroLogicDeathTest, ChildExitsUnsuccessfully) {
+  bool flag = false;
+  factory_->SetParameters(true, DeathTest::OVERSEE_TEST, 1, true);
+  EXPECT_DEATH(flag = true, "");
+  EXPECT_FALSE(flag);
+  EXPECT_EQ(1, factory_->AssumeRoleCalls());
+  EXPECT_EQ(1, factory_->WaitCalls());
+  ASSERT_EQ(1, factory_->PassedCalls());
+  EXPECT_TRUE(factory_->PassedArgument(0));
+  EXPECT_EQ(0, factory_->AbortCalls());
+  EXPECT_TRUE(factory_->TestDeleted());
+}
+
+// Tests that the (simulated) child process executes the death test
+// code, and is aborted with the correct AbortReason if it
+// executes a return statement.
+TEST_F(MacroLogicDeathTest, ChildPerformsReturn) {
+  bool flag = false;
+  factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true);
+  RunReturningDeathTest(&flag);
+  EXPECT_TRUE(flag);
+  EXPECT_EQ(1, factory_->AssumeRoleCalls());
+  EXPECT_EQ(0, factory_->WaitCalls());
+  EXPECT_EQ(0, factory_->PassedCalls());
+  EXPECT_EQ(1, factory_->AbortCalls());
+  EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT,
+            factory_->AbortArgument(0));
+  EXPECT_TRUE(factory_->TestDeleted());
+}
+
+// Tests that the (simulated) child process is aborted with the
+// correct AbortReason if it does not die.
+TEST_F(MacroLogicDeathTest, ChildDoesNotDie) {
+  bool flag = false;
+  factory_->SetParameters(true, DeathTest::EXECUTE_TEST, 0, true);
+  EXPECT_DEATH(flag = true, "");
+  EXPECT_TRUE(flag);
+  EXPECT_EQ(1, factory_->AssumeRoleCalls());
+  EXPECT_EQ(0, factory_->WaitCalls());
+  EXPECT_EQ(0, factory_->PassedCalls());
+  // This time there are two calls to Abort: one since the test didn't
+  // die, and another from the ReturnSentinel when it's destroyed.  The
+  // sentinel normally isn't destroyed if a test doesn't die, since
+  // _exit(2) is called in that case by ForkingDeathTest, but not by
+  // our MockDeathTest.
+  ASSERT_EQ(2, factory_->AbortCalls());
+  EXPECT_EQ(DeathTest::TEST_DID_NOT_DIE,
+            factory_->AbortArgument(0));
+  EXPECT_EQ(DeathTest::TEST_ENCOUNTERED_RETURN_STATEMENT,
+            factory_->AbortArgument(1));
+  EXPECT_TRUE(factory_->TestDeleted());
+}
+
+// Tests that a successful death test does not register a successful
+// test part.
+TEST(SuccessRegistrationDeathTest, NoSuccessPart) {
+  EXPECT_DEATH(_exit(1), "");
+  EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count());
+}
+
+TEST(StreamingAssertionsDeathTest, DeathTest) {
+  EXPECT_DEATH(_exit(1), "") << "unexpected failure";
+  ASSERT_DEATH(_exit(1), "") << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_DEATH(_exit(0), "") << "expected failure";
+  }, "expected failure");
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_DEATH(_exit(0), "") << "expected failure";
+  }, "expected failure");
+}
+
+// Tests that GetLastErrnoDescription returns an empty string when the
+// last error is 0 and non-empty string when it is non-zero.
+TEST(GetLastErrnoDescription, GetLastErrnoDescriptionWorks) {
+  errno = ENOENT;
+  EXPECT_STRNE("", GetLastErrnoDescription().c_str());
+  errno = 0;
+  EXPECT_STREQ("", GetLastErrnoDescription().c_str());
+}
+
+#if GTEST_OS_WINDOWS
+TEST(AutoHandleTest, AutoHandleWorks) {
+  HANDLE handle = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+  ASSERT_NE(INVALID_HANDLE_VALUE, handle);
+
+  // Tests that the AutoHandle is correctly initialized with a handle.
+  testing::internal::AutoHandle auto_handle(handle);
+  EXPECT_EQ(handle, auto_handle.Get());
+
+  // Tests that Reset assigns INVALID_HANDLE_VALUE.
+  // Note that this cannot verify whether the original handle is closed.
+  auto_handle.Reset();
+  EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle.Get());
+
+  // Tests that Reset assigns the new handle.
+  // Note that this cannot verify whether the original handle is closed.
+  handle = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+  ASSERT_NE(INVALID_HANDLE_VALUE, handle);
+  auto_handle.Reset(handle);
+  EXPECT_EQ(handle, auto_handle.Get());
+
+  // Tests that AutoHandle contains INVALID_HANDLE_VALUE by default.
+  testing::internal::AutoHandle auto_handle2;
+  EXPECT_EQ(INVALID_HANDLE_VALUE, auto_handle2.Get());
+}
+#endif  // GTEST_OS_WINDOWS
+
+#if GTEST_OS_WINDOWS
+typedef unsigned __int64 BiggestParsable;
+typedef signed __int64 BiggestSignedParsable;
+const BiggestParsable kBiggestParsableMax = ULLONG_MAX;
+const BiggestParsable kBiggestSignedParsableMax = LLONG_MAX;
+#else
+typedef unsigned long long BiggestParsable;
+typedef signed long long BiggestSignedParsable;
+const BiggestParsable kBiggestParsableMax =
+    ::std::numeric_limits<BiggestParsable>::max();
+const BiggestSignedParsable kBiggestSignedParsableMax =
+    ::std::numeric_limits<BiggestSignedParsable>::max();
+#endif  // GTEST_OS_WINDOWS
+
+TEST(ParseNaturalNumberTest, RejectsInvalidFormat) {
+  BiggestParsable result = 0;
+
+  // Rejects non-numbers.
+  EXPECT_FALSE(ParseNaturalNumber(String("non-number string"), &result));
+
+  // Rejects numbers with whitespace prefix.
+  EXPECT_FALSE(ParseNaturalNumber(String(" 123"), &result));
+
+  // Rejects negative numbers.
+  EXPECT_FALSE(ParseNaturalNumber(String("-123"), &result));
+
+  // Rejects numbers starting with a plus sign.
+  EXPECT_FALSE(ParseNaturalNumber(String("+123"), &result));
+  errno = 0;
+}
+
+TEST(ParseNaturalNumberTest, RejectsOverflownNumbers) {
+  BiggestParsable result = 0;
+
+  EXPECT_FALSE(ParseNaturalNumber(String("99999999999999999999999"), &result));
+
+  signed char char_result = 0;
+  EXPECT_FALSE(ParseNaturalNumber(String("200"), &char_result));
+  errno = 0;
+}
+
+TEST(ParseNaturalNumberTest, AcceptsValidNumbers) {
+  BiggestParsable result = 0;
+
+  result = 0;
+  ASSERT_TRUE(ParseNaturalNumber(String("123"), &result));
+  EXPECT_EQ(123U, result);
+
+  // Check 0 as an edge case.
+  result = 1;
+  ASSERT_TRUE(ParseNaturalNumber(String("0"), &result));
+  EXPECT_EQ(0U, result);
+
+  result = 1;
+  ASSERT_TRUE(ParseNaturalNumber(String("00000"), &result));
+  EXPECT_EQ(0U, result);
+}
+
+TEST(ParseNaturalNumberTest, AcceptsTypeLimits) {
+  Message msg;
+  msg << kBiggestParsableMax;
+
+  BiggestParsable result = 0;
+  EXPECT_TRUE(ParseNaturalNumber(msg.GetString(), &result));
+  EXPECT_EQ(kBiggestParsableMax, result);
+
+  Message msg2;
+  msg2 << kBiggestSignedParsableMax;
+
+  BiggestSignedParsable signed_result = 0;
+  EXPECT_TRUE(ParseNaturalNumber(msg2.GetString(), &signed_result));
+  EXPECT_EQ(kBiggestSignedParsableMax, signed_result);
+
+  Message msg3;
+  msg3 << INT_MAX;
+
+  int int_result = 0;
+  EXPECT_TRUE(ParseNaturalNumber(msg3.GetString(), &int_result));
+  EXPECT_EQ(INT_MAX, int_result);
+
+  Message msg4;
+  msg4 << UINT_MAX;
+
+  unsigned int uint_result = 0;
+  EXPECT_TRUE(ParseNaturalNumber(msg4.GetString(), &uint_result));
+  EXPECT_EQ(UINT_MAX, uint_result);
+}
+
+TEST(ParseNaturalNumberTest, WorksForShorterIntegers) {
+  short short_result = 0;
+  ASSERT_TRUE(ParseNaturalNumber(String("123"), &short_result));
+  EXPECT_EQ(123, short_result);
+
+  signed char char_result = 0;
+  ASSERT_TRUE(ParseNaturalNumber(String("123"), &char_result));
+  EXPECT_EQ(123, char_result);
+}
+
+#if GTEST_OS_WINDOWS
+TEST(EnvironmentTest, HandleFitsIntoSizeT) {
+  // TODO(vladl@google.com): Remove this test after this condition is verified
+  // in a static assertion in gtest-death-test.cc in the function
+  // GetStatusFileDescriptor.
+  ASSERT_TRUE(sizeof(HANDLE) <= sizeof(size_t));
+}
+#endif  // GTEST_OS_WINDOWS
+
+// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED trigger
+// failures when death tests are available on the system.
+TEST(ConditionalDeathMacrosDeathTest, ExpectsDeathWhenDeathTestsAvailable) {
+  EXPECT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestExpectMacro"),
+                            "death inside CondDeathTestExpectMacro");
+  ASSERT_DEATH_IF_SUPPORTED(DieInside("CondDeathTestAssertMacro"),
+                            "death inside CondDeathTestAssertMacro");
+
+  // Empty statement will not crash, which must trigger a failure.
+  EXPECT_NONFATAL_FAILURE(EXPECT_DEATH_IF_SUPPORTED(;, ""), "");
+  EXPECT_FATAL_FAILURE(ASSERT_DEATH_IF_SUPPORTED(;, ""), "");
+}
+
+#else
+
+using testing::internal::CaptureStderr;
+using testing::internal::GetCapturedStderr;
+using testing::internal::String;
+
+// Tests that EXPECT_DEATH_IF_SUPPORTED/ASSERT_DEATH_IF_SUPPORTED are still
+// defined but do not trigger failures when death tests are not available on
+// the system.
+TEST(ConditionalDeathMacrosTest, WarnsWhenDeathTestsNotAvailable) {
+  // Empty statement will not crash, but that should not trigger a failure
+  // when death tests are not supported.
+  CaptureStderr();
+  EXPECT_DEATH_IF_SUPPORTED(;, "");
+  String output = GetCapturedStderr();
+  ASSERT_TRUE(NULL != strstr(output.c_str(),
+                             "Death tests are not supported on this platform"));
+  ASSERT_TRUE(NULL != strstr(output.c_str(), ";"));
+
+  // The streamed message should not be printed as there is no test failure.
+  CaptureStderr();
+  EXPECT_DEATH_IF_SUPPORTED(;, "") << "streamed message";
+  output = GetCapturedStderr();
+  ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message"));
+
+  CaptureStderr();
+  ASSERT_DEATH_IF_SUPPORTED(;, "");  // NOLINT
+  output = GetCapturedStderr();
+  ASSERT_TRUE(NULL != strstr(output.c_str(),
+                             "Death tests are not supported on this platform"));
+  ASSERT_TRUE(NULL != strstr(output.c_str(), ";"));
+
+  CaptureStderr();
+  ASSERT_DEATH_IF_SUPPORTED(;, "") << "streamed message";  // NOLINT
+  output = GetCapturedStderr();
+  ASSERT_TRUE(NULL == strstr(output.c_str(), "streamed message"));
+}
+
+void FuncWithAssert(int* n) {
+  ASSERT_DEATH_IF_SUPPORTED(return;, "");
+  (*n)++;
+}
+
+// Tests that ASSERT_DEATH_IF_SUPPORTED does not return from the current
+// function (as ASSERT_DEATH does) if death tests are not supported.
+TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) {
+  int n = 0;
+  FuncWithAssert(&n);
+  EXPECT_EQ(1, n);
+}
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Tests that the death test macros expand to code which may or may not
+// be followed by operator<<, and that in either case the complete text
+// comprises only a single C++ statement.
+//
+// The syntax should work whether death tests are available or not.
+TEST(ConditionalDeathMacrosSyntaxDeathTest, SingleStatement) {
+  if (AlwaysFalse())
+    // This would fail if executed; this is a compilation test only
+    ASSERT_DEATH_IF_SUPPORTED(return, "");
+
+  if (AlwaysTrue())
+    EXPECT_DEATH_IF_SUPPORTED(_exit(1), "");
+  else
+    // This empty "else" branch is meant to ensure that EXPECT_DEATH
+    // doesn't expand into an "if" statement without an "else"
+    ;  // NOLINT
+
+  if (AlwaysFalse())
+    ASSERT_DEATH_IF_SUPPORTED(return, "") << "did not die";
+
+  if (AlwaysFalse())
+    ;  // NOLINT
+  else
+    EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << 1 << 2 << 3;
+}
+
+// Tests that conditional death test macros expand to code which interacts
+// well with switch statements.
+TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) {
+// Microsoft compiler usually complains about switch statements without
+// case labels. We suppress that warning for this test.
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4065)
+#endif  // _MSC_VER
+
+  switch (0)
+    default:
+      ASSERT_DEATH_IF_SUPPORTED(_exit(1), "")
+          << "exit in default switch handler";
+
+  switch (0)
+    case 0:
+      EXPECT_DEATH_IF_SUPPORTED(_exit(1), "") << "exit in switch case";
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif  // _MSC_VER
+}
+
+// Tests that a test case whose name ends with "DeathTest" works fine
+// on Windows.
+TEST(NotADeathTest, Test) {
+  SUCCEED();
+}
diff --git a/protobuf/gtest/test/gtest-filepath_test.cc b/protobuf/gtest/test/gtest-filepath_test.cc
new file mode 100644
index 0000000..6250282
--- /dev/null
+++ b/protobuf/gtest/test/gtest-filepath_test.cc
@@ -0,0 +1,690 @@
+// 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)
+//
+// Google Test filepath utilities
+//
+// This file tests classes and functions used internally by
+// Google Test.  They are subject to change without notice.
+//
+// This file is #included from gtest_unittest.cc, to avoid changing
+// build or make-files for some existing Google Test clients. Do not
+// #include this file anywhere else!
+
+#include <gtest/internal/gtest-filepath.h>
+#include <gtest/gtest.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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h>  // NOLINT
+#elif GTEST_OS_WINDOWS
+#include <direct.h>  // NOLINT
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+namespace testing {
+namespace internal {
+namespace {
+
+#if GTEST_OS_WINDOWS_MOBILE
+// TODO(wan@google.com): Move these to the POSIX adapter section in
+// gtest-port.h.
+
+// Windows CE doesn't have the remove C function.
+int remove(const char* path) {
+  LPCWSTR wpath = String::AnsiToUtf16(path);
+  int ret = DeleteFile(wpath) ? 0 : -1;
+  delete [] wpath;
+  return ret;
+}
+// Windows CE doesn't have the _rmdir C function.
+int _rmdir(const char* path) {
+  FilePath filepath(path);
+  LPCWSTR wpath = String::AnsiToUtf16(
+      filepath.RemoveTrailingPathSeparator().c_str());
+  int ret = RemoveDirectory(wpath) ? 0 : -1;
+  delete [] wpath;
+  return ret;
+}
+
+#else
+
+TEST(GetCurrentDirTest, ReturnsCurrentDir) {
+  const FilePath original_dir = FilePath::GetCurrentDir();
+  EXPECT_FALSE(original_dir.IsEmpty());
+
+  posix::ChDir(GTEST_PATH_SEP_);
+  const FilePath cwd = FilePath::GetCurrentDir();
+  posix::ChDir(original_dir.c_str());
+
+#if GTEST_OS_WINDOWS
+  // Skips the ":".
+  const char* const cwd_without_drive = strchr(cwd.c_str(), ':');
+  ASSERT_TRUE(cwd_without_drive != NULL);
+  EXPECT_STREQ(GTEST_PATH_SEP_, cwd_without_drive + 1);
+#else
+  EXPECT_STREQ(GTEST_PATH_SEP_, cwd.c_str());
+#endif
+}
+
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+TEST(IsEmptyTest, ReturnsTrueForEmptyPath) {
+  EXPECT_TRUE(FilePath("").IsEmpty());
+  EXPECT_TRUE(FilePath(NULL).IsEmpty());
+}
+
+TEST(IsEmptyTest, ReturnsFalseForNonEmptyPath) {
+  EXPECT_FALSE(FilePath("a").IsEmpty());
+  EXPECT_FALSE(FilePath(".").IsEmpty());
+  EXPECT_FALSE(FilePath("a/b").IsEmpty());
+  EXPECT_FALSE(FilePath("a\\b\\").IsEmpty());
+}
+
+// RemoveDirectoryName "" -> ""
+TEST(RemoveDirectoryNameTest, WhenEmptyName) {
+  EXPECT_STREQ("", FilePath("").RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName "afile" -> "afile"
+TEST(RemoveDirectoryNameTest, ButNoDirectory) {
+  EXPECT_STREQ("afile",
+      FilePath("afile").RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName "/afile" -> "afile"
+TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileName) {
+  EXPECT_STREQ("afile",
+      FilePath(GTEST_PATH_SEP_ "afile").RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName "adir/" -> ""
+TEST(RemoveDirectoryNameTest, WhereThereIsNoFileName) {
+  EXPECT_STREQ("",
+      FilePath("adir" GTEST_PATH_SEP_).RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName "adir/afile" -> "afile"
+TEST(RemoveDirectoryNameTest, ShouldGiveFileName) {
+  EXPECT_STREQ("afile",
+      FilePath("adir" GTEST_PATH_SEP_ "afile").RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName "adir/subdir/afile" -> "afile"
+TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileName) {
+  EXPECT_STREQ("afile",
+      FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile")
+      .RemoveDirectoryName().c_str());
+}
+
+#if GTEST_HAS_ALT_PATH_SEP_
+
+// Tests that RemoveDirectoryName() works with the alternate separator
+// on Windows.
+
+// RemoveDirectoryName("/afile") -> "afile"
+TEST(RemoveDirectoryNameTest, RootFileShouldGiveFileNameForAlternateSeparator) {
+  EXPECT_STREQ("afile",
+               FilePath("/afile").RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName("adir/") -> ""
+TEST(RemoveDirectoryNameTest, WhereThereIsNoFileNameForAlternateSeparator) {
+  EXPECT_STREQ("",
+               FilePath("adir/").RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName("adir/afile") -> "afile"
+TEST(RemoveDirectoryNameTest, ShouldGiveFileNameForAlternateSeparator) {
+  EXPECT_STREQ("afile",
+               FilePath("adir/afile").RemoveDirectoryName().c_str());
+}
+
+// RemoveDirectoryName("adir/subdir/afile") -> "afile"
+TEST(RemoveDirectoryNameTest, ShouldAlsoGiveFileNameForAlternateSeparator) {
+  EXPECT_STREQ("afile",
+               FilePath("adir/subdir/afile").RemoveDirectoryName().c_str());
+}
+
+#endif
+
+// RemoveFileName "" -> "./"
+TEST(RemoveFileNameTest, EmptyName) {
+#if GTEST_OS_WINDOWS_MOBILE
+  // On Windows CE, we use the root as the current directory.
+  EXPECT_STREQ(GTEST_PATH_SEP_,
+      FilePath("").RemoveFileName().c_str());
+#else
+  EXPECT_STREQ("." GTEST_PATH_SEP_,
+      FilePath("").RemoveFileName().c_str());
+#endif
+}
+
+// RemoveFileName "adir/" -> "adir/"
+TEST(RemoveFileNameTest, ButNoFile) {
+  EXPECT_STREQ("adir" GTEST_PATH_SEP_,
+      FilePath("adir" GTEST_PATH_SEP_).RemoveFileName().c_str());
+}
+
+// RemoveFileName "adir/afile" -> "adir/"
+TEST(RemoveFileNameTest, GivesDirName) {
+  EXPECT_STREQ("adir" GTEST_PATH_SEP_,
+      FilePath("adir" GTEST_PATH_SEP_ "afile")
+      .RemoveFileName().c_str());
+}
+
+// RemoveFileName "adir/subdir/afile" -> "adir/subdir/"
+TEST(RemoveFileNameTest, GivesDirAndSubDirName) {
+  EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_,
+      FilePath("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_ "afile")
+      .RemoveFileName().c_str());
+}
+
+// RemoveFileName "/afile" -> "/"
+TEST(RemoveFileNameTest, GivesRootDir) {
+  EXPECT_STREQ(GTEST_PATH_SEP_,
+      FilePath(GTEST_PATH_SEP_ "afile").RemoveFileName().c_str());
+}
+
+#if GTEST_HAS_ALT_PATH_SEP_
+
+// Tests that RemoveFileName() works with the alternate separator on
+// Windows.
+
+// RemoveFileName("adir/") -> "adir/"
+TEST(RemoveFileNameTest, ButNoFileForAlternateSeparator) {
+  EXPECT_STREQ("adir" GTEST_PATH_SEP_,
+               FilePath("adir/").RemoveFileName().c_str());
+}
+
+// RemoveFileName("adir/afile") -> "adir/"
+TEST(RemoveFileNameTest, GivesDirNameForAlternateSeparator) {
+  EXPECT_STREQ("adir" GTEST_PATH_SEP_,
+               FilePath("adir/afile").RemoveFileName().c_str());
+}
+
+// RemoveFileName("adir/subdir/afile") -> "adir/subdir/"
+TEST(RemoveFileNameTest, GivesDirAndSubDirNameForAlternateSeparator) {
+  EXPECT_STREQ("adir" GTEST_PATH_SEP_ "subdir" GTEST_PATH_SEP_,
+               FilePath("adir/subdir/afile").RemoveFileName().c_str());
+}
+
+// RemoveFileName("/afile") -> "\"
+TEST(RemoveFileNameTest, GivesRootDirForAlternateSeparator) {
+  EXPECT_STREQ(GTEST_PATH_SEP_,
+               FilePath("/afile").RemoveFileName().c_str());
+}
+
+#endif
+
+TEST(MakeFileNameTest, GenerateWhenNumberIsZero) {
+  FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"),
+      0, "xml");
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str());
+}
+
+TEST(MakeFileNameTest, GenerateFileNameNumberGtZero) {
+  FilePath actual = FilePath::MakeFileName(FilePath("foo"), FilePath("bar"),
+      12, "xml");
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.c_str());
+}
+
+TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberIsZero) {
+  FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_),
+      FilePath("bar"), 0, "xml");
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str());
+}
+
+TEST(MakeFileNameTest, GenerateFileNameWithSlashNumberGtZero) {
+  FilePath actual = FilePath::MakeFileName(FilePath("foo" GTEST_PATH_SEP_),
+      FilePath("bar"), 12, "xml");
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar_12.xml", actual.c_str());
+}
+
+TEST(MakeFileNameTest, GenerateWhenNumberIsZeroAndDirIsEmpty) {
+  FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"),
+      0, "xml");
+  EXPECT_STREQ("bar.xml", actual.c_str());
+}
+
+TEST(MakeFileNameTest, GenerateWhenNumberIsNotZeroAndDirIsEmpty) {
+  FilePath actual = FilePath::MakeFileName(FilePath(""), FilePath("bar"),
+      14, "xml");
+  EXPECT_STREQ("bar_14.xml", actual.c_str());
+}
+
+TEST(ConcatPathsTest, WorksWhenDirDoesNotEndWithPathSep) {
+  FilePath actual = FilePath::ConcatPaths(FilePath("foo"),
+                                          FilePath("bar.xml"));
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str());
+}
+
+TEST(ConcatPathsTest, WorksWhenPath1EndsWithPathSep) {
+  FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_),
+                                          FilePath("bar.xml"));
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar.xml", actual.c_str());
+}
+
+TEST(ConcatPathsTest, Path1BeingEmpty) {
+  FilePath actual = FilePath::ConcatPaths(FilePath(""),
+                                          FilePath("bar.xml"));
+  EXPECT_STREQ("bar.xml", actual.c_str());
+}
+
+TEST(ConcatPathsTest, Path2BeingEmpty) {
+  FilePath actual = FilePath::ConcatPaths(FilePath("foo"),
+                                          FilePath(""));
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_, actual.c_str());
+}
+
+TEST(ConcatPathsTest, BothPathBeingEmpty) {
+  FilePath actual = FilePath::ConcatPaths(FilePath(""),
+                                          FilePath(""));
+  EXPECT_STREQ("", actual.c_str());
+}
+
+TEST(ConcatPathsTest, Path1ContainsPathSep) {
+  FilePath actual = FilePath::ConcatPaths(FilePath("foo" GTEST_PATH_SEP_ "bar"),
+                                          FilePath("foobar.xml"));
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "foobar.xml",
+               actual.c_str());
+}
+
+TEST(ConcatPathsTest, Path2ContainsPathSep) {
+  FilePath actual = FilePath::ConcatPaths(
+      FilePath("foo" GTEST_PATH_SEP_),
+      FilePath("bar" GTEST_PATH_SEP_ "bar.xml"));
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_ "bar.xml",
+               actual.c_str());
+}
+
+TEST(ConcatPathsTest, Path2EndsWithPathSep) {
+  FilePath actual = FilePath::ConcatPaths(FilePath("foo"),
+                                          FilePath("bar" GTEST_PATH_SEP_));
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_, actual.c_str());
+}
+
+// RemoveTrailingPathSeparator "" -> ""
+TEST(RemoveTrailingPathSeparatorTest, EmptyString) {
+  EXPECT_STREQ("",
+      FilePath("").RemoveTrailingPathSeparator().c_str());
+}
+
+// RemoveTrailingPathSeparator "foo" -> "foo"
+TEST(RemoveTrailingPathSeparatorTest, FileNoSlashString) {
+  EXPECT_STREQ("foo",
+      FilePath("foo").RemoveTrailingPathSeparator().c_str());
+}
+
+// RemoveTrailingPathSeparator "foo/" -> "foo"
+TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveTrailingSeparator) {
+  EXPECT_STREQ(
+      "foo",
+      FilePath("foo" GTEST_PATH_SEP_).RemoveTrailingPathSeparator().c_str());
+#if GTEST_HAS_ALT_PATH_SEP_
+  EXPECT_STREQ("foo",
+               FilePath("foo/").RemoveTrailingPathSeparator().c_str());
+#endif
+}
+
+// RemoveTrailingPathSeparator "foo/bar/" -> "foo/bar/"
+TEST(RemoveTrailingPathSeparatorTest, ShouldRemoveLastSeparator) {
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar",
+               FilePath("foo" GTEST_PATH_SEP_ "bar" GTEST_PATH_SEP_)
+               .RemoveTrailingPathSeparator().c_str());
+}
+
+// RemoveTrailingPathSeparator "foo/bar" -> "foo/bar"
+TEST(RemoveTrailingPathSeparatorTest, ShouldReturnUnmodified) {
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar",
+               FilePath("foo" GTEST_PATH_SEP_ "bar")
+               .RemoveTrailingPathSeparator().c_str());
+}
+
+TEST(DirectoryTest, RootDirectoryExists) {
+#if GTEST_OS_WINDOWS  // We are on Windows.
+  char current_drive[_MAX_PATH];  // NOLINT
+  current_drive[0] = static_cast<char>(_getdrive() + 'A' - 1);
+  current_drive[1] = ':';
+  current_drive[2] = '\\';
+  current_drive[3] = '\0';
+  EXPECT_TRUE(FilePath(current_drive).DirectoryExists());
+#else
+  EXPECT_TRUE(FilePath("/").DirectoryExists());
+#endif  // GTEST_OS_WINDOWS
+}
+
+#if GTEST_OS_WINDOWS
+TEST(DirectoryTest, RootOfWrongDriveDoesNotExists) {
+  const int saved_drive_ = _getdrive();
+  // Find a drive that doesn't exist. Start with 'Z' to avoid common ones.
+  for (char drive = 'Z'; drive >= 'A'; drive--)
+    if (_chdrive(drive - 'A' + 1) == -1) {
+      char non_drive[_MAX_PATH];  // NOLINT
+      non_drive[0] = drive;
+      non_drive[1] = ':';
+      non_drive[2] = '\\';
+      non_drive[3] = '\0';
+      EXPECT_FALSE(FilePath(non_drive).DirectoryExists());
+      break;
+    }
+  _chdrive(saved_drive_);
+}
+#endif  // GTEST_OS_WINDOWS
+
+#if !GTEST_OS_WINDOWS_MOBILE
+// Windows CE _does_ consider an empty directory to exist.
+TEST(DirectoryTest, EmptyPathDirectoryDoesNotExist) {
+  EXPECT_FALSE(FilePath("").DirectoryExists());
+}
+#endif  // !GTEST_OS_WINDOWS_MOBILE
+
+TEST(DirectoryTest, CurrentDirectoryExists) {
+#if GTEST_OS_WINDOWS  // We are on Windows.
+#ifndef _WIN32_CE  // Windows CE doesn't have a current directory.
+  EXPECT_TRUE(FilePath(".").DirectoryExists());
+  EXPECT_TRUE(FilePath(".\\").DirectoryExists());
+#endif  // _WIN32_CE
+#else
+  EXPECT_TRUE(FilePath(".").DirectoryExists());
+  EXPECT_TRUE(FilePath("./").DirectoryExists());
+#endif  // GTEST_OS_WINDOWS
+}
+
+TEST(NormalizeTest, NullStringsEqualEmptyDirectory) {
+  EXPECT_STREQ("", FilePath(NULL).c_str());
+  EXPECT_STREQ("", FilePath(String(NULL)).c_str());
+}
+
+// "foo/bar" == foo//bar" == "foo///bar"
+TEST(NormalizeTest, MultipleConsecutiveSepaparatorsInMidstring) {
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar",
+               FilePath("foo" GTEST_PATH_SEP_ "bar").c_str());
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar",
+               FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str());
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_ "bar",
+               FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_
+                        GTEST_PATH_SEP_ "bar").c_str());
+}
+
+// "/bar" == //bar" == "///bar"
+TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringStart) {
+  EXPECT_STREQ(GTEST_PATH_SEP_ "bar",
+    FilePath(GTEST_PATH_SEP_ "bar").c_str());
+  EXPECT_STREQ(GTEST_PATH_SEP_ "bar",
+    FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str());
+  EXPECT_STREQ(GTEST_PATH_SEP_ "bar",
+    FilePath(GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_ "bar").c_str());
+}
+
+// "foo/" == foo//" == "foo///"
+TEST(NormalizeTest, MultipleConsecutiveSepaparatorsAtStringEnd) {
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_,
+    FilePath("foo" GTEST_PATH_SEP_).c_str());
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_,
+    FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_).c_str());
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_,
+    FilePath("foo" GTEST_PATH_SEP_ GTEST_PATH_SEP_ GTEST_PATH_SEP_).c_str());
+}
+
+#if GTEST_HAS_ALT_PATH_SEP_
+
+// Tests that separators at the end of the string are normalized
+// regardless of their combination (e.g. "foo\" =="foo/\" ==
+// "foo\\/").
+TEST(NormalizeTest, MixAlternateSeparatorAtStringEnd) {
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_,
+               FilePath("foo/").c_str());
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_,
+               FilePath("foo" GTEST_PATH_SEP_ "/").c_str());
+  EXPECT_STREQ("foo" GTEST_PATH_SEP_,
+               FilePath("foo//" GTEST_PATH_SEP_).c_str());
+}
+
+#endif
+
+TEST(AssignmentOperatorTest, DefaultAssignedToNonDefault) {
+  FilePath default_path;
+  FilePath non_default_path("path");
+  non_default_path = default_path;
+  EXPECT_STREQ("", non_default_path.c_str());
+  EXPECT_STREQ("", default_path.c_str());  // RHS var is unchanged.
+}
+
+TEST(AssignmentOperatorTest, NonDefaultAssignedToDefault) {
+  FilePath non_default_path("path");
+  FilePath default_path;
+  default_path = non_default_path;
+  EXPECT_STREQ("path", default_path.c_str());
+  EXPECT_STREQ("path", non_default_path.c_str());  // RHS var is unchanged.
+}
+
+TEST(AssignmentOperatorTest, ConstAssignedToNonConst) {
+  const FilePath const_default_path("const_path");
+  FilePath non_default_path("path");
+  non_default_path = const_default_path;
+  EXPECT_STREQ("const_path", non_default_path.c_str());
+}
+
+class DirectoryCreationTest : public Test {
+ protected:
+  virtual void SetUp() {
+    testdata_path_.Set(FilePath(String::Format("%s%s%s",
+        TempDir().c_str(), GetCurrentExecutableName().c_str(),
+        "_directory_creation" GTEST_PATH_SEP_ "test" GTEST_PATH_SEP_)));
+    testdata_file_.Set(testdata_path_.RemoveTrailingPathSeparator());
+
+    unique_file0_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"),
+        0, "txt"));
+    unique_file1_.Set(FilePath::MakeFileName(testdata_path_, FilePath("unique"),
+        1, "txt"));
+
+    remove(testdata_file_.c_str());
+    remove(unique_file0_.c_str());
+    remove(unique_file1_.c_str());
+    posix::RmDir(testdata_path_.c_str());
+  }
+
+  virtual void TearDown() {
+    remove(testdata_file_.c_str());
+    remove(unique_file0_.c_str());
+    remove(unique_file1_.c_str());
+    posix::RmDir(testdata_path_.c_str());
+  }
+
+  String TempDir() const {
+#if GTEST_OS_WINDOWS_MOBILE
+    return String("\\temp\\");
+#elif GTEST_OS_WINDOWS
+    const char* temp_dir = posix::GetEnv("TEMP");
+    if (temp_dir == NULL || temp_dir[0] == '\0')
+      return String("\\temp\\");
+    else if (String(temp_dir).EndsWith("\\"))
+      return String(temp_dir);
+    else
+      return String::Format("%s\\", temp_dir);
+#else
+    return String("/tmp/");
+#endif  // GTEST_OS_WINDOWS_MOBILE
+  }
+
+  void CreateTextFile(const char* filename) {
+    FILE* f = posix::FOpen(filename, "w");
+    fprintf(f, "text\n");
+    fclose(f);
+  }
+
+  // Strings representing a directory and a file, with identical paths
+  // except for the trailing separator character that distinquishes
+  // a directory named 'test' from a file named 'test'. Example names:
+  FilePath testdata_path_;  // "/tmp/directory_creation/test/"
+  FilePath testdata_file_;  // "/tmp/directory_creation/test"
+  FilePath unique_file0_;  // "/tmp/directory_creation/test/unique.txt"
+  FilePath unique_file1_;  // "/tmp/directory_creation/test/unique_1.txt"
+};
+
+TEST_F(DirectoryCreationTest, CreateDirectoriesRecursively) {
+  EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.c_str();
+  EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
+  EXPECT_TRUE(testdata_path_.DirectoryExists());
+}
+
+TEST_F(DirectoryCreationTest, CreateDirectoriesForAlreadyExistingPath) {
+  EXPECT_FALSE(testdata_path_.DirectoryExists()) << testdata_path_.c_str();
+  EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
+  // Call 'create' again... should still succeed.
+  EXPECT_TRUE(testdata_path_.CreateDirectoriesRecursively());
+}
+
+TEST_F(DirectoryCreationTest, CreateDirectoriesAndUniqueFilename) {
+  FilePath file_path(FilePath::GenerateUniqueFileName(testdata_path_,
+      FilePath("unique"), "txt"));
+  EXPECT_STREQ(unique_file0_.c_str(), file_path.c_str());
+  EXPECT_FALSE(file_path.FileOrDirectoryExists());  // file not there
+
+  testdata_path_.CreateDirectoriesRecursively();
+  EXPECT_FALSE(file_path.FileOrDirectoryExists());  // file still not there
+  CreateTextFile(file_path.c_str());
+  EXPECT_TRUE(file_path.FileOrDirectoryExists());
+
+  FilePath file_path2(FilePath::GenerateUniqueFileName(testdata_path_,
+      FilePath("unique"), "txt"));
+  EXPECT_STREQ(unique_file1_.c_str(), file_path2.c_str());
+  EXPECT_FALSE(file_path2.FileOrDirectoryExists());  // file not there
+  CreateTextFile(file_path2.c_str());
+  EXPECT_TRUE(file_path2.FileOrDirectoryExists());
+}
+
+TEST_F(DirectoryCreationTest, CreateDirectoriesFail) {
+  // force a failure by putting a file where we will try to create a directory.
+  CreateTextFile(testdata_file_.c_str());
+  EXPECT_TRUE(testdata_file_.FileOrDirectoryExists());
+  EXPECT_FALSE(testdata_file_.DirectoryExists());
+  EXPECT_FALSE(testdata_file_.CreateDirectoriesRecursively());
+}
+
+TEST(NoDirectoryCreationTest, CreateNoDirectoriesForDefaultXmlFile) {
+  const FilePath test_detail_xml("test_detail.xml");
+  EXPECT_FALSE(test_detail_xml.CreateDirectoriesRecursively());
+}
+
+TEST(FilePathTest, DefaultConstructor) {
+  FilePath fp;
+  EXPECT_STREQ("", fp.c_str());
+}
+
+TEST(FilePathTest, CharAndCopyConstructors) {
+  const FilePath fp("spicy");
+  EXPECT_STREQ("spicy", fp.c_str());
+
+  const FilePath fp_copy(fp);
+  EXPECT_STREQ("spicy", fp_copy.c_str());
+}
+
+TEST(FilePathTest, StringConstructor) {
+  const FilePath fp(String("cider"));
+  EXPECT_STREQ("cider", fp.c_str());
+}
+
+TEST(FilePathTest, Set) {
+  const FilePath apple("apple");
+  FilePath mac("mac");
+  mac.Set(apple);  // Implement Set() since overloading operator= is forbidden.
+  EXPECT_STREQ("apple", mac.c_str());
+  EXPECT_STREQ("apple", apple.c_str());
+}
+
+TEST(FilePathTest, ToString) {
+  const FilePath file("drink");
+  String str(file.ToString());
+  EXPECT_STREQ("drink", str.c_str());
+}
+
+TEST(FilePathTest, RemoveExtension) {
+  EXPECT_STREQ("app", FilePath("app.exe").RemoveExtension("exe").c_str());
+  EXPECT_STREQ("APP", FilePath("APP.EXE").RemoveExtension("exe").c_str());
+}
+
+TEST(FilePathTest, RemoveExtensionWhenThereIsNoExtension) {
+  EXPECT_STREQ("app", FilePath("app").RemoveExtension("exe").c_str());
+}
+
+TEST(FilePathTest, IsDirectory) {
+  EXPECT_FALSE(FilePath("cola").IsDirectory());
+  EXPECT_TRUE(FilePath("koala" GTEST_PATH_SEP_).IsDirectory());
+#if GTEST_HAS_ALT_PATH_SEP_
+  EXPECT_TRUE(FilePath("koala/").IsDirectory());
+#endif
+}
+
+TEST(FilePathTest, IsAbsolutePath) {
+  EXPECT_FALSE(FilePath("is" GTEST_PATH_SEP_ "relative").IsAbsolutePath());
+  EXPECT_FALSE(FilePath("").IsAbsolutePath());
+#if GTEST_OS_WINDOWS
+  EXPECT_TRUE(FilePath("c:\\" GTEST_PATH_SEP_ "is_not"
+                       GTEST_PATH_SEP_ "relative").IsAbsolutePath());
+  EXPECT_FALSE(FilePath("c:foo" GTEST_PATH_SEP_ "bar").IsAbsolutePath());
+  EXPECT_TRUE(FilePath("c:/" GTEST_PATH_SEP_ "is_not"
+                       GTEST_PATH_SEP_ "relative").IsAbsolutePath());
+#else
+  EXPECT_TRUE(FilePath(GTEST_PATH_SEP_ "is_not" GTEST_PATH_SEP_ "relative")
+              .IsAbsolutePath());
+#endif  // GTEST_OS_WINDOWS
+}
+
+TEST(FilePathTest, IsRootDirectory) {
+#if GTEST_OS_WINDOWS
+  EXPECT_TRUE(FilePath("a:\\").IsRootDirectory());
+  EXPECT_TRUE(FilePath("Z:/").IsRootDirectory());
+  EXPECT_TRUE(FilePath("e://").IsRootDirectory());
+  EXPECT_FALSE(FilePath("").IsRootDirectory());
+  EXPECT_FALSE(FilePath("b:").IsRootDirectory());
+  EXPECT_FALSE(FilePath("b:a").IsRootDirectory());
+  EXPECT_FALSE(FilePath("8:/").IsRootDirectory());
+  EXPECT_FALSE(FilePath("c|/").IsRootDirectory());
+#else
+  EXPECT_TRUE(FilePath("/").IsRootDirectory());
+  EXPECT_TRUE(FilePath("//").IsRootDirectory());
+  EXPECT_FALSE(FilePath("").IsRootDirectory());
+  EXPECT_FALSE(FilePath("\\").IsRootDirectory());
+  EXPECT_FALSE(FilePath("/x").IsRootDirectory());
+#endif
+}
+
+}  // namespace
+}  // namespace internal
+}  // namespace testing
diff --git a/protobuf/gtest/test/gtest-linked_ptr_test.cc b/protobuf/gtest/test/gtest-linked_ptr_test.cc
new file mode 100644
index 0000000..eae8229
--- /dev/null
+++ b/protobuf/gtest/test/gtest-linked_ptr_test.cc
@@ -0,0 +1,154 @@
+// Copyright 2003, 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: Dan Egnor (egnor@google.com)
+// Ported to Windows: Vadim Berman (vadimb@google.com)
+
+#include <gtest/internal/gtest-linked_ptr.h>
+
+#include <stdlib.h>
+#include <gtest/gtest.h>
+
+namespace {
+
+using testing::Message;
+using testing::internal::linked_ptr;
+
+int num;
+Message* history = NULL;
+
+// Class which tracks allocation/deallocation
+class A {
+ public:
+  A(): mynum(num++) { *history << "A" << mynum << " ctor\n"; }
+  virtual ~A() { *history << "A" << mynum << " dtor\n"; }
+  virtual void Use() { *history << "A" << mynum << " use\n"; }
+ protected:
+  int mynum;
+};
+
+// Subclass
+class B : public A {
+ public:
+  B() { *history << "B" << mynum << " ctor\n"; }
+  ~B() { *history << "B" << mynum << " dtor\n"; }
+  virtual void Use() { *history << "B" << mynum << " use\n"; }
+};
+
+class LinkedPtrTest : public testing::Test {
+ public:
+  LinkedPtrTest() {
+    num = 0;
+    history = new Message;
+  }
+
+  virtual ~LinkedPtrTest() {
+    delete history;
+    history = NULL;
+  }
+};
+
+TEST_F(LinkedPtrTest, GeneralTest) {
+  {
+    linked_ptr<A> a0, a1, a2;
+    a0 = a0;
+    a1 = a2;
+    ASSERT_EQ(a0.get(), static_cast<A*>(NULL));
+    ASSERT_EQ(a1.get(), static_cast<A*>(NULL));
+    ASSERT_EQ(a2.get(), static_cast<A*>(NULL));
+    ASSERT_TRUE(a0 == NULL);
+    ASSERT_TRUE(a1 == NULL);
+    ASSERT_TRUE(a2 == NULL);
+
+    {
+      linked_ptr<A> a3(new A);
+      a0 = a3;
+      ASSERT_TRUE(a0 == a3);
+      ASSERT_TRUE(a0 != NULL);
+      ASSERT_TRUE(a0.get() == a3);
+      ASSERT_TRUE(a0 == a3.get());
+      linked_ptr<A> a4(a0);
+      a1 = a4;
+      linked_ptr<A> a5(new A);
+      ASSERT_TRUE(a5.get() != a3);
+      ASSERT_TRUE(a5 != a3.get());
+      a2 = a5;
+      linked_ptr<B> b0(new B);
+      linked_ptr<A> a6(b0);
+      ASSERT_TRUE(b0 == a6);
+      ASSERT_TRUE(a6 == b0);
+      ASSERT_TRUE(b0 != NULL);
+      a5 = b0;
+      a5 = b0;
+      a3->Use();
+      a4->Use();
+      a5->Use();
+      a6->Use();
+      b0->Use();
+      (*b0).Use();
+      b0.get()->Use();
+    }
+
+    a0->Use();
+    a1->Use();
+    a2->Use();
+
+    a1 = a2;
+    a2.reset(new A);
+    a0.reset();
+
+    linked_ptr<A> a7;
+  }
+
+  ASSERT_STREQ(
+    "A0 ctor\n"
+    "A1 ctor\n"
+    "A2 ctor\n"
+    "B2 ctor\n"
+    "A0 use\n"
+    "A0 use\n"
+    "B2 use\n"
+    "B2 use\n"
+    "B2 use\n"
+    "B2 use\n"
+    "B2 use\n"
+    "B2 dtor\n"
+    "A2 dtor\n"
+    "A0 use\n"
+    "A0 use\n"
+    "A1 use\n"
+    "A3 ctor\n"
+    "A0 dtor\n"
+    "A3 dtor\n"
+    "A1 dtor\n",
+    history->GetString().c_str()
+  );
+}
+
+}  // Unnamed namespace
diff --git a/protobuf/gtest/test/gtest-listener_test.cc b/protobuf/gtest/test/gtest-listener_test.cc
new file mode 100644
index 0000000..c9be39a
--- /dev/null
+++ b/protobuf/gtest/test/gtest-listener_test.cc
@@ -0,0 +1,313 @@
+// Copyright 2009 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: vladl@google.com (Vlad Losev)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This file verifies Google Test event listeners receive events at the
+// right times.
+
+#include <gtest/gtest.h>
+#include <vector>
+
+using ::testing::AddGlobalTestEnvironment;
+using ::testing::Environment;
+using ::testing::InitGoogleTest;
+using ::testing::Test;
+using ::testing::TestCase;
+using ::testing::TestEventListener;
+using ::testing::TestInfo;
+using ::testing::TestPartResult;
+using ::testing::UnitTest;
+using ::testing::internal::String;
+
+// Used by tests to register their events.
+std::vector<String>* g_events = NULL;
+
+namespace testing {
+namespace internal {
+
+class EventRecordingListener : public TestEventListener {
+ public:
+  EventRecordingListener(const char* name) : name_(name) {}
+
+ protected:
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
+    g_events->push_back(GetFullMethodName("OnTestProgramStart"));
+  }
+
+  virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
+                                    int iteration) {
+    Message message;
+    message << GetFullMethodName("OnTestIterationStart")
+            << "(" << iteration << ")";
+    g_events->push_back(message.GetString());
+  }
+
+  virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {
+    g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpStart"));
+  }
+
+  virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {
+    g_events->push_back(GetFullMethodName("OnEnvironmentsSetUpEnd"));
+  }
+
+  virtual void OnTestCaseStart(const TestCase& /*test_case*/) {
+    g_events->push_back(GetFullMethodName("OnTestCaseStart"));
+  }
+
+  virtual void OnTestStart(const TestInfo& /*test_info*/) {
+    g_events->push_back(GetFullMethodName("OnTestStart"));
+  }
+
+  virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {
+    g_events->push_back(GetFullMethodName("OnTestPartResult"));
+  }
+
+  virtual void OnTestEnd(const TestInfo& /*test_info*/) {
+    g_events->push_back(GetFullMethodName("OnTestEnd"));
+  }
+
+  virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {
+    g_events->push_back(GetFullMethodName("OnTestCaseEnd"));
+  }
+
+  virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {
+    g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownStart"));
+  }
+
+  virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {
+    g_events->push_back(GetFullMethodName("OnEnvironmentsTearDownEnd"));
+  }
+
+  virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
+                                  int iteration) {
+    Message message;
+    message << GetFullMethodName("OnTestIterationEnd")
+            << "("  << iteration << ")";
+    g_events->push_back(message.GetString());
+  }
+
+  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {
+    g_events->push_back(GetFullMethodName("OnTestProgramEnd"));
+  }
+
+ private:
+  String GetFullMethodName(const char* name) {
+    Message message;
+    message << name_ << "." << name;
+    return message.GetString();
+  }
+
+  String name_;
+};
+
+class EnvironmentInvocationCatcher : public Environment {
+ protected:
+  virtual void SetUp() {
+    g_events->push_back(String("Environment::SetUp"));
+  }
+
+  virtual void TearDown() {
+    g_events->push_back(String("Environment::TearDown"));
+  }
+};
+
+class ListenerTest : public Test {
+ protected:
+  static void SetUpTestCase() {
+    g_events->push_back(String("ListenerTest::SetUpTestCase"));
+  }
+
+  static void TearDownTestCase() {
+    g_events->push_back(String("ListenerTest::TearDownTestCase"));
+  }
+
+  virtual void SetUp() {
+    g_events->push_back(String("ListenerTest::SetUp"));
+  }
+
+  virtual void TearDown() {
+    g_events->push_back(String("ListenerTest::TearDown"));
+  }
+};
+
+TEST_F(ListenerTest, DoesFoo) {
+  // Test execution order within a test case is not guaranteed so we are not
+  // recording the test name.
+  g_events->push_back(String("ListenerTest::* Test Body"));
+  SUCCEED();  // Triggers OnTestPartResult.
+}
+
+TEST_F(ListenerTest, DoesBar) {
+  g_events->push_back(String("ListenerTest::* Test Body"));
+  SUCCEED();  // Triggers OnTestPartResult.
+}
+
+}  // namespace internal
+
+}  // namespace testing
+
+using ::testing::internal::EnvironmentInvocationCatcher;
+using ::testing::internal::EventRecordingListener;
+
+void VerifyResults(const std::vector<String>& data,
+                   const char* const* expected_data,
+                   int expected_data_size) {
+  const int actual_size = data.size();
+  // If the following assertion fails, a new entry will be appended to
+  // data.  Hence we save data.size() first.
+  EXPECT_EQ(expected_data_size, actual_size);
+
+  // Compares the common prefix.
+  const int shorter_size = expected_data_size <= actual_size ?
+      expected_data_size : actual_size;
+  int i = 0;
+  for (; i < shorter_size; ++i) {
+    ASSERT_STREQ(expected_data[i], data[i].c_str())
+        << "at position " << i;
+  }
+
+  // Prints extra elements in the actual data.
+  for (; i < actual_size; ++i) {
+    printf("  Actual event #%d: %s\n", i, data[i].c_str());
+  }
+}
+
+int main(int argc, char **argv) {
+  std::vector<String> events;
+  g_events = &events;
+  InitGoogleTest(&argc, argv);
+
+  UnitTest::GetInstance()->listeners().Append(
+      new EventRecordingListener("1st"));
+  UnitTest::GetInstance()->listeners().Append(
+      new EventRecordingListener("2nd"));
+
+  AddGlobalTestEnvironment(new EnvironmentInvocationCatcher);
+
+  GTEST_CHECK_(events.size() == 0)
+      << "AddGlobalTestEnvironment should not generate any events itself.";
+
+  ::testing::GTEST_FLAG(repeat) = 2;
+  int ret_val = RUN_ALL_TESTS();
+
+  const char* const expected_events[] = {
+    "1st.OnTestProgramStart",
+    "2nd.OnTestProgramStart",
+    "1st.OnTestIterationStart(0)",
+    "2nd.OnTestIterationStart(0)",
+    "1st.OnEnvironmentsSetUpStart",
+    "2nd.OnEnvironmentsSetUpStart",
+    "Environment::SetUp",
+    "2nd.OnEnvironmentsSetUpEnd",
+    "1st.OnEnvironmentsSetUpEnd",
+    "1st.OnTestCaseStart",
+    "2nd.OnTestCaseStart",
+    "ListenerTest::SetUpTestCase",
+    "1st.OnTestStart",
+    "2nd.OnTestStart",
+    "ListenerTest::SetUp",
+    "ListenerTest::* Test Body",
+    "1st.OnTestPartResult",
+    "2nd.OnTestPartResult",
+    "ListenerTest::TearDown",
+    "2nd.OnTestEnd",
+    "1st.OnTestEnd",
+    "1st.OnTestStart",
+    "2nd.OnTestStart",
+    "ListenerTest::SetUp",
+    "ListenerTest::* Test Body",
+    "1st.OnTestPartResult",
+    "2nd.OnTestPartResult",
+    "ListenerTest::TearDown",
+    "2nd.OnTestEnd",
+    "1st.OnTestEnd",
+    "ListenerTest::TearDownTestCase",
+    "2nd.OnTestCaseEnd",
+    "1st.OnTestCaseEnd",
+    "1st.OnEnvironmentsTearDownStart",
+    "2nd.OnEnvironmentsTearDownStart",
+    "Environment::TearDown",
+    "2nd.OnEnvironmentsTearDownEnd",
+    "1st.OnEnvironmentsTearDownEnd",
+    "2nd.OnTestIterationEnd(0)",
+    "1st.OnTestIterationEnd(0)",
+    "1st.OnTestIterationStart(1)",
+    "2nd.OnTestIterationStart(1)",
+    "1st.OnEnvironmentsSetUpStart",
+    "2nd.OnEnvironmentsSetUpStart",
+    "Environment::SetUp",
+    "2nd.OnEnvironmentsSetUpEnd",
+    "1st.OnEnvironmentsSetUpEnd",
+    "1st.OnTestCaseStart",
+    "2nd.OnTestCaseStart",
+    "ListenerTest::SetUpTestCase",
+    "1st.OnTestStart",
+    "2nd.OnTestStart",
+    "ListenerTest::SetUp",
+    "ListenerTest::* Test Body",
+    "1st.OnTestPartResult",
+    "2nd.OnTestPartResult",
+    "ListenerTest::TearDown",
+    "2nd.OnTestEnd",
+    "1st.OnTestEnd",
+    "1st.OnTestStart",
+    "2nd.OnTestStart",
+    "ListenerTest::SetUp",
+    "ListenerTest::* Test Body",
+    "1st.OnTestPartResult",
+    "2nd.OnTestPartResult",
+    "ListenerTest::TearDown",
+    "2nd.OnTestEnd",
+    "1st.OnTestEnd",
+    "ListenerTest::TearDownTestCase",
+    "2nd.OnTestCaseEnd",
+    "1st.OnTestCaseEnd",
+    "1st.OnEnvironmentsTearDownStart",
+    "2nd.OnEnvironmentsTearDownStart",
+    "Environment::TearDown",
+    "2nd.OnEnvironmentsTearDownEnd",
+    "1st.OnEnvironmentsTearDownEnd",
+    "2nd.OnTestIterationEnd(1)",
+    "1st.OnTestIterationEnd(1)",
+    "2nd.OnTestProgramEnd",
+    "1st.OnTestProgramEnd"
+  };
+  VerifyResults(events,
+                expected_events,
+                sizeof(expected_events)/sizeof(expected_events[0]));
+
+  // We need to check manually for ad hoc test failures that happen after
+  // RUN_ALL_TESTS finishes.
+  if (UnitTest::GetInstance()->Failed())
+    ret_val = 1;
+
+  return ret_val;
+}
diff --git a/protobuf/gtest/test/gtest-message_test.cc b/protobuf/gtest/test/gtest-message_test.cc
new file mode 100644
index 0000000..e42b034
--- /dev/null
+++ b/protobuf/gtest/test/gtest-message_test.cc
@@ -0,0 +1,167 @@
+// 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)
+//
+// Tests for the Message class.
+
+#include <gtest/gtest-message.h>
+
+#include <gtest/gtest.h>
+
+namespace {
+
+using ::testing::Message;
+using ::testing::internal::StrStream;
+
+// A helper function that turns a Message into a C string.
+const char* ToCString(const Message& msg) {
+  static testing::internal::String result;
+  result = msg.GetString();
+  return result.c_str();
+}
+
+// Tests the testing::Message class
+
+// Tests the default constructor.
+TEST(MessageTest, DefaultConstructor) {
+  const Message msg;
+  EXPECT_STREQ("", ToCString(msg));
+}
+
+// Tests the copy constructor.
+TEST(MessageTest, CopyConstructor) {
+  const Message msg1("Hello");
+  const Message msg2(msg1);
+  EXPECT_STREQ("Hello", ToCString(msg2));
+}
+
+// Tests constructing a Message from a C-string.
+TEST(MessageTest, ConstructsFromCString) {
+  Message msg("Hello");
+  EXPECT_STREQ("Hello", ToCString(msg));
+}
+
+// Tests streaming a float.
+TEST(MessageTest, StreamsFloat) {
+  const char* const s = ToCString(Message() << 1.23456F << " " << 2.34567F);
+  // Both numbers should be printed with enough precision.
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, "1.234560", s);
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, " 2.345669", s);
+}
+
+// Tests streaming a double.
+TEST(MessageTest, StreamsDouble) {
+  const char* const s = ToCString(Message() << 1260570880.4555497 << " "
+                                  << 1260572265.1954534);
+  // Both numbers should be printed with enough precision.
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, "1260570880.45", s);
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, " 1260572265.19", s);
+}
+
+// Tests streaming a non-char pointer.
+TEST(MessageTest, StreamsPointer) {
+  int n = 0;
+  int* p = &n;
+  EXPECT_STRNE("(null)", ToCString(Message() << p));
+}
+
+// Tests streaming a NULL non-char pointer.
+TEST(MessageTest, StreamsNullPointer) {
+  int* p = NULL;
+  EXPECT_STREQ("(null)", ToCString(Message() << p));
+}
+
+// Tests streaming a C string.
+TEST(MessageTest, StreamsCString) {
+  EXPECT_STREQ("Foo", ToCString(Message() << "Foo"));
+}
+
+// Tests streaming a NULL C string.
+TEST(MessageTest, StreamsNullCString) {
+  char* p = NULL;
+  EXPECT_STREQ("(null)", ToCString(Message() << p));
+}
+
+// Tests streaming std::string.
+TEST(MessageTest, StreamsString) {
+  const ::std::string str("Hello");
+  EXPECT_STREQ("Hello", ToCString(Message() << str));
+}
+
+// Tests that we can output strings containing embedded NULs.
+TEST(MessageTest, StreamsStringWithEmbeddedNUL) {
+  const char char_array_with_nul[] =
+      "Here's a NUL\0 and some more string";
+  const ::std::string string_with_nul(char_array_with_nul,
+                                      sizeof(char_array_with_nul) - 1);
+  EXPECT_STREQ("Here's a NUL\\0 and some more string",
+               ToCString(Message() << string_with_nul));
+}
+
+// Tests streaming a NUL char.
+TEST(MessageTest, StreamsNULChar) {
+  EXPECT_STREQ("\\0", ToCString(Message() << '\0'));
+}
+
+// Tests streaming int.
+TEST(MessageTest, StreamsInt) {
+  EXPECT_STREQ("123", ToCString(Message() << 123));
+}
+
+// Tests that basic IO manipulators (endl, ends, and flush) can be
+// streamed to Message.
+TEST(MessageTest, StreamsBasicIoManip) {
+  EXPECT_STREQ("Line 1.\nA NUL char \\0 in line 2.",
+               ToCString(Message() << "Line 1." << std::endl
+                         << "A NUL char " << std::ends << std::flush
+                         << " in line 2."));
+}
+
+// Tests Message::GetString()
+TEST(MessageTest, GetString) {
+  Message msg;
+  msg << 1 << " lamb";
+  EXPECT_STREQ("1 lamb", msg.GetString().c_str());
+}
+
+// Tests streaming a Message object to an ostream.
+TEST(MessageTest, StreamsToOStream) {
+  Message msg("Hello");
+  StrStream ss;
+  ss << msg;
+  EXPECT_STREQ("Hello", testing::internal::StrStreamToString(&ss).c_str());
+}
+
+// Tests that a Message object doesn't take up too much stack space.
+TEST(MessageTest, DoesNotTakeUpMuchStackSpace) {
+  EXPECT_LE(sizeof(Message), 16U);
+}
+
+}  // namespace
diff --git a/protobuf/gtest/test/gtest-options_test.cc b/protobuf/gtest/test/gtest-options_test.cc
new file mode 100644
index 0000000..2e2cbc9
--- /dev/null
+++ b/protobuf/gtest/test/gtest-options_test.cc
@@ -0,0 +1,212 @@
+// 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)
+//
+// Google Test UnitTestOptions tests
+//
+// This file tests classes and functions used internally by
+// Google Test.  They are subject to change without notice.
+//
+// This file is #included from gtest.cc, to avoid changing build or
+// make-files on Windows and other platforms. Do not #include this file
+// anywhere else!
+
+#include <gtest/gtest.h>
+
+#if GTEST_OS_WINDOWS_MOBILE
+#include <windows.h>
+#elif GTEST_OS_WINDOWS
+#include <direct.h>
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+// 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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+namespace internal {
+namespace {
+
+// Turns the given relative path into an absolute path.
+FilePath GetAbsolutePathOf(const FilePath& relative_path) {
+  return FilePath::ConcatPaths(FilePath::GetCurrentDir(), relative_path);
+}
+
+// Testing UnitTestOptions::GetOutputFormat/GetOutputFile.
+
+TEST(XmlOutputTest, GetOutputFormatDefault) {
+  GTEST_FLAG(output) = "";
+  EXPECT_STREQ("", UnitTestOptions::GetOutputFormat().c_str());
+}
+
+TEST(XmlOutputTest, GetOutputFormat) {
+  GTEST_FLAG(output) = "xml:filename";
+  EXPECT_STREQ("xml", UnitTestOptions::GetOutputFormat().c_str());
+}
+
+TEST(XmlOutputTest, GetOutputFileDefault) {
+  GTEST_FLAG(output) = "";
+  EXPECT_STREQ(GetAbsolutePathOf(FilePath("test_detail.xml")).c_str(),
+               UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
+}
+
+TEST(XmlOutputTest, GetOutputFileSingleFile) {
+  GTEST_FLAG(output) = "xml:filename.abc";
+  EXPECT_STREQ(GetAbsolutePathOf(FilePath("filename.abc")).c_str(),
+               UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
+}
+
+TEST(XmlOutputTest, GetOutputFileFromDirectoryPath) {
+  GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_;
+  const std::string expected_output_file =
+      GetAbsolutePathOf(
+          FilePath(std::string("path") + GTEST_PATH_SEP_ +
+                   GetCurrentExecutableName().c_str() + ".xml")).c_str();
+  const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile();
+#if GTEST_OS_WINDOWS
+  EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
+#else
+  EXPECT_EQ(expected_output_file, output_file.c_str());
+#endif
+}
+
+TEST(OutputFileHelpersTest, GetCurrentExecutableName) {
+  const std::string exe_str = GetCurrentExecutableName().c_str();
+#if GTEST_OS_WINDOWS
+  const bool success =
+      _strcmpi("gtest-options_test", exe_str.c_str()) == 0 ||
+      _strcmpi("gtest-options-ex_test", exe_str.c_str()) == 0 ||
+      _strcmpi("gtest_all_test", exe_str.c_str()) == 0 ||
+      _strcmpi("gtest_dll_test", exe_str.c_str()) == 0;
+#else
+  // TODO(wan@google.com): remove the hard-coded "lt-" prefix when
+  //   Chandler Carruth's libtool replacement is ready.
+  const bool success =
+      exe_str == "gtest-options_test" ||
+      exe_str == "gtest_all_test" ||
+      exe_str == "lt-gtest_all_test" ||
+      exe_str == "gtest_dll_test";
+#endif  // GTEST_OS_WINDOWS
+  if (!success)
+    FAIL() << "GetCurrentExecutableName() returns " << exe_str;
+}
+
+class XmlOutputChangeDirTest : public Test {
+ protected:
+  virtual void SetUp() {
+    original_working_dir_ = FilePath::GetCurrentDir();
+    posix::ChDir("..");
+    // This will make the test fail if run from the root directory.
+    EXPECT_STRNE(original_working_dir_.c_str(),
+                 FilePath::GetCurrentDir().c_str());
+  }
+
+  virtual void TearDown() {
+    posix::ChDir(original_working_dir_.c_str());
+  }
+
+  FilePath original_working_dir_;
+};
+
+TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefault) {
+  GTEST_FLAG(output) = "";
+  EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_,
+                                     FilePath("test_detail.xml")).c_str(),
+               UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
+}
+
+TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithDefaultXML) {
+  GTEST_FLAG(output) = "xml";
+  EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_,
+                                     FilePath("test_detail.xml")).c_str(),
+               UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
+}
+
+TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativeFile) {
+  GTEST_FLAG(output) = "xml:filename.abc";
+  EXPECT_STREQ(FilePath::ConcatPaths(original_working_dir_,
+                                     FilePath("filename.abc")).c_str(),
+               UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
+}
+
+TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithRelativePath) {
+  GTEST_FLAG(output) = "xml:path" GTEST_PATH_SEP_;
+  const std::string expected_output_file =
+      FilePath::ConcatPaths(
+          original_working_dir_,
+          FilePath(std::string("path") + GTEST_PATH_SEP_ +
+                   GetCurrentExecutableName().c_str() + ".xml")).c_str();
+  const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile();
+#if GTEST_OS_WINDOWS
+  EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
+#else
+  EXPECT_EQ(expected_output_file, output_file.c_str());
+#endif
+}
+
+TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsoluteFile) {
+#if GTEST_OS_WINDOWS
+  GTEST_FLAG(output) = "xml:c:\\tmp\\filename.abc";
+  EXPECT_STREQ(FilePath("c:\\tmp\\filename.abc").c_str(),
+               UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
+#else
+  GTEST_FLAG(output) ="xml:/tmp/filename.abc";
+  EXPECT_STREQ(FilePath("/tmp/filename.abc").c_str(),
+               UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
+#endif
+}
+
+TEST_F(XmlOutputChangeDirTest, PreserveOriginalWorkingDirWithAbsolutePath) {
+#if GTEST_OS_WINDOWS
+  const std::string path = "c:\\tmp\\";
+#else
+  const std::string path = "/tmp/";
+#endif
+
+  GTEST_FLAG(output) = "xml:" + path;
+  const std::string expected_output_file =
+      path + GetCurrentExecutableName().c_str() + ".xml";
+  const String& output_file = UnitTestOptions::GetAbsolutePathToOutputFile();
+
+#if GTEST_OS_WINDOWS
+  EXPECT_STRCASEEQ(expected_output_file.c_str(), output_file.c_str());
+#else
+  EXPECT_EQ(expected_output_file, output_file.c_str());
+#endif
+}
+
+}  // namespace
+}  // namespace internal
+}  // namespace testing
diff --git a/protobuf/gtest/test/gtest-param-test2_test.cc b/protobuf/gtest/test/gtest-param-test2_test.cc
new file mode 100644
index 0000000..ccb6cfa
--- /dev/null
+++ b/protobuf/gtest/test/gtest-param-test2_test.cc
@@ -0,0 +1,65 @@
+// 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: vladl@google.com (Vlad Losev)
+//
+// Tests for Google Test itself.  This verifies that the basic constructs of
+// Google Test work.
+
+#include <gtest/gtest.h>
+
+#include "test/gtest-param-test_test.h"
+
+#if GTEST_HAS_PARAM_TEST
+
+using ::testing::Values;
+using ::testing::internal::ParamGenerator;
+
+// Tests that generators defined in a different translation unit
+// are functional. The test using extern_gen is defined
+// in gtest-param-test_test.cc.
+ParamGenerator<int> extern_gen = Values(33);
+
+// Tests that a parameterized test case can be defined in one translation unit
+// and instantiated in another. The test is defined in gtest-param-test_test.cc
+// and ExternalInstantiationTest fixture class is defined in
+// gtest-param-test_test.h.
+INSTANTIATE_TEST_CASE_P(MultiplesOf33,
+                        ExternalInstantiationTest,
+                        Values(33, 66));
+
+// Tests that a parameterized test case can be instantiated
+// in multiple translation units. Another instantiation is defined
+// in gtest-param-test_test.cc and InstantiationInMultipleTranslaionUnitsTest
+// fixture is defined in gtest-param-test_test.h
+INSTANTIATE_TEST_CASE_P(Sequence2,
+                        InstantiationInMultipleTranslaionUnitsTest,
+                        Values(42*3, 42*4, 42*5));
+
+#endif  // GTEST_HAS_PARAM_TEST
diff --git a/protobuf/gtest/test/gtest-param-test_test.cc b/protobuf/gtest/test/gtest-param-test_test.cc
new file mode 100644
index 0000000..d0a0e73
--- /dev/null
+++ b/protobuf/gtest/test/gtest-param-test_test.cc
@@ -0,0 +1,835 @@
+// 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: vladl@google.com (Vlad Losev)
+//
+// Tests for Google Test itself. This file verifies that the parameter
+// generators objects produce correct parameter sequences and that
+// Google Test runtime instantiates correct tests from those sequences.
+
+#include <gtest/gtest.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+#include <algorithm>
+#include <iostream>
+#include <list>
+#include <sstream>
+#include <string>
+#include <vector>
+
+// To include gtest-internal-inl.h.
+#define GTEST_IMPLEMENTATION_ 1
+#include "src/gtest-internal-inl.h"  // for UnitTestOptions
+#undef GTEST_IMPLEMENTATION_
+
+#include "test/gtest-param-test_test.h"
+
+using ::std::vector;
+using ::std::sort;
+
+using ::testing::AddGlobalTestEnvironment;
+using ::testing::Bool;
+using ::testing::Message;
+using ::testing::Range;
+using ::testing::TestWithParam;
+using ::testing::Values;
+using ::testing::ValuesIn;
+
+#if GTEST_HAS_COMBINE
+using ::testing::Combine;
+using ::std::tr1::get;
+using ::std::tr1::make_tuple;
+using ::std::tr1::tuple;
+#endif  // GTEST_HAS_COMBINE
+
+using ::testing::internal::ParamGenerator;
+using ::testing::internal::UnitTestOptions;
+
+// Prints a value to a string.
+//
+// TODO(wan@google.com): remove PrintValue() when we move matchers and
+// EXPECT_THAT() from Google Mock to Google Test.  At that time, we
+// can write EXPECT_THAT(x, Eq(y)) to compare two tuples x and y, as
+// EXPECT_THAT() and the matchers know how to print tuples.
+template <typename T>
+::std::string PrintValue(const T& value) {
+  ::std::stringstream stream;
+  stream << value;
+  return stream.str();
+}
+
+#if GTEST_HAS_COMBINE
+
+// These overloads allow printing tuples in our tests.  We cannot
+// define an operator<< for tuples, as that definition needs to be in
+// the std namespace in order to be picked up by Google Test via
+// Argument-Dependent Lookup, yet defining anything in the std
+// namespace in non-STL code is undefined behavior.
+
+template <typename T1, typename T2>
+::std::string PrintValue(const tuple<T1, T2>& value) {
+  ::std::stringstream stream;
+  stream << "(" << get<0>(value) << ", " << get<1>(value) << ")";
+  return stream.str();
+}
+
+template <typename T1, typename T2, typename T3>
+::std::string PrintValue(const tuple<T1, T2, T3>& value) {
+  ::std::stringstream stream;
+  stream << "(" << get<0>(value) << ", " << get<1>(value)
+         << ", "<< get<2>(value) << ")";
+  return stream.str();
+}
+
+template <typename T1, typename T2, typename T3, typename T4, typename T5,
+          typename T6, typename T7, typename T8, typename T9, typename T10>
+::std::string PrintValue(
+    const tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& value) {
+  ::std::stringstream stream;
+  stream << "(" << get<0>(value) << ", " << get<1>(value)
+         << ", "<< get<2>(value) << ", " << get<3>(value)
+         << ", "<< get<4>(value) << ", " << get<5>(value)
+         << ", "<< get<6>(value) << ", " << get<7>(value)
+         << ", "<< get<8>(value) << ", " << get<9>(value) << ")";
+  return stream.str();
+}
+
+#endif  // GTEST_HAS_COMBINE
+
+// Verifies that a sequence generated by the generator and accessed
+// via the iterator object matches the expected one using Google Test
+// assertions.
+template <typename T, size_t N>
+void VerifyGenerator(const ParamGenerator<T>& generator,
+                     const T (&expected_values)[N]) {
+  typename ParamGenerator<T>::iterator it = generator.begin();
+  for (size_t i = 0; i < N; ++i) {
+    ASSERT_FALSE(it == generator.end())
+        << "At element " << i << " when accessing via an iterator "
+        << "created with the copy constructor.\n";
+    // We cannot use EXPECT_EQ() here as the values may be tuples,
+    // which don't support <<.
+    EXPECT_TRUE(expected_values[i] == *it)
+        << "where i is " << i
+        << ", expected_values[i] is " << PrintValue(expected_values[i])
+        << ", *it is " << PrintValue(*it)
+        << ", and 'it' is an iterator created with the copy constructor.\n";
+    it++;
+  }
+  EXPECT_TRUE(it == generator.end())
+        << "At the presumed end of sequence when accessing via an iterator "
+        << "created with the copy constructor.\n";
+
+  // Test the iterator assignment. The following lines verify that
+  // the sequence accessed via an iterator initialized via the
+  // assignment operator (as opposed to a copy constructor) matches
+  // just the same.
+  it = generator.begin();
+  for (size_t i = 0; i < N; ++i) {
+    ASSERT_FALSE(it == generator.end())
+        << "At element " << i << " when accessing via an iterator "
+        << "created with the assignment operator.\n";
+    EXPECT_TRUE(expected_values[i] == *it)
+        << "where i is " << i
+        << ", expected_values[i] is " << PrintValue(expected_values[i])
+        << ", *it is " << PrintValue(*it)
+        << ", and 'it' is an iterator created with the copy constructor.\n";
+    it++;
+  }
+  EXPECT_TRUE(it == generator.end())
+        << "At the presumed end of sequence when accessing via an iterator "
+        << "created with the assignment operator.\n";
+}
+
+template <typename T>
+void VerifyGeneratorIsEmpty(const ParamGenerator<T>& generator) {
+  typename ParamGenerator<T>::iterator it = generator.begin();
+  EXPECT_TRUE(it == generator.end());
+
+  it = generator.begin();
+  EXPECT_TRUE(it == generator.end());
+}
+
+// Generator tests. They test that each of the provided generator functions
+// generates an expected sequence of values. The general test pattern
+// instantiates a generator using one of the generator functions,
+// checks the sequence produced by the generator using its iterator API,
+// and then resets the iterator back to the beginning of the sequence
+// and checks the sequence again.
+
+// Tests that iterators produced by generator functions conform to the
+// ForwardIterator concept.
+TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) {
+  const ParamGenerator<int> gen = Range(0, 10);
+  ParamGenerator<int>::iterator it = gen.begin();
+
+  // Verifies that iterator initialization works as expected.
+  ParamGenerator<int>::iterator it2 = it;
+  EXPECT_TRUE(*it == *it2) << "Initialized iterators must point to the "
+                           << "element same as its source points to";
+
+  // Verifies that iterator assignment works as expected.
+  it++;
+  EXPECT_FALSE(*it == *it2);
+  it2 = it;
+  EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the "
+                           << "element same as its source points to";
+
+  // Verifies that prefix operator++() returns *this.
+  EXPECT_EQ(&it, &(++it)) << "Result of the prefix operator++ must be "
+                          << "refer to the original object";
+
+  // Verifies that the result of the postfix operator++ points to the value
+  // pointed to by the original iterator.
+  int original_value = *it;  // Have to compute it outside of macro call to be
+                             // unaffected by the parameter evaluation order.
+  EXPECT_EQ(original_value, *(it++));
+
+  // Verifies that prefix and postfix operator++() advance an iterator
+  // all the same.
+  it2 = it;
+  it++;
+  ++it2;
+  EXPECT_TRUE(*it == *it2);
+}
+
+// Tests that Range() generates the expected sequence.
+TEST(RangeTest, IntRangeWithDefaultStep) {
+  const ParamGenerator<int> gen = Range(0, 3);
+  const int expected_values[] = {0, 1, 2};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Edge case. Tests that Range() generates the single element sequence
+// as expected when provided with range limits that are equal.
+TEST(RangeTest, IntRangeSingleValue) {
+  const ParamGenerator<int> gen = Range(0, 1);
+  const int expected_values[] = {0};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Edge case. Tests that Range() with generates empty sequence when
+// supplied with an empty range.
+TEST(RangeTest, IntRangeEmpty) {
+  const ParamGenerator<int> gen = Range(0, 0);
+  VerifyGeneratorIsEmpty(gen);
+}
+
+// Tests that Range() with custom step (greater then one) generates
+// the expected sequence.
+TEST(RangeTest, IntRangeWithCustomStep) {
+  const ParamGenerator<int> gen = Range(0, 9, 3);
+  const int expected_values[] = {0, 3, 6};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Tests that Range() with custom step (greater then one) generates
+// the expected sequence when the last element does not fall on the
+// upper range limit. Sequences generated by Range() must not have
+// elements beyond the range limits.
+TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) {
+  const ParamGenerator<int> gen = Range(0, 4, 3);
+  const int expected_values[] = {0, 3};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Verifies that Range works with user-defined types that define
+// copy constructor, operator=(), operator+(), and operator<().
+class DogAdder {
+ public:
+  explicit DogAdder(const char* a_value) : value_(a_value) {}
+  DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {}
+
+  DogAdder operator=(const DogAdder& other) {
+    if (this != &other)
+      value_ = other.value_;
+    return *this;
+  }
+  DogAdder operator+(const DogAdder& other) const {
+    Message msg;
+    msg << value_.c_str() << other.value_.c_str();
+    return DogAdder(msg.GetString().c_str());
+  }
+  bool operator<(const DogAdder& other) const {
+    return value_ < other.value_;
+  }
+  const ::testing::internal::String& value() const { return value_; }
+
+ private:
+  ::testing::internal::String value_;
+};
+
+TEST(RangeTest, WorksWithACustomType) {
+  const ParamGenerator<DogAdder> gen =
+      Range(DogAdder("cat"), DogAdder("catdogdog"), DogAdder("dog"));
+  ParamGenerator<DogAdder>::iterator it = gen.begin();
+
+  ASSERT_FALSE(it == gen.end());
+  EXPECT_STREQ("cat", it->value().c_str());
+
+  ASSERT_FALSE(++it == gen.end());
+  EXPECT_STREQ("catdog", it->value().c_str());
+
+  EXPECT_TRUE(++it == gen.end());
+}
+
+class IntWrapper {
+ public:
+  explicit IntWrapper(int a_value) : value_(a_value) {}
+  IntWrapper(const IntWrapper& other) : value_(other.value_) {}
+
+  IntWrapper operator=(const IntWrapper& other) {
+    value_ = other.value_;
+    return *this;
+  }
+  // operator+() adds a different type.
+  IntWrapper operator+(int other) const { return IntWrapper(value_ + other); }
+  bool operator<(const IntWrapper& other) const {
+    return value_ < other.value_;
+  }
+  int value() const { return value_; }
+
+ private:
+  int value_;
+};
+
+TEST(RangeTest, WorksWithACustomTypeWithDifferentIncrementType) {
+  const ParamGenerator<IntWrapper> gen = Range(IntWrapper(0), IntWrapper(2));
+  ParamGenerator<IntWrapper>::iterator it = gen.begin();
+
+  ASSERT_FALSE(it == gen.end());
+  EXPECT_EQ(0, it->value());
+
+  ASSERT_FALSE(++it == gen.end());
+  EXPECT_EQ(1, it->value());
+
+  EXPECT_TRUE(++it == gen.end());
+}
+
+// Tests that ValuesIn() with an array parameter generates
+// the expected sequence.
+TEST(ValuesInTest, ValuesInArray) {
+  int array[] = {3, 5, 8};
+  const ParamGenerator<int> gen = ValuesIn(array);
+  VerifyGenerator(gen, array);
+}
+
+// Tests that ValuesIn() with a const array parameter generates
+// the expected sequence.
+TEST(ValuesInTest, ValuesInConstArray) {
+  const int array[] = {3, 5, 8};
+  const ParamGenerator<int> gen = ValuesIn(array);
+  VerifyGenerator(gen, array);
+}
+
+// Edge case. Tests that ValuesIn() with an array parameter containing a
+// single element generates the single element sequence.
+TEST(ValuesInTest, ValuesInSingleElementArray) {
+  int array[] = {42};
+  const ParamGenerator<int> gen = ValuesIn(array);
+  VerifyGenerator(gen, array);
+}
+
+// Tests that ValuesIn() generates the expected sequence for an STL
+// container (vector).
+TEST(ValuesInTest, ValuesInVector) {
+  typedef ::std::vector<int> ContainerType;
+  ContainerType values;
+  values.push_back(3);
+  values.push_back(5);
+  values.push_back(8);
+  const ParamGenerator<int> gen = ValuesIn(values);
+
+  const int expected_values[] = {3, 5, 8};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Tests that ValuesIn() generates the expected sequence.
+TEST(ValuesInTest, ValuesInIteratorRange) {
+  typedef ::std::vector<int> ContainerType;
+  ContainerType values;
+  values.push_back(3);
+  values.push_back(5);
+  values.push_back(8);
+  const ParamGenerator<int> gen = ValuesIn(values.begin(), values.end());
+
+  const int expected_values[] = {3, 5, 8};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Edge case. Tests that ValuesIn() provided with an iterator range specifying a
+// single value generates a single-element sequence.
+TEST(ValuesInTest, ValuesInSingleElementIteratorRange) {
+  typedef ::std::vector<int> ContainerType;
+  ContainerType values;
+  values.push_back(42);
+  const ParamGenerator<int> gen = ValuesIn(values.begin(), values.end());
+
+  const int expected_values[] = {42};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Edge case. Tests that ValuesIn() provided with an empty iterator range
+// generates an empty sequence.
+TEST(ValuesInTest, ValuesInEmptyIteratorRange) {
+  typedef ::std::vector<int> ContainerType;
+  ContainerType values;
+  const ParamGenerator<int> gen = ValuesIn(values.begin(), values.end());
+
+  VerifyGeneratorIsEmpty(gen);
+}
+
+// Tests that the Values() generates the expected sequence.
+TEST(ValuesTest, ValuesWorks) {
+  const ParamGenerator<int> gen = Values(3, 5, 8);
+
+  const int expected_values[] = {3, 5, 8};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Tests that Values() generates the expected sequences from elements of
+// different types convertible to ParamGenerator's parameter type.
+TEST(ValuesTest, ValuesWorksForValuesOfCompatibleTypes) {
+  const ParamGenerator<double> gen = Values(3, 5.0f, 8.0);
+
+  const double expected_values[] = {3.0, 5.0, 8.0};
+  VerifyGenerator(gen, expected_values);
+}
+
+TEST(ValuesTest, ValuesWorksForMaxLengthList) {
+  const ParamGenerator<int> gen = Values(
+      10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
+      110, 120, 130, 140, 150, 160, 170, 180, 190, 200,
+      210, 220, 230, 240, 250, 260, 270, 280, 290, 300,
+      310, 320, 330, 340, 350, 360, 370, 380, 390, 400,
+      410, 420, 430, 440, 450, 460, 470, 480, 490, 500);
+
+  const int expected_values[] = {
+      10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
+      110, 120, 130, 140, 150, 160, 170, 180, 190, 200,
+      210, 220, 230, 240, 250, 260, 270, 280, 290, 300,
+      310, 320, 330, 340, 350, 360, 370, 380, 390, 400,
+      410, 420, 430, 440, 450, 460, 470, 480, 490, 500};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Edge case test. Tests that single-parameter Values() generates the sequence
+// with the single value.
+TEST(ValuesTest, ValuesWithSingleParameter) {
+  const ParamGenerator<int> gen = Values(42);
+
+  const int expected_values[] = {42};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Tests that Bool() generates sequence (false, true).
+TEST(BoolTest, BoolWorks) {
+  const ParamGenerator<bool> gen = Bool();
+
+  const bool expected_values[] = {false, true};
+  VerifyGenerator(gen, expected_values);
+}
+
+#if GTEST_HAS_COMBINE
+
+// Tests that Combine() with two parameters generates the expected sequence.
+TEST(CombineTest, CombineWithTwoParameters) {
+  const char* foo = "foo";
+  const char* bar = "bar";
+  const ParamGenerator<tuple<const char*, int> > gen =
+      Combine(Values(foo, bar), Values(3, 4));
+
+  tuple<const char*, int> expected_values[] = {
+    make_tuple(foo, 3), make_tuple(foo, 4),
+    make_tuple(bar, 3), make_tuple(bar, 4)};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Tests that Combine() with three parameters generates the expected sequence.
+TEST(CombineTest, CombineWithThreeParameters) {
+  const ParamGenerator<tuple<int, int, int> > gen = Combine(Values(0, 1),
+                                                            Values(3, 4),
+                                                            Values(5, 6));
+  tuple<int, int, int> expected_values[] = {
+    make_tuple(0, 3, 5), make_tuple(0, 3, 6),
+    make_tuple(0, 4, 5), make_tuple(0, 4, 6),
+    make_tuple(1, 3, 5), make_tuple(1, 3, 6),
+    make_tuple(1, 4, 5), make_tuple(1, 4, 6)};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Tests that the Combine() with the first parameter generating a single value
+// sequence generates a sequence with the number of elements equal to the
+// number of elements in the sequence generated by the second parameter.
+TEST(CombineTest, CombineWithFirstParameterSingleValue) {
+  const ParamGenerator<tuple<int, int> > gen = Combine(Values(42),
+                                                       Values(0, 1));
+
+  tuple<int, int> expected_values[] = {make_tuple(42, 0), make_tuple(42, 1)};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Tests that the Combine() with the second parameter generating a single value
+// sequence generates a sequence with the number of elements equal to the
+// number of elements in the sequence generated by the first parameter.
+TEST(CombineTest, CombineWithSecondParameterSingleValue) {
+  const ParamGenerator<tuple<int, int> > gen = Combine(Values(0, 1),
+                                                       Values(42));
+
+  tuple<int, int> expected_values[] = {make_tuple(0, 42), make_tuple(1, 42)};
+  VerifyGenerator(gen, expected_values);
+}
+
+// Tests that when the first parameter produces an empty sequence,
+// Combine() produces an empty sequence, too.
+TEST(CombineTest, CombineWithFirstParameterEmptyRange) {
+  const ParamGenerator<tuple<int, int> > gen = Combine(Range(0, 0),
+                                                       Values(0, 1));
+  VerifyGeneratorIsEmpty(gen);
+}
+
+// Tests that when the second parameter produces an empty sequence,
+// Combine() produces an empty sequence, too.
+TEST(CombineTest, CombineWithSecondParameterEmptyRange) {
+  const ParamGenerator<tuple<int, int> > gen = Combine(Values(0, 1),
+                                                       Range(1, 1));
+  VerifyGeneratorIsEmpty(gen);
+}
+
+// Edge case. Tests that combine works with the maximum number
+// of parameters supported by Google Test (currently 10).
+TEST(CombineTest, CombineWithMaxNumberOfParameters) {
+  const char* foo = "foo";
+  const char* bar = "bar";
+  const ParamGenerator<tuple<const char*, int, int, int, int, int, int, int,
+                             int, int> > gen = Combine(Values(foo, bar),
+                                                       Values(1), Values(2),
+                                                       Values(3), Values(4),
+                                                       Values(5), Values(6),
+                                                       Values(7), Values(8),
+                                                       Values(9));
+
+  tuple<const char*, int, int, int, int, int, int, int, int, int>
+      expected_values[] = {make_tuple(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9),
+                           make_tuple(bar, 1, 2, 3, 4, 5, 6, 7, 8, 9)};
+  VerifyGenerator(gen, expected_values);
+}
+
+#endif  // GTEST_HAS_COMBINE
+
+// Tests that an generator produces correct sequence after being
+// assigned from another generator.
+TEST(ParamGeneratorTest, AssignmentWorks) {
+  ParamGenerator<int> gen = Values(1, 2);
+  const ParamGenerator<int> gen2 = Values(3, 4);
+  gen = gen2;
+
+  const int expected_values[] = {3, 4};
+  VerifyGenerator(gen, expected_values);
+}
+
+// This test verifies that the tests are expanded and run as specified:
+// one test per element from the sequence produced by the generator
+// specified in INSTANTIATE_TEST_CASE_P. It also verifies that the test's
+// fixture constructor, SetUp(), and TearDown() have run and have been
+// supplied with the correct parameters.
+
+// The use of environment object allows detection of the case where no test
+// case functionality is run at all. In this case TestCaseTearDown will not
+// be able to detect missing tests, naturally.
+template <int kExpectedCalls>
+class TestGenerationEnvironment : public ::testing::Environment {
+ public:
+  static TestGenerationEnvironment* Instance() {
+    static TestGenerationEnvironment* instance = new TestGenerationEnvironment;
+    return instance;
+  }
+
+  void FixtureConstructorExecuted() { fixture_constructor_count_++; }
+  void SetUpExecuted() { set_up_count_++; }
+  void TearDownExecuted() { tear_down_count_++; }
+  void TestBodyExecuted() { test_body_count_++; }
+
+  virtual void TearDown() {
+    // If all MultipleTestGenerationTest tests have been de-selected
+    // by the filter flag, the following checks make no sense.
+    bool perform_check = false;
+
+    for (int i = 0; i < kExpectedCalls; ++i) {
+      Message msg;
+      msg << "TestsExpandedAndRun/" << i;
+      if (UnitTestOptions::FilterMatchesTest(
+             "TestExpansionModule/MultipleTestGenerationTest",
+              msg.GetString().c_str())) {
+        perform_check = true;
+      }
+    }
+    if (perform_check) {
+      EXPECT_EQ(kExpectedCalls, fixture_constructor_count_)
+          << "Fixture constructor of ParamTestGenerationTest test case "
+          << "has not been run as expected.";
+      EXPECT_EQ(kExpectedCalls, set_up_count_)
+          << "Fixture SetUp method of ParamTestGenerationTest test case "
+          << "has not been run as expected.";
+      EXPECT_EQ(kExpectedCalls, tear_down_count_)
+          << "Fixture TearDown method of ParamTestGenerationTest test case "
+          << "has not been run as expected.";
+      EXPECT_EQ(kExpectedCalls, test_body_count_)
+          << "Test in ParamTestGenerationTest test case "
+          << "has not been run as expected.";
+    }
+  }
+ private:
+  TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0),
+                                tear_down_count_(0), test_body_count_(0) {}
+
+  int fixture_constructor_count_;
+  int set_up_count_;
+  int tear_down_count_;
+  int test_body_count_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationEnvironment);
+};
+
+const int test_generation_params[] = {36, 42, 72};
+
+class TestGenerationTest : public TestWithParam<int> {
+ public:
+  enum {
+    PARAMETER_COUNT =
+        sizeof(test_generation_params)/sizeof(test_generation_params[0])
+  };
+
+  typedef TestGenerationEnvironment<PARAMETER_COUNT> Environment;
+
+  TestGenerationTest() {
+    Environment::Instance()->FixtureConstructorExecuted();
+    current_parameter_ = GetParam();
+  }
+  virtual void SetUp() {
+    Environment::Instance()->SetUpExecuted();
+    EXPECT_EQ(current_parameter_, GetParam());
+  }
+  virtual void TearDown() {
+    Environment::Instance()->TearDownExecuted();
+    EXPECT_EQ(current_parameter_, GetParam());
+  }
+
+  static void SetUpTestCase() {
+    bool all_tests_in_test_case_selected = true;
+
+    for (int i = 0; i < PARAMETER_COUNT; ++i) {
+      Message test_name;
+      test_name << "TestsExpandedAndRun/" << i;
+      if ( !UnitTestOptions::FilterMatchesTest(
+                "TestExpansionModule/MultipleTestGenerationTest",
+                test_name.GetString())) {
+        all_tests_in_test_case_selected = false;
+      }
+    }
+    EXPECT_TRUE(all_tests_in_test_case_selected)
+        << "When running the TestGenerationTest test case all of its tests\n"
+        << "must be selected by the filter flag for the test case to pass.\n"
+        << "If not all of them are enabled, we can't reliably conclude\n"
+        << "that the correct number of tests have been generated.";
+
+    collected_parameters_.clear();
+  }
+
+  static void TearDownTestCase() {
+    vector<int> expected_values(test_generation_params,
+                                test_generation_params + PARAMETER_COUNT);
+    // Test execution order is not guaranteed by Google Test,
+    // so the order of values in collected_parameters_ can be
+    // different and we have to sort to compare.
+    sort(expected_values.begin(), expected_values.end());
+    sort(collected_parameters_.begin(), collected_parameters_.end());
+
+    EXPECT_TRUE(collected_parameters_ == expected_values);
+  }
+ protected:
+  int current_parameter_;
+  static vector<int> collected_parameters_;
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationTest);
+};
+vector<int> TestGenerationTest::collected_parameters_;
+
+TEST_P(TestGenerationTest, TestsExpandedAndRun) {
+  Environment::Instance()->TestBodyExecuted();
+  EXPECT_EQ(current_parameter_, GetParam());
+  collected_parameters_.push_back(GetParam());
+}
+INSTANTIATE_TEST_CASE_P(TestExpansionModule, TestGenerationTest,
+                        ValuesIn(test_generation_params));
+
+// This test verifies that the element sequence (third parameter of
+// INSTANTIATE_TEST_CASE_P) is evaluated in InitGoogleTest() and neither at
+// the call site of INSTANTIATE_TEST_CASE_P nor in RUN_ALL_TESTS().  For
+// that, we declare param_value_ to be a static member of
+// GeneratorEvaluationTest and initialize it to 0.  We set it to 1 in
+// main(), just before invocation of InitGoogleTest().  After calling
+// InitGoogleTest(), we set the value to 2.  If the sequence is evaluated
+// before or after InitGoogleTest, INSTANTIATE_TEST_CASE_P will create a
+// test with parameter other than 1, and the test body will fail the
+// assertion.
+class GeneratorEvaluationTest : public TestWithParam<int> {
+ public:
+  static int param_value() { return param_value_; }
+  static void set_param_value(int param_value) { param_value_ = param_value; }
+
+ private:
+  static int param_value_;
+};
+int GeneratorEvaluationTest::param_value_ = 0;
+
+TEST_P(GeneratorEvaluationTest, GeneratorsEvaluatedInMain) {
+  EXPECT_EQ(1, GetParam());
+}
+INSTANTIATE_TEST_CASE_P(GenEvalModule,
+                        GeneratorEvaluationTest,
+                        Values(GeneratorEvaluationTest::param_value()));
+
+// Tests that generators defined in a different translation unit are
+// functional. Generator extern_gen is defined in gtest-param-test_test2.cc.
+extern ParamGenerator<int> extern_gen;
+class ExternalGeneratorTest : public TestWithParam<int> {};
+TEST_P(ExternalGeneratorTest, ExternalGenerator) {
+  // Sequence produced by extern_gen contains only a single value
+  // which we verify here.
+  EXPECT_EQ(GetParam(), 33);
+}
+INSTANTIATE_TEST_CASE_P(ExternalGeneratorModule,
+                        ExternalGeneratorTest,
+                        extern_gen);
+
+// Tests that a parameterized test case can be defined in one translation
+// unit and instantiated in another. This test will be instantiated in
+// gtest-param-test_test2.cc. ExternalInstantiationTest fixture class is
+// defined in gtest-param-test_test.h.
+TEST_P(ExternalInstantiationTest, IsMultipleOf33) {
+  EXPECT_EQ(0, GetParam() % 33);
+}
+
+// Tests that a parameterized test case can be instantiated with multiple
+// generators.
+class MultipleInstantiationTest : public TestWithParam<int> {};
+TEST_P(MultipleInstantiationTest, AllowsMultipleInstances) {
+}
+INSTANTIATE_TEST_CASE_P(Sequence1, MultipleInstantiationTest, Values(1, 2));
+INSTANTIATE_TEST_CASE_P(Sequence2, MultipleInstantiationTest, Range(3, 5));
+
+// Tests that a parameterized test case can be instantiated
+// in multiple translation units. This test will be instantiated
+// here and in gtest-param-test_test2.cc.
+// InstantiationInMultipleTranslationUnitsTest fixture class
+// is defined in gtest-param-test_test.h.
+TEST_P(InstantiationInMultipleTranslaionUnitsTest, IsMultipleOf42) {
+  EXPECT_EQ(0, GetParam() % 42);
+}
+INSTANTIATE_TEST_CASE_P(Sequence1,
+                        InstantiationInMultipleTranslaionUnitsTest,
+                        Values(42, 42*2));
+
+// Tests that each iteration of parameterized test runs in a separate test
+// object.
+class SeparateInstanceTest : public TestWithParam<int> {
+ public:
+  SeparateInstanceTest() : count_(0) {}
+
+  static void TearDownTestCase() {
+    EXPECT_GE(global_count_, 2)
+        << "If some (but not all) SeparateInstanceTest tests have been "
+        << "filtered out this test will fail. Make sure that all "
+        << "GeneratorEvaluationTest are selected or de-selected together "
+        << "by the test filter.";
+  }
+
+ protected:
+  int count_;
+  static int global_count_;
+};
+int SeparateInstanceTest::global_count_ = 0;
+
+TEST_P(SeparateInstanceTest, TestsRunInSeparateInstances) {
+  EXPECT_EQ(0, count_++);
+  global_count_++;
+}
+INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4));
+
+// Tests that all instantiations of a test have named appropriately. Test
+// defined with TEST_P(TestCaseName, TestName) and instantiated with
+// INSTANTIATE_TEST_CASE_P(SequenceName, TestCaseName, generator) must be named
+// SequenceName/TestCaseName.TestName/i, where i is the 0-based index of the
+// sequence element used to instantiate the test.
+class NamingTest : public TestWithParam<int> {};
+
+TEST_P(NamingTest, TestsAreNamedAppropriately) {
+  const ::testing::TestInfo* const test_info =
+     ::testing::UnitTest::GetInstance()->current_test_info();
+
+  EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name());
+
+  Message msg;
+  msg << "TestsAreNamedAppropriately/" << GetParam();
+  EXPECT_STREQ(msg.GetString().c_str(), test_info->name());
+}
+
+INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5));
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) {
+#if GTEST_HAS_COMBINE && !GTEST_HAS_PARAM_TEST
+  FAIL() << "GTEST_HAS_COMBINE is defined while GTEST_HAS_PARAM_TEST is not\n"
+#endif
+}
+
+int main(int argc, char **argv) {
+#if GTEST_HAS_PARAM_TEST
+  // Used in TestGenerationTest test case.
+  AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance());
+  // Used in GeneratorEvaluationTest test case. Tests that the updated value
+  // will be picked up for instantiating tests in GeneratorEvaluationTest.
+  GeneratorEvaluationTest::set_param_value(1);
+#endif  // GTEST_HAS_PARAM_TEST
+
+  ::testing::InitGoogleTest(&argc, argv);
+
+#if GTEST_HAS_PARAM_TEST
+  // Used in GeneratorEvaluationTest test case. Tests that value updated
+  // here will NOT be used for instantiating tests in
+  // GeneratorEvaluationTest.
+  GeneratorEvaluationTest::set_param_value(2);
+#endif  // GTEST_HAS_PARAM_TEST
+
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/test/gtest-param-test_test.h b/protobuf/gtest/test/gtest-param-test_test.h
new file mode 100644
index 0000000..b7f9493
--- /dev/null
+++ b/protobuf/gtest/test/gtest-param-test_test.h
@@ -0,0 +1,55 @@
+// 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: vladl@google.com (Vlad Losev)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This header file provides classes and functions used internally
+// for testing Google Test itself.
+
+#ifndef GTEST_TEST_GTEST_PARAM_TEST_TEST_H_
+#define GTEST_TEST_GTEST_PARAM_TEST_TEST_H_
+
+#include <gtest/gtest.h>
+
+#if GTEST_HAS_PARAM_TEST
+
+// Test fixture for testing definition and instantiation of a test
+// in separate translation units.
+class ExternalInstantiationTest : public ::testing::TestWithParam<int> {};
+
+// Test fixture for testing instantiation of a test in multiple
+// translation units.
+class InstantiationInMultipleTranslaionUnitsTest
+    : public ::testing::TestWithParam<int> {};
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+#endif  // GTEST_TEST_GTEST_PARAM_TEST_TEST_H_
diff --git a/protobuf/gtest/test/gtest-port_test.cc b/protobuf/gtest/test/gtest-port_test.cc
new file mode 100644
index 0000000..3725860
--- /dev/null
+++ b/protobuf/gtest/test/gtest-port_test.cc
@@ -0,0 +1,1018 @@
+// 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: vladl@google.com (Vlad Losev), wan@google.com (Zhanyong Wan)
+//
+// This file tests the internal cross-platform support utilities.
+
+#include <gtest/internal/gtest-port.h>
+
+#include <stdio.h>
+
+#if GTEST_OS_MAC
+#include <time.h>
+#endif  // GTEST_OS_MAC
+
+#include <utility>  // For std::pair and std::make_pair.
+
+#include <gtest/gtest.h>
+#include <gtest/gtest-spi.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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+using std::make_pair;
+using std::pair;
+
+namespace testing {
+namespace internal {
+
+// Tests that the element_type typedef is available in scoped_ptr and refers
+// to the parameter type.
+TEST(ScopedPtrTest, DefinesElementType) {
+  StaticAssertTypeEq<int, ::testing::internal::scoped_ptr<int>::element_type>();
+}
+
+// TODO(vladl@google.com): Implement THE REST of scoped_ptr tests.
+
+TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) {
+  if (AlwaysFalse())
+    GTEST_CHECK_(false) << "This should never be executed; "
+                           "It's a compilation test only.";
+
+  if (AlwaysTrue())
+    GTEST_CHECK_(true);
+  else
+    ;  // NOLINT
+
+  if (AlwaysFalse())
+    ;  // NOLINT
+  else
+    GTEST_CHECK_(true) << "";
+}
+
+TEST(GtestCheckSyntaxTest, WorksWithSwitch) {
+  switch (0) {
+    case 1:
+      break;
+    default:
+      GTEST_CHECK_(true);
+  }
+
+  switch(0)
+    case 0:
+      GTEST_CHECK_(true) << "Check failed in switch case";
+}
+
+#if GTEST_OS_MAC
+void* ThreadFunc(void* data) {
+  pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data);
+  pthread_mutex_lock(mutex);
+  pthread_mutex_unlock(mutex);
+  return NULL;
+}
+
+TEST(GetThreadCountTest, ReturnsCorrectValue) {
+  EXPECT_EQ(1U, GetThreadCount());
+  pthread_mutex_t mutex;
+  pthread_attr_t  attr;
+  pthread_t       thread_id;
+
+  // TODO(vladl@google.com): turn mutex into internal::Mutex for automatic
+  // destruction.
+  pthread_mutex_init(&mutex, NULL);
+  pthread_mutex_lock(&mutex);
+  ASSERT_EQ(0, pthread_attr_init(&attr));
+  ASSERT_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
+
+  const int status = pthread_create(&thread_id, &attr, &ThreadFunc, &mutex);
+  ASSERT_EQ(0, pthread_attr_destroy(&attr));
+  ASSERT_EQ(0, status);
+  EXPECT_EQ(2U, GetThreadCount());
+  pthread_mutex_unlock(&mutex);
+
+  void* dummy;
+  ASSERT_EQ(0, pthread_join(thread_id, &dummy));
+
+  // MacOS X may not immediately report the updated thread count after
+  // joining a thread, causing flakiness in this test. To counter that, we
+  // wait for up to .5 seconds for the OS to report the correct value.
+  for (int i = 0; i < 5; ++i) {
+    if (GetThreadCount() == 1)
+      break;
+
+    SleepMilliseconds(100);
+  }
+  EXPECT_EQ(1U, GetThreadCount());
+  pthread_mutex_destroy(&mutex);
+}
+#else
+TEST(GetThreadCountTest, ReturnsZeroWhenUnableToCountThreads) {
+  EXPECT_EQ(0U, GetThreadCount());
+}
+#endif  // GTEST_OS_MAC
+
+TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) {
+  const bool a_false_condition = false;
+  const char regex[] =
+#ifdef _MSC_VER
+     "gtest-port_test\\.cc\\(\\d+\\):"
+#else
+     "gtest-port_test\\.cc:[0-9]+"
+#endif  // _MSC_VER
+     ".*a_false_condition.*Extra info.*";
+
+  EXPECT_DEATH_IF_SUPPORTED(GTEST_CHECK_(a_false_condition) << "Extra info",
+                            regex);
+}
+
+#if GTEST_HAS_DEATH_TEST
+
+TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) {
+  EXPECT_EXIT({
+      GTEST_CHECK_(true) << "Extra info";
+      ::std::cerr << "Success\n";
+      exit(0); },
+      ::testing::ExitedWithCode(0), "Success");
+}
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+#if GTEST_USES_POSIX_RE
+
+#if GTEST_HAS_TYPED_TEST
+
+template <typename Str>
+class RETest : public ::testing::Test {};
+
+// Defines StringTypes as the list of all string types that class RE
+// supports.
+typedef testing::Types<
+    ::std::string,
+#if GTEST_HAS_GLOBAL_STRING
+    ::string,
+#endif  // GTEST_HAS_GLOBAL_STRING
+    const char*> StringTypes;
+
+TYPED_TEST_CASE(RETest, StringTypes);
+
+// Tests RE's implicit constructors.
+TYPED_TEST(RETest, ImplicitConstructorWorks) {
+  const RE empty(TypeParam(""));
+  EXPECT_STREQ("", empty.pattern());
+
+  const RE simple(TypeParam("hello"));
+  EXPECT_STREQ("hello", simple.pattern());
+
+  const RE normal(TypeParam(".*(\\w+)"));
+  EXPECT_STREQ(".*(\\w+)", normal.pattern());
+}
+
+// Tests that RE's constructors reject invalid regular expressions.
+TYPED_TEST(RETest, RejectsInvalidRegex) {
+  EXPECT_NONFATAL_FAILURE({
+    const RE invalid(TypeParam("?"));
+  }, "\"?\" is not a valid POSIX Extended regular expression.");
+}
+
+// Tests RE::FullMatch().
+TYPED_TEST(RETest, FullMatchWorks) {
+  const RE empty(TypeParam(""));
+  EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty));
+  EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty));
+
+  const RE re(TypeParam("a.*z"));
+  EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re));
+  EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re));
+  EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re));
+  EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re));
+}
+
+// Tests RE::PartialMatch().
+TYPED_TEST(RETest, PartialMatchWorks) {
+  const RE empty(TypeParam(""));
+  EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty));
+  EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty));
+
+  const RE re(TypeParam("a.*z"));
+  EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re));
+  EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re));
+  EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re));
+  EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re));
+  EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re));
+}
+
+#endif  // GTEST_HAS_TYPED_TEST
+
+#elif GTEST_USES_SIMPLE_RE
+
+TEST(IsInSetTest, NulCharIsNotInAnySet) {
+  EXPECT_FALSE(IsInSet('\0', ""));
+  EXPECT_FALSE(IsInSet('\0', "\0"));
+  EXPECT_FALSE(IsInSet('\0', "a"));
+}
+
+TEST(IsInSetTest, WorksForNonNulChars) {
+  EXPECT_FALSE(IsInSet('a', "Ab"));
+  EXPECT_FALSE(IsInSet('c', ""));
+
+  EXPECT_TRUE(IsInSet('b', "bcd"));
+  EXPECT_TRUE(IsInSet('b', "ab"));
+}
+
+TEST(IsDigitTest, IsFalseForNonDigit) {
+  EXPECT_FALSE(IsDigit('\0'));
+  EXPECT_FALSE(IsDigit(' '));
+  EXPECT_FALSE(IsDigit('+'));
+  EXPECT_FALSE(IsDigit('-'));
+  EXPECT_FALSE(IsDigit('.'));
+  EXPECT_FALSE(IsDigit('a'));
+}
+
+TEST(IsDigitTest, IsTrueForDigit) {
+  EXPECT_TRUE(IsDigit('0'));
+  EXPECT_TRUE(IsDigit('1'));
+  EXPECT_TRUE(IsDigit('5'));
+  EXPECT_TRUE(IsDigit('9'));
+}
+
+TEST(IsPunctTest, IsFalseForNonPunct) {
+  EXPECT_FALSE(IsPunct('\0'));
+  EXPECT_FALSE(IsPunct(' '));
+  EXPECT_FALSE(IsPunct('\n'));
+  EXPECT_FALSE(IsPunct('a'));
+  EXPECT_FALSE(IsPunct('0'));
+}
+
+TEST(IsPunctTest, IsTrueForPunct) {
+  for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) {
+    EXPECT_PRED1(IsPunct, *p);
+  }
+}
+
+TEST(IsRepeatTest, IsFalseForNonRepeatChar) {
+  EXPECT_FALSE(IsRepeat('\0'));
+  EXPECT_FALSE(IsRepeat(' '));
+  EXPECT_FALSE(IsRepeat('a'));
+  EXPECT_FALSE(IsRepeat('1'));
+  EXPECT_FALSE(IsRepeat('-'));
+}
+
+TEST(IsRepeatTest, IsTrueForRepeatChar) {
+  EXPECT_TRUE(IsRepeat('?'));
+  EXPECT_TRUE(IsRepeat('*'));
+  EXPECT_TRUE(IsRepeat('+'));
+}
+
+TEST(IsWhiteSpaceTest, IsFalseForNonWhiteSpace) {
+  EXPECT_FALSE(IsWhiteSpace('\0'));
+  EXPECT_FALSE(IsWhiteSpace('a'));
+  EXPECT_FALSE(IsWhiteSpace('1'));
+  EXPECT_FALSE(IsWhiteSpace('+'));
+  EXPECT_FALSE(IsWhiteSpace('_'));
+}
+
+TEST(IsWhiteSpaceTest, IsTrueForWhiteSpace) {
+  EXPECT_TRUE(IsWhiteSpace(' '));
+  EXPECT_TRUE(IsWhiteSpace('\n'));
+  EXPECT_TRUE(IsWhiteSpace('\r'));
+  EXPECT_TRUE(IsWhiteSpace('\t'));
+  EXPECT_TRUE(IsWhiteSpace('\v'));
+  EXPECT_TRUE(IsWhiteSpace('\f'));
+}
+
+TEST(IsWordCharTest, IsFalseForNonWordChar) {
+  EXPECT_FALSE(IsWordChar('\0'));
+  EXPECT_FALSE(IsWordChar('+'));
+  EXPECT_FALSE(IsWordChar('.'));
+  EXPECT_FALSE(IsWordChar(' '));
+  EXPECT_FALSE(IsWordChar('\n'));
+}
+
+TEST(IsWordCharTest, IsTrueForLetter) {
+  EXPECT_TRUE(IsWordChar('a'));
+  EXPECT_TRUE(IsWordChar('b'));
+  EXPECT_TRUE(IsWordChar('A'));
+  EXPECT_TRUE(IsWordChar('Z'));
+}
+
+TEST(IsWordCharTest, IsTrueForDigit) {
+  EXPECT_TRUE(IsWordChar('0'));
+  EXPECT_TRUE(IsWordChar('1'));
+  EXPECT_TRUE(IsWordChar('7'));
+  EXPECT_TRUE(IsWordChar('9'));
+}
+
+TEST(IsWordCharTest, IsTrueForUnderscore) {
+  EXPECT_TRUE(IsWordChar('_'));
+}
+
+TEST(IsValidEscapeTest, IsFalseForNonPrintable) {
+  EXPECT_FALSE(IsValidEscape('\0'));
+  EXPECT_FALSE(IsValidEscape('\007'));
+}
+
+TEST(IsValidEscapeTest, IsFalseForDigit) {
+  EXPECT_FALSE(IsValidEscape('0'));
+  EXPECT_FALSE(IsValidEscape('9'));
+}
+
+TEST(IsValidEscapeTest, IsFalseForWhiteSpace) {
+  EXPECT_FALSE(IsValidEscape(' '));
+  EXPECT_FALSE(IsValidEscape('\n'));
+}
+
+TEST(IsValidEscapeTest, IsFalseForSomeLetter) {
+  EXPECT_FALSE(IsValidEscape('a'));
+  EXPECT_FALSE(IsValidEscape('Z'));
+}
+
+TEST(IsValidEscapeTest, IsTrueForPunct) {
+  EXPECT_TRUE(IsValidEscape('.'));
+  EXPECT_TRUE(IsValidEscape('-'));
+  EXPECT_TRUE(IsValidEscape('^'));
+  EXPECT_TRUE(IsValidEscape('$'));
+  EXPECT_TRUE(IsValidEscape('('));
+  EXPECT_TRUE(IsValidEscape(']'));
+  EXPECT_TRUE(IsValidEscape('{'));
+  EXPECT_TRUE(IsValidEscape('|'));
+}
+
+TEST(IsValidEscapeTest, IsTrueForSomeLetter) {
+  EXPECT_TRUE(IsValidEscape('d'));
+  EXPECT_TRUE(IsValidEscape('D'));
+  EXPECT_TRUE(IsValidEscape('s'));
+  EXPECT_TRUE(IsValidEscape('S'));
+  EXPECT_TRUE(IsValidEscape('w'));
+  EXPECT_TRUE(IsValidEscape('W'));
+}
+
+TEST(AtomMatchesCharTest, EscapedPunct) {
+  EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0'));
+  EXPECT_FALSE(AtomMatchesChar(true, '\\', ' '));
+  EXPECT_FALSE(AtomMatchesChar(true, '_', '.'));
+  EXPECT_FALSE(AtomMatchesChar(true, '.', 'a'));
+
+  EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\'));
+  EXPECT_TRUE(AtomMatchesChar(true, '_', '_'));
+  EXPECT_TRUE(AtomMatchesChar(true, '+', '+'));
+  EXPECT_TRUE(AtomMatchesChar(true, '.', '.'));
+}
+
+TEST(AtomMatchesCharTest, Escaped_d) {
+  EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'd', '.'));
+
+  EXPECT_TRUE(AtomMatchesChar(true, 'd', '0'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'd', '9'));
+}
+
+TEST(AtomMatchesCharTest, Escaped_D) {
+  EXPECT_FALSE(AtomMatchesChar(true, 'D', '0'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'D', '9'));
+
+  EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'D', '-'));
+}
+
+TEST(AtomMatchesCharTest, Escaped_s) {
+  EXPECT_FALSE(AtomMatchesChar(true, 's', '\0'));
+  EXPECT_FALSE(AtomMatchesChar(true, 's', 'a'));
+  EXPECT_FALSE(AtomMatchesChar(true, 's', '.'));
+  EXPECT_FALSE(AtomMatchesChar(true, 's', '9'));
+
+  EXPECT_TRUE(AtomMatchesChar(true, 's', ' '));
+  EXPECT_TRUE(AtomMatchesChar(true, 's', '\n'));
+  EXPECT_TRUE(AtomMatchesChar(true, 's', '\t'));
+}
+
+TEST(AtomMatchesCharTest, Escaped_S) {
+  EXPECT_FALSE(AtomMatchesChar(true, 'S', ' '));
+  EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r'));
+
+  EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'S', '9'));
+}
+
+TEST(AtomMatchesCharTest, Escaped_w) {
+  EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'w', '+'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'w', ' '));
+  EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n'));
+
+  EXPECT_TRUE(AtomMatchesChar(true, 'w', '0'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'w', '_'));
+}
+
+TEST(AtomMatchesCharTest, Escaped_W) {
+  EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'W', '9'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'W', '_'));
+
+  EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'W', '*'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n'));
+}
+
+TEST(AtomMatchesCharTest, EscapedWhiteSpace) {
+  EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a'));
+  EXPECT_FALSE(AtomMatchesChar(true, 't', '\0'));
+  EXPECT_FALSE(AtomMatchesChar(true, 't', 't'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0'));
+  EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f'));
+
+  EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r'));
+  EXPECT_TRUE(AtomMatchesChar(true, 't', '\t'));
+  EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v'));
+}
+
+TEST(AtomMatchesCharTest, UnescapedDot) {
+  EXPECT_FALSE(AtomMatchesChar(false, '.', '\n'));
+
+  EXPECT_TRUE(AtomMatchesChar(false, '.', '\0'));
+  EXPECT_TRUE(AtomMatchesChar(false, '.', '.'));
+  EXPECT_TRUE(AtomMatchesChar(false, '.', 'a'));
+  EXPECT_TRUE(AtomMatchesChar(false, '.', ' '));
+}
+
+TEST(AtomMatchesCharTest, UnescapedChar) {
+  EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0'));
+  EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b'));
+  EXPECT_FALSE(AtomMatchesChar(false, '$', 'a'));
+
+  EXPECT_TRUE(AtomMatchesChar(false, '$', '$'));
+  EXPECT_TRUE(AtomMatchesChar(false, '5', '5'));
+  EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z'));
+}
+
+TEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) {
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)),
+                          "NULL is not a valid simple regular expression");
+  EXPECT_NONFATAL_FAILURE(
+      ASSERT_FALSE(ValidateRegex("a\\")),
+      "Syntax error at index 1 in simple regular expression \"a\\\": ");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")),
+                          "'\\' cannot appear at the end");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")),
+                          "'\\' cannot appear at the end");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")),
+                          "invalid escape sequence \"\\h\"");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")),
+                          "'^' can only appear at the beginning");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")),
+                          "'^' can only appear at the beginning");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")),
+                          "'$' can only appear at the end");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")),
+                          "'$' can only appear at the end");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")),
+                          "'(' is unsupported");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")),
+                          "')' is unsupported");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")),
+                          "'[' is unsupported");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")),
+                          "'{' is unsupported");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")),
+                          "'?' can only follow a repeatable token");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")),
+                          "'*' can only follow a repeatable token");
+  EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")),
+                          "'+' can only follow a repeatable token");
+}
+
+TEST(ValidateRegexTest, ReturnsTrueForValid) {
+  EXPECT_TRUE(ValidateRegex(""));
+  EXPECT_TRUE(ValidateRegex("a"));
+  EXPECT_TRUE(ValidateRegex(".*"));
+  EXPECT_TRUE(ValidateRegex("^a_+"));
+  EXPECT_TRUE(ValidateRegex("^a\\t\\&?"));
+  EXPECT_TRUE(ValidateRegex("09*$"));
+  EXPECT_TRUE(ValidateRegex("^Z$"));
+  EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}"));
+}
+
+TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) {
+  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba"));
+  // Repeating more than once.
+  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab"));
+
+  // Repeating zero times.
+  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba"));
+  // Repeating once.
+  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab"));
+  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##"));
+}
+
+TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) {
+  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab"));
+
+  // Repeating zero times.
+  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc"));
+  // Repeating once.
+  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc"));
+  // Repeating more than once.
+  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g"));
+}
+
+TEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) {
+  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab"));
+  // Repeating zero times.
+  EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc"));
+
+  // Repeating once.
+  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc"));
+  // Repeating more than once.
+  EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g"));
+}
+
+TEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) {
+  EXPECT_TRUE(MatchRegexAtHead("", ""));
+  EXPECT_TRUE(MatchRegexAtHead("", "ab"));
+}
+
+TEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) {
+  EXPECT_FALSE(MatchRegexAtHead("$", "a"));
+
+  EXPECT_TRUE(MatchRegexAtHead("$", ""));
+  EXPECT_TRUE(MatchRegexAtHead("a$", "a"));
+}
+
+TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) {
+  EXPECT_FALSE(MatchRegexAtHead("\\w", "+"));
+  EXPECT_FALSE(MatchRegexAtHead("\\W", "ab"));
+
+  EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab"));
+  EXPECT_TRUE(MatchRegexAtHead("\\d", "1a"));
+}
+
+TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) {
+  EXPECT_FALSE(MatchRegexAtHead(".+a", "abc"));
+  EXPECT_FALSE(MatchRegexAtHead("a?b", "aab"));
+
+  EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab"));
+  EXPECT_TRUE(MatchRegexAtHead("a?b", "b"));
+  EXPECT_TRUE(MatchRegexAtHead("a?b", "ab"));
+}
+
+TEST(MatchRegexAtHeadTest,
+     WorksWhenRegexStartsWithRepetionOfEscapeSequence) {
+  EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc"));
+  EXPECT_FALSE(MatchRegexAtHead("\\s?b", "  b"));
+
+  EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab"));
+  EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b"));
+  EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b"));
+  EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b"));
+}
+
+TEST(MatchRegexAtHeadTest, MatchesSequentially) {
+  EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc"));
+
+  EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc"));
+}
+
+TEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) {
+  EXPECT_FALSE(MatchRegexAnywhere("", NULL));
+}
+
+TEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) {
+  EXPECT_FALSE(MatchRegexAnywhere("^a", "ba"));
+  EXPECT_FALSE(MatchRegexAnywhere("^$", "a"));
+
+  EXPECT_TRUE(MatchRegexAnywhere("^a", "ab"));
+  EXPECT_TRUE(MatchRegexAnywhere("^", "ab"));
+  EXPECT_TRUE(MatchRegexAnywhere("^$", ""));
+}
+
+TEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) {
+  EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123"));
+  EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888"));
+}
+
+TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) {
+  EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5"));
+  EXPECT_TRUE(MatchRegexAnywhere(".*=", "="));
+  EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc"));
+}
+
+TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) {
+  EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5"));
+  EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "=  ...="));
+}
+
+// Tests RE's implicit constructors.
+TEST(RETest, ImplicitConstructorWorks) {
+  const RE empty("");
+  EXPECT_STREQ("", empty.pattern());
+
+  const RE simple("hello");
+  EXPECT_STREQ("hello", simple.pattern());
+}
+
+// Tests that RE's constructors reject invalid regular expressions.
+TEST(RETest, RejectsInvalidRegex) {
+  EXPECT_NONFATAL_FAILURE({
+    const RE normal(NULL);
+  }, "NULL is not a valid simple regular expression");
+
+  EXPECT_NONFATAL_FAILURE({
+    const RE normal(".*(\\w+");
+  }, "'(' is unsupported");
+
+  EXPECT_NONFATAL_FAILURE({
+    const RE invalid("^?");
+  }, "'?' can only follow a repeatable token");
+}
+
+// Tests RE::FullMatch().
+TEST(RETest, FullMatchWorks) {
+  const RE empty("");
+  EXPECT_TRUE(RE::FullMatch("", empty));
+  EXPECT_FALSE(RE::FullMatch("a", empty));
+
+  const RE re1("a");
+  EXPECT_TRUE(RE::FullMatch("a", re1));
+
+  const RE re("a.*z");
+  EXPECT_TRUE(RE::FullMatch("az", re));
+  EXPECT_TRUE(RE::FullMatch("axyz", re));
+  EXPECT_FALSE(RE::FullMatch("baz", re));
+  EXPECT_FALSE(RE::FullMatch("azy", re));
+}
+
+// Tests RE::PartialMatch().
+TEST(RETest, PartialMatchWorks) {
+  const RE empty("");
+  EXPECT_TRUE(RE::PartialMatch("", empty));
+  EXPECT_TRUE(RE::PartialMatch("a", empty));
+
+  const RE re("a.*z");
+  EXPECT_TRUE(RE::PartialMatch("az", re));
+  EXPECT_TRUE(RE::PartialMatch("axyz", re));
+  EXPECT_TRUE(RE::PartialMatch("baz", re));
+  EXPECT_TRUE(RE::PartialMatch("azy", re));
+  EXPECT_FALSE(RE::PartialMatch("zza", re));
+}
+
+#endif  // GTEST_USES_POSIX_RE
+
+#if !GTEST_OS_WINDOWS_MOBILE
+
+TEST(CaptureTest, CapturesStdout) {
+  CaptureStdout();
+  fprintf(stdout, "abc");
+  EXPECT_STREQ("abc", GetCapturedStdout().c_str());
+
+  CaptureStdout();
+  fprintf(stdout, "def%cghi", '\0');
+  EXPECT_EQ(::std::string("def\0ghi", 7), ::std::string(GetCapturedStdout()));
+}
+
+TEST(CaptureTest, CapturesStderr) {
+  CaptureStderr();
+  fprintf(stderr, "jkl");
+  EXPECT_STREQ("jkl", GetCapturedStderr().c_str());
+
+  CaptureStderr();
+  fprintf(stderr, "jkl%cmno", '\0');
+  EXPECT_EQ(::std::string("jkl\0mno", 7), ::std::string(GetCapturedStderr()));
+}
+
+// Tests that stdout and stderr capture don't interfere with each other.
+TEST(CaptureTest, CapturesStdoutAndStderr) {
+  CaptureStdout();
+  CaptureStderr();
+  fprintf(stdout, "pqr");
+  fprintf(stderr, "stu");
+  EXPECT_STREQ("pqr", GetCapturedStdout().c_str());
+  EXPECT_STREQ("stu", GetCapturedStderr().c_str());
+}
+
+TEST(CaptureDeathTest, CannotReenterStdoutCapture) {
+  CaptureStdout();
+  EXPECT_DEATH_IF_SUPPORTED(CaptureStdout();,
+                            "Only one stdout capturer can exist at a time");
+  GetCapturedStdout();
+
+  // We cannot test stderr capturing using death tests as they use it
+  // themselves.
+}
+
+#endif  // !GTEST_OS_WINDOWS_MOBILE
+
+TEST(ThreadLocalTest, DefaultConstructorInitializesToDefaultValues) {
+  ThreadLocal<int> t1;
+  EXPECT_EQ(0, t1.get());
+
+  ThreadLocal<void*> t2;
+  EXPECT_TRUE(t2.get() == NULL);
+}
+
+TEST(ThreadLocalTest, SingleParamConstructorInitializesToParam) {
+  ThreadLocal<int> t1(123);
+  EXPECT_EQ(123, t1.get());
+
+  int i = 0;
+  ThreadLocal<int*> t2(&i);
+  EXPECT_EQ(&i, t2.get());
+}
+
+class NoDefaultContructor {
+ public:
+  explicit NoDefaultContructor(const char*) {}
+  NoDefaultContructor(const NoDefaultContructor&) {}
+};
+
+TEST(ThreadLocalTest, ValueDefaultContructorIsNotRequiredForParamVersion) {
+  ThreadLocal<NoDefaultContructor> bar(NoDefaultContructor("foo"));
+  bar.pointer();
+}
+
+TEST(ThreadLocalTest, GetAndPointerReturnSameValue) {
+  ThreadLocal<String> thread_local;
+
+  EXPECT_EQ(thread_local.pointer(), &(thread_local.get()));
+
+  // Verifies the condition still holds after calling set.
+  thread_local.set("foo");
+  EXPECT_EQ(thread_local.pointer(), &(thread_local.get()));
+}
+
+TEST(ThreadLocalTest, PointerAndConstPointerReturnSameValue) {
+  ThreadLocal<String> thread_local;
+  const ThreadLocal<String>& const_thread_local = thread_local;
+
+  EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer());
+
+  thread_local.set("foo");
+  EXPECT_EQ(thread_local.pointer(), const_thread_local.pointer());
+}
+
+#if GTEST_IS_THREADSAFE
+
+void AddTwo(int* param) { *param += 2; }
+
+TEST(ThreadWithParamTest, ConstructorExecutesThreadFunc) {
+  int i = 40;
+  ThreadWithParam<int*> thread(&AddTwo, &i, NULL);
+  thread.Join();
+  EXPECT_EQ(42, i);
+}
+
+TEST(MutexDeathTest, AssertHeldShouldAssertWhenNotLocked) {
+  // AssertHeld() is flaky only in the presence of multiple threads accessing
+  // the lock. In this case, the test is robust.
+  EXPECT_DEATH_IF_SUPPORTED({
+    Mutex m;
+    { MutexLock lock(&m); }
+    m.AssertHeld();
+  },
+  "thread .*hold");
+}
+
+TEST(MutexTest, AssertHeldShouldNotAssertWhenLocked) {
+  Mutex m;
+  MutexLock lock(&m);
+  m.AssertHeld();
+}
+
+class AtomicCounterWithMutex {
+ public:
+  explicit AtomicCounterWithMutex(Mutex* mutex) :
+    value_(0), mutex_(mutex), random_(42) {}
+
+  void Increment() {
+    MutexLock lock(mutex_);
+    int temp = value_;
+    {
+      // Locking a mutex puts up a memory barrier, preventing reads and
+      // writes to value_ rearranged when observed from other threads.
+      //
+      // We cannot use Mutex and MutexLock here or rely on their memory
+      // barrier functionality as we are testing them here.
+      pthread_mutex_t memory_barrier_mutex;
+      GTEST_CHECK_POSIX_SUCCESS_(
+          pthread_mutex_init(&memory_barrier_mutex, NULL));
+      GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&memory_barrier_mutex));
+
+      SleepMilliseconds(random_.Generate(30));
+
+      GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&memory_barrier_mutex));
+    }
+    value_ = temp + 1;
+  }
+  int value() const { return value_; }
+
+ private:
+  volatile int value_;
+  Mutex* const mutex_;  // Protects value_.
+  Random       random_;
+};
+
+void CountingThreadFunc(pair<AtomicCounterWithMutex*, int> param) {
+  for (int i = 0; i < param.second; ++i)
+      param.first->Increment();
+}
+
+// Tests that the mutex only lets one thread at a time to lock it.
+TEST(MutexTest, OnlyOneThreadCanLockAtATime) {
+  Mutex mutex;
+  AtomicCounterWithMutex locked_counter(&mutex);
+
+  typedef ThreadWithParam<pair<AtomicCounterWithMutex*, int> > ThreadType;
+  const int kCycleCount = 20;
+  const int kThreadCount = 7;
+  scoped_ptr<ThreadType> counting_threads[kThreadCount];
+  Notification threads_can_start;
+  // Creates and runs kThreadCount threads that increment locked_counter
+  // kCycleCount times each.
+  for (int i = 0; i < kThreadCount; ++i) {
+    counting_threads[i].reset(new ThreadType(&CountingThreadFunc,
+                                             make_pair(&locked_counter,
+                                                       kCycleCount),
+                                             &threads_can_start));
+  }
+  threads_can_start.Notify();
+  for (int i = 0; i < kThreadCount; ++i)
+    counting_threads[i]->Join();
+
+  // If the mutex lets more than one thread to increment the counter at a
+  // time, they are likely to encounter a race condition and have some
+  // increments overwritten, resulting in the lower then expected counter
+  // value.
+  EXPECT_EQ(kCycleCount * kThreadCount, locked_counter.value());
+}
+
+template <typename T>
+void RunFromThread(void (func)(T), T param) {
+  ThreadWithParam<T> thread(func, param, NULL);
+  thread.Join();
+}
+
+void RetrieveThreadLocalValue(pair<ThreadLocal<String>*, String*> param) {
+  *param.second = param.first->get();
+}
+
+TEST(ThreadLocalTest, ParameterizedConstructorSetsDefault) {
+  ThreadLocal<String> thread_local("foo");
+  EXPECT_STREQ("foo", thread_local.get().c_str());
+
+  thread_local.set("bar");
+  EXPECT_STREQ("bar", thread_local.get().c_str());
+
+  String result;
+  RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result));
+  EXPECT_STREQ("foo", result.c_str());
+}
+
+// DestructorTracker keeps track of whether its instances have been
+// destroyed.
+static std::vector<bool> g_destroyed;
+
+class DestructorTracker {
+ public:
+  DestructorTracker() : index_(GetNewIndex()) {}
+  DestructorTracker(const DestructorTracker& /* rhs */)
+      : index_(GetNewIndex()) {}
+  ~DestructorTracker() {
+    // We never access g_destroyed concurrently, so we don't need to
+    // protect the write operation under a mutex.
+    g_destroyed[index_] = true;
+  }
+
+ private:
+  static int GetNewIndex() {
+    g_destroyed.push_back(false);
+    return g_destroyed.size() - 1;
+  }
+  const int index_;
+};
+
+typedef ThreadLocal<DestructorTracker>* ThreadParam;
+
+void CallThreadLocalGet(ThreadParam thread_local) {
+  thread_local->get();
+}
+
+// Tests that when a ThreadLocal object dies in a thread, it destroys
+// the managed object for that thread.
+TEST(ThreadLocalTest, DestroysManagedObjectForOwnThreadWhenDying) {
+  g_destroyed.clear();
+
+  {
+    // The next line default constructs a DestructorTracker object as
+    // the default value of objects managed by thread_local.
+    ThreadLocal<DestructorTracker> thread_local;
+    ASSERT_EQ(1U, g_destroyed.size());
+    ASSERT_FALSE(g_destroyed[0]);
+
+    // This creates another DestructorTracker object for the main thread.
+    thread_local.get();
+    ASSERT_EQ(2U, g_destroyed.size());
+    ASSERT_FALSE(g_destroyed[0]);
+    ASSERT_FALSE(g_destroyed[1]);
+  }
+
+  // Now thread_local has died.  It should have destroyed both the
+  // default value shared by all threads and the value for the main
+  // thread.
+  ASSERT_EQ(2U, g_destroyed.size());
+  EXPECT_TRUE(g_destroyed[0]);
+  EXPECT_TRUE(g_destroyed[1]);
+
+  g_destroyed.clear();
+}
+
+// Tests that when a thread exits, the thread-local object for that
+// thread is destroyed.
+TEST(ThreadLocalTest, DestroysManagedObjectAtThreadExit) {
+  g_destroyed.clear();
+
+  {
+    // The next line default constructs a DestructorTracker object as
+    // the default value of objects managed by thread_local.
+    ThreadLocal<DestructorTracker> thread_local;
+    ASSERT_EQ(1U, g_destroyed.size());
+    ASSERT_FALSE(g_destroyed[0]);
+
+    // This creates another DestructorTracker object in the new thread.
+    ThreadWithParam<ThreadParam> thread(
+        &CallThreadLocalGet, &thread_local, NULL);
+    thread.Join();
+
+    // Now the new thread has exited.  The per-thread object for it
+    // should have been destroyed.
+    ASSERT_EQ(2U, g_destroyed.size());
+    ASSERT_FALSE(g_destroyed[0]);
+    ASSERT_TRUE(g_destroyed[1]);
+  }
+
+  // Now thread_local has died.  The default value should have been
+  // destroyed too.
+  ASSERT_EQ(2U, g_destroyed.size());
+  EXPECT_TRUE(g_destroyed[0]);
+  EXPECT_TRUE(g_destroyed[1]);
+
+  g_destroyed.clear();
+}
+
+TEST(ThreadLocalTest, ThreadLocalMutationsAffectOnlyCurrentThread) {
+  ThreadLocal<String> thread_local;
+  thread_local.set("Foo");
+  EXPECT_STREQ("Foo", thread_local.get().c_str());
+
+  String result;
+  RunFromThread(&RetrieveThreadLocalValue, make_pair(&thread_local, &result));
+  EXPECT_TRUE(result.c_str() == NULL);
+}
+
+#endif  // GTEST_IS_THREADSAFE
+
+}  // namespace internal
+}  // namespace testing
diff --git a/protobuf/gtest/test/gtest-test-part_test.cc b/protobuf/gtest/test/gtest-test-part_test.cc
new file mode 100644
index 0000000..5a3e919
--- /dev/null
+++ b/protobuf/gtest/test/gtest-test-part_test.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.
+//
+// Author: mheule@google.com (Markus Heule)
+//
+
+#include <gtest/gtest-test-part.h>
+
+#include <gtest/gtest.h>
+
+using testing::Message;
+using testing::Test;
+using testing::TestPartResult;
+using testing::TestPartResultArray;
+
+namespace {
+
+// Tests the TestPartResult class.
+
+// The test fixture for testing TestPartResult.
+class TestPartResultTest : public Test {
+ protected:
+  TestPartResultTest()
+      : r1_(TestPartResult::kSuccess, "foo/bar.cc", 10, "Success!"),
+        r2_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure!"),
+        r3_(TestPartResult::kFatalFailure, NULL, -1, "Failure!") {}
+
+  TestPartResult r1_, r2_, r3_;
+};
+
+
+TEST_F(TestPartResultTest, ConstructorWorks) {
+  Message message;
+  message << "something is terribly wrong";
+  message << static_cast<const char*>(testing::internal::kStackTraceMarker);
+  message << "some unimportant stack trace";
+
+  const TestPartResult result(TestPartResult::kNonFatalFailure,
+                              "some_file.cc",
+                              42,
+                              message.GetString().c_str());
+
+  EXPECT_EQ(TestPartResult::kNonFatalFailure, result.type());
+  EXPECT_STREQ("some_file.cc", result.file_name());
+  EXPECT_EQ(42, result.line_number());
+  EXPECT_STREQ(message.GetString().c_str(), result.message());
+  EXPECT_STREQ("something is terribly wrong", result.summary());
+}
+
+TEST_F(TestPartResultTest, ResultAccessorsWork) {
+  const TestPartResult success(TestPartResult::kSuccess,
+                               "file.cc",
+                               42,
+                               "message");
+  EXPECT_TRUE(success.passed());
+  EXPECT_FALSE(success.failed());
+  EXPECT_FALSE(success.nonfatally_failed());
+  EXPECT_FALSE(success.fatally_failed());
+
+  const TestPartResult nonfatal_failure(TestPartResult::kNonFatalFailure,
+                                        "file.cc",
+                                        42,
+                                        "message");
+  EXPECT_FALSE(nonfatal_failure.passed());
+  EXPECT_TRUE(nonfatal_failure.failed());
+  EXPECT_TRUE(nonfatal_failure.nonfatally_failed());
+  EXPECT_FALSE(nonfatal_failure.fatally_failed());
+
+  const TestPartResult fatal_failure(TestPartResult::kFatalFailure,
+                                     "file.cc",
+                                     42,
+                                     "message");
+  EXPECT_FALSE(fatal_failure.passed());
+  EXPECT_TRUE(fatal_failure.failed());
+  EXPECT_FALSE(fatal_failure.nonfatally_failed());
+  EXPECT_TRUE(fatal_failure.fatally_failed());
+}
+
+// Tests TestPartResult::type().
+TEST_F(TestPartResultTest, type) {
+  EXPECT_EQ(TestPartResult::kSuccess, r1_.type());
+  EXPECT_EQ(TestPartResult::kNonFatalFailure, r2_.type());
+  EXPECT_EQ(TestPartResult::kFatalFailure, r3_.type());
+}
+
+// Tests TestPartResult::file_name().
+TEST_F(TestPartResultTest, file_name) {
+  EXPECT_STREQ("foo/bar.cc", r1_.file_name());
+  EXPECT_STREQ(NULL, r3_.file_name());
+}
+
+// Tests TestPartResult::line_number().
+TEST_F(TestPartResultTest, line_number) {
+  EXPECT_EQ(10, r1_.line_number());
+  EXPECT_EQ(-1, r2_.line_number());
+}
+
+// Tests TestPartResult::message().
+TEST_F(TestPartResultTest, message) {
+  EXPECT_STREQ("Success!", r1_.message());
+}
+
+// Tests TestPartResult::passed().
+TEST_F(TestPartResultTest, Passed) {
+  EXPECT_TRUE(r1_.passed());
+  EXPECT_FALSE(r2_.passed());
+  EXPECT_FALSE(r3_.passed());
+}
+
+// Tests TestPartResult::failed().
+TEST_F(TestPartResultTest, Failed) {
+  EXPECT_FALSE(r1_.failed());
+  EXPECT_TRUE(r2_.failed());
+  EXPECT_TRUE(r3_.failed());
+}
+
+// Tests TestPartResult::fatally_failed().
+TEST_F(TestPartResultTest, FatallyFailed) {
+  EXPECT_FALSE(r1_.fatally_failed());
+  EXPECT_FALSE(r2_.fatally_failed());
+  EXPECT_TRUE(r3_.fatally_failed());
+}
+
+// Tests TestPartResult::nonfatally_failed().
+TEST_F(TestPartResultTest, NonfatallyFailed) {
+  EXPECT_FALSE(r1_.nonfatally_failed());
+  EXPECT_TRUE(r2_.nonfatally_failed());
+  EXPECT_FALSE(r3_.nonfatally_failed());
+}
+
+// Tests the TestPartResultArray class.
+
+class TestPartResultArrayTest : public Test {
+ protected:
+  TestPartResultArrayTest()
+      : r1_(TestPartResult::kNonFatalFailure, "foo/bar.cc", -1, "Failure 1"),
+        r2_(TestPartResult::kFatalFailure, "foo/bar.cc", -1, "Failure 2") {}
+
+  const TestPartResult r1_, r2_;
+};
+
+// Tests that TestPartResultArray initially has size 0.
+TEST_F(TestPartResultArrayTest, InitialSizeIsZero) {
+  TestPartResultArray results;
+  EXPECT_EQ(0, results.size());
+}
+
+// Tests that TestPartResultArray contains the given TestPartResult
+// after one Append() operation.
+TEST_F(TestPartResultArrayTest, ContainsGivenResultAfterAppend) {
+  TestPartResultArray results;
+  results.Append(r1_);
+  EXPECT_EQ(1, results.size());
+  EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message());
+}
+
+// Tests that TestPartResultArray contains the given TestPartResults
+// after two Append() operations.
+TEST_F(TestPartResultArrayTest, ContainsGivenResultsAfterTwoAppends) {
+  TestPartResultArray results;
+  results.Append(r1_);
+  results.Append(r2_);
+  EXPECT_EQ(2, results.size());
+  EXPECT_STREQ("Failure 1", results.GetTestPartResult(0).message());
+  EXPECT_STREQ("Failure 2", results.GetTestPartResult(1).message());
+}
+
+typedef TestPartResultArrayTest TestPartResultArrayDeathTest;
+
+// Tests that the program dies when GetTestPartResult() is called with
+// an invalid index.
+TEST_F(TestPartResultArrayDeathTest, DiesWhenIndexIsOutOfBound) {
+  TestPartResultArray results;
+  results.Append(r1_);
+
+  EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(-1), "");
+  EXPECT_DEATH_IF_SUPPORTED(results.GetTestPartResult(1), "");
+}
+
+// TODO(mheule@google.com): Add a test for the class HasNewFatalFailureHelper.
+
+}  // namespace
diff --git a/protobuf/gtest/test/gtest-tuple_test.cc b/protobuf/gtest/test/gtest-tuple_test.cc
new file mode 100644
index 0000000..532f70b
--- /dev/null
+++ b/protobuf/gtest/test/gtest-tuple_test.cc
@@ -0,0 +1,320 @@
+// 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)
+
+#include <gtest/internal/gtest-tuple.h>
+#include <utility>
+#include <gtest/gtest.h>
+
+namespace {
+
+using ::std::tr1::get;
+using ::std::tr1::make_tuple;
+using ::std::tr1::tuple;
+using ::std::tr1::tuple_element;
+using ::std::tr1::tuple_size;
+using ::testing::StaticAssertTypeEq;
+
+// Tests that tuple_element<K, tuple<T0, T1, ..., TN> >::type returns TK.
+TEST(tuple_element_Test, ReturnsElementType) {
+  StaticAssertTypeEq<int, tuple_element<0, tuple<int, char> >::type>();
+  StaticAssertTypeEq<int&, tuple_element<1, tuple<double, int&> >::type>();
+  StaticAssertTypeEq<bool, tuple_element<2, tuple<double, int, bool> >::type>();
+}
+
+// Tests that tuple_size<T>::value gives the number of fields in tuple
+// type T.
+TEST(tuple_size_Test, ReturnsNumberOfFields) {
+  EXPECT_EQ(0, +tuple_size<tuple<> >::value);
+  EXPECT_EQ(1, +tuple_size<tuple<void*> >::value);
+  EXPECT_EQ(1, +tuple_size<tuple<char> >::value);
+  EXPECT_EQ(1, +(tuple_size<tuple<tuple<int, double> > >::value));
+  EXPECT_EQ(2, +(tuple_size<tuple<int&, const char> >::value));
+  EXPECT_EQ(3, +(tuple_size<tuple<char*, void, const bool&> >::value));
+}
+
+// Tests comparing a tuple with itself.
+TEST(ComparisonTest, ComparesWithSelf) {
+  const tuple<int, char, bool> a(5, 'a', false);
+
+  EXPECT_TRUE(a == a);
+  EXPECT_FALSE(a != a);
+}
+
+// Tests comparing two tuples with the same value.
+TEST(ComparisonTest, ComparesEqualTuples) {
+  const tuple<int, bool> a(5, true), b(5, true);
+
+  EXPECT_TRUE(a == b);
+  EXPECT_FALSE(a != b);
+}
+
+// Tests comparing two different tuples that have no reference fields.
+TEST(ComparisonTest, ComparesUnequalTuplesWithoutReferenceFields) {
+  typedef tuple<const int, char> FooTuple;
+
+  const FooTuple a(0, 'x');
+  const FooTuple b(1, 'a');
+
+  EXPECT_TRUE(a != b);
+  EXPECT_FALSE(a == b);
+
+  const FooTuple c(1, 'b');
+
+  EXPECT_TRUE(b != c);
+  EXPECT_FALSE(b == c);
+}
+
+// Tests comparing two different tuples that have reference fields.
+TEST(ComparisonTest, ComparesUnequalTuplesWithReferenceFields) {
+  typedef tuple<int&, const char&> FooTuple;
+
+  int i = 5;
+  const char ch = 'a';
+  const FooTuple a(i, ch);
+
+  int j = 6;
+  const FooTuple b(j, ch);
+
+  EXPECT_TRUE(a != b);
+  EXPECT_FALSE(a == b);
+
+  j = 5;
+  const char ch2 = 'b';
+  const FooTuple c(j, ch2);
+
+  EXPECT_TRUE(b != c);
+  EXPECT_FALSE(b == c);
+}
+
+// Tests that a tuple field with a reference type is an alias of the
+// variable it's supposed to reference.
+TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) {
+  int n = 0;
+  tuple<bool, int&> t(true, n);
+
+  n = 1;
+  EXPECT_EQ(n, get<1>(t))
+      << "Changing a underlying variable should update the reference field.";
+
+  // Makes sure that the implementation doesn't do anything funny with
+  // the & operator for the return type of get<>().
+  EXPECT_EQ(&n, &(get<1>(t)))
+      << "The address of a reference field should equal the address of "
+      << "the underlying variable.";
+
+  get<1>(t) = 2;
+  EXPECT_EQ(2, n)
+      << "Changing a reference field should update the underlying variable.";
+}
+
+// Tests that tuple's default constructor default initializes each field.
+// This test needs to compile without generating warnings.
+TEST(TupleConstructorTest, DefaultConstructorDefaultInitializesEachField) {
+  // The TR1 report requires that tuple's default constructor default
+  // initializes each field, even if it's a primitive type.  If the
+  // implementation forgets to do this, this test will catch it by
+  // generating warnings about using uninitialized variables (assuming
+  // a decent compiler).
+
+  tuple<> empty;
+
+  tuple<int> a1, b1;
+  b1 = a1;
+  EXPECT_EQ(0, get<0>(b1));
+
+  tuple<int, double> a2, b2;
+  b2 = a2;
+  EXPECT_EQ(0, get<0>(b2));
+  EXPECT_EQ(0.0, get<1>(b2));
+
+  tuple<double, char, bool*> a3, b3;
+  b3 = a3;
+  EXPECT_EQ(0.0, get<0>(b3));
+  EXPECT_EQ('\0', get<1>(b3));
+  EXPECT_TRUE(get<2>(b3) == NULL);
+
+  tuple<int, int, int, int, int, int, int, int, int, int> a10, b10;
+  b10 = a10;
+  EXPECT_EQ(0, get<0>(b10));
+  EXPECT_EQ(0, get<1>(b10));
+  EXPECT_EQ(0, get<2>(b10));
+  EXPECT_EQ(0, get<3>(b10));
+  EXPECT_EQ(0, get<4>(b10));
+  EXPECT_EQ(0, get<5>(b10));
+  EXPECT_EQ(0, get<6>(b10));
+  EXPECT_EQ(0, get<7>(b10));
+  EXPECT_EQ(0, get<8>(b10));
+  EXPECT_EQ(0, get<9>(b10));
+}
+
+// Tests constructing a tuple from its fields.
+TEST(TupleConstructorTest, ConstructsFromFields) {
+  int n = 1;
+  // Reference field.
+  tuple<int&> a(n);
+  EXPECT_EQ(&n, &(get<0>(a)));
+
+  // Non-reference fields.
+  tuple<int, char> b(5, 'a');
+  EXPECT_EQ(5, get<0>(b));
+  EXPECT_EQ('a', get<1>(b));
+
+  // Const reference field.
+  const int m = 2;
+  tuple<bool, const int&> c(true, m);
+  EXPECT_TRUE(get<0>(c));
+  EXPECT_EQ(&m, &(get<1>(c)));
+}
+
+// Tests tuple's copy constructor.
+TEST(TupleConstructorTest, CopyConstructor) {
+  tuple<double, bool> a(0.0, true);
+  tuple<double, bool> b(a);
+
+  EXPECT_DOUBLE_EQ(0.0, get<0>(b));
+  EXPECT_TRUE(get<1>(b));
+}
+
+// Tests constructing a tuple from another tuple that has a compatible
+// but different type.
+TEST(TupleConstructorTest, ConstructsFromDifferentTupleType) {
+  tuple<int, int, char> a(0, 1, 'a');
+  tuple<double, long, int> b(a);
+
+  EXPECT_DOUBLE_EQ(0.0, get<0>(b));
+  EXPECT_EQ(1, get<1>(b));
+  EXPECT_EQ('a', get<2>(b));
+}
+
+// Tests constructing a 2-tuple from an std::pair.
+TEST(TupleConstructorTest, ConstructsFromPair) {
+  ::std::pair<int, char> a(1, 'a');
+  tuple<int, char> b(a);
+  tuple<int, const char&> c(a);
+}
+
+// Tests assigning a tuple to another tuple with the same type.
+TEST(TupleAssignmentTest, AssignsToSameTupleType) {
+  const tuple<int, long> a(5, 7L);
+  tuple<int, long> b;
+  b = a;
+  EXPECT_EQ(5, get<0>(b));
+  EXPECT_EQ(7L, get<1>(b));
+}
+
+// Tests assigning a tuple to another tuple with a different but
+// compatible type.
+TEST(TupleAssignmentTest, AssignsToDifferentTupleType) {
+  const tuple<int, long, bool> a(1, 7L, true);
+  tuple<long, int, bool> b;
+  b = a;
+  EXPECT_EQ(1L, get<0>(b));
+  EXPECT_EQ(7, get<1>(b));
+  EXPECT_TRUE(get<2>(b));
+}
+
+// Tests assigning an std::pair to a 2-tuple.
+TEST(TupleAssignmentTest, AssignsFromPair) {
+  const ::std::pair<int, bool> a(5, true);
+  tuple<int, bool> b;
+  b = a;
+  EXPECT_EQ(5, get<0>(b));
+  EXPECT_TRUE(get<1>(b));
+
+  tuple<long, bool> c;
+  c = a;
+  EXPECT_EQ(5L, get<0>(c));
+  EXPECT_TRUE(get<1>(c));
+}
+
+// A fixture for testing big tuples.
+class BigTupleTest : public testing::Test {
+ protected:
+  typedef tuple<int, int, int, int, int, int, int, int, int, int> BigTuple;
+
+  BigTupleTest() :
+      a_(1, 0, 0, 0, 0, 0, 0, 0, 0, 2),
+      b_(1, 0, 0, 0, 0, 0, 0, 0, 0, 3) {}
+
+  BigTuple a_, b_;
+};
+
+// Tests constructing big tuples.
+TEST_F(BigTupleTest, Construction) {
+  BigTuple a;
+  BigTuple b(b_);
+}
+
+// Tests that get<N>(t) returns the N-th (0-based) field of tuple t.
+TEST_F(BigTupleTest, get) {
+  EXPECT_EQ(1, get<0>(a_));
+  EXPECT_EQ(2, get<9>(a_));
+
+  // Tests that get() works on a const tuple too.
+  const BigTuple a(a_);
+  EXPECT_EQ(1, get<0>(a));
+  EXPECT_EQ(2, get<9>(a));
+}
+
+// Tests comparing big tuples.
+TEST_F(BigTupleTest, Comparisons) {
+  EXPECT_TRUE(a_ == a_);
+  EXPECT_FALSE(a_ != a_);
+
+  EXPECT_TRUE(a_ != b_);
+  EXPECT_FALSE(a_ == b_);
+}
+
+TEST(MakeTupleTest, WorksForScalarTypes) {
+  tuple<bool, int> a;
+  a = make_tuple(true, 5);
+  EXPECT_TRUE(get<0>(a));
+  EXPECT_EQ(5, get<1>(a));
+
+  tuple<char, int, long> b;
+  b = make_tuple('a', 'b', 5);
+  EXPECT_EQ('a', get<0>(b));
+  EXPECT_EQ('b', get<1>(b));
+  EXPECT_EQ(5, get<2>(b));
+}
+
+TEST(MakeTupleTest, WorksForPointers) {
+  int a[] = { 1, 2, 3, 4 };
+  const char* const str = "hi";
+  int* const p = a;
+
+  tuple<const char*, int*> t;
+  t = make_tuple(str, p);
+  EXPECT_EQ(str, get<0>(t));
+  EXPECT_EQ(p, get<1>(t));
+}
+
+}  // namespace
diff --git a/protobuf/gtest/test/gtest-typed-test2_test.cc b/protobuf/gtest/test/gtest-typed-test2_test.cc
new file mode 100644
index 0000000..79a8a87
--- /dev/null
+++ b/protobuf/gtest/test/gtest-typed-test2_test.cc
@@ -0,0 +1,45 @@
+// 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 <vector>
+
+#include "test/gtest-typed-test_test.h"
+#include <gtest/gtest.h>
+
+#if GTEST_HAS_TYPED_TEST_P
+
+// Tests that the same type-parameterized test case can be
+// instantiated in different translation units linked together.
+// (ContainerTest is also instantiated in gtest-typed-test_test.cc.)
+INSTANTIATE_TYPED_TEST_CASE_P(Vector, ContainerTest,
+                              testing::Types<std::vector<int> >);
+
+#endif  // GTEST_HAS_TYPED_TEST_P
diff --git a/protobuf/gtest/test/gtest-typed-test_test.cc b/protobuf/gtest/test/gtest-typed-test_test.cc
new file mode 100644
index 0000000..f2c3972
--- /dev/null
+++ b/protobuf/gtest/test/gtest-typed-test_test.cc
@@ -0,0 +1,360 @@
+// 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 <set>
+#include <vector>
+
+#include "test/gtest-typed-test_test.h"
+#include <gtest/gtest.h>
+
+using testing::Test;
+
+// Used for testing that SetUpTestCase()/TearDownTestCase(), fixture
+// ctor/dtor, and SetUp()/TearDown() work correctly in typed tests and
+// type-parameterized test.
+template <typename T>
+class CommonTest : public Test {
+  // For some technical reason, SetUpTestCase() and TearDownTestCase()
+  // must be public.
+ public:
+  static void SetUpTestCase() {
+    shared_ = new T(5);
+  }
+
+  static void TearDownTestCase() {
+    delete shared_;
+    shared_ = NULL;
+  }
+
+  // This 'protected:' is optional.  There's no harm in making all
+  // members of this fixture class template public.
+ protected:
+  // We used to use std::list here, but switched to std::vector since
+  // MSVC's <list> doesn't compile cleanly with /W4.
+  typedef std::vector<T> Vector;
+  typedef std::set<int> IntSet;
+
+  CommonTest() : value_(1) {}
+
+  virtual ~CommonTest() { EXPECT_EQ(3, value_); }
+
+  virtual void SetUp() {
+    EXPECT_EQ(1, value_);
+    value_++;
+  }
+
+  virtual void TearDown() {
+    EXPECT_EQ(2, value_);
+    value_++;
+  }
+
+  T value_;
+  static T* shared_;
+};
+
+template <typename T>
+T* CommonTest<T>::shared_ = NULL;
+
+// This #ifdef block tests typed tests.
+#if GTEST_HAS_TYPED_TEST
+
+using testing::Types;
+
+// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor,
+// and SetUp()/TearDown() work correctly in typed tests
+
+typedef Types<char, int> TwoTypes;
+TYPED_TEST_CASE(CommonTest, TwoTypes);
+
+TYPED_TEST(CommonTest, ValuesAreCorrect) {
+  // Static members of the fixture class template can be visited via
+  // the TestFixture:: prefix.
+  EXPECT_EQ(5, *TestFixture::shared_);
+
+  // Typedefs in the fixture class template can be visited via the
+  // "typename TestFixture::" prefix.
+  typename TestFixture::Vector empty;
+  EXPECT_EQ(0U, empty.size());
+
+  typename TestFixture::IntSet empty2;
+  EXPECT_EQ(0U, empty2.size());
+
+  // Non-static members of the fixture class must be visited via
+  // 'this', as required by C++ for class templates.
+  EXPECT_EQ(2, this->value_);
+}
+
+// The second test makes sure shared_ is not deleted after the first
+// test.
+TYPED_TEST(CommonTest, ValuesAreStillCorrect) {
+  // Static members of the fixture class template can also be visited
+  // via 'this'.
+  ASSERT_TRUE(this->shared_ != NULL);
+  EXPECT_EQ(5, *this->shared_);
+
+  // TypeParam can be used to refer to the type parameter.
+  EXPECT_EQ(static_cast<TypeParam>(2), this->value_);
+}
+
+// Tests that multiple TYPED_TEST_CASE's can be defined in the same
+// translation unit.
+
+template <typename T>
+class TypedTest1 : public Test {
+};
+
+// Verifies that the second argument of TYPED_TEST_CASE can be a
+// single type.
+TYPED_TEST_CASE(TypedTest1, int);
+TYPED_TEST(TypedTest1, A) {}
+
+template <typename T>
+class TypedTest2 : public Test {
+};
+
+// Verifies that the second argument of TYPED_TEST_CASE can be a
+// Types<...> type list.
+TYPED_TEST_CASE(TypedTest2, Types<int>);
+
+// This also verifies that tests from different typed test cases can
+// share the same name.
+TYPED_TEST(TypedTest2, A) {}
+
+// Tests that a typed test case can be defined in a namespace.
+
+namespace library1 {
+
+template <typename T>
+class NumericTest : public Test {
+};
+
+typedef Types<int, long> NumericTypes;
+TYPED_TEST_CASE(NumericTest, NumericTypes);
+
+TYPED_TEST(NumericTest, DefaultIsZero) {
+  EXPECT_EQ(0, TypeParam());
+}
+
+}  // namespace library1
+
+#endif  // GTEST_HAS_TYPED_TEST
+
+// This #ifdef block tests type-parameterized tests.
+#if GTEST_HAS_TYPED_TEST_P
+
+using testing::Types;
+using testing::internal::TypedTestCasePState;
+
+// Tests TypedTestCasePState.
+
+class TypedTestCasePStateTest : public Test {
+ protected:
+  virtual void SetUp() {
+    state_.AddTestName("foo.cc", 0, "FooTest", "A");
+    state_.AddTestName("foo.cc", 0, "FooTest", "B");
+    state_.AddTestName("foo.cc", 0, "FooTest", "C");
+  }
+
+  TypedTestCasePState state_;
+};
+
+TEST_F(TypedTestCasePStateTest, SucceedsForMatchingList) {
+  const char* tests = "A, B, C";
+  EXPECT_EQ(tests,
+            state_.VerifyRegisteredTestNames("foo.cc", 1, tests));
+}
+
+// Makes sure that the order of the tests and spaces around the names
+// don't matter.
+TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) {
+  const char* tests = "A,C,   B";
+  EXPECT_EQ(tests,
+            state_.VerifyRegisteredTestNames("foo.cc", 1, tests));
+}
+
+typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest;
+
+TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) {
+  EXPECT_DEATH_IF_SUPPORTED(
+      state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"),
+      "foo\\.cc.1.?: Test A is listed more than once\\.");
+}
+
+TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) {
+  EXPECT_DEATH_IF_SUPPORTED(
+      state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"),
+      "foo\\.cc.1.?: No test named D can be found in this test case\\.");
+}
+
+TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) {
+  EXPECT_DEATH_IF_SUPPORTED(
+      state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"),
+      "foo\\.cc.1.?: You forgot to list test B\\.");
+}
+
+// Tests that defining a test for a parameterized test case generates
+// a run-time error if the test case has been registered.
+TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) {
+  state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C");
+  EXPECT_DEATH_IF_SUPPORTED(
+      state_.AddTestName("foo.cc", 2, "FooTest", "D"),
+      "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_CASE_P"
+      "\\(FooTest, \\.\\.\\.\\)\\.");
+}
+
+// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor,
+// and SetUp()/TearDown() work correctly in type-parameterized tests.
+
+template <typename T>
+class DerivedTest : public CommonTest<T> {
+};
+
+TYPED_TEST_CASE_P(DerivedTest);
+
+TYPED_TEST_P(DerivedTest, ValuesAreCorrect) {
+  // Static members of the fixture class template can be visited via
+  // the TestFixture:: prefix.
+  EXPECT_EQ(5, *TestFixture::shared_);
+
+  // Non-static members of the fixture class must be visited via
+  // 'this', as required by C++ for class templates.
+  EXPECT_EQ(2, this->value_);
+}
+
+// The second test makes sure shared_ is not deleted after the first
+// test.
+TYPED_TEST_P(DerivedTest, ValuesAreStillCorrect) {
+  // Static members of the fixture class template can also be visited
+  // via 'this'.
+  ASSERT_TRUE(this->shared_ != NULL);
+  EXPECT_EQ(5, *this->shared_);
+  EXPECT_EQ(2, this->value_);
+}
+
+REGISTER_TYPED_TEST_CASE_P(DerivedTest,
+                           ValuesAreCorrect, ValuesAreStillCorrect);
+
+typedef Types<short, long> MyTwoTypes;
+INSTANTIATE_TYPED_TEST_CASE_P(My, DerivedTest, MyTwoTypes);
+
+// Tests that multiple TYPED_TEST_CASE_P's can be defined in the same
+// translation unit.
+
+template <typename T>
+class TypedTestP1 : public Test {
+};
+
+TYPED_TEST_CASE_P(TypedTestP1);
+
+// For testing that the code between TYPED_TEST_CASE_P() and
+// TYPED_TEST_P() is not enclosed in a namespace.
+typedef int IntAfterTypedTestCaseP;
+
+TYPED_TEST_P(TypedTestP1, A) {}
+TYPED_TEST_P(TypedTestP1, B) {}
+
+// For testing that the code between TYPED_TEST_P() and
+// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace.
+typedef int IntBeforeRegisterTypedTestCaseP;
+
+REGISTER_TYPED_TEST_CASE_P(TypedTestP1, A, B);
+
+template <typename T>
+class TypedTestP2 : public Test {
+};
+
+TYPED_TEST_CASE_P(TypedTestP2);
+
+// This also verifies that tests from different type-parameterized
+// test cases can share the same name.
+TYPED_TEST_P(TypedTestP2, A) {}
+
+REGISTER_TYPED_TEST_CASE_P(TypedTestP2, A);
+
+// Verifies that the code between TYPED_TEST_CASE_P() and
+// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace.
+IntAfterTypedTestCaseP after = 0;
+IntBeforeRegisterTypedTestCaseP before = 0;
+
+// Verifies that the last argument of INSTANTIATE_TYPED_TEST_CASE_P()
+// can be either a single type or a Types<...> type list.
+INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP1, int);
+INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP2, Types<int>);
+
+// Tests that the same type-parameterized test case can be
+// instantiated more than once in the same translation unit.
+INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types<double>);
+
+// Tests that the same type-parameterized test case can be
+// instantiated in different translation units linked together.
+// (ContainerTest is also instantiated in gtest-typed-test_test.cc.)
+typedef Types<std::vector<double>, std::set<char> > MyContainers;
+INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers);
+
+// Tests that a type-parameterized test case can be defined and
+// instantiated in a namespace.
+
+namespace library2 {
+
+template <typename T>
+class NumericTest : public Test {
+};
+
+TYPED_TEST_CASE_P(NumericTest);
+
+TYPED_TEST_P(NumericTest, DefaultIsZero) {
+  EXPECT_EQ(0, TypeParam());
+}
+
+TYPED_TEST_P(NumericTest, ZeroIsLessThanOne) {
+  EXPECT_LT(TypeParam(0), TypeParam(1));
+}
+
+REGISTER_TYPED_TEST_CASE_P(NumericTest,
+                           DefaultIsZero, ZeroIsLessThanOne);
+typedef Types<int, double> NumericTypes;
+INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes);
+
+}  // namespace library2
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+#if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)
+
+// Google Test may not support type-parameterized tests with some
+// compilers. If we use conditional compilation to compile out all
+// code referring to the gtest_main library, MSVC linker will not link
+// that library at all and consequently complain about missing entry
+// point defined in that library (fatal error LNK1561: entry point
+// must be defined). This dummy test keeps gtest_main linked in.
+TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {}
+
+#endif  // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)
diff --git a/protobuf/gtest/test/gtest-typed-test_test.h b/protobuf/gtest/test/gtest-typed-test_test.h
new file mode 100644
index 0000000..40dfeac
--- /dev/null
+++ b/protobuf/gtest/test/gtest-typed-test_test.h
@@ -0,0 +1,66 @@
+// 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)
+
+#ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_
+#define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_
+
+#include <gtest/gtest.h>
+
+#if GTEST_HAS_TYPED_TEST_P
+
+using testing::Test;
+
+// For testing that the same type-parameterized test case can be
+// instantiated in different translation units linked together.
+// ContainerTest will be instantiated in both gtest-typed-test_test.cc
+// and gtest-typed-test2_test.cc.
+
+template <typename T>
+class ContainerTest : public Test {
+};
+
+TYPED_TEST_CASE_P(ContainerTest);
+
+TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) {
+  TypeParam container;
+}
+
+TYPED_TEST_P(ContainerTest, InitialSizeIsZero) {
+  TypeParam container;
+  EXPECT_EQ(0U, container.size());
+}
+
+REGISTER_TYPED_TEST_CASE_P(ContainerTest,
+                           CanBeDefaultConstructed, InitialSizeIsZero);
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+#endif  // GTEST_TEST_GTEST_TYPED_TEST_TEST_H_
diff --git a/protobuf/gtest/test/gtest-unittest-api_test.cc b/protobuf/gtest/test/gtest-unittest-api_test.cc
new file mode 100644
index 0000000..7e0f8f8
--- /dev/null
+++ b/protobuf/gtest/test/gtest-unittest-api_test.cc
@@ -0,0 +1,343 @@
+// Copyright 2009 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: vladl@google.com (Vlad Losev)
+//
+// The Google C++ Testing Framework (Google Test)
+//
+// This file contains tests verifying correctness of data provided via
+// UnitTest's public methods.
+
+#include <gtest/gtest.h>
+
+#include <string.h>  // For strcmp.
+#include <algorithm>
+
+using ::testing::InitGoogleTest;
+
+namespace testing {
+namespace internal {
+
+template <typename T>
+struct LessByName {
+  bool operator()(const T* a, const T* b) {
+    return strcmp(a->name(), b->name()) < 0;
+  }
+};
+
+class UnitTestHelper {
+ public:
+  // Returns the array of pointers to all test cases sorted by the test case
+  // name.  The caller is responsible for deleting the array.
+  static TestCase const** const GetSortedTestCases() {
+    UnitTest& unit_test = *UnitTest::GetInstance();
+    TestCase const** const test_cases =
+        new const TestCase*[unit_test.total_test_case_count()];
+
+    for (int i = 0; i < unit_test.total_test_case_count(); ++i)
+      test_cases[i] = unit_test.GetTestCase(i);
+
+    std::sort(test_cases,
+              test_cases + unit_test.total_test_case_count(),
+              LessByName<TestCase>());
+    return test_cases;
+  }
+
+  // Returns the test case by its name.  The caller doesn't own the returned
+  // pointer.
+  static const TestCase* FindTestCase(const char* name) {
+    UnitTest& unit_test = *UnitTest::GetInstance();
+    for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
+      const TestCase* test_case = unit_test.GetTestCase(i);
+      if (0 == strcmp(test_case->name(), name))
+        return test_case;
+    }
+    return NULL;
+  }
+
+  // Returns the array of pointers to all tests in a particular test case
+  // sorted by the test name.  The caller is responsible for deleting the
+  // array.
+  static TestInfo const** const GetSortedTests(const TestCase* test_case) {
+    TestInfo const** const tests =
+        new const TestInfo*[test_case->total_test_count()];
+
+    for (int i = 0; i < test_case->total_test_count(); ++i)
+      tests[i] = test_case->GetTestInfo(i);
+
+    std::sort(tests, tests + test_case->total_test_count(),
+              LessByName<TestInfo>());
+    return tests;
+  }
+};
+
+#if GTEST_HAS_TYPED_TEST
+template <typename T> class TestCaseWithCommentTest : public Test {};
+TYPED_TEST_CASE(TestCaseWithCommentTest, Types<int>);
+TYPED_TEST(TestCaseWithCommentTest, Dummy) {}
+
+const int kTypedTestCases = 1;
+const int kTypedTests = 1;
+
+String GetExpectedTestCaseComment() {
+  Message comment;
+  comment << "TypeParam = " << GetTypeName<int>().c_str();
+  return comment.GetString();
+}
+#else
+const int kTypedTestCases = 0;
+const int kTypedTests = 0;
+#endif  // GTEST_HAS_TYPED_TEST
+
+// We can only test the accessors that do not change value while tests run.
+// Since tests can be run in any order, the values the accessors that track
+// test execution (such as failed_test_count) can not be predicted.
+TEST(ApiTest, UnitTestImmutableAccessorsWork) {
+  UnitTest* unit_test = UnitTest::GetInstance();
+
+  ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count());
+  EXPECT_EQ(1 + kTypedTestCases, unit_test->test_case_to_run_count());
+  EXPECT_EQ(2, unit_test->disabled_test_count());
+  EXPECT_EQ(5 + kTypedTests, unit_test->total_test_count());
+  EXPECT_EQ(3 + kTypedTests, unit_test->test_to_run_count());
+
+  const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases();
+
+  EXPECT_STREQ("ApiTest", test_cases[0]->name());
+  EXPECT_STREQ("DISABLED_Test", test_cases[1]->name());
+#if GTEST_HAS_TYPED_TEST
+  EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name());
+#endif  // GTEST_HAS_TYPED_TEST
+
+  delete[] test_cases;
+
+  // The following lines initiate actions to verify certain methods in
+  // FinalSuccessChecker::TearDown.
+
+  // Records a test property to verify TestResult::GetTestProperty().
+  RecordProperty("key", "value");
+}
+
+TEST(ApiTest, TestCaseImmutableAccessorsWork) {
+  const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest");
+  ASSERT_TRUE(test_case != NULL);
+
+  EXPECT_STREQ("ApiTest", test_case->name());
+  EXPECT_STREQ("", test_case->comment());
+  EXPECT_TRUE(test_case->should_run());
+  EXPECT_EQ(1, test_case->disabled_test_count());
+  EXPECT_EQ(3, test_case->test_to_run_count());
+  ASSERT_EQ(4, test_case->total_test_count());
+
+  const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case);
+
+  EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name());
+  EXPECT_STREQ("ApiTest", tests[0]->test_case_name());
+  EXPECT_STREQ("", tests[0]->comment());
+  EXPECT_STREQ("", tests[0]->test_case_comment());
+  EXPECT_FALSE(tests[0]->should_run());
+
+  EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name());
+  EXPECT_STREQ("ApiTest", tests[1]->test_case_name());
+  EXPECT_STREQ("", tests[1]->comment());
+  EXPECT_STREQ("", tests[1]->test_case_comment());
+  EXPECT_TRUE(tests[1]->should_run());
+
+  EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name());
+  EXPECT_STREQ("ApiTest", tests[2]->test_case_name());
+  EXPECT_STREQ("", tests[2]->comment());
+  EXPECT_STREQ("", tests[2]->test_case_comment());
+  EXPECT_TRUE(tests[2]->should_run());
+
+  EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name());
+  EXPECT_STREQ("ApiTest", tests[3]->test_case_name());
+  EXPECT_STREQ("", tests[3]->comment());
+  EXPECT_STREQ("", tests[3]->test_case_comment());
+  EXPECT_TRUE(tests[3]->should_run());
+
+  delete[] tests;
+  tests = NULL;
+
+#if GTEST_HAS_TYPED_TEST
+  test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0");
+  ASSERT_TRUE(test_case != NULL);
+
+  EXPECT_STREQ("TestCaseWithCommentTest/0", test_case->name());
+  EXPECT_STREQ(GetExpectedTestCaseComment().c_str(), test_case->comment());
+  EXPECT_TRUE(test_case->should_run());
+  EXPECT_EQ(0, test_case->disabled_test_count());
+  EXPECT_EQ(1, test_case->test_to_run_count());
+  ASSERT_EQ(1, test_case->total_test_count());
+
+  tests = UnitTestHelper::GetSortedTests(test_case);
+
+  EXPECT_STREQ("Dummy", tests[0]->name());
+  EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name());
+  EXPECT_STREQ("", tests[0]->comment());
+  EXPECT_STREQ(GetExpectedTestCaseComment().c_str(),
+               tests[0]->test_case_comment());
+  EXPECT_TRUE(tests[0]->should_run());
+
+  delete[] tests;
+#endif  // GTEST_HAS_TYPED_TEST
+}
+
+TEST(ApiTest, TestCaseDisabledAccessorsWork) {
+  const TestCase* test_case = UnitTestHelper::FindTestCase("DISABLED_Test");
+  ASSERT_TRUE(test_case != NULL);
+
+  EXPECT_STREQ("DISABLED_Test", test_case->name());
+  EXPECT_STREQ("", test_case->comment());
+  EXPECT_FALSE(test_case->should_run());
+  EXPECT_EQ(1, test_case->disabled_test_count());
+  EXPECT_EQ(0, test_case->test_to_run_count());
+  ASSERT_EQ(1, test_case->total_test_count());
+
+  const TestInfo* const test_info = test_case->GetTestInfo(0);
+  EXPECT_STREQ("Dummy2", test_info->name());
+  EXPECT_STREQ("DISABLED_Test", test_info->test_case_name());
+  EXPECT_STREQ("", test_info->comment());
+  EXPECT_STREQ("", test_info->test_case_comment());
+  EXPECT_FALSE(test_info->should_run());
+}
+
+// These two tests are here to provide support for testing
+// test_case_to_run_count, disabled_test_count, and test_to_run_count.
+TEST(ApiTest, DISABLED_Dummy1) {}
+TEST(DISABLED_Test, Dummy2) {}
+
+class FinalSuccessChecker : public Environment {
+ protected:
+  virtual void TearDown() {
+    UnitTest* unit_test = UnitTest::GetInstance();
+
+    EXPECT_EQ(1 + kTypedTestCases, unit_test->successful_test_case_count());
+    EXPECT_EQ(3 + kTypedTests, unit_test->successful_test_count());
+    EXPECT_EQ(0, unit_test->failed_test_case_count());
+    EXPECT_EQ(0, unit_test->failed_test_count());
+    EXPECT_TRUE(unit_test->Passed());
+    EXPECT_FALSE(unit_test->Failed());
+    ASSERT_EQ(2 + kTypedTestCases, unit_test->total_test_case_count());
+
+    const TestCase** const test_cases = UnitTestHelper::GetSortedTestCases();
+
+    EXPECT_STREQ("ApiTest", test_cases[0]->name());
+    EXPECT_STREQ("", test_cases[0]->comment());
+    EXPECT_TRUE(test_cases[0]->should_run());
+    EXPECT_EQ(1, test_cases[0]->disabled_test_count());
+    ASSERT_EQ(4, test_cases[0]->total_test_count());
+    EXPECT_EQ(3, test_cases[0]->successful_test_count());
+    EXPECT_EQ(0, test_cases[0]->failed_test_count());
+    EXPECT_TRUE(test_cases[0]->Passed());
+    EXPECT_FALSE(test_cases[0]->Failed());
+
+    EXPECT_STREQ("DISABLED_Test", test_cases[1]->name());
+    EXPECT_STREQ("", test_cases[1]->comment());
+    EXPECT_FALSE(test_cases[1]->should_run());
+    EXPECT_EQ(1, test_cases[1]->disabled_test_count());
+    ASSERT_EQ(1, test_cases[1]->total_test_count());
+    EXPECT_EQ(0, test_cases[1]->successful_test_count());
+    EXPECT_EQ(0, test_cases[1]->failed_test_count());
+
+#if GTEST_HAS_TYPED_TEST
+    EXPECT_STREQ("TestCaseWithCommentTest/0", test_cases[2]->name());
+    EXPECT_STREQ(GetExpectedTestCaseComment().c_str(),
+                 test_cases[2]->comment());
+    EXPECT_TRUE(test_cases[2]->should_run());
+    EXPECT_EQ(0, test_cases[2]->disabled_test_count());
+    ASSERT_EQ(1, test_cases[2]->total_test_count());
+    EXPECT_EQ(1, test_cases[2]->successful_test_count());
+    EXPECT_EQ(0, test_cases[2]->failed_test_count());
+    EXPECT_TRUE(test_cases[2]->Passed());
+    EXPECT_FALSE(test_cases[2]->Failed());
+#endif  // GTEST_HAS_TYPED_TEST
+
+    const TestCase* test_case = UnitTestHelper::FindTestCase("ApiTest");
+    const TestInfo** tests = UnitTestHelper::GetSortedTests(test_case);
+    EXPECT_STREQ("DISABLED_Dummy1", tests[0]->name());
+    EXPECT_STREQ("ApiTest", tests[0]->test_case_name());
+    EXPECT_FALSE(tests[0]->should_run());
+
+    EXPECT_STREQ("TestCaseDisabledAccessorsWork", tests[1]->name());
+    EXPECT_STREQ("ApiTest", tests[1]->test_case_name());
+    EXPECT_STREQ("", tests[1]->comment());
+    EXPECT_STREQ("", tests[1]->test_case_comment());
+    EXPECT_TRUE(tests[1]->should_run());
+    EXPECT_TRUE(tests[1]->result()->Passed());
+    EXPECT_EQ(0, tests[1]->result()->test_property_count());
+
+    EXPECT_STREQ("TestCaseImmutableAccessorsWork", tests[2]->name());
+    EXPECT_STREQ("ApiTest", tests[2]->test_case_name());
+    EXPECT_STREQ("", tests[2]->comment());
+    EXPECT_STREQ("", tests[2]->test_case_comment());
+    EXPECT_TRUE(tests[2]->should_run());
+    EXPECT_TRUE(tests[2]->result()->Passed());
+    EXPECT_EQ(0, tests[2]->result()->test_property_count());
+
+    EXPECT_STREQ("UnitTestImmutableAccessorsWork", tests[3]->name());
+    EXPECT_STREQ("ApiTest", tests[3]->test_case_name());
+    EXPECT_STREQ("", tests[3]->comment());
+    EXPECT_STREQ("", tests[3]->test_case_comment());
+    EXPECT_TRUE(tests[3]->should_run());
+    EXPECT_TRUE(tests[3]->result()->Passed());
+    EXPECT_EQ(1, tests[3]->result()->test_property_count());
+    const TestProperty& property = tests[3]->result()->GetTestProperty(0);
+    EXPECT_STREQ("key", property.key());
+    EXPECT_STREQ("value", property.value());
+
+    delete[] tests;
+
+#if GTEST_HAS_TYPED_TEST
+    test_case = UnitTestHelper::FindTestCase("TestCaseWithCommentTest/0");
+    tests = UnitTestHelper::GetSortedTests(test_case);
+
+    EXPECT_STREQ("Dummy", tests[0]->name());
+    EXPECT_STREQ("TestCaseWithCommentTest/0", tests[0]->test_case_name());
+    EXPECT_STREQ("", tests[0]->comment());
+    EXPECT_STREQ(GetExpectedTestCaseComment().c_str(),
+                 tests[0]->test_case_comment());
+    EXPECT_TRUE(tests[0]->should_run());
+    EXPECT_TRUE(tests[0]->result()->Passed());
+    EXPECT_EQ(0, tests[0]->result()->test_property_count());
+
+    delete[] tests;
+#endif  // GTEST_HAS_TYPED_TEST
+    delete[] test_cases;
+  }
+};
+
+}  // namespace internal
+}  // namespace testing
+
+int main(int argc, char **argv) {
+  InitGoogleTest(&argc, argv);
+
+  AddGlobalTestEnvironment(new testing::internal::FinalSuccessChecker());
+
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/test/gtest_all_test.cc b/protobuf/gtest/test/gtest_all_test.cc
new file mode 100644
index 0000000..e1edb08
--- /dev/null
+++ b/protobuf/gtest/test/gtest_all_test.cc
@@ -0,0 +1,48 @@
+// Copyright 2009, 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)
+//
+// Tests for Google C++ Testing Framework (Google Test)
+//
+// Sometimes it's desirable to build most of Google Test's own tests
+// by compiling a single file.  This file serves this purpose.
+#include "test/gtest-filepath_test.cc"
+#include "test/gtest-linked_ptr_test.cc"
+#include "test/gtest-message_test.cc"
+#include "test/gtest-options_test.cc"
+#include "test/gtest-port_test.cc"
+#include "test/gtest_pred_impl_unittest.cc"
+#include "test/gtest_prod_test.cc"
+#include "test/gtest-test-part_test.cc"
+#include "test/gtest-typed-test_test.cc"
+#include "test/gtest-typed-test2_test.cc"
+#include "test/gtest_unittest.cc"
+#include "test/production.cc"
+#include "src/gtest_main.cc"
diff --git a/protobuf/gtest/test/gtest_break_on_failure_unittest.py b/protobuf/gtest/test/gtest_break_on_failure_unittest.py
new file mode 100755
index 0000000..c819183
--- /dev/null
+++ b/protobuf/gtest/test/gtest_break_on_failure_unittest.py
@@ -0,0 +1,218 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Unit test for Google Test's break-on-failure mode.
+
+A user can ask Google Test to seg-fault when an assertion fails, using
+either the GTEST_BREAK_ON_FAILURE environment variable or the
+--gtest_break_on_failure flag.  This script tests such functionality
+by invoking gtest_break_on_failure_unittest_ (a program written with
+Google Test) with different environments and command line flags.
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import gtest_test_utils
+import os
+import sys
+
+
+# Constants.
+
+IS_WINDOWS = os.name == 'nt'
+
+# The environment variable for enabling/disabling the break-on-failure mode.
+BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE'
+
+# The command line flag for enabling/disabling the break-on-failure mode.
+BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure'
+
+# The environment variable for enabling/disabling the throw-on-failure mode.
+THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE'
+
+# The environment variable for enabling/disabling the catch-exceptions mode.
+CATCH_EXCEPTIONS_ENV_VAR = 'GTEST_CATCH_EXCEPTIONS'
+
+# Path to the gtest_break_on_failure_unittest_ program.
+EXE_PATH = gtest_test_utils.GetTestExecutablePath(
+    'gtest_break_on_failure_unittest_')
+
+
+# Utilities.
+
+
+environ = os.environ.copy()
+
+
+def SetEnvVar(env_var, value):
+  """Sets an environment variable to a given value; unsets it when the
+  given value is None.
+  """
+
+  if value is not None:
+    environ[env_var] = value
+  elif env_var in environ:
+    del environ[env_var]
+
+
+def Run(command):
+  """Runs a command; returns 1 if it was killed by a signal, or 0 otherwise."""
+
+  p = gtest_test_utils.Subprocess(command, env=environ)
+  if p.terminated_by_signal:
+    return 1
+  else:
+    return 0
+
+
+# The tests.
+
+
+class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase):
+  """Tests using the GTEST_BREAK_ON_FAILURE environment variable or
+  the --gtest_break_on_failure flag to turn assertion failures into
+  segmentation faults.
+  """
+
+  def RunAndVerify(self, env_var_value, flag_value, expect_seg_fault):
+    """Runs gtest_break_on_failure_unittest_ and verifies that it does
+    (or does not) have a seg-fault.
+
+    Args:
+      env_var_value:    value of the GTEST_BREAK_ON_FAILURE environment
+                        variable; None if the variable should be unset.
+      flag_value:       value of the --gtest_break_on_failure flag;
+                        None if the flag should not be present.
+      expect_seg_fault: 1 if the program is expected to generate a seg-fault;
+                        0 otherwise.
+    """
+
+    SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, env_var_value)
+
+    if env_var_value is None:
+      env_var_value_msg = ' is not set'
+    else:
+      env_var_value_msg = '=' + env_var_value
+
+    if flag_value is None:
+      flag = ''
+    elif flag_value == '0':
+      flag = '--%s=0' % BREAK_ON_FAILURE_FLAG
+    else:
+      flag = '--%s' % BREAK_ON_FAILURE_FLAG
+
+    command = [EXE_PATH]
+    if flag:
+      command.append(flag)
+
+    if expect_seg_fault:
+      should_or_not = 'should'
+    else:
+      should_or_not = 'should not'
+
+    has_seg_fault = Run(command)
+
+    SetEnvVar(BREAK_ON_FAILURE_ENV_VAR, None)
+
+    msg = ('when %s%s, an assertion failure in "%s" %s cause a seg-fault.' %
+           (BREAK_ON_FAILURE_ENV_VAR, env_var_value_msg, ' '.join(command),
+            should_or_not))
+    self.assert_(has_seg_fault == expect_seg_fault, msg)
+
+  def testDefaultBehavior(self):
+    """Tests the behavior of the default mode."""
+
+    self.RunAndVerify(env_var_value=None,
+                      flag_value=None,
+                      expect_seg_fault=0)
+
+  def testEnvVar(self):
+    """Tests using the GTEST_BREAK_ON_FAILURE environment variable."""
+
+    self.RunAndVerify(env_var_value='0',
+                      flag_value=None,
+                      expect_seg_fault=0)
+    self.RunAndVerify(env_var_value='1',
+                      flag_value=None,
+                      expect_seg_fault=1)
+
+  def testFlag(self):
+    """Tests using the --gtest_break_on_failure flag."""
+
+    self.RunAndVerify(env_var_value=None,
+                      flag_value='0',
+                      expect_seg_fault=0)
+    self.RunAndVerify(env_var_value=None,
+                      flag_value='1',
+                      expect_seg_fault=1)
+
+  def testFlagOverridesEnvVar(self):
+    """Tests that the flag overrides the environment variable."""
+
+    self.RunAndVerify(env_var_value='0',
+                      flag_value='0',
+                      expect_seg_fault=0)
+    self.RunAndVerify(env_var_value='0',
+                      flag_value='1',
+                      expect_seg_fault=1)
+    self.RunAndVerify(env_var_value='1',
+                      flag_value='0',
+                      expect_seg_fault=0)
+    self.RunAndVerify(env_var_value='1',
+                      flag_value='1',
+                      expect_seg_fault=1)
+
+  def testBreakOnFailureOverridesThrowOnFailure(self):
+    """Tests that gtest_break_on_failure overrides gtest_throw_on_failure."""
+
+    SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1')
+    try:
+      self.RunAndVerify(env_var_value=None,
+                        flag_value='1',
+                        expect_seg_fault=1)
+    finally:
+      SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None)
+
+  if IS_WINDOWS:
+    def testCatchExceptionsDoesNotInterfere(self):
+      """Tests that gtest_catch_exceptions doesn't interfere."""
+
+      SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, '1')
+      try:
+        self.RunAndVerify(env_var_value='1',
+                          flag_value='1',
+                          expect_seg_fault=1)
+      finally:
+        SetEnvVar(CATCH_EXCEPTIONS_ENV_VAR, None)
+
+
+if __name__ == '__main__':
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_break_on_failure_unittest_.cc b/protobuf/gtest/test/gtest_break_on_failure_unittest_.cc
new file mode 100644
index 0000000..d28d1d3
--- /dev/null
+++ b/protobuf/gtest/test/gtest_break_on_failure_unittest_.cc
@@ -0,0 +1,86 @@
+// 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)
+
+// Unit test for Google Test's break-on-failure mode.
+//
+// A user can ask Google Test to seg-fault when an assertion fails, using
+// either the GTEST_BREAK_ON_FAILURE environment variable or the
+// --gtest_break_on_failure flag.  This file is used for testing such
+// functionality.
+//
+// This program will be invoked from a Python unit test.  It is
+// expected to fail.  Don't run it directly.
+
+#include <gtest/gtest.h>
+
+#if GTEST_OS_WINDOWS
+#include <windows.h>
+#include <stdlib.h>
+#endif
+
+namespace {
+
+// A test that's expected to fail.
+TEST(Foo, Bar) {
+  EXPECT_EQ(2, 3);
+}
+
+#if GTEST_HAS_SEH && !GTEST_OS_WINDOWS_MOBILE
+// On Windows Mobile global exception handlers are not supported.
+LONG WINAPI ExitWithExceptionCode(
+    struct _EXCEPTION_POINTERS* exception_pointers) {
+  exit(exception_pointers->ExceptionRecord->ExceptionCode);
+}
+#endif
+
+}  // namespace
+
+int main(int argc, char **argv) {
+#if GTEST_OS_WINDOWS
+  // Suppresses display of the Windows error dialog upon encountering
+  // a general protection fault (segment violation).
+  SetErrorMode(SEM_NOGPFAULTERRORBOX | SEM_FAILCRITICALERRORS);
+
+#if !GTEST_OS_WINDOWS_MOBILE
+  // The default unhandled exception filter does not always exit
+  // with the exception code as exit code - for example it exits with
+  // 0 for EXCEPTION_ACCESS_VIOLATION and 1 for EXCEPTION_BREAKPOINT
+  // if the application is compiled in debug mode. Thus we use our own
+  // filter which always exits with the exception code for unhandled
+  // exceptions.
+  SetUnhandledExceptionFilter(ExitWithExceptionCode);
+#endif
+#endif
+
+  testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/test/gtest_color_test.py b/protobuf/gtest/test/gtest_color_test.py
new file mode 100755
index 0000000..d02a53e
--- /dev/null
+++ b/protobuf/gtest/test/gtest_color_test.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Verifies that Google Test correctly determines whether to use colors."""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import gtest_test_utils
+
+
+IS_WINDOWS = os.name = 'nt'
+
+COLOR_ENV_VAR = 'GTEST_COLOR'
+COLOR_FLAG = 'gtest_color'
+COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_color_test_')
+
+
+def SetEnvVar(env_var, value):
+  """Sets the env variable to 'value'; unsets it when 'value' is None."""
+
+  if value is not None:
+    os.environ[env_var] = value
+  elif env_var in os.environ:
+    del os.environ[env_var]
+
+
+def UsesColor(term, color_env_var, color_flag):
+  """Runs gtest_color_test_ and returns its exit code."""
+
+  SetEnvVar('TERM', term)
+  SetEnvVar(COLOR_ENV_VAR, color_env_var)
+
+  if color_flag is None:
+    args = []
+  else:
+    args = ['--%s=%s' % (COLOR_FLAG, color_flag)]
+  p = gtest_test_utils.Subprocess([COMMAND] + args)
+  return not p.exited or p.exit_code
+
+
+class GTestColorTest(gtest_test_utils.TestCase):
+  def testNoEnvVarNoFlag(self):
+    """Tests the case when there's neither GTEST_COLOR nor --gtest_color."""
+
+    if not IS_WINDOWS:
+      self.assert_(not UsesColor('dumb', None, None))
+      self.assert_(not UsesColor('emacs', None, None))
+      self.assert_(not UsesColor('xterm-mono', None, None))
+      self.assert_(not UsesColor('unknown', None, None))
+      self.assert_(not UsesColor(None, None, None))
+    self.assert_(UsesColor('linux', None, None))
+    self.assert_(UsesColor('cygwin', None, None))
+    self.assert_(UsesColor('xterm', None, None))
+    self.assert_(UsesColor('xterm-color', None, None))
+    self.assert_(UsesColor('xterm-256color', None, None))
+
+  def testFlagOnly(self):
+    """Tests the case when there's --gtest_color but not GTEST_COLOR."""
+
+    self.assert_(not UsesColor('dumb', None, 'no'))
+    self.assert_(not UsesColor('xterm-color', None, 'no'))
+    if not IS_WINDOWS:
+      self.assert_(not UsesColor('emacs', None, 'auto'))
+    self.assert_(UsesColor('xterm', None, 'auto'))
+    self.assert_(UsesColor('dumb', None, 'yes'))
+    self.assert_(UsesColor('xterm', None, 'yes'))
+
+  def testEnvVarOnly(self):
+    """Tests the case when there's GTEST_COLOR but not --gtest_color."""
+
+    self.assert_(not UsesColor('dumb', 'no', None))
+    self.assert_(not UsesColor('xterm-color', 'no', None))
+    if not IS_WINDOWS:
+      self.assert_(not UsesColor('dumb', 'auto', None))
+    self.assert_(UsesColor('xterm-color', 'auto', None))
+    self.assert_(UsesColor('dumb', 'yes', None))
+    self.assert_(UsesColor('xterm-color', 'yes', None))
+
+  def testEnvVarAndFlag(self):
+    """Tests the case when there are both GTEST_COLOR and --gtest_color."""
+
+    self.assert_(not UsesColor('xterm-color', 'no', 'no'))
+    self.assert_(UsesColor('dumb', 'no', 'yes'))
+    self.assert_(UsesColor('xterm-color', 'no', 'auto'))
+
+  def testAliasesOfYesAndNo(self):
+    """Tests using aliases in specifying --gtest_color."""
+
+    self.assert_(UsesColor('dumb', None, 'true'))
+    self.assert_(UsesColor('dumb', None, 'YES'))
+    self.assert_(UsesColor('dumb', None, 'T'))
+    self.assert_(UsesColor('dumb', None, '1'))
+
+    self.assert_(not UsesColor('xterm', None, 'f'))
+    self.assert_(not UsesColor('xterm', None, 'false'))
+    self.assert_(not UsesColor('xterm', None, '0'))
+    self.assert_(not UsesColor('xterm', None, 'unknown'))
+
+
+if __name__ == '__main__':
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_color_test_.cc b/protobuf/gtest/test/gtest_color_test_.cc
new file mode 100644
index 0000000..58d377c
--- /dev/null
+++ b/protobuf/gtest/test/gtest_color_test_.cc
@@ -0,0 +1,71 @@
+// 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)
+
+// A helper program for testing how Google Test determines whether to use
+// colors in the output.  It prints "YES" and returns 1 if Google Test
+// decides to use colors, and prints "NO" and returns 0 otherwise.
+
+#include <stdio.h>
+
+#include <gtest/gtest.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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+using testing::internal::ShouldUseColor;
+
+// The purpose of this is to ensure that the UnitTest singleton is
+// created before main() is entered, and thus that ShouldUseColor()
+// works the same way as in a real Google-Test-based test.  We don't actual
+// run the TEST itself.
+TEST(GTestColorTest, Dummy) {
+}
+
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
+
+  if (ShouldUseColor(true)) {
+    // Google Test decides to use colors in the output (assuming it
+    // goes to a TTY).
+    printf("YES\n");
+    return 1;
+  } else {
+    // Google Test decides not to use colors in the output.
+    printf("NO\n");
+    return 0;
+  }
+}
diff --git a/protobuf/gtest/test/gtest_env_var_test.py b/protobuf/gtest/test/gtest_env_var_test.py
new file mode 100755
index 0000000..bcc0bfd
--- /dev/null
+++ b/protobuf/gtest/test/gtest_env_var_test.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Verifies that Google Test correctly parses environment variables."""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import gtest_test_utils
+
+
+IS_WINDOWS = os.name == 'nt'
+IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
+
+COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_')
+
+environ = os.environ.copy()
+
+
+def AssertEq(expected, actual):
+  if expected != actual:
+    print 'Expected: %s' % (expected,)
+    print '  Actual: %s' % (actual,)
+    raise AssertionError
+
+
+def SetEnvVar(env_var, value):
+  """Sets the env variable to 'value'; unsets it when 'value' is None."""
+
+  if value is not None:
+    environ[env_var] = value
+  elif env_var in environ:
+    del environ[env_var]
+
+
+def GetFlag(flag):
+  """Runs gtest_env_var_test_ and returns its output."""
+
+  args = [COMMAND]
+  if flag is not None:
+    args += [flag]
+  return gtest_test_utils.Subprocess(args, env=environ).output
+
+
+def TestFlag(flag, test_val, default_val):
+  """Verifies that the given flag is affected by the corresponding env var."""
+
+  env_var = 'GTEST_' + flag.upper()
+  SetEnvVar(env_var, test_val)
+  AssertEq(test_val, GetFlag(flag))
+  SetEnvVar(env_var, None)
+  AssertEq(default_val, GetFlag(flag))
+
+
+class GTestEnvVarTest(gtest_test_utils.TestCase):
+  def testEnvVarAffectsFlag(self):
+    """Tests that environment variable should affect the corresponding flag."""
+
+    TestFlag('break_on_failure', '1', '0')
+    TestFlag('color', 'yes', 'auto')
+    TestFlag('filter', 'FooTest.Bar', '*')
+    TestFlag('output', 'xml:tmp/foo.xml', '')
+    TestFlag('print_time', '0', '1')
+    TestFlag('repeat', '999', '1')
+    TestFlag('throw_on_failure', '1', '0')
+    TestFlag('death_test_style', 'threadsafe', 'fast')
+
+    if IS_WINDOWS:
+      TestFlag('catch_exceptions', '1', '0')
+
+    if IS_LINUX:
+      TestFlag('death_test_use_fork', '1', '0')
+      TestFlag('stack_trace_depth', '0', '100')
+
+
+if __name__ == '__main__':
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_env_var_test_.cc b/protobuf/gtest/test/gtest_env_var_test_.cc
new file mode 100644
index 0000000..f7c78fc
--- /dev/null
+++ b/protobuf/gtest/test/gtest_env_var_test_.cc
@@ -0,0 +1,126 @@
+// 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)
+
+// A helper program for testing that Google Test parses the environment
+// variables correctly.
+
+#include <gtest/gtest.h>
+
+#include <iostream>
+
+#define GTEST_IMPLEMENTATION_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+using ::std::cout;
+
+namespace testing {
+
+// The purpose of this is to make the test more realistic by ensuring
+// that the UnitTest singleton is created before main() is entered.
+// We don't actual run the TEST itself.
+TEST(GTestEnvVarTest, Dummy) {
+}
+
+void PrintFlag(const char* flag) {
+  if (strcmp(flag, "break_on_failure") == 0) {
+    cout << GTEST_FLAG(break_on_failure);
+    return;
+  }
+
+  if (strcmp(flag, "catch_exceptions") == 0) {
+    cout << GTEST_FLAG(catch_exceptions);
+    return;
+  }
+
+  if (strcmp(flag, "color") == 0) {
+    cout << GTEST_FLAG(color);
+    return;
+  }
+
+  if (strcmp(flag, "death_test_style") == 0) {
+    cout << GTEST_FLAG(death_test_style);
+    return;
+  }
+
+  if (strcmp(flag, "death_test_use_fork") == 0) {
+    cout << GTEST_FLAG(death_test_use_fork);
+    return;
+  }
+
+  if (strcmp(flag, "filter") == 0) {
+    cout << GTEST_FLAG(filter);
+    return;
+  }
+
+  if (strcmp(flag, "output") == 0) {
+    cout << GTEST_FLAG(output);
+    return;
+  }
+
+  if (strcmp(flag, "print_time") == 0) {
+    cout << GTEST_FLAG(print_time);
+    return;
+  }
+
+  if (strcmp(flag, "repeat") == 0) {
+    cout << GTEST_FLAG(repeat);
+    return;
+  }
+
+  if (strcmp(flag, "stack_trace_depth") == 0) {
+    cout << GTEST_FLAG(stack_trace_depth);
+    return;
+  }
+
+  if (strcmp(flag, "throw_on_failure") == 0) {
+    cout << GTEST_FLAG(throw_on_failure);
+    return;
+  }
+
+  cout << "Invalid flag name " << flag
+       << ".  Valid names are break_on_failure, color, filter, etc.\n";
+  exit(1);
+}
+
+}  // namespace testing
+
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
+
+  if (argc != 2) {
+    cout << "Usage: gtest_env_var_test_ NAME_OF_FLAG\n";
+    return 1;
+  }
+
+  testing::PrintFlag(argv[1]);
+  return 0;
+}
diff --git a/protobuf/gtest/test/gtest_environment_test.cc b/protobuf/gtest/test/gtest_environment_test.cc
new file mode 100644
index 0000000..c939261
--- /dev/null
+++ b/protobuf/gtest/test/gtest_environment_test.cc
@@ -0,0 +1,186 @@
+// 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)
+//
+// Tests using global test environments.
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <gtest/gtest.h>
+
+namespace testing {
+GTEST_DECLARE_string_(filter);
+}
+
+namespace {
+
+enum FailureType {
+  NO_FAILURE, NON_FATAL_FAILURE, FATAL_FAILURE
+};
+
+// For testing using global test environments.
+class MyEnvironment : public testing::Environment {
+ public:
+  MyEnvironment() { Reset(); }
+
+  // Depending on the value of failure_in_set_up_, SetUp() will
+  // generate a non-fatal failure, generate a fatal failure, or
+  // succeed.
+  virtual void SetUp() {
+    set_up_was_run_ = true;
+
+    switch (failure_in_set_up_) {
+      case NON_FATAL_FAILURE:
+        ADD_FAILURE() << "Expected non-fatal failure in global set-up.";
+        break;
+      case FATAL_FAILURE:
+        FAIL() << "Expected fatal failure in global set-up.";
+        break;
+      default:
+        break;
+    }
+  }
+
+  // Generates a non-fatal failure.
+  virtual void TearDown() {
+    tear_down_was_run_ = true;
+    ADD_FAILURE() << "Expected non-fatal failure in global tear-down.";
+  }
+
+  // Resets the state of the environment s.t. it can be reused.
+  void Reset() {
+    failure_in_set_up_ = NO_FAILURE;
+    set_up_was_run_ = false;
+    tear_down_was_run_ = false;
+  }
+
+  // We call this function to set the type of failure SetUp() should
+  // generate.
+  void set_failure_in_set_up(FailureType type) {
+    failure_in_set_up_ = type;
+  }
+
+  // Was SetUp() run?
+  bool set_up_was_run() const { return set_up_was_run_; }
+
+  // Was TearDown() run?
+  bool tear_down_was_run() const { return tear_down_was_run_; }
+ private:
+  FailureType failure_in_set_up_;
+  bool set_up_was_run_;
+  bool tear_down_was_run_;
+};
+
+// Was the TEST run?
+bool test_was_run;
+
+// The sole purpose of this TEST is to enable us to check whether it
+// was run.
+TEST(FooTest, Bar) {
+  test_was_run = true;
+}
+
+// Prints the message and aborts the program if condition is false.
+void Check(bool condition, const char* msg) {
+  if (!condition) {
+    printf("FAILED: %s\n", msg);
+    abort();
+  }
+}
+
+// Runs the tests.  Return true iff successful.
+//
+// The 'failure' parameter specifies the type of failure that should
+// be generated by the global set-up.
+int RunAllTests(MyEnvironment* env, FailureType failure) {
+  env->Reset();
+  env->set_failure_in_set_up(failure);
+  test_was_run = false;
+  return RUN_ALL_TESTS();
+}
+
+}  // namespace
+
+int main(int argc, char **argv) {
+  testing::InitGoogleTest(&argc, argv);
+
+  // Registers a global test environment, and verifies that the
+  // registration function returns its argument.
+  MyEnvironment* const env = new MyEnvironment;
+  Check(testing::AddGlobalTestEnvironment(env) == env,
+        "AddGlobalTestEnvironment() should return its argument.");
+
+  // Verifies that RUN_ALL_TESTS() runs the tests when the global
+  // set-up is successful.
+  Check(RunAllTests(env, NO_FAILURE) != 0,
+        "RUN_ALL_TESTS() should return non-zero, as the global tear-down "
+        "should generate a failure.");
+  Check(test_was_run,
+        "The tests should run, as the global set-up should generate no "
+        "failure");
+  Check(env->tear_down_was_run(),
+        "The global tear-down should run, as the global set-up was run.");
+
+  // Verifies that RUN_ALL_TESTS() runs the tests when the global
+  // set-up generates no fatal failure.
+  Check(RunAllTests(env, NON_FATAL_FAILURE) != 0,
+        "RUN_ALL_TESTS() should return non-zero, as both the global set-up "
+        "and the global tear-down should generate a non-fatal failure.");
+  Check(test_was_run,
+        "The tests should run, as the global set-up should generate no "
+        "fatal failure.");
+  Check(env->tear_down_was_run(),
+        "The global tear-down should run, as the global set-up was run.");
+
+  // Verifies that RUN_ALL_TESTS() runs no test when the global set-up
+  // generates a fatal failure.
+  Check(RunAllTests(env, FATAL_FAILURE) != 0,
+        "RUN_ALL_TESTS() should return non-zero, as the global set-up "
+        "should generate a fatal failure.");
+  Check(!test_was_run,
+        "The tests should not run, as the global set-up should generate "
+        "a fatal failure.");
+  Check(env->tear_down_was_run(),
+        "The global tear-down should run, as the global set-up was run.");
+
+  // Verifies that RUN_ALL_TESTS() doesn't do global set-up or
+  // tear-down when there is no test to run.
+  testing::GTEST_FLAG(filter) = "-*";
+  Check(RunAllTests(env, NO_FAILURE) == 0,
+        "RUN_ALL_TESTS() should return zero, as there is no test to run.");
+  Check(!env->set_up_was_run(),
+        "The global set-up should not run, as there is no test to run.");
+  Check(!env->tear_down_was_run(),
+        "The global tear-down should not run, "
+        "as the global set-up was not run.");
+
+  printf("PASS\n");
+  return 0;
+}
diff --git a/protobuf/gtest/test/gtest_filter_unittest.py b/protobuf/gtest/test/gtest_filter_unittest.py
new file mode 100755
index 0000000..0d1a770
--- /dev/null
+++ b/protobuf/gtest/test/gtest_filter_unittest.py
@@ -0,0 +1,633 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Unit test for Google Test test filters.
+
+A user can specify which test(s) in a Google Test program to run via either
+the GTEST_FILTER environment variable or the --gtest_filter flag.
+This script tests such functionality by invoking
+gtest_filter_unittest_ (a program written with Google Test) with different
+environments and command line flags.
+
+Note that test sharding may also influence which tests are filtered. Therefore,
+we test that here also.
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import re
+import sets
+import sys
+
+import gtest_test_utils
+
+# Constants.
+
+# Checks if this platform can pass empty environment variables to child
+# processes.  We set an env variable to an empty string and invoke a python
+# script in a subprocess to print whether the variable is STILL in
+# os.environ.  We then use 'eval' to parse the child's output so that an
+# exception is thrown if the input is anything other than 'True' nor 'False'.
+os.environ['EMPTY_VAR'] = ''
+child = gtest_test_utils.Subprocess(
+    [sys.executable, '-c', 'import os; print \'EMPTY_VAR\' in os.environ'])
+CAN_PASS_EMPTY_ENV = eval(child.output)
+
+
+# Check if this platform can unset environment variables in child processes.
+# We set an env variable to a non-empty string, unset it, and invoke
+# a python script in a subprocess to print whether the variable
+# is NO LONGER in os.environ.
+# We use 'eval' to parse the child's output so that an exception
+# is thrown if the input is neither 'True' nor 'False'.
+os.environ['UNSET_VAR'] = 'X'
+del os.environ['UNSET_VAR']
+child = gtest_test_utils.Subprocess(
+    [sys.executable, '-c', 'import os; print \'UNSET_VAR\' not in os.environ'])
+CAN_UNSET_ENV = eval(child.output)
+
+
+# Checks if we should test with an empty filter. This doesn't
+# make sense on platforms that cannot pass empty env variables (Win32)
+# and on platforms that cannot unset variables (since we cannot tell
+# the difference between "" and NULL -- Borland and Solaris < 5.10)
+CAN_TEST_EMPTY_FILTER = (CAN_PASS_EMPTY_ENV and CAN_UNSET_ENV)
+
+
+# The environment variable for specifying the test filters.
+FILTER_ENV_VAR = 'GTEST_FILTER'
+
+# The environment variables for test sharding.
+TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS'
+SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX'
+SHARD_STATUS_FILE_ENV_VAR = 'GTEST_SHARD_STATUS_FILE'
+
+# The command line flag for specifying the test filters.
+FILTER_FLAG = 'gtest_filter'
+
+# The command line flag for including disabled tests.
+ALSO_RUN_DISABED_TESTS_FLAG = 'gtest_also_run_disabled_tests'
+
+# Command to run the gtest_filter_unittest_ program.
+COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_filter_unittest_')
+
+# Regex for determining whether parameterized tests are enabled in the binary.
+PARAM_TEST_REGEX = re.compile(r'/ParamTest')
+
+# Regex for parsing test case names from Google Test's output.
+TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)')
+
+# Regex for parsing test names from Google Test's output.
+TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)')
+
+# The command line flag to tell Google Test to output the list of tests it
+# will run.
+LIST_TESTS_FLAG = '--gtest_list_tests'
+
+# Indicates whether Google Test supports death tests.
+SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess(
+    [COMMAND, LIST_TESTS_FLAG]).output
+
+# Full names of all tests in gtest_filter_unittests_.
+PARAM_TESTS = [
+    'SeqP/ParamTest.TestX/0',
+    'SeqP/ParamTest.TestX/1',
+    'SeqP/ParamTest.TestY/0',
+    'SeqP/ParamTest.TestY/1',
+    'SeqQ/ParamTest.TestX/0',
+    'SeqQ/ParamTest.TestX/1',
+    'SeqQ/ParamTest.TestY/0',
+    'SeqQ/ParamTest.TestY/1',
+    ]
+
+DISABLED_TESTS = [
+    'BarTest.DISABLED_TestFour',
+    'BarTest.DISABLED_TestFive',
+    'BazTest.DISABLED_TestC',
+    'DISABLED_FoobarTest.Test1',
+    'DISABLED_FoobarTest.DISABLED_Test2',
+    'DISABLED_FoobarbazTest.TestA',
+    ]
+
+if SUPPORTS_DEATH_TESTS:
+  DEATH_TESTS = [
+    'HasDeathTest.Test1',
+    'HasDeathTest.Test2',
+    ]
+else:
+  DEATH_TESTS = []
+
+# All the non-disabled tests.
+ACTIVE_TESTS = [
+    'FooTest.Abc',
+    'FooTest.Xyz',
+
+    'BarTest.TestOne',
+    'BarTest.TestTwo',
+    'BarTest.TestThree',
+
+    'BazTest.TestOne',
+    'BazTest.TestA',
+    'BazTest.TestB',
+    ] + DEATH_TESTS + PARAM_TESTS
+
+param_tests_present = None
+
+# Utilities.
+
+environ = os.environ.copy()
+
+
+def SetEnvVar(env_var, value):
+  """Sets the env variable to 'value'; unsets it when 'value' is None."""
+
+  if value is not None:
+    environ[env_var] = value
+  elif env_var in environ:
+    del environ[env_var]
+
+
+def RunAndReturnOutput(args = None):
+  """Runs the test program and returns its output."""
+
+  return gtest_test_utils.Subprocess([COMMAND] + (args or []),
+                                     env=environ).output
+
+
+def RunAndExtractTestList(args = None):
+  """Runs the test program and returns its exit code and a list of tests run."""
+
+  p = gtest_test_utils.Subprocess([COMMAND] + (args or []), env=environ)
+  tests_run = []
+  test_case = ''
+  test = ''
+  for line in p.output.split('\n'):
+    match = TEST_CASE_REGEX.match(line)
+    if match is not None:
+      test_case = match.group(1)
+    else:
+      match = TEST_REGEX.match(line)
+      if match is not None:
+        test = match.group(1)
+        tests_run.append(test_case + '.' + test)
+  return (tests_run, p.exit_code)
+
+
+def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs):
+  """Runs the given function and arguments in a modified environment."""
+  try:
+    original_env = environ.copy()
+    environ.update(extra_env)
+    return function(*args, **kwargs)
+  finally:
+    environ.clear()
+    environ.update(original_env)
+
+
+def RunWithSharding(total_shards, shard_index, command):
+  """Runs a test program shard and returns exit code and a list of tests run."""
+
+  extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index),
+               TOTAL_SHARDS_ENV_VAR: str(total_shards)}
+  return InvokeWithModifiedEnv(extra_env, RunAndExtractTestList, command)
+
+# The unit test.
+
+
+class GTestFilterUnitTest(gtest_test_utils.TestCase):
+  """Tests the env variable or the command line flag to filter tests."""
+
+  # Utilities.
+
+  def AssertSetEqual(self, lhs, rhs):
+    """Asserts that two sets are equal."""
+
+    for elem in lhs:
+      self.assert_(elem in rhs, '%s in %s' % (elem, rhs))
+
+    for elem in rhs:
+      self.assert_(elem in lhs, '%s in %s' % (elem, lhs))
+
+  def AssertPartitionIsValid(self, set_var, list_of_sets):
+    """Asserts that list_of_sets is a valid partition of set_var."""
+
+    full_partition = []
+    for slice_var in list_of_sets:
+      full_partition.extend(slice_var)
+    self.assertEqual(len(set_var), len(full_partition))
+    self.assertEqual(sets.Set(set_var), sets.Set(full_partition))
+
+  def AdjustForParameterizedTests(self, tests_to_run):
+    """Adjust tests_to_run in case value parameterized tests are disabled."""
+
+    global param_tests_present
+    if not param_tests_present:
+      return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS))
+    else:
+      return tests_to_run
+
+  def RunAndVerify(self, gtest_filter, tests_to_run):
+    """Checks that the binary runs correct set of tests for a given filter."""
+
+    tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
+
+    # First, tests using the environment variable.
+
+    # Windows removes empty variables from the environment when passing it
+    # to a new process.  This means it is impossible to pass an empty filter
+    # into a process using the environment variable.  However, we can still
+    # test the case when the variable is not supplied (i.e., gtest_filter is
+    # None).
+    # pylint: disable-msg=C6403
+    if CAN_TEST_EMPTY_FILTER or gtest_filter != '':
+      SetEnvVar(FILTER_ENV_VAR, gtest_filter)
+      tests_run = RunAndExtractTestList()[0]
+      SetEnvVar(FILTER_ENV_VAR, None)
+      self.AssertSetEqual(tests_run, tests_to_run)
+    # pylint: enable-msg=C6403
+
+    # Next, tests using the command line flag.
+
+    if gtest_filter is None:
+      args = []
+    else:
+      args = ['--%s=%s' % (FILTER_FLAG, gtest_filter)]
+
+    tests_run = RunAndExtractTestList(args)[0]
+    self.AssertSetEqual(tests_run, tests_to_run)
+
+  def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run,
+                               args=None, check_exit_0=False):
+    """Checks that binary runs correct tests for the given filter and shard.
+
+    Runs all shards of gtest_filter_unittest_ with the given filter, and
+    verifies that the right set of tests were run. The union of tests run
+    on each shard should be identical to tests_to_run, without duplicates.
+
+    Args:
+      gtest_filter: A filter to apply to the tests.
+      total_shards: A total number of shards to split test run into.
+      tests_to_run: A set of tests expected to run.
+      args   :      Arguments to pass to the to the test binary.
+      check_exit_0: When set to a true value, make sure that all shards
+                    return 0.
+    """
+
+    tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
+
+    # Windows removes empty variables from the environment when passing it
+    # to a new process.  This means it is impossible to pass an empty filter
+    # into a process using the environment variable.  However, we can still
+    # test the case when the variable is not supplied (i.e., gtest_filter is
+    # None).
+    # pylint: disable-msg=C6403
+    if CAN_TEST_EMPTY_FILTER or gtest_filter != '':
+      SetEnvVar(FILTER_ENV_VAR, gtest_filter)
+      partition = []
+      for i in range(0, total_shards):
+        (tests_run, exit_code) = RunWithSharding(total_shards, i, args)
+        if check_exit_0:
+          self.assertEqual(0, exit_code)
+        partition.append(tests_run)
+
+      self.AssertPartitionIsValid(tests_to_run, partition)
+      SetEnvVar(FILTER_ENV_VAR, None)
+    # pylint: enable-msg=C6403
+
+  def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run):
+    """Checks that the binary runs correct set of tests for the given filter.
+
+    Runs gtest_filter_unittest_ with the given filter, and enables
+    disabled tests. Verifies that the right set of tests were run.
+
+    Args:
+      gtest_filter: A filter to apply to the tests.
+      tests_to_run: A set of tests expected to run.
+    """
+
+    tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
+
+    # Construct the command line.
+    args = ['--%s' % ALSO_RUN_DISABED_TESTS_FLAG]
+    if gtest_filter is not None:
+      args.append('--%s=%s' % (FILTER_FLAG, gtest_filter))
+
+    tests_run = RunAndExtractTestList(args)[0]
+    self.AssertSetEqual(tests_run, tests_to_run)
+
+  def setUp(self):
+    """Sets up test case.
+
+    Determines whether value-parameterized tests are enabled in the binary and
+    sets the flags accordingly.
+    """
+
+    global param_tests_present
+    if param_tests_present is None:
+      param_tests_present = PARAM_TEST_REGEX.search(
+          RunAndReturnOutput()) is not None
+
+  def testDefaultBehavior(self):
+    """Tests the behavior of not specifying the filter."""
+
+    self.RunAndVerify(None, ACTIVE_TESTS)
+
+  def testDefaultBehaviorWithShards(self):
+    """Tests the behavior without the filter, with sharding enabled."""
+
+    self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS)
+    self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS)
+    self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS)
+    self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS), ACTIVE_TESTS)
+    self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) + 1, ACTIVE_TESTS)
+
+  def testEmptyFilter(self):
+    """Tests an empty filter."""
+
+    self.RunAndVerify('', [])
+    self.RunAndVerifyWithSharding('', 1, [])
+    self.RunAndVerifyWithSharding('', 2, [])
+
+  def testBadFilter(self):
+    """Tests a filter that matches nothing."""
+
+    self.RunAndVerify('BadFilter', [])
+    self.RunAndVerifyAllowingDisabled('BadFilter', [])
+
+  def testFullName(self):
+    """Tests filtering by full name."""
+
+    self.RunAndVerify('FooTest.Xyz', ['FooTest.Xyz'])
+    self.RunAndVerifyAllowingDisabled('FooTest.Xyz', ['FooTest.Xyz'])
+    self.RunAndVerifyWithSharding('FooTest.Xyz', 5, ['FooTest.Xyz'])
+
+  def testUniversalFilters(self):
+    """Tests filters that match everything."""
+
+    self.RunAndVerify('*', ACTIVE_TESTS)
+    self.RunAndVerify('*.*', ACTIVE_TESTS)
+    self.RunAndVerifyWithSharding('*.*', len(ACTIVE_TESTS) - 3, ACTIVE_TESTS)
+    self.RunAndVerifyAllowingDisabled('*', ACTIVE_TESTS + DISABLED_TESTS)
+    self.RunAndVerifyAllowingDisabled('*.*', ACTIVE_TESTS + DISABLED_TESTS)
+
+  def testFilterByTestCase(self):
+    """Tests filtering by test case name."""
+
+    self.RunAndVerify('FooTest.*', ['FooTest.Abc', 'FooTest.Xyz'])
+
+    BAZ_TESTS = ['BazTest.TestOne', 'BazTest.TestA', 'BazTest.TestB']
+    self.RunAndVerify('BazTest.*', BAZ_TESTS)
+    self.RunAndVerifyAllowingDisabled('BazTest.*',
+                                      BAZ_TESTS + ['BazTest.DISABLED_TestC'])
+
+  def testFilterByTest(self):
+    """Tests filtering by test name."""
+
+    self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne'])
+
+  def testFilterDisabledTests(self):
+    """Select only the disabled tests to run."""
+
+    self.RunAndVerify('DISABLED_FoobarTest.Test1', [])
+    self.RunAndVerifyAllowingDisabled('DISABLED_FoobarTest.Test1',
+                                      ['DISABLED_FoobarTest.Test1'])
+
+    self.RunAndVerify('*DISABLED_*', [])
+    self.RunAndVerifyAllowingDisabled('*DISABLED_*', DISABLED_TESTS)
+
+    self.RunAndVerify('*.DISABLED_*', [])
+    self.RunAndVerifyAllowingDisabled('*.DISABLED_*', [
+        'BarTest.DISABLED_TestFour',
+        'BarTest.DISABLED_TestFive',
+        'BazTest.DISABLED_TestC',
+        'DISABLED_FoobarTest.DISABLED_Test2',
+        ])
+
+    self.RunAndVerify('DISABLED_*', [])
+    self.RunAndVerifyAllowingDisabled('DISABLED_*', [
+        'DISABLED_FoobarTest.Test1',
+        'DISABLED_FoobarTest.DISABLED_Test2',
+        'DISABLED_FoobarbazTest.TestA',
+        ])
+
+  def testWildcardInTestCaseName(self):
+    """Tests using wildcard in the test case name."""
+
+    self.RunAndVerify('*a*.*', [
+        'BarTest.TestOne',
+        'BarTest.TestTwo',
+        'BarTest.TestThree',
+
+        'BazTest.TestOne',
+        'BazTest.TestA',
+        'BazTest.TestB', ] + DEATH_TESTS + PARAM_TESTS)
+
+  def testWildcardInTestName(self):
+    """Tests using wildcard in the test name."""
+
+    self.RunAndVerify('*.*A*', ['FooTest.Abc', 'BazTest.TestA'])
+
+  def testFilterWithoutDot(self):
+    """Tests a filter that has no '.' in it."""
+
+    self.RunAndVerify('*z*', [
+        'FooTest.Xyz',
+
+        'BazTest.TestOne',
+        'BazTest.TestA',
+        'BazTest.TestB',
+        ])
+
+  def testTwoPatterns(self):
+    """Tests filters that consist of two patterns."""
+
+    self.RunAndVerify('Foo*.*:*A*', [
+        'FooTest.Abc',
+        'FooTest.Xyz',
+
+        'BazTest.TestA',
+        ])
+
+    # An empty pattern + a non-empty one
+    self.RunAndVerify(':*A*', ['FooTest.Abc', 'BazTest.TestA'])
+
+  def testThreePatterns(self):
+    """Tests filters that consist of three patterns."""
+
+    self.RunAndVerify('*oo*:*A*:*One', [
+        'FooTest.Abc',
+        'FooTest.Xyz',
+
+        'BarTest.TestOne',
+
+        'BazTest.TestOne',
+        'BazTest.TestA',
+        ])
+
+    # The 2nd pattern is empty.
+    self.RunAndVerify('*oo*::*One', [
+        'FooTest.Abc',
+        'FooTest.Xyz',
+
+        'BarTest.TestOne',
+
+        'BazTest.TestOne',
+        ])
+
+    # The last 2 patterns are empty.
+    self.RunAndVerify('*oo*::', [
+        'FooTest.Abc',
+        'FooTest.Xyz',
+        ])
+
+  def testNegativeFilters(self):
+    self.RunAndVerify('*-BazTest.TestOne', [
+        'FooTest.Abc',
+        'FooTest.Xyz',
+
+        'BarTest.TestOne',
+        'BarTest.TestTwo',
+        'BarTest.TestThree',
+
+        'BazTest.TestA',
+        'BazTest.TestB',
+        ] + DEATH_TESTS + PARAM_TESTS)
+
+    self.RunAndVerify('*-FooTest.Abc:BazTest.*', [
+        'FooTest.Xyz',
+
+        'BarTest.TestOne',
+        'BarTest.TestTwo',
+        'BarTest.TestThree',
+        ] + DEATH_TESTS + PARAM_TESTS)
+
+    self.RunAndVerify('BarTest.*-BarTest.TestOne', [
+        'BarTest.TestTwo',
+        'BarTest.TestThree',
+        ])
+
+    # Tests without leading '*'.
+    self.RunAndVerify('-FooTest.Abc:FooTest.Xyz:BazTest.*', [
+        'BarTest.TestOne',
+        'BarTest.TestTwo',
+        'BarTest.TestThree',
+        ] + DEATH_TESTS + PARAM_TESTS)
+
+    # Value parameterized tests.
+    self.RunAndVerify('*/*', PARAM_TESTS)
+
+    # Value parameterized tests filtering by the sequence name.
+    self.RunAndVerify('SeqP/*', [
+        'SeqP/ParamTest.TestX/0',
+        'SeqP/ParamTest.TestX/1',
+        'SeqP/ParamTest.TestY/0',
+        'SeqP/ParamTest.TestY/1',
+        ])
+
+    # Value parameterized tests filtering by the test name.
+    self.RunAndVerify('*/0', [
+        'SeqP/ParamTest.TestX/0',
+        'SeqP/ParamTest.TestY/0',
+        'SeqQ/ParamTest.TestX/0',
+        'SeqQ/ParamTest.TestY/0',
+        ])
+
+  def testFlagOverridesEnvVar(self):
+    """Tests that the filter flag overrides the filtering env. variable."""
+
+    SetEnvVar(FILTER_ENV_VAR, 'Foo*')
+    args = ['--%s=%s' % (FILTER_FLAG, '*One')]
+    tests_run = RunAndExtractTestList(args)[0]
+    SetEnvVar(FILTER_ENV_VAR, None)
+
+    self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne'])
+
+  def testShardStatusFileIsCreated(self):
+    """Tests that the shard file is created if specified in the environment."""
+
+    shard_status_file = os.path.join(gtest_test_utils.GetTempDir(),
+                                     'shard_status_file')
+    self.assert_(not os.path.exists(shard_status_file))
+
+    extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
+    try:
+      InvokeWithModifiedEnv(extra_env, RunAndReturnOutput)
+    finally:
+      self.assert_(os.path.exists(shard_status_file))
+      os.remove(shard_status_file)
+
+  def testShardStatusFileIsCreatedWithListTests(self):
+    """Tests that the shard file is created with the "list_tests" flag."""
+
+    shard_status_file = os.path.join(gtest_test_utils.GetTempDir(),
+                                     'shard_status_file2')
+    self.assert_(not os.path.exists(shard_status_file))
+
+    extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
+    try:
+      output = InvokeWithModifiedEnv(extra_env,
+                                     RunAndReturnOutput,
+                                     [LIST_TESTS_FLAG])
+    finally:
+      # This assertion ensures that Google Test enumerated the tests as
+      # opposed to running them.
+      self.assert_('[==========]' not in output,
+                   'Unexpected output during test enumeration.\n'
+                   'Please ensure that LIST_TESTS_FLAG is assigned the\n'
+                   'correct flag value for listing Google Test tests.')
+
+      self.assert_(os.path.exists(shard_status_file))
+      os.remove(shard_status_file)
+
+  if SUPPORTS_DEATH_TESTS:
+    def testShardingWorksWithDeathTests(self):
+      """Tests integration with death tests and sharding."""
+
+      gtest_filter = 'HasDeathTest.*:SeqP/*'
+      expected_tests = [
+          'HasDeathTest.Test1',
+          'HasDeathTest.Test2',
+
+          'SeqP/ParamTest.TestX/0',
+          'SeqP/ParamTest.TestX/1',
+          'SeqP/ParamTest.TestY/0',
+          'SeqP/ParamTest.TestY/1',
+          ]
+
+      for flag in ['--gtest_death_test_style=threadsafe',
+                   '--gtest_death_test_style=fast']:
+        self.RunAndVerifyWithSharding(gtest_filter, 3, expected_tests,
+                                      check_exit_0=True, args=[flag])
+        self.RunAndVerifyWithSharding(gtest_filter, 5, expected_tests,
+                                      check_exit_0=True, args=[flag])
+
+if __name__ == '__main__':
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_filter_unittest_.cc b/protobuf/gtest/test/gtest_filter_unittest_.cc
new file mode 100644
index 0000000..325504f
--- /dev/null
+++ b/protobuf/gtest/test/gtest_filter_unittest_.cc
@@ -0,0 +1,140 @@
+// 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)
+
+// Unit test for Google Test test filters.
+//
+// A user can specify which test(s) in a Google Test program to run via
+// either the GTEST_FILTER environment variable or the --gtest_filter
+// flag.  This is used for testing such functionality.
+//
+// The program will be invoked from a Python unit test.  Don't run it
+// directly.
+
+#include <gtest/gtest.h>
+
+namespace {
+
+// Test case FooTest.
+
+class FooTest : public testing::Test {
+};
+
+TEST_F(FooTest, Abc) {
+}
+
+TEST_F(FooTest, Xyz) {
+  FAIL() << "Expected failure.";
+}
+
+// Test case BarTest.
+
+TEST(BarTest, TestOne) {
+}
+
+TEST(BarTest, TestTwo) {
+}
+
+TEST(BarTest, TestThree) {
+}
+
+TEST(BarTest, DISABLED_TestFour) {
+  FAIL() << "Expected failure.";
+}
+
+TEST(BarTest, DISABLED_TestFive) {
+  FAIL() << "Expected failure.";
+}
+
+// Test case BazTest.
+
+TEST(BazTest, TestOne) {
+  FAIL() << "Expected failure.";
+}
+
+TEST(BazTest, TestA) {
+}
+
+TEST(BazTest, TestB) {
+}
+
+TEST(BazTest, DISABLED_TestC) {
+  FAIL() << "Expected failure.";
+}
+
+// Test case HasDeathTest
+
+TEST(HasDeathTest, Test1) {
+  EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*");
+}
+
+// We need at least two death tests to make sure that the all death tests
+// aren't on the first shard.
+TEST(HasDeathTest, Test2) {
+  EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*");
+}
+
+// Test case FoobarTest
+
+TEST(DISABLED_FoobarTest, Test1) {
+  FAIL() << "Expected failure.";
+}
+
+TEST(DISABLED_FoobarTest, DISABLED_Test2) {
+  FAIL() << "Expected failure.";
+}
+
+// Test case FoobarbazTest
+
+TEST(DISABLED_FoobarbazTest, TestA) {
+  FAIL() << "Expected failure.";
+}
+
+#if GTEST_HAS_PARAM_TEST
+class ParamTest : public testing::TestWithParam<int> {
+};
+
+TEST_P(ParamTest, TestX) {
+}
+
+TEST_P(ParamTest, TestY) {
+}
+
+INSTANTIATE_TEST_CASE_P(SeqP, ParamTest, testing::Values(1, 2));
+INSTANTIATE_TEST_CASE_P(SeqQ, ParamTest, testing::Values(5, 6));
+#endif  // GTEST_HAS_PARAM_TEST
+
+}  // namespace
+
+int main(int argc, char **argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/test/gtest_help_test.py b/protobuf/gtest/test/gtest_help_test.py
new file mode 100755
index 0000000..3cb4c48
--- /dev/null
+++ b/protobuf/gtest/test/gtest_help_test.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+#
+# Copyright 2009, 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.
+
+"""Tests the --help flag of Google C++ Testing Framework.
+
+SYNOPSIS
+       gtest_help_test.py --gtest_build_dir=BUILD/DIR
+         # where BUILD/DIR contains the built gtest_help_test_ file.
+       gtest_help_test.py
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import re
+import gtest_test_utils
+
+
+IS_WINDOWS = os.name == 'nt'
+
+PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_help_test_')
+FLAG_PREFIX = '--gtest_'
+CATCH_EXCEPTIONS_FLAG = FLAG_PREFIX + 'catch_exceptions'
+DEATH_TEST_STYLE_FLAG = FLAG_PREFIX + 'death_test_style'
+UNKNOWN_FLAG = FLAG_PREFIX + 'unknown_flag_for_testing'
+LIST_TESTS_FLAG = FLAG_PREFIX + 'list_tests'
+INCORRECT_FLAG_VARIANTS = [re.sub('^--', '-', LIST_TESTS_FLAG),
+                           re.sub('^--', '/', LIST_TESTS_FLAG),
+                           re.sub('_', '-', LIST_TESTS_FLAG)]
+INTERNAL_FLAG_FOR_TESTING = FLAG_PREFIX + 'internal_flag_for_testing'
+
+SUPPORTS_DEATH_TESTS = "DeathTest" in gtest_test_utils.Subprocess(
+    [PROGRAM_PATH, LIST_TESTS_FLAG]).output
+
+# The help message must match this regex.
+HELP_REGEX = re.compile(
+    FLAG_PREFIX + r'list_tests.*' +
+    FLAG_PREFIX + r'filter=.*' +
+    FLAG_PREFIX + r'also_run_disabled_tests.*' +
+    FLAG_PREFIX + r'repeat=.*' +
+    FLAG_PREFIX + r'shuffle.*' +
+    FLAG_PREFIX + r'random_seed=.*' +
+    FLAG_PREFIX + r'color=.*' +
+    FLAG_PREFIX + r'print_time.*' +
+    FLAG_PREFIX + r'output=.*' +
+    FLAG_PREFIX + r'break_on_failure.*' +
+    FLAG_PREFIX + r'throw_on_failure.*',
+    re.DOTALL)
+
+
+def RunWithFlag(flag):
+  """Runs gtest_help_test_ with the given flag.
+
+  Returns:
+    the exit code and the text output as a tuple.
+  Args:
+    flag: the command-line flag to pass to gtest_help_test_, or None.
+  """
+
+  if flag is None:
+    command = [PROGRAM_PATH]
+  else:
+    command = [PROGRAM_PATH, flag]
+  child = gtest_test_utils.Subprocess(command)
+  return child.exit_code, child.output
+
+
+class GTestHelpTest(gtest_test_utils.TestCase):
+  """Tests the --help flag and its equivalent forms."""
+
+  def TestHelpFlag(self, flag):
+    """Verifies correct behavior when help flag is specified.
+
+    The right message must be printed and the tests must
+    skipped when the given flag is specified.
+
+    Args:
+      flag:  A flag to pass to the binary or None.
+    """
+
+    exit_code, output = RunWithFlag(flag)
+    self.assertEquals(0, exit_code)
+    self.assert_(HELP_REGEX.search(output), output)
+    if IS_WINDOWS:
+      self.assert_(CATCH_EXCEPTIONS_FLAG in output, output)
+    else:
+      self.assert_(CATCH_EXCEPTIONS_FLAG not in output, output)
+
+    if SUPPORTS_DEATH_TESTS and not IS_WINDOWS:
+      self.assert_(DEATH_TEST_STYLE_FLAG in output, output)
+    else:
+      self.assert_(DEATH_TEST_STYLE_FLAG not in output, output)
+
+  def TestNonHelpFlag(self, flag):
+    """Verifies correct behavior when no help flag is specified.
+
+    Verifies that when no help flag is specified, the tests are run
+    and the help message is not printed.
+
+    Args:
+      flag:  A flag to pass to the binary or None.
+    """
+
+    exit_code, output = RunWithFlag(flag)
+    self.assert_(exit_code != 0)
+    self.assert_(not HELP_REGEX.search(output), output)
+
+  def testPrintsHelpWithFullFlag(self):
+    self.TestHelpFlag('--help')
+
+  def testPrintsHelpWithShortFlag(self):
+    self.TestHelpFlag('-h')
+
+  def testPrintsHelpWithQuestionFlag(self):
+    self.TestHelpFlag('-?')
+
+  def testPrintsHelpWithWindowsStyleQuestionFlag(self):
+    self.TestHelpFlag('/?')
+
+  def testPrintsHelpWithUnrecognizedGoogleTestFlag(self):
+    self.TestHelpFlag(UNKNOWN_FLAG)
+
+  def testPrintsHelpWithIncorrectFlagStyle(self):
+    for incorrect_flag in INCORRECT_FLAG_VARIANTS:
+      self.TestHelpFlag(incorrect_flag)
+
+  def testRunsTestsWithoutHelpFlag(self):
+    """Verifies that when no help flag is specified, the tests are run
+    and the help message is not printed."""
+
+    self.TestNonHelpFlag(None)
+
+  def testRunsTestsWithGtestInternalFlag(self):
+    """Verifies that the tests are run and no help message is printed when
+    a flag starting with Google Test prefix and 'internal_' is supplied."""
+
+    self.TestNonHelpFlag(INTERNAL_FLAG_FOR_TESTING)
+
+
+if __name__ == '__main__':
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_help_test_.cc b/protobuf/gtest/test/gtest_help_test_.cc
new file mode 100644
index 0000000..aad0d72
--- /dev/null
+++ b/protobuf/gtest/test/gtest_help_test_.cc
@@ -0,0 +1,46 @@
+// Copyright 2009, 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 program is meant to be run by gtest_help_test.py.  Do not run
+// it directly.
+
+#include <gtest/gtest.h>
+
+// When a help flag is specified, this program should skip the tests
+// and exit with 0; otherwise the following test will be executed,
+// causing this program to exit with a non-zero code.
+TEST(HelpFlagTest, ShouldNotBeRun) {
+  ASSERT_TRUE(false) << "Tests shouldn't be run when --help is specified.";
+}
+
+#if GTEST_HAS_DEATH_TEST
+TEST(DeathTest, UsedByPythonScriptToDetectSupportForDeathTestsInThisBinary) {}
+#endif
diff --git a/protobuf/gtest/test/gtest_list_tests_unittest.py b/protobuf/gtest/test/gtest_list_tests_unittest.py
new file mode 100755
index 0000000..ce8c3ef
--- /dev/null
+++ b/protobuf/gtest/test/gtest_list_tests_unittest.py
@@ -0,0 +1,177 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Unit test for Google Test's --gtest_list_tests flag.
+
+A user can ask Google Test to list all tests by specifying the
+--gtest_list_tests flag.  This script tests such functionality
+by invoking gtest_list_tests_unittest_ (a program written with
+Google Test) the command line flags.
+"""
+
+__author__ = 'phanna@google.com (Patrick Hanna)'
+
+import gtest_test_utils
+
+
+# Constants.
+
+# The command line flag for enabling/disabling listing all tests.
+LIST_TESTS_FLAG = 'gtest_list_tests'
+
+# Path to the gtest_list_tests_unittest_ program.
+EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_list_tests_unittest_')
+
+# The expected output when running gtest_list_tests_unittest_ with
+# --gtest_list_tests
+EXPECTED_OUTPUT_NO_FILTER = """FooDeathTest.
+  Test1
+Foo.
+  Bar1
+  Bar2
+  DISABLED_Bar3
+Abc.
+  Xyz
+  Def
+FooBar.
+  Baz
+FooTest.
+  Test1
+  DISABLED_Test2
+  Test3
+"""
+
+# The expected output when running gtest_list_tests_unittest_ with
+# --gtest_list_tests and --gtest_filter=Foo*.
+EXPECTED_OUTPUT_FILTER_FOO = """FooDeathTest.
+  Test1
+Foo.
+  Bar1
+  Bar2
+  DISABLED_Bar3
+FooBar.
+  Baz
+FooTest.
+  Test1
+  DISABLED_Test2
+  Test3
+"""
+
+# Utilities.
+
+
+def Run(args):
+  """Runs gtest_list_tests_unittest_ and returns the list of tests printed."""
+
+  return gtest_test_utils.Subprocess([EXE_PATH] + args,
+                                     capture_stderr=False).output
+
+
+# The unit test.
+
+class GTestListTestsUnitTest(gtest_test_utils.TestCase):
+  """Tests using the --gtest_list_tests flag to list all tests."""
+
+  def RunAndVerify(self, flag_value, expected_output, other_flag):
+    """Runs gtest_list_tests_unittest_ and verifies that it prints
+    the correct tests.
+
+    Args:
+      flag_value:       value of the --gtest_list_tests flag;
+                        None if the flag should not be present.
+
+      expected_output:  the expected output after running command;
+
+      other_flag:       a different flag to be passed to command
+                        along with gtest_list_tests;
+                        None if the flag should not be present.
+    """
+
+    if flag_value is None:
+      flag = ''
+      flag_expression = 'not set'
+    elif flag_value == '0':
+      flag = '--%s=0' % LIST_TESTS_FLAG
+      flag_expression = '0'
+    else:
+      flag = '--%s' % LIST_TESTS_FLAG
+      flag_expression = '1'
+
+    args = [flag]
+
+    if other_flag is not None:
+      args += [other_flag]
+
+    output = Run(args)
+
+    msg = ('when %s is %s, the output of "%s" is "%s".' %
+           (LIST_TESTS_FLAG, flag_expression, ' '.join(args), output))
+
+    if expected_output is not None:
+      self.assert_(output == expected_output, msg)
+    else:
+      self.assert_(output != EXPECTED_OUTPUT_NO_FILTER, msg)
+
+  def testDefaultBehavior(self):
+    """Tests the behavior of the default mode."""
+
+    self.RunAndVerify(flag_value=None,
+                      expected_output=None,
+                      other_flag=None)
+
+  def testFlag(self):
+    """Tests using the --gtest_list_tests flag."""
+
+    self.RunAndVerify(flag_value='0',
+                      expected_output=None,
+                      other_flag=None)
+    self.RunAndVerify(flag_value='1',
+                      expected_output=EXPECTED_OUTPUT_NO_FILTER,
+                      other_flag=None)
+
+  def testOverrideNonFilterFlags(self):
+    """Tests that --gtest_list_tests overrides the non-filter flags."""
+
+    self.RunAndVerify(flag_value='1',
+                      expected_output=EXPECTED_OUTPUT_NO_FILTER,
+                      other_flag='--gtest_break_on_failure')
+
+  def testWithFilterFlags(self):
+    """Tests that --gtest_list_tests takes into account the
+    --gtest_filter flag."""
+
+    self.RunAndVerify(flag_value='1',
+                      expected_output=EXPECTED_OUTPUT_FILTER_FOO,
+                      other_flag='--gtest_filter=Foo*')
+
+
+if __name__ == '__main__':
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_list_tests_unittest_.cc b/protobuf/gtest/test/gtest_list_tests_unittest_.cc
new file mode 100644
index 0000000..a0ed082
--- /dev/null
+++ b/protobuf/gtest/test/gtest_list_tests_unittest_.cc
@@ -0,0 +1,85 @@
+// 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: phanna@google.com (Patrick Hanna)
+
+// Unit test for Google Test's --gtest_list_tests flag.
+//
+// A user can ask Google Test to list all tests that will run
+// so that when using a filter, a user will know what
+// tests to look for. The tests will not be run after listing.
+//
+// This program will be invoked from a Python unit test.
+// Don't run it directly.
+
+#include <gtest/gtest.h>
+
+namespace {
+
+// Several different test cases and tests that will be listed.
+TEST(Foo, Bar1) {
+}
+
+TEST(Foo, Bar2) {
+}
+
+TEST(Foo, DISABLED_Bar3) {
+}
+
+TEST(Abc, Xyz) {
+}
+
+TEST(Abc, Def) {
+}
+
+TEST(FooBar, Baz) {
+}
+
+class FooTest : public testing::Test {
+};
+
+TEST_F(FooTest, Test1) {
+}
+
+TEST_F(FooTest, DISABLED_Test2) {
+}
+
+TEST_F(FooTest, Test3) {
+}
+
+TEST(FooDeathTest, Test1) {
+}
+
+}  // namespace
+
+int main(int argc, char **argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/test/gtest_main_unittest.cc b/protobuf/gtest/test/gtest_main_unittest.cc
new file mode 100644
index 0000000..7a3f0ad
--- /dev/null
+++ b/protobuf/gtest/test/gtest_main_unittest.cc
@@ -0,0 +1,45 @@
+// 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)
+
+#include <gtest/gtest.h>
+
+// Tests that we don't have to define main() when we link to
+// gtest_main instead of gtest.
+
+namespace {
+
+TEST(GTestMainTest, ShouldSucceed) {
+}
+
+}  // namespace
+
+// We are using the main() function defined in src/gtest_main.cc, so
+// we don't define it here.
diff --git a/protobuf/gtest/test/gtest_no_test_unittest.cc b/protobuf/gtest/test/gtest_no_test_unittest.cc
new file mode 100644
index 0000000..afe2dc0
--- /dev/null
+++ b/protobuf/gtest/test/gtest_no_test_unittest.cc
@@ -0,0 +1,54 @@
+// 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.
+
+// Tests that a Google Test program that has no test defined can run
+// successfully.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#include <gtest/gtest.h>
+
+
+int main(int argc, char **argv) {
+  testing::InitGoogleTest(&argc, argv);
+
+  // An ad-hoc assertion outside of all tests.
+  //
+  // This serves two purposes:
+  //
+  // 1. It verifies that an ad-hoc assertion can be executed even if
+  //    no test is defined.
+  // 2. We had a bug where the XML output won't be generated if an
+  //    assertion is executed before RUN_ALL_TESTS() is called, even
+  //    though --gtest_output=xml is specified.  This makes sure the
+  //    bug is fixed and doesn't regress.
+  EXPECT_EQ(1, 1);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/test/gtest_output_test.py b/protobuf/gtest/test/gtest_output_test.py
new file mode 100755
index 0000000..192030a
--- /dev/null
+++ b/protobuf/gtest/test/gtest_output_test.py
@@ -0,0 +1,327 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Tests the text output of Google C++ Testing Framework.
+
+SYNOPSIS
+       gtest_output_test.py --gtest_build_dir=BUILD/DIR --gengolden
+         # where BUILD/DIR contains the built gtest_output_test_ file.
+       gtest_output_test.py --gengolden
+       gtest_output_test.py
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import re
+import sys
+import gtest_test_utils
+
+
+# The flag for generating the golden file
+GENGOLDEN_FLAG = '--gengolden'
+CATCH_EXCEPTIONS_ENV_VAR_NAME = 'GTEST_CATCH_EXCEPTIONS'
+
+IS_WINDOWS = os.name == 'nt'
+
+if IS_WINDOWS:
+  GOLDEN_NAME = 'gtest_output_test_golden_win.txt'
+else:
+  GOLDEN_NAME = 'gtest_output_test_golden_lin.txt'
+
+PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath('gtest_output_test_')
+
+# At least one command we exercise must not have the
+# --gtest_internal_skip_environment_and_ad_hoc_tests flag.
+COMMAND_LIST_TESTS = ({}, [PROGRAM_PATH, '--gtest_list_tests'])
+COMMAND_WITH_COLOR = ({}, [PROGRAM_PATH, '--gtest_color=yes'])
+COMMAND_WITH_TIME = ({}, [PROGRAM_PATH,
+                          '--gtest_print_time',
+                          '--gtest_internal_skip_environment_and_ad_hoc_tests',
+                          '--gtest_filter=FatalFailureTest.*:LoggingTest.*'])
+COMMAND_WITH_DISABLED = (
+    {}, [PROGRAM_PATH,
+         '--gtest_also_run_disabled_tests',
+         '--gtest_internal_skip_environment_and_ad_hoc_tests',
+         '--gtest_filter=*DISABLED_*'])
+COMMAND_WITH_SHARDING = (
+    {'GTEST_SHARD_INDEX': '1', 'GTEST_TOTAL_SHARDS': '2'},
+    [PROGRAM_PATH,
+     '--gtest_internal_skip_environment_and_ad_hoc_tests',
+     '--gtest_filter=PassingTest.*'])
+
+GOLDEN_PATH = os.path.join(gtest_test_utils.GetSourceDir(), GOLDEN_NAME)
+
+
+def ToUnixLineEnding(s):
+  """Changes all Windows/Mac line endings in s to UNIX line endings."""
+
+  return s.replace('\r\n', '\n').replace('\r', '\n')
+
+
+def RemoveLocations(test_output):
+  """Removes all file location info from a Google Test program's output.
+
+  Args:
+       test_output:  the output of a Google Test program.
+
+  Returns:
+       output with all file location info (in the form of
+       'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or
+       'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by
+       'FILE_NAME:#: '.
+  """
+
+  return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output)
+
+
+def RemoveStackTraceDetails(output):
+  """Removes all stack traces from a Google Test program's output."""
+
+  # *? means "find the shortest string that matches".
+  return re.sub(r'Stack trace:(.|\n)*?\n\n',
+                'Stack trace: (omitted)\n\n', output)
+
+
+def RemoveStackTraces(output):
+  """Removes all traces of stack traces from a Google Test program's output."""
+
+  # *? means "find the shortest string that matches".
+  return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output)
+
+
+def RemoveTime(output):
+  """Removes all time information from a Google Test program's output."""
+
+  return re.sub(r'\(\d+ ms', '(? ms', output)
+
+
+def RemoveTypeInfoDetails(test_output):
+  """Removes compiler-specific type info from Google Test program's output.
+
+  Args:
+       test_output:  the output of a Google Test program.
+
+  Returns:
+       output with type information normalized to canonical form.
+  """
+
+  # some compilers output the name of type 'unsigned int' as 'unsigned'
+  return re.sub(r'unsigned int', 'unsigned', test_output)
+
+
+def RemoveTestCounts(output):
+  """Removes test counts from a Google Test program's output."""
+
+  output = re.sub(r'\d+ tests?, listed below',
+                  '? tests, listed below', output)
+  output = re.sub(r'\d+ FAILED TESTS',
+                  '? FAILED TESTS', output)
+  output = re.sub(r'\d+ tests? from \d+ test cases?',
+                  '? tests from ? test cases', output)
+  output = re.sub(r'\d+ tests? from ([a-zA-Z_])',
+                  r'? tests from \1', output)
+  return re.sub(r'\d+ tests?\.', '? tests.', output)
+
+
+def RemoveMatchingTests(test_output, pattern):
+  """Removes output of specified tests from a Google Test program's output.
+
+  This function strips not only the beginning and the end of a test but also
+  all output in between.
+
+  Args:
+    test_output:       A string containing the test output.
+    pattern:           A regex string that matches names of test cases or
+                       tests to remove.
+
+  Returns:
+    Contents of test_output with tests whose names match pattern removed.
+  """
+
+  test_output = re.sub(
+      r'.*\[ RUN      \] .*%s(.|\n)*?\[(  FAILED  |       OK )\] .*%s.*\n' % (
+          pattern, pattern),
+      '',
+      test_output)
+  return re.sub(r'.*%s.*\n' % pattern, '', test_output)
+
+
+def NormalizeOutput(output):
+  """Normalizes output (the output of gtest_output_test_.exe)."""
+
+  output = ToUnixLineEnding(output)
+  output = RemoveLocations(output)
+  output = RemoveStackTraceDetails(output)
+  output = RemoveTime(output)
+  return output
+
+
+def GetShellCommandOutput(env_cmd):
+  """Runs a command in a sub-process, and returns its output in a string.
+
+  Args:
+    env_cmd: The shell command. A 2-tuple where element 0 is a dict of extra
+             environment variables to set, and element 1 is a string with
+             the command and any flags.
+
+  Returns:
+    A string with the command's combined standard and diagnostic output.
+  """
+
+  # Spawns cmd in a sub-process, and gets its standard I/O file objects.
+  # Set and save the environment properly.
+  environ = os.environ.copy()
+  environ.update(env_cmd[0])
+  p = gtest_test_utils.Subprocess(env_cmd[1], env=environ)
+
+  return p.output
+
+
+def GetCommandOutput(env_cmd):
+  """Runs a command and returns its output with all file location
+  info stripped off.
+
+  Args:
+    env_cmd:  The shell command. A 2-tuple where element 0 is a dict of extra
+              environment variables to set, and element 1 is a string with
+              the command and any flags.
+  """
+
+  # Disables exception pop-ups on Windows.
+  environ, cmdline = env_cmd
+  environ = dict(environ)  # Ensures we are modifying a copy.
+  environ[CATCH_EXCEPTIONS_ENV_VAR_NAME] = '1'
+  return NormalizeOutput(GetShellCommandOutput((environ, cmdline)))
+
+
+def GetOutputOfAllCommands():
+  """Returns concatenated output from several representative commands."""
+
+  return (GetCommandOutput(COMMAND_WITH_COLOR) +
+          GetCommandOutput(COMMAND_WITH_TIME) +
+          GetCommandOutput(COMMAND_WITH_DISABLED) +
+          GetCommandOutput(COMMAND_WITH_SHARDING))
+
+
+test_list = GetShellCommandOutput(COMMAND_LIST_TESTS)
+SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list
+SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list
+SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list
+SUPPORTS_STACK_TRACES = False
+
+CAN_GENERATE_GOLDEN_FILE = (SUPPORTS_DEATH_TESTS and
+                            SUPPORTS_TYPED_TESTS and
+                            SUPPORTS_THREADS)
+
+
+class GTestOutputTest(gtest_test_utils.TestCase):
+  def RemoveUnsupportedTests(self, test_output):
+    if not SUPPORTS_DEATH_TESTS:
+      test_output = RemoveMatchingTests(test_output, 'DeathTest')
+    if not SUPPORTS_TYPED_TESTS:
+      test_output = RemoveMatchingTests(test_output, 'TypedTest')
+      test_output = RemoveMatchingTests(test_output, 'TypedDeathTest')
+      test_output = RemoveMatchingTests(test_output, 'TypeParamDeathTest')
+    if not SUPPORTS_THREADS:
+      test_output = RemoveMatchingTests(test_output,
+                                        'ExpectFailureWithThreadsTest')
+      test_output = RemoveMatchingTests(test_output,
+                                        'ScopedFakeTestPartResultReporterTest')
+      test_output = RemoveMatchingTests(test_output,
+                                        'WorksConcurrently')
+    if not SUPPORTS_STACK_TRACES:
+      test_output = RemoveStackTraces(test_output)
+
+    return test_output
+
+  def testOutput(self):
+    output = GetOutputOfAllCommands()
+
+    golden_file = open(GOLDEN_PATH, 'rb')
+    # A mis-configured source control system can cause \r appear in EOL
+    # sequences when we read the golden file irrespective of an operating
+    # system used. Therefore, we need to strip those \r's from newlines
+    # unconditionally.
+    golden = ToUnixLineEnding(golden_file.read())
+    golden_file.close()
+
+    # We want the test to pass regardless of certain features being
+    # supported or not.
+
+    # We still have to remove type name specifics in all cases.
+    normalized_actual = RemoveTypeInfoDetails(output)
+    normalized_golden = RemoveTypeInfoDetails(golden)
+
+    if CAN_GENERATE_GOLDEN_FILE:
+      self.assertEqual(normalized_golden, normalized_actual)
+    else:
+      normalized_actual = RemoveTestCounts(normalized_actual)
+      normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(
+          normalized_golden))
+
+      # This code is very handy when debugging golden file differences:
+      if os.getenv('DEBUG_GTEST_OUTPUT_TEST'):
+        open(os.path.join(
+            gtest_test_utils.GetSourceDir(),
+            '_gtest_output_test_normalized_actual.txt'), 'wb').write(
+                normalized_actual)
+        open(os.path.join(
+            gtest_test_utils.GetSourceDir(),
+            '_gtest_output_test_normalized_golden.txt'), 'wb').write(
+                normalized_golden)
+
+      self.assertEqual(normalized_golden, normalized_actual)
+
+
+if __name__ == '__main__':
+  if sys.argv[1:] == [GENGOLDEN_FLAG]:
+    if CAN_GENERATE_GOLDEN_FILE:
+      output = GetOutputOfAllCommands()
+      golden_file = open(GOLDEN_PATH, 'wb')
+      golden_file.write(output)
+      golden_file.close()
+    else:
+      message = (
+          """Unable to write a golden file when compiled in an environment
+that does not support all the required features (death tests""")
+      if IS_WINDOWS:
+        message += (
+            """\nand typed tests). Please check that you are using VC++ 8.0 SP1
+or higher as your compiler.""")
+      else:
+        message += """\ntyped tests, and threads).  Please generate the
+golden file using a binary built with those features enabled."""
+
+      sys.stderr.write(message)
+      sys.exit(1)
+  else:
+    gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_output_test_.cc b/protobuf/gtest/test/gtest_output_test_.cc
new file mode 100644
index 0000000..273e8e9
--- /dev/null
+++ b/protobuf/gtest/test/gtest_output_test_.cc
@@ -0,0 +1,1135 @@
+// 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.
+//
+// A unit test for Google Test itself.  This verifies that the basic
+// constructs of Google Test work.
+//
+// Author: wan@google.com (Zhanyong Wan)
+
+#include <gtest/gtest-spi.h>
+#include <gtest/gtest.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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+#include <stdlib.h>
+
+#if GTEST_IS_THREADSAFE
+using testing::ScopedFakeTestPartResultReporter;
+using testing::TestPartResultArray;
+
+using testing::internal::Notification;
+using testing::internal::ThreadWithParam;
+#endif
+
+namespace posix = ::testing::internal::posix;
+using testing::internal::String;
+using testing::internal::scoped_ptr;
+
+// Tests catching fatal failures.
+
+// A subroutine used by the following test.
+void TestEq1(int x) {
+  ASSERT_EQ(1, x);
+}
+
+// This function calls a test subroutine, catches the fatal failure it
+// generates, and then returns early.
+void TryTestSubroutine() {
+  // Calls a subrountine that yields a fatal failure.
+  TestEq1(2);
+
+  // Catches the fatal failure and aborts the test.
+  //
+  // The testing::Test:: prefix is necessary when calling
+  // HasFatalFailure() outside of a TEST, TEST_F, or test fixture.
+  if (testing::Test::HasFatalFailure()) return;
+
+  // If we get here, something is wrong.
+  FAIL() << "This should never be reached.";
+}
+
+TEST(PassingTest, PassingTest1) {
+}
+
+TEST(PassingTest, PassingTest2) {
+}
+
+// Tests catching a fatal failure in a subroutine.
+TEST(FatalFailureTest, FatalFailureInSubroutine) {
+  printf("(expecting a failure that x should be 1)\n");
+
+  TryTestSubroutine();
+}
+
+// Tests catching a fatal failure in a nested subroutine.
+TEST(FatalFailureTest, FatalFailureInNestedSubroutine) {
+  printf("(expecting a failure that x should be 1)\n");
+
+  // Calls a subrountine that yields a fatal failure.
+  TryTestSubroutine();
+
+  // Catches the fatal failure and aborts the test.
+  //
+  // When calling HasFatalFailure() inside a TEST, TEST_F, or test
+  // fixture, the testing::Test:: prefix is not needed.
+  if (HasFatalFailure()) return;
+
+  // If we get here, something is wrong.
+  FAIL() << "This should never be reached.";
+}
+
+// Tests HasFatalFailure() after a failed EXPECT check.
+TEST(FatalFailureTest, NonfatalFailureInSubroutine) {
+  printf("(expecting a failure on false)\n");
+  EXPECT_TRUE(false);  // Generates a nonfatal failure
+  ASSERT_FALSE(HasFatalFailure());  // This should succeed.
+}
+
+// Tests interleaving user logging and Google Test assertions.
+TEST(LoggingTest, InterleavingLoggingAndAssertions) {
+  static const int a[4] = {
+    3, 9, 2, 6
+  };
+
+  printf("(expecting 2 failures on (3) >= (a[i]))\n");
+  for (int i = 0; i < static_cast<int>(sizeof(a)/sizeof(*a)); i++) {
+    printf("i == %d\n", i);
+    EXPECT_GE(3, a[i]);
+  }
+}
+
+// Tests the SCOPED_TRACE macro.
+
+// A helper function for testing SCOPED_TRACE.
+void SubWithoutTrace(int n) {
+  EXPECT_EQ(1, n);
+  ASSERT_EQ(2, n);
+}
+
+// Another helper function for testing SCOPED_TRACE.
+void SubWithTrace(int n) {
+  SCOPED_TRACE(testing::Message() << "n = " << n);
+
+  SubWithoutTrace(n);
+}
+
+// Tests that SCOPED_TRACE() obeys lexical scopes.
+TEST(SCOPED_TRACETest, ObeysScopes) {
+  printf("(expected to fail)\n");
+
+  // There should be no trace before SCOPED_TRACE() is invoked.
+  ADD_FAILURE() << "This failure is expected, and shouldn't have a trace.";
+
+  {
+    SCOPED_TRACE("Expected trace");
+    // After SCOPED_TRACE(), a failure in the current scope should contain
+    // the trace.
+    ADD_FAILURE() << "This failure is expected, and should have a trace.";
+  }
+
+  // Once the control leaves the scope of the SCOPED_TRACE(), there
+  // should be no trace again.
+  ADD_FAILURE() << "This failure is expected, and shouldn't have a trace.";
+}
+
+// Tests that SCOPED_TRACE works inside a loop.
+TEST(SCOPED_TRACETest, WorksInLoop) {
+  printf("(expected to fail)\n");
+
+  for (int i = 1; i <= 2; i++) {
+    SCOPED_TRACE(testing::Message() << "i = " << i);
+
+    SubWithoutTrace(i);
+  }
+}
+
+// Tests that SCOPED_TRACE works in a subroutine.
+TEST(SCOPED_TRACETest, WorksInSubroutine) {
+  printf("(expected to fail)\n");
+
+  SubWithTrace(1);
+  SubWithTrace(2);
+}
+
+// Tests that SCOPED_TRACE can be nested.
+TEST(SCOPED_TRACETest, CanBeNested) {
+  printf("(expected to fail)\n");
+
+  SCOPED_TRACE("");  // A trace without a message.
+
+  SubWithTrace(2);
+}
+
+// Tests that multiple SCOPED_TRACEs can be used in the same scope.
+TEST(SCOPED_TRACETest, CanBeRepeated) {
+  printf("(expected to fail)\n");
+
+  SCOPED_TRACE("A");
+  ADD_FAILURE()
+      << "This failure is expected, and should contain trace point A.";
+
+  SCOPED_TRACE("B");
+  ADD_FAILURE()
+      << "This failure is expected, and should contain trace point A and B.";
+
+  {
+    SCOPED_TRACE("C");
+    ADD_FAILURE() << "This failure is expected, and should contain "
+                  << "trace point A, B, and C.";
+  }
+
+  SCOPED_TRACE("D");
+  ADD_FAILURE() << "This failure is expected, and should contain "
+                << "trace point A, B, and D.";
+}
+
+#if GTEST_IS_THREADSAFE
+// Tests that SCOPED_TRACE()s can be used concurrently from multiple
+// threads.  Namely, an assertion should be affected by
+// SCOPED_TRACE()s in its own thread only.
+
+// Here's the sequence of actions that happen in the test:
+//
+//   Thread A (main)                | Thread B (spawned)
+//   ===============================|================================
+//   spawns thread B                |
+//   -------------------------------+--------------------------------
+//   waits for n1                   | SCOPED_TRACE("Trace B");
+//                                  | generates failure #1
+//                                  | notifies n1
+//   -------------------------------+--------------------------------
+//   SCOPED_TRACE("Trace A");       | waits for n2
+//   generates failure #2           |
+//   notifies n2                    |
+//   -------------------------------|--------------------------------
+//   waits for n3                   | generates failure #3
+//                                  | trace B dies
+//                                  | generates failure #4
+//                                  | notifies n3
+//   -------------------------------|--------------------------------
+//   generates failure #5           | finishes
+//   trace A dies                   |
+//   generates failure #6           |
+//   -------------------------------|--------------------------------
+//   waits for thread B to finish   |
+
+struct CheckPoints {
+  Notification n1;
+  Notification n2;
+  Notification n3;
+};
+
+static void ThreadWithScopedTrace(CheckPoints* check_points) {
+  {
+    SCOPED_TRACE("Trace B");
+    ADD_FAILURE()
+        << "Expected failure #1 (in thread B, only trace B alive).";
+    check_points->n1.Notify();
+    check_points->n2.WaitForNotification();
+
+    ADD_FAILURE()
+        << "Expected failure #3 (in thread B, trace A & B both alive).";
+  }  // Trace B dies here.
+  ADD_FAILURE()
+      << "Expected failure #4 (in thread B, only trace A alive).";
+  check_points->n3.Notify();
+}
+
+TEST(SCOPED_TRACETest, WorksConcurrently) {
+  printf("(expecting 6 failures)\n");
+
+  CheckPoints check_points;
+  ThreadWithParam<CheckPoints*> thread(&ThreadWithScopedTrace,
+                                       &check_points,
+                                       NULL);
+  check_points.n1.WaitForNotification();
+
+  {
+    SCOPED_TRACE("Trace A");
+    ADD_FAILURE()
+        << "Expected failure #2 (in thread A, trace A & B both alive).";
+    check_points.n2.Notify();
+    check_points.n3.WaitForNotification();
+
+    ADD_FAILURE()
+        << "Expected failure #5 (in thread A, only trace A alive).";
+  }  // Trace A dies here.
+  ADD_FAILURE()
+      << "Expected failure #6 (in thread A, no trace alive).";
+  thread.Join();
+}
+#endif  // GTEST_IS_THREADSAFE
+
+TEST(DisabledTestsWarningTest,
+     DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning) {
+  // This test body is intentionally empty.  Its sole purpose is for
+  // verifying that the --gtest_also_run_disabled_tests flag
+  // suppresses the "YOU HAVE 12 DISABLED TESTS" warning at the end of
+  // the test output.
+}
+
+// Tests using assertions outside of TEST and TEST_F.
+//
+// This function creates two failures intentionally.
+void AdHocTest() {
+  printf("The non-test part of the code is expected to have 2 failures.\n\n");
+  EXPECT_TRUE(false);
+  EXPECT_EQ(2, 3);
+}
+
+// Runs all TESTs, all TEST_Fs, and the ad hoc test.
+int RunAllTests() {
+  AdHocTest();
+  return RUN_ALL_TESTS();
+}
+
+// Tests non-fatal failures in the fixture constructor.
+class NonFatalFailureInFixtureConstructorTest : public testing::Test {
+ protected:
+  NonFatalFailureInFixtureConstructorTest() {
+    printf("(expecting 5 failures)\n");
+    ADD_FAILURE() << "Expected failure #1, in the test fixture c'tor.";
+  }
+
+  ~NonFatalFailureInFixtureConstructorTest() {
+    ADD_FAILURE() << "Expected failure #5, in the test fixture d'tor.";
+  }
+
+  virtual void SetUp() {
+    ADD_FAILURE() << "Expected failure #2, in SetUp().";
+  }
+
+  virtual void TearDown() {
+    ADD_FAILURE() << "Expected failure #4, in TearDown.";
+  }
+};
+
+TEST_F(NonFatalFailureInFixtureConstructorTest, FailureInConstructor) {
+  ADD_FAILURE() << "Expected failure #3, in the test body.";
+}
+
+// Tests fatal failures in the fixture constructor.
+class FatalFailureInFixtureConstructorTest : public testing::Test {
+ protected:
+  FatalFailureInFixtureConstructorTest() {
+    printf("(expecting 2 failures)\n");
+    Init();
+  }
+
+  ~FatalFailureInFixtureConstructorTest() {
+    ADD_FAILURE() << "Expected failure #2, in the test fixture d'tor.";
+  }
+
+  virtual void SetUp() {
+    ADD_FAILURE() << "UNEXPECTED failure in SetUp().  "
+                  << "We should never get here, as the test fixture c'tor "
+                  << "had a fatal failure.";
+  }
+
+  virtual void TearDown() {
+    ADD_FAILURE() << "UNEXPECTED failure in TearDown().  "
+                  << "We should never get here, as the test fixture c'tor "
+                  << "had a fatal failure.";
+  }
+ private:
+  void Init() {
+    FAIL() << "Expected failure #1, in the test fixture c'tor.";
+  }
+};
+
+TEST_F(FatalFailureInFixtureConstructorTest, FailureInConstructor) {
+  ADD_FAILURE() << "UNEXPECTED failure in the test body.  "
+                << "We should never get here, as the test fixture c'tor "
+                << "had a fatal failure.";
+}
+
+// Tests non-fatal failures in SetUp().
+class NonFatalFailureInSetUpTest : public testing::Test {
+ protected:
+  virtual ~NonFatalFailureInSetUpTest() {
+    Deinit();
+  }
+
+  virtual void SetUp() {
+    printf("(expecting 4 failures)\n");
+    ADD_FAILURE() << "Expected failure #1, in SetUp().";
+  }
+
+  virtual void TearDown() {
+    FAIL() << "Expected failure #3, in TearDown().";
+  }
+ private:
+  void Deinit() {
+    FAIL() << "Expected failure #4, in the test fixture d'tor.";
+  }
+};
+
+TEST_F(NonFatalFailureInSetUpTest, FailureInSetUp) {
+  FAIL() << "Expected failure #2, in the test function.";
+}
+
+// Tests fatal failures in SetUp().
+class FatalFailureInSetUpTest : public testing::Test {
+ protected:
+  virtual ~FatalFailureInSetUpTest() {
+    Deinit();
+  }
+
+  virtual void SetUp() {
+    printf("(expecting 3 failures)\n");
+    FAIL() << "Expected failure #1, in SetUp().";
+  }
+
+  virtual void TearDown() {
+    FAIL() << "Expected failure #2, in TearDown().";
+  }
+ private:
+  void Deinit() {
+    FAIL() << "Expected failure #3, in the test fixture d'tor.";
+  }
+};
+
+TEST_F(FatalFailureInSetUpTest, FailureInSetUp) {
+  FAIL() << "UNEXPECTED failure in the test function.  "
+         << "We should never get here, as SetUp() failed.";
+}
+
+#if GTEST_OS_WINDOWS
+
+// This group of tests verifies that Google Test handles SEH and C++
+// exceptions correctly.
+
+// A function that throws an SEH exception.
+static void ThrowSEH() {
+  int* p = NULL;
+  *p = 0;  // Raises an access violation.
+}
+
+// Tests exceptions thrown in the test fixture constructor.
+class ExceptionInFixtureCtorTest : public testing::Test {
+ protected:
+  ExceptionInFixtureCtorTest() {
+    printf("(expecting a failure on thrown exception "
+           "in the test fixture's constructor)\n");
+
+    ThrowSEH();
+  }
+
+  virtual ~ExceptionInFixtureCtorTest() {
+    Deinit();
+  }
+
+  virtual void SetUp() {
+    FAIL() << "UNEXPECTED failure in SetUp().  "
+           << "We should never get here, as the test fixture c'tor threw.";
+  }
+
+  virtual void TearDown() {
+    FAIL() << "UNEXPECTED failure in TearDown().  "
+           << "We should never get here, as the test fixture c'tor threw.";
+  }
+ private:
+  void Deinit() {
+    FAIL() << "UNEXPECTED failure in the d'tor.  "
+           << "We should never get here, as the test fixture c'tor threw.";
+  }
+};
+
+TEST_F(ExceptionInFixtureCtorTest, ExceptionInFixtureCtor) {
+  FAIL() << "UNEXPECTED failure in the test function.  "
+         << "We should never get here, as the test fixture c'tor threw.";
+}
+
+// Tests exceptions thrown in SetUp().
+class ExceptionInSetUpTest : public testing::Test {
+ protected:
+  virtual ~ExceptionInSetUpTest() {
+    Deinit();
+  }
+
+  virtual void SetUp() {
+    printf("(expecting 3 failures)\n");
+
+    ThrowSEH();
+  }
+
+  virtual void TearDown() {
+    FAIL() << "Expected failure #2, in TearDown().";
+  }
+ private:
+  void Deinit() {
+    FAIL() << "Expected failure #3, in the test fixture d'tor.";
+  }
+};
+
+TEST_F(ExceptionInSetUpTest, ExceptionInSetUp) {
+  FAIL() << "UNEXPECTED failure in the test function.  "
+         << "We should never get here, as SetUp() threw.";
+}
+
+// Tests that TearDown() and the test fixture d'tor are always called,
+// even when the test function throws an exception.
+class ExceptionInTestFunctionTest : public testing::Test {
+ protected:
+  virtual ~ExceptionInTestFunctionTest() {
+    Deinit();
+  }
+
+  virtual void TearDown() {
+    FAIL() << "Expected failure #2, in TearDown().";
+  }
+ private:
+  void Deinit() {
+    FAIL() << "Expected failure #3, in the test fixture d'tor.";
+  }
+};
+
+// Tests that the test fixture d'tor is always called, even when the
+// test function throws an SEH exception.
+TEST_F(ExceptionInTestFunctionTest, SEH) {
+  printf("(expecting 3 failures)\n");
+
+  ThrowSEH();
+}
+
+#if GTEST_HAS_EXCEPTIONS
+
+// Tests that the test fixture d'tor is always called, even when the
+// test function throws a C++ exception.  We do this only when
+// GTEST_HAS_EXCEPTIONS is non-zero, i.e. C++ exceptions are enabled.
+TEST_F(ExceptionInTestFunctionTest, CppException) {
+  throw 1;
+}
+
+// Tests exceptions thrown in TearDown().
+class ExceptionInTearDownTest : public testing::Test {
+ protected:
+  virtual ~ExceptionInTearDownTest() {
+    Deinit();
+  }
+
+  virtual void TearDown() {
+    throw 1;
+  }
+ private:
+  void Deinit() {
+    FAIL() << "Expected failure #2, in the test fixture d'tor.";
+  }
+};
+
+TEST_F(ExceptionInTearDownTest, ExceptionInTearDown) {
+  printf("(expecting 2 failures)\n");
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
+#endif  // GTEST_OS_WINDOWS
+
+#if GTEST_IS_THREADSAFE
+
+// A unary function that may die.
+void DieIf(bool should_die) {
+  GTEST_CHECK_(!should_die) << " - death inside DieIf().";
+}
+
+// Tests running death tests in a multi-threaded context.
+
+// Used for coordination between the main and the spawn thread.
+struct SpawnThreadNotifications {
+  SpawnThreadNotifications() {}
+
+  Notification spawn_thread_started;
+  Notification spawn_thread_ok_to_terminate;
+
+ private:
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications);
+};
+
+// The function to be executed in the thread spawn by the
+// MultipleThreads test (below).
+static void ThreadRoutine(SpawnThreadNotifications* notifications) {
+  // Signals the main thread that this thread has started.
+  notifications->spawn_thread_started.Notify();
+
+  // Waits for permission to finish from the main thread.
+  notifications->spawn_thread_ok_to_terminate.WaitForNotification();
+}
+
+// This is a death-test test, but it's not named with a DeathTest
+// suffix.  It starts threads which might interfere with later
+// death tests, so it must run after all other death tests.
+class DeathTestAndMultiThreadsTest : public testing::Test {
+ protected:
+  // Starts a thread and waits for it to begin.
+  virtual void SetUp() {
+    thread_.reset(new ThreadWithParam<SpawnThreadNotifications*>(
+        &ThreadRoutine, &notifications_, NULL));
+    notifications_.spawn_thread_started.WaitForNotification();
+  }
+  // Tells the thread to finish, and reaps it.
+  // Depending on the version of the thread library in use,
+  // a manager thread might still be left running that will interfere
+  // with later death tests.  This is unfortunate, but this class
+  // cleans up after itself as best it can.
+  virtual void TearDown() {
+    notifications_.spawn_thread_ok_to_terminate.Notify();
+  }
+
+ private:
+  SpawnThreadNotifications notifications_;
+  scoped_ptr<ThreadWithParam<SpawnThreadNotifications*> > thread_;
+};
+
+#endif  // GTEST_IS_THREADSAFE
+
+// The MixedUpTestCaseTest test case verifies that Google Test will fail a
+// test if it uses a different fixture class than what other tests in
+// the same test case use.  It deliberately contains two fixture
+// classes with the same name but defined in different namespaces.
+
+// The MixedUpTestCaseWithSameTestNameTest test case verifies that
+// when the user defines two tests with the same test case name AND
+// same test name (but in different namespaces), the second test will
+// fail.
+
+namespace foo {
+
+class MixedUpTestCaseTest : public testing::Test {
+};
+
+TEST_F(MixedUpTestCaseTest, FirstTestFromNamespaceFoo) {}
+TEST_F(MixedUpTestCaseTest, SecondTestFromNamespaceFoo) {}
+
+class MixedUpTestCaseWithSameTestNameTest : public testing::Test {
+};
+
+TEST_F(MixedUpTestCaseWithSameTestNameTest,
+       TheSecondTestWithThisNameShouldFail) {}
+
+}  // namespace foo
+
+namespace bar {
+
+class MixedUpTestCaseTest : public testing::Test {
+};
+
+// The following two tests are expected to fail.  We rely on the
+// golden file to check that Google Test generates the right error message.
+TEST_F(MixedUpTestCaseTest, ThisShouldFail) {}
+TEST_F(MixedUpTestCaseTest, ThisShouldFailToo) {}
+
+class MixedUpTestCaseWithSameTestNameTest : public testing::Test {
+};
+
+// Expected to fail.  We rely on the golden file to check that Google Test
+// generates the right error message.
+TEST_F(MixedUpTestCaseWithSameTestNameTest,
+       TheSecondTestWithThisNameShouldFail) {}
+
+}  // namespace bar
+
+// The following two test cases verify that Google Test catches the user
+// error of mixing TEST and TEST_F in the same test case.  The first
+// test case checks the scenario where TEST_F appears before TEST, and
+// the second one checks where TEST appears before TEST_F.
+
+class TEST_F_before_TEST_in_same_test_case : public testing::Test {
+};
+
+TEST_F(TEST_F_before_TEST_in_same_test_case, DefinedUsingTEST_F) {}
+
+// Expected to fail.  We rely on the golden file to check that Google Test
+// generates the right error message.
+TEST(TEST_F_before_TEST_in_same_test_case, DefinedUsingTESTAndShouldFail) {}
+
+class TEST_before_TEST_F_in_same_test_case : public testing::Test {
+};
+
+TEST(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST) {}
+
+// Expected to fail.  We rely on the golden file to check that Google Test
+// generates the right error message.
+TEST_F(TEST_before_TEST_F_in_same_test_case, DefinedUsingTEST_FAndShouldFail) {
+}
+
+// Used for testing EXPECT_NONFATAL_FAILURE() and EXPECT_FATAL_FAILURE().
+int global_integer = 0;
+
+// Tests that EXPECT_NONFATAL_FAILURE() can reference global variables.
+TEST(ExpectNonfatalFailureTest, CanReferenceGlobalVariables) {
+  global_integer = 0;
+  EXPECT_NONFATAL_FAILURE({
+    EXPECT_EQ(1, global_integer) << "Expected non-fatal failure.";
+  }, "Expected non-fatal failure.");
+}
+
+// Tests that EXPECT_NONFATAL_FAILURE() can reference local variables
+// (static or not).
+TEST(ExpectNonfatalFailureTest, CanReferenceLocalVariables) {
+  int m = 0;
+  static int n;
+  n = 1;
+  EXPECT_NONFATAL_FAILURE({
+    EXPECT_EQ(m, n) << "Expected non-fatal failure.";
+  }, "Expected non-fatal failure.");
+}
+
+// Tests that EXPECT_NONFATAL_FAILURE() succeeds when there is exactly
+// one non-fatal failure and no fatal failure.
+TEST(ExpectNonfatalFailureTest, SucceedsWhenThereIsOneNonfatalFailure) {
+  EXPECT_NONFATAL_FAILURE({
+    ADD_FAILURE() << "Expected non-fatal failure.";
+  }, "Expected non-fatal failure.");
+}
+
+// Tests that EXPECT_NONFATAL_FAILURE() fails when there is no
+// non-fatal failure.
+TEST(ExpectNonfatalFailureTest, FailsWhenThereIsNoNonfatalFailure) {
+  printf("(expecting a failure)\n");
+  EXPECT_NONFATAL_FAILURE({
+  }, "");
+}
+
+// Tests that EXPECT_NONFATAL_FAILURE() fails when there are two
+// non-fatal failures.
+TEST(ExpectNonfatalFailureTest, FailsWhenThereAreTwoNonfatalFailures) {
+  printf("(expecting a failure)\n");
+  EXPECT_NONFATAL_FAILURE({
+    ADD_FAILURE() << "Expected non-fatal failure 1.";
+    ADD_FAILURE() << "Expected non-fatal failure 2.";
+  }, "");
+}
+
+// Tests that EXPECT_NONFATAL_FAILURE() fails when there is one fatal
+// failure.
+TEST(ExpectNonfatalFailureTest, FailsWhenThereIsOneFatalFailure) {
+  printf("(expecting a failure)\n");
+  EXPECT_NONFATAL_FAILURE({
+    FAIL() << "Expected fatal failure.";
+  }, "");
+}
+
+// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being
+// tested returns.
+TEST(ExpectNonfatalFailureTest, FailsWhenStatementReturns) {
+  printf("(expecting a failure)\n");
+  EXPECT_NONFATAL_FAILURE({
+    return;
+  }, "");
+}
+
+#if GTEST_HAS_EXCEPTIONS
+
+// Tests that EXPECT_NONFATAL_FAILURE() fails when the statement being
+// tested throws.
+TEST(ExpectNonfatalFailureTest, FailsWhenStatementThrows) {
+  printf("(expecting a failure)\n");
+  try {
+    EXPECT_NONFATAL_FAILURE({
+      throw 0;
+    }, "");
+  } catch(int) {  // NOLINT
+  }
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
+// Tests that EXPECT_FATAL_FAILURE() can reference global variables.
+TEST(ExpectFatalFailureTest, CanReferenceGlobalVariables) {
+  global_integer = 0;
+  EXPECT_FATAL_FAILURE({
+    ASSERT_EQ(1, global_integer) << "Expected fatal failure.";
+  }, "Expected fatal failure.");
+}
+
+// Tests that EXPECT_FATAL_FAILURE() can reference local static
+// variables.
+TEST(ExpectFatalFailureTest, CanReferenceLocalStaticVariables) {
+  static int n;
+  n = 1;
+  EXPECT_FATAL_FAILURE({
+    ASSERT_EQ(0, n) << "Expected fatal failure.";
+  }, "Expected fatal failure.");
+}
+
+// Tests that EXPECT_FATAL_FAILURE() succeeds when there is exactly
+// one fatal failure and no non-fatal failure.
+TEST(ExpectFatalFailureTest, SucceedsWhenThereIsOneFatalFailure) {
+  EXPECT_FATAL_FAILURE({
+    FAIL() << "Expected fatal failure.";
+  }, "Expected fatal failure.");
+}
+
+// Tests that EXPECT_FATAL_FAILURE() fails when there is no fatal
+// failure.
+TEST(ExpectFatalFailureTest, FailsWhenThereIsNoFatalFailure) {
+  printf("(expecting a failure)\n");
+  EXPECT_FATAL_FAILURE({
+  }, "");
+}
+
+// A helper for generating a fatal failure.
+void FatalFailure() {
+  FAIL() << "Expected fatal failure.";
+}
+
+// Tests that EXPECT_FATAL_FAILURE() fails when there are two
+// fatal failures.
+TEST(ExpectFatalFailureTest, FailsWhenThereAreTwoFatalFailures) {
+  printf("(expecting a failure)\n");
+  EXPECT_FATAL_FAILURE({
+    FatalFailure();
+    FatalFailure();
+  }, "");
+}
+
+// Tests that EXPECT_FATAL_FAILURE() fails when there is one non-fatal
+// failure.
+TEST(ExpectFatalFailureTest, FailsWhenThereIsOneNonfatalFailure) {
+  printf("(expecting a failure)\n");
+  EXPECT_FATAL_FAILURE({
+    ADD_FAILURE() << "Expected non-fatal failure.";
+  }, "");
+}
+
+// Tests that EXPECT_FATAL_FAILURE() fails when the statement being
+// tested returns.
+TEST(ExpectFatalFailureTest, FailsWhenStatementReturns) {
+  printf("(expecting a failure)\n");
+  EXPECT_FATAL_FAILURE({
+    return;
+  }, "");
+}
+
+#if GTEST_HAS_EXCEPTIONS
+
+// Tests that EXPECT_FATAL_FAILURE() fails when the statement being
+// tested throws.
+TEST(ExpectFatalFailureTest, FailsWhenStatementThrows) {
+  printf("(expecting a failure)\n");
+  try {
+    EXPECT_FATAL_FAILURE({
+      throw 0;
+    }, "");
+  } catch(int) {  // NOLINT
+  }
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
+// This #ifdef block tests the output of typed tests.
+#if GTEST_HAS_TYPED_TEST
+
+template <typename T>
+class TypedTest : public testing::Test {
+};
+
+TYPED_TEST_CASE(TypedTest, testing::Types<int>);
+
+TYPED_TEST(TypedTest, Success) {
+  EXPECT_EQ(0, TypeParam());
+}
+
+TYPED_TEST(TypedTest, Failure) {
+  EXPECT_EQ(1, TypeParam()) << "Expected failure";
+}
+
+#endif  // GTEST_HAS_TYPED_TEST
+
+// This #ifdef block tests the output of type-parameterized tests.
+#if GTEST_HAS_TYPED_TEST_P
+
+template <typename T>
+class TypedTestP : public testing::Test {
+};
+
+TYPED_TEST_CASE_P(TypedTestP);
+
+TYPED_TEST_P(TypedTestP, Success) {
+  EXPECT_EQ(0U, TypeParam());
+}
+
+TYPED_TEST_P(TypedTestP, Failure) {
+  EXPECT_EQ(1U, TypeParam()) << "Expected failure";
+}
+
+REGISTER_TYPED_TEST_CASE_P(TypedTestP, Success, Failure);
+
+typedef testing::Types<unsigned char, unsigned int> UnsignedTypes;
+INSTANTIATE_TYPED_TEST_CASE_P(Unsigned, TypedTestP, UnsignedTypes);
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+#if GTEST_HAS_DEATH_TEST
+
+// We rely on the golden file to verify that tests whose test case
+// name ends with DeathTest are run first.
+
+TEST(ADeathTest, ShouldRunFirst) {
+}
+
+#if GTEST_HAS_TYPED_TEST
+
+// We rely on the golden file to verify that typed tests whose test
+// case name ends with DeathTest are run first.
+
+template <typename T>
+class ATypedDeathTest : public testing::Test {
+};
+
+typedef testing::Types<int, double> NumericTypes;
+TYPED_TEST_CASE(ATypedDeathTest, NumericTypes);
+
+TYPED_TEST(ATypedDeathTest, ShouldRunFirst) {
+}
+
+#endif  // GTEST_HAS_TYPED_TEST
+
+#if GTEST_HAS_TYPED_TEST_P
+
+
+// We rely on the golden file to verify that type-parameterized tests
+// whose test case name ends with DeathTest are run first.
+
+template <typename T>
+class ATypeParamDeathTest : public testing::Test {
+};
+
+TYPED_TEST_CASE_P(ATypeParamDeathTest);
+
+TYPED_TEST_P(ATypeParamDeathTest, ShouldRunFirst) {
+}
+
+REGISTER_TYPED_TEST_CASE_P(ATypeParamDeathTest, ShouldRunFirst);
+
+INSTANTIATE_TYPED_TEST_CASE_P(My, ATypeParamDeathTest, NumericTypes);
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+#endif  // GTEST_HAS_DEATH_TEST
+
+// Tests various failure conditions of
+// EXPECT_{,NON}FATAL_FAILURE{,_ON_ALL_THREADS}.
+class ExpectFailureTest : public testing::Test {
+ public:  // Must be public and not protected due to a bug in g++ 3.4.2.
+  enum FailureMode {
+    FATAL_FAILURE,
+    NONFATAL_FAILURE
+  };
+  static void AddFailure(FailureMode failure) {
+    if (failure == FATAL_FAILURE) {
+      FAIL() << "Expected fatal failure.";
+    } else {
+      ADD_FAILURE() << "Expected non-fatal failure.";
+    }
+  }
+};
+
+TEST_F(ExpectFailureTest, ExpectFatalFailure) {
+  // Expected fatal failure, but succeeds.
+  printf("(expecting 1 failure)\n");
+  EXPECT_FATAL_FAILURE(SUCCEED(), "Expected fatal failure.");
+  // Expected fatal failure, but got a non-fatal failure.
+  printf("(expecting 1 failure)\n");
+  EXPECT_FATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Expected non-fatal "
+                       "failure.");
+  // Wrong message.
+  printf("(expecting 1 failure)\n");
+  EXPECT_FATAL_FAILURE(AddFailure(FATAL_FAILURE), "Some other fatal failure "
+                       "expected.");
+}
+
+TEST_F(ExpectFailureTest, ExpectNonFatalFailure) {
+  // Expected non-fatal failure, but succeeds.
+  printf("(expecting 1 failure)\n");
+  EXPECT_NONFATAL_FAILURE(SUCCEED(), "Expected non-fatal failure.");
+  // Expected non-fatal failure, but got a fatal failure.
+  printf("(expecting 1 failure)\n");
+  EXPECT_NONFATAL_FAILURE(AddFailure(FATAL_FAILURE), "Expected fatal failure.");
+  // Wrong message.
+  printf("(expecting 1 failure)\n");
+  EXPECT_NONFATAL_FAILURE(AddFailure(NONFATAL_FAILURE), "Some other non-fatal "
+                          "failure.");
+}
+
+#if GTEST_IS_THREADSAFE
+
+class ExpectFailureWithThreadsTest : public ExpectFailureTest {
+ protected:
+  static void AddFailureInOtherThread(FailureMode failure) {
+    ThreadWithParam<FailureMode> thread(&AddFailure, failure, NULL);
+    thread.Join();
+  }
+};
+
+TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailure) {
+  // We only intercept the current thread.
+  printf("(expecting 2 failures)\n");
+  EXPECT_FATAL_FAILURE(AddFailureInOtherThread(FATAL_FAILURE),
+                       "Expected fatal failure.");
+}
+
+TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailure) {
+  // We only intercept the current thread.
+  printf("(expecting 2 failures)\n");
+  EXPECT_NONFATAL_FAILURE(AddFailureInOtherThread(NONFATAL_FAILURE),
+                          "Expected non-fatal failure.");
+}
+
+typedef ExpectFailureWithThreadsTest ScopedFakeTestPartResultReporterTest;
+
+// Tests that the ScopedFakeTestPartResultReporter only catches failures from
+// the current thread if it is instantiated with INTERCEPT_ONLY_CURRENT_THREAD.
+TEST_F(ScopedFakeTestPartResultReporterTest, InterceptOnlyCurrentThread) {
+  printf("(expecting 2 failures)\n");
+  TestPartResultArray results;
+  {
+    ScopedFakeTestPartResultReporter reporter(
+        ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD,
+        &results);
+    AddFailureInOtherThread(FATAL_FAILURE);
+    AddFailureInOtherThread(NONFATAL_FAILURE);
+  }
+  // The two failures should not have been intercepted.
+  EXPECT_EQ(0, results.size()) << "This shouldn't fail.";
+}
+
+#endif  // GTEST_IS_THREADSAFE
+
+TEST_F(ExpectFailureTest, ExpectFatalFailureOnAllThreads) {
+  // Expected fatal failure, but succeeds.
+  printf("(expecting 1 failure)\n");
+  EXPECT_FATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected fatal failure.");
+  // Expected fatal failure, but got a non-fatal failure.
+  printf("(expecting 1 failure)\n");
+  EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE),
+                                      "Expected non-fatal failure.");
+  // Wrong message.
+  printf("(expecting 1 failure)\n");
+  EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE),
+                                      "Some other fatal failure expected.");
+}
+
+TEST_F(ExpectFailureTest, ExpectNonFatalFailureOnAllThreads) {
+  // Expected non-fatal failure, but succeeds.
+  printf("(expecting 1 failure)\n");
+  EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(SUCCEED(), "Expected non-fatal "
+                                         "failure.");
+  // Expected non-fatal failure, but got a fatal failure.
+  printf("(expecting 1 failure)\n");
+  EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(FATAL_FAILURE),
+                                         "Expected fatal failure.");
+  // Wrong message.
+  printf("(expecting 1 failure)\n");
+  EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddFailure(NONFATAL_FAILURE),
+                                         "Some other non-fatal failure.");
+}
+
+
+// Two test environments for testing testing::AddGlobalTestEnvironment().
+
+class FooEnvironment : public testing::Environment {
+ public:
+  virtual void SetUp() {
+    printf("%s", "FooEnvironment::SetUp() called.\n");
+  }
+
+  virtual void TearDown() {
+    printf("%s", "FooEnvironment::TearDown() called.\n");
+    FAIL() << "Expected fatal failure.";
+  }
+};
+
+class BarEnvironment : public testing::Environment {
+ public:
+  virtual void SetUp() {
+    printf("%s", "BarEnvironment::SetUp() called.\n");
+  }
+
+  virtual void TearDown() {
+    printf("%s", "BarEnvironment::TearDown() called.\n");
+    ADD_FAILURE() << "Expected non-fatal failure.";
+  }
+};
+
+GTEST_DEFINE_bool_(internal_skip_environment_and_ad_hoc_tests, false,
+                   "This flag causes the program to skip test environment "
+                   "tests and ad hoc tests.");
+
+// The main function.
+//
+// The idea is to use Google Test to run all the tests we have defined (some
+// of them are intended to fail), and then compare the test results
+// with the "golden" file.
+int main(int argc, char **argv) {
+  testing::GTEST_FLAG(print_time) = false;
+
+  // We just run the tests, knowing some of them are intended to fail.
+  // We will use a separate Python script to compare the output of
+  // this program with the golden file.
+
+  // It's hard to test InitGoogleTest() directly, as it has many
+  // global side effects.  The following line serves as a sanity test
+  // for it.
+  testing::InitGoogleTest(&argc, argv);
+  if (argc >= 2 &&
+      String(argv[1]) == "--gtest_internal_skip_environment_and_ad_hoc_tests")
+    GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests) = true;
+
+#if GTEST_HAS_DEATH_TEST
+  if (testing::internal::GTEST_FLAG(internal_run_death_test) != "") {
+    // Skip the usual output capturing if we're running as the child
+    // process of an threadsafe-style death test.
+#if GTEST_OS_WINDOWS
+    posix::FReopen("nul:", "w", stdout);
+#else
+    posix::FReopen("/dev/null", "w", stdout);
+#endif  // GTEST_OS_WINDOWS
+    return RUN_ALL_TESTS();
+  }
+#endif  // GTEST_HAS_DEATH_TEST
+
+  if (GTEST_FLAG(internal_skip_environment_and_ad_hoc_tests))
+    return RUN_ALL_TESTS();
+
+  // Registers two global test environments.
+  // The golden file verifies that they are set up in the order they
+  // are registered, and torn down in the reverse order.
+  testing::AddGlobalTestEnvironment(new FooEnvironment);
+  testing::AddGlobalTestEnvironment(new BarEnvironment);
+
+  return RunAllTests();
+}
diff --git a/protobuf/gtest/test/gtest_output_test_golden_lin.txt b/protobuf/gtest/test/gtest_output_test_golden_lin.txt
new file mode 100644
index 0000000..ec60437
--- /dev/null
+++ b/protobuf/gtest/test/gtest_output_test_golden_lin.txt
@@ -0,0 +1,696 @@
+The non-test part of the code is expected to have 2 failures.
+
+gtest_output_test_.cc:#: Failure
+Value of: false
+  Actual: false
+Expected: true
+gtest_output_test_.cc:#: Failure
+Value of: 3
+Expected: 2
+[==========] Running 60 tests from 25 test cases.
+[----------] Global test environment set-up.
+FooEnvironment::SetUp() called.
+BarEnvironment::SetUp() called.
+[----------] 1 test from ADeathTest
+[ RUN      ] ADeathTest.ShouldRunFirst
+[       OK ] ADeathTest.ShouldRunFirst
+[----------] 1 test from ATypedDeathTest/0, where TypeParam = int
+[ RUN      ] ATypedDeathTest/0.ShouldRunFirst
+[       OK ] ATypedDeathTest/0.ShouldRunFirst
+[----------] 1 test from ATypedDeathTest/1, where TypeParam = double
+[ RUN      ] ATypedDeathTest/1.ShouldRunFirst
+[       OK ] ATypedDeathTest/1.ShouldRunFirst
+[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int
+[ RUN      ] My/ATypeParamDeathTest/0.ShouldRunFirst
+[       OK ] My/ATypeParamDeathTest/0.ShouldRunFirst
+[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double
+[ RUN      ] My/ATypeParamDeathTest/1.ShouldRunFirst
+[       OK ] My/ATypeParamDeathTest/1.ShouldRunFirst
+[----------] 2 tests from PassingTest
+[ RUN      ] PassingTest.PassingTest1
+[       OK ] PassingTest.PassingTest1
+[ RUN      ] PassingTest.PassingTest2
+[       OK ] PassingTest.PassingTest2
+[----------] 3 tests from FatalFailureTest
+[ RUN      ] FatalFailureTest.FatalFailureInSubroutine
+(expecting a failure that x should be 1)
+gtest_output_test_.cc:#: Failure
+Value of: x
+  Actual: 2
+Expected: 1
+[  FAILED  ] FatalFailureTest.FatalFailureInSubroutine
+[ RUN      ] FatalFailureTest.FatalFailureInNestedSubroutine
+(expecting a failure that x should be 1)
+gtest_output_test_.cc:#: Failure
+Value of: x
+  Actual: 2
+Expected: 1
+[  FAILED  ] FatalFailureTest.FatalFailureInNestedSubroutine
+[ RUN      ] FatalFailureTest.NonfatalFailureInSubroutine
+(expecting a failure on false)
+gtest_output_test_.cc:#: Failure
+Value of: false
+  Actual: false
+Expected: true
+[  FAILED  ] FatalFailureTest.NonfatalFailureInSubroutine
+[----------] 1 test from LoggingTest
+[ RUN      ] LoggingTest.InterleavingLoggingAndAssertions
+(expecting 2 failures on (3) >= (a[i]))
+i == 0
+i == 1
+gtest_output_test_.cc:#: Failure
+Expected: (3) >= (a[i]), actual: 3 vs 9
+i == 2
+i == 3
+gtest_output_test_.cc:#: Failure
+Expected: (3) >= (a[i]), actual: 3 vs 6
+[  FAILED  ] LoggingTest.InterleavingLoggingAndAssertions
+[----------] 6 tests from SCOPED_TRACETest
+[ RUN      ] SCOPED_TRACETest.ObeysScopes
+(expected to fail)
+gtest_output_test_.cc:#: Failure
+Failed
+This failure is expected, and shouldn't have a trace.
+gtest_output_test_.cc:#: Failure
+Failed
+This failure is expected, and should have a trace.
+Google Test trace:
+gtest_output_test_.cc:#: Expected trace
+gtest_output_test_.cc:#: Failure
+Failed
+This failure is expected, and shouldn't have a trace.
+[  FAILED  ] SCOPED_TRACETest.ObeysScopes
+[ RUN      ] SCOPED_TRACETest.WorksInLoop
+(expected to fail)
+gtest_output_test_.cc:#: Failure
+Value of: n
+  Actual: 1
+Expected: 2
+Google Test trace:
+gtest_output_test_.cc:#: i = 1
+gtest_output_test_.cc:#: Failure
+Value of: n
+  Actual: 2
+Expected: 1
+Google Test trace:
+gtest_output_test_.cc:#: i = 2
+[  FAILED  ] SCOPED_TRACETest.WorksInLoop
+[ RUN      ] SCOPED_TRACETest.WorksInSubroutine
+(expected to fail)
+gtest_output_test_.cc:#: Failure
+Value of: n
+  Actual: 1
+Expected: 2
+Google Test trace:
+gtest_output_test_.cc:#: n = 1
+gtest_output_test_.cc:#: Failure
+Value of: n
+  Actual: 2
+Expected: 1
+Google Test trace:
+gtest_output_test_.cc:#: n = 2
+[  FAILED  ] SCOPED_TRACETest.WorksInSubroutine
+[ RUN      ] SCOPED_TRACETest.CanBeNested
+(expected to fail)
+gtest_output_test_.cc:#: Failure
+Value of: n
+  Actual: 2
+Expected: 1
+Google Test trace:
+gtest_output_test_.cc:#: n = 2
+gtest_output_test_.cc:#: 
+[  FAILED  ] SCOPED_TRACETest.CanBeNested
+[ RUN      ] SCOPED_TRACETest.CanBeRepeated
+(expected to fail)
+gtest_output_test_.cc:#: Failure
+Failed
+This failure is expected, and should contain trace point A.
+Google Test trace:
+gtest_output_test_.cc:#: A
+gtest_output_test_.cc:#: Failure
+Failed
+This failure is expected, and should contain trace point A and B.
+Google Test trace:
+gtest_output_test_.cc:#: B
+gtest_output_test_.cc:#: A
+gtest_output_test_.cc:#: Failure
+Failed
+This failure is expected, and should contain trace point A, B, and C.
+Google Test trace:
+gtest_output_test_.cc:#: C
+gtest_output_test_.cc:#: B
+gtest_output_test_.cc:#: A
+gtest_output_test_.cc:#: Failure
+Failed
+This failure is expected, and should contain trace point A, B, and D.
+Google Test trace:
+gtest_output_test_.cc:#: D
+gtest_output_test_.cc:#: B
+gtest_output_test_.cc:#: A
+[  FAILED  ] SCOPED_TRACETest.CanBeRepeated
+[ RUN      ] SCOPED_TRACETest.WorksConcurrently
+(expecting 6 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #1 (in thread B, only trace B alive).
+Google Test trace:
+gtest_output_test_.cc:#: Trace B
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #2 (in thread A, trace A & B both alive).
+Google Test trace:
+gtest_output_test_.cc:#: Trace A
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #3 (in thread B, trace A & B both alive).
+Google Test trace:
+gtest_output_test_.cc:#: Trace B
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #4 (in thread B, only trace A alive).
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #5 (in thread A, only trace A alive).
+Google Test trace:
+gtest_output_test_.cc:#: Trace A
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #6 (in thread A, no trace alive).
+[  FAILED  ] SCOPED_TRACETest.WorksConcurrently
+[----------] 1 test from NonFatalFailureInFixtureConstructorTest
+[ RUN      ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
+(expecting 5 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #1, in the test fixture c'tor.
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #2, in SetUp().
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #3, in the test body.
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #4, in TearDown.
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #5, in the test fixture d'tor.
+[  FAILED  ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
+[----------] 1 test from FatalFailureInFixtureConstructorTest
+[ RUN      ] FatalFailureInFixtureConstructorTest.FailureInConstructor
+(expecting 2 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #1, in the test fixture c'tor.
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #2, in the test fixture d'tor.
+[  FAILED  ] FatalFailureInFixtureConstructorTest.FailureInConstructor
+[----------] 1 test from NonFatalFailureInSetUpTest
+[ RUN      ] NonFatalFailureInSetUpTest.FailureInSetUp
+(expecting 4 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #1, in SetUp().
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #2, in the test function.
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #3, in TearDown().
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #4, in the test fixture d'tor.
+[  FAILED  ] NonFatalFailureInSetUpTest.FailureInSetUp
+[----------] 1 test from FatalFailureInSetUpTest
+[ RUN      ] FatalFailureInSetUpTest.FailureInSetUp
+(expecting 3 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #1, in SetUp().
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #2, in TearDown().
+gtest_output_test_.cc:#: Failure
+Failed
+Expected failure #3, in the test fixture d'tor.
+[  FAILED  ] FatalFailureInSetUpTest.FailureInSetUp
+[----------] 4 tests from MixedUpTestCaseTest
+[ RUN      ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo
+[       OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo
+[ RUN      ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo
+[       OK ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo
+[ RUN      ] MixedUpTestCaseTest.ThisShouldFail
+gtest.cc:#: Failure
+Failed
+All tests in the same test case must use the same test fixture
+class.  However, in test case MixedUpTestCaseTest,
+you defined test FirstTestFromNamespaceFoo and test ThisShouldFail
+using two different test fixture classes.  This can happen if
+the two classes are from different namespaces or translation
+units and have the same name.  You should probably rename one
+of the classes to put the tests into different test cases.
+[  FAILED  ] MixedUpTestCaseTest.ThisShouldFail
+[ RUN      ] MixedUpTestCaseTest.ThisShouldFailToo
+gtest.cc:#: Failure
+Failed
+All tests in the same test case must use the same test fixture
+class.  However, in test case MixedUpTestCaseTest,
+you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo
+using two different test fixture classes.  This can happen if
+the two classes are from different namespaces or translation
+units and have the same name.  You should probably rename one
+of the classes to put the tests into different test cases.
+[  FAILED  ] MixedUpTestCaseTest.ThisShouldFailToo
+[----------] 2 tests from MixedUpTestCaseWithSameTestNameTest
+[ RUN      ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail
+[       OK ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail
+[ RUN      ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail
+gtest.cc:#: Failure
+Failed
+All tests in the same test case must use the same test fixture
+class.  However, in test case MixedUpTestCaseWithSameTestNameTest,
+you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail
+using two different test fixture classes.  This can happen if
+the two classes are from different namespaces or translation
+units and have the same name.  You should probably rename one
+of the classes to put the tests into different test cases.
+[  FAILED  ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail
+[----------] 2 tests from TEST_F_before_TEST_in_same_test_case
+[ RUN      ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F
+[       OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F
+[ RUN      ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail
+gtest.cc:#: Failure
+Failed
+All tests in the same test case must use the same test fixture
+class, so mixing TEST_F and TEST in the same test case is
+illegal.  In test case TEST_F_before_TEST_in_same_test_case,
+test DefinedUsingTEST_F is defined using TEST_F but
+test DefinedUsingTESTAndShouldFail is defined using TEST.  You probably
+want to change the TEST to TEST_F or move it to another test
+case.
+[  FAILED  ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail
+[----------] 2 tests from TEST_before_TEST_F_in_same_test_case
+[ RUN      ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST
+[       OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST
+[ RUN      ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail
+gtest.cc:#: Failure
+Failed
+All tests in the same test case must use the same test fixture
+class, so mixing TEST_F and TEST in the same test case is
+illegal.  In test case TEST_before_TEST_F_in_same_test_case,
+test DefinedUsingTEST_FAndShouldFail is defined using TEST_F but
+test DefinedUsingTEST is defined using TEST.  You probably
+want to change the TEST to TEST_F or move it to another test
+case.
+[  FAILED  ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail
+[----------] 8 tests from ExpectNonfatalFailureTest
+[ RUN      ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables
+[       OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables
+[ RUN      ] ExpectNonfatalFailureTest.CanReferenceLocalVariables
+[       OK ] ExpectNonfatalFailureTest.CanReferenceLocalVariables
+[ RUN      ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure
+[       OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure
+[ RUN      ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure
+(expecting a failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure
+[ RUN      ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures
+(expecting a failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+  Actual: 2 failures
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure 1.
+
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure 2.
+
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures
+[ RUN      ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure
+(expecting a failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+  Actual:
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure
+[ RUN      ] ExpectNonfatalFailureTest.FailsWhenStatementReturns
+(expecting a failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenStatementReturns
+[ RUN      ] ExpectNonfatalFailureTest.FailsWhenStatementThrows
+(expecting a failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenStatementThrows
+[----------] 8 tests from ExpectFatalFailureTest
+[ RUN      ] ExpectFatalFailureTest.CanReferenceGlobalVariables
+[       OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables
+[ RUN      ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables
+[       OK ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables
+[ RUN      ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure
+[       OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure
+[ RUN      ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure
+(expecting a failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure
+[ RUN      ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures
+(expecting a failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+  Actual: 2 failures
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures
+[ RUN      ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure
+(expecting a failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+  Actual:
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure.
+
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure
+[ RUN      ] ExpectFatalFailureTest.FailsWhenStatementReturns
+(expecting a failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenStatementReturns
+[ RUN      ] ExpectFatalFailureTest.FailsWhenStatementThrows
+(expecting a failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenStatementThrows
+[----------] 2 tests from TypedTest/0, where TypeParam = int
+[ RUN      ] TypedTest/0.Success
+[       OK ] TypedTest/0.Success
+[ RUN      ] TypedTest/0.Failure
+gtest_output_test_.cc:#: Failure
+Value of: TypeParam()
+  Actual: 0
+Expected: 1
+Expected failure
+[  FAILED  ] TypedTest/0.Failure
+[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char
+[ RUN      ] Unsigned/TypedTestP/0.Success
+[       OK ] Unsigned/TypedTestP/0.Success
+[ RUN      ] Unsigned/TypedTestP/0.Failure
+gtest_output_test_.cc:#: Failure
+Value of: TypeParam()
+  Actual: \0
+Expected: 1U
+Which is: 1
+Expected failure
+[  FAILED  ] Unsigned/TypedTestP/0.Failure
+[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int
+[ RUN      ] Unsigned/TypedTestP/1.Success
+[       OK ] Unsigned/TypedTestP/1.Success
+[ RUN      ] Unsigned/TypedTestP/1.Failure
+gtest_output_test_.cc:#: Failure
+Value of: TypeParam()
+  Actual: 0
+Expected: 1U
+Which is: 1
+Expected failure
+[  FAILED  ] Unsigned/TypedTestP/1.Failure
+[----------] 4 tests from ExpectFailureTest
+[ RUN      ] ExpectFailureTest.ExpectFatalFailure
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+  Actual:
+gtest_output_test_.cc:#: Success:
+Succeeded
+
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+  Actual:
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure.
+
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure containing "Some other fatal failure expected."
+  Actual:
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+[  FAILED  ] ExpectFailureTest.ExpectFatalFailure
+[ RUN      ] ExpectFailureTest.ExpectNonFatalFailure
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+  Actual:
+gtest_output_test_.cc:#: Success:
+Succeeded
+
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+  Actual:
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure containing "Some other non-fatal failure."
+  Actual:
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure.
+
+[  FAILED  ] ExpectFailureTest.ExpectNonFatalFailure
+[ RUN      ] ExpectFailureTest.ExpectFatalFailureOnAllThreads
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+  Actual:
+gtest_output_test_.cc:#: Success:
+Succeeded
+
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+  Actual:
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure.
+
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 fatal failure containing "Some other fatal failure expected."
+  Actual:
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+[  FAILED  ] ExpectFailureTest.ExpectFatalFailureOnAllThreads
+[ RUN      ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+  Actual:
+gtest_output_test_.cc:#: Success:
+Succeeded
+
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+  Actual:
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+(expecting 1 failure)
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure containing "Some other non-fatal failure."
+  Actual:
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure.
+
+[  FAILED  ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads
+[----------] 2 tests from ExpectFailureWithThreadsTest
+[ RUN      ] ExpectFailureWithThreadsTest.ExpectFatalFailure
+(expecting 2 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected fatal failure.
+gtest.cc:#: Failure
+Expected: 1 fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectFailureWithThreadsTest.ExpectFatalFailure
+[ RUN      ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure
+(expecting 2 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected non-fatal failure.
+gtest.cc:#: Failure
+Expected: 1 non-fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure
+[----------] 1 test from ScopedFakeTestPartResultReporterTest
+[ RUN      ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
+(expecting 2 failures)
+gtest_output_test_.cc:#: Failure
+Failed
+Expected fatal failure.
+gtest_output_test_.cc:#: Failure
+Failed
+Expected non-fatal failure.
+[  FAILED  ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
+[----------] Global test environment tear-down
+BarEnvironment::TearDown() called.
+gtest_output_test_.cc:#: Failure
+Failed
+Expected non-fatal failure.
+FooEnvironment::TearDown() called.
+gtest_output_test_.cc:#: Failure
+Failed
+Expected fatal failure.
+[==========] 60 tests from 25 test cases ran.
+[  PASSED  ] 21 tests.
+[  FAILED  ] 39 tests, listed below:
+[  FAILED  ] FatalFailureTest.FatalFailureInSubroutine
+[  FAILED  ] FatalFailureTest.FatalFailureInNestedSubroutine
+[  FAILED  ] FatalFailureTest.NonfatalFailureInSubroutine
+[  FAILED  ] LoggingTest.InterleavingLoggingAndAssertions
+[  FAILED  ] SCOPED_TRACETest.ObeysScopes
+[  FAILED  ] SCOPED_TRACETest.WorksInLoop
+[  FAILED  ] SCOPED_TRACETest.WorksInSubroutine
+[  FAILED  ] SCOPED_TRACETest.CanBeNested
+[  FAILED  ] SCOPED_TRACETest.CanBeRepeated
+[  FAILED  ] SCOPED_TRACETest.WorksConcurrently
+[  FAILED  ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
+[  FAILED  ] FatalFailureInFixtureConstructorTest.FailureInConstructor
+[  FAILED  ] NonFatalFailureInSetUpTest.FailureInSetUp
+[  FAILED  ] FatalFailureInSetUpTest.FailureInSetUp
+[  FAILED  ] MixedUpTestCaseTest.ThisShouldFail
+[  FAILED  ] MixedUpTestCaseTest.ThisShouldFailToo
+[  FAILED  ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail
+[  FAILED  ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail
+[  FAILED  ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenStatementReturns
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenStatementThrows
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenStatementReturns
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenStatementThrows
+[  FAILED  ] TypedTest/0.Failure, where TypeParam = int
+[  FAILED  ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char
+[  FAILED  ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int
+[  FAILED  ] ExpectFailureTest.ExpectFatalFailure
+[  FAILED  ] ExpectFailureTest.ExpectNonFatalFailure
+[  FAILED  ] ExpectFailureTest.ExpectFatalFailureOnAllThreads
+[  FAILED  ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads
+[  FAILED  ] ExpectFailureWithThreadsTest.ExpectFatalFailure
+[  FAILED  ] ExpectFailureWithThreadsTest.ExpectNonFatalFailure
+[  FAILED  ] ScopedFakeTestPartResultReporterTest.InterceptOnlyCurrentThread
+
+39 FAILED TESTS
+  YOU HAVE 1 DISABLED TEST
+
+Note: Google Test filter = FatalFailureTest.*:LoggingTest.*
+[==========] Running 4 tests from 2 test cases.
+[----------] Global test environment set-up.
+[----------] 3 tests from FatalFailureTest
+[ RUN      ] FatalFailureTest.FatalFailureInSubroutine
+(expecting a failure that x should be 1)
+gtest_output_test_.cc:#: Failure
+Value of: x
+  Actual: 2
+Expected: 1
+[  FAILED  ] FatalFailureTest.FatalFailureInSubroutine (? ms)
+[ RUN      ] FatalFailureTest.FatalFailureInNestedSubroutine
+(expecting a failure that x should be 1)
+gtest_output_test_.cc:#: Failure
+Value of: x
+  Actual: 2
+Expected: 1
+[  FAILED  ] FatalFailureTest.FatalFailureInNestedSubroutine (? ms)
+[ RUN      ] FatalFailureTest.NonfatalFailureInSubroutine
+(expecting a failure on false)
+gtest_output_test_.cc:#: Failure
+Value of: false
+  Actual: false
+Expected: true
+[  FAILED  ] FatalFailureTest.NonfatalFailureInSubroutine (? ms)
+[----------] 3 tests from FatalFailureTest (? ms total)
+
+[----------] 1 test from LoggingTest
+[ RUN      ] LoggingTest.InterleavingLoggingAndAssertions
+(expecting 2 failures on (3) >= (a[i]))
+i == 0
+i == 1
+gtest_output_test_.cc:#: Failure
+Expected: (3) >= (a[i]), actual: 3 vs 9
+i == 2
+i == 3
+gtest_output_test_.cc:#: Failure
+Expected: (3) >= (a[i]), actual: 3 vs 6
+[  FAILED  ] LoggingTest.InterleavingLoggingAndAssertions (? ms)
+[----------] 1 test from LoggingTest (? ms total)
+
+[----------] Global test environment tear-down
+[==========] 4 tests from 2 test cases ran. (? ms total)
+[  PASSED  ] 0 tests.
+[  FAILED  ] 4 tests, listed below:
+[  FAILED  ] FatalFailureTest.FatalFailureInSubroutine
+[  FAILED  ] FatalFailureTest.FatalFailureInNestedSubroutine
+[  FAILED  ] FatalFailureTest.NonfatalFailureInSubroutine
+[  FAILED  ] LoggingTest.InterleavingLoggingAndAssertions
+
+ 4 FAILED TESTS
+  YOU HAVE 1 DISABLED TEST
+
+Note: Google Test filter = *DISABLED_*
+[==========] Running 1 test from 1 test case.
+[----------] Global test environment set-up.
+[----------] 1 test from DisabledTestsWarningTest
+[ RUN      ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning
+[       OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning
+[----------] Global test environment tear-down
+[==========] 1 test from 1 test case ran.
+[  PASSED  ] 1 test.
+Note: Google Test filter = PassingTest.*
+Note: This is test shard 1 of 2.
+[==========] Running 1 test from 1 test case.
+[----------] Global test environment set-up.
+[----------] 1 test from PassingTest
+[ RUN      ] PassingTest.PassingTest2
+[       OK ] PassingTest.PassingTest2
+[----------] Global test environment tear-down
+[==========] 1 test from 1 test case ran.
+[  PASSED  ] 1 test.
+
+  YOU HAVE 1 DISABLED TEST
+
diff --git a/protobuf/gtest/test/gtest_output_test_golden_win.txt b/protobuf/gtest/test/gtest_output_test_golden_win.txt
new file mode 100644
index 0000000..313c3aa
--- /dev/null
+++ b/protobuf/gtest/test/gtest_output_test_golden_win.txt
@@ -0,0 +1,605 @@
+The non-test part of the code is expected to have 2 failures.
+
+gtest_output_test_.cc:#: error: Value of: false
+  Actual: false
+Expected: true
+gtest_output_test_.cc:#: error: Value of: 3
+Expected: 2
+[==========] Running 61 tests from 27 test cases.
+[----------] Global test environment set-up.
+FooEnvironment::SetUp() called.
+BarEnvironment::SetUp() called.
+[----------] 1 test from ADeathTest
+[ RUN      ] ADeathTest.ShouldRunFirst
+[       OK ] ADeathTest.ShouldRunFirst
+[----------] 1 test from ATypedDeathTest/0, where TypeParam = int
+[ RUN      ] ATypedDeathTest/0.ShouldRunFirst
+[       OK ] ATypedDeathTest/0.ShouldRunFirst
+[----------] 1 test from ATypedDeathTest/1, where TypeParam = double
+[ RUN      ] ATypedDeathTest/1.ShouldRunFirst
+[       OK ] ATypedDeathTest/1.ShouldRunFirst
+[----------] 1 test from My/ATypeParamDeathTest/0, where TypeParam = int
+[ RUN      ] My/ATypeParamDeathTest/0.ShouldRunFirst
+[       OK ] My/ATypeParamDeathTest/0.ShouldRunFirst
+[----------] 1 test from My/ATypeParamDeathTest/1, where TypeParam = double
+[ RUN      ] My/ATypeParamDeathTest/1.ShouldRunFirst
+[       OK ] My/ATypeParamDeathTest/1.ShouldRunFirst
+[----------] 2 tests from PassingTest
+[ RUN      ] PassingTest.PassingTest1
+[       OK ] PassingTest.PassingTest1
+[ RUN      ] PassingTest.PassingTest2
+[       OK ] PassingTest.PassingTest2
+[----------] 3 tests from FatalFailureTest
+[ RUN      ] FatalFailureTest.FatalFailureInSubroutine
+(expecting a failure that x should be 1)
+gtest_output_test_.cc:#: error: Value of: x
+  Actual: 2
+Expected: 1
+[  FAILED  ] FatalFailureTest.FatalFailureInSubroutine
+[ RUN      ] FatalFailureTest.FatalFailureInNestedSubroutine
+(expecting a failure that x should be 1)
+gtest_output_test_.cc:#: error: Value of: x
+  Actual: 2
+Expected: 1
+[  FAILED  ] FatalFailureTest.FatalFailureInNestedSubroutine
+[ RUN      ] FatalFailureTest.NonfatalFailureInSubroutine
+(expecting a failure on false)
+gtest_output_test_.cc:#: error: Value of: false
+  Actual: false
+Expected: true
+[  FAILED  ] FatalFailureTest.NonfatalFailureInSubroutine
+[----------] 1 test from LoggingTest
+[ RUN      ] LoggingTest.InterleavingLoggingAndAssertions
+(expecting 2 failures on (3) >= (a[i]))
+i == 0
+i == 1
+gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 9
+i == 2
+i == 3
+gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 6
+[  FAILED  ] LoggingTest.InterleavingLoggingAndAssertions
+[----------] 5 tests from SCOPED_TRACETest
+[ RUN      ] SCOPED_TRACETest.ObeysScopes
+(expected to fail)
+gtest_output_test_.cc:#: error: Failed
+This failure is expected, and shouldn't have a trace.
+gtest_output_test_.cc:#: error: Failed
+This failure is expected, and should have a trace.
+Google Test trace:
+gtest_output_test_.cc:#: Expected trace
+gtest_output_test_.cc:#: error: Failed
+This failure is expected, and shouldn't have a trace.
+[  FAILED  ] SCOPED_TRACETest.ObeysScopes
+[ RUN      ] SCOPED_TRACETest.WorksInLoop
+(expected to fail)
+gtest_output_test_.cc:#: error: Value of: n
+  Actual: 1
+Expected: 2
+Google Test trace:
+gtest_output_test_.cc:#: i = 1
+gtest_output_test_.cc:#: error: Value of: n
+  Actual: 2
+Expected: 1
+Google Test trace:
+gtest_output_test_.cc:#: i = 2
+[  FAILED  ] SCOPED_TRACETest.WorksInLoop
+[ RUN      ] SCOPED_TRACETest.WorksInSubroutine
+(expected to fail)
+gtest_output_test_.cc:#: error: Value of: n
+  Actual: 1
+Expected: 2
+Google Test trace:
+gtest_output_test_.cc:#: n = 1
+gtest_output_test_.cc:#: error: Value of: n
+  Actual: 2
+Expected: 1
+Google Test trace:
+gtest_output_test_.cc:#: n = 2
+[  FAILED  ] SCOPED_TRACETest.WorksInSubroutine
+[ RUN      ] SCOPED_TRACETest.CanBeNested
+(expected to fail)
+gtest_output_test_.cc:#: error: Value of: n
+  Actual: 2
+Expected: 1
+Google Test trace:
+gtest_output_test_.cc:#: n = 2
+gtest_output_test_.cc:#: 
+[  FAILED  ] SCOPED_TRACETest.CanBeNested
+[ RUN      ] SCOPED_TRACETest.CanBeRepeated
+(expected to fail)
+gtest_output_test_.cc:#: error: Failed
+This failure is expected, and should contain trace point A.
+Google Test trace:
+gtest_output_test_.cc:#: A
+gtest_output_test_.cc:#: error: Failed
+This failure is expected, and should contain trace point A and B.
+Google Test trace:
+gtest_output_test_.cc:#: B
+gtest_output_test_.cc:#: A
+gtest_output_test_.cc:#: error: Failed
+This failure is expected, and should contain trace point A, B, and C.
+Google Test trace:
+gtest_output_test_.cc:#: C
+gtest_output_test_.cc:#: B
+gtest_output_test_.cc:#: A
+gtest_output_test_.cc:#: error: Failed
+This failure is expected, and should contain trace point A, B, and D.
+Google Test trace:
+gtest_output_test_.cc:#: D
+gtest_output_test_.cc:#: B
+gtest_output_test_.cc:#: A
+[  FAILED  ] SCOPED_TRACETest.CanBeRepeated
+[----------] 1 test from NonFatalFailureInFixtureConstructorTest
+[ RUN      ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
+(expecting 5 failures)
+gtest_output_test_.cc:#: error: Failed
+Expected failure #1, in the test fixture c'tor.
+gtest_output_test_.cc:#: error: Failed
+Expected failure #2, in SetUp().
+gtest_output_test_.cc:#: error: Failed
+Expected failure #3, in the test body.
+gtest_output_test_.cc:#: error: Failed
+Expected failure #4, in TearDown.
+gtest_output_test_.cc:#: error: Failed
+Expected failure #5, in the test fixture d'tor.
+[  FAILED  ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
+[----------] 1 test from FatalFailureInFixtureConstructorTest
+[ RUN      ] FatalFailureInFixtureConstructorTest.FailureInConstructor
+(expecting 2 failures)
+gtest_output_test_.cc:#: error: Failed
+Expected failure #1, in the test fixture c'tor.
+gtest_output_test_.cc:#: error: Failed
+Expected failure #2, in the test fixture d'tor.
+[  FAILED  ] FatalFailureInFixtureConstructorTest.FailureInConstructor
+[----------] 1 test from NonFatalFailureInSetUpTest
+[ RUN      ] NonFatalFailureInSetUpTest.FailureInSetUp
+(expecting 4 failures)
+gtest_output_test_.cc:#: error: Failed
+Expected failure #1, in SetUp().
+gtest_output_test_.cc:#: error: Failed
+Expected failure #2, in the test function.
+gtest_output_test_.cc:#: error: Failed
+Expected failure #3, in TearDown().
+gtest_output_test_.cc:#: error: Failed
+Expected failure #4, in the test fixture d'tor.
+[  FAILED  ] NonFatalFailureInSetUpTest.FailureInSetUp
+[----------] 1 test from FatalFailureInSetUpTest
+[ RUN      ] FatalFailureInSetUpTest.FailureInSetUp
+(expecting 3 failures)
+gtest_output_test_.cc:#: error: Failed
+Expected failure #1, in SetUp().
+gtest_output_test_.cc:#: error: Failed
+Expected failure #2, in TearDown().
+gtest_output_test_.cc:#: error: Failed
+Expected failure #3, in the test fixture d'tor.
+[  FAILED  ] FatalFailureInSetUpTest.FailureInSetUp
+[----------] 1 test from ExceptionInFixtureCtorTest
+[ RUN      ] ExceptionInFixtureCtorTest.ExceptionInFixtureCtor
+(expecting a failure on thrown exception in the test fixture's constructor)
+unknown file: error: Exception thrown with code 0xc0000005 in the test fixture's constructor.
+[----------] 1 test from ExceptionInSetUpTest
+[ RUN      ] ExceptionInSetUpTest.ExceptionInSetUp
+(expecting 3 failures)
+unknown file: error: Exception thrown with code 0xc0000005 in SetUp().
+gtest_output_test_.cc:#: error: Failed
+Expected failure #2, in TearDown().
+gtest_output_test_.cc:#: error: Failed
+Expected failure #3, in the test fixture d'tor.
+[  FAILED  ] ExceptionInSetUpTest.ExceptionInSetUp
+[----------] 2 tests from ExceptionInTestFunctionTest
+[ RUN      ] ExceptionInTestFunctionTest.SEH
+(expecting 3 failures)
+unknown file: error: Exception thrown with code 0xc0000005 in the test body.
+gtest_output_test_.cc:#: error: Failed
+Expected failure #2, in TearDown().
+gtest_output_test_.cc:#: error: Failed
+Expected failure #3, in the test fixture d'tor.
+[  FAILED  ] ExceptionInTestFunctionTest.SEH
+[ RUN      ] ExceptionInTestFunctionTest.CppException
+unknown file: error: Exception thrown with code 0xe06d7363 in the test body.
+gtest_output_test_.cc:#: error: Failed
+Expected failure #2, in TearDown().
+gtest_output_test_.cc:#: error: Failed
+Expected failure #3, in the test fixture d'tor.
+[  FAILED  ] ExceptionInTestFunctionTest.CppException
+[----------] 1 test from ExceptionInTearDownTest
+[ RUN      ] ExceptionInTearDownTest.ExceptionInTearDown
+(expecting 2 failures)
+unknown file: error: Exception thrown with code 0xe06d7363 in TearDown().
+gtest_output_test_.cc:#: error: Failed
+Expected failure #2, in the test fixture d'tor.
+[  FAILED  ] ExceptionInTearDownTest.ExceptionInTearDown
+[----------] 4 tests from MixedUpTestCaseTest
+[ RUN      ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo
+[       OK ] MixedUpTestCaseTest.FirstTestFromNamespaceFoo
+[ RUN      ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo
+[       OK ] MixedUpTestCaseTest.SecondTestFromNamespaceFoo
+[ RUN      ] MixedUpTestCaseTest.ThisShouldFail
+gtest.cc:#: error: Failed
+All tests in the same test case must use the same test fixture
+class.  However, in test case MixedUpTestCaseTest,
+you defined test FirstTestFromNamespaceFoo and test ThisShouldFail
+using two different test fixture classes.  This can happen if
+the two classes are from different namespaces or translation
+units and have the same name.  You should probably rename one
+of the classes to put the tests into different test cases.
+[  FAILED  ] MixedUpTestCaseTest.ThisShouldFail
+[ RUN      ] MixedUpTestCaseTest.ThisShouldFailToo
+gtest.cc:#: error: Failed
+All tests in the same test case must use the same test fixture
+class.  However, in test case MixedUpTestCaseTest,
+you defined test FirstTestFromNamespaceFoo and test ThisShouldFailToo
+using two different test fixture classes.  This can happen if
+the two classes are from different namespaces or translation
+units and have the same name.  You should probably rename one
+of the classes to put the tests into different test cases.
+[  FAILED  ] MixedUpTestCaseTest.ThisShouldFailToo
+[----------] 2 tests from MixedUpTestCaseWithSameTestNameTest
+[ RUN      ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail
+[       OK ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail
+[ RUN      ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail
+gtest.cc:#: error: Failed
+All tests in the same test case must use the same test fixture
+class.  However, in test case MixedUpTestCaseWithSameTestNameTest,
+you defined test TheSecondTestWithThisNameShouldFail and test TheSecondTestWithThisNameShouldFail
+using two different test fixture classes.  This can happen if
+the two classes are from different namespaces or translation
+units and have the same name.  You should probably rename one
+of the classes to put the tests into different test cases.
+[  FAILED  ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail
+[----------] 2 tests from TEST_F_before_TEST_in_same_test_case
+[ RUN      ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F
+[       OK ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTEST_F
+[ RUN      ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail
+gtest.cc:#: error: Failed
+All tests in the same test case must use the same test fixture
+class, so mixing TEST_F and TEST in the same test case is
+illegal.  In test case TEST_F_before_TEST_in_same_test_case,
+test DefinedUsingTEST_F is defined using TEST_F but
+test DefinedUsingTESTAndShouldFail is defined using TEST.  You probably
+want to change the TEST to TEST_F or move it to another test
+case.
+[  FAILED  ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail
+[----------] 2 tests from TEST_before_TEST_F_in_same_test_case
+[ RUN      ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST
+[       OK ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST
+[ RUN      ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail
+gtest.cc:#: error: Failed
+All tests in the same test case must use the same test fixture
+class, so mixing TEST_F and TEST in the same test case is
+illegal.  In test case TEST_before_TEST_F_in_same_test_case,
+test DefinedUsingTEST_FAndShouldFail is defined using TEST_F but
+test DefinedUsingTEST is defined using TEST.  You probably
+want to change the TEST to TEST_F or move it to another test
+case.
+[  FAILED  ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail
+[----------] 8 tests from ExpectNonfatalFailureTest
+[ RUN      ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables
+[       OK ] ExpectNonfatalFailureTest.CanReferenceGlobalVariables
+[ RUN      ] ExpectNonfatalFailureTest.CanReferenceLocalVariables
+[       OK ] ExpectNonfatalFailureTest.CanReferenceLocalVariables
+[ RUN      ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure
+[       OK ] ExpectNonfatalFailureTest.SucceedsWhenThereIsOneNonfatalFailure
+[ RUN      ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure
+(expecting a failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure
+[ RUN      ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures
+(expecting a failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure
+  Actual: 2 failures
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure 1.
+
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure 2.
+
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures
+[ RUN      ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure
+(expecting a failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure
+  Actual:
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure
+[ RUN      ] ExpectNonfatalFailureTest.FailsWhenStatementReturns
+(expecting a failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenStatementReturns
+[ RUN      ] ExpectNonfatalFailureTest.FailsWhenStatementThrows
+(expecting a failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenStatementThrows
+[----------] 8 tests from ExpectFatalFailureTest
+[ RUN      ] ExpectFatalFailureTest.CanReferenceGlobalVariables
+[       OK ] ExpectFatalFailureTest.CanReferenceGlobalVariables
+[ RUN      ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables
+[       OK ] ExpectFatalFailureTest.CanReferenceLocalStaticVariables
+[ RUN      ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure
+[       OK ] ExpectFatalFailureTest.SucceedsWhenThereIsOneFatalFailure
+[ RUN      ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure
+(expecting a failure)
+gtest.cc:#: error: Expected: 1 fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure
+[ RUN      ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures
+(expecting a failure)
+gtest.cc:#: error: Expected: 1 fatal failure
+  Actual: 2 failures
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures
+[ RUN      ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure
+(expecting a failure)
+gtest.cc:#: error: Expected: 1 fatal failure
+  Actual:
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure.
+
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure
+[ RUN      ] ExpectFatalFailureTest.FailsWhenStatementReturns
+(expecting a failure)
+gtest.cc:#: error: Expected: 1 fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenStatementReturns
+[ RUN      ] ExpectFatalFailureTest.FailsWhenStatementThrows
+(expecting a failure)
+gtest.cc:#: error: Expected: 1 fatal failure
+  Actual: 0 failures
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenStatementThrows
+[----------] 2 tests from TypedTest/0, where TypeParam = int
+[ RUN      ] TypedTest/0.Success
+[       OK ] TypedTest/0.Success
+[ RUN      ] TypedTest/0.Failure
+gtest_output_test_.cc:#: error: Value of: TypeParam()
+  Actual: 0
+Expected: 1
+Expected failure
+[  FAILED  ] TypedTest/0.Failure
+[----------] 2 tests from Unsigned/TypedTestP/0, where TypeParam = unsigned char
+[ RUN      ] Unsigned/TypedTestP/0.Success
+[       OK ] Unsigned/TypedTestP/0.Success
+[ RUN      ] Unsigned/TypedTestP/0.Failure
+gtest_output_test_.cc:#: error: Value of: TypeParam()
+  Actual: \0
+Expected: 1U
+Which is: 1
+Expected failure
+[  FAILED  ] Unsigned/TypedTestP/0.Failure
+[----------] 2 tests from Unsigned/TypedTestP/1, where TypeParam = unsigned int
+[ RUN      ] Unsigned/TypedTestP/1.Success
+[       OK ] Unsigned/TypedTestP/1.Success
+[ RUN      ] Unsigned/TypedTestP/1.Failure
+gtest_output_test_.cc:#: error: Value of: TypeParam()
+  Actual: 0
+Expected: 1U
+Which is: 1
+Expected failure
+[  FAILED  ] Unsigned/TypedTestP/1.Failure
+[----------] 4 tests from ExpectFailureTest
+[ RUN      ] ExpectFailureTest.ExpectFatalFailure
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 fatal failure
+  Actual:
+gtest_output_test_.cc:#: Success:
+Succeeded
+
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 fatal failure
+  Actual:
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure.
+
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 fatal failure containing "Some other fatal failure expected."
+  Actual:
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+[  FAILED  ] ExpectFailureTest.ExpectFatalFailure
+[ RUN      ] ExpectFailureTest.ExpectNonFatalFailure
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure
+  Actual:
+gtest_output_test_.cc:#: Success:
+Succeeded
+
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure
+  Actual:
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure containing "Some other non-fatal failure."
+  Actual:
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure.
+
+[  FAILED  ] ExpectFailureTest.ExpectNonFatalFailure
+[ RUN      ] ExpectFailureTest.ExpectFatalFailureOnAllThreads
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 fatal failure
+  Actual:
+gtest_output_test_.cc:#: Success:
+Succeeded
+
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 fatal failure
+  Actual:
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure.
+
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 fatal failure containing "Some other fatal failure expected."
+  Actual:
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+[  FAILED  ] ExpectFailureTest.ExpectFatalFailureOnAllThreads
+[ RUN      ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure
+  Actual:
+gtest_output_test_.cc:#: Success:
+Succeeded
+
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure
+  Actual:
+gtest_output_test_.cc:#: Fatal failure:
+Failed
+Expected fatal failure.
+
+(expecting 1 failure)
+gtest.cc:#: error: Expected: 1 non-fatal failure containing "Some other non-fatal failure."
+  Actual:
+gtest_output_test_.cc:#: Non-fatal failure:
+Failed
+Expected non-fatal failure.
+
+[  FAILED  ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads
+[----------] Global test environment tear-down
+BarEnvironment::TearDown() called.
+gtest_output_test_.cc:#: error: Failed
+Expected non-fatal failure.
+FooEnvironment::TearDown() called.
+gtest_output_test_.cc:#: error: Failed
+Expected fatal failure.
+[==========] 61 tests from 27 test cases ran.
+[  PASSED  ] 21 tests.
+[  FAILED  ] 40 tests, listed below:
+[  FAILED  ] FatalFailureTest.FatalFailureInSubroutine
+[  FAILED  ] FatalFailureTest.FatalFailureInNestedSubroutine
+[  FAILED  ] FatalFailureTest.NonfatalFailureInSubroutine
+[  FAILED  ] LoggingTest.InterleavingLoggingAndAssertions
+[  FAILED  ] SCOPED_TRACETest.ObeysScopes
+[  FAILED  ] SCOPED_TRACETest.WorksInLoop
+[  FAILED  ] SCOPED_TRACETest.WorksInSubroutine
+[  FAILED  ] SCOPED_TRACETest.CanBeNested
+[  FAILED  ] SCOPED_TRACETest.CanBeRepeated
+[  FAILED  ] NonFatalFailureInFixtureConstructorTest.FailureInConstructor
+[  FAILED  ] FatalFailureInFixtureConstructorTest.FailureInConstructor
+[  FAILED  ] NonFatalFailureInSetUpTest.FailureInSetUp
+[  FAILED  ] FatalFailureInSetUpTest.FailureInSetUp
+[  FAILED  ] ExceptionInFixtureCtorTest.ExceptionInFixtureCtor
+[  FAILED  ] ExceptionInSetUpTest.ExceptionInSetUp
+[  FAILED  ] ExceptionInTestFunctionTest.SEH
+[  FAILED  ] ExceptionInTestFunctionTest.CppException
+[  FAILED  ] ExceptionInTearDownTest.ExceptionInTearDown
+[  FAILED  ] MixedUpTestCaseTest.ThisShouldFail
+[  FAILED  ] MixedUpTestCaseTest.ThisShouldFailToo
+[  FAILED  ] MixedUpTestCaseWithSameTestNameTest.TheSecondTestWithThisNameShouldFail
+[  FAILED  ] TEST_F_before_TEST_in_same_test_case.DefinedUsingTESTAndShouldFail
+[  FAILED  ] TEST_before_TEST_F_in_same_test_case.DefinedUsingTEST_FAndShouldFail
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereIsNoNonfatalFailure
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereAreTwoNonfatalFailures
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenThereIsOneFatalFailure
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenStatementReturns
+[  FAILED  ] ExpectNonfatalFailureTest.FailsWhenStatementThrows
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereIsNoFatalFailure
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereAreTwoFatalFailures
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenThereIsOneNonfatalFailure
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenStatementReturns
+[  FAILED  ] ExpectFatalFailureTest.FailsWhenStatementThrows
+[  FAILED  ] TypedTest/0.Failure, where TypeParam = int
+[  FAILED  ] Unsigned/TypedTestP/0.Failure, where TypeParam = unsigned char
+[  FAILED  ] Unsigned/TypedTestP/1.Failure, where TypeParam = unsigned int
+[  FAILED  ] ExpectFailureTest.ExpectFatalFailure
+[  FAILED  ] ExpectFailureTest.ExpectNonFatalFailure
+[  FAILED  ] ExpectFailureTest.ExpectFatalFailureOnAllThreads
+[  FAILED  ] ExpectFailureTest.ExpectNonFatalFailureOnAllThreads
+
+40 FAILED TESTS
+  YOU HAVE 1 DISABLED TEST
+
+Note: Google Test filter = FatalFailureTest.*:LoggingTest.*
+[==========] Running 4 tests from 2 test cases.
+[----------] Global test environment set-up.
+[----------] 3 tests from FatalFailureTest
+[ RUN      ] FatalFailureTest.FatalFailureInSubroutine
+(expecting a failure that x should be 1)
+gtest_output_test_.cc:#: error: Value of: x
+  Actual: 2
+Expected: 1
+[  FAILED  ] FatalFailureTest.FatalFailureInSubroutine (? ms)
+[ RUN      ] FatalFailureTest.FatalFailureInNestedSubroutine
+(expecting a failure that x should be 1)
+gtest_output_test_.cc:#: error: Value of: x
+  Actual: 2
+Expected: 1
+[  FAILED  ] FatalFailureTest.FatalFailureInNestedSubroutine (? ms)
+[ RUN      ] FatalFailureTest.NonfatalFailureInSubroutine
+(expecting a failure on false)
+gtest_output_test_.cc:#: error: Value of: false
+  Actual: false
+Expected: true
+[  FAILED  ] FatalFailureTest.NonfatalFailureInSubroutine (? ms)
+[----------] 3 tests from FatalFailureTest (? ms total)
+
+[----------] 1 test from LoggingTest
+[ RUN      ] LoggingTest.InterleavingLoggingAndAssertions
+(expecting 2 failures on (3) >= (a[i]))
+i == 0
+i == 1
+gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 9
+i == 2
+i == 3
+gtest_output_test_.cc:#: error: Expected: (3) >= (a[i]), actual: 3 vs 6
+[  FAILED  ] LoggingTest.InterleavingLoggingAndAssertions (? ms)
+[----------] 1 test from LoggingTest (? ms total)
+
+[----------] Global test environment tear-down
+[==========] 4 tests from 2 test cases ran. (? ms total)
+[  PASSED  ] 0 tests.
+[  FAILED  ] 4 tests, listed below:
+[  FAILED  ] FatalFailureTest.FatalFailureInSubroutine
+[  FAILED  ] FatalFailureTest.FatalFailureInNestedSubroutine
+[  FAILED  ] FatalFailureTest.NonfatalFailureInSubroutine
+[  FAILED  ] LoggingTest.InterleavingLoggingAndAssertions
+
+ 4 FAILED TESTS
+  YOU HAVE 1 DISABLED TEST
+
+Note: Google Test filter = *DISABLED_*
+[==========] Running 1 test from 1 test case.
+[----------] Global test environment set-up.
+[----------] 1 test from DisabledTestsWarningTest
+[ RUN      ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning
+[       OK ] DisabledTestsWarningTest.DISABLED_AlsoRunDisabledTestsFlagSuppressesWarning
+[----------] Global test environment tear-down
+[==========] 1 test from 1 test case ran.
+[  PASSED  ] 1 test.
+Note: Google Test filter = PassingTest.*
+Note: This is test shard 1 of 2.
+[==========] Running 1 test from 1 test case.
+[----------] Global test environment set-up.
+[----------] 1 test from PassingTest
+[ RUN      ] PassingTest.PassingTest2
+[       OK ] PassingTest.PassingTest2
+[----------] Global test environment tear-down
+[==========] 1 test from 1 test case ran.
+[  PASSED  ] 1 test.
+
+  YOU HAVE 1 DISABLED TEST
+
diff --git a/protobuf/gtest/test/gtest_pred_impl_unittest.cc b/protobuf/gtest/test/gtest_pred_impl_unittest.cc
new file mode 100644
index 0000000..e7ee54b
--- /dev/null
+++ b/protobuf/gtest/test/gtest_pred_impl_unittest.cc
@@ -0,0 +1,2432 @@
+// 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 10/02/2008 by command
+// 'gen_gtest_pred_impl.py 5'.  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");
+}
+
+// Sample functions/functors for testing unary predicate assertions.
+
+// A unary predicate function.
+template <typename T1>
+bool PredFunction1(T1 v1) {
+  return v1 > 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 PredFunction1Int(int v1) {
+  return v1 > 0;
+}
+bool PredFunction1Bool(Bool v1) {
+  return v1 > 0;
+}
+
+// A unary predicate functor.
+struct PredFunctor1 {
+  template <typename T1>
+  bool operator()(const T1& v1) {
+    return v1 > 0;
+  }
+};
+
+// A unary predicate-formatter function.
+template <typename T1>
+testing::AssertionResult PredFormatFunction1(const char* e1,
+                                             const T1& v1) {
+  if (PredFunction1(v1))
+    return testing::AssertionSuccess();
+
+  testing::Message msg;
+  msg << e1
+      << " is expected to be positive, but evaluates to "
+      << v1 << ".";
+  return testing::AssertionFailure(msg);
+}
+
+// A unary predicate-formatter functor.
+struct PredFormatFunctor1 {
+  template <typename T1>
+  testing::AssertionResult operator()(const char* e1,
+                                      const T1& v1) const {
+    return PredFormatFunction1(e1, v1);
+  }
+};
+
+// Tests for {EXPECT|ASSERT}_PRED_FORMAT1.
+
+class Predicate1Test : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    expected_to_finish_ = true;
+    finished_ = false;
+    n1_ = 0;
+  }
+
+  virtual void TearDown() {
+    // Verifies that each of the predicate's arguments was evaluated
+    // exactly once.
+    EXPECT_EQ(1, n1_) <<
+        "The predicate assertion didn't evaluate argument 2 "
+        "exactly once.";
+
+    // 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_;
+
+  static int n1_;
+};
+
+bool Predicate1Test::expected_to_finish_;
+bool Predicate1Test::finished_;
+int Predicate1Test::n1_;
+
+typedef Predicate1Test EXPECT_PRED_FORMAT1Test;
+typedef Predicate1Test ASSERT_PRED_FORMAT1Test;
+typedef Predicate1Test EXPECT_PRED1Test;
+typedef Predicate1Test ASSERT_PRED1Test;
+
+// Tests a successful EXPECT_PRED1 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeSuccess) {
+  EXPECT_PRED1(PredFunction1Int,
+               ++n1_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED1 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeSuccess) {
+  EXPECT_PRED1(PredFunction1Bool,
+               Bool(++n1_));
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED1 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeSuccess) {
+  EXPECT_PRED1(PredFunctor1(),
+               ++n1_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED1 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeSuccess) {
+  EXPECT_PRED1(PredFunctor1(),
+               Bool(++n1_));
+  finished_ = true;
+}
+
+// Tests a failed EXPECT_PRED1 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED1Test, FunctionOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED1(PredFunction1Int,
+                 n1_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED1 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED1Test, FunctionOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED1(PredFunction1Bool,
+                 Bool(n1_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED1 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED1Test, FunctorOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED1(PredFunctor1(),
+                 n1_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED1 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED1Test, FunctorOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED1(PredFunctor1(),
+                 Bool(n1_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful ASSERT_PRED1 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeSuccess) {
+  ASSERT_PRED1(PredFunction1Int,
+               ++n1_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED1 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeSuccess) {
+  ASSERT_PRED1(PredFunction1Bool,
+               Bool(++n1_));
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED1 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeSuccess) {
+  ASSERT_PRED1(PredFunctor1(),
+               ++n1_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED1 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeSuccess) {
+  ASSERT_PRED1(PredFunctor1(),
+               Bool(++n1_));
+  finished_ = true;
+}
+
+// Tests a failed ASSERT_PRED1 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED1Test, FunctionOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED1(PredFunction1Int,
+                 n1_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED1 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED1Test, FunctionOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED1(PredFunction1Bool,
+                 Bool(n1_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED1 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED1Test, FunctorOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED1(PredFunctor1(),
+                 n1_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED1 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED1Test, FunctorOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED1(PredFunctor1(),
+                 Bool(n1_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful EXPECT_PRED_FORMAT1 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) {
+  EXPECT_PRED_FORMAT1(PredFormatFunction1,
+                      ++n1_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT1 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) {
+  EXPECT_PRED_FORMAT1(PredFormatFunction1,
+                      Bool(++n1_));
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT1 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) {
+  EXPECT_PRED_FORMAT1(PredFormatFunctor1(),
+                      ++n1_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT1 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) {
+  EXPECT_PRED_FORMAT1(PredFormatFunctor1(),
+                      Bool(++n1_));
+  finished_ = true;
+}
+
+// Tests a failed EXPECT_PRED_FORMAT1 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT1(PredFormatFunction1,
+                        n1_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT1 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT1(PredFormatFunction1,
+                        Bool(n1_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT1 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT1(PredFormatFunctor1(),
+                        n1_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT1 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT1(PredFormatFunctor1(),
+                        Bool(n1_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful ASSERT_PRED_FORMAT1 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeSuccess) {
+  ASSERT_PRED_FORMAT1(PredFormatFunction1,
+                      ++n1_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT1 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeSuccess) {
+  ASSERT_PRED_FORMAT1(PredFormatFunction1,
+                      Bool(++n1_));
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT1 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeSuccess) {
+  ASSERT_PRED_FORMAT1(PredFormatFunctor1(),
+                      ++n1_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT1 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeSuccess) {
+  ASSERT_PRED_FORMAT1(PredFormatFunctor1(),
+                      Bool(++n1_));
+  finished_ = true;
+}
+
+// Tests a failed ASSERT_PRED_FORMAT1 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT1(PredFormatFunction1,
+                        n1_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT1 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT1Test, FunctionOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT1(PredFormatFunction1,
+                        Bool(n1_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT1 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT1(PredFormatFunctor1(),
+                        n1_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT1 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT1Test, FunctorOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT1(PredFormatFunctor1(),
+                        Bool(n1_++));
+    finished_ = true;
+  }, "");
+}
+// Sample functions/functors for testing binary predicate assertions.
+
+// A binary predicate function.
+template <typename T1, typename T2>
+bool PredFunction2(T1 v1, T2 v2) {
+  return v1 + v2 > 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 PredFunction2Int(int v1, int v2) {
+  return v1 + v2 > 0;
+}
+bool PredFunction2Bool(Bool v1, Bool v2) {
+  return v1 + v2 > 0;
+}
+
+// A binary predicate functor.
+struct PredFunctor2 {
+  template <typename T1, typename T2>
+  bool operator()(const T1& v1,
+                  const T2& v2) {
+    return v1 + v2 > 0;
+  }
+};
+
+// A binary predicate-formatter function.
+template <typename T1, typename T2>
+testing::AssertionResult PredFormatFunction2(const char* e1,
+                                             const char* e2,
+                                             const T1& v1,
+                                             const T2& v2) {
+  if (PredFunction2(v1, v2))
+    return testing::AssertionSuccess();
+
+  testing::Message msg;
+  msg << e1 << " + " << e2
+      << " is expected to be positive, but evaluates to "
+      << v1 + v2 << ".";
+  return testing::AssertionFailure(msg);
+}
+
+// A binary predicate-formatter functor.
+struct PredFormatFunctor2 {
+  template <typename T1, typename T2>
+  testing::AssertionResult operator()(const char* e1,
+                                      const char* e2,
+                                      const T1& v1,
+                                      const T2& v2) const {
+    return PredFormatFunction2(e1, e2, v1, v2);
+  }
+};
+
+// Tests for {EXPECT|ASSERT}_PRED_FORMAT2.
+
+class Predicate2Test : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    expected_to_finish_ = true;
+    finished_ = false;
+    n1_ = n2_ = 0;
+  }
+
+  virtual void TearDown() {
+    // Verifies that each of the predicate's arguments was evaluated
+    // exactly once.
+    EXPECT_EQ(1, n1_) <<
+        "The predicate assertion didn't evaluate argument 2 "
+        "exactly once.";
+    EXPECT_EQ(1, n2_) <<
+        "The predicate assertion didn't evaluate argument 3 "
+        "exactly once.";
+
+    // 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_;
+
+  static int n1_;
+  static int n2_;
+};
+
+bool Predicate2Test::expected_to_finish_;
+bool Predicate2Test::finished_;
+int Predicate2Test::n1_;
+int Predicate2Test::n2_;
+
+typedef Predicate2Test EXPECT_PRED_FORMAT2Test;
+typedef Predicate2Test ASSERT_PRED_FORMAT2Test;
+typedef Predicate2Test EXPECT_PRED2Test;
+typedef Predicate2Test ASSERT_PRED2Test;
+
+// Tests a successful EXPECT_PRED2 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeSuccess) {
+  EXPECT_PRED2(PredFunction2Int,
+               ++n1_,
+               ++n2_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED2 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeSuccess) {
+  EXPECT_PRED2(PredFunction2Bool,
+               Bool(++n1_),
+               Bool(++n2_));
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED2 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeSuccess) {
+  EXPECT_PRED2(PredFunctor2(),
+               ++n1_,
+               ++n2_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED2 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeSuccess) {
+  EXPECT_PRED2(PredFunctor2(),
+               Bool(++n1_),
+               Bool(++n2_));
+  finished_ = true;
+}
+
+// Tests a failed EXPECT_PRED2 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED2Test, FunctionOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED2(PredFunction2Int,
+                 n1_++,
+                 n2_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED2 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED2Test, FunctionOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED2(PredFunction2Bool,
+                 Bool(n1_++),
+                 Bool(n2_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED2 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED2Test, FunctorOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED2(PredFunctor2(),
+                 n1_++,
+                 n2_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED2 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED2Test, FunctorOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED2(PredFunctor2(),
+                 Bool(n1_++),
+                 Bool(n2_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful ASSERT_PRED2 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeSuccess) {
+  ASSERT_PRED2(PredFunction2Int,
+               ++n1_,
+               ++n2_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED2 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeSuccess) {
+  ASSERT_PRED2(PredFunction2Bool,
+               Bool(++n1_),
+               Bool(++n2_));
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED2 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeSuccess) {
+  ASSERT_PRED2(PredFunctor2(),
+               ++n1_,
+               ++n2_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED2 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeSuccess) {
+  ASSERT_PRED2(PredFunctor2(),
+               Bool(++n1_),
+               Bool(++n2_));
+  finished_ = true;
+}
+
+// Tests a failed ASSERT_PRED2 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED2Test, FunctionOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED2(PredFunction2Int,
+                 n1_++,
+                 n2_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED2 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED2Test, FunctionOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED2(PredFunction2Bool,
+                 Bool(n1_++),
+                 Bool(n2_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED2 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED2Test, FunctorOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED2(PredFunctor2(),
+                 n1_++,
+                 n2_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED2 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED2Test, FunctorOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED2(PredFunctor2(),
+                 Bool(n1_++),
+                 Bool(n2_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful EXPECT_PRED_FORMAT2 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) {
+  EXPECT_PRED_FORMAT2(PredFormatFunction2,
+                      ++n1_,
+                      ++n2_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT2 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) {
+  EXPECT_PRED_FORMAT2(PredFormatFunction2,
+                      Bool(++n1_),
+                      Bool(++n2_));
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT2 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) {
+  EXPECT_PRED_FORMAT2(PredFormatFunctor2(),
+                      ++n1_,
+                      ++n2_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT2 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) {
+  EXPECT_PRED_FORMAT2(PredFormatFunctor2(),
+                      Bool(++n1_),
+                      Bool(++n2_));
+  finished_ = true;
+}
+
+// Tests a failed EXPECT_PRED_FORMAT2 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT2(PredFormatFunction2,
+                        n1_++,
+                        n2_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT2 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT2(PredFormatFunction2,
+                        Bool(n1_++),
+                        Bool(n2_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT2 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT2(PredFormatFunctor2(),
+                        n1_++,
+                        n2_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT2 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT2(PredFormatFunctor2(),
+                        Bool(n1_++),
+                        Bool(n2_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful ASSERT_PRED_FORMAT2 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeSuccess) {
+  ASSERT_PRED_FORMAT2(PredFormatFunction2,
+                      ++n1_,
+                      ++n2_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT2 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeSuccess) {
+  ASSERT_PRED_FORMAT2(PredFormatFunction2,
+                      Bool(++n1_),
+                      Bool(++n2_));
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT2 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeSuccess) {
+  ASSERT_PRED_FORMAT2(PredFormatFunctor2(),
+                      ++n1_,
+                      ++n2_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT2 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeSuccess) {
+  ASSERT_PRED_FORMAT2(PredFormatFunctor2(),
+                      Bool(++n1_),
+                      Bool(++n2_));
+  finished_ = true;
+}
+
+// Tests a failed ASSERT_PRED_FORMAT2 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT2(PredFormatFunction2,
+                        n1_++,
+                        n2_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT2 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT2Test, FunctionOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT2(PredFormatFunction2,
+                        Bool(n1_++),
+                        Bool(n2_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT2 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT2(PredFormatFunctor2(),
+                        n1_++,
+                        n2_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT2 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT2Test, FunctorOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT2(PredFormatFunctor2(),
+                        Bool(n1_++),
+                        Bool(n2_++));
+    finished_ = true;
+  }, "");
+}
+// Sample functions/functors for testing ternary predicate assertions.
+
+// A ternary predicate function.
+template <typename T1, typename T2, typename T3>
+bool PredFunction3(T1 v1, T2 v2, T3 v3) {
+  return v1 + v2 + v3 > 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 PredFunction3Int(int v1, int v2, int v3) {
+  return v1 + v2 + v3 > 0;
+}
+bool PredFunction3Bool(Bool v1, Bool v2, Bool v3) {
+  return v1 + v2 + v3 > 0;
+}
+
+// A ternary predicate functor.
+struct PredFunctor3 {
+  template <typename T1, typename T2, typename T3>
+  bool operator()(const T1& v1,
+                  const T2& v2,
+                  const T3& v3) {
+    return v1 + v2 + v3 > 0;
+  }
+};
+
+// A ternary predicate-formatter function.
+template <typename T1, typename T2, typename T3>
+testing::AssertionResult PredFormatFunction3(const char* e1,
+                                             const char* e2,
+                                             const char* e3,
+                                             const T1& v1,
+                                             const T2& v2,
+                                             const T3& v3) {
+  if (PredFunction3(v1, v2, v3))
+    return testing::AssertionSuccess();
+
+  testing::Message msg;
+  msg << e1 << " + " << e2 << " + " << e3
+      << " is expected to be positive, but evaluates to "
+      << v1 + v2 + v3 << ".";
+  return testing::AssertionFailure(msg);
+}
+
+// A ternary predicate-formatter functor.
+struct PredFormatFunctor3 {
+  template <typename T1, typename T2, typename T3>
+  testing::AssertionResult operator()(const char* e1,
+                                      const char* e2,
+                                      const char* e3,
+                                      const T1& v1,
+                                      const T2& v2,
+                                      const T3& v3) const {
+    return PredFormatFunction3(e1, e2, e3, v1, v2, v3);
+  }
+};
+
+// Tests for {EXPECT|ASSERT}_PRED_FORMAT3.
+
+class Predicate3Test : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    expected_to_finish_ = true;
+    finished_ = false;
+    n1_ = n2_ = n3_ = 0;
+  }
+
+  virtual void TearDown() {
+    // Verifies that each of the predicate's arguments was evaluated
+    // exactly once.
+    EXPECT_EQ(1, n1_) <<
+        "The predicate assertion didn't evaluate argument 2 "
+        "exactly once.";
+    EXPECT_EQ(1, n2_) <<
+        "The predicate assertion didn't evaluate argument 3 "
+        "exactly once.";
+    EXPECT_EQ(1, n3_) <<
+        "The predicate assertion didn't evaluate argument 4 "
+        "exactly once.";
+
+    // 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_;
+
+  static int n1_;
+  static int n2_;
+  static int n3_;
+};
+
+bool Predicate3Test::expected_to_finish_;
+bool Predicate3Test::finished_;
+int Predicate3Test::n1_;
+int Predicate3Test::n2_;
+int Predicate3Test::n3_;
+
+typedef Predicate3Test EXPECT_PRED_FORMAT3Test;
+typedef Predicate3Test ASSERT_PRED_FORMAT3Test;
+typedef Predicate3Test EXPECT_PRED3Test;
+typedef Predicate3Test ASSERT_PRED3Test;
+
+// Tests a successful EXPECT_PRED3 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeSuccess) {
+  EXPECT_PRED3(PredFunction3Int,
+               ++n1_,
+               ++n2_,
+               ++n3_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED3 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeSuccess) {
+  EXPECT_PRED3(PredFunction3Bool,
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_));
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED3 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeSuccess) {
+  EXPECT_PRED3(PredFunctor3(),
+               ++n1_,
+               ++n2_,
+               ++n3_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED3 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeSuccess) {
+  EXPECT_PRED3(PredFunctor3(),
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_));
+  finished_ = true;
+}
+
+// Tests a failed EXPECT_PRED3 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED3Test, FunctionOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED3(PredFunction3Int,
+                 n1_++,
+                 n2_++,
+                 n3_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED3 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED3Test, FunctionOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED3(PredFunction3Bool,
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED3 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED3Test, FunctorOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED3(PredFunctor3(),
+                 n1_++,
+                 n2_++,
+                 n3_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED3 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED3Test, FunctorOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED3(PredFunctor3(),
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful ASSERT_PRED3 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeSuccess) {
+  ASSERT_PRED3(PredFunction3Int,
+               ++n1_,
+               ++n2_,
+               ++n3_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED3 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeSuccess) {
+  ASSERT_PRED3(PredFunction3Bool,
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_));
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED3 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeSuccess) {
+  ASSERT_PRED3(PredFunctor3(),
+               ++n1_,
+               ++n2_,
+               ++n3_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED3 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeSuccess) {
+  ASSERT_PRED3(PredFunctor3(),
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_));
+  finished_ = true;
+}
+
+// Tests a failed ASSERT_PRED3 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED3Test, FunctionOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED3(PredFunction3Int,
+                 n1_++,
+                 n2_++,
+                 n3_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED3 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED3Test, FunctionOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED3(PredFunction3Bool,
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED3 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED3Test, FunctorOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED3(PredFunctor3(),
+                 n1_++,
+                 n2_++,
+                 n3_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED3 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED3Test, FunctorOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED3(PredFunctor3(),
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful EXPECT_PRED_FORMAT3 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) {
+  EXPECT_PRED_FORMAT3(PredFormatFunction3,
+                      ++n1_,
+                      ++n2_,
+                      ++n3_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT3 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) {
+  EXPECT_PRED_FORMAT3(PredFormatFunction3,
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_));
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT3 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) {
+  EXPECT_PRED_FORMAT3(PredFormatFunctor3(),
+                      ++n1_,
+                      ++n2_,
+                      ++n3_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT3 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) {
+  EXPECT_PRED_FORMAT3(PredFormatFunctor3(),
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_));
+  finished_ = true;
+}
+
+// Tests a failed EXPECT_PRED_FORMAT3 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT3(PredFormatFunction3,
+                        n1_++,
+                        n2_++,
+                        n3_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT3 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT3(PredFormatFunction3,
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT3 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT3(PredFormatFunctor3(),
+                        n1_++,
+                        n2_++,
+                        n3_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT3 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT3(PredFormatFunctor3(),
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful ASSERT_PRED_FORMAT3 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeSuccess) {
+  ASSERT_PRED_FORMAT3(PredFormatFunction3,
+                      ++n1_,
+                      ++n2_,
+                      ++n3_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT3 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeSuccess) {
+  ASSERT_PRED_FORMAT3(PredFormatFunction3,
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_));
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT3 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeSuccess) {
+  ASSERT_PRED_FORMAT3(PredFormatFunctor3(),
+                      ++n1_,
+                      ++n2_,
+                      ++n3_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT3 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeSuccess) {
+  ASSERT_PRED_FORMAT3(PredFormatFunctor3(),
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_));
+  finished_ = true;
+}
+
+// Tests a failed ASSERT_PRED_FORMAT3 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT3(PredFormatFunction3,
+                        n1_++,
+                        n2_++,
+                        n3_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT3 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT3Test, FunctionOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT3(PredFormatFunction3,
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT3 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT3(PredFormatFunctor3(),
+                        n1_++,
+                        n2_++,
+                        n3_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT3 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT3Test, FunctorOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT3(PredFormatFunctor3(),
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++));
+    finished_ = true;
+  }, "");
+}
+// Sample functions/functors for testing 4-ary predicate assertions.
+
+// A 4-ary predicate function.
+template <typename T1, typename T2, typename T3, typename T4>
+bool PredFunction4(T1 v1, T2 v2, T3 v3, T4 v4) {
+  return v1 + v2 + v3 + v4 > 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 PredFunction4Int(int v1, int v2, int v3, int v4) {
+  return v1 + v2 + v3 + v4 > 0;
+}
+bool PredFunction4Bool(Bool v1, Bool v2, Bool v3, Bool v4) {
+  return v1 + v2 + v3 + v4 > 0;
+}
+
+// A 4-ary predicate functor.
+struct PredFunctor4 {
+  template <typename T1, typename T2, typename T3, typename T4>
+  bool operator()(const T1& v1,
+                  const T2& v2,
+                  const T3& v3,
+                  const T4& v4) {
+    return v1 + v2 + v3 + v4 > 0;
+  }
+};
+
+// A 4-ary predicate-formatter function.
+template <typename T1, typename T2, typename T3, typename T4>
+testing::AssertionResult PredFormatFunction4(const char* e1,
+                                             const char* e2,
+                                             const char* e3,
+                                             const char* e4,
+                                             const T1& v1,
+                                             const T2& v2,
+                                             const T3& v3,
+                                             const T4& v4) {
+  if (PredFunction4(v1, v2, v3, v4))
+    return testing::AssertionSuccess();
+
+  testing::Message msg;
+  msg << e1 << " + " << e2 << " + " << e3 << " + " << e4
+      << " is expected to be positive, but evaluates to "
+      << v1 + v2 + v3 + v4 << ".";
+  return testing::AssertionFailure(msg);
+}
+
+// A 4-ary predicate-formatter functor.
+struct PredFormatFunctor4 {
+  template <typename T1, typename T2, typename T3, typename T4>
+  testing::AssertionResult operator()(const char* e1,
+                                      const char* e2,
+                                      const char* e3,
+                                      const char* e4,
+                                      const T1& v1,
+                                      const T2& v2,
+                                      const T3& v3,
+                                      const T4& v4) const {
+    return PredFormatFunction4(e1, e2, e3, e4, v1, v2, v3, v4);
+  }
+};
+
+// Tests for {EXPECT|ASSERT}_PRED_FORMAT4.
+
+class Predicate4Test : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    expected_to_finish_ = true;
+    finished_ = false;
+    n1_ = n2_ = n3_ = n4_ = 0;
+  }
+
+  virtual void TearDown() {
+    // Verifies that each of the predicate's arguments was evaluated
+    // exactly once.
+    EXPECT_EQ(1, n1_) <<
+        "The predicate assertion didn't evaluate argument 2 "
+        "exactly once.";
+    EXPECT_EQ(1, n2_) <<
+        "The predicate assertion didn't evaluate argument 3 "
+        "exactly once.";
+    EXPECT_EQ(1, n3_) <<
+        "The predicate assertion didn't evaluate argument 4 "
+        "exactly once.";
+    EXPECT_EQ(1, n4_) <<
+        "The predicate assertion didn't evaluate argument 5 "
+        "exactly once.";
+
+    // 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_;
+
+  static int n1_;
+  static int n2_;
+  static int n3_;
+  static int n4_;
+};
+
+bool Predicate4Test::expected_to_finish_;
+bool Predicate4Test::finished_;
+int Predicate4Test::n1_;
+int Predicate4Test::n2_;
+int Predicate4Test::n3_;
+int Predicate4Test::n4_;
+
+typedef Predicate4Test EXPECT_PRED_FORMAT4Test;
+typedef Predicate4Test ASSERT_PRED_FORMAT4Test;
+typedef Predicate4Test EXPECT_PRED4Test;
+typedef Predicate4Test ASSERT_PRED4Test;
+
+// Tests a successful EXPECT_PRED4 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeSuccess) {
+  EXPECT_PRED4(PredFunction4Int,
+               ++n1_,
+               ++n2_,
+               ++n3_,
+               ++n4_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED4 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeSuccess) {
+  EXPECT_PRED4(PredFunction4Bool,
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_),
+               Bool(++n4_));
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED4 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeSuccess) {
+  EXPECT_PRED4(PredFunctor4(),
+               ++n1_,
+               ++n2_,
+               ++n3_,
+               ++n4_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED4 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeSuccess) {
+  EXPECT_PRED4(PredFunctor4(),
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_),
+               Bool(++n4_));
+  finished_ = true;
+}
+
+// Tests a failed EXPECT_PRED4 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED4Test, FunctionOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED4(PredFunction4Int,
+                 n1_++,
+                 n2_++,
+                 n3_++,
+                 n4_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED4 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED4Test, FunctionOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED4(PredFunction4Bool,
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++),
+                 Bool(n4_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED4 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED4Test, FunctorOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED4(PredFunctor4(),
+                 n1_++,
+                 n2_++,
+                 n3_++,
+                 n4_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED4 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED4Test, FunctorOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED4(PredFunctor4(),
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++),
+                 Bool(n4_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful ASSERT_PRED4 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeSuccess) {
+  ASSERT_PRED4(PredFunction4Int,
+               ++n1_,
+               ++n2_,
+               ++n3_,
+               ++n4_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED4 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeSuccess) {
+  ASSERT_PRED4(PredFunction4Bool,
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_),
+               Bool(++n4_));
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED4 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeSuccess) {
+  ASSERT_PRED4(PredFunctor4(),
+               ++n1_,
+               ++n2_,
+               ++n3_,
+               ++n4_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED4 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeSuccess) {
+  ASSERT_PRED4(PredFunctor4(),
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_),
+               Bool(++n4_));
+  finished_ = true;
+}
+
+// Tests a failed ASSERT_PRED4 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED4Test, FunctionOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED4(PredFunction4Int,
+                 n1_++,
+                 n2_++,
+                 n3_++,
+                 n4_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED4 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED4Test, FunctionOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED4(PredFunction4Bool,
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++),
+                 Bool(n4_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED4 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED4Test, FunctorOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED4(PredFunctor4(),
+                 n1_++,
+                 n2_++,
+                 n3_++,
+                 n4_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED4 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED4Test, FunctorOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED4(PredFunctor4(),
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++),
+                 Bool(n4_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful EXPECT_PRED_FORMAT4 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) {
+  EXPECT_PRED_FORMAT4(PredFormatFunction4,
+                      ++n1_,
+                      ++n2_,
+                      ++n3_,
+                      ++n4_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT4 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) {
+  EXPECT_PRED_FORMAT4(PredFormatFunction4,
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_),
+                      Bool(++n4_));
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT4 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) {
+  EXPECT_PRED_FORMAT4(PredFormatFunctor4(),
+                      ++n1_,
+                      ++n2_,
+                      ++n3_,
+                      ++n4_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT4 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) {
+  EXPECT_PRED_FORMAT4(PredFormatFunctor4(),
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_),
+                      Bool(++n4_));
+  finished_ = true;
+}
+
+// Tests a failed EXPECT_PRED_FORMAT4 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT4(PredFormatFunction4,
+                        n1_++,
+                        n2_++,
+                        n3_++,
+                        n4_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT4 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT4(PredFormatFunction4,
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++),
+                        Bool(n4_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT4 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT4(PredFormatFunctor4(),
+                        n1_++,
+                        n2_++,
+                        n3_++,
+                        n4_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT4 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT4(PredFormatFunctor4(),
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++),
+                        Bool(n4_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful ASSERT_PRED_FORMAT4 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeSuccess) {
+  ASSERT_PRED_FORMAT4(PredFormatFunction4,
+                      ++n1_,
+                      ++n2_,
+                      ++n3_,
+                      ++n4_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT4 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) {
+  ASSERT_PRED_FORMAT4(PredFormatFunction4,
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_),
+                      Bool(++n4_));
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT4 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeSuccess) {
+  ASSERT_PRED_FORMAT4(PredFormatFunctor4(),
+                      ++n1_,
+                      ++n2_,
+                      ++n3_,
+                      ++n4_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT4 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeSuccess) {
+  ASSERT_PRED_FORMAT4(PredFormatFunctor4(),
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_),
+                      Bool(++n4_));
+  finished_ = true;
+}
+
+// Tests a failed ASSERT_PRED_FORMAT4 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT4(PredFormatFunction4,
+                        n1_++,
+                        n2_++,
+                        n3_++,
+                        n4_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT4 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT4(PredFormatFunction4,
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++),
+                        Bool(n4_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT4 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT4(PredFormatFunctor4(),
+                        n1_++,
+                        n2_++,
+                        n3_++,
+                        n4_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT4 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT4Test, FunctorOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT4(PredFormatFunctor4(),
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++),
+                        Bool(n4_++));
+    finished_ = true;
+  }, "");
+}
+// Sample functions/functors for testing 5-ary predicate assertions.
+
+// A 5-ary predicate function.
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+bool PredFunction5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) {
+  return v1 + v2 + v3 + v4 + v5 > 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 PredFunction5Int(int v1, int v2, int v3, int v4, int v5) {
+  return v1 + v2 + v3 + v4 + v5 > 0;
+}
+bool PredFunction5Bool(Bool v1, Bool v2, Bool v3, Bool v4, Bool v5) {
+  return v1 + v2 + v3 + v4 + v5 > 0;
+}
+
+// A 5-ary predicate functor.
+struct PredFunctor5 {
+  template <typename T1, typename T2, typename T3, typename T4, typename T5>
+  bool operator()(const T1& v1,
+                  const T2& v2,
+                  const T3& v3,
+                  const T4& v4,
+                  const T5& v5) {
+    return v1 + v2 + v3 + v4 + v5 > 0;
+  }
+};
+
+// A 5-ary predicate-formatter function.
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+testing::AssertionResult PredFormatFunction5(const char* e1,
+                                             const char* e2,
+                                             const char* e3,
+                                             const char* e4,
+                                             const char* e5,
+                                             const T1& v1,
+                                             const T2& v2,
+                                             const T3& v3,
+                                             const T4& v4,
+                                             const T5& v5) {
+  if (PredFunction5(v1, v2, v3, v4, v5))
+    return testing::AssertionSuccess();
+
+  testing::Message msg;
+  msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5
+      << " is expected to be positive, but evaluates to "
+      << v1 + v2 + v3 + v4 + v5 << ".";
+  return testing::AssertionFailure(msg);
+}
+
+// A 5-ary predicate-formatter functor.
+struct PredFormatFunctor5 {
+  template <typename T1, typename T2, typename T3, typename T4, typename T5>
+  testing::AssertionResult operator()(const char* e1,
+                                      const char* e2,
+                                      const char* e3,
+                                      const char* e4,
+                                      const char* e5,
+                                      const T1& v1,
+                                      const T2& v2,
+                                      const T3& v3,
+                                      const T4& v4,
+                                      const T5& v5) const {
+    return PredFormatFunction5(e1, e2, e3, e4, e5, v1, v2, v3, v4, v5);
+  }
+};
+
+// Tests for {EXPECT|ASSERT}_PRED_FORMAT5.
+
+class Predicate5Test : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    expected_to_finish_ = true;
+    finished_ = false;
+    n1_ = n2_ = n3_ = n4_ = n5_ = 0;
+  }
+
+  virtual void TearDown() {
+    // Verifies that each of the predicate's arguments was evaluated
+    // exactly once.
+    EXPECT_EQ(1, n1_) <<
+        "The predicate assertion didn't evaluate argument 2 "
+        "exactly once.";
+    EXPECT_EQ(1, n2_) <<
+        "The predicate assertion didn't evaluate argument 3 "
+        "exactly once.";
+    EXPECT_EQ(1, n3_) <<
+        "The predicate assertion didn't evaluate argument 4 "
+        "exactly once.";
+    EXPECT_EQ(1, n4_) <<
+        "The predicate assertion didn't evaluate argument 5 "
+        "exactly once.";
+    EXPECT_EQ(1, n5_) <<
+        "The predicate assertion didn't evaluate argument 6 "
+        "exactly once.";
+
+    // 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_;
+
+  static int n1_;
+  static int n2_;
+  static int n3_;
+  static int n4_;
+  static int n5_;
+};
+
+bool Predicate5Test::expected_to_finish_;
+bool Predicate5Test::finished_;
+int Predicate5Test::n1_;
+int Predicate5Test::n2_;
+int Predicate5Test::n3_;
+int Predicate5Test::n4_;
+int Predicate5Test::n5_;
+
+typedef Predicate5Test EXPECT_PRED_FORMAT5Test;
+typedef Predicate5Test ASSERT_PRED_FORMAT5Test;
+typedef Predicate5Test EXPECT_PRED5Test;
+typedef Predicate5Test ASSERT_PRED5Test;
+
+// Tests a successful EXPECT_PRED5 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeSuccess) {
+  EXPECT_PRED5(PredFunction5Int,
+               ++n1_,
+               ++n2_,
+               ++n3_,
+               ++n4_,
+               ++n5_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED5 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeSuccess) {
+  EXPECT_PRED5(PredFunction5Bool,
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_),
+               Bool(++n4_),
+               Bool(++n5_));
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED5 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeSuccess) {
+  EXPECT_PRED5(PredFunctor5(),
+               ++n1_,
+               ++n2_,
+               ++n3_,
+               ++n4_,
+               ++n5_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED5 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeSuccess) {
+  EXPECT_PRED5(PredFunctor5(),
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_),
+               Bool(++n4_),
+               Bool(++n5_));
+  finished_ = true;
+}
+
+// Tests a failed EXPECT_PRED5 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED5Test, FunctionOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED5(PredFunction5Int,
+                 n1_++,
+                 n2_++,
+                 n3_++,
+                 n4_++,
+                 n5_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED5 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED5Test, FunctionOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED5(PredFunction5Bool,
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++),
+                 Bool(n4_++),
+                 Bool(n5_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED5 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED5Test, FunctorOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED5(PredFunctor5(),
+                 n1_++,
+                 n2_++,
+                 n3_++,
+                 n4_++,
+                 n5_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED5 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED5Test, FunctorOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED5(PredFunctor5(),
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++),
+                 Bool(n4_++),
+                 Bool(n5_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful ASSERT_PRED5 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeSuccess) {
+  ASSERT_PRED5(PredFunction5Int,
+               ++n1_,
+               ++n2_,
+               ++n3_,
+               ++n4_,
+               ++n5_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED5 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeSuccess) {
+  ASSERT_PRED5(PredFunction5Bool,
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_),
+               Bool(++n4_),
+               Bool(++n5_));
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED5 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeSuccess) {
+  ASSERT_PRED5(PredFunctor5(),
+               ++n1_,
+               ++n2_,
+               ++n3_,
+               ++n4_,
+               ++n5_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED5 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeSuccess) {
+  ASSERT_PRED5(PredFunctor5(),
+               Bool(++n1_),
+               Bool(++n2_),
+               Bool(++n3_),
+               Bool(++n4_),
+               Bool(++n5_));
+  finished_ = true;
+}
+
+// Tests a failed ASSERT_PRED5 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED5Test, FunctionOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED5(PredFunction5Int,
+                 n1_++,
+                 n2_++,
+                 n3_++,
+                 n4_++,
+                 n5_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED5 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED5Test, FunctionOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED5(PredFunction5Bool,
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++),
+                 Bool(n4_++),
+                 Bool(n5_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED5 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED5Test, FunctorOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED5(PredFunctor5(),
+                 n1_++,
+                 n2_++,
+                 n3_++,
+                 n4_++,
+                 n5_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED5 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED5Test, FunctorOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED5(PredFunctor5(),
+                 Bool(n1_++),
+                 Bool(n2_++),
+                 Bool(n3_++),
+                 Bool(n4_++),
+                 Bool(n5_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful EXPECT_PRED_FORMAT5 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) {
+  EXPECT_PRED_FORMAT5(PredFormatFunction5,
+                      ++n1_,
+                      ++n2_,
+                      ++n3_,
+                      ++n4_,
+                      ++n5_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT5 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) {
+  EXPECT_PRED_FORMAT5(PredFormatFunction5,
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_),
+                      Bool(++n4_),
+                      Bool(++n5_));
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT5 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) {
+  EXPECT_PRED_FORMAT5(PredFormatFunctor5(),
+                      ++n1_,
+                      ++n2_,
+                      ++n3_,
+                      ++n4_,
+                      ++n5_);
+  finished_ = true;
+}
+
+// Tests a successful EXPECT_PRED_FORMAT5 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) {
+  EXPECT_PRED_FORMAT5(PredFormatFunctor5(),
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_),
+                      Bool(++n4_),
+                      Bool(++n5_));
+  finished_ = true;
+}
+
+// Tests a failed EXPECT_PRED_FORMAT5 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT5(PredFormatFunction5,
+                        n1_++,
+                        n2_++,
+                        n3_++,
+                        n4_++,
+                        n5_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT5 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT5(PredFormatFunction5,
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++),
+                        Bool(n4_++),
+                        Bool(n5_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT5 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT5(PredFormatFunctor5(),
+                        n1_++,
+                        n2_++,
+                        n3_++,
+                        n4_++,
+                        n5_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed EXPECT_PRED_FORMAT5 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(EXPECT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) {
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT5(PredFormatFunctor5(),
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++),
+                        Bool(n4_++),
+                        Bool(n5_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a successful ASSERT_PRED_FORMAT5 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeSuccess) {
+  ASSERT_PRED_FORMAT5(PredFormatFunction5,
+                      ++n1_,
+                      ++n2_,
+                      ++n3_,
+                      ++n4_,
+                      ++n5_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT5 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeSuccess) {
+  ASSERT_PRED_FORMAT5(PredFormatFunction5,
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_),
+                      Bool(++n4_),
+                      Bool(++n5_));
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT5 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeSuccess) {
+  ASSERT_PRED_FORMAT5(PredFormatFunctor5(),
+                      ++n1_,
+                      ++n2_,
+                      ++n3_,
+                      ++n4_,
+                      ++n5_);
+  finished_ = true;
+}
+
+// Tests a successful ASSERT_PRED_FORMAT5 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeSuccess) {
+  ASSERT_PRED_FORMAT5(PredFormatFunctor5(),
+                      Bool(++n1_),
+                      Bool(++n2_),
+                      Bool(++n3_),
+                      Bool(++n4_),
+                      Bool(++n5_));
+  finished_ = true;
+}
+
+// Tests a failed ASSERT_PRED_FORMAT5 where the
+// predicate-formatter is a function on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT5(PredFormatFunction5,
+                        n1_++,
+                        n2_++,
+                        n3_++,
+                        n4_++,
+                        n5_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT5 where the
+// predicate-formatter is a function on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT5Test, FunctionOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT5(PredFormatFunction5,
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++),
+                        Bool(n4_++),
+                        Bool(n5_++));
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT5 where the
+// predicate-formatter is a functor on a built-in type (int).
+TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnBuiltInTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT5(PredFormatFunctor5(),
+                        n1_++,
+                        n2_++,
+                        n3_++,
+                        n4_++,
+                        n5_++);
+    finished_ = true;
+  }, "");
+}
+
+// Tests a failed ASSERT_PRED_FORMAT5 where the
+// predicate-formatter is a functor on a user-defined type (Bool).
+TEST_F(ASSERT_PRED_FORMAT5Test, FunctorOnUserTypeFailure) {
+  expected_to_finish_ = false;
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT5(PredFormatFunctor5(),
+                        Bool(n1_++),
+                        Bool(n2_++),
+                        Bool(n3_++),
+                        Bool(n4_++),
+                        Bool(n5_++));
+    finished_ = true;
+  }, "");
+}
diff --git a/protobuf/gtest/test/gtest_prod_test.cc b/protobuf/gtest/test/gtest_prod_test.cc
new file mode 100644
index 0000000..bc3201d
--- /dev/null
+++ b/protobuf/gtest/test/gtest_prod_test.cc
@@ -0,0 +1,57 @@
+// 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)
+//
+// Unit test for include/gtest/gtest_prod.h.
+
+#include <gtest/gtest.h>
+#include "test/production.h"
+
+// Tests that private members can be accessed from a TEST declared as
+// a friend of the class.
+TEST(PrivateCodeTest, CanAccessPrivateMembers) {
+  PrivateCode a;
+  EXPECT_EQ(0, a.x_);
+
+  a.set_x(1);
+  EXPECT_EQ(1, a.x_);
+}
+
+typedef testing::Test PrivateCodeFixtureTest;
+
+// Tests that private members can be accessed from a TEST_F declared
+// as a friend of the class.
+TEST_F(PrivateCodeFixtureTest, CanAccessPrivateMembers) {
+  PrivateCode a;
+  EXPECT_EQ(0, a.x_);
+
+  a.set_x(2);
+  EXPECT_EQ(2, a.x_);
+}
diff --git a/protobuf/gtest/test/gtest_repeat_test.cc b/protobuf/gtest/test/gtest_repeat_test.cc
new file mode 100644
index 0000000..df6868b
--- /dev/null
+++ b/protobuf/gtest/test/gtest_repeat_test.cc
@@ -0,0 +1,253 @@
+// 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)
+
+// Tests the --gtest_repeat=number flag.
+
+#include <stdlib.h>
+#include <iostream>
+#include <gtest/gtest.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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+namespace testing {
+
+GTEST_DECLARE_string_(death_test_style);
+GTEST_DECLARE_string_(filter);
+GTEST_DECLARE_int32_(repeat);
+
+}  // namespace testing
+
+using testing::GTEST_FLAG(death_test_style);
+using testing::GTEST_FLAG(filter);
+using testing::GTEST_FLAG(repeat);
+
+namespace {
+
+// We need this when we are testing Google Test itself and therefore
+// cannot use Google Test assertions.
+#define GTEST_CHECK_INT_EQ_(expected, actual) \
+  do {\
+    const int expected_val = (expected);\
+    const int actual_val = (actual);\
+    if (::testing::internal::IsTrue(expected_val != actual_val)) {\
+      ::std::cout << "Value of: " #actual "\n"\
+                  << "  Actual: " << actual_val << "\n"\
+                  << "Expected: " #expected "\n"\
+                  << "Which is: " << expected_val << "\n";\
+      abort();\
+    }\
+  } while(::testing::internal::AlwaysFalse())
+
+
+// Used for verifying that global environment set-up and tear-down are
+// inside the gtest_repeat loop.
+
+int g_environment_set_up_count = 0;
+int g_environment_tear_down_count = 0;
+
+class MyEnvironment : public testing::Environment {
+ public:
+  MyEnvironment() {}
+  virtual void SetUp() { g_environment_set_up_count++; }
+  virtual void TearDown() { g_environment_tear_down_count++; }
+};
+
+// A test that should fail.
+
+int g_should_fail_count = 0;
+
+TEST(FooTest, ShouldFail) {
+  g_should_fail_count++;
+  EXPECT_EQ(0, 1) << "Expected failure.";
+}
+
+// A test that should pass.
+
+int g_should_pass_count = 0;
+
+TEST(FooTest, ShouldPass) {
+  g_should_pass_count++;
+}
+
+// A test that contains a thread-safe death test and a fast death
+// test.  It should pass.
+
+int g_death_test_count = 0;
+
+TEST(BarDeathTest, ThreadSafeAndFast) {
+  g_death_test_count++;
+
+  GTEST_FLAG(death_test_style) = "threadsafe";
+  EXPECT_DEATH_IF_SUPPORTED(abort(), "");
+
+  GTEST_FLAG(death_test_style) = "fast";
+  EXPECT_DEATH_IF_SUPPORTED(abort(), "");
+}
+
+#if GTEST_HAS_PARAM_TEST
+int g_param_test_count = 0;
+
+const int kNumberOfParamTests = 10;
+
+class MyParamTest : public testing::TestWithParam<int> {};
+
+TEST_P(MyParamTest, ShouldPass) {
+  // TODO(vladl@google.com): Make parameter value checking robust
+  //                         WRT order of tests.
+  GTEST_CHECK_INT_EQ_(g_param_test_count % kNumberOfParamTests, GetParam());
+  g_param_test_count++;
+}
+INSTANTIATE_TEST_CASE_P(MyParamSequence,
+                        MyParamTest,
+                        testing::Range(0, kNumberOfParamTests));
+#endif  // GTEST_HAS_PARAM_TEST
+
+// Resets the count for each test.
+void ResetCounts() {
+  g_environment_set_up_count = 0;
+  g_environment_tear_down_count = 0;
+  g_should_fail_count = 0;
+  g_should_pass_count = 0;
+  g_death_test_count = 0;
+#if GTEST_HAS_PARAM_TEST
+  g_param_test_count = 0;
+#endif  // GTEST_HAS_PARAM_TEST
+}
+
+// Checks that the count for each test is expected.
+void CheckCounts(int expected) {
+  GTEST_CHECK_INT_EQ_(expected, g_environment_set_up_count);
+  GTEST_CHECK_INT_EQ_(expected, g_environment_tear_down_count);
+  GTEST_CHECK_INT_EQ_(expected, g_should_fail_count);
+  GTEST_CHECK_INT_EQ_(expected, g_should_pass_count);
+  GTEST_CHECK_INT_EQ_(expected, g_death_test_count);
+#if GTEST_HAS_PARAM_TEST
+  GTEST_CHECK_INT_EQ_(expected * kNumberOfParamTests, g_param_test_count);
+#endif  // GTEST_HAS_PARAM_TEST
+}
+
+// Tests the behavior of Google Test when --gtest_repeat is not specified.
+void TestRepeatUnspecified() {
+  ResetCounts();
+  GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS());
+  CheckCounts(1);
+}
+
+// Tests the behavior of Google Test when --gtest_repeat has the given value.
+void TestRepeat(int repeat) {
+  GTEST_FLAG(repeat) = repeat;
+
+  ResetCounts();
+  GTEST_CHECK_INT_EQ_(repeat > 0 ? 1 : 0, RUN_ALL_TESTS());
+  CheckCounts(repeat);
+}
+
+// Tests using --gtest_repeat when --gtest_filter specifies an empty
+// set of tests.
+void TestRepeatWithEmptyFilter(int repeat) {
+  GTEST_FLAG(repeat) = repeat;
+  GTEST_FLAG(filter) = "None";
+
+  ResetCounts();
+  GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS());
+  CheckCounts(0);
+}
+
+// Tests using --gtest_repeat when --gtest_filter specifies a set of
+// successful tests.
+void TestRepeatWithFilterForSuccessfulTests(int repeat) {
+  GTEST_FLAG(repeat) = repeat;
+  GTEST_FLAG(filter) = "*-*ShouldFail";
+
+  ResetCounts();
+  GTEST_CHECK_INT_EQ_(0, RUN_ALL_TESTS());
+  GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count);
+  GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count);
+  GTEST_CHECK_INT_EQ_(0, g_should_fail_count);
+  GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count);
+  GTEST_CHECK_INT_EQ_(repeat, g_death_test_count);
+#if GTEST_HAS_PARAM_TEST
+  GTEST_CHECK_INT_EQ_(repeat * kNumberOfParamTests, g_param_test_count);
+#endif  // GTEST_HAS_PARAM_TEST
+}
+
+// Tests using --gtest_repeat when --gtest_filter specifies a set of
+// failed tests.
+void TestRepeatWithFilterForFailedTests(int repeat) {
+  GTEST_FLAG(repeat) = repeat;
+  GTEST_FLAG(filter) = "*ShouldFail";
+
+  ResetCounts();
+  GTEST_CHECK_INT_EQ_(1, RUN_ALL_TESTS());
+  GTEST_CHECK_INT_EQ_(repeat, g_environment_set_up_count);
+  GTEST_CHECK_INT_EQ_(repeat, g_environment_tear_down_count);
+  GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count);
+  GTEST_CHECK_INT_EQ_(0, g_should_pass_count);
+  GTEST_CHECK_INT_EQ_(0, g_death_test_count);
+#if GTEST_HAS_PARAM_TEST
+  GTEST_CHECK_INT_EQ_(0, g_param_test_count);
+#endif  // GTEST_HAS_PARAM_TEST
+}
+
+}  // namespace
+
+int main(int argc, char **argv) {
+  testing::InitGoogleTest(&argc, argv);
+  testing::AddGlobalTestEnvironment(new MyEnvironment);
+
+  TestRepeatUnspecified();
+  TestRepeat(0);
+  TestRepeat(1);
+  TestRepeat(5);
+
+  TestRepeatWithEmptyFilter(2);
+  TestRepeatWithEmptyFilter(3);
+
+  TestRepeatWithFilterForSuccessfulTests(3);
+
+  TestRepeatWithFilterForFailedTests(4);
+
+  // It would be nice to verify that the tests indeed loop forever
+  // when GTEST_FLAG(repeat) is negative, but this test will be quite
+  // complicated to write.  Since this flag is for interactive
+  // debugging only and doesn't affect the normal test result, such a
+  // test would be an overkill.
+
+  printf("PASS\n");
+  return 0;
+}
diff --git a/protobuf/gtest/test/gtest_shuffle_test.py b/protobuf/gtest/test/gtest_shuffle_test.py
new file mode 100755
index 0000000..30d0303
--- /dev/null
+++ b/protobuf/gtest/test/gtest_shuffle_test.py
@@ -0,0 +1,325 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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.
+
+"""Verifies that test shuffling works."""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import gtest_test_utils
+
+# Command to run the gtest_shuffle_test_ program.
+COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_shuffle_test_')
+
+# The environment variables for test sharding.
+TOTAL_SHARDS_ENV_VAR = 'GTEST_TOTAL_SHARDS'
+SHARD_INDEX_ENV_VAR = 'GTEST_SHARD_INDEX'
+
+TEST_FILTER = 'A*.A:A*.B:C*'
+
+ALL_TESTS = []
+ACTIVE_TESTS = []
+FILTERED_TESTS = []
+SHARDED_TESTS = []
+
+SHUFFLED_ALL_TESTS = []
+SHUFFLED_ACTIVE_TESTS = []
+SHUFFLED_FILTERED_TESTS = []
+SHUFFLED_SHARDED_TESTS = []
+
+
+def AlsoRunDisabledTestsFlag():
+  return '--gtest_also_run_disabled_tests'
+
+
+def FilterFlag(test_filter):
+  return '--gtest_filter=%s' % (test_filter,)
+
+
+def RepeatFlag(n):
+  return '--gtest_repeat=%s' % (n,)
+
+
+def ShuffleFlag():
+  return '--gtest_shuffle'
+
+
+def RandomSeedFlag(n):
+  return '--gtest_random_seed=%s' % (n,)
+
+
+def RunAndReturnOutput(extra_env, args):
+  """Runs the test program and returns its output."""
+
+  environ_copy = os.environ.copy()
+  environ_copy.update(extra_env)
+
+  return gtest_test_utils.Subprocess([COMMAND] + args, env=environ_copy).output
+
+
+def GetTestsForAllIterations(extra_env, args):
+  """Runs the test program and returns a list of test lists.
+
+  Args:
+    extra_env: a map from environment variables to their values
+    args: command line flags to pass to gtest_shuffle_test_
+
+  Returns:
+    A list where the i-th element is the list of tests run in the i-th
+    test iteration.
+  """
+
+  test_iterations = []
+  for line in RunAndReturnOutput(extra_env, args).split('\n'):
+    if line.startswith('----'):
+      tests = []
+      test_iterations.append(tests)
+    elif line.strip():
+      tests.append(line.strip())  # 'TestCaseName.TestName'
+
+  return test_iterations
+
+
+def GetTestCases(tests):
+  """Returns a list of test cases in the given full test names.
+
+  Args:
+    tests: a list of full test names
+
+  Returns:
+    A list of test cases from 'tests', in their original order.
+    Consecutive duplicates are removed.
+  """
+
+  test_cases = []
+  for test in tests:
+    test_case = test.split('.')[0]
+    if not test_case in test_cases:
+      test_cases.append(test_case)
+
+  return test_cases
+
+
+def CalculateTestLists():
+  """Calculates the list of tests run under different flags."""
+
+  if not ALL_TESTS:
+    ALL_TESTS.extend(
+        GetTestsForAllIterations({}, [AlsoRunDisabledTestsFlag()])[0])
+
+  if not ACTIVE_TESTS:
+    ACTIVE_TESTS.extend(GetTestsForAllIterations({}, [])[0])
+
+  if not FILTERED_TESTS:
+    FILTERED_TESTS.extend(
+        GetTestsForAllIterations({}, [FilterFlag(TEST_FILTER)])[0])
+
+  if not SHARDED_TESTS:
+    SHARDED_TESTS.extend(
+        GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
+                                  SHARD_INDEX_ENV_VAR: '1'},
+                                 [])[0])
+
+  if not SHUFFLED_ALL_TESTS:
+    SHUFFLED_ALL_TESTS.extend(GetTestsForAllIterations(
+        {}, [AlsoRunDisabledTestsFlag(), ShuffleFlag(), RandomSeedFlag(1)])[0])
+
+  if not SHUFFLED_ACTIVE_TESTS:
+    SHUFFLED_ACTIVE_TESTS.extend(GetTestsForAllIterations(
+        {}, [ShuffleFlag(), RandomSeedFlag(1)])[0])
+
+  if not SHUFFLED_FILTERED_TESTS:
+    SHUFFLED_FILTERED_TESTS.extend(GetTestsForAllIterations(
+        {}, [ShuffleFlag(), RandomSeedFlag(1), FilterFlag(TEST_FILTER)])[0])
+
+  if not SHUFFLED_SHARDED_TESTS:
+    SHUFFLED_SHARDED_TESTS.extend(
+        GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
+                                  SHARD_INDEX_ENV_VAR: '1'},
+                                 [ShuffleFlag(), RandomSeedFlag(1)])[0])
+
+
+class GTestShuffleUnitTest(gtest_test_utils.TestCase):
+  """Tests test shuffling."""
+
+  def setUp(self):
+    CalculateTestLists()
+
+  def testShufflePreservesNumberOfTests(self):
+    self.assertEqual(len(ALL_TESTS), len(SHUFFLED_ALL_TESTS))
+    self.assertEqual(len(ACTIVE_TESTS), len(SHUFFLED_ACTIVE_TESTS))
+    self.assertEqual(len(FILTERED_TESTS), len(SHUFFLED_FILTERED_TESTS))
+    self.assertEqual(len(SHARDED_TESTS), len(SHUFFLED_SHARDED_TESTS))
+
+  def testShuffleChangesTestOrder(self):
+    self.assert_(SHUFFLED_ALL_TESTS != ALL_TESTS, SHUFFLED_ALL_TESTS)
+    self.assert_(SHUFFLED_ACTIVE_TESTS != ACTIVE_TESTS, SHUFFLED_ACTIVE_TESTS)
+    self.assert_(SHUFFLED_FILTERED_TESTS != FILTERED_TESTS,
+                 SHUFFLED_FILTERED_TESTS)
+    self.assert_(SHUFFLED_SHARDED_TESTS != SHARDED_TESTS,
+                 SHUFFLED_SHARDED_TESTS)
+
+  def testShuffleChangesTestCaseOrder(self):
+    self.assert_(GetTestCases(SHUFFLED_ALL_TESTS) != GetTestCases(ALL_TESTS),
+                 GetTestCases(SHUFFLED_ALL_TESTS))
+    self.assert_(
+        GetTestCases(SHUFFLED_ACTIVE_TESTS) != GetTestCases(ACTIVE_TESTS),
+        GetTestCases(SHUFFLED_ACTIVE_TESTS))
+    self.assert_(
+        GetTestCases(SHUFFLED_FILTERED_TESTS) != GetTestCases(FILTERED_TESTS),
+        GetTestCases(SHUFFLED_FILTERED_TESTS))
+    self.assert_(
+        GetTestCases(SHUFFLED_SHARDED_TESTS) != GetTestCases(SHARDED_TESTS),
+        GetTestCases(SHUFFLED_SHARDED_TESTS))
+
+  def testShuffleDoesNotRepeatTest(self):
+    for test in SHUFFLED_ALL_TESTS:
+      self.assertEqual(1, SHUFFLED_ALL_TESTS.count(test),
+                       '%s appears more than once' % (test,))
+    for test in SHUFFLED_ACTIVE_TESTS:
+      self.assertEqual(1, SHUFFLED_ACTIVE_TESTS.count(test),
+                       '%s appears more than once' % (test,))
+    for test in SHUFFLED_FILTERED_TESTS:
+      self.assertEqual(1, SHUFFLED_FILTERED_TESTS.count(test),
+                       '%s appears more than once' % (test,))
+    for test in SHUFFLED_SHARDED_TESTS:
+      self.assertEqual(1, SHUFFLED_SHARDED_TESTS.count(test),
+                       '%s appears more than once' % (test,))
+
+  def testShuffleDoesNotCreateNewTest(self):
+    for test in SHUFFLED_ALL_TESTS:
+      self.assert_(test in ALL_TESTS, '%s is an invalid test' % (test,))
+    for test in SHUFFLED_ACTIVE_TESTS:
+      self.assert_(test in ACTIVE_TESTS, '%s is an invalid test' % (test,))
+    for test in SHUFFLED_FILTERED_TESTS:
+      self.assert_(test in FILTERED_TESTS, '%s is an invalid test' % (test,))
+    for test in SHUFFLED_SHARDED_TESTS:
+      self.assert_(test in SHARDED_TESTS, '%s is an invalid test' % (test,))
+
+  def testShuffleIncludesAllTests(self):
+    for test in ALL_TESTS:
+      self.assert_(test in SHUFFLED_ALL_TESTS, '%s is missing' % (test,))
+    for test in ACTIVE_TESTS:
+      self.assert_(test in SHUFFLED_ACTIVE_TESTS, '%s is missing' % (test,))
+    for test in FILTERED_TESTS:
+      self.assert_(test in SHUFFLED_FILTERED_TESTS, '%s is missing' % (test,))
+    for test in SHARDED_TESTS:
+      self.assert_(test in SHUFFLED_SHARDED_TESTS, '%s is missing' % (test,))
+
+  def testShuffleLeavesDeathTestsAtFront(self):
+    non_death_test_found = False
+    for test in SHUFFLED_ACTIVE_TESTS:
+      if 'DeathTest.' in test:
+        self.assert_(not non_death_test_found,
+                     '%s appears after a non-death test' % (test,))
+      else:
+        non_death_test_found = True
+
+  def _VerifyTestCasesDoNotInterleave(self, tests):
+    test_cases = []
+    for test in tests:
+      [test_case, _] = test.split('.')
+      if test_cases and test_cases[-1] != test_case:
+        test_cases.append(test_case)
+        self.assertEqual(1, test_cases.count(test_case),
+                         'Test case %s is not grouped together in %s' %
+                         (test_case, tests))
+
+  def testShuffleDoesNotInterleaveTestCases(self):
+    self._VerifyTestCasesDoNotInterleave(SHUFFLED_ALL_TESTS)
+    self._VerifyTestCasesDoNotInterleave(SHUFFLED_ACTIVE_TESTS)
+    self._VerifyTestCasesDoNotInterleave(SHUFFLED_FILTERED_TESTS)
+    self._VerifyTestCasesDoNotInterleave(SHUFFLED_SHARDED_TESTS)
+
+  def testShuffleRestoresOrderAfterEachIteration(self):
+    # Get the test lists in all 3 iterations, using random seed 1, 2,
+    # and 3 respectively.  Google Test picks a different seed in each
+    # iteration, and this test depends on the current implementation
+    # picking successive numbers.  This dependency is not ideal, but
+    # makes the test much easier to write.
+    [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = (
+        GetTestsForAllIterations(
+            {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)]))
+
+    # Make sure running the tests with random seed 1 gets the same
+    # order as in iteration 1 above.
+    [tests_with_seed1] = GetTestsForAllIterations(
+        {}, [ShuffleFlag(), RandomSeedFlag(1)])
+    self.assertEqual(tests_in_iteration1, tests_with_seed1)
+
+    # Make sure running the tests with random seed 2 gets the same
+    # order as in iteration 2 above.  Success means that Google Test
+    # correctly restores the test order before re-shuffling at the
+    # beginning of iteration 2.
+    [tests_with_seed2] = GetTestsForAllIterations(
+        {}, [ShuffleFlag(), RandomSeedFlag(2)])
+    self.assertEqual(tests_in_iteration2, tests_with_seed2)
+
+    # Make sure running the tests with random seed 3 gets the same
+    # order as in iteration 3 above.  Success means that Google Test
+    # correctly restores the test order before re-shuffling at the
+    # beginning of iteration 3.
+    [tests_with_seed3] = GetTestsForAllIterations(
+        {}, [ShuffleFlag(), RandomSeedFlag(3)])
+    self.assertEqual(tests_in_iteration3, tests_with_seed3)
+
+  def testShuffleGeneratesNewOrderInEachIteration(self):
+    [tests_in_iteration1, tests_in_iteration2, tests_in_iteration3] = (
+        GetTestsForAllIterations(
+            {}, [ShuffleFlag(), RandomSeedFlag(1), RepeatFlag(3)]))
+
+    self.assert_(tests_in_iteration1 != tests_in_iteration2,
+                 tests_in_iteration1)
+    self.assert_(tests_in_iteration1 != tests_in_iteration3,
+                 tests_in_iteration1)
+    self.assert_(tests_in_iteration2 != tests_in_iteration3,
+                 tests_in_iteration2)
+
+  def testShuffleShardedTestsPreservesPartition(self):
+    # If we run M tests on N shards, the same M tests should be run in
+    # total, regardless of the random seeds used by the shards.
+    [tests1] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
+                                         SHARD_INDEX_ENV_VAR: '0'},
+                                        [ShuffleFlag(), RandomSeedFlag(1)])
+    [tests2] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
+                                         SHARD_INDEX_ENV_VAR: '1'},
+                                        [ShuffleFlag(), RandomSeedFlag(20)])
+    [tests3] = GetTestsForAllIterations({TOTAL_SHARDS_ENV_VAR: '3',
+                                         SHARD_INDEX_ENV_VAR: '2'},
+                                        [ShuffleFlag(), RandomSeedFlag(25)])
+    sorted_sharded_tests = tests1 + tests2 + tests3
+    sorted_sharded_tests.sort()
+    sorted_active_tests = []
+    sorted_active_tests.extend(ACTIVE_TESTS)
+    sorted_active_tests.sort()
+    self.assertEqual(sorted_active_tests, sorted_sharded_tests)
+
+if __name__ == '__main__':
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_shuffle_test_.cc b/protobuf/gtest/test/gtest_shuffle_test_.cc
new file mode 100644
index 0000000..53ecf77
--- /dev/null
+++ b/protobuf/gtest/test/gtest_shuffle_test_.cc
@@ -0,0 +1,104 @@
+// Copyright 2009, 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)
+
+// Verifies that test shuffling works.
+
+#include <gtest/gtest.h>
+
+namespace {
+
+using ::testing::EmptyTestEventListener;
+using ::testing::InitGoogleTest;
+using ::testing::Message;
+using ::testing::Test;
+using ::testing::TestEventListeners;
+using ::testing::TestInfo;
+using ::testing::UnitTest;
+using ::testing::internal::String;
+using ::testing::internal::scoped_ptr;
+
+// The test methods are empty, as the sole purpose of this program is
+// to print the test names before/after shuffling.
+
+class A : public Test {};
+TEST_F(A, A) {}
+TEST_F(A, B) {}
+
+TEST(ADeathTest, A) {}
+TEST(ADeathTest, B) {}
+TEST(ADeathTest, C) {}
+
+TEST(B, A) {}
+TEST(B, B) {}
+TEST(B, C) {}
+TEST(B, DISABLED_D) {}
+TEST(B, DISABLED_E) {}
+
+TEST(BDeathTest, A) {}
+TEST(BDeathTest, B) {}
+
+TEST(C, A) {}
+TEST(C, B) {}
+TEST(C, C) {}
+TEST(C, DISABLED_D) {}
+
+TEST(CDeathTest, A) {}
+
+TEST(DISABLED_D, A) {}
+TEST(DISABLED_D, DISABLED_B) {}
+
+// This printer prints the full test names only, starting each test
+// iteration with a "----" marker.
+class TestNamePrinter : public EmptyTestEventListener {
+ public:
+  virtual void OnTestIterationStart(const UnitTest& /* unit_test */,
+                                    int /* iteration */) {
+    printf("----\n");
+  }
+
+  virtual void OnTestStart(const TestInfo& test_info) {
+    printf("%s.%s\n", test_info.test_case_name(), test_info.name());
+  }
+};
+
+}  // namespace
+
+int main(int argc, char **argv) {
+  InitGoogleTest(&argc, argv);
+
+  // Replaces the default printer with TestNamePrinter, which prints
+  // the test name only.
+  TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
+  delete listeners.Release(listeners.default_result_printer());
+  listeners.Append(new TestNamePrinter);
+
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/test/gtest_sole_header_test.cc b/protobuf/gtest/test/gtest_sole_header_test.cc
new file mode 100644
index 0000000..de91e80
--- /dev/null
+++ b/protobuf/gtest/test/gtest_sole_header_test.cc
@@ -0,0 +1,57 @@
+// 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: mheule@google.com (Markus Heule)
+//
+// This test verifies that it's possible to use Google Test by including
+// the gtest.h header file alone.
+
+#include <gtest/gtest.h>
+
+namespace {
+
+void Subroutine() {
+  EXPECT_EQ(42, 42);
+}
+
+TEST(NoFatalFailureTest, ExpectNoFatalFailure) {
+  EXPECT_NO_FATAL_FAILURE(;);
+  EXPECT_NO_FATAL_FAILURE(SUCCEED());
+  EXPECT_NO_FATAL_FAILURE(Subroutine());
+  EXPECT_NO_FATAL_FAILURE({ SUCCEED(); });
+}
+
+TEST(NoFatalFailureTest, AssertNoFatalFailure) {
+  ASSERT_NO_FATAL_FAILURE(;);
+  ASSERT_NO_FATAL_FAILURE(SUCCEED());
+  ASSERT_NO_FATAL_FAILURE(Subroutine());
+  ASSERT_NO_FATAL_FAILURE({ SUCCEED(); });
+}
+
+}  // namespace
diff --git a/protobuf/gtest/test/gtest_stress_test.cc b/protobuf/gtest/test/gtest_stress_test.cc
new file mode 100644
index 0000000..f5af78c
--- /dev/null
+++ b/protobuf/gtest/test/gtest_stress_test.cc
@@ -0,0 +1,257 @@
+// 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)
+
+// Tests that SCOPED_TRACE() and various Google Test assertions can be
+// used in a large number of threads concurrently.
+
+#include <gtest/gtest.h>
+
+#include <iostream>
+#include <vector>
+
+// We must define this macro in order to #include
+// gtest-internal-inl.h.  This is how Google Test prevents a user from
+// accidentally depending on its internal implementation.
+#define GTEST_IMPLEMENTATION_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+#if GTEST_IS_THREADSAFE
+
+namespace testing {
+namespace {
+
+using internal::Notification;
+using internal::String;
+using internal::TestPropertyKeyIs;
+using internal::ThreadWithParam;
+using internal::scoped_ptr;
+
+// In order to run tests in this file, for platforms where Google Test is
+// thread safe, implement ThreadWithParam. See the description of its API
+// in gtest-port.h, where it is defined for already supported platforms.
+
+// How many threads to create?
+const int kThreadCount = 50;
+
+String IdToKey(int id, const char* suffix) {
+  Message key;
+  key << "key_" << id << "_" << suffix;
+  return key.GetString();
+}
+
+String IdToString(int id) {
+  Message id_message;
+  id_message << id;
+  return id_message.GetString();
+}
+
+void ExpectKeyAndValueWereRecordedForId(
+    const std::vector<TestProperty>& properties,
+    int id, const char* suffix) {
+  TestPropertyKeyIs matches_key(IdToKey(id, suffix).c_str());
+  const std::vector<TestProperty>::const_iterator property =
+      std::find_if(properties.begin(), properties.end(), matches_key);
+  ASSERT_TRUE(property != properties.end())
+      << "expecting " << suffix << " value for id " << id;
+  EXPECT_STREQ(IdToString(id).c_str(), property->value());
+}
+
+// Calls a large number of Google Test assertions, where exactly one of them
+// will fail.
+void ManyAsserts(int id) {
+  GTEST_LOG_(INFO) << "Thread #" << id << " running...";
+
+  SCOPED_TRACE(Message() << "Thread #" << id);
+
+  for (int i = 0; i < kThreadCount; i++) {
+    SCOPED_TRACE(Message() << "Iteration #" << i);
+
+    // A bunch of assertions that should succeed.
+    EXPECT_TRUE(true);
+    ASSERT_FALSE(false) << "This shouldn't fail.";
+    EXPECT_STREQ("a", "a");
+    ASSERT_LE(5, 6);
+    EXPECT_EQ(i, i) << "This shouldn't fail.";
+
+    // RecordProperty() should interact safely with other threads as well.
+    // The shared_key forces property updates.
+    Test::RecordProperty(IdToKey(id, "string").c_str(), IdToString(id).c_str());
+    Test::RecordProperty(IdToKey(id, "int").c_str(), id);
+    Test::RecordProperty("shared_key", IdToString(id).c_str());
+
+    // This assertion should fail kThreadCount times per thread.  It
+    // is for testing whether Google Test can handle failed assertions in a
+    // multi-threaded context.
+    EXPECT_LT(i, 0) << "This should always fail.";
+  }
+}
+
+void CheckTestFailureCount(int expected_failures) {
+  const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
+  const TestResult* const result = info->result();
+  GTEST_CHECK_(expected_failures == result->total_part_count())
+      << "Logged " << result->total_part_count() << " failures "
+      << " vs. " << expected_failures << " expected";
+}
+
+// Tests using SCOPED_TRACE() and Google Test assertions in many threads
+// concurrently.
+TEST(StressTest, CanUseScopedTraceAndAssertionsInManyThreads) {
+  {
+    scoped_ptr<ThreadWithParam<int> > threads[kThreadCount];
+    Notification threads_can_start;
+    for (int i = 0; i != kThreadCount; i++)
+      threads[i].reset(new ThreadWithParam<int>(&ManyAsserts,
+                                                i,
+                                                &threads_can_start));
+
+    threads_can_start.Notify();
+
+    // Blocks until all the threads are done.
+    for (int i = 0; i != kThreadCount; i++)
+      threads[i]->Join();
+  }
+
+  // Ensures that kThreadCount*kThreadCount failures have been reported.
+  const TestInfo* const info = UnitTest::GetInstance()->current_test_info();
+  const TestResult* const result = info->result();
+
+  std::vector<TestProperty> properties;
+  // We have no access to the TestResult's list of properties but we can
+  // copy them one by one.
+  for (int i = 0; i < result->test_property_count(); ++i)
+    properties.push_back(result->GetTestProperty(i));
+
+  EXPECT_EQ(kThreadCount * 2 + 1, result->test_property_count())
+      << "String and int values recorded on each thread, "
+      << "as well as one shared_key";
+  for (int i = 0; i < kThreadCount; ++i) {
+    ExpectKeyAndValueWereRecordedForId(properties, i, "string");
+    ExpectKeyAndValueWereRecordedForId(properties, i, "int");
+  }
+  CheckTestFailureCount(kThreadCount*kThreadCount);
+}
+
+void FailingThread(bool is_fatal) {
+  if (is_fatal)
+    FAIL() << "Fatal failure in some other thread. "
+           << "(This failure is expected.)";
+  else
+    ADD_FAILURE() << "Non-fatal failure in some other thread. "
+                  << "(This failure is expected.)";
+}
+
+void GenerateFatalFailureInAnotherThread(bool is_fatal) {
+  ThreadWithParam<bool> thread(&FailingThread, is_fatal, NULL);
+  thread.Join();
+}
+
+TEST(NoFatalFailureTest, ExpectNoFatalFailureIgnoresFailuresInOtherThreads) {
+  EXPECT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
+  // We should only have one failure (the one from
+  // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
+  // should succeed.
+  CheckTestFailureCount(1);
+}
+
+void AssertNoFatalFailureIgnoresFailuresInOtherThreads() {
+  ASSERT_NO_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true));
+}
+TEST(NoFatalFailureTest, AssertNoFatalFailureIgnoresFailuresInOtherThreads) {
+  // Using a subroutine, to make sure, that the test continues.
+  AssertNoFatalFailureIgnoresFailuresInOtherThreads();
+  // We should only have one failure (the one from
+  // GenerateFatalFailureInAnotherThread()), since the EXPECT_NO_FATAL_FAILURE
+  // should succeed.
+  CheckTestFailureCount(1);
+}
+
+TEST(FatalFailureTest, ExpectFatalFailureIgnoresFailuresInOtherThreads) {
+  // This statement should fail, since the current thread doesn't generate a
+  // fatal failure, only another one does.
+  EXPECT_FATAL_FAILURE(GenerateFatalFailureInAnotherThread(true), "expected");
+  CheckTestFailureCount(2);
+}
+
+TEST(FatalFailureOnAllThreadsTest, ExpectFatalFailureOnAllThreads) {
+  // This statement should succeed, because failures in all threads are
+  // considered.
+  EXPECT_FATAL_FAILURE_ON_ALL_THREADS(
+      GenerateFatalFailureInAnotherThread(true), "expected");
+  CheckTestFailureCount(0);
+  // We need to add a failure, because main() checks that there are failures.
+  // But when only this test is run, we shouldn't have any failures.
+  ADD_FAILURE() << "This is an expected non-fatal failure.";
+}
+
+TEST(NonFatalFailureTest, ExpectNonFatalFailureIgnoresFailuresInOtherThreads) {
+  // This statement should fail, since the current thread doesn't generate a
+  // fatal failure, only another one does.
+  EXPECT_NONFATAL_FAILURE(GenerateFatalFailureInAnotherThread(false),
+                          "expected");
+  CheckTestFailureCount(2);
+}
+
+TEST(NonFatalFailureOnAllThreadsTest, ExpectNonFatalFailureOnAllThreads) {
+  // This statement should succeed, because failures in all threads are
+  // considered.
+  EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(
+      GenerateFatalFailureInAnotherThread(false), "expected");
+  CheckTestFailureCount(0);
+  // We need to add a failure, because main() checks that there are failures,
+  // But when only this test is run, we shouldn't have any failures.
+  ADD_FAILURE() << "This is an expected non-fatal failure.";
+}
+
+}  // namespace
+}  // namespace testing
+
+int main(int argc, char **argv) {
+  testing::InitGoogleTest(&argc, argv);
+
+  const int result = RUN_ALL_TESTS();  // Expected to fail.
+  GTEST_CHECK_(result == 1) << "RUN_ALL_TESTS() did not fail as expected";
+
+  printf("\nPASS\n");
+  return 0;
+}
+
+#else
+TEST(StressTest,
+     DISABLED_ThreadSafetyTestsAreSkippedWhenGoogleTestIsNotThreadSafe) {
+}
+
+int main(int argc, char **argv) {
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
+#endif  // GTEST_IS_THREADSAFE
diff --git a/protobuf/gtest/test/gtest_test_utils.py b/protobuf/gtest/test/gtest_test_utils.py
new file mode 100755
index 0000000..e0f5973
--- /dev/null
+++ b/protobuf/gtest/test/gtest_test_utils.py
@@ -0,0 +1,309 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Unit test utilities for Google C++ Testing Framework."""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import atexit
+import os
+import shutil
+import sys
+import tempfile
+import unittest
+_test_module = unittest
+
+# Suppresses the 'Import not at the top of the file' lint complaint.
+# pylint: disable-msg=C6204
+try:
+  import subprocess
+  _SUBPROCESS_MODULE_AVAILABLE = True
+except:
+  import popen2
+  _SUBPROCESS_MODULE_AVAILABLE = False
+# pylint: enable-msg=C6204
+
+GTEST_OUTPUT_VAR_NAME = 'GTEST_OUTPUT'
+
+IS_WINDOWS = os.name == 'nt'
+IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0]
+
+# Here we expose a class from a particular module, depending on the
+# environment. The comment suppresses the 'Invalid variable name' lint
+# complaint.
+TestCase = _test_module.TestCase  # pylint: disable-msg=C6409
+
+# Initially maps a flag to its default value. After
+# _ParseAndStripGTestFlags() is called, maps a flag to its actual value.
+_flag_map = {'gtest_source_dir': os.path.dirname(sys.argv[0]),
+             'gtest_build_dir': os.path.dirname(sys.argv[0])}
+_gtest_flags_are_parsed = False
+
+
+def _ParseAndStripGTestFlags(argv):
+  """Parses and strips Google Test flags from argv.  This is idempotent."""
+
+  # Suppresses the lint complaint about a global variable since we need it
+  # here to maintain module-wide state.
+  global _gtest_flags_are_parsed  # pylint: disable-msg=W0603
+  if _gtest_flags_are_parsed:
+    return
+
+  _gtest_flags_are_parsed = True
+  for flag in _flag_map:
+    # The environment variable overrides the default value.
+    if flag.upper() in os.environ:
+      _flag_map[flag] = os.environ[flag.upper()]
+
+    # The command line flag overrides the environment variable.
+    i = 1  # Skips the program name.
+    while i < len(argv):
+      prefix = '--' + flag + '='
+      if argv[i].startswith(prefix):
+        _flag_map[flag] = argv[i][len(prefix):]
+        del argv[i]
+        break
+      else:
+        # We don't increment i in case we just found a --gtest_* flag
+        # and removed it from argv.
+        i += 1
+
+
+def GetFlag(flag):
+  """Returns the value of the given flag."""
+
+  # In case GetFlag() is called before Main(), we always call
+  # _ParseAndStripGTestFlags() here to make sure the --gtest_* flags
+  # are parsed.
+  _ParseAndStripGTestFlags(sys.argv)
+
+  return _flag_map[flag]
+
+
+def GetSourceDir():
+  """Returns the absolute path of the directory where the .py files are."""
+
+  return os.path.abspath(GetFlag('gtest_source_dir'))
+
+
+def GetBuildDir():
+  """Returns the absolute path of the directory where the test binaries are."""
+
+  return os.path.abspath(GetFlag('gtest_build_dir'))
+
+
+_temp_dir = None
+
+def _RemoveTempDir():
+  if _temp_dir:
+    shutil.rmtree(_temp_dir, ignore_errors=True)
+
+atexit.register(_RemoveTempDir)
+
+
+def GetTempDir():
+  """Returns a directory for temporary files."""
+
+  global _temp_dir
+  if not _temp_dir:
+    _temp_dir = tempfile.mkdtemp()
+  return _temp_dir
+
+
+def GetTestExecutablePath(executable_name, build_dir=None):
+  """Returns the absolute path of the test binary given its name.
+
+  The function will print a message and abort the program if the resulting file
+  doesn't exist.
+
+  Args:
+    executable_name: name of the test binary that the test script runs.
+    build_dir:       directory where to look for executables, by default
+                     the result of GetBuildDir().
+
+  Returns:
+    The absolute path of the test binary.
+  """
+
+  path = os.path.abspath(os.path.join(build_dir or GetBuildDir(),
+                                      executable_name))
+  if (IS_WINDOWS or IS_CYGWIN) and not path.endswith('.exe'):
+    path += '.exe'
+
+  if not os.path.exists(path):
+    message = (
+        'Unable to find the test binary. Please make sure to provide path\n'
+        'to the binary via the --gtest_build_dir flag or the GTEST_BUILD_DIR\n'
+        'environment variable. For convenient use, invoke this script via\n'
+        'mk_test.py.\n'
+        # TODO(vladl@google.com): change mk_test.py to test.py after renaming
+        # the file.
+        'Please run mk_test.py -h for help.')
+    print >> sys.stderr, message
+    sys.exit(1)
+
+  return path
+
+
+def GetExitStatus(exit_code):
+  """Returns the argument to exit(), or -1 if exit() wasn't called.
+
+  Args:
+    exit_code: the result value of os.system(command).
+  """
+
+  if os.name == 'nt':
+    # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns
+    # the argument to exit() directly.
+    return exit_code
+  else:
+    # On Unix, os.WEXITSTATUS() must be used to extract the exit status
+    # from the result of os.system().
+    if os.WIFEXITED(exit_code):
+      return os.WEXITSTATUS(exit_code)
+    else:
+      return -1
+
+
+class Subprocess:
+  def __init__(self, command, working_dir=None, capture_stderr=True, env=None):
+    """Changes into a specified directory, if provided, and executes a command.
+
+    Restores the old directory afterwards.
+
+    Args:
+      command:        The command to run, in the form of sys.argv.
+      working_dir:    The directory to change into.
+      capture_stderr: Determines whether to capture stderr in the output member
+                      or to discard it.
+      env:            Dictionary with environment to pass to the subprocess.
+
+    Returns:
+      An object that represents outcome of the executed process. It has the
+      following attributes:
+        terminated_by_signal   True iff the child process has been terminated
+                               by a signal.
+        signal                 Sygnal that terminated the child process.
+        exited                 True iff the child process exited normally.
+        exit_code              The code with which the child process exited.
+        output                 Child process's stdout and stderr output
+                               combined in a string.
+    """
+
+    # The subprocess module is the preferrable way of running programs
+    # since it is available and behaves consistently on all platforms,
+    # including Windows. But it is only available starting in python 2.4.
+    # In earlier python versions, we revert to the popen2 module, which is
+    # available in python 2.0 and later but doesn't provide required
+    # functionality (Popen4) under Windows. This allows us to support Mac
+    # OS X 10.4 Tiger, which has python 2.3 installed.
+    if _SUBPROCESS_MODULE_AVAILABLE:
+      if capture_stderr:
+        stderr = subprocess.STDOUT
+      else:
+        stderr = subprocess.PIPE
+
+      p = subprocess.Popen(command,
+                           stdout=subprocess.PIPE, stderr=stderr,
+                           cwd=working_dir, universal_newlines=True, env=env)
+      # communicate returns a tuple with the file obect for the child's
+      # output.
+      self.output = p.communicate()[0]
+      self._return_code = p.returncode
+    else:
+      old_dir = os.getcwd()
+
+      def _ReplaceEnvDict(dest, src):
+        # Changes made by os.environ.clear are not inheritable by child
+        # processes until Python 2.6. To produce inheritable changes we have
+        # to delete environment items with the del statement.
+        for key in dest:
+          del dest[key]
+        dest.update(src)
+
+      # When 'env' is not None, backup the environment variables and replace
+      # them with the passed 'env'. When 'env' is None, we simply use the
+      # current 'os.environ' for compatibility with the subprocess.Popen
+      # semantics used above.
+      if env is not None:
+        old_environ = os.environ.copy()
+        _ReplaceEnvDict(os.environ, env)
+
+      try:
+        if working_dir is not None:
+          os.chdir(working_dir)
+        if capture_stderr:
+          p = popen2.Popen4(command)
+        else:
+          p = popen2.Popen3(command)
+        p.tochild.close()
+        self.output = p.fromchild.read()
+        ret_code = p.wait()
+      finally:
+        os.chdir(old_dir)
+
+        # Restore the old environment variables
+        # if they were replaced.
+        if env is not None:
+          _ReplaceEnvDict(os.environ, old_environ)
+
+      # Converts ret_code to match the semantics of
+      # subprocess.Popen.returncode.
+      if os.WIFSIGNALED(ret_code):
+        self._return_code = -os.WTERMSIG(ret_code)
+      else:  # os.WIFEXITED(ret_code) should return True here.
+        self._return_code = os.WEXITSTATUS(ret_code)
+
+    if self._return_code < 0:
+      self.terminated_by_signal = True
+      self.exited = False
+      self.signal = -self._return_code
+    else:
+      self.terminated_by_signal = False
+      self.exited = True
+      self.exit_code = self._return_code
+
+
+def Main():
+  """Runs the unit test."""
+
+  # We must call _ParseAndStripGTestFlags() before calling
+  # unittest.main().  Otherwise the latter will be confused by the
+  # --gtest_* flags.
+  _ParseAndStripGTestFlags(sys.argv)
+  # The tested binaries should not be writing XML output files unless the
+  # script explicitly instructs them to.
+  # TODO(vladl@google.com): Move this into Subprocess when we implement
+  # passing environment into it as a parameter.
+  if GTEST_OUTPUT_VAR_NAME in os.environ:
+    del os.environ[GTEST_OUTPUT_VAR_NAME]
+
+  _test_module.main()
diff --git a/protobuf/gtest/test/gtest_throw_on_failure_ex_test.cc b/protobuf/gtest/test/gtest_throw_on_failure_ex_test.cc
new file mode 100644
index 0000000..8bf9dc9
--- /dev/null
+++ b/protobuf/gtest/test/gtest_throw_on_failure_ex_test.cc
@@ -0,0 +1,92 @@
+// Copyright 2009, 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)
+
+// Tests Google Test's throw-on-failure mode with exceptions enabled.
+
+#include <gtest/gtest.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdexcept>
+
+// Prints the given failure message and exits the program with
+// non-zero.  We use this instead of a Google Test assertion to
+// indicate a failure, as the latter is been tested and cannot be
+// relied on.
+void Fail(const char* msg) {
+  printf("FAILURE: %s\n", msg);
+  fflush(stdout);
+  exit(1);
+}
+
+// Tests that an assertion failure throws a subclass of
+// std::runtime_error.
+void TestFailureThrowsRuntimeError() {
+  testing::GTEST_FLAG(throw_on_failure) = true;
+
+  // A successful assertion shouldn't throw.
+  try {
+    EXPECT_EQ(3, 3);
+  } catch(...) {
+    Fail("A successful assertion wrongfully threw.");
+  }
+
+  // A failed assertion should throw a subclass of std::runtime_error.
+  try {
+    EXPECT_EQ(2, 3) << "Expected failure";
+  } catch(const std::runtime_error& e) {
+    if (strstr(e.what(), "Expected failure") != NULL)
+      return;
+
+    printf("%s",
+           "A failed assertion did throw an exception of the right type, "
+           "but the message is incorrect.  Instead of containing \"Expected "
+           "failure\", it is:\n");
+    Fail(e.what());
+  } catch(...) {
+    Fail("A failed assertion threw the wrong type of exception.");
+  }
+  Fail("A failed assertion should've thrown but didn't.");
+}
+
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
+
+  // We want to ensure that people can use Google Test assertions in
+  // other testing frameworks, as long as they initialize Google Test
+  // properly and set the thrown-on-failure mode.  Therefore, we don't
+  // use Google Test's constructs for defining and running tests
+  // (e.g. TEST and RUN_ALL_TESTS) here.
+
+  TestFailureThrowsRuntimeError();
+  return 0;
+}
diff --git a/protobuf/gtest/test/gtest_throw_on_failure_test.py b/protobuf/gtest/test/gtest_throw_on_failure_test.py
new file mode 100755
index 0000000..5678ffe
--- /dev/null
+++ b/protobuf/gtest/test/gtest_throw_on_failure_test.py
@@ -0,0 +1,171 @@
+#!/usr/bin/env python
+#
+# Copyright 2009, 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.
+
+"""Tests Google Test's throw-on-failure mode with exceptions disabled.
+
+This script invokes gtest_throw_on_failure_test_ (a program written with
+Google Test) with different environments and command line flags.
+"""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import os
+import gtest_test_utils
+
+
+# Constants.
+
+# The command line flag for enabling/disabling the throw-on-failure mode.
+THROW_ON_FAILURE = 'gtest_throw_on_failure'
+
+# Path to the gtest_throw_on_failure_test_ program, compiled with
+# exceptions disabled.
+EXE_PATH = gtest_test_utils.GetTestExecutablePath(
+    'gtest_throw_on_failure_test_')
+
+
+# Utilities.
+
+
+def SetEnvVar(env_var, value):
+  """Sets an environment variable to a given value; unsets it when the
+  given value is None.
+  """
+
+  env_var = env_var.upper()
+  if value is not None:
+    os.environ[env_var] = value
+  elif env_var in os.environ:
+    del os.environ[env_var]
+
+
+def Run(command):
+  """Runs a command; returns True/False if its exit code is/isn't 0."""
+
+  print 'Running "%s". . .' % ' '.join(command)
+  p = gtest_test_utils.Subprocess(command)
+  return p.exited and p.exit_code == 0
+
+
+# The tests.  TODO(wan@google.com): refactor the class to share common
+# logic with code in gtest_break_on_failure_unittest.py.
+class ThrowOnFailureTest(gtest_test_utils.TestCase):
+  """Tests the throw-on-failure mode."""
+
+  def RunAndVerify(self, env_var_value, flag_value, should_fail):
+    """Runs gtest_throw_on_failure_test_ and verifies that it does
+    (or does not) exit with a non-zero code.
+
+    Args:
+      env_var_value:    value of the GTEST_BREAK_ON_FAILURE environment
+                        variable; None if the variable should be unset.
+      flag_value:       value of the --gtest_break_on_failure flag;
+                        None if the flag should not be present.
+      should_fail:      True iff the program is expected to fail.
+    """
+
+    SetEnvVar(THROW_ON_FAILURE, env_var_value)
+
+    if env_var_value is None:
+      env_var_value_msg = ' is not set'
+    else:
+      env_var_value_msg = '=' + env_var_value
+
+    if flag_value is None:
+      flag = ''
+    elif flag_value == '0':
+      flag = '--%s=0' % THROW_ON_FAILURE
+    else:
+      flag = '--%s' % THROW_ON_FAILURE
+
+    command = [EXE_PATH]
+    if flag:
+      command.append(flag)
+
+    if should_fail:
+      should_or_not = 'should'
+    else:
+      should_or_not = 'should not'
+
+    failed = not Run(command)
+
+    SetEnvVar(THROW_ON_FAILURE, None)
+
+    msg = ('when %s%s, an assertion failure in "%s" %s cause a non-zero '
+           'exit code.' %
+           (THROW_ON_FAILURE, env_var_value_msg, ' '.join(command),
+            should_or_not))
+    self.assert_(failed == should_fail, msg)
+
+  def testDefaultBehavior(self):
+    """Tests the behavior of the default mode."""
+
+    self.RunAndVerify(env_var_value=None, flag_value=None, should_fail=False)
+
+  def testThrowOnFailureEnvVar(self):
+    """Tests using the GTEST_THROW_ON_FAILURE environment variable."""
+
+    self.RunAndVerify(env_var_value='0',
+                      flag_value=None,
+                      should_fail=False)
+    self.RunAndVerify(env_var_value='1',
+                      flag_value=None,
+                      should_fail=True)
+
+  def testThrowOnFailureFlag(self):
+    """Tests using the --gtest_throw_on_failure flag."""
+
+    self.RunAndVerify(env_var_value=None,
+                      flag_value='0',
+                      should_fail=False)
+    self.RunAndVerify(env_var_value=None,
+                      flag_value='1',
+                      should_fail=True)
+
+  def testThrowOnFailureFlagOverridesEnvVar(self):
+    """Tests that --gtest_throw_on_failure overrides GTEST_THROW_ON_FAILURE."""
+
+    self.RunAndVerify(env_var_value='0',
+                      flag_value='0',
+                      should_fail=False)
+    self.RunAndVerify(env_var_value='0',
+                      flag_value='1',
+                      should_fail=True)
+    self.RunAndVerify(env_var_value='1',
+                      flag_value='0',
+                      should_fail=False)
+    self.RunAndVerify(env_var_value='1',
+                      flag_value='1',
+                      should_fail=True)
+
+
+if __name__ == '__main__':
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_throw_on_failure_test_.cc b/protobuf/gtest/test/gtest_throw_on_failure_test_.cc
new file mode 100644
index 0000000..88fbd5a
--- /dev/null
+++ b/protobuf/gtest/test/gtest_throw_on_failure_test_.cc
@@ -0,0 +1,56 @@
+// Copyright 2009, 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)
+
+// Tests Google Test's throw-on-failure mode with exceptions disabled.
+//
+// This program must be compiled with exceptions disabled.  It will be
+// invoked by gtest_throw_on_failure_test.py, and is expected to exit
+// with non-zero in the throw-on-failure mode or 0 otherwise.
+
+#include <gtest/gtest.h>
+
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
+
+  // We want to ensure that people can use Google Test assertions in
+  // other testing frameworks, as long as they initialize Google Test
+  // properly and set the thrown-on-failure mode.  Therefore, we don't
+  // use Google Test's constructs for defining and running tests
+  // (e.g. TEST and RUN_ALL_TESTS) here.
+
+  // In the throw-on-failure mode with exceptions disabled, this
+  // assertion will cause the program to exit with a non-zero code.
+  EXPECT_EQ(2, 3);
+
+  // When not in the throw-on-failure mode, the control will reach
+  // here.
+  return 0;
+}
diff --git a/protobuf/gtest/test/gtest_uninitialized_test.py b/protobuf/gtest/test/gtest_uninitialized_test.py
new file mode 100755
index 0000000..6ae57ee
--- /dev/null
+++ b/protobuf/gtest/test/gtest_uninitialized_test.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Verifies that Google Test warns the user when not initialized properly."""
+
+__author__ = 'wan@google.com (Zhanyong Wan)'
+
+import gtest_test_utils
+
+
+COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_')
+
+
+def Assert(condition):
+  if not condition:
+    raise AssertionError
+
+
+def AssertEq(expected, actual):
+  if expected != actual:
+    print 'Expected: %s' % (expected,)
+    print '  Actual: %s' % (actual,)
+    raise AssertionError
+
+
+def TestExitCodeAndOutput(command):
+  """Runs the given command and verifies its exit code and output."""
+
+  # Verifies that 'command' exits with code 1.
+  p = gtest_test_utils.Subprocess(command)
+  Assert(p.exited)
+  AssertEq(1, p.exit_code)
+  Assert('InitGoogleTest' in p.output)
+
+
+class GTestUninitializedTest(gtest_test_utils.TestCase):
+  def testExitCodeAndOutput(self):
+    TestExitCodeAndOutput(COMMAND)
+
+
+if __name__ == '__main__':
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_uninitialized_test_.cc b/protobuf/gtest/test/gtest_uninitialized_test_.cc
new file mode 100644
index 0000000..e8b2aa8
--- /dev/null
+++ b/protobuf/gtest/test/gtest_uninitialized_test_.cc
@@ -0,0 +1,43 @@
+// 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/gtest.h>
+
+TEST(DummyTest, Dummy) {
+  // This test doesn't verify anything.  We just need it to create a
+  // realistic stage for testing the behavior of Google Test when
+  // RUN_ALL_TESTS() is called without testing::InitGoogleTest() being
+  // called first.
+}
+
+int main() {
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/test/gtest_unittest.cc b/protobuf/gtest/test/gtest_unittest.cc
new file mode 100644
index 0000000..a14f065
--- /dev/null
+++ b/protobuf/gtest/test/gtest_unittest.cc
@@ -0,0 +1,6718 @@
+// 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)
+//
+// Tests for Google Test itself.  This verifies that the basic constructs of
+// Google Test work.
+
+#include <gtest/gtest.h>
+#include <vector>
+
+// Verifies that the command line flag variables can be accessed
+// in code once <gtest/gtest.h> has been #included.
+// Do not move it after other #includes.
+TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
+  bool dummy = testing::GTEST_FLAG(also_run_disabled_tests)
+      || testing::GTEST_FLAG(break_on_failure)
+      || testing::GTEST_FLAG(catch_exceptions)
+      || testing::GTEST_FLAG(color) != "unknown"
+      || testing::GTEST_FLAG(filter) != "unknown"
+      || testing::GTEST_FLAG(list_tests)
+      || testing::GTEST_FLAG(output) != "unknown"
+      || testing::GTEST_FLAG(print_time)
+      || testing::GTEST_FLAG(random_seed)
+      || testing::GTEST_FLAG(repeat) > 0
+      || testing::GTEST_FLAG(show_internal_stack_frames)
+      || testing::GTEST_FLAG(shuffle)
+      || testing::GTEST_FLAG(stack_trace_depth) > 0
+      || testing::GTEST_FLAG(throw_on_failure);
+  EXPECT_TRUE(dummy || !dummy);  // Suppresses warning that dummy is unused.
+}
+
+#include <gtest/gtest-spi.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_ 1
+#include "src/gtest-internal-inl.h"
+#undef GTEST_IMPLEMENTATION_
+
+#include <limits.h>  // For INT_MAX.
+#include <stdlib.h>
+#include <time.h>
+
+#include <map>
+
+namespace testing {
+namespace internal {
+
+// Provides access to otherwise private parts of the TestEventListeners class
+// that are needed to test it.
+class TestEventListenersAccessor {
+ public:
+  static TestEventListener* GetRepeater(TestEventListeners* listeners) {
+    return listeners->repeater();
+  }
+
+  static void SetDefaultResultPrinter(TestEventListeners* listeners,
+                                      TestEventListener* listener) {
+    listeners->SetDefaultResultPrinter(listener);
+  }
+  static void SetDefaultXmlGenerator(TestEventListeners* listeners,
+                                     TestEventListener* listener) {
+    listeners->SetDefaultXmlGenerator(listener);
+  }
+
+  static bool EventForwardingEnabled(const TestEventListeners& listeners) {
+    return listeners.EventForwardingEnabled();
+  }
+
+  static void SuppressEventForwarding(TestEventListeners* listeners) {
+    listeners->SuppressEventForwarding();
+  }
+};
+
+}  // namespace internal
+}  // namespace testing
+
+using testing::AssertionFailure;
+using testing::AssertionResult;
+using testing::AssertionSuccess;
+using testing::DoubleLE;
+using testing::EmptyTestEventListener;
+using testing::FloatLE;
+using testing::GTEST_FLAG(also_run_disabled_tests);
+using testing::GTEST_FLAG(break_on_failure);
+using testing::GTEST_FLAG(catch_exceptions);
+using testing::GTEST_FLAG(color);
+using testing::GTEST_FLAG(death_test_use_fork);
+using testing::GTEST_FLAG(filter);
+using testing::GTEST_FLAG(list_tests);
+using testing::GTEST_FLAG(output);
+using testing::GTEST_FLAG(print_time);
+using testing::GTEST_FLAG(random_seed);
+using testing::GTEST_FLAG(repeat);
+using testing::GTEST_FLAG(show_internal_stack_frames);
+using testing::GTEST_FLAG(shuffle);
+using testing::GTEST_FLAG(stack_trace_depth);
+using testing::GTEST_FLAG(throw_on_failure);
+using testing::IsNotSubstring;
+using testing::IsSubstring;
+using testing::Message;
+using testing::ScopedFakeTestPartResultReporter;
+using testing::StaticAssertTypeEq;
+using testing::Test;
+using testing::TestEventListeners;
+using testing::TestCase;
+using testing::TestPartResult;
+using testing::TestPartResultArray;
+using testing::TestProperty;
+using testing::TestResult;
+using testing::UnitTest;
+using testing::kMaxStackTraceDepth;
+using testing::internal::AlwaysFalse;
+using testing::internal::AlwaysTrue;
+using testing::internal::AppendUserMessage;
+using testing::internal::CodePointToUtf8;
+using testing::internal::CountIf;
+using testing::internal::EqFailure;
+using testing::internal::FloatingPoint;
+using testing::internal::FormatTimeInMillisAsSeconds;
+using testing::internal::ForEach;
+using testing::internal::GTestFlagSaver;
+using testing::internal::GetCurrentOsStackTraceExceptTop;
+using testing::internal::GetElementOr;
+using testing::internal::GetNextRandomSeed;
+using testing::internal::GetRandomSeedFromFlag;
+using testing::internal::GetTestTypeId;
+using testing::internal::GetTypeId;
+using testing::internal::GetUnitTestImpl;
+using testing::internal::Int32;
+using testing::internal::Int32FromEnvOrDie;
+using testing::internal::ParseInt32Flag;
+using testing::internal::ShouldRunTestOnShard;
+using testing::internal::ShouldShard;
+using testing::internal::ShouldUseColor;
+using testing::internal::Shuffle;
+using testing::internal::ShuffleRange;
+using testing::internal::StreamableToString;
+using testing::internal::String;
+using testing::internal::TestEventListenersAccessor;
+using testing::internal::TestResultAccessor;
+using testing::internal::UInt32;
+using testing::internal::WideStringToUtf8;
+using testing::internal::kMaxRandomSeed;
+using testing::internal::kTestTypeIdInGoogleTest;
+using testing::internal::scoped_ptr;
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+using testing::internal::CaptureStdout;
+using testing::internal::GetCapturedStdout;
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
+#if GTEST_IS_THREADSAFE
+using testing::internal::ThreadWithParam;
+#endif
+
+class TestingVector : public std::vector<int> {
+};
+
+::std::ostream& operator<<(::std::ostream& os,
+                           const TestingVector& vector) {
+  os << "{ ";
+  for (size_t i = 0; i < vector.size(); i++) {
+    os << vector[i] << " ";
+  }
+  os << "}";
+  return os;
+}
+
+// This line tests that we can define tests in an unnamed namespace.
+namespace {
+
+TEST(GetRandomSeedFromFlagTest, HandlesZero) {
+  const int seed = GetRandomSeedFromFlag(0);
+  EXPECT_LE(1, seed);
+  EXPECT_LE(seed, static_cast<int>(kMaxRandomSeed));
+}
+
+TEST(GetRandomSeedFromFlagTest, PreservesValidSeed) {
+  EXPECT_EQ(1, GetRandomSeedFromFlag(1));
+  EXPECT_EQ(2, GetRandomSeedFromFlag(2));
+  EXPECT_EQ(kMaxRandomSeed - 1, GetRandomSeedFromFlag(kMaxRandomSeed - 1));
+  EXPECT_EQ(static_cast<int>(kMaxRandomSeed),
+            GetRandomSeedFromFlag(kMaxRandomSeed));
+}
+
+TEST(GetRandomSeedFromFlagTest, NormalizesInvalidSeed) {
+  const int seed1 = GetRandomSeedFromFlag(-1);
+  EXPECT_LE(1, seed1);
+  EXPECT_LE(seed1, static_cast<int>(kMaxRandomSeed));
+
+  const int seed2 = GetRandomSeedFromFlag(kMaxRandomSeed + 1);
+  EXPECT_LE(1, seed2);
+  EXPECT_LE(seed2, static_cast<int>(kMaxRandomSeed));
+}
+
+TEST(GetNextRandomSeedTest, WorksForValidInput) {
+  EXPECT_EQ(2, GetNextRandomSeed(1));
+  EXPECT_EQ(3, GetNextRandomSeed(2));
+  EXPECT_EQ(static_cast<int>(kMaxRandomSeed),
+            GetNextRandomSeed(kMaxRandomSeed - 1));
+  EXPECT_EQ(1, GetNextRandomSeed(kMaxRandomSeed));
+
+  // We deliberately don't test GetNextRandomSeed() with invalid
+  // inputs, as that requires death tests, which are expensive.  This
+  // is fine as GetNextRandomSeed() is internal and has a
+  // straightforward definition.
+}
+
+static void ClearCurrentTestPartResults() {
+  TestResultAccessor::ClearTestPartResults(
+      GetUnitTestImpl()->current_test_result());
+}
+
+// Tests GetTypeId.
+
+TEST(GetTypeIdTest, ReturnsSameValueForSameType) {
+  EXPECT_EQ(GetTypeId<int>(), GetTypeId<int>());
+  EXPECT_EQ(GetTypeId<Test>(), GetTypeId<Test>());
+}
+
+class SubClassOfTest : public Test {};
+class AnotherSubClassOfTest : public Test {};
+
+TEST(GetTypeIdTest, ReturnsDifferentValuesForDifferentTypes) {
+  EXPECT_NE(GetTypeId<int>(), GetTypeId<const int>());
+  EXPECT_NE(GetTypeId<int>(), GetTypeId<char>());
+  EXPECT_NE(GetTypeId<int>(), GetTestTypeId());
+  EXPECT_NE(GetTypeId<SubClassOfTest>(), GetTestTypeId());
+  EXPECT_NE(GetTypeId<AnotherSubClassOfTest>(), GetTestTypeId());
+  EXPECT_NE(GetTypeId<AnotherSubClassOfTest>(), GetTypeId<SubClassOfTest>());
+}
+
+// Verifies that GetTestTypeId() returns the same value, no matter it
+// is called from inside Google Test or outside of it.
+TEST(GetTestTypeIdTest, ReturnsTheSameValueInsideOrOutsideOfGoogleTest) {
+  EXPECT_EQ(kTestTypeIdInGoogleTest, GetTestTypeId());
+}
+
+// Tests FormatTimeInMillisAsSeconds().
+
+TEST(FormatTimeInMillisAsSecondsTest, FormatsZero) {
+  EXPECT_EQ("0", FormatTimeInMillisAsSeconds(0));
+}
+
+TEST(FormatTimeInMillisAsSecondsTest, FormatsPositiveNumber) {
+  EXPECT_EQ("0.003", FormatTimeInMillisAsSeconds(3));
+  EXPECT_EQ("0.01", FormatTimeInMillisAsSeconds(10));
+  EXPECT_EQ("0.2", FormatTimeInMillisAsSeconds(200));
+  EXPECT_EQ("1.2", FormatTimeInMillisAsSeconds(1200));
+  EXPECT_EQ("3", FormatTimeInMillisAsSeconds(3000));
+}
+
+TEST(FormatTimeInMillisAsSecondsTest, FormatsNegativeNumber) {
+  EXPECT_EQ("-0.003", FormatTimeInMillisAsSeconds(-3));
+  EXPECT_EQ("-0.01", FormatTimeInMillisAsSeconds(-10));
+  EXPECT_EQ("-0.2", FormatTimeInMillisAsSeconds(-200));
+  EXPECT_EQ("-1.2", FormatTimeInMillisAsSeconds(-1200));
+  EXPECT_EQ("-3", FormatTimeInMillisAsSeconds(-3000));
+}
+
+#if GTEST_CAN_COMPARE_NULL
+
+#ifdef __BORLANDC__
+// Silences warnings: "Condition is always true", "Unreachable code"
+#pragma option push -w-ccc -w-rch
+#endif
+
+// Tests that GTEST_IS_NULL_LITERAL_(x) is true when x is a null
+// pointer literal.
+TEST(NullLiteralTest, IsTrueForNullLiterals) {
+  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(NULL));
+  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0));
+  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0U));
+  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(0L));
+  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(false));
+#ifndef __BORLANDC__
+  // Some compilers may fail to detect some null pointer literals;
+  // as long as users of the framework don't use such literals, this
+  // is harmless.
+  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(1 - 1));
+  EXPECT_TRUE(GTEST_IS_NULL_LITERAL_(true && false));
+#endif
+}
+
+// Tests that GTEST_IS_NULL_LITERAL_(x) is false when x is not a null
+// pointer literal.
+TEST(NullLiteralTest, IsFalseForNonNullLiterals) {
+  EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(1));
+  EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(0.0));
+  EXPECT_FALSE(GTEST_IS_NULL_LITERAL_('a'));
+  EXPECT_FALSE(GTEST_IS_NULL_LITERAL_(static_cast<void*>(NULL)));
+}
+
+#ifdef __BORLANDC__
+// Restores warnings after previous "#pragma option push" suppressed them.
+#pragma option pop
+#endif
+
+#endif  // GTEST_CAN_COMPARE_NULL
+//
+// Tests CodePointToUtf8().
+
+// Tests that the NUL character L'\0' is encoded correctly.
+TEST(CodePointToUtf8Test, CanEncodeNul) {
+  char buffer[32];
+  EXPECT_STREQ("", CodePointToUtf8(L'\0', buffer));
+}
+
+// Tests that ASCII characters are encoded correctly.
+TEST(CodePointToUtf8Test, CanEncodeAscii) {
+  char buffer[32];
+  EXPECT_STREQ("a", CodePointToUtf8(L'a', buffer));
+  EXPECT_STREQ("Z", CodePointToUtf8(L'Z', buffer));
+  EXPECT_STREQ("&", CodePointToUtf8(L'&', buffer));
+  EXPECT_STREQ("\x7F", CodePointToUtf8(L'\x7F', buffer));
+}
+
+// Tests that Unicode code-points that have 8 to 11 bits are encoded
+// as 110xxxxx 10xxxxxx.
+TEST(CodePointToUtf8Test, CanEncode8To11Bits) {
+  char buffer[32];
+  // 000 1101 0011 => 110-00011 10-010011
+  EXPECT_STREQ("\xC3\x93", CodePointToUtf8(L'\xD3', buffer));
+
+  // 101 0111 0110 => 110-10101 10-110110
+  EXPECT_STREQ("\xD5\xB6", CodePointToUtf8(L'\x576', buffer));
+}
+
+// Tests that Unicode code-points that have 12 to 16 bits are encoded
+// as 1110xxxx 10xxxxxx 10xxxxxx.
+TEST(CodePointToUtf8Test, CanEncode12To16Bits) {
+  char buffer[32];
+  // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011
+  EXPECT_STREQ("\xE0\xA3\x93", CodePointToUtf8(L'\x8D3', buffer));
+
+  // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101
+  EXPECT_STREQ("\xEC\x9D\x8D", CodePointToUtf8(L'\xC74D', buffer));
+}
+
+#if !GTEST_WIDE_STRING_USES_UTF16_
+// Tests in this group require a wchar_t to hold > 16 bits, and thus
+// are skipped on Windows, Cygwin, and Symbian, where a wchar_t is
+// 16-bit wide. This code may not compile on those systems.
+
+// Tests that Unicode code-points that have 17 to 21 bits are encoded
+// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx.
+TEST(CodePointToUtf8Test, CanEncode17To21Bits) {
+  char buffer[32];
+  // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011
+  EXPECT_STREQ("\xF0\x90\xA3\x93", CodePointToUtf8(L'\x108D3', buffer));
+
+  // 0 0001 0000 0100 0000 0000 => 11110-000 10-010000 10-010000 10-000000
+  EXPECT_STREQ("\xF0\x90\x90\x80", CodePointToUtf8(L'\x10400', buffer));
+
+  // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100
+  EXPECT_STREQ("\xF4\x88\x98\xB4", CodePointToUtf8(L'\x108634', buffer));
+}
+
+// Tests that encoding an invalid code-point generates the expected result.
+TEST(CodePointToUtf8Test, CanEncodeInvalidCodePoint) {
+  char buffer[32];
+  EXPECT_STREQ("(Invalid Unicode 0x1234ABCD)",
+               CodePointToUtf8(L'\x1234ABCD', buffer));
+}
+
+#endif  // !GTEST_WIDE_STRING_USES_UTF16_
+
+// Tests WideStringToUtf8().
+
+// Tests that the NUL character L'\0' is encoded correctly.
+TEST(WideStringToUtf8Test, CanEncodeNul) {
+  EXPECT_STREQ("", WideStringToUtf8(L"", 0).c_str());
+  EXPECT_STREQ("", WideStringToUtf8(L"", -1).c_str());
+}
+
+// Tests that ASCII strings are encoded correctly.
+TEST(WideStringToUtf8Test, CanEncodeAscii) {
+  EXPECT_STREQ("a", WideStringToUtf8(L"a", 1).c_str());
+  EXPECT_STREQ("ab", WideStringToUtf8(L"ab", 2).c_str());
+  EXPECT_STREQ("a", WideStringToUtf8(L"a", -1).c_str());
+  EXPECT_STREQ("ab", WideStringToUtf8(L"ab", -1).c_str());
+}
+
+// Tests that Unicode code-points that have 8 to 11 bits are encoded
+// as 110xxxxx 10xxxxxx.
+TEST(WideStringToUtf8Test, CanEncode8To11Bits) {
+  // 000 1101 0011 => 110-00011 10-010011
+  EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", 1).c_str());
+  EXPECT_STREQ("\xC3\x93", WideStringToUtf8(L"\xD3", -1).c_str());
+
+  // 101 0111 0110 => 110-10101 10-110110
+  EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(L"\x576", 1).c_str());
+  EXPECT_STREQ("\xD5\xB6", WideStringToUtf8(L"\x576", -1).c_str());
+}
+
+// Tests that Unicode code-points that have 12 to 16 bits are encoded
+// as 1110xxxx 10xxxxxx 10xxxxxx.
+TEST(WideStringToUtf8Test, CanEncode12To16Bits) {
+  // 0000 1000 1101 0011 => 1110-0000 10-100011 10-010011
+  EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(L"\x8D3", 1).c_str());
+  EXPECT_STREQ("\xE0\xA3\x93", WideStringToUtf8(L"\x8D3", -1).c_str());
+
+  // 1100 0111 0100 1101 => 1110-1100 10-011101 10-001101
+  EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(L"\xC74D", 1).c_str());
+  EXPECT_STREQ("\xEC\x9D\x8D", WideStringToUtf8(L"\xC74D", -1).c_str());
+}
+
+// Tests that the conversion stops when the function encounters \0 character.
+TEST(WideStringToUtf8Test, StopsOnNulCharacter) {
+  EXPECT_STREQ("ABC", WideStringToUtf8(L"ABC\0XYZ", 100).c_str());
+}
+
+// Tests that the conversion stops when the function reaches the limit
+// specified by the 'length' parameter.
+TEST(WideStringToUtf8Test, StopsWhenLengthLimitReached) {
+  EXPECT_STREQ("ABC", WideStringToUtf8(L"ABCDEF", 3).c_str());
+}
+
+
+#if !GTEST_WIDE_STRING_USES_UTF16_
+// Tests that Unicode code-points that have 17 to 21 bits are encoded
+// as 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx. This code may not compile
+// on the systems using UTF-16 encoding.
+TEST(WideStringToUtf8Test, CanEncode17To21Bits) {
+  // 0 0001 0000 1000 1101 0011 => 11110-000 10-010000 10-100011 10-010011
+  EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", 1).c_str());
+  EXPECT_STREQ("\xF0\x90\xA3\x93", WideStringToUtf8(L"\x108D3", -1).c_str());
+
+  // 1 0000 1000 0110 0011 0100 => 11110-100 10-001000 10-011000 10-110100
+  EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", 1).c_str());
+  EXPECT_STREQ("\xF4\x88\x98\xB4", WideStringToUtf8(L"\x108634", -1).c_str());
+}
+
+// Tests that encoding an invalid code-point generates the expected result.
+TEST(WideStringToUtf8Test, CanEncodeInvalidCodePoint) {
+  EXPECT_STREQ("(Invalid Unicode 0xABCDFF)",
+               WideStringToUtf8(L"\xABCDFF", -1).c_str());
+}
+#else  // !GTEST_WIDE_STRING_USES_UTF16_
+// Tests that surrogate pairs are encoded correctly on the systems using
+// UTF-16 encoding in the wide strings.
+TEST(WideStringToUtf8Test, CanEncodeValidUtf16SUrrogatePairs) {
+  EXPECT_STREQ("\xF0\x90\x90\x80",
+               WideStringToUtf8(L"\xD801\xDC00", -1).c_str());
+}
+
+// Tests that encoding an invalid UTF-16 surrogate pair
+// generates the expected result.
+TEST(WideStringToUtf8Test, CanEncodeInvalidUtf16SurrogatePair) {
+  // Leading surrogate is at the end of the string.
+  EXPECT_STREQ("\xED\xA0\x80", WideStringToUtf8(L"\xD800", -1).c_str());
+  // Leading surrogate is not followed by the trailing surrogate.
+  EXPECT_STREQ("\xED\xA0\x80$", WideStringToUtf8(L"\xD800$", -1).c_str());
+  // Trailing surrogate appearas without a leading surrogate.
+  EXPECT_STREQ("\xED\xB0\x80PQR", WideStringToUtf8(L"\xDC00PQR", -1).c_str());
+}
+#endif  // !GTEST_WIDE_STRING_USES_UTF16_
+
+// Tests that codepoint concatenation works correctly.
+#if !GTEST_WIDE_STRING_USES_UTF16_
+TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) {
+  EXPECT_STREQ(
+      "\xF4\x88\x98\xB4"
+          "\xEC\x9D\x8D"
+          "\n"
+          "\xD5\xB6"
+          "\xE0\xA3\x93"
+          "\xF4\x88\x98\xB4",
+      WideStringToUtf8(L"\x108634\xC74D\n\x576\x8D3\x108634", -1).c_str());
+}
+#else
+TEST(WideStringToUtf8Test, ConcatenatesCodepointsCorrectly) {
+  EXPECT_STREQ(
+      "\xEC\x9D\x8D" "\n" "\xD5\xB6" "\xE0\xA3\x93",
+      WideStringToUtf8(L"\xC74D\n\x576\x8D3", -1).c_str());
+}
+#endif  // !GTEST_WIDE_STRING_USES_UTF16_
+
+// Tests the Random class.
+
+TEST(RandomDeathTest, GeneratesCrashesOnInvalidRange) {
+  testing::internal::Random random(42);
+  EXPECT_DEATH_IF_SUPPORTED(
+      random.Generate(0),
+      "Cannot generate a number in the range \\[0, 0\\)");
+  EXPECT_DEATH_IF_SUPPORTED(
+      random.Generate(testing::internal::Random::kMaxRange + 1),
+      "Generation of a number in \\[0, 2147483649\\) was requested, "
+      "but this can only generate numbers in \\[0, 2147483648\\)");
+}
+
+TEST(RandomTest, GeneratesNumbersWithinRange) {
+  const UInt32 kRange = 10000;
+  testing::internal::Random random(12345);
+  for (int i = 0; i < 10; i++) {
+    EXPECT_LT(random.Generate(kRange), kRange) << " for iteration " << i;
+  }
+
+  testing::internal::Random random2(testing::internal::Random::kMaxRange);
+  for (int i = 0; i < 10; i++) {
+    EXPECT_LT(random2.Generate(kRange), kRange) << " for iteration " << i;
+  }
+}
+
+TEST(RandomTest, RepeatsWhenReseeded) {
+  const int kSeed = 123;
+  const int kArraySize = 10;
+  const UInt32 kRange = 10000;
+  UInt32 values[kArraySize];
+
+  testing::internal::Random random(kSeed);
+  for (int i = 0; i < kArraySize; i++) {
+    values[i] = random.Generate(kRange);
+  }
+
+  random.Reseed(kSeed);
+  for (int i = 0; i < kArraySize; i++) {
+    EXPECT_EQ(values[i], random.Generate(kRange)) << " for iteration " << i;
+  }
+}
+
+// Tests STL container utilities.
+
+// Tests CountIf().
+
+static bool IsPositive(int n) { return n > 0; }
+
+TEST(ContainerUtilityTest, CountIf) {
+  std::vector<int> v;
+  EXPECT_EQ(0, CountIf(v, IsPositive));  // Works for an empty container.
+
+  v.push_back(-1);
+  v.push_back(0);
+  EXPECT_EQ(0, CountIf(v, IsPositive));  // Works when no value satisfies.
+
+  v.push_back(2);
+  v.push_back(-10);
+  v.push_back(10);
+  EXPECT_EQ(2, CountIf(v, IsPositive));
+}
+
+// Tests ForEach().
+
+static int g_sum = 0;
+static void Accumulate(int n) { g_sum += n; }
+
+TEST(ContainerUtilityTest, ForEach) {
+  std::vector<int> v;
+  g_sum = 0;
+  ForEach(v, Accumulate);
+  EXPECT_EQ(0, g_sum);  // Works for an empty container;
+
+  g_sum = 0;
+  v.push_back(1);
+  ForEach(v, Accumulate);
+  EXPECT_EQ(1, g_sum);  // Works for a container with one element.
+
+  g_sum = 0;
+  v.push_back(20);
+  v.push_back(300);
+  ForEach(v, Accumulate);
+  EXPECT_EQ(321, g_sum);
+}
+
+// Tests GetElementOr().
+TEST(ContainerUtilityTest, GetElementOr) {
+  std::vector<char> a;
+  EXPECT_EQ('x', GetElementOr(a, 0, 'x'));
+
+  a.push_back('a');
+  a.push_back('b');
+  EXPECT_EQ('a', GetElementOr(a, 0, 'x'));
+  EXPECT_EQ('b', GetElementOr(a, 1, 'x'));
+  EXPECT_EQ('x', GetElementOr(a, -2, 'x'));
+  EXPECT_EQ('x', GetElementOr(a, 2, 'x'));
+}
+
+TEST(ContainerUtilityDeathTest, ShuffleRange) {
+  std::vector<int> a;
+  a.push_back(0);
+  a.push_back(1);
+  a.push_back(2);
+  testing::internal::Random random(1);
+
+  EXPECT_DEATH_IF_SUPPORTED(
+      ShuffleRange(&random, -1, 1, &a),
+      "Invalid shuffle range start -1: must be in range \\[0, 3\\]");
+  EXPECT_DEATH_IF_SUPPORTED(
+      ShuffleRange(&random, 4, 4, &a),
+      "Invalid shuffle range start 4: must be in range \\[0, 3\\]");
+  EXPECT_DEATH_IF_SUPPORTED(
+      ShuffleRange(&random, 3, 2, &a),
+      "Invalid shuffle range finish 2: must be in range \\[3, 3\\]");
+  EXPECT_DEATH_IF_SUPPORTED(
+      ShuffleRange(&random, 3, 4, &a),
+      "Invalid shuffle range finish 4: must be in range \\[3, 3\\]");
+}
+
+class VectorShuffleTest : public Test {
+ protected:
+  static const int kVectorSize = 20;
+
+  VectorShuffleTest() : random_(1) {
+    for (int i = 0; i < kVectorSize; i++) {
+      vector_.push_back(i);
+    }
+  }
+
+  static bool VectorIsCorrupt(const TestingVector& vector) {
+    if (kVectorSize != static_cast<int>(vector.size())) {
+      return true;
+    }
+
+    bool found_in_vector[kVectorSize] = { false };
+    for (size_t i = 0; i < vector.size(); i++) {
+      const int e = vector[i];
+      if (e < 0 || e >= kVectorSize || found_in_vector[e]) {
+        return true;
+      }
+      found_in_vector[e] = true;
+    }
+
+    // Vector size is correct, elements' range is correct, no
+    // duplicate elements.  Therefore no corruption has occurred.
+    return false;
+  }
+
+  static bool VectorIsNotCorrupt(const TestingVector& vector) {
+    return !VectorIsCorrupt(vector);
+  }
+
+  static bool RangeIsShuffled(const TestingVector& vector, int begin, int end) {
+    for (int i = begin; i < end; i++) {
+      if (i != vector[i]) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  static bool RangeIsUnshuffled(
+      const TestingVector& vector, int begin, int end) {
+    return !RangeIsShuffled(vector, begin, end);
+  }
+
+  static bool VectorIsShuffled(const TestingVector& vector) {
+    return RangeIsShuffled(vector, 0, static_cast<int>(vector.size()));
+  }
+
+  static bool VectorIsUnshuffled(const TestingVector& vector) {
+    return !VectorIsShuffled(vector);
+  }
+
+  testing::internal::Random random_;
+  TestingVector vector_;
+};  // class VectorShuffleTest
+
+const int VectorShuffleTest::kVectorSize;
+
+TEST_F(VectorShuffleTest, HandlesEmptyRange) {
+  // Tests an empty range at the beginning...
+  ShuffleRange(&random_, 0, 0, &vector_);
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  ASSERT_PRED1(VectorIsUnshuffled, vector_);
+
+  // ...in the middle...
+  ShuffleRange(&random_, kVectorSize/2, kVectorSize/2, &vector_);
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  ASSERT_PRED1(VectorIsUnshuffled, vector_);
+
+  // ...at the end...
+  ShuffleRange(&random_, kVectorSize - 1, kVectorSize - 1, &vector_);
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  ASSERT_PRED1(VectorIsUnshuffled, vector_);
+
+  // ...and past the end.
+  ShuffleRange(&random_, kVectorSize, kVectorSize, &vector_);
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  ASSERT_PRED1(VectorIsUnshuffled, vector_);
+}
+
+TEST_F(VectorShuffleTest, HandlesRangeOfSizeOne) {
+  // Tests a size one range at the beginning...
+  ShuffleRange(&random_, 0, 1, &vector_);
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  ASSERT_PRED1(VectorIsUnshuffled, vector_);
+
+  // ...in the middle...
+  ShuffleRange(&random_, kVectorSize/2, kVectorSize/2 + 1, &vector_);
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  ASSERT_PRED1(VectorIsUnshuffled, vector_);
+
+  // ...and at the end.
+  ShuffleRange(&random_, kVectorSize - 1, kVectorSize, &vector_);
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  ASSERT_PRED1(VectorIsUnshuffled, vector_);
+}
+
+// Because we use our own random number generator and a fixed seed,
+// we can guarantee that the following "random" tests will succeed.
+
+TEST_F(VectorShuffleTest, ShufflesEntireVector) {
+  Shuffle(&random_, &vector_);
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  EXPECT_FALSE(VectorIsUnshuffled(vector_)) << vector_;
+
+  // Tests the first and last elements in particular to ensure that
+  // there are no off-by-one problems in our shuffle algorithm.
+  EXPECT_NE(0, vector_[0]);
+  EXPECT_NE(kVectorSize - 1, vector_[kVectorSize - 1]);
+}
+
+TEST_F(VectorShuffleTest, ShufflesStartOfVector) {
+  const int kRangeSize = kVectorSize/2;
+
+  ShuffleRange(&random_, 0, kRangeSize, &vector_);
+
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  EXPECT_PRED3(RangeIsShuffled, vector_, 0, kRangeSize);
+  EXPECT_PRED3(RangeIsUnshuffled, vector_, kRangeSize, kVectorSize);
+}
+
+TEST_F(VectorShuffleTest, ShufflesEndOfVector) {
+  const int kRangeSize = kVectorSize / 2;
+  ShuffleRange(&random_, kRangeSize, kVectorSize, &vector_);
+
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize);
+  EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, kVectorSize);
+}
+
+TEST_F(VectorShuffleTest, ShufflesMiddleOfVector) {
+  int kRangeSize = kVectorSize/3;
+  ShuffleRange(&random_, kRangeSize, 2*kRangeSize, &vector_);
+
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  EXPECT_PRED3(RangeIsUnshuffled, vector_, 0, kRangeSize);
+  EXPECT_PRED3(RangeIsShuffled, vector_, kRangeSize, 2*kRangeSize);
+  EXPECT_PRED3(RangeIsUnshuffled, vector_, 2*kRangeSize, kVectorSize);
+}
+
+TEST_F(VectorShuffleTest, ShufflesRepeatably) {
+  TestingVector vector2;
+  for (int i = 0; i < kVectorSize; i++) {
+    vector2.push_back(i);
+  }
+
+  random_.Reseed(1234);
+  Shuffle(&random_, &vector_);
+  random_.Reseed(1234);
+  Shuffle(&random_, &vector2);
+
+  ASSERT_PRED1(VectorIsNotCorrupt, vector_);
+  ASSERT_PRED1(VectorIsNotCorrupt, vector2);
+
+  for (int i = 0; i < kVectorSize; i++) {
+    EXPECT_EQ(vector_[i], vector2[i]) << " where i is " << i;
+  }
+}
+
+// Tests the size of the AssertHelper class.
+
+TEST(AssertHelperTest, AssertHelperIsSmall) {
+  // To avoid breaking clients that use lots of assertions in one
+  // function, we cannot grow the size of AssertHelper.
+  EXPECT_LE(sizeof(testing::internal::AssertHelper), sizeof(void*));
+}
+
+// Tests the String class.
+
+// Tests String's constructors.
+TEST(StringTest, Constructors) {
+  // Default ctor.
+  String s1;
+  // We aren't using EXPECT_EQ(NULL, s1.c_str()) because comparing
+  // pointers with NULL isn't supported on all platforms.
+  EXPECT_EQ(0U, s1.length());
+  EXPECT_TRUE(NULL == s1.c_str());
+
+  // Implicitly constructs from a C-string.
+  String s2 = "Hi";
+  EXPECT_EQ(2U, s2.length());
+  EXPECT_STREQ("Hi", s2.c_str());
+
+  // Constructs from a C-string and a length.
+  String s3("hello", 3);
+  EXPECT_EQ(3U, s3.length());
+  EXPECT_STREQ("hel", s3.c_str());
+
+  // The empty String should be created when String is constructed with
+  // a NULL pointer and length 0.
+  EXPECT_EQ(0U, String(NULL, 0).length());
+  EXPECT_FALSE(String(NULL, 0).c_str() == NULL);
+
+  // Constructs a String that contains '\0'.
+  String s4("a\0bcd", 4);
+  EXPECT_EQ(4U, s4.length());
+  EXPECT_EQ('a', s4.c_str()[0]);
+  EXPECT_EQ('\0', s4.c_str()[1]);
+  EXPECT_EQ('b', s4.c_str()[2]);
+  EXPECT_EQ('c', s4.c_str()[3]);
+
+  // Copy ctor where the source is NULL.
+  const String null_str;
+  String s5 = null_str;
+  EXPECT_TRUE(s5.c_str() == NULL);
+
+  // Copy ctor where the source isn't NULL.
+  String s6 = s3;
+  EXPECT_EQ(3U, s6.length());
+  EXPECT_STREQ("hel", s6.c_str());
+
+  // Copy ctor where the source contains '\0'.
+  String s7 = s4;
+  EXPECT_EQ(4U, s7.length());
+  EXPECT_EQ('a', s7.c_str()[0]);
+  EXPECT_EQ('\0', s7.c_str()[1]);
+  EXPECT_EQ('b', s7.c_str()[2]);
+  EXPECT_EQ('c', s7.c_str()[3]);
+}
+
+TEST(StringTest, ConvertsFromStdString) {
+  // An empty std::string.
+  const std::string src1("");
+  const String dest1 = src1;
+  EXPECT_EQ(0U, dest1.length());
+  EXPECT_STREQ("", dest1.c_str());
+
+  // A normal std::string.
+  const std::string src2("Hi");
+  const String dest2 = src2;
+  EXPECT_EQ(2U, dest2.length());
+  EXPECT_STREQ("Hi", dest2.c_str());
+
+  // An std::string with an embedded NUL character.
+  const char src3[] = "a\0b";
+  const String dest3 = std::string(src3, sizeof(src3));
+  EXPECT_EQ(sizeof(src3), dest3.length());
+  EXPECT_EQ('a', dest3.c_str()[0]);
+  EXPECT_EQ('\0', dest3.c_str()[1]);
+  EXPECT_EQ('b', dest3.c_str()[2]);
+}
+
+TEST(StringTest, ConvertsToStdString) {
+  // An empty String.
+  const String src1("");
+  const std::string dest1 = src1;
+  EXPECT_EQ("", dest1);
+
+  // A normal String.
+  const String src2("Hi");
+  const std::string dest2 = src2;
+  EXPECT_EQ("Hi", dest2);
+
+  // A String containing a '\0'.
+  const String src3("x\0y", 3);
+  const std::string dest3 = src3;
+  EXPECT_EQ(std::string("x\0y", 3), dest3);
+}
+
+#if GTEST_HAS_GLOBAL_STRING
+
+TEST(StringTest, ConvertsFromGlobalString) {
+  // An empty ::string.
+  const ::string src1("");
+  const String dest1 = src1;
+  EXPECT_EQ(0U, dest1.length());
+  EXPECT_STREQ("", dest1.c_str());
+
+  // A normal ::string.
+  const ::string src2("Hi");
+  const String dest2 = src2;
+  EXPECT_EQ(2U, dest2.length());
+  EXPECT_STREQ("Hi", dest2.c_str());
+
+  // An ::string with an embedded NUL character.
+  const char src3[] = "x\0y";
+  const String dest3 = ::string(src3, sizeof(src3));
+  EXPECT_EQ(sizeof(src3), dest3.length());
+  EXPECT_EQ('x', dest3.c_str()[0]);
+  EXPECT_EQ('\0', dest3.c_str()[1]);
+  EXPECT_EQ('y', dest3.c_str()[2]);
+}
+
+TEST(StringTest, ConvertsToGlobalString) {
+  // An empty String.
+  const String src1("");
+  const ::string dest1 = src1;
+  EXPECT_EQ("", dest1);
+
+  // A normal String.
+  const String src2("Hi");
+  const ::string dest2 = src2;
+  EXPECT_EQ("Hi", dest2);
+
+  const String src3("x\0y", 3);
+  const ::string dest3 = src3;
+  EXPECT_EQ(::string("x\0y", 3), dest3);
+}
+
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+// Tests String::ShowCStringQuoted().
+TEST(StringTest, ShowCStringQuoted) {
+  EXPECT_STREQ("(null)",
+               String::ShowCStringQuoted(NULL).c_str());
+  EXPECT_STREQ("\"\"",
+               String::ShowCStringQuoted("").c_str());
+  EXPECT_STREQ("\"foo\"",
+               String::ShowCStringQuoted("foo").c_str());
+}
+
+// Tests String::empty().
+TEST(StringTest, Empty) {
+  EXPECT_TRUE(String("").empty());
+  EXPECT_FALSE(String().empty());
+  EXPECT_FALSE(String(NULL).empty());
+  EXPECT_FALSE(String("a").empty());
+  EXPECT_FALSE(String("\0", 1).empty());
+}
+
+// Tests String::Compare().
+TEST(StringTest, Compare) {
+  // NULL vs NULL.
+  EXPECT_EQ(0, String().Compare(String()));
+
+  // NULL vs non-NULL.
+  EXPECT_EQ(-1, String().Compare(String("")));
+
+  // Non-NULL vs NULL.
+  EXPECT_EQ(1, String("").Compare(String()));
+
+  // The following covers non-NULL vs non-NULL.
+
+  // "" vs "".
+  EXPECT_EQ(0, String("").Compare(String("")));
+
+  // "" vs non-"".
+  EXPECT_EQ(-1, String("").Compare(String("\0", 1)));
+  EXPECT_EQ(-1, String("").Compare(" "));
+
+  // Non-"" vs "".
+  EXPECT_EQ(1, String("a").Compare(String("")));
+
+  // The following covers non-"" vs non-"".
+
+  // Same length and equal.
+  EXPECT_EQ(0, String("a").Compare(String("a")));
+
+  // Same length and different.
+  EXPECT_EQ(-1, String("a\0b", 3).Compare(String("a\0c", 3)));
+  EXPECT_EQ(1, String("b").Compare(String("a")));
+
+  // Different lengths.
+  EXPECT_EQ(-1, String("a").Compare(String("ab")));
+  EXPECT_EQ(-1, String("a").Compare(String("a\0", 2)));
+  EXPECT_EQ(1, String("abc").Compare(String("aacd")));
+}
+
+// Tests String::operator==().
+TEST(StringTest, Equals) {
+  const String null(NULL);
+  EXPECT_TRUE(null == NULL);  // NOLINT
+  EXPECT_FALSE(null == "");  // NOLINT
+  EXPECT_FALSE(null == "bar");  // NOLINT
+
+  const String empty("");
+  EXPECT_FALSE(empty == NULL);  // NOLINT
+  EXPECT_TRUE(empty == "");  // NOLINT
+  EXPECT_FALSE(empty == "bar");  // NOLINT
+
+  const String foo("foo");
+  EXPECT_FALSE(foo == NULL);  // NOLINT
+  EXPECT_FALSE(foo == "");  // NOLINT
+  EXPECT_FALSE(foo == "bar");  // NOLINT
+  EXPECT_TRUE(foo == "foo");  // NOLINT
+
+  const String bar("x\0y", 3);
+  EXPECT_FALSE(bar == "x");
+}
+
+// Tests String::operator!=().
+TEST(StringTest, NotEquals) {
+  const String null(NULL);
+  EXPECT_FALSE(null != NULL);  // NOLINT
+  EXPECT_TRUE(null != "");  // NOLINT
+  EXPECT_TRUE(null != "bar");  // NOLINT
+
+  const String empty("");
+  EXPECT_TRUE(empty != NULL);  // NOLINT
+  EXPECT_FALSE(empty != "");  // NOLINT
+  EXPECT_TRUE(empty != "bar");  // NOLINT
+
+  const String foo("foo");
+  EXPECT_TRUE(foo != NULL);  // NOLINT
+  EXPECT_TRUE(foo != "");  // NOLINT
+  EXPECT_TRUE(foo != "bar");  // NOLINT
+  EXPECT_FALSE(foo != "foo");  // NOLINT
+
+  const String bar("x\0y", 3);
+  EXPECT_TRUE(bar != "x");
+}
+
+// Tests String::length().
+TEST(StringTest, Length) {
+  EXPECT_EQ(0U, String().length());
+  EXPECT_EQ(0U, String("").length());
+  EXPECT_EQ(2U, String("ab").length());
+  EXPECT_EQ(3U, String("a\0b", 3).length());
+}
+
+// Tests String::EndsWith().
+TEST(StringTest, EndsWith) {
+  EXPECT_TRUE(String("foobar").EndsWith("bar"));
+  EXPECT_TRUE(String("foobar").EndsWith(""));
+  EXPECT_TRUE(String("").EndsWith(""));
+
+  EXPECT_FALSE(String("foobar").EndsWith("foo"));
+  EXPECT_FALSE(String("").EndsWith("foo"));
+}
+
+// Tests String::EndsWithCaseInsensitive().
+TEST(StringTest, EndsWithCaseInsensitive) {
+  EXPECT_TRUE(String("foobar").EndsWithCaseInsensitive("BAR"));
+  EXPECT_TRUE(String("foobaR").EndsWithCaseInsensitive("bar"));
+  EXPECT_TRUE(String("foobar").EndsWithCaseInsensitive(""));
+  EXPECT_TRUE(String("").EndsWithCaseInsensitive(""));
+
+  EXPECT_FALSE(String("Foobar").EndsWithCaseInsensitive("foo"));
+  EXPECT_FALSE(String("foobar").EndsWithCaseInsensitive("Foo"));
+  EXPECT_FALSE(String("").EndsWithCaseInsensitive("foo"));
+}
+
+// C++Builder's preprocessor is buggy; it fails to expand macros that
+// appear in macro parameters after wide char literals.  Provide an alias
+// for NULL as a workaround.
+static const wchar_t* const kNull = NULL;
+
+// Tests String::CaseInsensitiveWideCStringEquals
+TEST(StringTest, CaseInsensitiveWideCStringEquals) {
+  EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(NULL, NULL));
+  EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L""));
+  EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"", kNull));
+  EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(kNull, L"foobar"));
+  EXPECT_FALSE(String::CaseInsensitiveWideCStringEquals(L"foobar", kNull));
+  EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"foobar"));
+  EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"foobar", L"FOOBAR"));
+  EXPECT_TRUE(String::CaseInsensitiveWideCStringEquals(L"FOOBAR", L"foobar"));
+}
+
+// Tests that NULL can be assigned to a String.
+TEST(StringTest, CanBeAssignedNULL) {
+  const String src(NULL);
+  String dest;
+
+  dest = src;
+  EXPECT_STREQ(NULL, dest.c_str());
+}
+
+// Tests that the empty string "" can be assigned to a String.
+TEST(StringTest, CanBeAssignedEmpty) {
+  const String src("");
+  String dest;
+
+  dest = src;
+  EXPECT_STREQ("", dest.c_str());
+}
+
+// Tests that a non-empty string can be assigned to a String.
+TEST(StringTest, CanBeAssignedNonEmpty) {
+  const String src("hello");
+  String dest;
+  dest = src;
+  EXPECT_EQ(5U, dest.length());
+  EXPECT_STREQ("hello", dest.c_str());
+
+  const String src2("x\0y", 3);
+  String dest2;
+  dest2 = src2;
+  EXPECT_EQ(3U, dest2.length());
+  EXPECT_EQ('x', dest2.c_str()[0]);
+  EXPECT_EQ('\0', dest2.c_str()[1]);
+  EXPECT_EQ('y', dest2.c_str()[2]);
+}
+
+// Tests that a String can be assigned to itself.
+TEST(StringTest, CanBeAssignedSelf) {
+  String dest("hello");
+
+  dest = dest;
+  EXPECT_STREQ("hello", dest.c_str());
+}
+
+// Sun Studio < 12 incorrectly rejects this code due to an overloading
+// ambiguity.
+#if !(defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
+// Tests streaming a String.
+TEST(StringTest, Streams) {
+  EXPECT_EQ(StreamableToString(String()), "(null)");
+  EXPECT_EQ(StreamableToString(String("")), "");
+  EXPECT_EQ(StreamableToString(String("a\0b", 3)), "a\\0b");
+}
+#endif
+
+// Tests that String::Format() works.
+TEST(StringTest, FormatWorks) {
+  // Normal case: the format spec is valid, the arguments match the
+  // spec, and the result is < 4095 characters.
+  EXPECT_STREQ("Hello, 42", String::Format("%s, %d", "Hello", 42).c_str());
+
+  // Edge case: the result is 4095 characters.
+  char buffer[4096];
+  const size_t kSize = sizeof(buffer);
+  memset(buffer, 'a', kSize - 1);
+  buffer[kSize - 1] = '\0';
+  EXPECT_STREQ(buffer, String::Format("%s", buffer).c_str());
+
+  // The result needs to be 4096 characters, exceeding Format()'s limit.
+  EXPECT_STREQ("<formatting error or buffer exceeded>",
+               String::Format("x%s", buffer).c_str());
+
+#if GTEST_OS_LINUX
+  // On Linux, invalid format spec should lead to an error message.
+  // In other environment (e.g. MSVC on Windows), String::Format() may
+  // simply ignore a bad format spec, so this assertion is run on
+  // Linux only.
+  EXPECT_STREQ("<formatting error or buffer exceeded>",
+               String::Format("%").c_str());
+#endif
+}
+
+#if GTEST_OS_WINDOWS
+
+// Tests String::ShowWideCString().
+TEST(StringTest, ShowWideCString) {
+  EXPECT_STREQ("(null)",
+               String::ShowWideCString(NULL).c_str());
+  EXPECT_STREQ("", String::ShowWideCString(L"").c_str());
+  EXPECT_STREQ("foo", String::ShowWideCString(L"foo").c_str());
+}
+
+// Tests String::ShowWideCStringQuoted().
+TEST(StringTest, ShowWideCStringQuoted) {
+  EXPECT_STREQ("(null)",
+               String::ShowWideCStringQuoted(NULL).c_str());
+  EXPECT_STREQ("L\"\"",
+               String::ShowWideCStringQuoted(L"").c_str());
+  EXPECT_STREQ("L\"foo\"",
+               String::ShowWideCStringQuoted(L"foo").c_str());
+}
+
+#if GTEST_OS_WINDOWS_MOBILE
+TEST(StringTest, AnsiAndUtf16Null) {
+  EXPECT_EQ(NULL, String::AnsiToUtf16(NULL));
+  EXPECT_EQ(NULL, String::Utf16ToAnsi(NULL));
+}
+
+TEST(StringTest, AnsiAndUtf16ConvertBasic) {
+  const char* ansi = String::Utf16ToAnsi(L"str");
+  EXPECT_STREQ("str", ansi);
+  delete [] ansi;
+  const WCHAR* utf16 = String::AnsiToUtf16("str");
+  EXPECT_EQ(0, wcsncmp(L"str", utf16, 3));
+  delete [] utf16;
+}
+
+TEST(StringTest, AnsiAndUtf16ConvertPathChars) {
+  const char* ansi = String::Utf16ToAnsi(L".:\\ \"*?");
+  EXPECT_STREQ(".:\\ \"*?", ansi);
+  delete [] ansi;
+  const WCHAR* utf16 = String::AnsiToUtf16(".:\\ \"*?");
+  EXPECT_EQ(0, wcsncmp(L".:\\ \"*?", utf16, 3));
+  delete [] utf16;
+}
+#endif  // GTEST_OS_WINDOWS_MOBILE
+
+#endif  // GTEST_OS_WINDOWS
+
+// Tests TestProperty construction.
+TEST(TestPropertyTest, StringValue) {
+  TestProperty property("key", "1");
+  EXPECT_STREQ("key", property.key());
+  EXPECT_STREQ("1", property.value());
+}
+
+// Tests TestProperty replacing a value.
+TEST(TestPropertyTest, ReplaceStringValue) {
+  TestProperty property("key", "1");
+  EXPECT_STREQ("1", property.value());
+  property.SetValue("2");
+  EXPECT_STREQ("2", property.value());
+}
+
+// AddFatalFailure() and AddNonfatalFailure() must be stand-alone
+// functions (i.e. their definitions cannot be inlined at the call
+// sites), or C++Builder won't compile the code.
+static void AddFatalFailure() {
+  FAIL() << "Expected fatal failure.";
+}
+
+static void AddNonfatalFailure() {
+  ADD_FAILURE() << "Expected non-fatal failure.";
+}
+
+class ScopedFakeTestPartResultReporterTest : public Test {
+ public:  // Must be public and not protected due to a bug in g++ 3.4.2.
+  enum FailureMode {
+    FATAL_FAILURE,
+    NONFATAL_FAILURE
+  };
+  static void AddFailure(FailureMode failure) {
+    if (failure == FATAL_FAILURE) {
+      AddFatalFailure();
+    } else {
+      AddNonfatalFailure();
+    }
+  }
+};
+
+// Tests that ScopedFakeTestPartResultReporter intercepts test
+// failures.
+TEST_F(ScopedFakeTestPartResultReporterTest, InterceptsTestFailures) {
+  TestPartResultArray results;
+  {
+    ScopedFakeTestPartResultReporter reporter(
+        ScopedFakeTestPartResultReporter::INTERCEPT_ONLY_CURRENT_THREAD,
+        &results);
+    AddFailure(NONFATAL_FAILURE);
+    AddFailure(FATAL_FAILURE);
+  }
+
+  EXPECT_EQ(2, results.size());
+  EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed());
+  EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed());
+}
+
+TEST_F(ScopedFakeTestPartResultReporterTest, DeprecatedConstructor) {
+  TestPartResultArray results;
+  {
+    // Tests, that the deprecated constructor still works.
+    ScopedFakeTestPartResultReporter reporter(&results);
+    AddFailure(NONFATAL_FAILURE);
+  }
+  EXPECT_EQ(1, results.size());
+}
+
+#if GTEST_IS_THREADSAFE
+
+class ScopedFakeTestPartResultReporterWithThreadsTest
+  : public ScopedFakeTestPartResultReporterTest {
+ protected:
+  static void AddFailureInOtherThread(FailureMode failure) {
+    ThreadWithParam<FailureMode> thread(&AddFailure, failure, NULL);
+    thread.Join();
+  }
+};
+
+TEST_F(ScopedFakeTestPartResultReporterWithThreadsTest,
+       InterceptsTestFailuresInAllThreads) {
+  TestPartResultArray results;
+  {
+    ScopedFakeTestPartResultReporter reporter(
+        ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, &results);
+    AddFailure(NONFATAL_FAILURE);
+    AddFailure(FATAL_FAILURE);
+    AddFailureInOtherThread(NONFATAL_FAILURE);
+    AddFailureInOtherThread(FATAL_FAILURE);
+  }
+
+  EXPECT_EQ(4, results.size());
+  EXPECT_TRUE(results.GetTestPartResult(0).nonfatally_failed());
+  EXPECT_TRUE(results.GetTestPartResult(1).fatally_failed());
+  EXPECT_TRUE(results.GetTestPartResult(2).nonfatally_failed());
+  EXPECT_TRUE(results.GetTestPartResult(3).fatally_failed());
+}
+
+#endif  // GTEST_IS_THREADSAFE
+
+// Tests EXPECT_FATAL_FAILURE{,ON_ALL_THREADS}.  Makes sure that they
+// work even if the failure is generated in a called function rather than
+// the current context.
+
+typedef ScopedFakeTestPartResultReporterTest ExpectFatalFailureTest;
+
+TEST_F(ExpectFatalFailureTest, CatchesFatalFaliure) {
+  EXPECT_FATAL_FAILURE(AddFatalFailure(), "Expected fatal failure.");
+}
+
+TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) {
+  // We have another test below to verify that the macro catches fatal
+  // failures generated on another thread.
+  EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFatalFailure(),
+                                      "Expected fatal failure.");
+}
+
+#ifdef __BORLANDC__
+// Silences warnings: "Condition is always true"
+#pragma option push -w-ccc
+#endif
+
+// Tests that EXPECT_FATAL_FAILURE() can be used in a non-void
+// function even when the statement in it contains ASSERT_*.
+
+int NonVoidFunction() {
+  EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), "");
+  EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), "");
+  return 0;
+}
+
+TEST_F(ExpectFatalFailureTest, CanBeUsedInNonVoidFunction) {
+  NonVoidFunction();
+}
+
+// Tests that EXPECT_FATAL_FAILURE(statement, ...) doesn't abort the
+// current function even though 'statement' generates a fatal failure.
+
+void DoesNotAbortHelper(bool* aborted) {
+  EXPECT_FATAL_FAILURE(ASSERT_TRUE(false), "");
+  EXPECT_FATAL_FAILURE_ON_ALL_THREADS(FAIL(), "");
+
+  *aborted = false;
+}
+
+#ifdef __BORLANDC__
+// Restores warnings after previous "#pragma option push" suppressed them.
+#pragma option pop
+#endif
+
+TEST_F(ExpectFatalFailureTest, DoesNotAbort) {
+  bool aborted = true;
+  DoesNotAbortHelper(&aborted);
+  EXPECT_FALSE(aborted);
+}
+
+// Tests that the EXPECT_FATAL_FAILURE{,_ON_ALL_THREADS} accepts a
+// statement that contains a macro which expands to code containing an
+// unprotected comma.
+
+static int global_var = 0;
+#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++
+
+TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) {
+#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600
+  // ICE's in C++Builder 2007.
+  EXPECT_FATAL_FAILURE({
+    GTEST_USE_UNPROTECTED_COMMA_;
+    AddFatalFailure();
+  }, "");
+#endif
+
+  EXPECT_FATAL_FAILURE_ON_ALL_THREADS({
+    GTEST_USE_UNPROTECTED_COMMA_;
+    AddFatalFailure();
+  }, "");
+}
+
+// Tests EXPECT_NONFATAL_FAILURE{,ON_ALL_THREADS}.
+
+typedef ScopedFakeTestPartResultReporterTest ExpectNonfatalFailureTest;
+
+TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailure) {
+  EXPECT_NONFATAL_FAILURE(AddNonfatalFailure(),
+                          "Expected non-fatal failure.");
+}
+
+TEST_F(ExpectNonfatalFailureTest, CatchesNonfatalFailureOnAllThreads) {
+  // We have another test below to verify that the macro catches
+  // non-fatal failures generated on another thread.
+  EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(AddNonfatalFailure(),
+                                         "Expected non-fatal failure.");
+}
+
+// Tests that the EXPECT_NONFATAL_FAILURE{,_ON_ALL_THREADS} accepts a
+// statement that contains a macro which expands to code containing an
+// unprotected comma.
+TEST_F(ExpectNonfatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) {
+  EXPECT_NONFATAL_FAILURE({
+    GTEST_USE_UNPROTECTED_COMMA_;
+    AddNonfatalFailure();
+  }, "");
+
+  EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS({
+    GTEST_USE_UNPROTECTED_COMMA_;
+    AddNonfatalFailure();
+  }, "");
+}
+
+#if GTEST_IS_THREADSAFE
+
+typedef ScopedFakeTestPartResultReporterWithThreadsTest
+    ExpectFailureWithThreadsTest;
+
+TEST_F(ExpectFailureWithThreadsTest, ExpectFatalFailureOnAllThreads) {
+  EXPECT_FATAL_FAILURE_ON_ALL_THREADS(AddFailureInOtherThread(FATAL_FAILURE),
+                                      "Expected fatal failure.");
+}
+
+TEST_F(ExpectFailureWithThreadsTest, ExpectNonFatalFailureOnAllThreads) {
+  EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(
+      AddFailureInOtherThread(NONFATAL_FAILURE), "Expected non-fatal failure.");
+}
+
+#endif  // GTEST_IS_THREADSAFE
+
+// Tests the TestProperty class.
+
+TEST(TestPropertyTest, ConstructorWorks) {
+  const TestProperty property("key", "value");
+  EXPECT_STREQ("key", property.key());
+  EXPECT_STREQ("value", property.value());
+}
+
+TEST(TestPropertyTest, SetValue) {
+  TestProperty property("key", "value_1");
+  EXPECT_STREQ("key", property.key());
+  property.SetValue("value_2");
+  EXPECT_STREQ("key", property.key());
+  EXPECT_STREQ("value_2", property.value());
+}
+
+// Tests the TestResult class
+
+// The test fixture for testing TestResult.
+class TestResultTest : public Test {
+ protected:
+  typedef std::vector<TestPartResult> TPRVector;
+
+  // We make use of 2 TestPartResult objects,
+  TestPartResult * pr1, * pr2;
+
+  // ... and 3 TestResult objects.
+  TestResult * r0, * r1, * r2;
+
+  virtual void SetUp() {
+    // pr1 is for success.
+    pr1 = new TestPartResult(TestPartResult::kSuccess,
+                             "foo/bar.cc",
+                             10,
+                             "Success!");
+
+    // pr2 is for fatal failure.
+    pr2 = new TestPartResult(TestPartResult::kFatalFailure,
+                             "foo/bar.cc",
+                             -1,  // This line number means "unknown"
+                             "Failure!");
+
+    // Creates the TestResult objects.
+    r0 = new TestResult();
+    r1 = new TestResult();
+    r2 = new TestResult();
+
+    // In order to test TestResult, we need to modify its internal
+    // state, in particular the TestPartResult vector it holds.
+    // test_part_results() returns a const reference to this vector.
+    // We cast it to a non-const object s.t. it can be modified (yes,
+    // this is a hack).
+    TPRVector* results1 = const_cast<TPRVector*>(
+        &TestResultAccessor::test_part_results(*r1));
+    TPRVector* results2 = const_cast<TPRVector*>(
+        &TestResultAccessor::test_part_results(*r2));
+
+    // r0 is an empty TestResult.
+
+    // r1 contains a single SUCCESS TestPartResult.
+    results1->push_back(*pr1);
+
+    // r2 contains a SUCCESS, and a FAILURE.
+    results2->push_back(*pr1);
+    results2->push_back(*pr2);
+  }
+
+  virtual void TearDown() {
+    delete pr1;
+    delete pr2;
+
+    delete r0;
+    delete r1;
+    delete r2;
+  }
+
+  // Helper that compares two two TestPartResults.
+  static void CompareTestPartResult(const TestPartResult& expected,
+                                    const TestPartResult& actual) {
+    EXPECT_EQ(expected.type(), actual.type());
+    EXPECT_STREQ(expected.file_name(), actual.file_name());
+    EXPECT_EQ(expected.line_number(), actual.line_number());
+    EXPECT_STREQ(expected.summary(), actual.summary());
+    EXPECT_STREQ(expected.message(), actual.message());
+    EXPECT_EQ(expected.passed(), actual.passed());
+    EXPECT_EQ(expected.failed(), actual.failed());
+    EXPECT_EQ(expected.nonfatally_failed(), actual.nonfatally_failed());
+    EXPECT_EQ(expected.fatally_failed(), actual.fatally_failed());
+  }
+};
+
+// Tests TestResult::total_part_count().
+TEST_F(TestResultTest, total_part_count) {
+  ASSERT_EQ(0, r0->total_part_count());
+  ASSERT_EQ(1, r1->total_part_count());
+  ASSERT_EQ(2, r2->total_part_count());
+}
+
+// Tests TestResult::Passed().
+TEST_F(TestResultTest, Passed) {
+  ASSERT_TRUE(r0->Passed());
+  ASSERT_TRUE(r1->Passed());
+  ASSERT_FALSE(r2->Passed());
+}
+
+// Tests TestResult::Failed().
+TEST_F(TestResultTest, Failed) {
+  ASSERT_FALSE(r0->Failed());
+  ASSERT_FALSE(r1->Failed());
+  ASSERT_TRUE(r2->Failed());
+}
+
+// Tests TestResult::GetTestPartResult().
+
+typedef TestResultTest TestResultDeathTest;
+
+TEST_F(TestResultDeathTest, GetTestPartResult) {
+  CompareTestPartResult(*pr1, r2->GetTestPartResult(0));
+  CompareTestPartResult(*pr2, r2->GetTestPartResult(1));
+  EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(2), "");
+  EXPECT_DEATH_IF_SUPPORTED(r2->GetTestPartResult(-1), "");
+}
+
+// Tests TestResult has no properties when none are added.
+TEST(TestResultPropertyTest, NoPropertiesFoundWhenNoneAreAdded) {
+  TestResult test_result;
+  ASSERT_EQ(0, test_result.test_property_count());
+}
+
+// Tests TestResult has the expected property when added.
+TEST(TestResultPropertyTest, OnePropertyFoundWhenAdded) {
+  TestResult test_result;
+  TestProperty property("key_1", "1");
+  TestResultAccessor::RecordProperty(&test_result, property);
+  ASSERT_EQ(1, test_result.test_property_count());
+  const TestProperty& actual_property = test_result.GetTestProperty(0);
+  EXPECT_STREQ("key_1", actual_property.key());
+  EXPECT_STREQ("1", actual_property.value());
+}
+
+// Tests TestResult has multiple properties when added.
+TEST(TestResultPropertyTest, MultiplePropertiesFoundWhenAdded) {
+  TestResult test_result;
+  TestProperty property_1("key_1", "1");
+  TestProperty property_2("key_2", "2");
+  TestResultAccessor::RecordProperty(&test_result, property_1);
+  TestResultAccessor::RecordProperty(&test_result, property_2);
+  ASSERT_EQ(2, test_result.test_property_count());
+  const TestProperty& actual_property_1 = test_result.GetTestProperty(0);
+  EXPECT_STREQ("key_1", actual_property_1.key());
+  EXPECT_STREQ("1", actual_property_1.value());
+
+  const TestProperty& actual_property_2 = test_result.GetTestProperty(1);
+  EXPECT_STREQ("key_2", actual_property_2.key());
+  EXPECT_STREQ("2", actual_property_2.value());
+}
+
+// Tests TestResult::RecordProperty() overrides values for duplicate keys.
+TEST(TestResultPropertyTest, OverridesValuesForDuplicateKeys) {
+  TestResult test_result;
+  TestProperty property_1_1("key_1", "1");
+  TestProperty property_2_1("key_2", "2");
+  TestProperty property_1_2("key_1", "12");
+  TestProperty property_2_2("key_2", "22");
+  TestResultAccessor::RecordProperty(&test_result, property_1_1);
+  TestResultAccessor::RecordProperty(&test_result, property_2_1);
+  TestResultAccessor::RecordProperty(&test_result, property_1_2);
+  TestResultAccessor::RecordProperty(&test_result, property_2_2);
+
+  ASSERT_EQ(2, test_result.test_property_count());
+  const TestProperty& actual_property_1 = test_result.GetTestProperty(0);
+  EXPECT_STREQ("key_1", actual_property_1.key());
+  EXPECT_STREQ("12", actual_property_1.value());
+
+  const TestProperty& actual_property_2 = test_result.GetTestProperty(1);
+  EXPECT_STREQ("key_2", actual_property_2.key());
+  EXPECT_STREQ("22", actual_property_2.value());
+}
+
+// Tests TestResult::GetTestProperty().
+TEST(TestResultPropertyDeathTest, GetTestProperty) {
+  TestResult test_result;
+  TestProperty property_1("key_1", "1");
+  TestProperty property_2("key_2", "2");
+  TestProperty property_3("key_3", "3");
+  TestResultAccessor::RecordProperty(&test_result, property_1);
+  TestResultAccessor::RecordProperty(&test_result, property_2);
+  TestResultAccessor::RecordProperty(&test_result, property_3);
+
+  const TestProperty& fetched_property_1 = test_result.GetTestProperty(0);
+  const TestProperty& fetched_property_2 = test_result.GetTestProperty(1);
+  const TestProperty& fetched_property_3 = test_result.GetTestProperty(2);
+
+  EXPECT_STREQ("key_1", fetched_property_1.key());
+  EXPECT_STREQ("1", fetched_property_1.value());
+
+  EXPECT_STREQ("key_2", fetched_property_2.key());
+  EXPECT_STREQ("2", fetched_property_2.value());
+
+  EXPECT_STREQ("key_3", fetched_property_3.key());
+  EXPECT_STREQ("3", fetched_property_3.value());
+
+  EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(3), "");
+  EXPECT_DEATH_IF_SUPPORTED(test_result.GetTestProperty(-1), "");
+}
+
+// When a property using a reserved key is supplied to this function, it tests
+// that a non-fatal failure is added, a fatal failure is not added, and that the
+// property is not recorded.
+void ExpectNonFatalFailureRecordingPropertyWithReservedKey(const char* key) {
+  TestResult test_result;
+  TestProperty property(key, "1");
+  EXPECT_NONFATAL_FAILURE(
+      TestResultAccessor::RecordProperty(&test_result, property),
+      "Reserved key");
+  ASSERT_EQ(0, test_result.test_property_count()) << "Not recorded";
+}
+
+// Attempting to recording a property with the Reserved literal "name"
+// should add a non-fatal failure and the property should not be recorded.
+TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledName) {
+  ExpectNonFatalFailureRecordingPropertyWithReservedKey("name");
+}
+
+// Attempting to recording a property with the Reserved literal "status"
+// should add a non-fatal failure and the property should not be recorded.
+TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledStatus) {
+  ExpectNonFatalFailureRecordingPropertyWithReservedKey("status");
+}
+
+// Attempting to recording a property with the Reserved literal "time"
+// should add a non-fatal failure and the property should not be recorded.
+TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledTime) {
+  ExpectNonFatalFailureRecordingPropertyWithReservedKey("time");
+}
+
+// Attempting to recording a property with the Reserved literal "classname"
+// should add a non-fatal failure and the property should not be recorded.
+TEST(TestResultPropertyTest, AddFailureWhenUsingReservedKeyCalledClassname) {
+  ExpectNonFatalFailureRecordingPropertyWithReservedKey("classname");
+}
+
+// Tests that GTestFlagSaver works on Windows and Mac.
+
+class GTestFlagSaverTest : public Test {
+ protected:
+  // Saves the Google Test flags such that we can restore them later, and
+  // then sets them to their default values.  This will be called
+  // before the first test in this test case is run.
+  static void SetUpTestCase() {
+    saver_ = new GTestFlagSaver;
+
+    GTEST_FLAG(also_run_disabled_tests) = false;
+    GTEST_FLAG(break_on_failure) = false;
+    GTEST_FLAG(catch_exceptions) = false;
+    GTEST_FLAG(death_test_use_fork) = false;
+    GTEST_FLAG(color) = "auto";
+    GTEST_FLAG(filter) = "";
+    GTEST_FLAG(list_tests) = false;
+    GTEST_FLAG(output) = "";
+    GTEST_FLAG(print_time) = true;
+    GTEST_FLAG(random_seed) = 0;
+    GTEST_FLAG(repeat) = 1;
+    GTEST_FLAG(shuffle) = false;
+    GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth;
+    GTEST_FLAG(throw_on_failure) = false;
+  }
+
+  // Restores the Google Test flags that the tests have modified.  This will
+  // be called after the last test in this test case is run.
+  static void TearDownTestCase() {
+    delete saver_;
+    saver_ = NULL;
+  }
+
+  // Verifies that the Google Test flags have their default values, and then
+  // modifies each of them.
+  void VerifyAndModifyFlags() {
+    EXPECT_FALSE(GTEST_FLAG(also_run_disabled_tests));
+    EXPECT_FALSE(GTEST_FLAG(break_on_failure));
+    EXPECT_FALSE(GTEST_FLAG(catch_exceptions));
+    EXPECT_STREQ("auto", GTEST_FLAG(color).c_str());
+    EXPECT_FALSE(GTEST_FLAG(death_test_use_fork));
+    EXPECT_STREQ("", GTEST_FLAG(filter).c_str());
+    EXPECT_FALSE(GTEST_FLAG(list_tests));
+    EXPECT_STREQ("", GTEST_FLAG(output).c_str());
+    EXPECT_TRUE(GTEST_FLAG(print_time));
+    EXPECT_EQ(0, GTEST_FLAG(random_seed));
+    EXPECT_EQ(1, GTEST_FLAG(repeat));
+    EXPECT_FALSE(GTEST_FLAG(shuffle));
+    EXPECT_EQ(kMaxStackTraceDepth, GTEST_FLAG(stack_trace_depth));
+    EXPECT_FALSE(GTEST_FLAG(throw_on_failure));
+
+    GTEST_FLAG(also_run_disabled_tests) = true;
+    GTEST_FLAG(break_on_failure) = true;
+    GTEST_FLAG(catch_exceptions) = true;
+    GTEST_FLAG(color) = "no";
+    GTEST_FLAG(death_test_use_fork) = true;
+    GTEST_FLAG(filter) = "abc";
+    GTEST_FLAG(list_tests) = true;
+    GTEST_FLAG(output) = "xml:foo.xml";
+    GTEST_FLAG(print_time) = false;
+    GTEST_FLAG(random_seed) = 1;
+    GTEST_FLAG(repeat) = 100;
+    GTEST_FLAG(shuffle) = true;
+    GTEST_FLAG(stack_trace_depth) = 1;
+    GTEST_FLAG(throw_on_failure) = true;
+  }
+ private:
+  // For saving Google Test flags during this test case.
+  static GTestFlagSaver* saver_;
+};
+
+GTestFlagSaver* GTestFlagSaverTest::saver_ = NULL;
+
+// Google Test doesn't guarantee the order of tests.  The following two
+// tests are designed to work regardless of their order.
+
+// Modifies the Google Test flags in the test body.
+TEST_F(GTestFlagSaverTest, ModifyGTestFlags) {
+  VerifyAndModifyFlags();
+}
+
+// Verifies that the Google Test flags in the body of the previous test were
+// restored to their original values.
+TEST_F(GTestFlagSaverTest, VerifyGTestFlags) {
+  VerifyAndModifyFlags();
+}
+
+// Sets an environment variable with the given name to the given
+// value.  If the value argument is "", unsets the environment
+// variable.  The caller must ensure that both arguments are not NULL.
+static void SetEnv(const char* name, const char* value) {
+#if GTEST_OS_WINDOWS_MOBILE
+  // Environment variables are not supported on Windows CE.
+  return;
+#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
+  // C++Builder's putenv only stores a pointer to its parameter; we have to
+  // ensure that the string remains valid as long as it might be needed.
+  // We use an std::map to do so.
+  static std::map<String, String*> added_env;
+
+  // Because putenv stores a pointer to the string buffer, we can't delete the
+  // previous string (if present) until after it's replaced.
+  String *prev_env = NULL;
+  if (added_env.find(name) != added_env.end()) {
+    prev_env = added_env[name];
+  }
+  added_env[name] = new String((Message() << name << "=" << value).GetString());
+
+  // The standard signature of putenv accepts a 'char*' argument. Other
+  // implementations, like C++Builder's, accept a 'const char*'.
+  // We cast away the 'const' since that would work for both variants.
+  putenv(const_cast<char*>(added_env[name]->c_str()));
+  delete prev_env;
+#elif GTEST_OS_WINDOWS  // If we are on Windows proper.
+  _putenv((Message() << name << "=" << value).GetString().c_str());
+#else
+  if (*value == '\0') {
+    unsetenv(name);
+  } else {
+    setenv(name, value, 1);
+  }
+#endif  // GTEST_OS_WINDOWS_MOBILE
+}
+
+#if !GTEST_OS_WINDOWS_MOBILE
+// Environment variables are not supported on Windows CE.
+
+using testing::internal::Int32FromGTestEnv;
+
+// Tests Int32FromGTestEnv().
+
+// Tests that Int32FromGTestEnv() returns the default value when the
+// environment variable is not set.
+TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenVariableIsNotSet) {
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "");
+  EXPECT_EQ(10, Int32FromGTestEnv("temp", 10));
+}
+
+// Tests that Int32FromGTestEnv() returns the default value when the
+// environment variable overflows as an Int32.
+TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueOverflows) {
+  printf("(expecting 2 warnings)\n");
+
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12345678987654321");
+  EXPECT_EQ(20, Int32FromGTestEnv("temp", 20));
+
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-12345678987654321");
+  EXPECT_EQ(30, Int32FromGTestEnv("temp", 30));
+}
+
+// Tests that Int32FromGTestEnv() returns the default value when the
+// environment variable does not represent a valid decimal integer.
+TEST(Int32FromGTestEnvTest, ReturnsDefaultWhenValueIsInvalid) {
+  printf("(expecting 2 warnings)\n");
+
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "A1");
+  EXPECT_EQ(40, Int32FromGTestEnv("temp", 40));
+
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "12X");
+  EXPECT_EQ(50, Int32FromGTestEnv("temp", 50));
+}
+
+// Tests that Int32FromGTestEnv() parses and returns the value of the
+// environment variable when it represents a valid decimal integer in
+// the range of an Int32.
+TEST(Int32FromGTestEnvTest, ParsesAndReturnsValidValue) {
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "123");
+  EXPECT_EQ(123, Int32FromGTestEnv("temp", 0));
+
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "TEMP", "-321");
+  EXPECT_EQ(-321, Int32FromGTestEnv("temp", 0));
+}
+#endif  // !GTEST_OS_WINDOWS_MOBILE
+
+// Tests ParseInt32Flag().
+
+// Tests that ParseInt32Flag() returns false and doesn't change the
+// output value when the flag has wrong format
+TEST(ParseInt32FlagTest, ReturnsFalseForInvalidFlag) {
+  Int32 value = 123;
+  EXPECT_FALSE(ParseInt32Flag("--a=100", "b", &value));
+  EXPECT_EQ(123, value);
+
+  EXPECT_FALSE(ParseInt32Flag("a=100", "a", &value));
+  EXPECT_EQ(123, value);
+}
+
+// Tests that ParseInt32Flag() returns false and doesn't change the
+// output value when the flag overflows as an Int32.
+TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueOverflows) {
+  printf("(expecting 2 warnings)\n");
+
+  Int32 value = 123;
+  EXPECT_FALSE(ParseInt32Flag("--abc=12345678987654321", "abc", &value));
+  EXPECT_EQ(123, value);
+
+  EXPECT_FALSE(ParseInt32Flag("--abc=-12345678987654321", "abc", &value));
+  EXPECT_EQ(123, value);
+}
+
+// Tests that ParseInt32Flag() returns false and doesn't change the
+// output value when the flag does not represent a valid decimal
+// integer.
+TEST(ParseInt32FlagTest, ReturnsDefaultWhenValueIsInvalid) {
+  printf("(expecting 2 warnings)\n");
+
+  Int32 value = 123;
+  EXPECT_FALSE(ParseInt32Flag("--abc=A1", "abc", &value));
+  EXPECT_EQ(123, value);
+
+  EXPECT_FALSE(ParseInt32Flag("--abc=12X", "abc", &value));
+  EXPECT_EQ(123, value);
+}
+
+// Tests that ParseInt32Flag() parses the value of the flag and
+// returns true when the flag represents a valid decimal integer in
+// the range of an Int32.
+TEST(ParseInt32FlagTest, ParsesAndReturnsValidValue) {
+  Int32 value = 123;
+  EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=456", "abc", &value));
+  EXPECT_EQ(456, value);
+
+  EXPECT_TRUE(ParseInt32Flag("--" GTEST_FLAG_PREFIX_ "abc=-789",
+                             "abc", &value));
+  EXPECT_EQ(-789, value);
+}
+
+// Tests that Int32FromEnvOrDie() parses the value of the var or
+// returns the correct default.
+// Environment variables are not supported on Windows CE.
+#if !GTEST_OS_WINDOWS_MOBILE
+TEST(Int32FromEnvOrDieTest, ParsesAndReturnsValidValue) {
+  EXPECT_EQ(333, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333));
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "123");
+  EXPECT_EQ(123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333));
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", "-123");
+  EXPECT_EQ(-123, Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "UnsetVar", 333));
+}
+#endif  // !GTEST_OS_WINDOWS_MOBILE
+
+// Tests that Int32FromEnvOrDie() aborts with an error message
+// if the variable is not an Int32.
+TEST(Int32FromEnvOrDieDeathTest, AbortsOnFailure) {
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "xxx");
+  EXPECT_DEATH_IF_SUPPORTED(
+      Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123),
+      ".*");
+}
+
+// Tests that Int32FromEnvOrDie() aborts with an error message
+// if the variable cannot be represnted by an Int32.
+TEST(Int32FromEnvOrDieDeathTest, AbortsOnInt32Overflow) {
+  SetEnv(GTEST_FLAG_PREFIX_UPPER_ "VAR", "1234567891234567891234");
+  EXPECT_DEATH_IF_SUPPORTED(
+      Int32FromEnvOrDie(GTEST_FLAG_PREFIX_UPPER_ "VAR", 123),
+      ".*");
+}
+
+// Tests that ShouldRunTestOnShard() selects all tests
+// where there is 1 shard.
+TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereIsOneShard) {
+  EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 0));
+  EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 1));
+  EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 2));
+  EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 3));
+  EXPECT_TRUE(ShouldRunTestOnShard(1, 0, 4));
+}
+
+class ShouldShardTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    index_var_ = GTEST_FLAG_PREFIX_UPPER_ "INDEX";
+    total_var_ = GTEST_FLAG_PREFIX_UPPER_ "TOTAL";
+  }
+
+  virtual void TearDown() {
+    SetEnv(index_var_, "");
+    SetEnv(total_var_, "");
+  }
+
+  const char* index_var_;
+  const char* total_var_;
+};
+
+// Tests that sharding is disabled if neither of the environment variables
+// are set.
+TEST_F(ShouldShardTest, ReturnsFalseWhenNeitherEnvVarIsSet) {
+  SetEnv(index_var_, "");
+  SetEnv(total_var_, "");
+
+  EXPECT_FALSE(ShouldShard(total_var_, index_var_, false));
+  EXPECT_FALSE(ShouldShard(total_var_, index_var_, true));
+}
+
+// Tests that sharding is not enabled if total_shards  == 1.
+TEST_F(ShouldShardTest, ReturnsFalseWhenTotalShardIsOne) {
+  SetEnv(index_var_, "0");
+  SetEnv(total_var_, "1");
+  EXPECT_FALSE(ShouldShard(total_var_, index_var_, false));
+  EXPECT_FALSE(ShouldShard(total_var_, index_var_, true));
+}
+
+// Tests that sharding is enabled if total_shards > 1 and
+// we are not in a death test subprocess.
+// Environment variables are not supported on Windows CE.
+#if !GTEST_OS_WINDOWS_MOBILE
+TEST_F(ShouldShardTest, WorksWhenShardEnvVarsAreValid) {
+  SetEnv(index_var_, "4");
+  SetEnv(total_var_, "22");
+  EXPECT_TRUE(ShouldShard(total_var_, index_var_, false));
+  EXPECT_FALSE(ShouldShard(total_var_, index_var_, true));
+
+  SetEnv(index_var_, "8");
+  SetEnv(total_var_, "9");
+  EXPECT_TRUE(ShouldShard(total_var_, index_var_, false));
+  EXPECT_FALSE(ShouldShard(total_var_, index_var_, true));
+
+  SetEnv(index_var_, "0");
+  SetEnv(total_var_, "9");
+  EXPECT_TRUE(ShouldShard(total_var_, index_var_, false));
+  EXPECT_FALSE(ShouldShard(total_var_, index_var_, true));
+}
+#endif  // !GTEST_OS_WINDOWS_MOBILE
+
+// Tests that we exit in error if the sharding values are not valid.
+
+typedef ShouldShardTest ShouldShardDeathTest;
+
+TEST_F(ShouldShardDeathTest, AbortsWhenShardingEnvVarsAreInvalid) {
+  SetEnv(index_var_, "4");
+  SetEnv(total_var_, "4");
+  EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*");
+
+  SetEnv(index_var_, "4");
+  SetEnv(total_var_, "-2");
+  EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*");
+
+  SetEnv(index_var_, "5");
+  SetEnv(total_var_, "");
+  EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*");
+
+  SetEnv(index_var_, "");
+  SetEnv(total_var_, "5");
+  EXPECT_DEATH_IF_SUPPORTED(ShouldShard(total_var_, index_var_, false), ".*");
+}
+
+// Tests that ShouldRunTestOnShard is a partition when 5
+// shards are used.
+TEST(ShouldRunTestOnShardTest, IsPartitionWhenThereAreFiveShards) {
+  // Choose an arbitrary number of tests and shards.
+  const int num_tests = 17;
+  const int num_shards = 5;
+
+  // Check partitioning: each test should be on exactly 1 shard.
+  for (int test_id = 0; test_id < num_tests; test_id++) {
+    int prev_selected_shard_index = -1;
+    for (int shard_index = 0; shard_index < num_shards; shard_index++) {
+      if (ShouldRunTestOnShard(num_shards, shard_index, test_id)) {
+        if (prev_selected_shard_index < 0) {
+          prev_selected_shard_index = shard_index;
+        } else {
+          ADD_FAILURE() << "Shard " << prev_selected_shard_index << " and "
+            << shard_index << " are both selected to run test " << test_id;
+        }
+      }
+    }
+  }
+
+  // Check balance: This is not required by the sharding protocol, but is a
+  // desirable property for performance.
+  for (int shard_index = 0; shard_index < num_shards; shard_index++) {
+    int num_tests_on_shard = 0;
+    for (int test_id = 0; test_id < num_tests; test_id++) {
+      num_tests_on_shard +=
+        ShouldRunTestOnShard(num_shards, shard_index, test_id);
+    }
+    EXPECT_GE(num_tests_on_shard, num_tests / num_shards);
+  }
+}
+
+// For the same reason we are not explicitly testing everything in the
+// Test class, there are no separate tests for the following classes
+// (except for some trivial cases):
+//
+//   TestCase, UnitTest, UnitTestResultPrinter.
+//
+// Similarly, there are no separate tests for the following macros:
+//
+//   TEST, TEST_F, RUN_ALL_TESTS
+
+TEST(UnitTestTest, CanGetOriginalWorkingDir) {
+  ASSERT_TRUE(UnitTest::GetInstance()->original_working_dir() != NULL);
+  EXPECT_STRNE(UnitTest::GetInstance()->original_working_dir(), "");
+}
+
+// This group of tests is for predicate assertions (ASSERT_PRED*, etc)
+// of various arities.  They do not attempt to be exhaustive.  Rather,
+// view them as smoke tests that can be easily reviewed and verified.
+// A more complete set of tests for predicate assertions can be found
+// in gtest_pred_impl_unittest.cc.
+
+// First, some predicates and predicate-formatters needed by the tests.
+
+// Returns true iff the argument is an even number.
+bool IsEven(int n) {
+  return (n % 2) == 0;
+}
+
+// A functor that returns true iff the argument is an even number.
+struct IsEvenFunctor {
+  bool operator()(int n) { return IsEven(n); }
+};
+
+// A predicate-formatter function that asserts the argument is an even
+// number.
+AssertionResult AssertIsEven(const char* expr, int n) {
+  if (IsEven(n)) {
+    return AssertionSuccess();
+  }
+
+  Message msg;
+  msg << expr << " evaluates to " << n << ", which is not even.";
+  return AssertionFailure(msg);
+}
+
+// A predicate function that returns AssertionResult for use in
+// EXPECT/ASSERT_TRUE/FALSE.
+AssertionResult ResultIsEven(int n) {
+  if (IsEven(n))
+    return AssertionSuccess() << n << " is even";
+  else
+    return AssertionFailure() << n << " is odd";
+}
+
+// A predicate function that returns AssertionResult but gives no
+// explanation why it succeeds. Needed for testing that
+// EXPECT/ASSERT_FALSE handles such functions correctly.
+AssertionResult ResultIsEvenNoExplanation(int n) {
+  if (IsEven(n))
+    return AssertionSuccess();
+  else
+    return AssertionFailure() << n << " is odd";
+}
+
+// A predicate-formatter functor that asserts the argument is an even
+// number.
+struct AssertIsEvenFunctor {
+  AssertionResult operator()(const char* expr, int n) {
+    return AssertIsEven(expr, n);
+  }
+};
+
+// Returns true iff the sum of the arguments is an even number.
+bool SumIsEven2(int n1, int n2) {
+  return IsEven(n1 + n2);
+}
+
+// A functor that returns true iff the sum of the arguments is an even
+// number.
+struct SumIsEven3Functor {
+  bool operator()(int n1, int n2, int n3) {
+    return IsEven(n1 + n2 + n3);
+  }
+};
+
+// A predicate-formatter function that asserts the sum of the
+// arguments is an even number.
+AssertionResult AssertSumIsEven4(
+    const char* e1, const char* e2, const char* e3, const char* e4,
+    int n1, int n2, int n3, int n4) {
+  const int sum = n1 + n2 + n3 + n4;
+  if (IsEven(sum)) {
+    return AssertionSuccess();
+  }
+
+  Message msg;
+  msg << e1 << " + " << e2 << " + " << e3 << " + " << e4
+      << " (" << n1 << " + " << n2 << " + " << n3 << " + " << n4
+      << ") evaluates to " << sum << ", which is not even.";
+  return AssertionFailure(msg);
+}
+
+// A predicate-formatter functor that asserts the sum of the arguments
+// is an even number.
+struct AssertSumIsEven5Functor {
+  AssertionResult operator()(
+      const char* e1, const char* e2, const char* e3, const char* e4,
+      const char* e5, int n1, int n2, int n3, int n4, int n5) {
+    const int sum = n1 + n2 + n3 + n4 + n5;
+    if (IsEven(sum)) {
+      return AssertionSuccess();
+    }
+
+    Message msg;
+    msg << e1 << " + " << e2 << " + " << e3 << " + " << e4 << " + " << e5
+        << " ("
+        << n1 << " + " << n2 << " + " << n3 << " + " << n4 << " + " << n5
+        << ") evaluates to " << sum << ", which is not even.";
+    return AssertionFailure(msg);
+  }
+};
+
+
+// Tests unary predicate assertions.
+
+// Tests unary predicate assertions that don't use a custom formatter.
+TEST(Pred1Test, WithoutFormat) {
+  // Success cases.
+  EXPECT_PRED1(IsEvenFunctor(), 2) << "This failure is UNEXPECTED!";
+  ASSERT_PRED1(IsEven, 4);
+
+  // Failure cases.
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED1(IsEven, 5) << "This failure is expected.";
+  }, "This failure is expected.");
+  EXPECT_FATAL_FAILURE(ASSERT_PRED1(IsEvenFunctor(), 5),
+                       "evaluates to false");
+}
+
+// Tests unary predicate assertions that use a custom formatter.
+TEST(Pred1Test, WithFormat) {
+  // Success cases.
+  EXPECT_PRED_FORMAT1(AssertIsEven, 2);
+  ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), 4)
+    << "This failure is UNEXPECTED!";
+
+  // Failure cases.
+  const int n = 5;
+  EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT1(AssertIsEvenFunctor(), n),
+                          "n evaluates to 5, which is not even.");
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT1(AssertIsEven, 5) << "This failure is expected.";
+  }, "This failure is expected.");
+}
+
+// Tests that unary predicate assertions evaluates their arguments
+// exactly once.
+TEST(Pred1Test, SingleEvaluationOnFailure) {
+  // A success case.
+  static int n = 0;
+  EXPECT_PRED1(IsEven, n++);
+  EXPECT_EQ(1, n) << "The argument is not evaluated exactly once.";
+
+  // A failure case.
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT1(AssertIsEvenFunctor(), n++)
+        << "This failure is expected.";
+  }, "This failure is expected.");
+  EXPECT_EQ(2, n) << "The argument is not evaluated exactly once.";
+}
+
+
+// Tests predicate assertions whose arity is >= 2.
+
+// Tests predicate assertions that don't use a custom formatter.
+TEST(PredTest, WithoutFormat) {
+  // Success cases.
+  ASSERT_PRED2(SumIsEven2, 2, 4) << "This failure is UNEXPECTED!";
+  EXPECT_PRED3(SumIsEven3Functor(), 4, 6, 8);
+
+  // Failure cases.
+  const int n1 = 1;
+  const int n2 = 2;
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED2(SumIsEven2, n1, n2) << "This failure is expected.";
+  }, "This failure is expected.");
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED3(SumIsEven3Functor(), 1, 2, 4);
+  }, "evaluates to false");
+}
+
+// Tests predicate assertions that use a custom formatter.
+TEST(PredTest, WithFormat) {
+  // Success cases.
+  ASSERT_PRED_FORMAT4(AssertSumIsEven4, 4, 6, 8, 10) <<
+    "This failure is UNEXPECTED!";
+  EXPECT_PRED_FORMAT5(AssertSumIsEven5Functor(), 2, 4, 6, 8, 10);
+
+  // Failure cases.
+  const int n1 = 1;
+  const int n2 = 2;
+  const int n3 = 4;
+  const int n4 = 6;
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT4(AssertSumIsEven4, n1, n2, n3, n4);
+  }, "evaluates to 13, which is not even.");
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(), 1, 2, 4, 6, 8)
+        << "This failure is expected.";
+  }, "This failure is expected.");
+}
+
+// Tests that predicate assertions evaluates their arguments
+// exactly once.
+TEST(PredTest, SingleEvaluationOnFailure) {
+  // A success case.
+  int n1 = 0;
+  int n2 = 0;
+  EXPECT_PRED2(SumIsEven2, n1++, n2++);
+  EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once.";
+  EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once.";
+
+  // Another success case.
+  n1 = n2 = 0;
+  int n3 = 0;
+  int n4 = 0;
+  int n5 = 0;
+  ASSERT_PRED_FORMAT5(AssertSumIsEven5Functor(),
+                      n1++, n2++, n3++, n4++, n5++)
+                        << "This failure is UNEXPECTED!";
+  EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once.";
+  EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once.";
+  EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once.";
+  EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once.";
+  EXPECT_EQ(1, n5) << "Argument 5 is not evaluated exactly once.";
+
+  // A failure case.
+  n1 = n2 = n3 = 0;
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED3(SumIsEven3Functor(), ++n1, n2++, n3++)
+        << "This failure is expected.";
+  }, "This failure is expected.");
+  EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once.";
+  EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once.";
+  EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once.";
+
+  // Another failure case.
+  n1 = n2 = n3 = n4 = 0;
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT4(AssertSumIsEven4, ++n1, n2++, n3++, n4++);
+  }, "evaluates to 1, which is not even.");
+  EXPECT_EQ(1, n1) << "Argument 1 is not evaluated exactly once.";
+  EXPECT_EQ(1, n2) << "Argument 2 is not evaluated exactly once.";
+  EXPECT_EQ(1, n3) << "Argument 3 is not evaluated exactly once.";
+  EXPECT_EQ(1, n4) << "Argument 4 is not evaluated exactly once.";
+}
+
+
+// Some helper functions for testing using overloaded/template
+// functions with ASSERT_PREDn and EXPECT_PREDn.
+
+bool IsPositive(double x) {
+  return x > 0;
+}
+
+template <typename T>
+bool IsNegative(T x) {
+  return x < 0;
+}
+
+template <typename T1, typename T2>
+bool GreaterThan(T1 x1, T2 x2) {
+  return x1 > x2;
+}
+
+// Tests that overloaded functions can be used in *_PRED* as long as
+// their types are explicitly specified.
+TEST(PredicateAssertionTest, AcceptsOverloadedFunction) {
+  // C++Builder requires C-style casts rather than static_cast.
+  EXPECT_PRED1((bool (*)(int))(IsPositive), 5);  // NOLINT
+  ASSERT_PRED1((bool (*)(double))(IsPositive), 6.0);  // NOLINT
+}
+
+// Tests that template functions can be used in *_PRED* as long as
+// their types are explicitly specified.
+TEST(PredicateAssertionTest, AcceptsTemplateFunction) {
+  EXPECT_PRED1(IsNegative<int>, -5);
+  // Makes sure that we can handle templates with more than one
+  // parameter.
+  ASSERT_PRED2((GreaterThan<int, int>), 5, 0);
+}
+
+
+// Some helper functions for testing using overloaded/template
+// functions with ASSERT_PRED_FORMATn and EXPECT_PRED_FORMATn.
+
+AssertionResult IsPositiveFormat(const char* /* expr */, int n) {
+  return n > 0 ? AssertionSuccess() :
+      AssertionFailure(Message() << "Failure");
+}
+
+AssertionResult IsPositiveFormat(const char* /* expr */, double x) {
+  return x > 0 ? AssertionSuccess() :
+      AssertionFailure(Message() << "Failure");
+}
+
+template <typename T>
+AssertionResult IsNegativeFormat(const char* /* expr */, T x) {
+  return x < 0 ? AssertionSuccess() :
+      AssertionFailure(Message() << "Failure");
+}
+
+template <typename T1, typename T2>
+AssertionResult EqualsFormat(const char* /* expr1 */, const char* /* expr2 */,
+                             const T1& x1, const T2& x2) {
+  return x1 == x2 ? AssertionSuccess() :
+      AssertionFailure(Message() << "Failure");
+}
+
+// Tests that overloaded functions can be used in *_PRED_FORMAT*
+// without explicitly specifying their types.
+TEST(PredicateFormatAssertionTest, AcceptsOverloadedFunction) {
+  EXPECT_PRED_FORMAT1(IsPositiveFormat, 5);
+  ASSERT_PRED_FORMAT1(IsPositiveFormat, 6.0);
+}
+
+// Tests that template functions can be used in *_PRED_FORMAT* without
+// explicitly specifying their types.
+TEST(PredicateFormatAssertionTest, AcceptsTemplateFunction) {
+  EXPECT_PRED_FORMAT1(IsNegativeFormat, -5);
+  ASSERT_PRED_FORMAT2(EqualsFormat, 3, 3);
+}
+
+
+// Tests string assertions.
+
+// Tests ASSERT_STREQ with non-NULL arguments.
+TEST(StringAssertionTest, ASSERT_STREQ) {
+  const char * const p1 = "good";
+  ASSERT_STREQ(p1, p1);
+
+  // Let p2 have the same content as p1, but be at a different address.
+  const char p2[] = "good";
+  ASSERT_STREQ(p1, p2);
+
+  EXPECT_FATAL_FAILURE(ASSERT_STREQ("bad", "good"),
+                       "Expected: \"bad\"");
+}
+
+// Tests ASSERT_STREQ with NULL arguments.
+TEST(StringAssertionTest, ASSERT_STREQ_Null) {
+  ASSERT_STREQ(static_cast<const char *>(NULL), NULL);
+  EXPECT_FATAL_FAILURE(ASSERT_STREQ(NULL, "non-null"),
+                       "non-null");
+}
+
+// Tests ASSERT_STREQ with NULL arguments.
+TEST(StringAssertionTest, ASSERT_STREQ_Null2) {
+  EXPECT_FATAL_FAILURE(ASSERT_STREQ("non-null", NULL),
+                       "non-null");
+}
+
+// Tests ASSERT_STRNE.
+TEST(StringAssertionTest, ASSERT_STRNE) {
+  ASSERT_STRNE("hi", "Hi");
+  ASSERT_STRNE("Hi", NULL);
+  ASSERT_STRNE(NULL, "Hi");
+  ASSERT_STRNE("", NULL);
+  ASSERT_STRNE(NULL, "");
+  ASSERT_STRNE("", "Hi");
+  ASSERT_STRNE("Hi", "");
+  EXPECT_FATAL_FAILURE(ASSERT_STRNE("Hi", "Hi"),
+                       "\"Hi\" vs \"Hi\"");
+}
+
+// Tests ASSERT_STRCASEEQ.
+TEST(StringAssertionTest, ASSERT_STRCASEEQ) {
+  ASSERT_STRCASEEQ("hi", "Hi");
+  ASSERT_STRCASEEQ(static_cast<const char *>(NULL), NULL);
+
+  ASSERT_STRCASEEQ("", "");
+  EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("Hi", "hi2"),
+                       "(ignoring case)");
+}
+
+// Tests ASSERT_STRCASENE.
+TEST(StringAssertionTest, ASSERT_STRCASENE) {
+  ASSERT_STRCASENE("hi1", "Hi2");
+  ASSERT_STRCASENE("Hi", NULL);
+  ASSERT_STRCASENE(NULL, "Hi");
+  ASSERT_STRCASENE("", NULL);
+  ASSERT_STRCASENE(NULL, "");
+  ASSERT_STRCASENE("", "Hi");
+  ASSERT_STRCASENE("Hi", "");
+  EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("Hi", "hi"),
+                       "(ignoring case)");
+}
+
+// Tests *_STREQ on wide strings.
+TEST(StringAssertionTest, STREQ_Wide) {
+  // NULL strings.
+  ASSERT_STREQ(static_cast<const wchar_t *>(NULL), NULL);
+
+  // Empty strings.
+  ASSERT_STREQ(L"", L"");
+
+  // Non-null vs NULL.
+  EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"non-null", NULL),
+                          "non-null");
+
+  // Equal strings.
+  EXPECT_STREQ(L"Hi", L"Hi");
+
+  // Unequal strings.
+  EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc", L"Abc"),
+                          "Abc");
+
+  // Strings containing wide characters.
+  EXPECT_NONFATAL_FAILURE(EXPECT_STREQ(L"abc\x8119", L"abc\x8120"),
+                          "abc");
+}
+
+// Tests *_STRNE on wide strings.
+TEST(StringAssertionTest, STRNE_Wide) {
+  // NULL strings.
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_STRNE(static_cast<const wchar_t *>(NULL), NULL);
+  }, "");
+
+  // Empty strings.
+  EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"", L""),
+                          "L\"\"");
+
+  // Non-null vs NULL.
+  ASSERT_STRNE(L"non-null", NULL);
+
+  // Equal strings.
+  EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"Hi", L"Hi"),
+                          "L\"Hi\"");
+
+  // Unequal strings.
+  EXPECT_STRNE(L"abc", L"Abc");
+
+  // Strings containing wide characters.
+  EXPECT_NONFATAL_FAILURE(EXPECT_STRNE(L"abc\x8119", L"abc\x8119"),
+                          "abc");
+}
+
+// Tests for ::testing::IsSubstring().
+
+// Tests that IsSubstring() returns the correct result when the input
+// argument type is const char*.
+TEST(IsSubstringTest, ReturnsCorrectResultForCString) {
+  EXPECT_FALSE(IsSubstring("", "", NULL, "a"));
+  EXPECT_FALSE(IsSubstring("", "", "b", NULL));
+  EXPECT_FALSE(IsSubstring("", "", "needle", "haystack"));
+
+  EXPECT_TRUE(IsSubstring("", "", static_cast<const char*>(NULL), NULL));
+  EXPECT_TRUE(IsSubstring("", "", "needle", "two needles"));
+}
+
+// Tests that IsSubstring() returns the correct result when the input
+// argument type is const wchar_t*.
+TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) {
+  EXPECT_FALSE(IsSubstring("", "", kNull, L"a"));
+  EXPECT_FALSE(IsSubstring("", "", L"b", kNull));
+  EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack"));
+
+  EXPECT_TRUE(IsSubstring("", "", static_cast<const wchar_t*>(NULL), NULL));
+  EXPECT_TRUE(IsSubstring("", "", L"needle", L"two needles"));
+}
+
+// Tests that IsSubstring() generates the correct message when the input
+// argument type is const char*.
+TEST(IsSubstringTest, GeneratesCorrectMessageForCString) {
+  EXPECT_STREQ("Value of: needle_expr\n"
+               "  Actual: \"needle\"\n"
+               "Expected: a substring of haystack_expr\n"
+               "Which is: \"haystack\"",
+               IsSubstring("needle_expr", "haystack_expr",
+                           "needle", "haystack").failure_message());
+}
+
+// Tests that IsSubstring returns the correct result when the input
+// argument type is ::std::string.
+TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) {
+  EXPECT_TRUE(IsSubstring("", "", std::string("hello"), "ahellob"));
+  EXPECT_FALSE(IsSubstring("", "", "hello", std::string("world")));
+}
+
+#if GTEST_HAS_STD_WSTRING
+// Tests that IsSubstring returns the correct result when the input
+// argument type is ::std::wstring.
+TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) {
+  EXPECT_TRUE(IsSubstring("", "", ::std::wstring(L"needle"), L"two needles"));
+  EXPECT_FALSE(IsSubstring("", "", L"needle", ::std::wstring(L"haystack")));
+}
+
+// Tests that IsSubstring() generates the correct message when the input
+// argument type is ::std::wstring.
+TEST(IsSubstringTest, GeneratesCorrectMessageForWstring) {
+  EXPECT_STREQ("Value of: needle_expr\n"
+               "  Actual: L\"needle\"\n"
+               "Expected: a substring of haystack_expr\n"
+               "Which is: L\"haystack\"",
+               IsSubstring(
+                   "needle_expr", "haystack_expr",
+                   ::std::wstring(L"needle"), L"haystack").failure_message());
+}
+
+#endif  // GTEST_HAS_STD_WSTRING
+
+// Tests for ::testing::IsNotSubstring().
+
+// Tests that IsNotSubstring() returns the correct result when the input
+// argument type is const char*.
+TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) {
+  EXPECT_TRUE(IsNotSubstring("", "", "needle", "haystack"));
+  EXPECT_FALSE(IsNotSubstring("", "", "needle", "two needles"));
+}
+
+// Tests that IsNotSubstring() returns the correct result when the input
+// argument type is const wchar_t*.
+TEST(IsNotSubstringTest, ReturnsCorrectResultForWideCString) {
+  EXPECT_TRUE(IsNotSubstring("", "", L"needle", L"haystack"));
+  EXPECT_FALSE(IsNotSubstring("", "", L"needle", L"two needles"));
+}
+
+// Tests that IsNotSubstring() generates the correct message when the input
+// argument type is const wchar_t*.
+TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) {
+  EXPECT_STREQ("Value of: needle_expr\n"
+               "  Actual: L\"needle\"\n"
+               "Expected: not a substring of haystack_expr\n"
+               "Which is: L\"two needles\"",
+               IsNotSubstring(
+                   "needle_expr", "haystack_expr",
+                   L"needle", L"two needles").failure_message());
+}
+
+// Tests that IsNotSubstring returns the correct result when the input
+// argument type is ::std::string.
+TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) {
+  EXPECT_FALSE(IsNotSubstring("", "", std::string("hello"), "ahellob"));
+  EXPECT_TRUE(IsNotSubstring("", "", "hello", std::string("world")));
+}
+
+// Tests that IsNotSubstring() generates the correct message when the input
+// argument type is ::std::string.
+TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) {
+  EXPECT_STREQ("Value of: needle_expr\n"
+               "  Actual: \"needle\"\n"
+               "Expected: not a substring of haystack_expr\n"
+               "Which is: \"two needles\"",
+               IsNotSubstring(
+                   "needle_expr", "haystack_expr",
+                   ::std::string("needle"), "two needles").failure_message());
+}
+
+#if GTEST_HAS_STD_WSTRING
+
+// Tests that IsNotSubstring returns the correct result when the input
+// argument type is ::std::wstring.
+TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) {
+  EXPECT_FALSE(
+      IsNotSubstring("", "", ::std::wstring(L"needle"), L"two needles"));
+  EXPECT_TRUE(IsNotSubstring("", "", L"needle", ::std::wstring(L"haystack")));
+}
+
+#endif  // GTEST_HAS_STD_WSTRING
+
+// Tests floating-point assertions.
+
+template <typename RawType>
+class FloatingPointTest : public Test {
+ protected:
+
+  // Pre-calculated numbers to be used by the tests.
+  struct TestValues {
+    RawType close_to_positive_zero;
+    RawType close_to_negative_zero;
+    RawType further_from_negative_zero;
+
+    RawType close_to_one;
+    RawType further_from_one;
+
+    RawType infinity;
+    RawType close_to_infinity;
+    RawType further_from_infinity;
+
+    RawType nan1;
+    RawType nan2;
+  };
+
+  typedef typename testing::internal::FloatingPoint<RawType> Floating;
+  typedef typename Floating::Bits Bits;
+
+  virtual void SetUp() {
+    const size_t max_ulps = Floating::kMaxUlps;
+
+    // The bits that represent 0.0.
+    const Bits zero_bits = Floating(0).bits();
+
+    // Makes some numbers close to 0.0.
+    values_.close_to_positive_zero = Floating::ReinterpretBits(
+        zero_bits + max_ulps/2);
+    values_.close_to_negative_zero = -Floating::ReinterpretBits(
+        zero_bits + max_ulps - max_ulps/2);
+    values_.further_from_negative_zero = -Floating::ReinterpretBits(
+        zero_bits + max_ulps + 1 - max_ulps/2);
+
+    // The bits that represent 1.0.
+    const Bits one_bits = Floating(1).bits();
+
+    // Makes some numbers close to 1.0.
+    values_.close_to_one = Floating::ReinterpretBits(one_bits + max_ulps);
+    values_.further_from_one = Floating::ReinterpretBits(
+        one_bits + max_ulps + 1);
+
+    // +infinity.
+    values_.infinity = Floating::Infinity();
+
+    // The bits that represent +infinity.
+    const Bits infinity_bits = Floating(values_.infinity).bits();
+
+    // Makes some numbers close to infinity.
+    values_.close_to_infinity = Floating::ReinterpretBits(
+        infinity_bits - max_ulps);
+    values_.further_from_infinity = Floating::ReinterpretBits(
+        infinity_bits - max_ulps - 1);
+
+    // Makes some NAN's.  Sets the most significant bit of the fraction so that
+    // our NaN's are quiet; trying to process a signaling NaN would raise an
+    // exception if our environment enables floating point exceptions.
+    values_.nan1 = Floating::ReinterpretBits(Floating::kExponentBitMask
+        | (static_cast<Bits>(1) << (Floating::kFractionBitCount - 1)) | 1);
+    values_.nan2 = Floating::ReinterpretBits(Floating::kExponentBitMask
+        | (static_cast<Bits>(1) << (Floating::kFractionBitCount - 1)) | 200);
+  }
+
+  void TestSize() {
+    EXPECT_EQ(sizeof(RawType), sizeof(Bits));
+  }
+
+  static TestValues values_;
+};
+
+template <typename RawType>
+typename FloatingPointTest<RawType>::TestValues
+    FloatingPointTest<RawType>::values_;
+
+// Instantiates FloatingPointTest for testing *_FLOAT_EQ.
+typedef FloatingPointTest<float> FloatTest;
+
+// Tests that the size of Float::Bits matches the size of float.
+TEST_F(FloatTest, Size) {
+  TestSize();
+}
+
+// Tests comparing with +0 and -0.
+TEST_F(FloatTest, Zeros) {
+  EXPECT_FLOAT_EQ(0.0, -0.0);
+  EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(-0.0, 1.0),
+                          "1.0");
+  EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.5),
+                       "1.5");
+}
+
+// Tests comparing numbers close to 0.
+//
+// This ensures that *_FLOAT_EQ handles the sign correctly and no
+// overflow occurs when comparing numbers whose absolute value is very
+// small.
+TEST_F(FloatTest, AlmostZeros) {
+  // In C++Builder, names within local classes (such as used by
+  // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
+  // scoping class.  Use a static local alias as a workaround.
+  // We use the assignment syntax since some compilers, like Sun Studio,
+  // don't allow initializing references using construction syntax
+  // (parentheses).
+  static const FloatTest::TestValues& v = this->values_;
+
+  EXPECT_FLOAT_EQ(0.0, v.close_to_positive_zero);
+  EXPECT_FLOAT_EQ(-0.0, v.close_to_negative_zero);
+  EXPECT_FLOAT_EQ(v.close_to_positive_zero, v.close_to_negative_zero);
+
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_FLOAT_EQ(v.close_to_positive_zero,
+                    v.further_from_negative_zero);
+  }, "v.further_from_negative_zero");
+}
+
+// Tests comparing numbers close to each other.
+TEST_F(FloatTest, SmallDiff) {
+  EXPECT_FLOAT_EQ(1.0, values_.close_to_one);
+  EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, values_.further_from_one),
+                          "values_.further_from_one");
+}
+
+// Tests comparing numbers far apart.
+TEST_F(FloatTest, LargeDiff) {
+  EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(2.5, 3.0),
+                          "3.0");
+}
+
+// Tests comparing with infinity.
+//
+// This ensures that no overflow occurs when comparing numbers whose
+// absolute value is very large.
+TEST_F(FloatTest, Infinity) {
+  EXPECT_FLOAT_EQ(values_.infinity, values_.close_to_infinity);
+  EXPECT_FLOAT_EQ(-values_.infinity, -values_.close_to_infinity);
+#if !GTEST_OS_SYMBIAN
+  // Nokia's STLport crashes if we try to output infinity or NaN.
+  EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, -values_.infinity),
+                          "-values_.infinity");
+
+  // This is interesting as the representations of infinity and nan1
+  // are only 1 DLP apart.
+  EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.infinity, values_.nan1),
+                          "values_.nan1");
+#endif  // !GTEST_OS_SYMBIAN
+}
+
+// Tests that comparing with NAN always returns false.
+TEST_F(FloatTest, NaN) {
+#if !GTEST_OS_SYMBIAN
+// Nokia's STLport crashes if we try to output infinity or NaN.
+
+  // In C++Builder, names within local classes (such as used by
+  // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
+  // scoping class.  Use a static local alias as a workaround.
+  // We use the assignment syntax since some compilers, like Sun Studio,
+  // don't allow initializing references using construction syntax
+  // (parentheses).
+  static const FloatTest::TestValues& v = this->values_;
+
+  EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan1),
+                          "v.nan1");
+  EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(v.nan1, v.nan2),
+                          "v.nan2");
+  EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(1.0, v.nan1),
+                          "v.nan1");
+
+  EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(v.nan1, v.infinity),
+                       "v.infinity");
+#endif  // !GTEST_OS_SYMBIAN
+}
+
+// Tests that *_FLOAT_EQ are reflexive.
+TEST_F(FloatTest, Reflexive) {
+  EXPECT_FLOAT_EQ(0.0, 0.0);
+  EXPECT_FLOAT_EQ(1.0, 1.0);
+  ASSERT_FLOAT_EQ(values_.infinity, values_.infinity);
+}
+
+// Tests that *_FLOAT_EQ are commutative.
+TEST_F(FloatTest, Commutative) {
+  // We already tested EXPECT_FLOAT_EQ(1.0, values_.close_to_one).
+  EXPECT_FLOAT_EQ(values_.close_to_one, 1.0);
+
+  // We already tested EXPECT_FLOAT_EQ(1.0, values_.further_from_one).
+  EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(values_.further_from_one, 1.0),
+                          "1.0");
+}
+
+// Tests EXPECT_NEAR.
+TEST_F(FloatTest, EXPECT_NEAR) {
+  EXPECT_NEAR(-1.0f, -1.1f, 0.2f);
+  EXPECT_NEAR(2.0f, 3.0f, 1.0f);
+  EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0f,1.5f, 0.25f),  // NOLINT
+                          "The difference between 1.0f and 1.5f is 0.5, "
+                          "which exceeds 0.25f");
+  // To work around a bug in gcc 2.95.0, there is intentionally no
+  // space after the first comma in the previous line.
+}
+
+// Tests ASSERT_NEAR.
+TEST_F(FloatTest, ASSERT_NEAR) {
+  ASSERT_NEAR(-1.0f, -1.1f, 0.2f);
+  ASSERT_NEAR(2.0f, 3.0f, 1.0f);
+  EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0f,1.5f, 0.25f),  // NOLINT
+                       "The difference between 1.0f and 1.5f is 0.5, "
+                       "which exceeds 0.25f");
+  // To work around a bug in gcc 2.95.0, there is intentionally no
+  // space after the first comma in the previous line.
+}
+
+// Tests the cases where FloatLE() should succeed.
+TEST_F(FloatTest, FloatLESucceeds) {
+  EXPECT_PRED_FORMAT2(FloatLE, 1.0f, 2.0f);  // When val1 < val2,
+  ASSERT_PRED_FORMAT2(FloatLE, 1.0f, 1.0f);  // val1 == val2,
+
+  // or when val1 is greater than, but almost equals to, val2.
+  EXPECT_PRED_FORMAT2(FloatLE, values_.close_to_positive_zero, 0.0f);
+}
+
+// Tests the cases where FloatLE() should fail.
+TEST_F(FloatTest, FloatLEFails) {
+  // When val1 is greater than val2 by a large margin,
+  EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(FloatLE, 2.0f, 1.0f),
+                          "(2.0f) <= (1.0f)");
+
+  // or by a small yet non-negligible margin,
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT2(FloatLE, values_.further_from_one, 1.0f);
+  }, "(values_.further_from_one) <= (1.0f)");
+
+#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__)
+  // Nokia's STLport crashes if we try to output infinity or NaN.
+  // C++Builder gives bad results for ordered comparisons involving NaNs
+  // due to compiler bugs.
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT2(FloatLE, values_.nan1, values_.infinity);
+  }, "(values_.nan1) <= (values_.infinity)");
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT2(FloatLE, -values_.infinity, values_.nan1);
+  }, "(-values_.infinity) <= (values_.nan1)");
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT2(FloatLE, values_.nan1, values_.nan1);
+  }, "(values_.nan1) <= (values_.nan1)");
+#endif  // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__)
+}
+
+// Instantiates FloatingPointTest for testing *_DOUBLE_EQ.
+typedef FloatingPointTest<double> DoubleTest;
+
+// Tests that the size of Double::Bits matches the size of double.
+TEST_F(DoubleTest, Size) {
+  TestSize();
+}
+
+// Tests comparing with +0 and -0.
+TEST_F(DoubleTest, Zeros) {
+  EXPECT_DOUBLE_EQ(0.0, -0.0);
+  EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(-0.0, 1.0),
+                          "1.0");
+  EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(0.0, 1.0),
+                       "1.0");
+}
+
+// Tests comparing numbers close to 0.
+//
+// This ensures that *_DOUBLE_EQ handles the sign correctly and no
+// overflow occurs when comparing numbers whose absolute value is very
+// small.
+TEST_F(DoubleTest, AlmostZeros) {
+  // In C++Builder, names within local classes (such as used by
+  // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
+  // scoping class.  Use a static local alias as a workaround.
+  // We use the assignment syntax since some compilers, like Sun Studio,
+  // don't allow initializing references using construction syntax
+  // (parentheses).
+  static const DoubleTest::TestValues& v = this->values_;
+
+  EXPECT_DOUBLE_EQ(0.0, v.close_to_positive_zero);
+  EXPECT_DOUBLE_EQ(-0.0, v.close_to_negative_zero);
+  EXPECT_DOUBLE_EQ(v.close_to_positive_zero, v.close_to_negative_zero);
+
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_DOUBLE_EQ(v.close_to_positive_zero,
+                     v.further_from_negative_zero);
+  }, "v.further_from_negative_zero");
+}
+
+// Tests comparing numbers close to each other.
+TEST_F(DoubleTest, SmallDiff) {
+  EXPECT_DOUBLE_EQ(1.0, values_.close_to_one);
+  EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, values_.further_from_one),
+                          "values_.further_from_one");
+}
+
+// Tests comparing numbers far apart.
+TEST_F(DoubleTest, LargeDiff) {
+  EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(2.0, 3.0),
+                          "3.0");
+}
+
+// Tests comparing with infinity.
+//
+// This ensures that no overflow occurs when comparing numbers whose
+// absolute value is very large.
+TEST_F(DoubleTest, Infinity) {
+  EXPECT_DOUBLE_EQ(values_.infinity, values_.close_to_infinity);
+  EXPECT_DOUBLE_EQ(-values_.infinity, -values_.close_to_infinity);
+#if !GTEST_OS_SYMBIAN
+  // Nokia's STLport crashes if we try to output infinity or NaN.
+  EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, -values_.infinity),
+                          "-values_.infinity");
+
+  // This is interesting as the representations of infinity_ and nan1_
+  // are only 1 DLP apart.
+  EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.infinity, values_.nan1),
+                          "values_.nan1");
+#endif  // !GTEST_OS_SYMBIAN
+}
+
+// Tests that comparing with NAN always returns false.
+TEST_F(DoubleTest, NaN) {
+#if !GTEST_OS_SYMBIAN
+  // In C++Builder, names within local classes (such as used by
+  // EXPECT_FATAL_FAILURE) cannot be resolved against static members of the
+  // scoping class.  Use a static local alias as a workaround.
+  // We use the assignment syntax since some compilers, like Sun Studio,
+  // don't allow initializing references using construction syntax
+  // (parentheses).
+  static const DoubleTest::TestValues& v = this->values_;
+
+  // Nokia's STLport crashes if we try to output infinity or NaN.
+  EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan1),
+                          "v.nan1");
+  EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(v.nan1, v.nan2), "v.nan2");
+  EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(1.0, v.nan1), "v.nan1");
+  EXPECT_FATAL_FAILURE(ASSERT_DOUBLE_EQ(v.nan1, v.infinity),
+                       "v.infinity");
+#endif  // !GTEST_OS_SYMBIAN
+}
+
+// Tests that *_DOUBLE_EQ are reflexive.
+TEST_F(DoubleTest, Reflexive) {
+  EXPECT_DOUBLE_EQ(0.0, 0.0);
+  EXPECT_DOUBLE_EQ(1.0, 1.0);
+#if !GTEST_OS_SYMBIAN
+  // Nokia's STLport crashes if we try to output infinity or NaN.
+  ASSERT_DOUBLE_EQ(values_.infinity, values_.infinity);
+#endif  // !GTEST_OS_SYMBIAN
+}
+
+// Tests that *_DOUBLE_EQ are commutative.
+TEST_F(DoubleTest, Commutative) {
+  // We already tested EXPECT_DOUBLE_EQ(1.0, values_.close_to_one).
+  EXPECT_DOUBLE_EQ(values_.close_to_one, 1.0);
+
+  // We already tested EXPECT_DOUBLE_EQ(1.0, values_.further_from_one).
+  EXPECT_NONFATAL_FAILURE(EXPECT_DOUBLE_EQ(values_.further_from_one, 1.0),
+                          "1.0");
+}
+
+// Tests EXPECT_NEAR.
+TEST_F(DoubleTest, EXPECT_NEAR) {
+  EXPECT_NEAR(-1.0, -1.1, 0.2);
+  EXPECT_NEAR(2.0, 3.0, 1.0);
+  EXPECT_NONFATAL_FAILURE(EXPECT_NEAR(1.0, 1.5, 0.25),  // NOLINT
+                          "The difference between 1.0 and 1.5 is 0.5, "
+                          "which exceeds 0.25");
+  // To work around a bug in gcc 2.95.0, there is intentionally no
+  // space after the first comma in the previous statement.
+}
+
+// Tests ASSERT_NEAR.
+TEST_F(DoubleTest, ASSERT_NEAR) {
+  ASSERT_NEAR(-1.0, -1.1, 0.2);
+  ASSERT_NEAR(2.0, 3.0, 1.0);
+  EXPECT_FATAL_FAILURE(ASSERT_NEAR(1.0, 1.5, 0.25),  // NOLINT
+                       "The difference between 1.0 and 1.5 is 0.5, "
+                       "which exceeds 0.25");
+  // To work around a bug in gcc 2.95.0, there is intentionally no
+  // space after the first comma in the previous statement.
+}
+
+// Tests the cases where DoubleLE() should succeed.
+TEST_F(DoubleTest, DoubleLESucceeds) {
+  EXPECT_PRED_FORMAT2(DoubleLE, 1.0, 2.0);  // When val1 < val2,
+  ASSERT_PRED_FORMAT2(DoubleLE, 1.0, 1.0);  // val1 == val2,
+
+  // or when val1 is greater than, but almost equals to, val2.
+  EXPECT_PRED_FORMAT2(DoubleLE, values_.close_to_positive_zero, 0.0);
+}
+
+// Tests the cases where DoubleLE() should fail.
+TEST_F(DoubleTest, DoubleLEFails) {
+  // When val1 is greater than val2 by a large margin,
+  EXPECT_NONFATAL_FAILURE(EXPECT_PRED_FORMAT2(DoubleLE, 2.0, 1.0),
+                          "(2.0) <= (1.0)");
+
+  // or by a small yet non-negligible margin,
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT2(DoubleLE, values_.further_from_one, 1.0);
+  }, "(values_.further_from_one) <= (1.0)");
+
+#if !GTEST_OS_SYMBIAN && !defined(__BORLANDC__)
+  // Nokia's STLport crashes if we try to output infinity or NaN.
+  // C++Builder gives bad results for ordered comparisons involving NaNs
+  // due to compiler bugs.
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.infinity);
+  }, "(values_.nan1) <= (values_.infinity)");
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_PRED_FORMAT2(DoubleLE, -values_.infinity, values_.nan1);
+  }, " (-values_.infinity) <= (values_.nan1)");
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_PRED_FORMAT2(DoubleLE, values_.nan1, values_.nan1);
+  }, "(values_.nan1) <= (values_.nan1)");
+#endif  // !GTEST_OS_SYMBIAN && !defined(__BORLANDC__)
+}
+
+
+// Verifies that a test or test case whose name starts with DISABLED_ is
+// not run.
+
+// A test whose name starts with DISABLED_.
+// Should not run.
+TEST(DisabledTest, DISABLED_TestShouldNotRun) {
+  FAIL() << "Unexpected failure: Disabled test should not be run.";
+}
+
+// A test whose name does not start with DISABLED_.
+// Should run.
+TEST(DisabledTest, NotDISABLED_TestShouldRun) {
+  EXPECT_EQ(1, 1);
+}
+
+// A test case whose name starts with DISABLED_.
+// Should not run.
+TEST(DISABLED_TestCase, TestShouldNotRun) {
+  FAIL() << "Unexpected failure: Test in disabled test case should not be run.";
+}
+
+// A test case and test whose names start with DISABLED_.
+// Should not run.
+TEST(DISABLED_TestCase, DISABLED_TestShouldNotRun) {
+  FAIL() << "Unexpected failure: Test in disabled test case should not be run.";
+}
+
+// Check that when all tests in a test case are disabled, SetupTestCase() and
+// TearDownTestCase() are not called.
+class DisabledTestsTest : public Test {
+ protected:
+  static void SetUpTestCase() {
+    FAIL() << "Unexpected failure: All tests disabled in test case. "
+              "SetupTestCase() should not be called.";
+  }
+
+  static void TearDownTestCase() {
+    FAIL() << "Unexpected failure: All tests disabled in test case. "
+              "TearDownTestCase() should not be called.";
+  }
+};
+
+TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_1) {
+  FAIL() << "Unexpected failure: Disabled test should not be run.";
+}
+
+TEST_F(DisabledTestsTest, DISABLED_TestShouldNotRun_2) {
+  FAIL() << "Unexpected failure: Disabled test should not be run.";
+}
+
+// Tests that disabled typed tests aren't run.
+
+#if GTEST_HAS_TYPED_TEST
+
+template <typename T>
+class TypedTest : public Test {
+};
+
+typedef testing::Types<int, double> NumericTypes;
+TYPED_TEST_CASE(TypedTest, NumericTypes);
+
+TYPED_TEST(TypedTest, DISABLED_ShouldNotRun) {
+  FAIL() << "Unexpected failure: Disabled typed test should not run.";
+}
+
+template <typename T>
+class DISABLED_TypedTest : public Test {
+};
+
+TYPED_TEST_CASE(DISABLED_TypedTest, NumericTypes);
+
+TYPED_TEST(DISABLED_TypedTest, ShouldNotRun) {
+  FAIL() << "Unexpected failure: Disabled typed test should not run.";
+}
+
+#endif  // GTEST_HAS_TYPED_TEST
+
+// Tests that disabled type-parameterized tests aren't run.
+
+#if GTEST_HAS_TYPED_TEST_P
+
+template <typename T>
+class TypedTestP : public Test {
+};
+
+TYPED_TEST_CASE_P(TypedTestP);
+
+TYPED_TEST_P(TypedTestP, DISABLED_ShouldNotRun) {
+  FAIL() << "Unexpected failure: "
+         << "Disabled type-parameterized test should not run.";
+}
+
+REGISTER_TYPED_TEST_CASE_P(TypedTestP, DISABLED_ShouldNotRun);
+
+INSTANTIATE_TYPED_TEST_CASE_P(My, TypedTestP, NumericTypes);
+
+template <typename T>
+class DISABLED_TypedTestP : public Test {
+};
+
+TYPED_TEST_CASE_P(DISABLED_TypedTestP);
+
+TYPED_TEST_P(DISABLED_TypedTestP, ShouldNotRun) {
+  FAIL() << "Unexpected failure: "
+         << "Disabled type-parameterized test should not run.";
+}
+
+REGISTER_TYPED_TEST_CASE_P(DISABLED_TypedTestP, ShouldNotRun);
+
+INSTANTIATE_TYPED_TEST_CASE_P(My, DISABLED_TypedTestP, NumericTypes);
+
+#endif  // GTEST_HAS_TYPED_TEST_P
+
+// Tests that assertion macros evaluate their arguments exactly once.
+
+class SingleEvaluationTest : public Test {
+ public:  // Must be public and not protected due to a bug in g++ 3.4.2.
+  // This helper function is needed by the FailedASSERT_STREQ test
+  // below.  It's public to work around C++Builder's bug with scoping local
+  // classes.
+  static void CompareAndIncrementCharPtrs() {
+    ASSERT_STREQ(p1_++, p2_++);
+  }
+
+  // This helper function is needed by the FailedASSERT_NE test below.  It's
+  // public to work around C++Builder's bug with scoping local classes.
+  static void CompareAndIncrementInts() {
+    ASSERT_NE(a_++, b_++);
+  }
+
+ protected:
+  SingleEvaluationTest() {
+    p1_ = s1_;
+    p2_ = s2_;
+    a_ = 0;
+    b_ = 0;
+  }
+
+  static const char* const s1_;
+  static const char* const s2_;
+  static const char* p1_;
+  static const char* p2_;
+
+  static int a_;
+  static int b_;
+};
+
+const char* const SingleEvaluationTest::s1_ = "01234";
+const char* const SingleEvaluationTest::s2_ = "abcde";
+const char* SingleEvaluationTest::p1_;
+const char* SingleEvaluationTest::p2_;
+int SingleEvaluationTest::a_;
+int SingleEvaluationTest::b_;
+
+// Tests that when ASSERT_STREQ fails, it evaluates its arguments
+// exactly once.
+TEST_F(SingleEvaluationTest, FailedASSERT_STREQ) {
+  EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementCharPtrs(),
+                       "p2_++");
+  EXPECT_EQ(s1_ + 1, p1_);
+  EXPECT_EQ(s2_ + 1, p2_);
+}
+
+// Tests that string assertion arguments are evaluated exactly once.
+TEST_F(SingleEvaluationTest, ASSERT_STR) {
+  // successful EXPECT_STRNE
+  EXPECT_STRNE(p1_++, p2_++);
+  EXPECT_EQ(s1_ + 1, p1_);
+  EXPECT_EQ(s2_ + 1, p2_);
+
+  // failed EXPECT_STRCASEEQ
+  EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ(p1_++, p2_++),
+                          "ignoring case");
+  EXPECT_EQ(s1_ + 2, p1_);
+  EXPECT_EQ(s2_ + 2, p2_);
+}
+
+// Tests that when ASSERT_NE fails, it evaluates its arguments exactly
+// once.
+TEST_F(SingleEvaluationTest, FailedASSERT_NE) {
+  EXPECT_FATAL_FAILURE(SingleEvaluationTest::CompareAndIncrementInts(),
+                       "(a_++) != (b_++)");
+  EXPECT_EQ(1, a_);
+  EXPECT_EQ(1, b_);
+}
+
+// Tests that assertion arguments are evaluated exactly once.
+TEST_F(SingleEvaluationTest, OtherCases) {
+  // successful EXPECT_TRUE
+  EXPECT_TRUE(0 == a_++);  // NOLINT
+  EXPECT_EQ(1, a_);
+
+  // failed EXPECT_TRUE
+  EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(-1 == a_++), "-1 == a_++");
+  EXPECT_EQ(2, a_);
+
+  // successful EXPECT_GT
+  EXPECT_GT(a_++, b_++);
+  EXPECT_EQ(3, a_);
+  EXPECT_EQ(1, b_);
+
+  // failed EXPECT_LT
+  EXPECT_NONFATAL_FAILURE(EXPECT_LT(a_++, b_++), "(a_++) < (b_++)");
+  EXPECT_EQ(4, a_);
+  EXPECT_EQ(2, b_);
+
+  // successful ASSERT_TRUE
+  ASSERT_TRUE(0 < a_++);  // NOLINT
+  EXPECT_EQ(5, a_);
+
+  // successful ASSERT_GT
+  ASSERT_GT(a_++, b_++);
+  EXPECT_EQ(6, a_);
+  EXPECT_EQ(3, b_);
+}
+
+#if GTEST_HAS_EXCEPTIONS
+
+void ThrowAnInteger() {
+  throw 1;
+}
+
+// Tests that assertion arguments are evaluated exactly once.
+TEST_F(SingleEvaluationTest, ExceptionTests) {
+  // successful EXPECT_THROW
+  EXPECT_THROW({  // NOLINT
+    a_++;
+    ThrowAnInteger();
+  }, int);
+  EXPECT_EQ(1, a_);
+
+  // failed EXPECT_THROW, throws different
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW({  // NOLINT
+    a_++;
+    ThrowAnInteger();
+  }, bool), "throws a different type");
+  EXPECT_EQ(2, a_);
+
+  // failed EXPECT_THROW, throws nothing
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW(a_++, bool), "throws nothing");
+  EXPECT_EQ(3, a_);
+
+  // successful EXPECT_NO_THROW
+  EXPECT_NO_THROW(a_++);
+  EXPECT_EQ(4, a_);
+
+  // failed EXPECT_NO_THROW
+  EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW({  // NOLINT
+    a_++;
+    ThrowAnInteger();
+  }), "it throws");
+  EXPECT_EQ(5, a_);
+
+  // successful EXPECT_ANY_THROW
+  EXPECT_ANY_THROW({  // NOLINT
+    a_++;
+    ThrowAnInteger();
+  });
+  EXPECT_EQ(6, a_);
+
+  // failed EXPECT_ANY_THROW
+  EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(a_++), "it doesn't");
+  EXPECT_EQ(7, a_);
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
+// Tests {ASSERT|EXPECT}_NO_FATAL_FAILURE.
+class NoFatalFailureTest : public Test {
+ protected:
+  void Succeeds() {}
+  void FailsNonFatal() {
+    ADD_FAILURE() << "some non-fatal failure";
+  }
+  void Fails() {
+    FAIL() << "some fatal failure";
+  }
+
+  void DoAssertNoFatalFailureOnFails() {
+    ASSERT_NO_FATAL_FAILURE(Fails());
+    ADD_FAILURE() << "shold not reach here.";
+  }
+
+  void DoExpectNoFatalFailureOnFails() {
+    EXPECT_NO_FATAL_FAILURE(Fails());
+    ADD_FAILURE() << "other failure";
+  }
+};
+
+TEST_F(NoFatalFailureTest, NoFailure) {
+  EXPECT_NO_FATAL_FAILURE(Succeeds());
+  ASSERT_NO_FATAL_FAILURE(Succeeds());
+}
+
+TEST_F(NoFatalFailureTest, NonFatalIsNoFailure) {
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_NO_FATAL_FAILURE(FailsNonFatal()),
+      "some non-fatal failure");
+  EXPECT_NONFATAL_FAILURE(
+      ASSERT_NO_FATAL_FAILURE(FailsNonFatal()),
+      "some non-fatal failure");
+}
+
+TEST_F(NoFatalFailureTest, AssertNoFatalFailureOnFatalFailure) {
+  TestPartResultArray gtest_failures;
+  {
+    ScopedFakeTestPartResultReporter gtest_reporter(&gtest_failures);
+    DoAssertNoFatalFailureOnFails();
+  }
+  ASSERT_EQ(2, gtest_failures.size());
+  EXPECT_EQ(TestPartResult::kFatalFailure,
+            gtest_failures.GetTestPartResult(0).type());
+  EXPECT_EQ(TestPartResult::kFatalFailure,
+            gtest_failures.GetTestPartResult(1).type());
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure",
+                      gtest_failures.GetTestPartResult(0).message());
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does",
+                      gtest_failures.GetTestPartResult(1).message());
+}
+
+TEST_F(NoFatalFailureTest, ExpectNoFatalFailureOnFatalFailure) {
+  TestPartResultArray gtest_failures;
+  {
+    ScopedFakeTestPartResultReporter gtest_reporter(&gtest_failures);
+    DoExpectNoFatalFailureOnFails();
+  }
+  ASSERT_EQ(3, gtest_failures.size());
+  EXPECT_EQ(TestPartResult::kFatalFailure,
+            gtest_failures.GetTestPartResult(0).type());
+  EXPECT_EQ(TestPartResult::kNonFatalFailure,
+            gtest_failures.GetTestPartResult(1).type());
+  EXPECT_EQ(TestPartResult::kNonFatalFailure,
+            gtest_failures.GetTestPartResult(2).type());
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, "some fatal failure",
+                      gtest_failures.GetTestPartResult(0).message());
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, "it does",
+                      gtest_failures.GetTestPartResult(1).message());
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, "other failure",
+                      gtest_failures.GetTestPartResult(2).message());
+}
+
+TEST_F(NoFatalFailureTest, MessageIsStreamable) {
+  TestPartResultArray gtest_failures;
+  {
+    ScopedFakeTestPartResultReporter gtest_reporter(&gtest_failures);
+    EXPECT_NO_FATAL_FAILURE(FAIL() << "foo") << "my message";
+  }
+  ASSERT_EQ(2, gtest_failures.size());
+  EXPECT_EQ(TestPartResult::kNonFatalFailure,
+            gtest_failures.GetTestPartResult(0).type());
+  EXPECT_EQ(TestPartResult::kNonFatalFailure,
+            gtest_failures.GetTestPartResult(1).type());
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, "foo",
+                      gtest_failures.GetTestPartResult(0).message());
+  EXPECT_PRED_FORMAT2(testing::IsSubstring, "my message",
+                      gtest_failures.GetTestPartResult(1).message());
+}
+
+// Tests non-string assertions.
+
+// Tests EqFailure(), used for implementing *EQ* assertions.
+TEST(AssertionTest, EqFailure) {
+  const String foo_val("5"), bar_val("6");
+  const String msg1(
+      EqFailure("foo", "bar", foo_val, bar_val, false)
+      .failure_message());
+  EXPECT_STREQ(
+      "Value of: bar\n"
+      "  Actual: 6\n"
+      "Expected: foo\n"
+      "Which is: 5",
+      msg1.c_str());
+
+  const String msg2(
+      EqFailure("foo", "6", foo_val, bar_val, false)
+      .failure_message());
+  EXPECT_STREQ(
+      "Value of: 6\n"
+      "Expected: foo\n"
+      "Which is: 5",
+      msg2.c_str());
+
+  const String msg3(
+      EqFailure("5", "bar", foo_val, bar_val, false)
+      .failure_message());
+  EXPECT_STREQ(
+      "Value of: bar\n"
+      "  Actual: 6\n"
+      "Expected: 5",
+      msg3.c_str());
+
+  const String msg4(
+      EqFailure("5", "6", foo_val, bar_val, false).failure_message());
+  EXPECT_STREQ(
+      "Value of: 6\n"
+      "Expected: 5",
+      msg4.c_str());
+
+  const String msg5(
+      EqFailure("foo", "bar",
+                String("\"x\""), String("\"y\""),
+                true).failure_message());
+  EXPECT_STREQ(
+      "Value of: bar\n"
+      "  Actual: \"y\"\n"
+      "Expected: foo (ignoring case)\n"
+      "Which is: \"x\"",
+      msg5.c_str());
+}
+
+// Tests AppendUserMessage(), used for implementing the *EQ* macros.
+TEST(AssertionTest, AppendUserMessage) {
+  const String foo("foo");
+
+  Message msg;
+  EXPECT_STREQ("foo",
+               AppendUserMessage(foo, msg).c_str());
+
+  msg << "bar";
+  EXPECT_STREQ("foo\nbar",
+               AppendUserMessage(foo, msg).c_str());
+}
+
+#ifdef __BORLANDC__
+// Silences warnings: "Condition is always true", "Unreachable code"
+#pragma option push -w-ccc -w-rch
+#endif
+
+// Tests ASSERT_TRUE.
+TEST(AssertionTest, ASSERT_TRUE) {
+  ASSERT_TRUE(2 > 1);  // NOLINT
+  EXPECT_FATAL_FAILURE(ASSERT_TRUE(2 < 1),
+                       "2 < 1");
+}
+
+// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult.
+TEST(AssertionTest, AssertTrueWithAssertionResult) {
+  ASSERT_TRUE(ResultIsEven(2));
+#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600
+  // ICE's in C++Builder 2007.
+  EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)),
+                       "Value of: ResultIsEven(3)\n"
+                       "  Actual: false (3 is odd)\n"
+                       "Expected: true");
+#endif
+  ASSERT_TRUE(ResultIsEvenNoExplanation(2));
+  EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)),
+                       "Value of: ResultIsEvenNoExplanation(3)\n"
+                       "  Actual: false (3 is odd)\n"
+                       "Expected: true");
+}
+
+// Tests ASSERT_FALSE.
+TEST(AssertionTest, ASSERT_FALSE) {
+  ASSERT_FALSE(2 < 1);  // NOLINT
+  EXPECT_FATAL_FAILURE(ASSERT_FALSE(2 > 1),
+                       "Value of: 2 > 1\n"
+                       "  Actual: true\n"
+                       "Expected: false");
+}
+
+// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult.
+TEST(AssertionTest, AssertFalseWithAssertionResult) {
+  ASSERT_FALSE(ResultIsEven(3));
+#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600
+  // ICE's in C++Builder 2007.
+  EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)),
+                       "Value of: ResultIsEven(2)\n"
+                       "  Actual: true (2 is even)\n"
+                       "Expected: false");
+#endif
+  ASSERT_FALSE(ResultIsEvenNoExplanation(3));
+  EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)),
+                       "Value of: ResultIsEvenNoExplanation(2)\n"
+                       "  Actual: true\n"
+                       "Expected: false");
+}
+
+#ifdef __BORLANDC__
+// Restores warnings after previous "#pragma option push" supressed them
+#pragma option pop
+#endif
+
+// Tests using ASSERT_EQ on double values.  The purpose is to make
+// sure that the specialization we did for integer and anonymous enums
+// isn't used for double arguments.
+TEST(ExpectTest, ASSERT_EQ_Double) {
+  // A success.
+  ASSERT_EQ(5.6, 5.6);
+
+  // A failure.
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(5.1, 5.2),
+                       "5.1");
+}
+
+// Tests ASSERT_EQ.
+TEST(AssertionTest, ASSERT_EQ) {
+  ASSERT_EQ(5, 2 + 3);
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(5, 2*3),
+                       "Value of: 2*3\n"
+                       "  Actual: 6\n"
+                       "Expected: 5");
+}
+
+// Tests ASSERT_EQ(NULL, pointer).
+#if GTEST_CAN_COMPARE_NULL
+TEST(AssertionTest, ASSERT_EQ_NULL) {
+  // A success.
+  const char* p = NULL;
+  // Some older GCC versions may issue a spurious waring in this or the next
+  // assertion statement. This warning should not be suppressed with
+  // static_cast since the test verifies the ability to use bare NULL as the
+  // expected parameter to the macro.
+  ASSERT_EQ(NULL, p);
+
+  // A failure.
+  static int n = 0;
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(NULL, &n),
+                       "Value of: &n\n");
+}
+#endif  // GTEST_CAN_COMPARE_NULL
+
+// Tests ASSERT_EQ(0, non_pointer).  Since the literal 0 can be
+// treated as a null pointer by the compiler, we need to make sure
+// that ASSERT_EQ(0, non_pointer) isn't interpreted by Google Test as
+// ASSERT_EQ(static_cast<void*>(NULL), non_pointer).
+TEST(ExpectTest, ASSERT_EQ_0) {
+  int n = 0;
+
+  // A success.
+  ASSERT_EQ(0, n);
+
+  // A failure.
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(0, 5.6),
+                       "Expected: 0");
+}
+
+// Tests ASSERT_NE.
+TEST(AssertionTest, ASSERT_NE) {
+  ASSERT_NE(6, 7);
+  EXPECT_FATAL_FAILURE(ASSERT_NE('a', 'a'),
+                       "Expected: ('a') != ('a'), "
+                       "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)");
+}
+
+// Tests ASSERT_LE.
+TEST(AssertionTest, ASSERT_LE) {
+  ASSERT_LE(2, 3);
+  ASSERT_LE(2, 2);
+  EXPECT_FATAL_FAILURE(ASSERT_LE(2, 0),
+                       "Expected: (2) <= (0), actual: 2 vs 0");
+}
+
+// Tests ASSERT_LT.
+TEST(AssertionTest, ASSERT_LT) {
+  ASSERT_LT(2, 3);
+  EXPECT_FATAL_FAILURE(ASSERT_LT(2, 2),
+                       "Expected: (2) < (2), actual: 2 vs 2");
+}
+
+// Tests ASSERT_GE.
+TEST(AssertionTest, ASSERT_GE) {
+  ASSERT_GE(2, 1);
+  ASSERT_GE(2, 2);
+  EXPECT_FATAL_FAILURE(ASSERT_GE(2, 3),
+                       "Expected: (2) >= (3), actual: 2 vs 3");
+}
+
+// Tests ASSERT_GT.
+TEST(AssertionTest, ASSERT_GT) {
+  ASSERT_GT(2, 1);
+  EXPECT_FATAL_FAILURE(ASSERT_GT(2, 2),
+                       "Expected: (2) > (2), actual: 2 vs 2");
+}
+
+#if GTEST_HAS_EXCEPTIONS
+
+void ThrowNothing() {}
+
+// Tests ASSERT_THROW.
+TEST(AssertionTest, ASSERT_THROW) {
+  ASSERT_THROW(ThrowAnInteger(), int);
+
+#ifndef __BORLANDC__
+  // ICE's in C++Builder 2007 and 2009.
+  EXPECT_FATAL_FAILURE(
+      ASSERT_THROW(ThrowAnInteger(), bool),
+      "Expected: ThrowAnInteger() throws an exception of type bool.\n"
+      "  Actual: it throws a different type.");
+#endif
+
+  EXPECT_FATAL_FAILURE(
+      ASSERT_THROW(ThrowNothing(), bool),
+      "Expected: ThrowNothing() throws an exception of type bool.\n"
+      "  Actual: it throws nothing.");
+}
+
+// Tests ASSERT_NO_THROW.
+TEST(AssertionTest, ASSERT_NO_THROW) {
+  ASSERT_NO_THROW(ThrowNothing());
+  EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()),
+                       "Expected: ThrowAnInteger() doesn't throw an exception."
+                       "\n  Actual: it throws.");
+}
+
+// Tests ASSERT_ANY_THROW.
+TEST(AssertionTest, ASSERT_ANY_THROW) {
+  ASSERT_ANY_THROW(ThrowAnInteger());
+  EXPECT_FATAL_FAILURE(
+      ASSERT_ANY_THROW(ThrowNothing()),
+      "Expected: ThrowNothing() throws an exception.\n"
+      "  Actual: it doesn't.");
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
+// Makes sure we deal with the precedence of <<.  This test should
+// compile.
+TEST(AssertionTest, AssertPrecedence) {
+  ASSERT_EQ(1 < 2, true);
+  ASSERT_EQ(true && false, false);
+}
+
+// A subroutine used by the following test.
+void TestEq1(int x) {
+  ASSERT_EQ(1, x);
+}
+
+// Tests calling a test subroutine that's not part of a fixture.
+TEST(AssertionTest, NonFixtureSubroutine) {
+  EXPECT_FATAL_FAILURE(TestEq1(2),
+                       "Value of: x");
+}
+
+// An uncopyable class.
+class Uncopyable {
+ public:
+  explicit Uncopyable(int a_value) : value_(a_value) {}
+
+  int value() const { return value_; }
+  bool operator==(const Uncopyable& rhs) const {
+    return value() == rhs.value();
+  }
+ private:
+  // This constructor deliberately has no implementation, as we don't
+  // want this class to be copyable.
+  Uncopyable(const Uncopyable&);  // NOLINT
+
+  int value_;
+};
+
+::std::ostream& operator<<(::std::ostream& os, const Uncopyable& value) {
+  return os << value.value();
+}
+
+
+bool IsPositiveUncopyable(const Uncopyable& x) {
+  return x.value() > 0;
+}
+
+// A subroutine used by the following test.
+void TestAssertNonPositive() {
+  Uncopyable y(-1);
+  ASSERT_PRED1(IsPositiveUncopyable, y);
+}
+// A subroutine used by the following test.
+void TestAssertEqualsUncopyable() {
+  Uncopyable x(5);
+  Uncopyable y(-1);
+  ASSERT_EQ(x, y);
+}
+
+// Tests that uncopyable objects can be used in assertions.
+TEST(AssertionTest, AssertWorksWithUncopyableObject) {
+  Uncopyable x(5);
+  ASSERT_PRED1(IsPositiveUncopyable, x);
+  ASSERT_EQ(x, x);
+  EXPECT_FATAL_FAILURE(TestAssertNonPositive(),
+    "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1");
+  EXPECT_FATAL_FAILURE(TestAssertEqualsUncopyable(),
+    "Value of: y\n  Actual: -1\nExpected: x\nWhich is: 5");
+}
+
+// Tests that uncopyable objects can be used in expects.
+TEST(AssertionTest, ExpectWorksWithUncopyableObject) {
+  Uncopyable x(5);
+  EXPECT_PRED1(IsPositiveUncopyable, x);
+  Uncopyable y(-1);
+  EXPECT_NONFATAL_FAILURE(EXPECT_PRED1(IsPositiveUncopyable, y),
+    "IsPositiveUncopyable(y) evaluates to false, where\ny evaluates to -1");
+  EXPECT_EQ(x, x);
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(x, y),
+    "Value of: y\n  Actual: -1\nExpected: x\nWhich is: 5");
+}
+
+
+// The version of gcc used in XCode 2.2 has a bug and doesn't allow
+// anonymous enums in assertions.  Therefore the following test is not
+// done on Mac.
+// Sun Studio also rejects this code.
+#if !GTEST_OS_MAC && !defined(__SUNPRO_CC)
+
+// Tests using assertions with anonymous enums.
+enum {
+  CASE_A = -1,
+#if GTEST_OS_LINUX
+  // We want to test the case where the size of the anonymous enum is
+  // larger than sizeof(int), to make sure our implementation of the
+  // assertions doesn't truncate the enums.  However, MSVC
+  // (incorrectly) doesn't allow an enum value to exceed the range of
+  // an int, so this has to be conditionally compiled.
+  //
+  // On Linux, CASE_B and CASE_A have the same value when truncated to
+  // int size.  We want to test whether this will confuse the
+  // assertions.
+  CASE_B = testing::internal::kMaxBiggestInt,
+#else
+  CASE_B = INT_MAX,
+#endif  // GTEST_OS_LINUX
+};
+
+TEST(AssertionTest, AnonymousEnum) {
+#if GTEST_OS_LINUX
+  EXPECT_EQ(static_cast<int>(CASE_A), static_cast<int>(CASE_B));
+#endif  // GTEST_OS_LINUX
+
+  EXPECT_EQ(CASE_A, CASE_A);
+  EXPECT_NE(CASE_A, CASE_B);
+  EXPECT_LT(CASE_A, CASE_B);
+  EXPECT_LE(CASE_A, CASE_B);
+  EXPECT_GT(CASE_B, CASE_A);
+  EXPECT_GE(CASE_A, CASE_A);
+  EXPECT_NONFATAL_FAILURE(EXPECT_GE(CASE_A, CASE_B),
+                          "(CASE_A) >= (CASE_B)");
+
+  ASSERT_EQ(CASE_A, CASE_A);
+  ASSERT_NE(CASE_A, CASE_B);
+  ASSERT_LT(CASE_A, CASE_B);
+  ASSERT_LE(CASE_A, CASE_B);
+  ASSERT_GT(CASE_B, CASE_A);
+  ASSERT_GE(CASE_A, CASE_A);
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(CASE_A, CASE_B),
+                       "Value of: CASE_B");
+}
+
+#endif  // !GTEST_OS_MAC && !defined(__SUNPRO_CC)
+
+#if GTEST_OS_WINDOWS
+
+static HRESULT UnexpectedHRESULTFailure() {
+  return E_UNEXPECTED;
+}
+
+static HRESULT OkHRESULTSuccess() {
+  return S_OK;
+}
+
+static HRESULT FalseHRESULTSuccess() {
+  return S_FALSE;
+}
+
+// HRESULT assertion tests test both zero and non-zero
+// success codes as well as failure message for each.
+//
+// Windows CE doesn't support message texts.
+TEST(HRESULTAssertionTest, EXPECT_HRESULT_SUCCEEDED) {
+  EXPECT_HRESULT_SUCCEEDED(S_OK);
+  EXPECT_HRESULT_SUCCEEDED(S_FALSE);
+
+  EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()),
+    "Expected: (UnexpectedHRESULTFailure()) succeeds.\n"
+    "  Actual: 0x8000FFFF");
+}
+
+TEST(HRESULTAssertionTest, ASSERT_HRESULT_SUCCEEDED) {
+  ASSERT_HRESULT_SUCCEEDED(S_OK);
+  ASSERT_HRESULT_SUCCEEDED(S_FALSE);
+
+  EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(UnexpectedHRESULTFailure()),
+    "Expected: (UnexpectedHRESULTFailure()) succeeds.\n"
+    "  Actual: 0x8000FFFF");
+}
+
+TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) {
+  EXPECT_HRESULT_FAILED(E_UNEXPECTED);
+
+  EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(OkHRESULTSuccess()),
+    "Expected: (OkHRESULTSuccess()) fails.\n"
+    "  Actual: 0x00000000");
+  EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(FalseHRESULTSuccess()),
+    "Expected: (FalseHRESULTSuccess()) fails.\n"
+    "  Actual: 0x00000001");
+}
+
+TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) {
+  ASSERT_HRESULT_FAILED(E_UNEXPECTED);
+
+#ifndef __BORLANDC__
+  // ICE's in C++Builder 2007 and 2009.
+  EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()),
+    "Expected: (OkHRESULTSuccess()) fails.\n"
+    "  Actual: 0x00000000");
+#endif
+  EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()),
+    "Expected: (FalseHRESULTSuccess()) fails.\n"
+    "  Actual: 0x00000001");
+}
+
+// Tests that streaming to the HRESULT macros works.
+TEST(HRESULTAssertionTest, Streaming) {
+  EXPECT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure";
+  ASSERT_HRESULT_SUCCEEDED(S_OK) << "unexpected failure";
+  EXPECT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure";
+  ASSERT_HRESULT_FAILED(E_UNEXPECTED) << "unexpected failure";
+
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure",
+      "expected failure");
+
+#ifndef __BORLANDC__
+  // ICE's in C++Builder 2007 and 2009.
+  EXPECT_FATAL_FAILURE(
+      ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) << "expected failure",
+      "expected failure");
+#endif
+
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_HRESULT_FAILED(S_OK) << "expected failure",
+      "expected failure");
+
+  EXPECT_FATAL_FAILURE(
+      ASSERT_HRESULT_FAILED(S_OK) << "expected failure",
+      "expected failure");
+}
+
+#endif  // GTEST_OS_WINDOWS
+
+#ifdef __BORLANDC__
+// Silences warnings: "Condition is always true", "Unreachable code"
+#pragma option push -w-ccc -w-rch
+#endif
+
+// Tests that the assertion macros behave like single statements.
+TEST(AssertionSyntaxTest, BasicAssertionsBehavesLikeSingleStatement) {
+  if (AlwaysFalse())
+    ASSERT_TRUE(false) << "This should never be executed; "
+                          "It's a compilation test only.";
+
+  if (AlwaysTrue())
+    EXPECT_FALSE(false);
+  else
+    ;  // NOLINT
+
+  if (AlwaysFalse())
+    ASSERT_LT(1, 3);
+
+  if (AlwaysFalse())
+    ;  // NOLINT
+  else
+    EXPECT_GT(3, 2) << "";
+}
+
+#if GTEST_HAS_EXCEPTIONS
+// Tests that the compiler will not complain about unreachable code in the
+// EXPECT_THROW/EXPECT_ANY_THROW/EXPECT_NO_THROW macros.
+TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) {
+  int n = 0;
+
+  EXPECT_THROW(throw 1, int);
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW(n++, int), "");
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW(throw 1, const char*), "");
+  EXPECT_NO_THROW(n++);
+  EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(throw 1), "");
+  EXPECT_ANY_THROW(throw 1);
+  EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(n++), "");
+}
+
+TEST(AssertionSyntaxTest, ExceptionAssertionsBehavesLikeSingleStatement) {
+  if (AlwaysFalse())
+    EXPECT_THROW(ThrowNothing(), bool);
+
+  if (AlwaysTrue())
+    EXPECT_THROW(ThrowAnInteger(), int);
+  else
+    ;  // NOLINT
+
+  if (AlwaysFalse())
+    EXPECT_NO_THROW(ThrowAnInteger());
+
+  if (AlwaysTrue())
+    EXPECT_NO_THROW(ThrowNothing());
+  else
+    ;  // NOLINT
+
+  if (AlwaysFalse())
+    EXPECT_ANY_THROW(ThrowNothing());
+
+  if (AlwaysTrue())
+    EXPECT_ANY_THROW(ThrowAnInteger());
+  else
+    ;  // NOLINT
+}
+#endif  // GTEST_HAS_EXCEPTIONS
+
+TEST(AssertionSyntaxTest, NoFatalFailureAssertionsBehavesLikeSingleStatement) {
+  if (AlwaysFalse())
+    EXPECT_NO_FATAL_FAILURE(FAIL()) << "This should never be executed. "
+                                    << "It's a compilation test only.";
+  else
+    ;  // NOLINT
+
+  if (AlwaysFalse())
+    ASSERT_NO_FATAL_FAILURE(FAIL()) << "";
+  else
+    ;  // NOLINT
+
+  if (AlwaysTrue())
+    EXPECT_NO_FATAL_FAILURE(SUCCEED());
+  else
+    ;  // NOLINT
+
+  if (AlwaysFalse())
+    ;  // NOLINT
+  else
+    ASSERT_NO_FATAL_FAILURE(SUCCEED());
+}
+
+// Tests that the assertion macros work well with switch statements.
+TEST(AssertionSyntaxTest, WorksWithSwitch) {
+  switch (0) {
+    case 1:
+      break;
+    default:
+      ASSERT_TRUE(true);
+  }
+
+  switch (0)
+    case 0:
+      EXPECT_FALSE(false) << "EXPECT_FALSE failed in switch case";
+
+  // Binary assertions are implemented using a different code path
+  // than the Boolean assertions.  Hence we test them separately.
+  switch (0) {
+    case 1:
+    default:
+      ASSERT_EQ(1, 1) << "ASSERT_EQ failed in default switch handler";
+  }
+
+  switch (0)
+    case 0:
+      EXPECT_NE(1, 2);
+}
+
+#if GTEST_HAS_EXCEPTIONS
+
+void ThrowAString() {
+    throw "String";
+}
+
+// Test that the exception assertion macros compile and work with const
+// type qualifier.
+TEST(AssertionSyntaxTest, WorksWithConst) {
+    ASSERT_THROW(ThrowAString(), const char*);
+
+    EXPECT_THROW(ThrowAString(), const char*);
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
+}  // namespace
+
+namespace testing {
+
+// Tests that Google Test tracks SUCCEED*.
+TEST(SuccessfulAssertionTest, SUCCEED) {
+  SUCCEED();
+  SUCCEED() << "OK";
+  EXPECT_EQ(2, GetUnitTestImpl()->current_test_result()->total_part_count());
+}
+
+// Tests that Google Test doesn't track successful EXPECT_*.
+TEST(SuccessfulAssertionTest, EXPECT) {
+  EXPECT_TRUE(true);
+  EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count());
+}
+
+// Tests that Google Test doesn't track successful EXPECT_STR*.
+TEST(SuccessfulAssertionTest, EXPECT_STR) {
+  EXPECT_STREQ("", "");
+  EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count());
+}
+
+// Tests that Google Test doesn't track successful ASSERT_*.
+TEST(SuccessfulAssertionTest, ASSERT) {
+  ASSERT_TRUE(true);
+  EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count());
+}
+
+// Tests that Google Test doesn't track successful ASSERT_STR*.
+TEST(SuccessfulAssertionTest, ASSERT_STR) {
+  ASSERT_STREQ("", "");
+  EXPECT_EQ(0, GetUnitTestImpl()->current_test_result()->total_part_count());
+}
+
+}  // namespace testing
+
+namespace {
+
+// Tests EXPECT_TRUE.
+TEST(ExpectTest, EXPECT_TRUE) {
+  EXPECT_TRUE(2 > 1);  // NOLINT
+  EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 < 1),
+                          "Value of: 2 < 1\n"
+                          "  Actual: false\n"
+                          "Expected: true");
+  EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(2 > 3),
+                          "2 > 3");
+}
+
+// Tests EXPECT_TRUE(predicate) for predicates returning AssertionResult.
+TEST(ExpectTest, ExpectTrueWithAssertionResult) {
+  EXPECT_TRUE(ResultIsEven(2));
+  EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEven(3)),
+                          "Value of: ResultIsEven(3)\n"
+                          "  Actual: false (3 is odd)\n"
+                          "Expected: true");
+  EXPECT_TRUE(ResultIsEvenNoExplanation(2));
+  EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(ResultIsEvenNoExplanation(3)),
+                          "Value of: ResultIsEvenNoExplanation(3)\n"
+                          "  Actual: false (3 is odd)\n"
+                          "Expected: true");
+}
+
+// Tests EXPECT_FALSE.
+TEST(ExpectTest, EXPECT_FALSE) {
+  EXPECT_FALSE(2 < 1);  // NOLINT
+  EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 > 1),
+                          "Value of: 2 > 1\n"
+                          "  Actual: true\n"
+                          "Expected: false");
+  EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(2 < 3),
+                          "2 < 3");
+}
+
+// Tests EXPECT_FALSE(predicate) for predicates returning AssertionResult.
+TEST(ExpectTest, ExpectFalseWithAssertionResult) {
+  EXPECT_FALSE(ResultIsEven(3));
+  EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEven(2)),
+                          "Value of: ResultIsEven(2)\n"
+                          "  Actual: true (2 is even)\n"
+                          "Expected: false");
+  EXPECT_FALSE(ResultIsEvenNoExplanation(3));
+  EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(ResultIsEvenNoExplanation(2)),
+                          "Value of: ResultIsEvenNoExplanation(2)\n"
+                          "  Actual: true\n"
+                          "Expected: false");
+}
+
+#ifdef __BORLANDC__
+// Restores warnings after previous "#pragma option push" supressed them
+#pragma option pop
+#endif
+
+// Tests EXPECT_EQ.
+TEST(ExpectTest, EXPECT_EQ) {
+  EXPECT_EQ(5, 2 + 3);
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2*3),
+                          "Value of: 2*3\n"
+                          "  Actual: 6\n"
+                          "Expected: 5");
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5, 2 - 3),
+                          "2 - 3");
+}
+
+// Tests using EXPECT_EQ on double values.  The purpose is to make
+// sure that the specialization we did for integer and anonymous enums
+// isn't used for double arguments.
+TEST(ExpectTest, EXPECT_EQ_Double) {
+  // A success.
+  EXPECT_EQ(5.6, 5.6);
+
+  // A failure.
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(5.1, 5.2),
+                          "5.1");
+}
+
+#if GTEST_CAN_COMPARE_NULL
+// Tests EXPECT_EQ(NULL, pointer).
+TEST(ExpectTest, EXPECT_EQ_NULL) {
+  // A success.
+  const char* p = NULL;
+  // Some older GCC versions may issue a spurious waring in this or the next
+  // assertion statement. This warning should not be suppressed with
+  // static_cast since the test verifies the ability to use bare NULL as the
+  // expected parameter to the macro.
+  EXPECT_EQ(NULL, p);
+
+  // A failure.
+  int n = 0;
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(NULL, &n),
+                          "Value of: &n\n");
+}
+#endif  // GTEST_CAN_COMPARE_NULL
+
+// Tests EXPECT_EQ(0, non_pointer).  Since the literal 0 can be
+// treated as a null pointer by the compiler, we need to make sure
+// that EXPECT_EQ(0, non_pointer) isn't interpreted by Google Test as
+// EXPECT_EQ(static_cast<void*>(NULL), non_pointer).
+TEST(ExpectTest, EXPECT_EQ_0) {
+  int n = 0;
+
+  // A success.
+  EXPECT_EQ(0, n);
+
+  // A failure.
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(0, 5.6),
+                          "Expected: 0");
+}
+
+// Tests EXPECT_NE.
+TEST(ExpectTest, EXPECT_NE) {
+  EXPECT_NE(6, 7);
+
+  EXPECT_NONFATAL_FAILURE(EXPECT_NE('a', 'a'),
+                          "Expected: ('a') != ('a'), "
+                          "actual: 'a' (97, 0x61) vs 'a' (97, 0x61)");
+  EXPECT_NONFATAL_FAILURE(EXPECT_NE(2, 2),
+                          "2");
+  char* const p0 = NULL;
+  EXPECT_NONFATAL_FAILURE(EXPECT_NE(p0, p0),
+                          "p0");
+  // Only way to get the Nokia compiler to compile the cast
+  // is to have a separate void* variable first. Putting
+  // the two casts on the same line doesn't work, neither does
+  // a direct C-style to char*.
+  void* pv1 = (void*)0x1234;  // NOLINT
+  char* const p1 = reinterpret_cast<char*>(pv1);
+  EXPECT_NONFATAL_FAILURE(EXPECT_NE(p1, p1),
+                          "p1");
+}
+
+// Tests EXPECT_LE.
+TEST(ExpectTest, EXPECT_LE) {
+  EXPECT_LE(2, 3);
+  EXPECT_LE(2, 2);
+  EXPECT_NONFATAL_FAILURE(EXPECT_LE(2, 0),
+                          "Expected: (2) <= (0), actual: 2 vs 0");
+  EXPECT_NONFATAL_FAILURE(EXPECT_LE(1.1, 0.9),
+                          "(1.1) <= (0.9)");
+}
+
+// Tests EXPECT_LT.
+TEST(ExpectTest, EXPECT_LT) {
+  EXPECT_LT(2, 3);
+  EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 2),
+                          "Expected: (2) < (2), actual: 2 vs 2");
+  EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1),
+                          "(2) < (1)");
+}
+
+// Tests EXPECT_GE.
+TEST(ExpectTest, EXPECT_GE) {
+  EXPECT_GE(2, 1);
+  EXPECT_GE(2, 2);
+  EXPECT_NONFATAL_FAILURE(EXPECT_GE(2, 3),
+                          "Expected: (2) >= (3), actual: 2 vs 3");
+  EXPECT_NONFATAL_FAILURE(EXPECT_GE(0.9, 1.1),
+                          "(0.9) >= (1.1)");
+}
+
+// Tests EXPECT_GT.
+TEST(ExpectTest, EXPECT_GT) {
+  EXPECT_GT(2, 1);
+  EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 2),
+                          "Expected: (2) > (2), actual: 2 vs 2");
+  EXPECT_NONFATAL_FAILURE(EXPECT_GT(2, 3),
+                          "(2) > (3)");
+}
+
+#if GTEST_HAS_EXCEPTIONS
+
+// Tests EXPECT_THROW.
+TEST(ExpectTest, EXPECT_THROW) {
+  EXPECT_THROW(ThrowAnInteger(), int);
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool),
+                          "Expected: ThrowAnInteger() throws an exception of "
+                          "type bool.\n  Actual: it throws a different type.");
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_THROW(ThrowNothing(), bool),
+      "Expected: ThrowNothing() throws an exception of type bool.\n"
+      "  Actual: it throws nothing.");
+}
+
+// Tests EXPECT_NO_THROW.
+TEST(ExpectTest, EXPECT_NO_THROW) {
+  EXPECT_NO_THROW(ThrowNothing());
+  EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()),
+                          "Expected: ThrowAnInteger() doesn't throw an "
+                          "exception.\n  Actual: it throws.");
+}
+
+// Tests EXPECT_ANY_THROW.
+TEST(ExpectTest, EXPECT_ANY_THROW) {
+  EXPECT_ANY_THROW(ThrowAnInteger());
+  EXPECT_NONFATAL_FAILURE(
+      EXPECT_ANY_THROW(ThrowNothing()),
+      "Expected: ThrowNothing() throws an exception.\n"
+      "  Actual: it doesn't.");
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
+// Make sure we deal with the precedence of <<.
+TEST(ExpectTest, ExpectPrecedence) {
+  EXPECT_EQ(1 < 2, true);
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(true, true && false),
+                          "Value of: true && false");
+}
+
+
+// Tests the StreamableToString() function.
+
+// Tests using StreamableToString() on a scalar.
+TEST(StreamableToStringTest, Scalar) {
+  EXPECT_STREQ("5", StreamableToString(5).c_str());
+}
+
+// Tests using StreamableToString() on a non-char pointer.
+TEST(StreamableToStringTest, Pointer) {
+  int n = 0;
+  int* p = &n;
+  EXPECT_STRNE("(null)", StreamableToString(p).c_str());
+}
+
+// Tests using StreamableToString() on a NULL non-char pointer.
+TEST(StreamableToStringTest, NullPointer) {
+  int* p = NULL;
+  EXPECT_STREQ("(null)", StreamableToString(p).c_str());
+}
+
+// Tests using StreamableToString() on a C string.
+TEST(StreamableToStringTest, CString) {
+  EXPECT_STREQ("Foo", StreamableToString("Foo").c_str());
+}
+
+// Tests using StreamableToString() on a NULL C string.
+TEST(StreamableToStringTest, NullCString) {
+  char* p = NULL;
+  EXPECT_STREQ("(null)", StreamableToString(p).c_str());
+}
+
+// Tests using streamable values as assertion messages.
+
+// Tests using std::string as an assertion message.
+TEST(StreamableTest, string) {
+  static const std::string str(
+      "This failure message is a std::string, and is expected.");
+  EXPECT_FATAL_FAILURE(FAIL() << str,
+                       str.c_str());
+}
+
+// Tests that we can output strings containing embedded NULs.
+// Limited to Linux because we can only do this with std::string's.
+TEST(StreamableTest, stringWithEmbeddedNUL) {
+  static const char char_array_with_nul[] =
+      "Here's a NUL\0 and some more string";
+  static const std::string string_with_nul(char_array_with_nul,
+                                           sizeof(char_array_with_nul)
+                                           - 1);  // drops the trailing NUL
+  EXPECT_FATAL_FAILURE(FAIL() << string_with_nul,
+                       "Here's a NUL\\0 and some more string");
+}
+
+// Tests that we can output a NUL char.
+TEST(StreamableTest, NULChar) {
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    FAIL() << "A NUL" << '\0' << " and some more string";
+  }, "A NUL\\0 and some more string");
+}
+
+// Tests using int as an assertion message.
+TEST(StreamableTest, int) {
+  EXPECT_FATAL_FAILURE(FAIL() << 900913,
+                       "900913");
+}
+
+// Tests using NULL char pointer as an assertion message.
+//
+// In MSVC, streaming a NULL char * causes access violation.  Google Test
+// implemented a workaround (substituting "(null)" for NULL).  This
+// tests whether the workaround works.
+TEST(StreamableTest, NullCharPtr) {
+  EXPECT_FATAL_FAILURE(FAIL() << static_cast<const char*>(NULL),
+                       "(null)");
+}
+
+// Tests that basic IO manipulators (endl, ends, and flush) can be
+// streamed to testing::Message.
+TEST(StreamableTest, BasicIoManip) {
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    FAIL() << "Line 1." << std::endl
+           << "A NUL char " << std::ends << std::flush << " in line 2.";
+  }, "Line 1.\nA NUL char \\0 in line 2.");
+}
+
+// Tests the macros that haven't been covered so far.
+
+void AddFailureHelper(bool* aborted) {
+  *aborted = true;
+  ADD_FAILURE() << "Failure";
+  *aborted = false;
+}
+
+// Tests ADD_FAILURE.
+TEST(MacroTest, ADD_FAILURE) {
+  bool aborted = true;
+  EXPECT_NONFATAL_FAILURE(AddFailureHelper(&aborted),
+                          "Failure");
+  EXPECT_FALSE(aborted);
+}
+
+// Tests FAIL.
+TEST(MacroTest, FAIL) {
+  EXPECT_FATAL_FAILURE(FAIL(),
+                       "Failed");
+  EXPECT_FATAL_FAILURE(FAIL() << "Intentional failure.",
+                       "Intentional failure.");
+}
+
+// Tests SUCCEED
+TEST(MacroTest, SUCCEED) {
+  SUCCEED();
+  SUCCEED() << "Explicit success.";
+}
+
+
+// Tests for EXPECT_EQ() and ASSERT_EQ().
+//
+// These tests fail *intentionally*, s.t. the failure messages can be
+// generated and tested.
+//
+// We have different tests for different argument types.
+
+// Tests using bool values in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, Bool) {
+  EXPECT_EQ(true,  true);
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(false, true),
+                       "Value of: true");
+}
+
+// Tests using int values in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, Int) {
+  ASSERT_EQ(32, 32);
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(32, 33),
+                          "33");
+}
+
+// Tests using time_t values in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, Time_T) {
+  EXPECT_EQ(static_cast<time_t>(0),
+            static_cast<time_t>(0));
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast<time_t>(0),
+                                 static_cast<time_t>(1234)),
+                       "1234");
+}
+
+// Tests using char values in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, Char) {
+  ASSERT_EQ('z', 'z');
+  const char ch = 'b';
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ('\0', ch),
+                          "ch");
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ('a', ch),
+                          "ch");
+}
+
+// Tests using wchar_t values in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, WideChar) {
+  EXPECT_EQ(L'b', L'b');
+
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'\0', L'x'),
+                          "Value of: L'x'\n"
+                          "  Actual: L'x' (120, 0x78)\n"
+                          "Expected: L'\0'\n"
+                          "Which is: L'\0' (0, 0x0)");
+
+  static wchar_t wchar;
+  wchar = L'b';
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(L'a', wchar),
+                          "wchar");
+  wchar = L'\x8119';
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(L'\x8120', wchar),
+                       "Value of: wchar");
+}
+
+// Tests using ::std::string values in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, StdString) {
+  // Compares a const char* to an std::string that has identical
+  // content.
+  ASSERT_EQ("Test", ::std::string("Test"));
+
+  // Compares two identical std::strings.
+  static const ::std::string str1("A * in the middle");
+  static const ::std::string str2(str1);
+  EXPECT_EQ(str1, str2);
+
+  // Compares a const char* to an std::string that has different
+  // content
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ("Test", ::std::string("test")),
+                          "::std::string(\"test\")");
+
+  // Compares an std::string to a char* that has different content.
+  char* const p1 = const_cast<char*>("foo");
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::std::string("bar"), p1),
+                          "p1");
+
+  // Compares two std::strings that have different contents, one of
+  // which having a NUL character in the middle.  This should fail.
+  static ::std::string str3(str1);
+  str3.at(2) = '\0';
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(str1, str3),
+                       "Value of: str3\n"
+                       "  Actual: \"A \\0 in the middle\"");
+}
+
+#if GTEST_HAS_STD_WSTRING
+
+// Tests using ::std::wstring values in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, StdWideString) {
+  // Compares an std::wstring to a const wchar_t* that has identical
+  // content.
+  EXPECT_EQ(::std::wstring(L"Test\x8119"), L"Test\x8119");
+
+  // Compares two identical std::wstrings.
+  const ::std::wstring wstr1(L"A * in the middle");
+  const ::std::wstring wstr2(wstr1);
+  ASSERT_EQ(wstr1, wstr2);
+
+  // Compares an std::wstring to a const wchar_t* that has different
+  // content.
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_EQ(::std::wstring(L"Test\x8119"), L"Test\x8120");
+  }, "L\"Test\\x8120\"");
+
+  // Compares two std::wstrings that have different contents, one of
+  // which having a NUL character in the middle.
+  ::std::wstring wstr3(wstr1);
+  wstr3.at(2) = L'\0';
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(wstr1, wstr3),
+                          "wstr3");
+
+  // Compares a wchar_t* to an std::wstring that has different
+  // content.
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_EQ(const_cast<wchar_t*>(L"foo"), ::std::wstring(L"bar"));
+  }, "");
+}
+
+#endif  // GTEST_HAS_STD_WSTRING
+
+#if GTEST_HAS_GLOBAL_STRING
+// Tests using ::string values in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, GlobalString) {
+  // Compares a const char* to a ::string that has identical content.
+  EXPECT_EQ("Test", ::string("Test"));
+
+  // Compares two identical ::strings.
+  const ::string str1("A * in the middle");
+  const ::string str2(str1);
+  ASSERT_EQ(str1, str2);
+
+  // Compares a ::string to a const char* that has different content.
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(::string("Test"), "test"),
+                          "test");
+
+  // Compares two ::strings that have different contents, one of which
+  // having a NUL character in the middle.
+  ::string str3(str1);
+  str3.at(2) = '\0';
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(str1, str3),
+                          "str3");
+
+  // Compares a ::string to a char* that has different content.
+  EXPECT_FATAL_FAILURE({  // NOLINT
+    ASSERT_EQ(::string("bar"), const_cast<char*>("foo"));
+  }, "");
+}
+
+#endif  // GTEST_HAS_GLOBAL_STRING
+
+#if GTEST_HAS_GLOBAL_WSTRING
+
+// Tests using ::wstring values in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, GlobalWideString) {
+  // Compares a const wchar_t* to a ::wstring that has identical content.
+  ASSERT_EQ(L"Test\x8119", ::wstring(L"Test\x8119"));
+
+  // Compares two identical ::wstrings.
+  static const ::wstring wstr1(L"A * in the middle");
+  static const ::wstring wstr2(wstr1);
+  EXPECT_EQ(wstr1, wstr2);
+
+  // Compares a const wchar_t* to a ::wstring that has different
+  // content.
+  EXPECT_NONFATAL_FAILURE({  // NOLINT
+    EXPECT_EQ(L"Test\x8120", ::wstring(L"Test\x8119"));
+  }, "Test\\x8119");
+
+  // Compares a wchar_t* to a ::wstring that has different content.
+  wchar_t* const p1 = const_cast<wchar_t*>(L"foo");
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, ::wstring(L"bar")),
+                          "bar");
+
+  // Compares two ::wstrings that have different contents, one of which
+  // having a NUL character in the middle.
+  static ::wstring wstr3;
+  wstr3 = wstr1;
+  wstr3.at(2) = L'\0';
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(wstr1, wstr3),
+                       "wstr3");
+}
+
+#endif  // GTEST_HAS_GLOBAL_WSTRING
+
+// Tests using char pointers in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, CharPointer) {
+  char* const p0 = NULL;
+  // Only way to get the Nokia compiler to compile the cast
+  // is to have a separate void* variable first. Putting
+  // the two casts on the same line doesn't work, neither does
+  // a direct C-style to char*.
+  void* pv1 = (void*)0x1234;  // NOLINT
+  void* pv2 = (void*)0xABC0;  // NOLINT
+  char* const p1 = reinterpret_cast<char*>(pv1);
+  char* const p2 = reinterpret_cast<char*>(pv2);
+  ASSERT_EQ(p1, p1);
+
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2),
+                          "Value of: p2");
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2),
+                          "p2");
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(reinterpret_cast<char*>(0x1234),
+                                 reinterpret_cast<char*>(0xABC0)),
+                       "ABC0");
+}
+
+// Tests using wchar_t pointers in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, WideCharPointer) {
+  wchar_t* const p0 = NULL;
+  // Only way to get the Nokia compiler to compile the cast
+  // is to have a separate void* variable first. Putting
+  // the two casts on the same line doesn't work, neither does
+  // a direct C-style to char*.
+  void* pv1 = (void*)0x1234;  // NOLINT
+  void* pv2 = (void*)0xABC0;  // NOLINT
+  wchar_t* const p1 = reinterpret_cast<wchar_t*>(pv1);
+  wchar_t* const p2 = reinterpret_cast<wchar_t*>(pv2);
+  EXPECT_EQ(p0, p0);
+
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p0, p2),
+                          "Value of: p2");
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p1, p2),
+                          "p2");
+  void* pv3 = (void*)0x1234;  // NOLINT
+  void* pv4 = (void*)0xABC0;  // NOLINT
+  const wchar_t* p3 = reinterpret_cast<const wchar_t*>(pv3);
+  const wchar_t* p4 = reinterpret_cast<const wchar_t*>(pv4);
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(p3, p4),
+                          "p4");
+}
+
+// Tests using other types of pointers in {EXPECT|ASSERT}_EQ.
+TEST(EqAssertionTest, OtherPointer) {
+  ASSERT_EQ(static_cast<const int*>(NULL),
+            static_cast<const int*>(NULL));
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(static_cast<const int*>(NULL),
+                                 reinterpret_cast<const int*>(0x1234)),
+                       "0x1234");
+}
+
+// Tests the FRIEND_TEST macro.
+
+// This class has a private member we want to test.  We will test it
+// both in a TEST and in a TEST_F.
+class Foo {
+ public:
+  Foo() {}
+
+ private:
+  int Bar() const { return 1; }
+
+  // Declares the friend tests that can access the private member
+  // Bar().
+  FRIEND_TEST(FRIEND_TEST_Test, TEST);
+  FRIEND_TEST(FRIEND_TEST_Test2, TEST_F);
+};
+
+// Tests that the FRIEND_TEST declaration allows a TEST to access a
+// class's private members.  This should compile.
+TEST(FRIEND_TEST_Test, TEST) {
+  ASSERT_EQ(1, Foo().Bar());
+}
+
+// The fixture needed to test using FRIEND_TEST with TEST_F.
+class FRIEND_TEST_Test2 : public Test {
+ protected:
+  Foo foo;
+};
+
+// Tests that the FRIEND_TEST declaration allows a TEST_F to access a
+// class's private members.  This should compile.
+TEST_F(FRIEND_TEST_Test2, TEST_F) {
+  ASSERT_EQ(1, foo.Bar());
+}
+
+// Tests the life cycle of Test objects.
+
+// The test fixture for testing the life cycle of Test objects.
+//
+// This class counts the number of live test objects that uses this
+// fixture.
+class TestLifeCycleTest : public Test {
+ protected:
+  // Constructor.  Increments the number of test objects that uses
+  // this fixture.
+  TestLifeCycleTest() { count_++; }
+
+  // Destructor.  Decrements the number of test objects that uses this
+  // fixture.
+  ~TestLifeCycleTest() { count_--; }
+
+  // Returns the number of live test objects that uses this fixture.
+  int count() const { return count_; }
+
+ private:
+  static int count_;
+};
+
+int TestLifeCycleTest::count_ = 0;
+
+// Tests the life cycle of test objects.
+TEST_F(TestLifeCycleTest, Test1) {
+  // There should be only one test object in this test case that's
+  // currently alive.
+  ASSERT_EQ(1, count());
+}
+
+// Tests the life cycle of test objects.
+TEST_F(TestLifeCycleTest, Test2) {
+  // After Test1 is done and Test2 is started, there should still be
+  // only one live test object, as the object for Test1 should've been
+  // deleted.
+  ASSERT_EQ(1, count());
+}
+
+}  // namespace
+
+// Tests that the copy constructor works when it is NOT optimized away by
+// the compiler.
+TEST(AssertionResultTest, CopyConstructorWorksWhenNotOptimied) {
+  // Checks that the copy constructor doesn't try to dereference NULL pointers
+  // in the source object.
+  AssertionResult r1 = AssertionSuccess();
+  AssertionResult r2 = r1;
+  // The following line is added to prevent the compiler from optimizing
+  // away the constructor call.
+  r1 << "abc";
+
+  AssertionResult r3 = r1;
+  EXPECT_EQ(static_cast<bool>(r3), static_cast<bool>(r1));
+  EXPECT_STREQ("abc", r1.message());
+}
+
+// Tests that AssertionSuccess and AssertionFailure construct
+// AssertionResult objects as expected.
+TEST(AssertionResultTest, ConstructionWorks) {
+  AssertionResult r1 = AssertionSuccess();
+  EXPECT_TRUE(r1);
+  EXPECT_STREQ("", r1.message());
+
+  AssertionResult r2 = AssertionSuccess() << "abc";
+  EXPECT_TRUE(r2);
+  EXPECT_STREQ("abc", r2.message());
+
+  AssertionResult r3 = AssertionFailure();
+  EXPECT_FALSE(r3);
+  EXPECT_STREQ("", r3.message());
+
+  AssertionResult r4 = AssertionFailure() << "def";
+  EXPECT_FALSE(r4);
+  EXPECT_STREQ("def", r4.message());
+
+  AssertionResult r5 = AssertionFailure(Message() << "ghi");
+  EXPECT_FALSE(r5);
+  EXPECT_STREQ("ghi", r5.message());
+}
+
+// Tests that the negation fips the predicate result but keeps the message.
+TEST(AssertionResultTest, NegationWorks) {
+  AssertionResult r1 = AssertionSuccess() << "abc";
+  EXPECT_FALSE(!r1);
+  EXPECT_STREQ("abc", (!r1).message());
+
+  AssertionResult r2 = AssertionFailure() << "def";
+  EXPECT_TRUE(!r2);
+  EXPECT_STREQ("def", (!r2).message());
+}
+
+TEST(AssertionResultTest, StreamingWorks) {
+  AssertionResult r = AssertionSuccess();
+  r << "abc" << 'd' << 0 << true;
+  EXPECT_STREQ("abcd0true", r.message());
+}
+
+// Tests streaming a user type whose definition and operator << are
+// both in the global namespace.
+class Base {
+ public:
+  explicit Base(int an_x) : x_(an_x) {}
+  int x() const { return x_; }
+ private:
+  int x_;
+};
+std::ostream& operator<<(std::ostream& os,
+                         const Base& val) {
+  return os << val.x();
+}
+std::ostream& operator<<(std::ostream& os,
+                         const Base* pointer) {
+  return os << "(" << pointer->x() << ")";
+}
+
+TEST(MessageTest, CanStreamUserTypeInGlobalNameSpace) {
+  Message msg;
+  Base a(1);
+
+  msg << a << &a;  // Uses ::operator<<.
+  EXPECT_STREQ("1(1)", msg.GetString().c_str());
+}
+
+// Tests streaming a user type whose definition and operator<< are
+// both in an unnamed namespace.
+namespace {
+class MyTypeInUnnamedNameSpace : public Base {
+ public:
+  explicit MyTypeInUnnamedNameSpace(int an_x): Base(an_x) {}
+};
+std::ostream& operator<<(std::ostream& os,
+                         const MyTypeInUnnamedNameSpace& val) {
+  return os << val.x();
+}
+std::ostream& operator<<(std::ostream& os,
+                         const MyTypeInUnnamedNameSpace* pointer) {
+  return os << "(" << pointer->x() << ")";
+}
+}  // namespace
+
+TEST(MessageTest, CanStreamUserTypeInUnnamedNameSpace) {
+  Message msg;
+  MyTypeInUnnamedNameSpace a(1);
+
+  msg << a << &a;  // Uses <unnamed_namespace>::operator<<.
+  EXPECT_STREQ("1(1)", msg.GetString().c_str());
+}
+
+// Tests streaming a user type whose definition and operator<< are
+// both in a user namespace.
+namespace namespace1 {
+class MyTypeInNameSpace1 : public Base {
+ public:
+  explicit MyTypeInNameSpace1(int an_x): Base(an_x) {}
+};
+std::ostream& operator<<(std::ostream& os,
+                         const MyTypeInNameSpace1& val) {
+  return os << val.x();
+}
+std::ostream& operator<<(std::ostream& os,
+                         const MyTypeInNameSpace1* pointer) {
+  return os << "(" << pointer->x() << ")";
+}
+}  // namespace namespace1
+
+TEST(MessageTest, CanStreamUserTypeInUserNameSpace) {
+  Message msg;
+  namespace1::MyTypeInNameSpace1 a(1);
+
+  msg << a << &a;  // Uses namespace1::operator<<.
+  EXPECT_STREQ("1(1)", msg.GetString().c_str());
+}
+
+// Tests streaming a user type whose definition is in a user namespace
+// but whose operator<< is in the global namespace.
+namespace namespace2 {
+class MyTypeInNameSpace2 : public ::Base {
+ public:
+  explicit MyTypeInNameSpace2(int an_x): Base(an_x) {}
+};
+}  // namespace namespace2
+std::ostream& operator<<(std::ostream& os,
+                         const namespace2::MyTypeInNameSpace2& val) {
+  return os << val.x();
+}
+std::ostream& operator<<(std::ostream& os,
+                         const namespace2::MyTypeInNameSpace2* pointer) {
+  return os << "(" << pointer->x() << ")";
+}
+
+TEST(MessageTest, CanStreamUserTypeInUserNameSpaceWithStreamOperatorInGlobal) {
+  Message msg;
+  namespace2::MyTypeInNameSpace2 a(1);
+
+  msg << a << &a;  // Uses ::operator<<.
+  EXPECT_STREQ("1(1)", msg.GetString().c_str());
+}
+
+// Tests streaming NULL pointers to testing::Message.
+TEST(MessageTest, NullPointers) {
+  Message msg;
+  char* const p1 = NULL;
+  unsigned char* const p2 = NULL;
+  int* p3 = NULL;
+  double* p4 = NULL;
+  bool* p5 = NULL;
+  Message* p6 = NULL;
+
+  msg << p1 << p2 << p3 << p4 << p5 << p6;
+  ASSERT_STREQ("(null)(null)(null)(null)(null)(null)",
+               msg.GetString().c_str());
+}
+
+// Tests streaming wide strings to testing::Message.
+TEST(MessageTest, WideStrings) {
+  // Streams a NULL of type const wchar_t*.
+  const wchar_t* const_wstr = NULL;
+  EXPECT_STREQ("(null)",
+               (Message() << const_wstr).GetString().c_str());
+
+  // Streams a NULL of type wchar_t*.
+  wchar_t* wstr = NULL;
+  EXPECT_STREQ("(null)",
+               (Message() << wstr).GetString().c_str());
+
+  // Streams a non-NULL of type const wchar_t*.
+  const_wstr = L"abc\x8119";
+  EXPECT_STREQ("abc\xe8\x84\x99",
+               (Message() << const_wstr).GetString().c_str());
+
+  // Streams a non-NULL of type wchar_t*.
+  wstr = const_cast<wchar_t*>(const_wstr);
+  EXPECT_STREQ("abc\xe8\x84\x99",
+               (Message() << wstr).GetString().c_str());
+}
+
+
+// This line tests that we can define tests in the testing namespace.
+namespace testing {
+
+// Tests the TestInfo class.
+
+class TestInfoTest : public Test {
+ protected:
+  static const TestInfo* GetTestInfo(const char* test_name) {
+    const TestCase* const test_case = GetUnitTestImpl()->
+        GetTestCase("TestInfoTest", "", NULL, NULL);
+
+    for (int i = 0; i < test_case->total_test_count(); ++i) {
+      const TestInfo* const test_info = test_case->GetTestInfo(i);
+      if (strcmp(test_name, test_info->name()) == 0)
+        return test_info;
+    }
+    return NULL;
+  }
+
+  static const TestResult* GetTestResult(
+      const TestInfo* test_info) {
+    return test_info->result();
+  }
+};
+
+// Tests TestInfo::test_case_name() and TestInfo::name().
+TEST_F(TestInfoTest, Names) {
+  const TestInfo* const test_info = GetTestInfo("Names");
+
+  ASSERT_STREQ("TestInfoTest", test_info->test_case_name());
+  ASSERT_STREQ("Names", test_info->name());
+}
+
+// Tests TestInfo::result().
+TEST_F(TestInfoTest, result) {
+  const TestInfo* const test_info = GetTestInfo("result");
+
+  // Initially, there is no TestPartResult for this test.
+  ASSERT_EQ(0, GetTestResult(test_info)->total_part_count());
+
+  // After the previous assertion, there is still none.
+  ASSERT_EQ(0, GetTestResult(test_info)->total_part_count());
+}
+
+// Tests setting up and tearing down a test case.
+
+class SetUpTestCaseTest : public Test {
+ protected:
+  // This will be called once before the first test in this test case
+  // is run.
+  static void SetUpTestCase() {
+    printf("Setting up the test case . . .\n");
+
+    // Initializes some shared resource.  In this simple example, we
+    // just create a C string.  More complex stuff can be done if
+    // desired.
+    shared_resource_ = "123";
+
+    // Increments the number of test cases that have been set up.
+    counter_++;
+
+    // SetUpTestCase() should be called only once.
+    EXPECT_EQ(1, counter_);
+  }
+
+  // This will be called once after the last test in this test case is
+  // run.
+  static void TearDownTestCase() {
+    printf("Tearing down the test case . . .\n");
+
+    // Decrements the number of test cases that have been set up.
+    counter_--;
+
+    // TearDownTestCase() should be called only once.
+    EXPECT_EQ(0, counter_);
+
+    // Cleans up the shared resource.
+    shared_resource_ = NULL;
+  }
+
+  // This will be called before each test in this test case.
+  virtual void SetUp() {
+    // SetUpTestCase() should be called only once, so counter_ should
+    // always be 1.
+    EXPECT_EQ(1, counter_);
+  }
+
+  // Number of test cases that have been set up.
+  static int counter_;
+
+  // Some resource to be shared by all tests in this test case.
+  static const char* shared_resource_;
+};
+
+int SetUpTestCaseTest::counter_ = 0;
+const char* SetUpTestCaseTest::shared_resource_ = NULL;
+
+// A test that uses the shared resource.
+TEST_F(SetUpTestCaseTest, Test1) {
+  EXPECT_STRNE(NULL, shared_resource_);
+}
+
+// Another test that uses the shared resource.
+TEST_F(SetUpTestCaseTest, Test2) {
+  EXPECT_STREQ("123", shared_resource_);
+}
+
+// The InitGoogleTestTest test case tests testing::InitGoogleTest().
+
+// The Flags struct stores a copy of all Google Test flags.
+struct Flags {
+  // Constructs a Flags struct where each flag has its default value.
+  Flags() : also_run_disabled_tests(false),
+            break_on_failure(false),
+            catch_exceptions(false),
+            death_test_use_fork(false),
+            filter(""),
+            list_tests(false),
+            output(""),
+            print_time(true),
+            random_seed(0),
+            repeat(1),
+            shuffle(false),
+            stack_trace_depth(kMaxStackTraceDepth),
+            throw_on_failure(false) {}
+
+  // Factory methods.
+
+  // Creates a Flags struct where the gtest_also_run_disabled_tests flag has
+  // the given value.
+  static Flags AlsoRunDisabledTests(bool also_run_disabled_tests) {
+    Flags flags;
+    flags.also_run_disabled_tests = also_run_disabled_tests;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_break_on_failure flag has
+  // the given value.
+  static Flags BreakOnFailure(bool break_on_failure) {
+    Flags flags;
+    flags.break_on_failure = break_on_failure;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_catch_exceptions flag has
+  // the given value.
+  static Flags CatchExceptions(bool catch_exceptions) {
+    Flags flags;
+    flags.catch_exceptions = catch_exceptions;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_death_test_use_fork flag has
+  // the given value.
+  static Flags DeathTestUseFork(bool death_test_use_fork) {
+    Flags flags;
+    flags.death_test_use_fork = death_test_use_fork;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_filter flag has the given
+  // value.
+  static Flags Filter(const char* filter) {
+    Flags flags;
+    flags.filter = filter;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_list_tests flag has the
+  // given value.
+  static Flags ListTests(bool list_tests) {
+    Flags flags;
+    flags.list_tests = list_tests;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_output flag has the given
+  // value.
+  static Flags Output(const char* output) {
+    Flags flags;
+    flags.output = output;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_print_time flag has the given
+  // value.
+  static Flags PrintTime(bool print_time) {
+    Flags flags;
+    flags.print_time = print_time;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_random_seed flag has
+  // the given value.
+  static Flags RandomSeed(Int32 random_seed) {
+    Flags flags;
+    flags.random_seed = random_seed;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_repeat flag has the given
+  // value.
+  static Flags Repeat(Int32 repeat) {
+    Flags flags;
+    flags.repeat = repeat;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_shuffle flag has
+  // the given value.
+  static Flags Shuffle(bool shuffle) {
+    Flags flags;
+    flags.shuffle = shuffle;
+    return flags;
+  }
+
+  // Creates a Flags struct where the GTEST_FLAG(stack_trace_depth) flag has
+  // the given value.
+  static Flags StackTraceDepth(Int32 stack_trace_depth) {
+    Flags flags;
+    flags.stack_trace_depth = stack_trace_depth;
+    return flags;
+  }
+
+  // Creates a Flags struct where the gtest_throw_on_failure flag has
+  // the given value.
+  static Flags ThrowOnFailure(bool throw_on_failure) {
+    Flags flags;
+    flags.throw_on_failure = throw_on_failure;
+    return flags;
+  }
+
+  // These fields store the flag values.
+  bool also_run_disabled_tests;
+  bool break_on_failure;
+  bool catch_exceptions;
+  bool death_test_use_fork;
+  const char* filter;
+  bool list_tests;
+  const char* output;
+  bool print_time;
+  Int32 random_seed;
+  Int32 repeat;
+  bool shuffle;
+  Int32 stack_trace_depth;
+  bool throw_on_failure;
+};
+
+// Fixture for testing InitGoogleTest().
+class InitGoogleTestTest : public Test {
+ protected:
+  // Clears the flags before each test.
+  virtual void SetUp() {
+    GTEST_FLAG(also_run_disabled_tests) = false;
+    GTEST_FLAG(break_on_failure) = false;
+    GTEST_FLAG(catch_exceptions) = false;
+    GTEST_FLAG(death_test_use_fork) = false;
+    GTEST_FLAG(filter) = "";
+    GTEST_FLAG(list_tests) = false;
+    GTEST_FLAG(output) = "";
+    GTEST_FLAG(print_time) = true;
+    GTEST_FLAG(random_seed) = 0;
+    GTEST_FLAG(repeat) = 1;
+    GTEST_FLAG(shuffle) = false;
+    GTEST_FLAG(stack_trace_depth) = kMaxStackTraceDepth;
+    GTEST_FLAG(throw_on_failure) = false;
+  }
+
+  // Asserts that two narrow or wide string arrays are equal.
+  template <typename CharType>
+  static void AssertStringArrayEq(size_t size1, CharType** array1,
+                                  size_t size2, CharType** array2) {
+    ASSERT_EQ(size1, size2) << " Array sizes different.";
+
+    for (size_t i = 0; i != size1; i++) {
+      ASSERT_STREQ(array1[i], array2[i]) << " where i == " << i;
+    }
+  }
+
+  // Verifies that the flag values match the expected values.
+  static void CheckFlags(const Flags& expected) {
+    EXPECT_EQ(expected.also_run_disabled_tests,
+              GTEST_FLAG(also_run_disabled_tests));
+    EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure));
+    EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions));
+    EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork));
+    EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str());
+    EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests));
+    EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str());
+    EXPECT_EQ(expected.print_time, GTEST_FLAG(print_time));
+    EXPECT_EQ(expected.random_seed, GTEST_FLAG(random_seed));
+    EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat));
+    EXPECT_EQ(expected.shuffle, GTEST_FLAG(shuffle));
+    EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure));
+    EXPECT_EQ(expected.stack_trace_depth, GTEST_FLAG(stack_trace_depth));
+  }
+
+  // Parses a command line (specified by argc1 and argv1), then
+  // verifies that the flag values are expected and that the
+  // recognized flags are removed from the command line.
+  template <typename CharType>
+  static void TestParsingFlags(int argc1, const CharType** argv1,
+                               int argc2, const CharType** argv2,
+                               const Flags& expected, bool should_print_help) {
+    const bool saved_help_flag = ::testing::internal::g_help_flag;
+    ::testing::internal::g_help_flag = false;
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+    CaptureStdout();
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
+    // Parses the command line.
+    internal::ParseGoogleTestFlagsOnly(&argc1, const_cast<CharType**>(argv1));
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+    const String captured_stdout = GetCapturedStdout();
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
+    // Verifies the flag values.
+    CheckFlags(expected);
+
+    // Verifies that the recognized flags are removed from the command
+    // line.
+    AssertStringArrayEq(argc1 + 1, argv1, argc2 + 1, argv2);
+
+    // ParseGoogleTestFlagsOnly should neither set g_help_flag nor print the
+    // help message for the flags it recognizes.
+    EXPECT_EQ(should_print_help, ::testing::internal::g_help_flag);
+
+#if GTEST_HAS_STREAM_REDIRECTION_
+    const char* const expected_help_fragment =
+        "This program contains tests written using";
+    if (should_print_help) {
+      EXPECT_PRED_FORMAT2(IsSubstring, expected_help_fragment, captured_stdout);
+    } else {
+      EXPECT_PRED_FORMAT2(IsNotSubstring,
+                          expected_help_fragment, captured_stdout);
+    }
+#endif  // GTEST_HAS_STREAM_REDIRECTION_
+
+    ::testing::internal::g_help_flag = saved_help_flag;
+  }
+
+  // This macro wraps TestParsingFlags s.t. the user doesn't need
+  // to specify the array sizes.
+#define GTEST_TEST_PARSING_FLAGS_(argv1, argv2, expected, should_print_help) \
+  TestParsingFlags(sizeof(argv1)/sizeof(*argv1) - 1, argv1, \
+                   sizeof(argv2)/sizeof(*argv2) - 1, argv2, \
+                   expected, should_print_help)
+};
+
+// Tests parsing an empty command line.
+TEST_F(InitGoogleTestTest, Empty) {
+  const char* argv[] = {
+    NULL
+  };
+
+  const char* argv2[] = {
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false);
+}
+
+// Tests parsing a command line that has no flag.
+TEST_F(InitGoogleTestTest, NoFlag) {
+  const char* argv[] = {
+    "foo.exe",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false);
+}
+
+// Tests parsing a bad --gtest_filter flag.
+TEST_F(InitGoogleTestTest, FilterBad) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_filter",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    "--gtest_filter",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), true);
+}
+
+// Tests parsing an empty --gtest_filter flag.
+TEST_F(InitGoogleTestTest, FilterEmpty) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_filter=",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter(""), false);
+}
+
+// Tests parsing a non-empty --gtest_filter flag.
+TEST_F(InitGoogleTestTest, FilterNonEmpty) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_filter=abc",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("abc"), false);
+}
+
+// Tests parsing --gtest_break_on_failure.
+TEST_F(InitGoogleTestTest, BreakOnFailureWithoutValue) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_break_on_failure",
+    NULL
+};
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false);
+}
+
+// Tests parsing --gtest_break_on_failure=0.
+TEST_F(InitGoogleTestTest, BreakOnFailureFalse_0) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_break_on_failure=0",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false);
+}
+
+// Tests parsing --gtest_break_on_failure=f.
+TEST_F(InitGoogleTestTest, BreakOnFailureFalse_f) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_break_on_failure=f",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false);
+}
+
+// Tests parsing --gtest_break_on_failure=F.
+TEST_F(InitGoogleTestTest, BreakOnFailureFalse_F) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_break_on_failure=F",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(false), false);
+}
+
+// Tests parsing a --gtest_break_on_failure flag that has a "true"
+// definition.
+TEST_F(InitGoogleTestTest, BreakOnFailureTrue) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_break_on_failure=1",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::BreakOnFailure(true), false);
+}
+
+// Tests parsing --gtest_catch_exceptions.
+TEST_F(InitGoogleTestTest, CatchExceptions) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_catch_exceptions",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::CatchExceptions(true), false);
+}
+
+// Tests parsing --gtest_death_test_use_fork.
+TEST_F(InitGoogleTestTest, DeathTestUseFork) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_death_test_use_fork",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::DeathTestUseFork(true), false);
+}
+
+// Tests having the same flag twice with different values.  The
+// expected behavior is that the one coming last takes precedence.
+TEST_F(InitGoogleTestTest, DuplicatedFlags) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_filter=a",
+    "--gtest_filter=b",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Filter("b"), false);
+}
+
+// Tests having an unrecognized flag on the command line.
+TEST_F(InitGoogleTestTest, UnrecognizedFlag) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_break_on_failure",
+    "bar",  // Unrecognized by Google Test.
+    "--gtest_filter=b",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    "bar",
+    NULL
+  };
+
+  Flags flags;
+  flags.break_on_failure = true;
+  flags.filter = "b";
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, flags, false);
+}
+
+// Tests having a --gtest_list_tests flag
+TEST_F(InitGoogleTestTest, ListTestsFlag) {
+    const char* argv[] = {
+      "foo.exe",
+      "--gtest_list_tests",
+      NULL
+    };
+
+    const char* argv2[] = {
+      "foo.exe",
+      NULL
+    };
+
+    GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false);
+}
+
+// Tests having a --gtest_list_tests flag with a "true" value
+TEST_F(InitGoogleTestTest, ListTestsTrue) {
+    const char* argv[] = {
+      "foo.exe",
+      "--gtest_list_tests=1",
+      NULL
+    };
+
+    const char* argv2[] = {
+      "foo.exe",
+      NULL
+    };
+
+    GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(true), false);
+}
+
+// Tests having a --gtest_list_tests flag with a "false" value
+TEST_F(InitGoogleTestTest, ListTestsFalse) {
+    const char* argv[] = {
+      "foo.exe",
+      "--gtest_list_tests=0",
+      NULL
+    };
+
+    const char* argv2[] = {
+      "foo.exe",
+      NULL
+    };
+
+    GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false);
+}
+
+// Tests parsing --gtest_list_tests=f.
+TEST_F(InitGoogleTestTest, ListTestsFalse_f) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_list_tests=f",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false);
+}
+
+// Tests parsing --gtest_list_tests=F.
+TEST_F(InitGoogleTestTest, ListTestsFalse_F) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_list_tests=F",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ListTests(false), false);
+}
+
+// Tests parsing --gtest_output (invalid).
+TEST_F(InitGoogleTestTest, OutputEmpty) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_output",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    "--gtest_output",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), true);
+}
+
+// Tests parsing --gtest_output=xml
+TEST_F(InitGoogleTestTest, OutputXml) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_output=xml",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml"), false);
+}
+
+// Tests parsing --gtest_output=xml:file
+TEST_F(InitGoogleTestTest, OutputXmlFile) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_output=xml:file",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Output("xml:file"), false);
+}
+
+// Tests parsing --gtest_output=xml:directory/path/
+TEST_F(InitGoogleTestTest, OutputXmlDirectory) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_output=xml:directory/path/",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2,
+                            Flags::Output("xml:directory/path/"), false);
+}
+
+// Tests having a --gtest_print_time flag
+TEST_F(InitGoogleTestTest, PrintTimeFlag) {
+    const char* argv[] = {
+      "foo.exe",
+      "--gtest_print_time",
+      NULL
+    };
+
+    const char* argv2[] = {
+      "foo.exe",
+      NULL
+    };
+
+    GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false);
+}
+
+// Tests having a --gtest_print_time flag with a "true" value
+TEST_F(InitGoogleTestTest, PrintTimeTrue) {
+    const char* argv[] = {
+      "foo.exe",
+      "--gtest_print_time=1",
+      NULL
+    };
+
+    const char* argv2[] = {
+      "foo.exe",
+      NULL
+    };
+
+    GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(true), false);
+}
+
+// Tests having a --gtest_print_time flag with a "false" value
+TEST_F(InitGoogleTestTest, PrintTimeFalse) {
+    const char* argv[] = {
+      "foo.exe",
+      "--gtest_print_time=0",
+      NULL
+    };
+
+    const char* argv2[] = {
+      "foo.exe",
+      NULL
+    };
+
+    GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false);
+}
+
+// Tests parsing --gtest_print_time=f.
+TEST_F(InitGoogleTestTest, PrintTimeFalse_f) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_print_time=f",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false);
+}
+
+// Tests parsing --gtest_print_time=F.
+TEST_F(InitGoogleTestTest, PrintTimeFalse_F) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_print_time=F",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::PrintTime(false), false);
+}
+
+// Tests parsing --gtest_random_seed=number
+TEST_F(InitGoogleTestTest, RandomSeed) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_random_seed=1000",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::RandomSeed(1000), false);
+}
+
+// Tests parsing --gtest_repeat=number
+TEST_F(InitGoogleTestTest, Repeat) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_repeat=1000",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Repeat(1000), false);
+}
+
+// Tests having a --gtest_also_run_disabled_tests flag
+TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFlag) {
+    const char* argv[] = {
+      "foo.exe",
+      "--gtest_also_run_disabled_tests",
+      NULL
+    };
+
+    const char* argv2[] = {
+      "foo.exe",
+      NULL
+    };
+
+    GTEST_TEST_PARSING_FLAGS_(argv, argv2,
+                              Flags::AlsoRunDisabledTests(true), false);
+}
+
+// Tests having a --gtest_also_run_disabled_tests flag with a "true" value
+TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsTrue) {
+    const char* argv[] = {
+      "foo.exe",
+      "--gtest_also_run_disabled_tests=1",
+      NULL
+    };
+
+    const char* argv2[] = {
+      "foo.exe",
+      NULL
+    };
+
+    GTEST_TEST_PARSING_FLAGS_(argv, argv2,
+                              Flags::AlsoRunDisabledTests(true), false);
+}
+
+// Tests having a --gtest_also_run_disabled_tests flag with a "false" value
+TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) {
+    const char* argv[] = {
+      "foo.exe",
+      "--gtest_also_run_disabled_tests=0",
+      NULL
+    };
+
+    const char* argv2[] = {
+      "foo.exe",
+      NULL
+    };
+
+    GTEST_TEST_PARSING_FLAGS_(argv, argv2,
+                              Flags::AlsoRunDisabledTests(false), false);
+}
+
+// Tests parsing --gtest_shuffle.
+TEST_F(InitGoogleTestTest, ShuffleWithoutValue) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_shuffle",
+    NULL
+};
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false);
+}
+
+// Tests parsing --gtest_shuffle=0.
+TEST_F(InitGoogleTestTest, ShuffleFalse_0) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_shuffle=0",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(false), false);
+}
+
+// Tests parsing a --gtest_shuffle flag that has a "true"
+// definition.
+TEST_F(InitGoogleTestTest, ShuffleTrue) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_shuffle=1",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::Shuffle(true), false);
+}
+
+// Tests parsing --gtest_stack_trace_depth=number.
+TEST_F(InitGoogleTestTest, StackTraceDepth) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_stack_trace_depth=5",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::StackTraceDepth(5), false);
+}
+
+// Tests parsing --gtest_throw_on_failure.
+TEST_F(InitGoogleTestTest, ThrowOnFailureWithoutValue) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_throw_on_failure",
+    NULL
+};
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false);
+}
+
+// Tests parsing --gtest_throw_on_failure=0.
+TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_throw_on_failure=0",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false), false);
+}
+
+// Tests parsing a --gtest_throw_on_failure flag that has a "true"
+// definition.
+TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) {
+  const char* argv[] = {
+    "foo.exe",
+    "--gtest_throw_on_failure=1",
+    NULL
+  };
+
+  const char* argv2[] = {
+    "foo.exe",
+    NULL
+  };
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true), false);
+}
+
+#if GTEST_OS_WINDOWS
+// Tests parsing wide strings.
+TEST_F(InitGoogleTestTest, WideStrings) {
+  const wchar_t* argv[] = {
+    L"foo.exe",
+    L"--gtest_filter=Foo*",
+    L"--gtest_list_tests=1",
+    L"--gtest_break_on_failure",
+    L"--non_gtest_flag",
+    NULL
+  };
+
+  const wchar_t* argv2[] = {
+    L"foo.exe",
+    L"--non_gtest_flag",
+    NULL
+  };
+
+  Flags expected_flags;
+  expected_flags.break_on_failure = true;
+  expected_flags.filter = "Foo*";
+  expected_flags.list_tests = true;
+
+  GTEST_TEST_PARSING_FLAGS_(argv, argv2, expected_flags, false);
+}
+#endif  // GTEST_OS_WINDOWS
+
+// Tests current_test_info() in UnitTest.
+class CurrentTestInfoTest : public Test {
+ protected:
+  // Tests that current_test_info() returns NULL before the first test in
+  // the test case is run.
+  static void SetUpTestCase() {
+    // There should be no tests running at this point.
+    const TestInfo* test_info =
+      UnitTest::GetInstance()->current_test_info();
+    EXPECT_TRUE(test_info == NULL)
+        << "There should be no tests running at this point.";
+  }
+
+  // Tests that current_test_info() returns NULL after the last test in
+  // the test case has run.
+  static void TearDownTestCase() {
+    const TestInfo* test_info =
+      UnitTest::GetInstance()->current_test_info();
+    EXPECT_TRUE(test_info == NULL)
+        << "There should be no tests running at this point.";
+  }
+};
+
+// Tests that current_test_info() returns TestInfo for currently running
+// test by checking the expected test name against the actual one.
+TEST_F(CurrentTestInfoTest, WorksForFirstTestInATestCase) {
+  const TestInfo* test_info =
+    UnitTest::GetInstance()->current_test_info();
+  ASSERT_TRUE(NULL != test_info)
+      << "There is a test running so we should have a valid TestInfo.";
+  EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name())
+      << "Expected the name of the currently running test case.";
+  EXPECT_STREQ("WorksForFirstTestInATestCase", test_info->name())
+      << "Expected the name of the currently running test.";
+}
+
+// Tests that current_test_info() returns TestInfo for currently running
+// test by checking the expected test name against the actual one.  We
+// use this test to see that the TestInfo object actually changed from
+// the previous invocation.
+TEST_F(CurrentTestInfoTest, WorksForSecondTestInATestCase) {
+  const TestInfo* test_info =
+    UnitTest::GetInstance()->current_test_info();
+  ASSERT_TRUE(NULL != test_info)
+      << "There is a test running so we should have a valid TestInfo.";
+  EXPECT_STREQ("CurrentTestInfoTest", test_info->test_case_name())
+      << "Expected the name of the currently running test case.";
+  EXPECT_STREQ("WorksForSecondTestInATestCase", test_info->name())
+      << "Expected the name of the currently running test.";
+}
+
+}  // namespace testing
+
+// These two lines test that we can define tests in a namespace that
+// has the name "testing" and is nested in another namespace.
+namespace my_namespace {
+namespace testing {
+
+// Makes sure that TEST knows to use ::testing::Test instead of
+// ::my_namespace::testing::Test.
+class Test {};
+
+// Makes sure that an assertion knows to use ::testing::Message instead of
+// ::my_namespace::testing::Message.
+class Message {};
+
+// Makes sure that an assertion knows to use
+// ::testing::AssertionResult instead of
+// ::my_namespace::testing::AssertionResult.
+class AssertionResult {};
+
+// Tests that an assertion that should succeed works as expected.
+TEST(NestedTestingNamespaceTest, Success) {
+  EXPECT_EQ(1, 1) << "This shouldn't fail.";
+}
+
+// Tests that an assertion that should fail works as expected.
+TEST(NestedTestingNamespaceTest, Failure) {
+  EXPECT_FATAL_FAILURE(FAIL() << "This failure is expected.",
+                       "This failure is expected.");
+}
+
+}  // namespace testing
+}  // namespace my_namespace
+
+// Tests that one can call superclass SetUp and TearDown methods--
+// that is, that they are not private.
+// No tests are based on this fixture; the test "passes" if it compiles
+// successfully.
+class ProtectedFixtureMethodsTest : public Test {
+ protected:
+  virtual void SetUp() {
+    Test::SetUp();
+  }
+  virtual void TearDown() {
+    Test::TearDown();
+  }
+};
+
+// StreamingAssertionsTest tests the streaming versions of a representative
+// sample of assertions.
+TEST(StreamingAssertionsTest, Unconditional) {
+  SUCCEED() << "expected success";
+  EXPECT_NONFATAL_FAILURE(ADD_FAILURE() << "expected failure",
+                          "expected failure");
+  EXPECT_FATAL_FAILURE(FAIL() << "expected failure",
+                       "expected failure");
+}
+
+#ifdef __BORLANDC__
+// Silences warnings: "Condition is always true", "Unreachable code"
+#pragma option push -w-ccc -w-rch
+#endif
+
+TEST(StreamingAssertionsTest, Truth) {
+  EXPECT_TRUE(true) << "unexpected failure";
+  ASSERT_TRUE(true) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_TRUE(false) << "expected failure",
+                          "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_TRUE(false) << "expected failure",
+                       "expected failure");
+}
+
+TEST(StreamingAssertionsTest, Truth2) {
+  EXPECT_FALSE(false) << "unexpected failure";
+  ASSERT_FALSE(false) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_FALSE(true) << "expected failure",
+                          "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_FALSE(true) << "expected failure",
+                       "expected failure");
+}
+
+#ifdef __BORLANDC__
+// Restores warnings after previous "#pragma option push" supressed them
+#pragma option pop
+#endif
+
+TEST(StreamingAssertionsTest, IntegerEquals) {
+  EXPECT_EQ(1, 1) << "unexpected failure";
+  ASSERT_EQ(1, 1) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_EQ(1, 2) << "expected failure",
+                          "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_EQ(1, 2) << "expected failure",
+                       "expected failure");
+}
+
+TEST(StreamingAssertionsTest, IntegerLessThan) {
+  EXPECT_LT(1, 2) << "unexpected failure";
+  ASSERT_LT(1, 2) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_LT(2, 1) << "expected failure",
+                          "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_LT(2, 1) << "expected failure",
+                       "expected failure");
+}
+
+TEST(StreamingAssertionsTest, StringsEqual) {
+  EXPECT_STREQ("foo", "foo") << "unexpected failure";
+  ASSERT_STREQ("foo", "foo") << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_STREQ("foo", "bar") << "expected failure",
+                          "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_STREQ("foo", "bar") << "expected failure",
+                       "expected failure");
+}
+
+TEST(StreamingAssertionsTest, StringsNotEqual) {
+  EXPECT_STRNE("foo", "bar") << "unexpected failure";
+  ASSERT_STRNE("foo", "bar") << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_STRNE("foo", "foo") << "expected failure",
+                          "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_STRNE("foo", "foo") << "expected failure",
+                       "expected failure");
+}
+
+TEST(StreamingAssertionsTest, StringsEqualIgnoringCase) {
+  EXPECT_STRCASEEQ("foo", "FOO") << "unexpected failure";
+  ASSERT_STRCASEEQ("foo", "FOO") << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_STRCASEEQ("foo", "bar") << "expected failure",
+                          "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_STRCASEEQ("foo", "bar") << "expected failure",
+                       "expected failure");
+}
+
+TEST(StreamingAssertionsTest, StringNotEqualIgnoringCase) {
+  EXPECT_STRCASENE("foo", "bar") << "unexpected failure";
+  ASSERT_STRCASENE("foo", "bar") << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_STRCASENE("foo", "FOO") << "expected failure",
+                          "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("bar", "BAR") << "expected failure",
+                       "expected failure");
+}
+
+TEST(StreamingAssertionsTest, FloatingPointEquals) {
+  EXPECT_FLOAT_EQ(1.0, 1.0) << "unexpected failure";
+  ASSERT_FLOAT_EQ(1.0, 1.0) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_FLOAT_EQ(0.0, 1.0) << "expected failure",
+                          "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_FLOAT_EQ(0.0, 1.0) << "expected failure",
+                       "expected failure");
+}
+
+#if GTEST_HAS_EXCEPTIONS
+
+TEST(StreamingAssertionsTest, Throw) {
+  EXPECT_THROW(ThrowAnInteger(), int) << "unexpected failure";
+  ASSERT_THROW(ThrowAnInteger(), int) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_THROW(ThrowAnInteger(), bool) <<
+                          "expected failure", "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_THROW(ThrowAnInteger(), bool) <<
+                       "expected failure", "expected failure");
+}
+
+TEST(StreamingAssertionsTest, NoThrow) {
+  EXPECT_NO_THROW(ThrowNothing()) << "unexpected failure";
+  ASSERT_NO_THROW(ThrowNothing()) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_NO_THROW(ThrowAnInteger()) <<
+                          "expected failure", "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_NO_THROW(ThrowAnInteger()) <<
+                       "expected failure", "expected failure");
+}
+
+TEST(StreamingAssertionsTest, AnyThrow) {
+  EXPECT_ANY_THROW(ThrowAnInteger()) << "unexpected failure";
+  ASSERT_ANY_THROW(ThrowAnInteger()) << "unexpected failure";
+  EXPECT_NONFATAL_FAILURE(EXPECT_ANY_THROW(ThrowNothing()) <<
+                          "expected failure", "expected failure");
+  EXPECT_FATAL_FAILURE(ASSERT_ANY_THROW(ThrowNothing()) <<
+                       "expected failure", "expected failure");
+}
+
+#endif  // GTEST_HAS_EXCEPTIONS
+
+// Tests that Google Test correctly decides whether to use colors in the output.
+
+TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsYes) {
+  GTEST_FLAG(color) = "yes";
+
+  SetEnv("TERM", "xterm");  // TERM supports colors.
+  EXPECT_TRUE(ShouldUseColor(true));  // Stdout is a TTY.
+  EXPECT_TRUE(ShouldUseColor(false));  // Stdout is not a TTY.
+
+  SetEnv("TERM", "dumb");  // TERM doesn't support colors.
+  EXPECT_TRUE(ShouldUseColor(true));  // Stdout is a TTY.
+  EXPECT_TRUE(ShouldUseColor(false));  // Stdout is not a TTY.
+}
+
+TEST(ColoredOutputTest, UsesColorsWhenGTestColorFlagIsAliasOfYes) {
+  SetEnv("TERM", "dumb");  // TERM doesn't support colors.
+
+  GTEST_FLAG(color) = "True";
+  EXPECT_TRUE(ShouldUseColor(false));  // Stdout is not a TTY.
+
+  GTEST_FLAG(color) = "t";
+  EXPECT_TRUE(ShouldUseColor(false));  // Stdout is not a TTY.
+
+  GTEST_FLAG(color) = "1";
+  EXPECT_TRUE(ShouldUseColor(false));  // Stdout is not a TTY.
+}
+
+TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsNo) {
+  GTEST_FLAG(color) = "no";
+
+  SetEnv("TERM", "xterm");  // TERM supports colors.
+  EXPECT_FALSE(ShouldUseColor(true));  // Stdout is a TTY.
+  EXPECT_FALSE(ShouldUseColor(false));  // Stdout is not a TTY.
+
+  SetEnv("TERM", "dumb");  // TERM doesn't support colors.
+  EXPECT_FALSE(ShouldUseColor(true));  // Stdout is a TTY.
+  EXPECT_FALSE(ShouldUseColor(false));  // Stdout is not a TTY.
+}
+
+TEST(ColoredOutputTest, UsesNoColorWhenGTestColorFlagIsInvalid) {
+  SetEnv("TERM", "xterm");  // TERM supports colors.
+
+  GTEST_FLAG(color) = "F";
+  EXPECT_FALSE(ShouldUseColor(true));  // Stdout is a TTY.
+
+  GTEST_FLAG(color) = "0";
+  EXPECT_FALSE(ShouldUseColor(true));  // Stdout is a TTY.
+
+  GTEST_FLAG(color) = "unknown";
+  EXPECT_FALSE(ShouldUseColor(true));  // Stdout is a TTY.
+}
+
+TEST(ColoredOutputTest, UsesColorsWhenStdoutIsTty) {
+  GTEST_FLAG(color) = "auto";
+
+  SetEnv("TERM", "xterm");  // TERM supports colors.
+  EXPECT_FALSE(ShouldUseColor(false));  // Stdout is not a TTY.
+  EXPECT_TRUE(ShouldUseColor(true));    // Stdout is a TTY.
+}
+
+TEST(ColoredOutputTest, UsesColorsWhenTermSupportsColors) {
+  GTEST_FLAG(color) = "auto";
+
+#if GTEST_OS_WINDOWS
+  // On Windows, we ignore the TERM variable as it's usually not set.
+
+  SetEnv("TERM", "dumb");
+  EXPECT_TRUE(ShouldUseColor(true));  // Stdout is a TTY.
+
+  SetEnv("TERM", "");
+  EXPECT_TRUE(ShouldUseColor(true));  // Stdout is a TTY.
+
+  SetEnv("TERM", "xterm");
+  EXPECT_TRUE(ShouldUseColor(true));  // Stdout is a TTY.
+#else
+  // On non-Windows platforms, we rely on TERM to determine if the
+  // terminal supports colors.
+
+  SetEnv("TERM", "dumb");  // TERM doesn't support colors.
+  EXPECT_FALSE(ShouldUseColor(true));  // Stdout is a TTY.
+
+  SetEnv("TERM", "emacs");  // TERM doesn't support colors.
+  EXPECT_FALSE(ShouldUseColor(true));  // Stdout is a TTY.
+
+  SetEnv("TERM", "vt100");  // TERM doesn't support colors.
+  EXPECT_FALSE(ShouldUseColor(true));  // Stdout is a TTY.
+
+  SetEnv("TERM", "xterm-mono");  // TERM doesn't support colors.
+  EXPECT_FALSE(ShouldUseColor(true));  // Stdout is a TTY.
+
+  SetEnv("TERM", "xterm");  // TERM supports colors.
+  EXPECT_TRUE(ShouldUseColor(true));  // Stdout is a TTY.
+
+  SetEnv("TERM", "xterm-color");  // TERM supports colors.
+  EXPECT_TRUE(ShouldUseColor(true));  // Stdout is a TTY.
+
+  SetEnv("TERM", "linux");  // TERM supports colors.
+  EXPECT_TRUE(ShouldUseColor(true));  // Stdout is a TTY.
+#endif  // GTEST_OS_WINDOWS
+}
+
+// Verifies that StaticAssertTypeEq works in a namespace scope.
+
+static bool dummy1 = StaticAssertTypeEq<bool, bool>();
+static bool dummy2 = StaticAssertTypeEq<const int, const int>();
+
+// Verifies that StaticAssertTypeEq works in a class.
+
+template <typename T>
+class StaticAssertTypeEqTestHelper {
+ public:
+  StaticAssertTypeEqTestHelper() { StaticAssertTypeEq<bool, T>(); }
+};
+
+TEST(StaticAssertTypeEqTest, WorksInClass) {
+  StaticAssertTypeEqTestHelper<bool>();
+}
+
+// Verifies that StaticAssertTypeEq works inside a function.
+
+typedef int IntAlias;
+
+TEST(StaticAssertTypeEqTest, CompilesForEqualTypes) {
+  StaticAssertTypeEq<int, IntAlias>();
+  StaticAssertTypeEq<int*, IntAlias*>();
+}
+
+TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) {
+  testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
+
+  // We don't have a stack walker in Google Test yet.
+  EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str());
+  EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str());
+}
+
+TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsNoFailure) {
+  EXPECT_FALSE(HasNonfatalFailure());
+}
+
+static void FailFatally() { FAIL(); }
+
+TEST(HasNonfatalFailureTest, ReturnsFalseWhenThereIsOnlyFatalFailure) {
+  FailFatally();
+  const bool has_nonfatal_failure = HasNonfatalFailure();
+  ClearCurrentTestPartResults();
+  EXPECT_FALSE(has_nonfatal_failure);
+}
+
+TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) {
+  ADD_FAILURE();
+  const bool has_nonfatal_failure = HasNonfatalFailure();
+  ClearCurrentTestPartResults();
+  EXPECT_TRUE(has_nonfatal_failure);
+}
+
+TEST(HasNonfatalFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) {
+  FailFatally();
+  ADD_FAILURE();
+  const bool has_nonfatal_failure = HasNonfatalFailure();
+  ClearCurrentTestPartResults();
+  EXPECT_TRUE(has_nonfatal_failure);
+}
+
+// A wrapper for calling HasNonfatalFailure outside of a test body.
+static bool HasNonfatalFailureHelper() {
+  return testing::Test::HasNonfatalFailure();
+}
+
+TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody) {
+  EXPECT_FALSE(HasNonfatalFailureHelper());
+}
+
+TEST(HasNonfatalFailureTest, WorksOutsideOfTestBody2) {
+  ADD_FAILURE();
+  const bool has_nonfatal_failure = HasNonfatalFailureHelper();
+  ClearCurrentTestPartResults();
+  EXPECT_TRUE(has_nonfatal_failure);
+}
+
+TEST(HasFailureTest, ReturnsFalseWhenThereIsNoFailure) {
+  EXPECT_FALSE(HasFailure());
+}
+
+TEST(HasFailureTest, ReturnsTrueWhenThereIsFatalFailure) {
+  FailFatally();
+  const bool has_failure = HasFailure();
+  ClearCurrentTestPartResults();
+  EXPECT_TRUE(has_failure);
+}
+
+TEST(HasFailureTest, ReturnsTrueWhenThereIsNonfatalFailure) {
+  ADD_FAILURE();
+  const bool has_failure = HasFailure();
+  ClearCurrentTestPartResults();
+  EXPECT_TRUE(has_failure);
+}
+
+TEST(HasFailureTest, ReturnsTrueWhenThereAreFatalAndNonfatalFailures) {
+  FailFatally();
+  ADD_FAILURE();
+  const bool has_failure = HasFailure();
+  ClearCurrentTestPartResults();
+  EXPECT_TRUE(has_failure);
+}
+
+// A wrapper for calling HasFailure outside of a test body.
+static bool HasFailureHelper() { return testing::Test::HasFailure(); }
+
+TEST(HasFailureTest, WorksOutsideOfTestBody) {
+  EXPECT_FALSE(HasFailureHelper());
+}
+
+TEST(HasFailureTest, WorksOutsideOfTestBody2) {
+  ADD_FAILURE();
+  const bool has_failure = HasFailureHelper();
+  ClearCurrentTestPartResults();
+  EXPECT_TRUE(has_failure);
+}
+
+class TestListener : public EmptyTestEventListener {
+ public:
+  TestListener() : on_start_counter_(NULL), is_destroyed_(NULL) {}
+  TestListener(int* on_start_counter, bool* is_destroyed)
+      : on_start_counter_(on_start_counter),
+        is_destroyed_(is_destroyed) {}
+
+  virtual ~TestListener() {
+    if (is_destroyed_)
+      *is_destroyed_ = true;
+  }
+
+ protected:
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
+    if (on_start_counter_ != NULL)
+      (*on_start_counter_)++;
+  }
+
+ private:
+  int* on_start_counter_;
+  bool* is_destroyed_;
+};
+
+// Tests the constructor.
+TEST(TestEventListenersTest, ConstructionWorks) {
+  TestEventListeners listeners;
+
+  EXPECT_TRUE(TestEventListenersAccessor::GetRepeater(&listeners) != NULL);
+  EXPECT_TRUE(listeners.default_result_printer() == NULL);
+  EXPECT_TRUE(listeners.default_xml_generator() == NULL);
+}
+
+// Tests that the TestEventListeners destructor deletes all the listeners it
+// owns.
+TEST(TestEventListenersTest, DestructionWorks) {
+  bool default_result_printer_is_destroyed = false;
+  bool default_xml_printer_is_destroyed = false;
+  bool extra_listener_is_destroyed = false;
+  TestListener* default_result_printer = new TestListener(
+      NULL, &default_result_printer_is_destroyed);
+  TestListener* default_xml_printer = new TestListener(
+      NULL, &default_xml_printer_is_destroyed);
+  TestListener* extra_listener = new TestListener(
+      NULL, &extra_listener_is_destroyed);
+
+  {
+    TestEventListeners listeners;
+    TestEventListenersAccessor::SetDefaultResultPrinter(&listeners,
+                                                        default_result_printer);
+    TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners,
+                                                       default_xml_printer);
+    listeners.Append(extra_listener);
+  }
+  EXPECT_TRUE(default_result_printer_is_destroyed);
+  EXPECT_TRUE(default_xml_printer_is_destroyed);
+  EXPECT_TRUE(extra_listener_is_destroyed);
+}
+
+// Tests that a listener Append'ed to a TestEventListeners list starts
+// receiving events.
+TEST(TestEventListenersTest, Append) {
+  int on_start_counter = 0;
+  bool is_destroyed = false;
+  TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
+  {
+    TestEventListeners listeners;
+    listeners.Append(listener);
+    TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
+        *UnitTest::GetInstance());
+    EXPECT_EQ(1, on_start_counter);
+  }
+  EXPECT_TRUE(is_destroyed);
+}
+
+// Tests that listeners receive events in the order they were appended to
+// the list, except for *End requests, which must be received in the reverse
+// order.
+class SequenceTestingListener : public EmptyTestEventListener {
+ public:
+  SequenceTestingListener(std::vector<String>* vector, const char* id)
+      : vector_(vector), id_(id) {}
+
+ protected:
+  virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {
+    vector_->push_back(GetEventDescription("OnTestProgramStart"));
+  }
+
+  virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {
+    vector_->push_back(GetEventDescription("OnTestProgramEnd"));
+  }
+
+  virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
+                                    int /*iteration*/) {
+    vector_->push_back(GetEventDescription("OnTestIterationStart"));
+  }
+
+  virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
+                                  int /*iteration*/) {
+    vector_->push_back(GetEventDescription("OnTestIterationEnd"));
+  }
+
+ private:
+  String GetEventDescription(const char* method) {
+    Message message;
+    message << id_ << "." << method;
+    return message.GetString();
+  }
+
+  std::vector<String>* vector_;
+  const char* const id_;
+
+  GTEST_DISALLOW_COPY_AND_ASSIGN_(SequenceTestingListener);
+};
+
+TEST(EventListenerTest, AppendKeepsOrder) {
+  std::vector<String> vec;
+  TestEventListeners listeners;
+  listeners.Append(new SequenceTestingListener(&vec, "1st"));
+  listeners.Append(new SequenceTestingListener(&vec, "2nd"));
+  listeners.Append(new SequenceTestingListener(&vec, "3rd"));
+
+  TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
+      *UnitTest::GetInstance());
+  ASSERT_EQ(3U, vec.size());
+  EXPECT_STREQ("1st.OnTestProgramStart", vec[0].c_str());
+  EXPECT_STREQ("2nd.OnTestProgramStart", vec[1].c_str());
+  EXPECT_STREQ("3rd.OnTestProgramStart", vec[2].c_str());
+
+  vec.clear();
+  TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramEnd(
+      *UnitTest::GetInstance());
+  ASSERT_EQ(3U, vec.size());
+  EXPECT_STREQ("3rd.OnTestProgramEnd", vec[0].c_str());
+  EXPECT_STREQ("2nd.OnTestProgramEnd", vec[1].c_str());
+  EXPECT_STREQ("1st.OnTestProgramEnd", vec[2].c_str());
+
+  vec.clear();
+  TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationStart(
+      *UnitTest::GetInstance(), 0);
+  ASSERT_EQ(3U, vec.size());
+  EXPECT_STREQ("1st.OnTestIterationStart", vec[0].c_str());
+  EXPECT_STREQ("2nd.OnTestIterationStart", vec[1].c_str());
+  EXPECT_STREQ("3rd.OnTestIterationStart", vec[2].c_str());
+
+  vec.clear();
+  TestEventListenersAccessor::GetRepeater(&listeners)->OnTestIterationEnd(
+      *UnitTest::GetInstance(), 0);
+  ASSERT_EQ(3U, vec.size());
+  EXPECT_STREQ("3rd.OnTestIterationEnd", vec[0].c_str());
+  EXPECT_STREQ("2nd.OnTestIterationEnd", vec[1].c_str());
+  EXPECT_STREQ("1st.OnTestIterationEnd", vec[2].c_str());
+}
+
+// Tests that a listener removed from a TestEventListeners list stops receiving
+// events and is not deleted when the list is destroyed.
+TEST(TestEventListenersTest, Release) {
+  int on_start_counter = 0;
+  bool is_destroyed = false;
+  // Although Append passes the ownership of this object to the list,
+  // the following calls release it, and we need to delete it before the
+  // test ends.
+  TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
+  {
+    TestEventListeners listeners;
+    listeners.Append(listener);
+    EXPECT_EQ(listener, listeners.Release(listener));
+    TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
+        *UnitTest::GetInstance());
+    EXPECT_TRUE(listeners.Release(listener) == NULL);
+  }
+  EXPECT_EQ(0, on_start_counter);
+  EXPECT_FALSE(is_destroyed);
+  delete listener;
+}
+
+// Tests that no events are forwarded when event forwarding is disabled.
+TEST(EventListenerTest, SuppressEventForwarding) {
+  int on_start_counter = 0;
+  TestListener* listener = new TestListener(&on_start_counter, NULL);
+
+  TestEventListeners listeners;
+  listeners.Append(listener);
+  ASSERT_TRUE(TestEventListenersAccessor::EventForwardingEnabled(listeners));
+  TestEventListenersAccessor::SuppressEventForwarding(&listeners);
+  ASSERT_FALSE(TestEventListenersAccessor::EventForwardingEnabled(listeners));
+  TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
+      *UnitTest::GetInstance());
+  EXPECT_EQ(0, on_start_counter);
+}
+
+// Tests that events generated by Google Test are not forwarded in
+// death test subprocesses.
+TEST(EventListenerDeathTest, EventsNotForwardedInDeathTestSubprecesses) {
+  EXPECT_DEATH_IF_SUPPORTED({
+      GTEST_CHECK_(TestEventListenersAccessor::EventForwardingEnabled(
+          *GetUnitTestImpl()->listeners())) << "expected failure";},
+      "expected failure");
+}
+
+// Tests that a listener installed via SetDefaultResultPrinter() starts
+// receiving events and is returned via default_result_printer() and that
+// the previous default_result_printer is removed from the list and deleted.
+TEST(EventListenerTest, default_result_printer) {
+  int on_start_counter = 0;
+  bool is_destroyed = false;
+  TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
+
+  TestEventListeners listeners;
+  TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener);
+
+  EXPECT_EQ(listener, listeners.default_result_printer());
+
+  TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
+      *UnitTest::GetInstance());
+
+  EXPECT_EQ(1, on_start_counter);
+
+  // Replacing default_result_printer with something else should remove it
+  // from the list and destroy it.
+  TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, NULL);
+
+  EXPECT_TRUE(listeners.default_result_printer() == NULL);
+  EXPECT_TRUE(is_destroyed);
+
+  // After broadcasting an event the counter is still the same, indicating
+  // the listener is not in the list anymore.
+  TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
+      *UnitTest::GetInstance());
+  EXPECT_EQ(1, on_start_counter);
+}
+
+// Tests that the default_result_printer listener stops receiving events
+// when removed via Release and that is not owned by the list anymore.
+TEST(EventListenerTest, RemovingDefaultResultPrinterWorks) {
+  int on_start_counter = 0;
+  bool is_destroyed = false;
+  // Although Append passes the ownership of this object to the list,
+  // the following calls release it, and we need to delete it before the
+  // test ends.
+  TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
+  {
+    TestEventListeners listeners;
+    TestEventListenersAccessor::SetDefaultResultPrinter(&listeners, listener);
+
+    EXPECT_EQ(listener, listeners.Release(listener));
+    EXPECT_TRUE(listeners.default_result_printer() == NULL);
+    EXPECT_FALSE(is_destroyed);
+
+    // Broadcasting events now should not affect default_result_printer.
+    TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
+        *UnitTest::GetInstance());
+    EXPECT_EQ(0, on_start_counter);
+  }
+  // Destroying the list should not affect the listener now, too.
+  EXPECT_FALSE(is_destroyed);
+  delete listener;
+}
+
+// Tests that a listener installed via SetDefaultXmlGenerator() starts
+// receiving events and is returned via default_xml_generator() and that
+// the previous default_xml_generator is removed from the list and deleted.
+TEST(EventListenerTest, default_xml_generator) {
+  int on_start_counter = 0;
+  bool is_destroyed = false;
+  TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
+
+  TestEventListeners listeners;
+  TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener);
+
+  EXPECT_EQ(listener, listeners.default_xml_generator());
+
+  TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
+      *UnitTest::GetInstance());
+
+  EXPECT_EQ(1, on_start_counter);
+
+  // Replacing default_xml_generator with something else should remove it
+  // from the list and destroy it.
+  TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, NULL);
+
+  EXPECT_TRUE(listeners.default_xml_generator() == NULL);
+  EXPECT_TRUE(is_destroyed);
+
+  // After broadcasting an event the counter is still the same, indicating
+  // the listener is not in the list anymore.
+  TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
+      *UnitTest::GetInstance());
+  EXPECT_EQ(1, on_start_counter);
+}
+
+// Tests that the default_xml_generator listener stops receiving events
+// when removed via Release and that is not owned by the list anymore.
+TEST(EventListenerTest, RemovingDefaultXmlGeneratorWorks) {
+  int on_start_counter = 0;
+  bool is_destroyed = false;
+  // Although Append passes the ownership of this object to the list,
+  // the following calls release it, and we need to delete it before the
+  // test ends.
+  TestListener* listener = new TestListener(&on_start_counter, &is_destroyed);
+  {
+    TestEventListeners listeners;
+    TestEventListenersAccessor::SetDefaultXmlGenerator(&listeners, listener);
+
+    EXPECT_EQ(listener, listeners.Release(listener));
+    EXPECT_TRUE(listeners.default_xml_generator() == NULL);
+    EXPECT_FALSE(is_destroyed);
+
+    // Broadcasting events now should not affect default_xml_generator.
+    TestEventListenersAccessor::GetRepeater(&listeners)->OnTestProgramStart(
+        *UnitTest::GetInstance());
+    EXPECT_EQ(0, on_start_counter);
+  }
+  // Destroying the list should not affect the listener now, too.
+  EXPECT_FALSE(is_destroyed);
+  delete listener;
+}
+
+// Sanity tests to ensure that the alternative, verbose spellings of
+// some of the macros work.  We don't test them thoroughly as that
+// would be quite involved.  Since their implementations are
+// straightforward, and they are rarely used, we'll just rely on the
+// users to tell us when they are broken.
+GTEST_TEST(AlternativeNameTest, Works) {  // GTEST_TEST is the same as TEST.
+  GTEST_SUCCEED() << "OK";  // GTEST_SUCCEED is the same as SUCCEED.
+
+  // GTEST_FAIL is the same as FAIL.
+  EXPECT_FATAL_FAILURE(GTEST_FAIL() << "An expected failure",
+                       "An expected failure");
+}
diff --git a/protobuf/gtest/test/gtest_xml_outfile1_test_.cc b/protobuf/gtest/test/gtest_xml_outfile1_test_.cc
new file mode 100644
index 0000000..664baad
--- /dev/null
+++ b/protobuf/gtest/test/gtest_xml_outfile1_test_.cc
@@ -0,0 +1,49 @@
+// 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)
+//
+// gtest_xml_outfile1_test_ writes some xml via TestProperty used by
+// gtest_xml_outfiles_test.py
+
+#include <gtest/gtest.h>
+
+class PropertyOne : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    RecordProperty("SetUpProp", 1);
+  }
+  virtual void TearDown() {
+    RecordProperty("TearDownProp", 1);
+  }
+};
+
+TEST_F(PropertyOne, TestSomeProperties) {
+  RecordProperty("TestSomeProperty", 1);
+}
diff --git a/protobuf/gtest/test/gtest_xml_outfile2_test_.cc b/protobuf/gtest/test/gtest_xml_outfile2_test_.cc
new file mode 100644
index 0000000..3411a3d
--- /dev/null
+++ b/protobuf/gtest/test/gtest_xml_outfile2_test_.cc
@@ -0,0 +1,49 @@
+// 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)
+//
+// gtest_xml_outfile2_test_ writes some xml via TestProperty used by
+// gtest_xml_outfiles_test.py
+
+#include <gtest/gtest.h>
+
+class PropertyTwo : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    RecordProperty("SetUpProp", 2);
+  }
+  virtual void TearDown() {
+    RecordProperty("TearDownProp", 2);
+  }
+};
+
+TEST_F(PropertyTwo, TestSomeProperties) {
+  RecordProperty("TestSomeProperty", 2);
+}
diff --git a/protobuf/gtest/test/gtest_xml_outfiles_test.py b/protobuf/gtest/test/gtest_xml_outfiles_test.py
new file mode 100755
index 0000000..0fe947f
--- /dev/null
+++ b/protobuf/gtest/test/gtest_xml_outfiles_test.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Unit test for the gtest_xml_output module."""
+
+__author__ = "keith.ray@gmail.com (Keith Ray)"
+
+import os
+from xml.dom import minidom, Node
+
+import gtest_test_utils
+import gtest_xml_test_utils
+
+
+GTEST_OUTPUT_SUBDIR = "xml_outfiles"
+GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_"
+GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_"
+
+EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?>
+<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" name="AllTests">
+  <testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*">
+    <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyOne" SetUpProp="1" TestSomeProperty="1" TearDownProp="1" />
+  </testsuite>
+</testsuites>
+"""
+
+EXPECTED_XML_2 = """<?xml version="1.0" encoding="UTF-8"?>
+<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" name="AllTests">
+  <testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*">
+    <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyTwo" SetUpProp="2" TestSomeProperty="2" TearDownProp="2" />
+  </testsuite>
+</testsuites>
+"""
+
+
+class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase):
+  """Unit test for Google Test's XML output functionality."""
+
+  def setUp(self):
+    # We want the trailing '/' that the last "" provides in os.path.join, for
+    # telling Google Test to create an output directory instead of a single file
+    # for xml output.
+    self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(),
+                                    GTEST_OUTPUT_SUBDIR, "")
+    self.DeleteFilesAndDir()
+
+  def tearDown(self):
+    self.DeleteFilesAndDir()
+
+  def DeleteFilesAndDir(self):
+    try:
+      os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_1_TEST + ".xml"))
+    except os.error:
+      pass
+    try:
+      os.remove(os.path.join(self.output_dir_, GTEST_OUTPUT_2_TEST + ".xml"))
+    except os.error:
+      pass
+    try:
+      os.rmdir(self.output_dir_)
+    except os.error:
+      pass
+
+  def testOutfile1(self):
+    self._TestOutFile(GTEST_OUTPUT_1_TEST, EXPECTED_XML_1)
+
+  def testOutfile2(self):
+    self._TestOutFile(GTEST_OUTPUT_2_TEST, EXPECTED_XML_2)
+
+  def _TestOutFile(self, test_name, expected_xml):
+    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name)
+    command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_]
+    p = gtest_test_utils.Subprocess(command,
+                                    working_dir=gtest_test_utils.GetTempDir())
+    self.assert_(p.exited)
+    self.assertEquals(0, p.exit_code)
+
+    # TODO(wan@google.com): libtool causes the built test binary to be
+    #   named lt-gtest_xml_outfiles_test_ instead of
+    #   gtest_xml_outfiles_test_.  To account for this possibillity, we
+    #   allow both names in the following code.  We should remove this
+    #   hack when Chandler Carruth's libtool replacement tool is ready.
+    output_file_name1 = test_name + ".xml"
+    output_file1 = os.path.join(self.output_dir_, output_file_name1)
+    output_file_name2 = 'lt-' + output_file_name1
+    output_file2 = os.path.join(self.output_dir_, output_file_name2)
+    self.assert_(os.path.isfile(output_file1) or os.path.isfile(output_file2),
+                 output_file1)
+
+    expected = minidom.parseString(expected_xml)
+    if os.path.isfile(output_file1):
+      actual = minidom.parse(output_file1)
+    else:
+      actual = minidom.parse(output_file2)
+    self.NormalizeXml(actual.documentElement)
+    self.AssertEquivalentNodes(expected.documentElement,
+                               actual.documentElement)
+    expected.unlink()
+    actual.unlink()
+
+
+if __name__ == "__main__":
+  os.environ["GTEST_STACK_TRACE_DEPTH"] = "0"
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_xml_output_unittest.py b/protobuf/gtest/test/gtest_xml_output_unittest.py
new file mode 100755
index 0000000..6d44929
--- /dev/null
+++ b/protobuf/gtest/test/gtest_xml_output_unittest.py
@@ -0,0 +1,224 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Unit test for the gtest_xml_output module"""
+
+__author__ = 'eefacm@gmail.com (Sean Mcafee)'
+
+import errno
+import os
+import sys
+from xml.dom import minidom, Node
+
+import gtest_test_utils
+import gtest_xml_test_utils
+
+
+GTEST_OUTPUT_FLAG         = "--gtest_output"
+GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
+GTEST_PROGRAM_NAME = "gtest_xml_output_unittest_"
+
+SUPPORTS_STACK_TRACES = False
+
+if SUPPORTS_STACK_TRACES:
+  STACK_TRACE_TEMPLATE = "\nStack trace:\n*"
+else:
+  STACK_TRACE_TEMPLATE = ""
+
+EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
+<testsuites tests="15" failures="4" disabled="2" errors="0" time="*" name="AllTests">
+  <testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
+    <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
+  </testsuite>
+  <testsuite name="FailedTest" tests="1" failures="1" disabled="0" errors="0" time="*">
+    <testcase name="Fails" status="run" time="*" classname="FailedTest">
+      <failure message="Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
+Value of: 2
+Expected: 1%(stack)s]]></failure>
+    </testcase>
+  </testsuite>
+  <testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
+    <testcase name="Succeeds" status="run" time="*" classname="MixedResultTest"/>
+    <testcase name="Fails" status="run" time="*" classname="MixedResultTest">
+      <failure message="Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
+Value of: 2
+Expected: 1%(stack)s]]></failure>
+      <failure message="Value of: 3&#x0A;Expected: 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
+Value of: 3
+Expected: 2%(stack)s]]></failure>
+    </testcase>
+    <testcase name="DISABLED_test" status="notrun" time="*" classname="MixedResultTest"/>
+  </testsuite>
+  <testsuite name="XmlQuotingTest" tests="1" failures="1" disabled="0" errors="0" time="*">
+    <testcase name="OutputsCData" status="run" time="*" classname="XmlQuotingTest">
+      <failure message="Failed&#x0A;XML output: &lt;?xml encoding=&quot;utf-8&quot;&gt;&lt;top&gt;&lt;![CDATA[cdata text]]&gt;&lt;/top&gt;" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
+Failed
+XML output: <?xml encoding="utf-8"><top><![CDATA[cdata text]]>]]&gt;<![CDATA[</top>%(stack)s]]></failure>
+    </testcase>
+  </testsuite>
+  <testsuite name="InvalidCharactersTest" tests="1" failures="1" disabled="0" errors="0" time="*">
+    <testcase name="InvalidCharactersInMessage" status="run" time="*" classname="InvalidCharactersTest">
+      <failure message="Failed&#x0A;Invalid characters in brackets []" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
+Failed
+Invalid characters in brackets []%(stack)s]]></failure>
+    </testcase>
+  </testsuite>
+  <testsuite name="DisabledTest" tests="1" failures="0" disabled="1" errors="0" time="*">
+    <testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/>
+  </testsuite>
+  <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*">
+    <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/>
+    <testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/>
+    <testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/>
+    <testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest" key_1="2"/>
+  </testsuite>
+  <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*">
+     <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/>
+     <testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/>
+     <testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/>
+  </testsuite>
+</testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}
+
+
+EXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
+<testsuites tests="0" failures="0" disabled="0" errors="0" time="*" name="AllTests">
+</testsuites>"""
+
+
+class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
+  """
+  Unit test for Google Test's XML output functionality.
+  """
+
+  def testNonEmptyXmlOutput(self):
+    """
+    Runs a test program that generates a non-empty XML output, and
+    tests that the XML output is expected.
+    """
+    self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1)
+
+  def testEmptyXmlOutput(self):
+    """
+    Runs a test program that generates an empty XML output, and
+    tests that the XML output is expected.
+    """
+
+    self._TestXmlOutput("gtest_no_test_unittest",
+                        EXPECTED_EMPTY_XML, 0)
+
+  def testDefaultOutputFile(self):
+    """
+    Confirms that Google Test produces an XML output file with the expected
+    default name if no name is explicitly specified.
+    """
+    output_file = os.path.join(gtest_test_utils.GetTempDir(),
+                               GTEST_DEFAULT_OUTPUT_FILE)
+    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
+        "gtest_no_test_unittest")
+    try:
+      os.remove(output_file)
+    except OSError, e:
+      if e.errno != errno.ENOENT:
+        raise
+
+    p = gtest_test_utils.Subprocess(
+        [gtest_prog_path, "%s=xml" % GTEST_OUTPUT_FLAG],
+        working_dir=gtest_test_utils.GetTempDir())
+    self.assert_(p.exited)
+    self.assertEquals(0, p.exit_code)
+    self.assert_(os.path.isfile(output_file))
+
+  def testSuppressedXmlOutput(self):
+    """
+    Tests that no XML file is generated if the default XML listener is
+    shut down before RUN_ALL_TESTS is invoked.
+    """
+
+    xml_path = os.path.join(gtest_test_utils.GetTempDir(),
+                            GTEST_PROGRAM_NAME + "out.xml")
+    if os.path.isfile(xml_path):
+      os.remove(xml_path)
+
+    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME)
+
+    command = [gtest_prog_path,
+               "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path),
+               "--shut_down_xml"]
+    p = gtest_test_utils.Subprocess(command)
+    if p.terminated_by_signal:
+      self.assert_(False,
+                   "%s was killed by signal %d" % (gtest_prog_name, p.signal))
+    else:
+      self.assert_(p.exited)
+      self.assertEquals(1, p.exit_code,
+                        "'%s' exited with code %s, which doesn't match "
+                        "the expected exit code %s."
+                        % (command, p.exit_code, 1))
+
+    self.assert_(not os.path.isfile(xml_path))
+
+
+  def _TestXmlOutput(self, gtest_prog_name, expected_xml, expected_exit_code):
+    """
+    Asserts that the XML document generated by running the program
+    gtest_prog_name matches expected_xml, a string containing another
+    XML document.  Furthermore, the program's exit code must be
+    expected_exit_code.
+    """
+    xml_path = os.path.join(gtest_test_utils.GetTempDir(),
+                            gtest_prog_name + "out.xml")
+    gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
+
+    command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)]
+    p = gtest_test_utils.Subprocess(command)
+    if p.terminated_by_signal:
+      self.assert_(False,
+                   "%s was killed by signal %d" % (gtest_prog_name, p.signal))
+    else:
+      self.assert_(p.exited)
+      self.assertEquals(expected_exit_code, p.exit_code,
+                        "'%s' exited with code %s, which doesn't match "
+                        "the expected exit code %s."
+                        % (command, p.exit_code, expected_exit_code))
+
+    expected = minidom.parseString(expected_xml)
+    actual   = minidom.parse(xml_path)
+    self.NormalizeXml(actual.documentElement)
+    self.AssertEquivalentNodes(expected.documentElement,
+                               actual.documentElement)
+    expected.unlink()
+    actual  .unlink()
+
+
+
+if __name__ == '__main__':
+  os.environ['GTEST_STACK_TRACE_DEPTH'] = '1'
+  gtest_test_utils.Main()
diff --git a/protobuf/gtest/test/gtest_xml_output_unittest_.cc b/protobuf/gtest/test/gtest_xml_output_unittest_.cc
new file mode 100644
index 0000000..fc07ef4
--- /dev/null
+++ b/protobuf/gtest/test/gtest_xml_output_unittest_.cc
@@ -0,0 +1,145 @@
+// 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: eefacm@gmail.com (Sean Mcafee)
+
+// Unit test for Google Test XML output.
+//
+// A user can specify XML output in a Google Test program to run via
+// either the GTEST_OUTPUT environment variable or the --gtest_output
+// flag.  This is used for testing such functionality.
+//
+// This program will be invoked from a Python unit test.  Don't run it
+// directly.
+
+#include <gtest/gtest.h>
+
+using ::testing::InitGoogleTest;
+using ::testing::TestEventListeners;
+using ::testing::UnitTest;
+
+class SuccessfulTest : public testing::Test {
+};
+
+TEST_F(SuccessfulTest, Succeeds) {
+  SUCCEED() << "This is a success.";
+  ASSERT_EQ(1, 1);
+}
+
+class FailedTest : public testing::Test {
+};
+
+TEST_F(FailedTest, Fails) {
+  ASSERT_EQ(1, 2);
+}
+
+class DisabledTest : public testing::Test {
+};
+
+TEST_F(DisabledTest, DISABLED_test_not_run) {
+  FAIL() << "Unexpected failure: Disabled test should not be run";
+}
+
+TEST(MixedResultTest, Succeeds) {
+  EXPECT_EQ(1, 1);
+  ASSERT_EQ(1, 1);
+}
+
+TEST(MixedResultTest, Fails) {
+  EXPECT_EQ(1, 2);
+  ASSERT_EQ(2, 3);
+}
+
+TEST(MixedResultTest, DISABLED_test) {
+  FAIL() << "Unexpected failure: Disabled test should not be run";
+}
+
+TEST(XmlQuotingTest, OutputsCData) {
+  FAIL() << "XML output: "
+            "<?xml encoding=\"utf-8\"><top><![CDATA[cdata text]]></top>";
+}
+
+// Helps to test that invalid characters produced by test code do not make
+// it into the XML file.
+TEST(InvalidCharactersTest, InvalidCharactersInMessage) {
+  FAIL() << "Invalid characters in brackets [\x1\x2]";
+}
+
+class PropertyRecordingTest : public testing::Test {
+};
+
+TEST_F(PropertyRecordingTest, OneProperty) {
+  RecordProperty("key_1", "1");
+}
+
+TEST_F(PropertyRecordingTest, IntValuedProperty) {
+  RecordProperty("key_int", 1);
+}
+
+TEST_F(PropertyRecordingTest, ThreeProperties) {
+  RecordProperty("key_1", "1");
+  RecordProperty("key_2", "2");
+  RecordProperty("key_3", "3");
+}
+
+TEST_F(PropertyRecordingTest, TwoValuesForOneKeyUsesLastValue) {
+  RecordProperty("key_1", "1");
+  RecordProperty("key_1", "2");
+}
+
+TEST(NoFixtureTest, RecordProperty) {
+  RecordProperty("key", "1");
+}
+
+void ExternalUtilityThatCallsRecordProperty(const char* key, int value) {
+  testing::Test::RecordProperty(key, value);
+}
+
+void ExternalUtilityThatCallsRecordProperty(const char* key,
+                                            const char* value) {
+  testing::Test::RecordProperty(key, value);
+}
+
+TEST(NoFixtureTest, ExternalUtilityThatCallsRecordIntValuedProperty) {
+  ExternalUtilityThatCallsRecordProperty("key_for_utility_int", 1);
+}
+
+TEST(NoFixtureTest, ExternalUtilityThatCallsRecordStringValuedProperty) {
+  ExternalUtilityThatCallsRecordProperty("key_for_utility_string", "1");
+}
+
+int main(int argc, char** argv) {
+  InitGoogleTest(&argc, argv);
+
+  if (argc > 1 && strcmp(argv[1], "--shut_down_xml") == 0) {
+    TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
+    delete listeners.Release(listeners.default_xml_generator());
+  }
+  return RUN_ALL_TESTS();
+}
diff --git a/protobuf/gtest/test/gtest_xml_test_utils.py b/protobuf/gtest/test/gtest_xml_test_utils.py
new file mode 100755
index 0000000..c83c3b7
--- /dev/null
+++ b/protobuf/gtest/test/gtest_xml_test_utils.py
@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Unit test utilities for gtest_xml_output"""
+
+__author__ = 'eefacm@gmail.com (Sean Mcafee)'
+
+import re
+from xml.dom import minidom, Node
+
+import gtest_test_utils
+
+
+GTEST_OUTPUT_FLAG         = "--gtest_output"
+GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
+
+class GTestXMLTestCase(gtest_test_utils.TestCase):
+  """
+  Base class for tests of Google Test's XML output functionality.
+  """
+
+
+  def AssertEquivalentNodes(self, expected_node, actual_node):
+    """
+    Asserts that actual_node (a DOM node object) is equivalent to
+    expected_node (another DOM node object), in that either both of
+    them are CDATA nodes and have the same value, or both are DOM
+    elements and actual_node meets all of the following conditions:
+
+    *  It has the same tag name as expected_node.
+    *  It has the same set of attributes as expected_node, each with
+       the same value as the corresponding attribute of expected_node.
+       An exception is any attribute named "time", which needs only be
+       convertible to a floating-point number.
+    *  It has an equivalent set of child nodes (including elements and
+       CDATA sections) as expected_node.  Note that we ignore the
+       order of the children as they are not guaranteed to be in any
+       particular order.
+    """
+
+    if expected_node.nodeType == Node.CDATA_SECTION_NODE:
+      self.assertEquals(Node.CDATA_SECTION_NODE, actual_node.nodeType)
+      self.assertEquals(expected_node.nodeValue, actual_node.nodeValue)
+      return
+
+    self.assertEquals(Node.ELEMENT_NODE, actual_node.nodeType)
+    self.assertEquals(Node.ELEMENT_NODE, expected_node.nodeType)
+    self.assertEquals(expected_node.tagName, actual_node.tagName)
+
+    expected_attributes = expected_node.attributes
+    actual_attributes   = actual_node  .attributes
+    self.assertEquals(
+        expected_attributes.length, actual_attributes.length,
+        "attribute numbers differ in element " + actual_node.tagName)
+    for i in range(expected_attributes.length):
+      expected_attr = expected_attributes.item(i)
+      actual_attr   = actual_attributes.get(expected_attr.name)
+      self.assert_(
+          actual_attr is not None,
+          "expected attribute %s not found in element %s" %
+          (expected_attr.name, actual_node.tagName))
+      self.assertEquals(expected_attr.value, actual_attr.value,
+                        " values of attribute %s in element %s differ" %
+                        (expected_attr.name, actual_node.tagName))
+
+    expected_children = self._GetChildren(expected_node)
+    actual_children = self._GetChildren(actual_node)
+    self.assertEquals(
+        len(expected_children), len(actual_children),
+        "number of child elements differ in element " + actual_node.tagName)
+    for child_id, child in expected_children.iteritems():
+      self.assert_(child_id in actual_children,
+                   '<%s> is not in <%s> (in element %s)' %
+                   (child_id, actual_children, actual_node.tagName))
+      self.AssertEquivalentNodes(child, actual_children[child_id])
+
+  identifying_attribute = {
+    "testsuites": "name",
+    "testsuite": "name",
+    "testcase":  "name",
+    "failure":   "message",
+    }
+
+  def _GetChildren(self, element):
+    """
+    Fetches all of the child nodes of element, a DOM Element object.
+    Returns them as the values of a dictionary keyed by the IDs of the
+    children.  For <testsuites>, <testsuite> and <testcase> elements, the ID
+    is the value of their "name" attribute; for <failure> elements, it is
+    the value of the "message" attribute; CDATA sections and non-whitespace
+    text nodes are concatenated into a single CDATA section with ID
+    "detail".  An exception is raised if any element other than the above
+    four is encountered, if two child elements with the same identifying
+    attributes are encountered, or if any other type of node is encountered.
+    """
+
+    children = {}
+    for child in element.childNodes:
+      if child.nodeType == Node.ELEMENT_NODE:
+        self.assert_(child.tagName in self.identifying_attribute,
+                     "Encountered unknown element <%s>" % child.tagName)
+        childID = child.getAttribute(self.identifying_attribute[child.tagName])
+        self.assert_(childID not in children)
+        children[childID] = child
+      elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]:
+        if "detail" not in children:
+          if (child.nodeType == Node.CDATA_SECTION_NODE or
+              not child.nodeValue.isspace()):
+            children["detail"] = child.ownerDocument.createCDATASection(
+                child.nodeValue)
+        else:
+          children["detail"].nodeValue += child.nodeValue
+      else:
+        self.fail("Encountered unexpected node type %d" % child.nodeType)
+    return children
+
+  def NormalizeXml(self, element):
+    """
+    Normalizes Google Test's XML output to eliminate references to transient
+    information that may change from run to run.
+
+    *  The "time" attribute of <testsuites>, <testsuite> and <testcase>
+       elements is replaced with a single asterisk, if it contains
+       only digit characters.
+    *  The line number reported in the first line of the "message"
+       attribute of <failure> elements is replaced with a single asterisk.
+    *  The directory names in file paths are removed.
+    *  The stack traces are removed.
+    """
+
+    if element.tagName in ("testsuites", "testsuite", "testcase"):
+      time = element.getAttributeNode("time")
+      time.value = re.sub(r"^\d+(\.\d+)?$", "*", time.value)
+    elif element.tagName == "failure":
+      for child in element.childNodes:
+        if child.nodeType == Node.CDATA_SECTION_NODE:
+          # Removes the source line number.
+          cdata = re.sub(r"^.*[/\\](.*:)\d+\n", "\\1*\n", child.nodeValue)
+          # Removes the actual stack trace.
+          child.nodeValue = re.sub(r"\nStack trace:\n(.|\n)*",
+                                   "", cdata)
+    for child in element.childNodes:
+      if child.nodeType == Node.ELEMENT_NODE:
+        self.NormalizeXml(child)
diff --git a/protobuf/gtest/test/production.cc b/protobuf/gtest/test/production.cc
new file mode 100644
index 0000000..8b8a40b
--- /dev/null
+++ b/protobuf/gtest/test/production.cc
@@ -0,0 +1,36 @@
+// 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)
+//
+// This is part of the unit test for include/gtest/gtest_prod.h.
+
+#include "production.h"
+
+PrivateCode::PrivateCode() : x_(0) {}
diff --git a/protobuf/gtest/test/production.h b/protobuf/gtest/test/production.h
new file mode 100644
index 0000000..8f16fff
--- /dev/null
+++ b/protobuf/gtest/test/production.h
@@ -0,0 +1,55 @@
+// 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)
+//
+// This is part of the unit test for include/gtest/gtest_prod.h.
+
+#ifndef GTEST_TEST_PRODUCTION_H_
+#define GTEST_TEST_PRODUCTION_H_
+
+#include <gtest/gtest_prod.h>
+
+class PrivateCode {
+ public:
+  // Declares a friend test that does not use a fixture.
+  FRIEND_TEST(PrivateCodeTest, CanAccessPrivateMembers);
+
+  // Declares a friend test that uses a fixture.
+  FRIEND_TEST(PrivateCodeFixtureTest, CanAccessPrivateMembers);
+
+  PrivateCode();
+
+  int x() const { return x_; }
+ private:
+  void set_x(int an_x) { x_ = an_x; }
+  int x_;
+};
+
+#endif  // GTEST_TEST_PRODUCTION_H_
diff --git a/protobuf/gtest/test/run_tests_util.py b/protobuf/gtest/test/run_tests_util.py
new file mode 100755
index 0000000..9e57931
--- /dev/null
+++ b/protobuf/gtest/test/run_tests_util.py
@@ -0,0 +1,466 @@
+# 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.
+
+"""Provides facilities for running SCons-built Google Test/Mock tests."""
+
+
+import optparse
+import os
+import re
+import sets
+import sys
+
+try:
+  # subrocess module is a preferable way to invoke subprocesses but it may
+  # not be available on MacOS X 10.4.
+  # Suppresses the 'Import not at the top of the file' lint complaint.
+  # pylint: disable-msg=C6204
+  import subprocess
+except ImportError:
+  subprocess = None
+
+HELP_MSG = """Runs the specified tests for %(proj)s.
+
+SYNOPSIS
+       run_tests.py [OPTION]... [BUILD_DIR]... [TEST]...
+
+DESCRIPTION
+       Runs the specified tests (either binary or Python), and prints a
+       summary of the results. BUILD_DIRS will be used to search for the
+       binaries. If no TESTs are specified, all binary tests found in
+       BUILD_DIRs and all Python tests found in the directory test/ (in the
+       %(proj)s root) are run.
+
+       TEST is a name of either a binary or a Python test. A binary test is
+       an executable file named *_test or *_unittest (with the .exe
+       extension on Windows) A Python test is a script named *_test.py or
+       *_unittest.py.
+
+OPTIONS
+       -h, --help
+              Print this help message.
+       -c CONFIGURATIONS
+              Specify build directories via build configurations.
+              CONFIGURATIONS is either a comma-separated list of build
+              configurations or 'all'. Each configuration is equivalent to
+              adding 'scons/build/<configuration>/%(proj)s/scons' to BUILD_DIRs.
+              Specifying -c=all is equivalent to providing all directories
+              listed in KNOWN BUILD DIRECTORIES section below.
+       -a
+              Equivalent to -c=all
+       -b
+              Equivalent to -c=all with the exception that the script will not
+              fail if some of the KNOWN BUILD DIRECTORIES do not exists; the
+              script will simply not run the tests there. 'b' stands for
+              'built directories'.
+
+RETURN VALUE
+       Returns 0 if all tests are successful; otherwise returns 1.
+
+EXAMPLES
+       run_tests.py
+              Runs all tests for the default build configuration.
+       run_tests.py -a
+              Runs all tests with binaries in KNOWN BUILD DIRECTORIES.
+       run_tests.py -b
+              Runs all tests in KNOWN BUILD DIRECTORIES that have been
+              built.
+       run_tests.py foo/
+              Runs all tests in the foo/ directory and all Python tests in
+              the directory test. The Python tests are instructed to look
+              for binaries in foo/.
+       run_tests.py bar_test.exe test/baz_test.exe foo/ bar/
+              Runs foo/bar_test.exe, bar/bar_test.exe, foo/baz_test.exe, and
+              bar/baz_test.exe.
+       run_tests.py foo bar test/foo_test.py
+              Runs test/foo_test.py twice instructing it to look for its
+              test binaries in the directories foo and bar,
+              correspondingly.
+
+KNOWN BUILD DIRECTORIES
+      run_tests.py knows about directories where the SCons build script
+      deposits its products. These are the directories where run_tests.py
+      will be looking for its binaries. Currently, %(proj)s's SConstruct file
+      defines them as follows (the default build directory is the first one
+      listed in each group):
+      On Windows:
+              <%(proj)s root>/scons/build/win-dbg8/%(proj)s/scons/
+              <%(proj)s root>/scons/build/win-opt8/%(proj)s/scons/
+      On Mac:
+              <%(proj)s root>/scons/build/mac-dbg/%(proj)s/scons/
+              <%(proj)s root>/scons/build/mac-opt/%(proj)s/scons/
+      On other platforms:
+              <%(proj)s root>/scons/build/dbg/%(proj)s/scons/
+              <%(proj)s root>/scons/build/opt/%(proj)s/scons/"""
+
+IS_WINDOWS = os.name == 'nt'
+IS_MAC = os.name == 'posix' and os.uname()[0] == 'Darwin'
+IS_CYGWIN = os.name == 'posix' and 'CYGWIN' in os.uname()[0]
+
+# Definition of CONFIGS must match that of the build directory names in the
+# SConstruct script. The first list item is the default build configuration.
+if IS_WINDOWS:
+  CONFIGS = ('win-dbg8', 'win-opt8')
+elif IS_MAC:
+  CONFIGS = ('mac-dbg', 'mac-opt')
+else:
+  CONFIGS = ('dbg', 'opt')
+
+if IS_WINDOWS or IS_CYGWIN:
+  PYTHON_TEST_REGEX = re.compile(r'_(unit)?test\.py$', re.IGNORECASE)
+  BINARY_TEST_REGEX = re.compile(r'_(unit)?test(\.exe)?$', re.IGNORECASE)
+  BINARY_TEST_SEARCH_REGEX = re.compile(r'_(unit)?test\.exe$', re.IGNORECASE)
+else:
+  PYTHON_TEST_REGEX = re.compile(r'_(unit)?test\.py$')
+  BINARY_TEST_REGEX = re.compile(r'_(unit)?test$')
+  BINARY_TEST_SEARCH_REGEX = BINARY_TEST_REGEX
+
+
+def _GetGtestBuildDir(injected_os, script_dir, config):
+  """Calculates path to the Google Test SCons build directory."""
+
+  return injected_os.path.normpath(injected_os.path.join(script_dir,
+                                                         'scons/build',
+                                                         config,
+                                                         'gtest/scons'))
+
+
+def _GetConfigFromBuildDir(build_dir):
+  """Extracts the configuration name from the build directory."""
+
+  # We don't want to depend on build_dir containing the correct path
+  # separators.
+  m = re.match(r'.*[\\/]([^\\/]+)[\\/][^\\/]+[\\/]scons[\\/]?$', build_dir)
+  if m:
+    return m.group(1)
+  else:
+    print >>sys.stderr, ('%s is an invalid build directory that does not '
+                         'correspond to any configuration.' % (build_dir,))
+    return ''
+
+
+# All paths in this script are either absolute or relative to the current
+# working directory, unless otherwise specified.
+class TestRunner(object):
+  """Provides facilities for running Python and binary tests for Google Test."""
+
+  def __init__(self,
+               script_dir,
+               build_dir_var_name='GTEST_BUILD_DIR',
+               injected_os=os,
+               injected_subprocess=subprocess,
+               injected_build_dir_finder=_GetGtestBuildDir):
+    """Initializes a TestRunner instance.
+
+    Args:
+      script_dir:                File path to the calling script.
+      build_dir_var_name:        Name of the env variable used to pass the
+                                 the build directory path to the invoked
+                                 tests.
+      injected_os:               standard os module or a mock/stub for
+                                 testing.
+      injected_subprocess:       standard subprocess module or a mock/stub
+                                 for testing
+      injected_build_dir_finder: function that determines the path to
+                                 the build directory.
+    """
+
+    self.os = injected_os
+    self.subprocess = injected_subprocess
+    self.build_dir_finder = injected_build_dir_finder
+    self.build_dir_var_name = build_dir_var_name
+    self.script_dir = script_dir
+
+  def _GetBuildDirForConfig(self, config):
+    """Returns the build directory for a given configuration."""
+
+    return self.build_dir_finder(self.os, self.script_dir, config)
+
+  def _Run(self, args):
+    """Runs the executable with given args (args[0] is the executable name).
+
+    Args:
+      args: Command line arguments for the process.
+
+    Returns:
+      Process's exit code if it exits normally, or -signal if the process is
+      killed by a signal.
+    """
+
+    if self.subprocess:
+      return self.subprocess.Popen(args).wait()
+    else:
+      return self.os.spawnv(self.os.P_WAIT, args[0], args)
+
+  def _RunBinaryTest(self, test):
+    """Runs the binary test given its path.
+
+    Args:
+      test: Path to the test binary.
+
+    Returns:
+      Process's exit code if it exits normally, or -signal if the process is
+      killed by a signal.
+    """
+
+    return self._Run([test])
+
+  def _RunPythonTest(self, test, build_dir):
+    """Runs the Python test script with the specified build directory.
+
+    Args:
+      test: Path to the test's Python script.
+      build_dir: Path to the directory where the test binary is to be found.
+
+    Returns:
+      Process's exit code if it exits normally, or -signal if the process is
+      killed by a signal.
+    """
+
+    old_build_dir = self.os.environ.get(self.build_dir_var_name)
+
+    try:
+      self.os.environ[self.build_dir_var_name] = build_dir
+
+      # If this script is run on a Windows machine that has no association
+      # between the .py extension and a python interpreter, simply passing
+      # the script name into subprocess.Popen/os.spawn will not work.
+      print 'Running %s . . .' % (test,)
+      return self._Run([sys.executable, test])
+
+    finally:
+      if old_build_dir is None:
+        del self.os.environ[self.build_dir_var_name]
+      else:
+        self.os.environ[self.build_dir_var_name] = old_build_dir
+
+  def _FindFilesByRegex(self, directory, regex):
+    """Returns files in a directory whose names match a regular expression.
+
+    Args:
+      directory: Path to the directory to search for files.
+      regex: Regular expression to filter file names.
+
+    Returns:
+      The list of the paths to the files in the directory.
+    """
+
+    return [self.os.path.join(directory, file_name)
+            for file_name in self.os.listdir(directory)
+            if re.search(regex, file_name)]
+
+  # TODO(vladl@google.com): Implement parsing of scons/SConscript to run all
+  # tests defined there when no tests are specified.
+  # TODO(vladl@google.com): Update the docstring after the code is changed to
+  # try to test all builds defined in scons/SConscript.
+  def GetTestsToRun(self,
+                    args,
+                    named_configurations,
+                    built_configurations,
+                    available_configurations=CONFIGS,
+                    python_tests_to_skip=None):
+    """Determines what tests should be run.
+
+    Args:
+      args: The list of non-option arguments from the command line.
+      named_configurations: The list of configurations specified via -c or -a.
+      built_configurations: True if -b has been specified.
+      available_configurations: a list of configurations available on the
+                            current platform, injectable for testing.
+      python_tests_to_skip: a collection of (configuration, python test name)s
+                            that need to be skipped.
+
+    Returns:
+      A tuple with 2 elements: the list of Python tests to run and the list of
+      binary tests to run.
+    """
+
+    if named_configurations == 'all':
+      named_configurations = ','.join(available_configurations)
+
+    normalized_args = [self.os.path.normpath(arg) for arg in args]
+
+    # A final list of build directories which will be searched for the test
+    # binaries. First, add directories specified directly on the command
+    # line.
+    build_dirs = filter(self.os.path.isdir, normalized_args)
+
+    # Adds build directories specified via their build configurations using
+    # the -c or -a options.
+    if named_configurations:
+      build_dirs += [self._GetBuildDirForConfig(config)
+                     for config in named_configurations.split(',')]
+
+    # Adds KNOWN BUILD DIRECTORIES if -b is specified.
+    if built_configurations:
+      build_dirs += [self._GetBuildDirForConfig(config)
+                     for config in available_configurations
+                     if self.os.path.isdir(self._GetBuildDirForConfig(config))]
+
+    # If no directories were specified either via -a, -b, -c, or directly, use
+    # the default configuration.
+    elif not build_dirs:
+      build_dirs = [self._GetBuildDirForConfig(available_configurations[0])]
+
+    # Makes sure there are no duplications.
+    build_dirs = sets.Set(build_dirs)
+
+    errors_found = False
+    listed_python_tests = []  # All Python tests listed on the command line.
+    listed_binary_tests = []  # All binary tests listed on the command line.
+
+    test_dir = self.os.path.normpath(self.os.path.join(self.script_dir, 'test'))
+
+    # Sifts through non-directory arguments fishing for any Python or binary
+    # tests and detecting errors.
+    for argument in sets.Set(normalized_args) - build_dirs:
+      if re.search(PYTHON_TEST_REGEX, argument):
+        python_path = self.os.path.join(test_dir,
+                                        self.os.path.basename(argument))
+        if self.os.path.isfile(python_path):
+          listed_python_tests.append(python_path)
+        else:
+          sys.stderr.write('Unable to find Python test %s' % argument)
+          errors_found = True
+      elif re.search(BINARY_TEST_REGEX, argument):
+        # This script also accepts binary test names prefixed with test/ for
+        # the convenience of typing them (can use path completions in the
+        # shell).  Strips test/ prefix from the binary test names.
+        listed_binary_tests.append(self.os.path.basename(argument))
+      else:
+        sys.stderr.write('%s is neither test nor build directory' % argument)
+        errors_found = True
+
+    if errors_found:
+      return None
+
+    user_has_listed_tests = listed_python_tests or listed_binary_tests
+
+    if user_has_listed_tests:
+      selected_python_tests = listed_python_tests
+    else:
+      selected_python_tests = self._FindFilesByRegex(test_dir,
+                                                     PYTHON_TEST_REGEX)
+
+    # TODO(vladl@google.com): skip unbuilt Python tests when -b is specified.
+    python_test_pairs = []
+    for directory in build_dirs:
+      for test in selected_python_tests:
+        config = _GetConfigFromBuildDir(directory)
+        file_name = os.path.basename(test)
+        if python_tests_to_skip and (config, file_name) in python_tests_to_skip:
+          print ('NOTE: %s is skipped for configuration %s, as it does not '
+                 'work there.' % (file_name, config))
+        else:
+          python_test_pairs.append((directory, test))
+
+    binary_test_pairs = []
+    for directory in build_dirs:
+      if user_has_listed_tests:
+        binary_test_pairs.extend(
+            [(directory, self.os.path.join(directory, test))
+             for test in listed_binary_tests])
+      else:
+        tests = self._FindFilesByRegex(directory, BINARY_TEST_SEARCH_REGEX)
+        binary_test_pairs.extend([(directory, test) for test in tests])
+
+    return (python_test_pairs, binary_test_pairs)
+
+  def RunTests(self, python_tests, binary_tests):
+    """Runs Python and binary tests and reports results to the standard output.
+
+    Args:
+      python_tests: List of Python tests to run in the form of tuples
+                    (build directory, Python test script).
+      binary_tests: List of binary tests to run in the form of tuples
+                    (build directory, binary file).
+
+    Returns:
+      The exit code the program should pass into sys.exit().
+    """
+
+    if python_tests or binary_tests:
+      results = []
+      for directory, test in python_tests:
+        results.append((directory,
+                        test,
+                        self._RunPythonTest(test, directory) == 0))
+      for directory, test in binary_tests:
+        results.append((directory,
+                        self.os.path.basename(test),
+                        self._RunBinaryTest(test) == 0))
+
+      failed = [(directory, test)
+                for (directory, test, success) in results
+                if not success]
+      print
+      print '%d tests run.' % len(results)
+      if failed:
+        print 'The following %d tests failed:' % len(failed)
+        for (directory, test) in failed:
+          print '%s in %s' % (test, directory)
+        return 1
+      else:
+        print 'All tests passed!'
+    else:  # No tests defined
+      print 'Nothing to test - no tests specified!'
+
+    return 0
+
+
+def ParseArgs(project_name, argv=None, help_callback=None):
+  """Parses the options run_tests.py uses."""
+
+  # Suppresses lint warning on unused arguments.  These arguments are
+  # required by optparse, even though they are unused.
+  # pylint: disable-msg=W0613
+  def PrintHelp(option, opt, value, parser):
+    print HELP_MSG % {'proj': project_name}
+    sys.exit(1)
+
+  parser = optparse.OptionParser()
+  parser.add_option('-c',
+                    action='store',
+                    dest='configurations',
+                    default=None)
+  parser.add_option('-a',
+                    action='store_const',
+                    dest='configurations',
+                    default=None,
+                    const='all')
+  parser.add_option('-b',
+                    action='store_const',
+                    dest='built_configurations',
+                    default=False,
+                    const=True)
+  # Replaces the built-in help with ours.
+  parser.remove_option('-h')
+  parser.add_option('-h', '--help',
+                    action='callback',
+                    callback=help_callback or PrintHelp)
+  return parser.parse_args(argv)
diff --git a/protobuf/gtest/test/run_tests_util_test.py b/protobuf/gtest/test/run_tests_util_test.py
new file mode 100755
index 0000000..9c55726
--- /dev/null
+++ b/protobuf/gtest/test/run_tests_util_test.py
@@ -0,0 +1,676 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 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.
+
+"""Tests for run_tests_util.py test runner script."""
+
+__author__ = 'vladl@google.com (Vlad Losev)'
+
+import os
+import re
+import sets
+import unittest
+
+import run_tests_util
+
+
+GTEST_DBG_DIR = 'scons/build/dbg/gtest/scons'
+GTEST_OPT_DIR = 'scons/build/opt/gtest/scons'
+GTEST_OTHER_DIR = 'scons/build/other/gtest/scons'
+
+
+def AddExeExtension(path):
+  """Appends .exe to the path on Windows or Cygwin."""
+
+  if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN:
+    return path + '.exe'
+  else:
+    return path
+
+
+class FakePath(object):
+  """A fake os.path module for testing."""
+
+  def __init__(self, current_dir=os.getcwd(), known_paths=None):
+    self.current_dir = current_dir
+    self.tree = {}
+    self.path_separator = os.sep
+
+    # known_paths contains either absolute or relative paths. Relative paths
+    # are absolutized with self.current_dir.
+    if known_paths:
+      self._AddPaths(known_paths)
+
+  def _AddPath(self, path):
+    ends_with_slash = path.endswith('/')
+    path = self.abspath(path)
+    if ends_with_slash:
+      path += self.path_separator
+    name_list = path.split(self.path_separator)
+    tree = self.tree
+    for name in name_list[:-1]:
+      if not name:
+        continue
+      if name in tree:
+        tree = tree[name]
+      else:
+        tree[name] = {}
+        tree = tree[name]
+
+    name = name_list[-1]
+    if name:
+      if name in tree:
+        assert tree[name] == 1
+      else:
+        tree[name] = 1
+
+  def _AddPaths(self, paths):
+    for path in paths:
+      self._AddPath(path)
+
+  def PathElement(self, path):
+    """Returns an internal representation of directory tree entry for path."""
+    tree = self.tree
+    name_list = self.abspath(path).split(self.path_separator)
+    for name in name_list:
+      if not name:
+        continue
+      tree = tree.get(name, None)
+      if tree is None:
+        break
+
+    return tree
+
+  # Silences pylint warning about using standard names.
+  # pylint: disable-msg=C6409
+  def normpath(self, path):
+    return os.path.normpath(path)
+
+  def abspath(self, path):
+    return self.normpath(os.path.join(self.current_dir, path))
+
+  def isfile(self, path):
+    return self.PathElement(self.abspath(path)) == 1
+
+  def isdir(self, path):
+    return type(self.PathElement(self.abspath(path))) == type(dict())
+
+  def basename(self, path):
+    return os.path.basename(path)
+
+  def dirname(self, path):
+    return os.path.dirname(path)
+
+  def join(self, *kargs):
+    return os.path.join(*kargs)
+
+
+class FakeOs(object):
+  """A fake os module for testing."""
+  P_WAIT = os.P_WAIT
+
+  def __init__(self, fake_path_module):
+    self.path = fake_path_module
+
+    # Some methods/attributes are delegated to the real os module.
+    self.environ = os.environ
+
+  # pylint: disable-msg=C6409
+  def listdir(self, path):
+    assert self.path.isdir(path)
+    return self.path.PathElement(path).iterkeys()
+
+  def spawnv(self, wait, executable, *kargs):
+    assert wait == FakeOs.P_WAIT
+    return self.spawn_impl(executable, kargs)
+
+
+class GetTestsToRunTest(unittest.TestCase):
+  """Exercises TestRunner.GetTestsToRun."""
+
+  def NormalizeGetTestsToRunResults(self, results):
+    """Normalizes path data returned from GetTestsToRun for comparison."""
+
+    def NormalizePythonTestPair(pair):
+      """Normalizes path data in the (directory, python_script) pair."""
+
+      return (os.path.normpath(pair[0]), os.path.normpath(pair[1]))
+
+    def NormalizeBinaryTestPair(pair):
+      """Normalizes path data in the (directory, binary_executable) pair."""
+
+      directory, executable = map(os.path.normpath, pair)
+
+      # On Windows and Cygwin, the test file names have the .exe extension, but
+      # they can be invoked either by name or by name+extension. Our test must
+      # accommodate both situations.
+      if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN:
+        executable = re.sub(r'\.exe$', '', executable)
+      return (directory, executable)
+
+    python_tests = sets.Set(map(NormalizePythonTestPair, results[0]))
+    binary_tests = sets.Set(map(NormalizeBinaryTestPair, results[1]))
+    return (python_tests, binary_tests)
+
+  def AssertResultsEqual(self, results, expected):
+    """Asserts results returned by GetTestsToRun equal to expected results."""
+
+    self.assertEqual(self.NormalizeGetTestsToRunResults(results),
+                     self.NormalizeGetTestsToRunResults(expected),
+                     'Incorrect set of tests returned:\n%s\nexpected:\n%s' %
+                     (results, expected))
+
+  def setUp(self):
+    self.fake_os = FakeOs(FakePath(
+        current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
+        known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'),
+                     AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'),
+                     'test/gtest_color_test.py']))
+    self.fake_configurations = ['dbg', 'opt']
+    self.test_runner = run_tests_util.TestRunner(script_dir='.',
+                                                 injected_os=self.fake_os,
+                                                 injected_subprocess=None)
+
+  def testBinaryTestsOnly(self):
+    """Exercises GetTestsToRun with parameters designating binary tests only."""
+
+    # A default build.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_unittest'],
+            '',
+            False,
+            available_configurations=self.fake_configurations),
+        ([],
+         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+    # An explicitly specified directory.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            [GTEST_DBG_DIR, 'gtest_unittest'],
+            '',
+            False,
+            available_configurations=self.fake_configurations),
+        ([],
+         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+    # A particular configuration.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_unittest'],
+            'other',
+            False,
+            available_configurations=self.fake_configurations),
+        ([],
+         [(GTEST_OTHER_DIR, GTEST_OTHER_DIR + '/gtest_unittest')]))
+
+    # All available configurations
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_unittest'],
+            'all',
+            False,
+            available_configurations=self.fake_configurations),
+        ([],
+         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
+          (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
+
+    # All built configurations (unbuilt don't cause failure).
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_unittest'],
+            '',
+            True,
+            available_configurations=self.fake_configurations + ['unbuilt']),
+        ([],
+         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
+          (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
+
+    # A combination of an explicit directory and a configuration.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            [GTEST_DBG_DIR, 'gtest_unittest'],
+            'opt',
+            False,
+            available_configurations=self.fake_configurations),
+        ([],
+         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
+          (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
+
+    # Same test specified in an explicit directory and via a configuration.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            [GTEST_DBG_DIR, 'gtest_unittest'],
+            'dbg',
+            False,
+            available_configurations=self.fake_configurations),
+        ([],
+         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+    # All built configurations + explicit directory + explicit configuration.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            [GTEST_DBG_DIR, 'gtest_unittest'],
+            'opt',
+            True,
+            available_configurations=self.fake_configurations),
+        ([],
+         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest'),
+          (GTEST_OPT_DIR, GTEST_OPT_DIR + '/gtest_unittest')]))
+
+  def testPythonTestsOnly(self):
+    """Exercises GetTestsToRun with parameters designating Python tests only."""
+
+    # A default build.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_color_test.py'],
+            '',
+            False,
+            available_configurations=self.fake_configurations),
+        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+         []))
+
+    # An explicitly specified directory.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            [GTEST_DBG_DIR, 'test/gtest_color_test.py'],
+            '',
+            False,
+            available_configurations=self.fake_configurations),
+        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+         []))
+
+    # A particular configuration.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_color_test.py'],
+            'other',
+            False,
+            available_configurations=self.fake_configurations),
+        ([(GTEST_OTHER_DIR, 'test/gtest_color_test.py')],
+         []))
+
+    # All available configurations
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['test/gtest_color_test.py'],
+            'all',
+            False,
+            available_configurations=self.fake_configurations),
+        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
+          (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
+         []))
+
+    # All built configurations (unbuilt don't cause failure).
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_color_test.py'],
+            '',
+            True,
+            available_configurations=self.fake_configurations + ['unbuilt']),
+        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
+          (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
+         []))
+
+    # A combination of an explicit directory and a configuration.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            [GTEST_DBG_DIR, 'gtest_color_test.py'],
+            'opt',
+            False,
+            available_configurations=self.fake_configurations),
+        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
+          (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
+         []))
+
+    # Same test specified in an explicit directory and via a configuration.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            [GTEST_DBG_DIR, 'gtest_color_test.py'],
+            'dbg',
+            False,
+            available_configurations=self.fake_configurations),
+        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+         []))
+
+    # All built configurations + explicit directory + explicit configuration.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            [GTEST_DBG_DIR, 'gtest_color_test.py'],
+            'opt',
+            True,
+            available_configurations=self.fake_configurations),
+        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py'),
+          (GTEST_OPT_DIR, 'test/gtest_color_test.py')],
+         []))
+
+  def testCombinationOfBinaryAndPythonTests(self):
+    """Exercises GetTestsToRun with mixed binary/Python tests."""
+
+    # Use only default configuration for this test.
+
+    # Neither binary nor Python tests are specified so find all.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            [],
+            '',
+            False,
+            available_configurations=self.fake_configurations),
+        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+    # Specifying both binary and Python tests.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_unittest', 'gtest_color_test.py'],
+            '',
+            False,
+            available_configurations=self.fake_configurations),
+        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+    # Specifying binary tests suppresses Python tests.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_unittest'],
+            '',
+            False,
+            available_configurations=self.fake_configurations),
+        ([],
+         [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]))
+
+   # Specifying Python tests suppresses binary tests.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_color_test.py'],
+            '',
+            False,
+            available_configurations=self.fake_configurations),
+        ([(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+         []))
+
+  def testIgnoresNonTestFiles(self):
+    """Verifies that GetTestsToRun ignores non-test files in the filesystem."""
+
+    self.fake_os = FakeOs(FakePath(
+        current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
+        known_paths=[AddExeExtension(GTEST_DBG_DIR + '/gtest_nontest'),
+                     'test/']))
+    self.test_runner = run_tests_util.TestRunner(script_dir='.',
+                                                 injected_os=self.fake_os,
+                                                 injected_subprocess=None)
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            [],
+            '',
+            True,
+            available_configurations=self.fake_configurations),
+        ([], []))
+
+  def testWorksFromDifferentDir(self):
+    """Exercises GetTestsToRun from a directory different from run_test.py's."""
+
+    # Here we simulate an test script in directory /d/ called from the
+    # directory /a/b/c/.
+    self.fake_os = FakeOs(FakePath(
+        current_dir=os.path.abspath('/a/b/c'),
+        known_paths=[
+            '/a/b/c/',
+            AddExeExtension('/d/' + GTEST_DBG_DIR + '/gtest_unittest'),
+            AddExeExtension('/d/' + GTEST_OPT_DIR + '/gtest_unittest'),
+            '/d/test/gtest_color_test.py']))
+    self.fake_configurations = ['dbg', 'opt']
+    self.test_runner = run_tests_util.TestRunner(script_dir='/d/',
+                                                 injected_os=self.fake_os,
+                                                 injected_subprocess=None)
+    # A binary test.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_unittest'],
+            '',
+            False,
+            available_configurations=self.fake_configurations),
+        ([],
+         [('/d/' + GTEST_DBG_DIR, '/d/' + GTEST_DBG_DIR + '/gtest_unittest')]))
+
+    # A Python test.
+    self.AssertResultsEqual(
+        self.test_runner.GetTestsToRun(
+            ['gtest_color_test.py'],
+            '',
+            False,
+            available_configurations=self.fake_configurations),
+        ([('/d/' + GTEST_DBG_DIR, '/d/test/gtest_color_test.py')], []))
+
+  def testNonTestBinary(self):
+    """Exercises GetTestsToRun with a non-test parameter."""
+
+    self.assert_(
+        not self.test_runner.GetTestsToRun(
+            ['gtest_unittest_not_really'],
+            '',
+            False,
+            available_configurations=self.fake_configurations))
+
+  def testNonExistingPythonTest(self):
+    """Exercises GetTestsToRun with a non-existent Python test parameter."""
+
+    self.assert_(
+        not self.test_runner.GetTestsToRun(
+            ['nonexistent_test.py'],
+            '',
+            False,
+            available_configurations=self.fake_configurations))
+
+  if run_tests_util.IS_WINDOWS or run_tests_util.IS_CYGWIN:
+
+    def testDoesNotPickNonExeFilesOnWindows(self):
+      """Verifies that GetTestsToRun does not find _test files on Windows."""
+
+      self.fake_os = FakeOs(FakePath(
+          current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
+          known_paths=['/d/' + GTEST_DBG_DIR + '/gtest_test', 'test/']))
+      self.test_runner = run_tests_util.TestRunner(script_dir='.',
+                                                   injected_os=self.fake_os,
+                                                   injected_subprocess=None)
+      self.AssertResultsEqual(
+          self.test_runner.GetTestsToRun(
+              [],
+              '',
+              True,
+              available_configurations=self.fake_configurations),
+          ([], []))
+
+
+class RunTestsTest(unittest.TestCase):
+  """Exercises TestRunner.RunTests."""
+
+  def SpawnSuccess(self, unused_executable, unused_argv):
+    """Fakes test success by returning 0 as an exit code."""
+
+    self.num_spawn_calls += 1
+    return 0
+
+  def SpawnFailure(self, unused_executable, unused_argv):
+    """Fakes test success by returning 1 as an exit code."""
+
+    self.num_spawn_calls += 1
+    return 1
+
+  def setUp(self):
+    self.fake_os = FakeOs(FakePath(
+        current_dir=os.path.abspath(os.path.dirname(run_tests_util.__file__)),
+        known_paths=[
+            AddExeExtension(GTEST_DBG_DIR + '/gtest_unittest'),
+            AddExeExtension(GTEST_OPT_DIR + '/gtest_unittest'),
+            'test/gtest_color_test.py']))
+    self.fake_configurations = ['dbg', 'opt']
+    self.test_runner = run_tests_util.TestRunner(
+        script_dir=os.path.dirname(__file__) or '.',
+        injected_os=self.fake_os,
+        injected_subprocess=None)
+    self.num_spawn_calls = 0  # A number of calls to spawn.
+
+  def testRunPythonTestSuccess(self):
+    """Exercises RunTests to handle a Python test success."""
+
+    self.fake_os.spawn_impl = self.SpawnSuccess
+    self.assertEqual(
+        self.test_runner.RunTests(
+            [(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+            []),
+        0)
+    self.assertEqual(self.num_spawn_calls, 1)
+
+  def testRunBinaryTestSuccess(self):
+    """Exercises RunTests to handle a binary test success."""
+
+    self.fake_os.spawn_impl = self.SpawnSuccess
+    self.assertEqual(
+        self.test_runner.RunTests(
+            [],
+            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
+        0)
+    self.assertEqual(self.num_spawn_calls, 1)
+
+  def testRunPythonTestFauilure(self):
+    """Exercises RunTests to handle a Python test failure."""
+
+    self.fake_os.spawn_impl = self.SpawnFailure
+    self.assertEqual(
+        self.test_runner.RunTests(
+            [(GTEST_DBG_DIR, 'test/gtest_color_test.py')],
+            []),
+        1)
+    self.assertEqual(self.num_spawn_calls, 1)
+
+  def testRunBinaryTestFailure(self):
+    """Exercises RunTests to handle a binary test failure."""
+
+    self.fake_os.spawn_impl = self.SpawnFailure
+    self.assertEqual(
+        self.test_runner.RunTests(
+            [],
+            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
+        1)
+    self.assertEqual(self.num_spawn_calls, 1)
+
+  def testCombinedTestSuccess(self):
+    """Exercises RunTests to handle a success of both Python and binary test."""
+
+    self.fake_os.spawn_impl = self.SpawnSuccess
+    self.assertEqual(
+        self.test_runner.RunTests(
+            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')],
+            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
+        0)
+    self.assertEqual(self.num_spawn_calls, 2)
+
+  def testCombinedTestSuccessAndFailure(self):
+    """Exercises RunTests to handle a success of both Python and binary test."""
+
+    def SpawnImpl(executable, argv):
+      self.num_spawn_calls += 1
+      # Simulates failure of a Python test and success of a binary test.
+      if '.py' in executable or '.py' in argv[0]:
+        return 1
+      else:
+        return 0
+
+    self.fake_os.spawn_impl = SpawnImpl
+    self.assertEqual(
+        self.test_runner.RunTests(
+            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')],
+            [(GTEST_DBG_DIR, GTEST_DBG_DIR + '/gtest_unittest')]),
+        0)
+    self.assertEqual(self.num_spawn_calls, 2)
+
+
+class ParseArgsTest(unittest.TestCase):
+  """Exercises ParseArgs."""
+
+  def testNoOptions(self):
+    options, args = run_tests_util.ParseArgs('gtest', argv=['script.py'])
+    self.assertEqual(args, ['script.py'])
+    self.assert_(options.configurations is None)
+    self.assertFalse(options.built_configurations)
+
+  def testOptionC(self):
+    options, args = run_tests_util.ParseArgs(
+        'gtest', argv=['script.py', '-c', 'dbg'])
+    self.assertEqual(args, ['script.py'])
+    self.assertEqual(options.configurations, 'dbg')
+    self.assertFalse(options.built_configurations)
+
+  def testOptionA(self):
+    options, args = run_tests_util.ParseArgs('gtest', argv=['script.py', '-a'])
+    self.assertEqual(args, ['script.py'])
+    self.assertEqual(options.configurations, 'all')
+    self.assertFalse(options.built_configurations)
+
+  def testOptionB(self):
+    options, args = run_tests_util.ParseArgs('gtest', argv=['script.py', '-b'])
+    self.assertEqual(args, ['script.py'])
+    self.assert_(options.configurations is None)
+    self.assertTrue(options.built_configurations)
+
+  def testOptionCAndOptionB(self):
+    options, args = run_tests_util.ParseArgs(
+        'gtest', argv=['script.py', '-c', 'dbg', '-b'])
+    self.assertEqual(args, ['script.py'])
+    self.assertEqual(options.configurations, 'dbg')
+    self.assertTrue(options.built_configurations)
+
+  def testOptionH(self):
+    help_called = [False]
+
+    # Suppresses lint warning on unused arguments.  These arguments are
+    # required by optparse, even though they are unused.
+    # pylint: disable-msg=W0613
+    def VerifyHelp(option, opt, value, parser):
+      help_called[0] = True
+
+    # Verifies that -h causes the help callback to be called.
+    help_called[0] = False
+    _, args = run_tests_util.ParseArgs(
+        'gtest', argv=['script.py', '-h'], help_callback=VerifyHelp)
+    self.assertEqual(args, ['script.py'])
+    self.assertTrue(help_called[0])
+
+    # Verifies that --help causes the help callback to be called.
+    help_called[0] = False
+    _, args = run_tests_util.ParseArgs(
+        'gtest', argv=['script.py', '--help'], help_callback=VerifyHelp)
+    self.assertEqual(args, ['script.py'])
+    self.assertTrue(help_called[0])
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/protobuf/gtest/xcode/Config/DebugProject.xcconfig b/protobuf/gtest/xcode/Config/DebugProject.xcconfig
new file mode 100644
index 0000000..3d68157
--- /dev/null
+++ b/protobuf/gtest/xcode/Config/DebugProject.xcconfig
@@ -0,0 +1,30 @@
+//
+//  DebugProject.xcconfig
+//
+//  These are Debug Configuration project settings for the gtest framework and
+//  examples. It is set in the "Based On:" dropdown in the "Project" info
+//  dialog.
+//  This file is based on the Xcode Configuration files in:
+//  http://code.google.com/p/google-toolbox-for-mac/
+// 
+
+#include "General.xcconfig"
+
+// No optimization
+GCC_OPTIMIZATION_LEVEL = 0
+
+// Deployment postprocessing is what triggers Xcode to strip, turn it off
+DEPLOYMENT_POSTPROCESSING = NO
+
+// Dead code stripping off
+DEAD_CODE_STRIPPING = NO
+
+// Debug symbols should be on obviously
+GCC_GENERATE_DEBUGGING_SYMBOLS = YES
+
+// Define the DEBUG macro in all debug builds
+OTHER_CFLAGS = $(OTHER_CFLAGS) -DDEBUG=1
+
+// These are turned off to avoid STL incompatibilities with client code
+// // Turns on special C++ STL checks to "encourage" good STL use
+// GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS) _GLIBCXX_DEBUG_PEDANTIC _GLIBCXX_DEBUG _GLIBCPP_CONCEPT_CHECKS
diff --git a/protobuf/gtest/xcode/Config/FrameworkTarget.xcconfig b/protobuf/gtest/xcode/Config/FrameworkTarget.xcconfig
new file mode 100644
index 0000000..357b1c8
--- /dev/null
+++ b/protobuf/gtest/xcode/Config/FrameworkTarget.xcconfig
@@ -0,0 +1,17 @@
+//
+//  FrameworkTarget.xcconfig
+//
+//  These are Framework target settings for the gtest framework and examples. It
+//  is set in the "Based On:" dropdown in the "Target" info dialog.
+//  This file is based on the Xcode Configuration files in:
+//  http://code.google.com/p/google-toolbox-for-mac/
+// 
+
+// Dynamic libs need to be position independent
+GCC_DYNAMIC_NO_PIC = NO
+
+// Dynamic libs should not have their external symbols stripped.
+STRIP_STYLE = non-global
+
+// Let the user install by specifying the $DSTROOT with xcodebuild
+SKIP_INSTALL = NO
diff --git a/protobuf/gtest/xcode/Config/General.xcconfig b/protobuf/gtest/xcode/Config/General.xcconfig
new file mode 100644
index 0000000..f23e322
--- /dev/null
+++ b/protobuf/gtest/xcode/Config/General.xcconfig
@@ -0,0 +1,41 @@
+//
+//  General.xcconfig
+//
+//  These are General configuration settings for the gtest framework and
+//  examples.
+//  This file is based on the Xcode Configuration files in:
+//  http://code.google.com/p/google-toolbox-for-mac/
+// 
+
+// Build for PPC and Intel, 32- and 64-bit
+ARCHS = i386 x86_64 ppc ppc64
+
+// Zerolink prevents link warnings so turn it off
+ZERO_LINK = NO
+
+// Prebinding considered unhelpful in 10.3 and later
+PREBINDING = NO
+
+// Strictest warning policy
+WARNING_CFLAGS = -Wall -Werror -Wendif-labels -Wnewline-eof -Wno-sign-compare -Wshadow
+
+// Work around Xcode bugs by using external strip. See:
+// http://lists.apple.com/archives/Xcode-users/2006/Feb/msg00050.html
+SEPARATE_STRIP = YES
+
+// Force C99 dialect
+GCC_C_LANGUAGE_STANDARD = c99
+
+// not sure why apple defaults this on, but it's pretty risky
+ALWAYS_SEARCH_USER_PATHS = NO
+
+// Turn on position dependent code for most cases (overridden where appropriate)
+GCC_DYNAMIC_NO_PIC = YES
+
+// Default SDK and minimum OS version is 10.4
+SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk
+MACOSX_DEPLOYMENT_TARGET = 10.4
+GCC_VERSION = 4.0
+
+// VERSIONING BUILD SETTINGS (used in Info.plist)
+GTEST_VERSIONINFO_ABOUT =  © 2008 Google Inc.
diff --git a/protobuf/gtest/xcode/Config/ReleaseProject.xcconfig b/protobuf/gtest/xcode/Config/ReleaseProject.xcconfig
new file mode 100644
index 0000000..5349f0a
--- /dev/null
+++ b/protobuf/gtest/xcode/Config/ReleaseProject.xcconfig
@@ -0,0 +1,32 @@
+//
+//  ReleaseProject.xcconfig
+//
+//  These are Release Configuration project settings for the gtest framework
+//  and examples. It is set in the "Based On:" dropdown in the "Project" info
+//  dialog.
+//  This file is based on the Xcode Configuration files in:
+//  http://code.google.com/p/google-toolbox-for-mac/
+// 
+
+#include "General.xcconfig"
+
+// subconfig/Release.xcconfig
+
+// Optimize for space and size (Apple recommendation)
+GCC_OPTIMIZATION_LEVEL = s
+
+// Deploment postprocessing is what triggers Xcode to strip
+DEPLOYMENT_POSTPROCESSING = YES
+
+// No symbols
+GCC_GENERATE_DEBUGGING_SYMBOLS = NO
+
+// Dead code strip does not affect ObjC code but can help for C
+DEAD_CODE_STRIPPING = YES
+
+// NDEBUG is used by things like assert.h, so define it for general compat.
+// ASSERT going away in release tends to create unused vars.
+OTHER_CFLAGS = $(OTHER_CFLAGS) -DNDEBUG=1 -Wno-unused-variable
+
+// When we strip we want to strip all symbols in release, but save externals.
+STRIP_STYLE = all
diff --git a/protobuf/gtest/xcode/Config/StaticLibraryTarget.xcconfig b/protobuf/gtest/xcode/Config/StaticLibraryTarget.xcconfig
new file mode 100644
index 0000000..3922fa5
--- /dev/null
+++ b/protobuf/gtest/xcode/Config/StaticLibraryTarget.xcconfig
@@ -0,0 +1,18 @@
+//
+//  StaticLibraryTarget.xcconfig
+//
+//  These are static library target settings for libgtest.a. It
+//  is set in the "Based On:" dropdown in the "Target" info dialog.
+//  This file is based on the Xcode Configuration files in:
+//  http://code.google.com/p/google-toolbox-for-mac/
+// 
+
+// Static libs can be included in bundles so make them position independent
+GCC_DYNAMIC_NO_PIC = NO
+
+// Static libs should not have their internal globals or external symbols
+// stripped.
+STRIP_STYLE = debugging
+
+// Let the user install by specifying the $DSTROOT with xcodebuild
+SKIP_INSTALL = NO
diff --git a/protobuf/gtest/xcode/Config/TestTarget.xcconfig b/protobuf/gtest/xcode/Config/TestTarget.xcconfig
new file mode 100644
index 0000000..e6652ba
--- /dev/null
+++ b/protobuf/gtest/xcode/Config/TestTarget.xcconfig
@@ -0,0 +1,8 @@
+//
+//  TestTarget.xcconfig
+//
+//  These are Test target settings for the gtest framework and examples. It
+//  is set in the "Based On:" dropdown in the "Target" info dialog.
+
+PRODUCT_NAME = $(TARGET_NAME)
+HEADER_SEARCH_PATHS = ../include
diff --git a/protobuf/gtest/xcode/Resources/Info.plist b/protobuf/gtest/xcode/Resources/Info.plist
new file mode 100644
index 0000000..9dd28ea
--- /dev/null
+++ b/protobuf/gtest/xcode/Resources/Info.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.google.${PRODUCT_NAME}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>GTEST_VERSIONINFO_LONG</string>
+	<key>CFBundleShortVersionString</key>
+	<string>GTEST_VERSIONINFO_SHORT</string>
+	<key>CFBundleGetInfoString</key>
+	<string>${PRODUCT_NAME} GTEST_VERSIONINFO_LONG, ${GTEST_VERSIONINFO_ABOUT}</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>${GTEST_VERSIONINFO_ABOUT}</string>
+	<key>CSResourcesFileMapped</key>
+	<true/>
+</dict>
+</plist>
diff --git a/protobuf/gtest/xcode/Samples/FrameworkSample/Info.plist b/protobuf/gtest/xcode/Samples/FrameworkSample/Info.plist
new file mode 100644
index 0000000..f3852ed
--- /dev/null
+++ b/protobuf/gtest/xcode/Samples/FrameworkSample/Info.plist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.google.gtest.${PRODUCT_NAME:identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>1.0</string>
+	<key>CSResourcesFileMapped</key>
+	<true/>
+</dict>
+</plist>
diff --git a/protobuf/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj b/protobuf/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..497617e
--- /dev/null
+++ b/protobuf/gtest/xcode/Samples/FrameworkSample/WidgetFramework.xcodeproj/project.pbxproj
@@ -0,0 +1,457 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 42;
+	objects = {
+
+/* Begin PBXAggregateTarget section */
+		4024D162113D7D2400C7059E /* Test */ = {
+			isa = PBXAggregateTarget;
+			buildConfigurationList = 4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */;
+			buildPhases = (
+				4024D161113D7D2400C7059E /* ShellScript */,
+			);
+			dependencies = (
+				4024D166113D7D3100C7059E /* PBXTargetDependency */,
+			);
+			name = Test;
+			productName = TestAndBuild;
+		};
+		4024D1E9113D83FF00C7059E /* TestAndBuild */ = {
+			isa = PBXAggregateTarget;
+			buildConfigurationList = 4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */;
+			buildPhases = (
+			);
+			dependencies = (
+				4024D1ED113D840900C7059E /* PBXTargetDependency */,
+				4024D1EF113D840D00C7059E /* PBXTargetDependency */,
+			);
+			name = TestAndBuild;
+			productName = TestAndBuild;
+		};
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+		3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1230E5AEE3500C7F239 /* widget.cc */; };
+		3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B7EB1240E5AEE3500C7F239 /* widget.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B7EB1270E5AEE4600C7F239 /* widget_test.cc */; };
+		3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */; };
+		4024D188113D7D7800C7059E /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D185113D7D5500C7059E /* libgtest.a */; };
+		4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4024D183113D7D5500C7059E /* libgtest_main.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
+			remoteInfo = gTestExample;
+		};
+		4024D165113D7D3100C7059E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 3B07BDE90E3F3F9E00647869;
+			remoteInfo = WidgetFrameworkTest;
+		};
+		4024D1EC113D840900C7059E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
+			remoteInfo = WidgetFramework;
+		};
+		4024D1EE113D840D00C7059E /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 4024D162113D7D2400C7059E;
+			remoteInfo = Test;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = WidgetFrameworkTest; sourceTree = BUILT_PRODUCTS_DIR; };
+		3B7EB1230E5AEE3500C7F239 /* widget.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget.cc; sourceTree = "<group>"; };
+		3B7EB1240E5AEE3500C7F239 /* widget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = widget.h; sourceTree = "<group>"; };
+		3B7EB1270E5AEE4600C7F239 /* widget_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = widget_test.cc; sourceTree = "<group>"; };
+		4024D183113D7D5500C7059E /* libgtest_main.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest_main.a; path = /usr/local/lib/libgtest_main.a; sourceTree = "<absolute>"; };
+		4024D185113D7D5500C7059E /* libgtest.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libgtest.a; path = /usr/local/lib/libgtest.a; sourceTree = "<absolute>"; };
+		4024D1E2113D838200C7059E /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = "<group>"; };
+		8D07F2C70486CC7A007CD1D0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+		8D07F2C80486CC7A007CD1D0 /* Widget.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Widget.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		3B07BDE80E3F3F9E00647869 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4024D189113D7D7A00C7059E /* libgtest_main.a in Frameworks */,
+				4024D188113D7D7800C7059E /* libgtest.a in Frameworks */,
+				3B7EB1480E5AF3B400C7F239 /* Widget.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D07F2C30486CC7A007CD1D0 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		034768DDFF38A45A11DB9C8B /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				8D07F2C80486CC7A007CD1D0 /* Widget.framework */,
+				3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		0867D691FE84028FC02AAC07 /* gTestExample */ = {
+			isa = PBXGroup;
+			children = (
+				4024D1E1113D836C00C7059E /* Scripts */,
+				08FB77ACFE841707C02AAC07 /* Source */,
+				089C1665FE841158C02AAC07 /* Resources */,
+				3B07BE350E4094E400647869 /* Test */,
+				0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */,
+				034768DDFF38A45A11DB9C8B /* Products */,
+			);
+			name = gTestExample;
+			sourceTree = "<group>";
+		};
+		0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = {
+			isa = PBXGroup;
+			children = (
+				4024D183113D7D5500C7059E /* libgtest_main.a */,
+				4024D185113D7D5500C7059E /* libgtest.a */,
+			);
+			name = "External Frameworks and Libraries";
+			sourceTree = "<group>";
+		};
+		089C1665FE841158C02AAC07 /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				8D07F2C70486CC7A007CD1D0 /* Info.plist */,
+			);
+			name = Resources;
+			sourceTree = "<group>";
+		};
+		08FB77ACFE841707C02AAC07 /* Source */ = {
+			isa = PBXGroup;
+			children = (
+				3B7EB1230E5AEE3500C7F239 /* widget.cc */,
+				3B7EB1240E5AEE3500C7F239 /* widget.h */,
+			);
+			name = Source;
+			sourceTree = "<group>";
+		};
+		3B07BE350E4094E400647869 /* Test */ = {
+			isa = PBXGroup;
+			children = (
+				3B7EB1270E5AEE4600C7F239 /* widget_test.cc */,
+			);
+			name = Test;
+			sourceTree = "<group>";
+		};
+		4024D1E1113D836C00C7059E /* Scripts */ = {
+			isa = PBXGroup;
+			children = (
+				4024D1E2113D838200C7059E /* runtests.sh */,
+			);
+			name = Scripts;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		8D07F2BD0486CC7A007CD1D0 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3B7EB1260E5AEE3500C7F239 /* widget.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */;
+			buildPhases = (
+				3B07BDE70E3F3F9E00647869 /* Sources */,
+				3B07BDE80E3F3F9E00647869 /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */,
+			);
+			name = WidgetFrameworkTest;
+			productName = gTestExampleTest;
+			productReference = 3B07BDEA0E3F3F9E00647869 /* WidgetFrameworkTest */;
+			productType = "com.apple.product-type.tool";
+		};
+		8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */;
+			buildPhases = (
+				8D07F2C10486CC7A007CD1D0 /* Sources */,
+				8D07F2C30486CC7A007CD1D0 /* Frameworks */,
+				8D07F2BD0486CC7A007CD1D0 /* Headers */,
+				8D07F2BF0486CC7A007CD1D0 /* Resources */,
+				8D07F2C50486CC7A007CD1D0 /* Rez */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = WidgetFramework;
+			productInstallPath = "$(HOME)/Library/Frameworks";
+			productName = gTestExample;
+			productReference = 8D07F2C80486CC7A007CD1D0 /* Widget.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		0867D690FE84028FC02AAC07 /* Project object */ = {
+			isa = PBXProject;
+			buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */;
+			compatibilityVersion = "Xcode 2.4";
+			hasScannedForEncodings = 1;
+			mainGroup = 0867D691FE84028FC02AAC07 /* gTestExample */;
+			productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */,
+				3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */,
+				4024D162113D7D2400C7059E /* Test */,
+				4024D1E9113D83FF00C7059E /* TestAndBuild */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		8D07F2BF0486CC7A007CD1D0 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXRezBuildPhase section */
+		8D07F2C50486CC7A007CD1D0 /* Rez */ = {
+			isa = PBXRezBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXRezBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		4024D161113D7D2400C7059E /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "/bin/bash $SRCROOT/runtests.sh $BUILT_PRODUCTS_DIR/WidgetFrameworkTest\n";
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		3B07BDE70E3F3F9E00647869 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3B7EB1280E5AEE4600C7F239 /* widget_test.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D07F2C10486CC7A007CD1D0 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3B7EB1250E5AEE3500C7F239 /* widget.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		3B07BDF10E3F3FAE00647869 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */;
+			targetProxy = 3B07BDF00E3F3FAE00647869 /* PBXContainerItemProxy */;
+		};
+		4024D166113D7D3100C7059E /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 3B07BDE90E3F3F9E00647869 /* WidgetFrameworkTest */;
+			targetProxy = 4024D165113D7D3100C7059E /* PBXContainerItemProxy */;
+		};
+		4024D1ED113D840900C7059E /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 8D07F2BC0486CC7A007CD1D0 /* WidgetFramework */;
+			targetProxy = 4024D1EC113D840900C7059E /* PBXContainerItemProxy */;
+		};
+		4024D1EF113D840D00C7059E /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 4024D162113D7D2400C7059E /* Test */;
+			targetProxy = 4024D1EE113D840D00C7059E /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+		3B07BDEC0E3F3F9F00647869 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = WidgetFrameworkTest;
+			};
+			name = Debug;
+		};
+		3B07BDED0E3F3F9F00647869 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = WidgetFrameworkTest;
+			};
+			name = Release;
+		};
+		4024D163113D7D2400C7059E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = TestAndBuild;
+			};
+			name = Debug;
+		};
+		4024D164113D7D2400C7059E /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = TestAndBuild;
+			};
+			name = Release;
+		};
+		4024D1EA113D83FF00C7059E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = TestAndBuild;
+			};
+			name = Debug;
+		};
+		4024D1EB113D83FF00C7059E /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = TestAndBuild;
+			};
+			name = Release;
+		};
+		4FADC24308B4156D00ABE55E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_VERSION = A;
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "@loader_path/../Frameworks";
+				PRODUCT_NAME = Widget;
+			};
+			name = Debug;
+		};
+		4FADC24408B4156D00ABE55E /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				FRAMEWORK_VERSION = A;
+				INFOPLIST_FILE = Info.plist;
+				INSTALL_PATH = "@loader_path/../Frameworks";
+				PRODUCT_NAME = Widget;
+			};
+			name = Release;
+		};
+		4FADC24708B4156D00ABE55E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_VERSION = 4.0;
+				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+			};
+			name = Debug;
+		};
+		4FADC24808B4156D00ABE55E /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				GCC_VERSION = 4.0;
+				SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		3B07BDF40E3F3FB600647869 /* Build configuration list for PBXNativeTarget "WidgetFrameworkTest" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				3B07BDEC0E3F3F9F00647869 /* Debug */,
+				3B07BDED0E3F3F9F00647869 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4024D169113D7D4600C7059E /* Build configuration list for PBXAggregateTarget "Test" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4024D163113D7D2400C7059E /* Debug */,
+				4024D164113D7D2400C7059E /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4024D1F0113D842B00C7059E /* Build configuration list for PBXAggregateTarget "TestAndBuild" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4024D1EA113D83FF00C7059E /* Debug */,
+				4024D1EB113D83FF00C7059E /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "WidgetFramework" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4FADC24308B4156D00ABE55E /* Debug */,
+				4FADC24408B4156D00ABE55E /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "WidgetFramework" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4FADC24708B4156D00ABE55E /* Debug */,
+				4FADC24808B4156D00ABE55E /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
+}
diff --git a/protobuf/gtest/xcode/Samples/FrameworkSample/runtests.sh b/protobuf/gtest/xcode/Samples/FrameworkSample/runtests.sh
new file mode 100644
index 0000000..4a0d413
--- /dev/null
+++ b/protobuf/gtest/xcode/Samples/FrameworkSample/runtests.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+#
+# 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.
+
+# Executes the samples and tests for the Google Test Framework.
+
+# Help the dynamic linker find the path to the libraries.
+export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR
+export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR
+
+# Create some executables.
+test_executables=$@
+
+# Now execute each one in turn keeping track of how many succeeded and failed.
+succeeded=0
+failed=0
+failed_list=()
+for test in ${test_executables[*]}; do
+  "$test"
+  result=$?
+  if [ $result -eq 0 ]; then
+    succeeded=$(( $succeeded + 1 ))
+  else
+    failed=$(( failed + 1 ))
+    failed_list="$failed_list $test"
+  fi
+done
+
+# Report the successes and failures to the console.
+echo "Tests complete with $succeeded successes and $failed failures."
+if [ $failed -ne 0 ]; then
+  echo "The following tests failed:"
+  echo $failed_list
+fi
+exit $failed
diff --git a/protobuf/gtest/xcode/Samples/FrameworkSample/widget.cc b/protobuf/gtest/xcode/Samples/FrameworkSample/widget.cc
new file mode 100644
index 0000000..bfc4e7f
--- /dev/null
+++ b/protobuf/gtest/xcode/Samples/FrameworkSample/widget.cc
@@ -0,0 +1,63 @@
+// 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: preston.a.jackson@gmail.com (Preston Jackson)
+//
+// Google Test - FrameworkSample
+// widget.cc
+//
+
+// Widget is a very simple class used for demonstrating the use of gtest
+
+#include "widget.h"
+
+Widget::Widget(int number, const std::string& name)
+    : number_(number),
+      name_(name) {}
+
+Widget::~Widget() {}
+
+float Widget::GetFloatValue() const {
+  return number_;
+}
+
+int Widget::GetIntValue() const {
+  return static_cast<int>(number_);
+}
+
+std::string Widget::GetStringValue() const {
+  return name_;
+}
+
+void Widget::GetCharPtrValue(char* buffer, size_t max_size) const {
+  // Copy the char* representation of name_ into buffer, up to max_size.
+  strncpy(buffer, name_.c_str(), max_size-1);
+  buffer[max_size-1] = '\0';
+  return;
+}
diff --git a/protobuf/gtest/xcode/Samples/FrameworkSample/widget.h b/protobuf/gtest/xcode/Samples/FrameworkSample/widget.h
new file mode 100644
index 0000000..0c55cdc
--- /dev/null
+++ b/protobuf/gtest/xcode/Samples/FrameworkSample/widget.h
@@ -0,0 +1,59 @@
+// 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: preston.a.jackson@gmail.com (Preston Jackson)
+//
+// Google Test - FrameworkSample
+// widget.h
+//
+
+// Widget is a very simple class used for demonstrating the use of gtest. It
+// simply stores two values a string and an integer, which are returned via
+// public accessors in multiple forms.
+
+#import <string>
+
+class Widget {
+ public:
+  Widget(int number, const std::string& name);
+  ~Widget();
+
+  // Public accessors to number data
+  float GetFloatValue() const;
+  int GetIntValue() const;
+
+  // Public accessors to the string data
+  std::string GetStringValue() const;
+  void GetCharPtrValue(char* buffer, size_t max_size) const;
+
+ private:
+  // Data members
+  float number_;
+  std::string name_;
+};
diff --git a/protobuf/gtest/xcode/Samples/FrameworkSample/widget_test.cc b/protobuf/gtest/xcode/Samples/FrameworkSample/widget_test.cc
new file mode 100644
index 0000000..61c0d2f
--- /dev/null
+++ b/protobuf/gtest/xcode/Samples/FrameworkSample/widget_test.cc
@@ -0,0 +1,68 @@
+// 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: preston.a.jackson@gmail.com (Preston Jackson)
+//
+// Google Test - FrameworkSample
+// widget_test.cc
+//
+
+// This is a simple test file for the Widget class in the Widget.framework
+
+#include <string>
+#include <gtest/gtest.h>
+
+#include <Widget/widget.h>
+
+// This test verifies that the constructor sets the internal state of the
+// Widget class correctly.
+TEST(WidgetInitializerTest, TestConstructor) {
+  Widget widget(1.0f, "name");
+  EXPECT_FLOAT_EQ(1.0f, widget.GetFloatValue());
+  EXPECT_EQ(std::string("name"), widget.GetStringValue());
+}
+
+// This test verifies the conversion of the float and string values to int and
+// char*, respectively.
+TEST(WidgetInitializerTest, TestConversion) {
+  Widget widget(1.0f, "name");
+  EXPECT_EQ(1, widget.GetIntValue());
+
+  size_t max_size = 128;
+  char buffer[max_size];
+  widget.GetCharPtrValue(buffer, max_size);
+  EXPECT_STREQ("name", buffer);
+}
+
+// Use the Google Test main that is linked into the framework. It does something
+// like this:
+// int main(int argc, char** argv) {
+//   testing::InitGoogleTest(&argc, argv);
+//   return RUN_ALL_TESTS();
+// }
diff --git a/protobuf/gtest/xcode/Scripts/runtests.sh b/protobuf/gtest/xcode/Scripts/runtests.sh
new file mode 100644
index 0000000..3fc229f
--- /dev/null
+++ b/protobuf/gtest/xcode/Scripts/runtests.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+#
+# 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.
+
+# Executes the samples and tests for the Google Test Framework.
+
+# Help the dynamic linker find the path to the libraries.
+export DYLD_FRAMEWORK_PATH=$BUILT_PRODUCTS_DIR
+export DYLD_LIBRARY_PATH=$BUILT_PRODUCTS_DIR
+
+# Create some executables.
+test_executables=("$BUILT_PRODUCTS_DIR/gtest_unittest-framework"
+                  "$BUILT_PRODUCTS_DIR/gtest_unittest"
+                  "$BUILT_PRODUCTS_DIR/sample1_unittest-framework"
+                  "$BUILT_PRODUCTS_DIR/sample1_unittest-static")
+
+# Now execute each one in turn keeping track of how many succeeded and failed. 
+succeeded=0
+failed=0
+failed_list=()
+for test in ${test_executables[*]}; do
+  "$test"
+  result=$?
+  if [ $result -eq 0 ]; then
+    succeeded=$(( $succeeded + 1 ))
+  else
+    failed=$(( failed + 1 ))
+    failed_list="$failed_list $test"
+  fi
+done
+
+# Report the successes and failures to the console.
+echo "Tests complete with $succeeded successes and $failed failures."
+if [ $failed -ne 0 ]; then
+  echo "The following tests failed:"
+  echo $failed_list
+fi
+exit $failed
diff --git a/protobuf/gtest/xcode/Scripts/versiongenerate.py b/protobuf/gtest/xcode/Scripts/versiongenerate.py
new file mode 100755
index 0000000..81de8c9
--- /dev/null
+++ b/protobuf/gtest/xcode/Scripts/versiongenerate.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""A script to prepare version informtion for use the gtest Info.plist file.
+
+  This script extracts the version information from the configure.ac file and
+  uses it to generate a header file containing the same information. The
+  #defines in this header file will be included in during the generation of
+  the Info.plist of the framework, giving the correct value to the version
+  shown in the Finder.
+
+  This script makes the following assumptions (these are faults of the script,
+  not problems with the Autoconf):
+    1. The AC_INIT macro will be contained within the first 1024 characters
+       of configure.ac
+    2. The version string will be 3 integers separated by periods and will be
+       surrounded by squre brackets, "[" and "]" (e.g. [1.0.1]). The first
+       segment represents the major version, the second represents the minor
+       version and the third represents the fix version.
+    3. No ")" character exists between the opening "(" and closing ")" of
+       AC_INIT, including in comments and character strings.
+"""
+
+import sys
+import re
+
+# Read the command line argument (the output directory for Version.h)
+if (len(sys.argv) < 3):
+  print "Usage: versiongenerate.py input_dir output_dir"
+  sys.exit(1)
+else:
+  input_dir = sys.argv[1]
+  output_dir = sys.argv[2]
+
+# Read the first 1024 characters of the configure.ac file
+config_file = open("%s/configure.ac" % input_dir, 'r')
+buffer_size = 1024
+opening_string = config_file.read(buffer_size)
+config_file.close()
+
+# Extract the version string from the AC_INIT macro
+#   The following init_expression means:
+#     Extract three integers separated by periods and surrounded by squre
+#     brackets(e.g. "[1.0.1]") between "AC_INIT(" and ")". Do not be greedy
+#     (*? is the non-greedy flag) since that would pull in everything between
+#     the first "(" and the last ")" in the file.
+version_expression = re.compile(r"AC_INIT\(.*?\[(\d+)\.(\d+)\.(\d+)\].*?\)",
+                                re.DOTALL)
+version_values = version_expression.search(opening_string)
+major_version = version_values.group(1)
+minor_version = version_values.group(2)
+fix_version = version_values.group(3)
+
+# Write the version information to a header file to be included in the
+# Info.plist file.
+file_data = """//
+// DO NOT MODIFY THIS FILE (but you can delete it)
+//
+// This file is autogenerated by the versiongenerate.py script. This script
+// is executed in a "Run Script" build phase when creating gtest.framework. This
+// header file is not used during compilation of C-source. Rather, it simply
+// defines some version strings for substitution in the Info.plist. Because of
+// this, we are not not restricted to C-syntax nor are we using include guards.
+//
+
+#define GTEST_VERSIONINFO_SHORT %s.%s
+#define GTEST_VERSIONINFO_LONG %s.%s.%s
+
+""" % (major_version, minor_version, major_version, minor_version, fix_version)
+version_file = open("%s/Version.h" % output_dir, 'w')
+version_file.write(file_data)
+version_file.close()
diff --git a/protobuf/gtest/xcode/gtest.xcodeproj/project.pbxproj b/protobuf/gtest/xcode/gtest.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..4234e72
--- /dev/null
+++ b/protobuf/gtest/xcode/gtest.xcodeproj/project.pbxproj
@@ -0,0 +1,1080 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 42;
+	objects = {
+
+/* Begin PBXAggregateTarget section */
+		3B238F5F0E828B5400846E11 /* Check */ = {
+			isa = PBXAggregateTarget;
+			buildConfigurationList = 3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */;
+			buildPhases = (
+				3B238F5E0E828B5400846E11 /* ShellScript */,
+			);
+			dependencies = (
+				40899F9D0FFA740F000B29AE /* PBXTargetDependency */,
+				40C849F7101A43440083642A /* PBXTargetDependency */,
+				4089A0980FFAD34A000B29AE /* PBXTargetDependency */,
+				40C849F9101A43490083642A /* PBXTargetDependency */,
+			);
+			name = Check;
+			productName = Check;
+		};
+		40C44ADC0E3798F4008FCC51 /* Version Info */ = {
+			isa = PBXAggregateTarget;
+			buildConfigurationList = 40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */;
+			buildPhases = (
+				40C44ADB0E3798F4008FCC51 /* Generate Version.h */,
+			);
+			comments = "The generation of Version.h must be performed in its own target. Since the Info.plist is preprocessed before any of the other build phases in gtest, the Version.h file would not be ready if included as a build phase of that target.";
+			dependencies = (
+			);
+			name = "Version Info";
+			productName = Version.h;
+		};
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+		224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */ = {isa = PBXBuildFile; fileRef = 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */; };
+		3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DB0E2F799B00CF7658 /* gtest-death-test.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		404884390E2F799B00CF7658 /* gtest-message.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DC0E2F799B00CF7658 /* gtest-message.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DD0E2F799B00CF7658 /* gtest-spi.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4048843B0E2F799B00CF7658 /* gtest.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DE0E2F799B00CF7658 /* gtest.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */ = {isa = PBXBuildFile; fileRef = 404883E00E2F799B00CF7658 /* gtest_prod.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		404884500E2F799B00CF7658 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 404883F60E2F799B00CF7658 /* README */; };
+		404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */; };
+		404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E30E2F799B00CF7658 /* gtest-filepath.h */; };
+		404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E40E2F799B00CF7658 /* gtest-internal.h */; };
+		404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E50E2F799B00CF7658 /* gtest-port.h */; };
+		404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 404883E60E2F799B00CF7658 /* gtest-string.h */; };
+		404884AC0E2F7CD900CF7658 /* CHANGES in Resources */ = {isa = PBXBuildFile; fileRef = 404884A90E2F7CD900CF7658 /* CHANGES */; };
+		404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */ = {isa = PBXBuildFile; fileRef = 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */; };
+		404884AE0E2F7CD900CF7658 /* COPYING in Resources */ = {isa = PBXBuildFile; fileRef = 404884AB0E2F7CD900CF7658 /* COPYING */; };
+		40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; };
+		40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 40899F4D0FFA7271000B29AE /* gtest-tuple.h */; };
+		40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; };
+		4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; };
+		4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; };
+		40C848FF101A21150083642A /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = 224A12A10E9EADA700BD17FD /* gtest-all.cc */; };
+		40C84915101A21DF0083642A /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4048840D0E2F799B00CF7658 /* gtest_main.cc */; };
+		40C84916101A235B0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; };
+		40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; };
+		40C84978101A36540083642A /* libgtest_main.a in Resources */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; };
+		40C84980101A36850083642A /* gtest_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238C120E7FE13C00846E11 /* gtest_unittest.cc */; };
+		40C84982101A36850083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; };
+		40C84983101A36850083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; };
+		40C8498F101A36A60083642A /* sample1.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02C0FFACF7F000B29AE /* sample1.cc */; };
+		40C84990101A36A60083642A /* sample1_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */; };
+		40C84992101A36A60083642A /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C848FA101A209C0083642A /* libgtest.a */; };
+		40C84993101A36A60083642A /* libgtest_main.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 40C8490B101A217E0083642A /* libgtest_main.a */; };
+		40C849A2101A37050083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; };
+		40C849A4101A37150083642A /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4539C8FF0EC27F6400A70F4C /* gtest.framework */; };
+		4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 4539C9330EC280AE00A70F4C /* gtest-param-test.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */; };
+		4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */; };
+		4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9370EC280E200A70F4C /* gtest-param-util.h */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 40899F420FFA7184000B29AE;
+			remoteInfo = gtest_unittest;
+		};
+		4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 4089A0120FFACEFC000B29AE;
+			remoteInfo = sample1_unittest;
+		};
+		408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 40C848F9101A209C0083642A;
+			remoteInfo = "gtest-static";
+		};
+		40C44AE50E379922008FCC51 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 40C44ADC0E3798F4008FCC51;
+			remoteInfo = Version.h;
+		};
+		40C8497C101A36850083642A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 40C848F9101A209C0083642A;
+			remoteInfo = "gtest-static";
+		};
+		40C8497E101A36850083642A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 40C8490A101A217E0083642A;
+			remoteInfo = "gtest_main-static";
+		};
+		40C8498B101A36A60083642A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 40C848F9101A209C0083642A;
+			remoteInfo = "gtest-static";
+		};
+		40C8498D101A36A60083642A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 40C8490A101A217E0083642A;
+			remoteInfo = "gtest_main-static";
+		};
+		40C8499B101A36DC0083642A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 40C8490A101A217E0083642A;
+			remoteInfo = "gtest_main-static";
+		};
+		40C8499D101A36E50083642A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
+			remoteInfo = "gtest-framework";
+		};
+		40C8499F101A36F10083642A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
+			remoteInfo = "gtest-framework";
+		};
+		40C849F6101A43440083642A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 40C8497A101A36850083642A;
+			remoteInfo = "gtest_unittest-static";
+		};
+		40C849F8101A43490083642A /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 40C84989101A36A60083642A;
+			remoteInfo = "sample1_unittest-static";
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		404884A50E2F7C0400CF7658 /* Copy Headers Internal */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = Headers/internal;
+			dstSubfolderSpec = 6;
+			files = (
+				404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */,
+				404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */,
+				404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */,
+				4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */,
+				4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */,
+				4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */,
+				404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */,
+				404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */,
+				40899F500FFA7281000B29AE /* gtest-tuple.h in Copy Headers Internal */,
+				3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */,
+			);
+			name = "Copy Headers Internal";
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		224A12A10E9EADA700BD17FD /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-all.cc"; sourceTree = "<group>"; };
+		224A12A20E9EADCC00BD17FD /* gtest-test-part.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = "gtest-test-part.h"; sourceTree = "<group>"; };
+		3B238C120E7FE13C00846E11 /* gtest_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_unittest.cc; sourceTree = "<group>"; };
+		3B87D2100E96B92E000D1852 /* runtests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = runtests.sh; sourceTree = "<group>"; };
+		3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-type-util.h"; sourceTree = "<group>"; };
+		3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-typed-test.h"; sourceTree = "<group>"; };
+		403EE37C0E377822004BD1E2 /* versiongenerate.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = versiongenerate.py; sourceTree = "<group>"; };
+		404883DB0E2F799B00CF7658 /* gtest-death-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test.h"; sourceTree = "<group>"; };
+		404883DC0E2F799B00CF7658 /* gtest-message.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-message.h"; sourceTree = "<group>"; };
+		404883DD0E2F799B00CF7658 /* gtest-spi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-spi.h"; sourceTree = "<group>"; };
+		404883DE0E2F799B00CF7658 /* gtest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest.h; sourceTree = "<group>"; };
+		404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_pred_impl.h; sourceTree = "<group>"; };
+		404883E00E2F799B00CF7658 /* gtest_prod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gtest_prod.h; sourceTree = "<group>"; };
+		404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-death-test-internal.h"; sourceTree = "<group>"; };
+		404883E30E2F799B00CF7658 /* gtest-filepath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-filepath.h"; sourceTree = "<group>"; };
+		404883E40E2F799B00CF7658 /* gtest-internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-internal.h"; sourceTree = "<group>"; };
+		404883E50E2F799B00CF7658 /* gtest-port.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-port.h"; sourceTree = "<group>"; };
+		404883E60E2F799B00CF7658 /* gtest-string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-string.h"; sourceTree = "<group>"; };
+		404883F60E2F799B00CF7658 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README; path = ../README; sourceTree = SOURCE_ROOT; };
+		4048840D0E2F799B00CF7658 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = "<group>"; };
+		404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; };
+		404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; };
+		404884AB0E2F7CD900CF7658 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = ../COPYING; sourceTree = SOURCE_ROOT; };
+		40899F430FFA7184000B29AE /* gtest_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; };
+		40899F4D0FFA7271000B29AE /* gtest-tuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-tuple.h"; sourceTree = "<group>"; };
+		40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = StaticLibraryTarget.xcconfig; sourceTree = "<group>"; };
+		4089A0130FFACEFC000B29AE /* sample1_unittest-framework */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-framework"; sourceTree = BUILT_PRODUCTS_DIR; };
+		4089A02C0FFACF7F000B29AE /* sample1.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1.cc; sourceTree = "<group>"; };
+		4089A02D0FFACF7F000B29AE /* sample1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sample1.h; sourceTree = "<group>"; };
+		4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample1_unittest.cc; sourceTree = "<group>"; };
+		40C848FA101A209C0083642A /* libgtest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		40C8490B101A217E0083642A /* libgtest_main.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest_main.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		40C84987101A36850083642A /* gtest_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gtest_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
+		40C84997101A36A60083642A /* sample1_unittest-static */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "sample1_unittest-static"; sourceTree = BUILT_PRODUCTS_DIR; };
+		40D4CDF10E30E07400294801 /* DebugProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugProject.xcconfig; sourceTree = "<group>"; };
+		40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = FrameworkTarget.xcconfig; sourceTree = "<group>"; };
+		40D4CDF30E30E07400294801 /* General.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = "<group>"; };
+		40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseProject.xcconfig; sourceTree = "<group>"; };
+		40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		4539C8FF0EC27F6400A70F4C /* gtest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gtest.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		4539C9330EC280AE00A70F4C /* gtest-param-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-test.h"; sourceTree = "<group>"; };
+		4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-linked_ptr.h"; sourceTree = "<group>"; };
+		4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util-generated.h"; sourceTree = "<group>"; };
+		4539C9370EC280E200A70F4C /* gtest-param-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util.h"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		40899F410FFA7184000B29AE /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				40C849A4101A37150083642A /* gtest.framework in Frameworks */,
+				40C84916101A235B0083642A /* libgtest_main.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4089A0110FFACEFC000B29AE /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				40C849A2101A37050083642A /* gtest.framework in Frameworks */,
+				40C84921101A23AD0083642A /* libgtest_main.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		40C84981101A36850083642A /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				40C84982101A36850083642A /* libgtest.a in Frameworks */,
+				40C84983101A36850083642A /* libgtest_main.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		40C84991101A36A60083642A /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				40C84992101A36A60083642A /* libgtest.a in Frameworks */,
+				40C84993101A36A60083642A /* libgtest_main.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		034768DDFF38A45A11DB9C8B /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				4539C8FF0EC27F6400A70F4C /* gtest.framework */,
+				40C848FA101A209C0083642A /* libgtest.a */,
+				40C8490B101A217E0083642A /* libgtest_main.a */,
+				40899F430FFA7184000B29AE /* gtest_unittest-framework */,
+				40C84987101A36850083642A /* gtest_unittest */,
+				4089A0130FFACEFC000B29AE /* sample1_unittest-framework */,
+				40C84997101A36A60083642A /* sample1_unittest-static */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		0867D691FE84028FC02AAC07 /* gtest */ = {
+			isa = PBXGroup;
+			children = (
+				40D4CDF00E30E07400294801 /* Config */,
+				08FB77ACFE841707C02AAC07 /* Source */,
+				40D4CF4E0E30F5E200294801 /* Resources */,
+				403EE37B0E377822004BD1E2 /* Scripts */,
+				034768DDFF38A45A11DB9C8B /* Products */,
+			);
+			name = gtest;
+			sourceTree = "<group>";
+		};
+		08FB77ACFE841707C02AAC07 /* Source */ = {
+			isa = PBXGroup;
+			children = (
+				404884A90E2F7CD900CF7658 /* CHANGES */,
+				404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */,
+				404884AB0E2F7CD900CF7658 /* COPYING */,
+				404883F60E2F799B00CF7658 /* README */,
+				404883D90E2F799B00CF7658 /* include */,
+				4089A02F0FFACF84000B29AE /* samples */,
+				404884070E2F799B00CF7658 /* src */,
+				3B238BF00E7FE13B00846E11 /* test */,
+			);
+			name = Source;
+			sourceTree = "<group>";
+		};
+		3B238BF00E7FE13B00846E11 /* test */ = {
+			isa = PBXGroup;
+			children = (
+				3B238C120E7FE13C00846E11 /* gtest_unittest.cc */,
+			);
+			name = test;
+			path = ../test;
+			sourceTree = SOURCE_ROOT;
+		};
+		403EE37B0E377822004BD1E2 /* Scripts */ = {
+			isa = PBXGroup;
+			children = (
+				403EE37C0E377822004BD1E2 /* versiongenerate.py */,
+				3B87D2100E96B92E000D1852 /* runtests.sh */,
+			);
+			path = Scripts;
+			sourceTree = "<group>";
+		};
+		404883D90E2F799B00CF7658 /* include */ = {
+			isa = PBXGroup;
+			children = (
+				404883DA0E2F799B00CF7658 /* gtest */,
+			);
+			name = include;
+			path = ../include;
+			sourceTree = SOURCE_ROOT;
+		};
+		404883DA0E2F799B00CF7658 /* gtest */ = {
+			isa = PBXGroup;
+			children = (
+				404883E10E2F799B00CF7658 /* internal */,
+				224A12A20E9EADCC00BD17FD /* gtest-test-part.h */,
+				404883DB0E2F799B00CF7658 /* gtest-death-test.h */,
+				404883DC0E2F799B00CF7658 /* gtest-message.h */,
+				4539C9330EC280AE00A70F4C /* gtest-param-test.h */,
+				404883DD0E2F799B00CF7658 /* gtest-spi.h */,
+				404883DE0E2F799B00CF7658 /* gtest.h */,
+				404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */,
+				404883E00E2F799B00CF7658 /* gtest_prod.h */,
+				3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */,
+			);
+			path = gtest;
+			sourceTree = "<group>";
+		};
+		404883E10E2F799B00CF7658 /* internal */ = {
+			isa = PBXGroup;
+			children = (
+				404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */,
+				404883E30E2F799B00CF7658 /* gtest-filepath.h */,
+				404883E40E2F799B00CF7658 /* gtest-internal.h */,
+				4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */,
+				4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */,
+				4539C9370EC280E200A70F4C /* gtest-param-util.h */,
+				404883E50E2F799B00CF7658 /* gtest-port.h */,
+				404883E60E2F799B00CF7658 /* gtest-string.h */,
+				40899F4D0FFA7271000B29AE /* gtest-tuple.h */,
+				3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */,
+			);
+			path = internal;
+			sourceTree = "<group>";
+		};
+		404884070E2F799B00CF7658 /* src */ = {
+			isa = PBXGroup;
+			children = (
+				224A12A10E9EADA700BD17FD /* gtest-all.cc */,
+				4048840D0E2F799B00CF7658 /* gtest_main.cc */,
+			);
+			name = src;
+			path = ../src;
+			sourceTree = SOURCE_ROOT;
+		};
+		4089A02F0FFACF84000B29AE /* samples */ = {
+			isa = PBXGroup;
+			children = (
+				4089A02C0FFACF7F000B29AE /* sample1.cc */,
+				4089A02D0FFACF7F000B29AE /* sample1.h */,
+				4089A02E0FFACF7F000B29AE /* sample1_unittest.cc */,
+			);
+			name = samples;
+			path = ../samples;
+			sourceTree = SOURCE_ROOT;
+		};
+		40D4CDF00E30E07400294801 /* Config */ = {
+			isa = PBXGroup;
+			children = (
+				40D4CDF10E30E07400294801 /* DebugProject.xcconfig */,
+				40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */,
+				40D4CDF30E30E07400294801 /* General.xcconfig */,
+				40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */,
+				40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */,
+			);
+			path = Config;
+			sourceTree = "<group>";
+		};
+		40D4CF4E0E30F5E200294801 /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				40D4CF510E30F5E200294801 /* Info.plist */,
+			);
+			path = Resources;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+		8D07F2BD0486CC7A007CD1D0 /* Headers */ = {
+			isa = PBXHeadersBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */,
+				404884390E2F799B00CF7658 /* gtest-message.h in Headers */,
+				4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */,
+				3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */,
+				4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */,
+				4048843B0E2F799B00CF7658 /* gtest.h in Headers */,
+				4048843C0E2F799B00CF7658 /* gtest_pred_impl.h in Headers */,
+				4048843D0E2F799B00CF7658 /* gtest_prod.h in Headers */,
+				224A12A30E9EADCC00BD17FD /* gtest-test-part.h in Headers */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+		40899F420FFA7184000B29AE /* gtest_unittest-framework */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */;
+			buildPhases = (
+				40899F400FFA7184000B29AE /* Sources */,
+				40899F410FFA7184000B29AE /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				40C849A0101A36F10083642A /* PBXTargetDependency */,
+			);
+			name = "gtest_unittest-framework";
+			productName = gtest_unittest;
+			productReference = 40899F430FFA7184000B29AE /* gtest_unittest-framework */;
+			productType = "com.apple.product-type.tool";
+		};
+		4089A0120FFACEFC000B29AE /* sample1_unittest-framework */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */;
+			buildPhases = (
+				4089A0100FFACEFC000B29AE /* Sources */,
+				4089A0110FFACEFC000B29AE /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				40C8499E101A36E50083642A /* PBXTargetDependency */,
+			);
+			name = "sample1_unittest-framework";
+			productName = sample1_unittest;
+			productReference = 4089A0130FFACEFC000B29AE /* sample1_unittest-framework */;
+			productType = "com.apple.product-type.tool";
+		};
+		40C848F9101A209C0083642A /* gtest-static */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */;
+			buildPhases = (
+				40C848F7101A209C0083642A /* Sources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "gtest-static";
+			productName = "gtest-static";
+			productReference = 40C848FA101A209C0083642A /* libgtest.a */;
+			productType = "com.apple.product-type.library.static";
+		};
+		40C8490A101A217E0083642A /* gtest_main-static */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */;
+			buildPhases = (
+				40C84908101A217E0083642A /* Sources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "gtest_main-static";
+			productName = "gtest_main-static";
+			productReference = 40C8490B101A217E0083642A /* libgtest_main.a */;
+			productType = "com.apple.product-type.library.static";
+		};
+		40C8497A101A36850083642A /* gtest_unittest-static */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */;
+			buildPhases = (
+				40C8497F101A36850083642A /* Sources */,
+				40C84981101A36850083642A /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				40C8497B101A36850083642A /* PBXTargetDependency */,
+				40C8497D101A36850083642A /* PBXTargetDependency */,
+			);
+			name = "gtest_unittest-static";
+			productName = gtest_unittest;
+			productReference = 40C84987101A36850083642A /* gtest_unittest */;
+			productType = "com.apple.product-type.tool";
+		};
+		40C84989101A36A60083642A /* sample1_unittest-static */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */;
+			buildPhases = (
+				40C8498E101A36A60083642A /* Sources */,
+				40C84991101A36A60083642A /* Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				40C8498A101A36A60083642A /* PBXTargetDependency */,
+				40C8498C101A36A60083642A /* PBXTargetDependency */,
+			);
+			name = "sample1_unittest-static";
+			productName = sample1_unittest;
+			productReference = 40C84997101A36A60083642A /* sample1_unittest-static */;
+			productType = "com.apple.product-type.tool";
+		};
+		8D07F2BC0486CC7A007CD1D0 /* gtest-framework */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */;
+			buildPhases = (
+				8D07F2C10486CC7A007CD1D0 /* Sources */,
+				8D07F2BD0486CC7A007CD1D0 /* Headers */,
+				404884A50E2F7C0400CF7658 /* Copy Headers Internal */,
+				8D07F2BF0486CC7A007CD1D0 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				40C44AE60E379922008FCC51 /* PBXTargetDependency */,
+				408BEC101046CFE900DEF522 /* PBXTargetDependency */,
+				40C8499C101A36DC0083642A /* PBXTargetDependency */,
+			);
+			name = "gtest-framework";
+			productInstallPath = "$(HOME)/Library/Frameworks";
+			productName = gtest;
+			productReference = 4539C8FF0EC27F6400A70F4C /* gtest.framework */;
+			productType = "com.apple.product-type.framework";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		0867D690FE84028FC02AAC07 /* Project object */ = {
+			isa = PBXProject;
+			buildConfigurationList = 4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */;
+			compatibilityVersion = "Xcode 2.4";
+			hasScannedForEncodings = 1;
+			knownRegions = (
+				English,
+				Japanese,
+				French,
+				German,
+				en,
+			);
+			mainGroup = 0867D691FE84028FC02AAC07 /* gtest */;
+			productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				8D07F2BC0486CC7A007CD1D0 /* gtest-framework */,
+				40C848F9101A209C0083642A /* gtest-static */,
+				40C8490A101A217E0083642A /* gtest_main-static */,
+				40899F420FFA7184000B29AE /* gtest_unittest-framework */,
+				40C8497A101A36850083642A /* gtest_unittest-static */,
+				4089A0120FFACEFC000B29AE /* sample1_unittest-framework */,
+				40C84989101A36A60083642A /* sample1_unittest-static */,
+				3B238F5F0E828B5400846E11 /* Check */,
+				40C44ADC0E3798F4008FCC51 /* Version Info */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		8D07F2BF0486CC7A007CD1D0 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				404884500E2F799B00CF7658 /* README in Resources */,
+				404884AC0E2F7CD900CF7658 /* CHANGES in Resources */,
+				404884AD0E2F7CD900CF7658 /* CONTRIBUTORS in Resources */,
+				404884AE0E2F7CD900CF7658 /* COPYING in Resources */,
+				40C84978101A36540083642A /* libgtest_main.a in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		3B238F5E0E828B5400846E11 /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/bin/bash Scripts/runtests.sh";
+		};
+		40C44ADB0E3798F4008FCC51 /* Generate Version.h */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"$(SRCROOT)/Scripts/versiongenerate.py",
+				"$(SRCROOT)/../configure.ac",
+			);
+			name = "Generate Version.h";
+			outputPaths = (
+				"$(PROJECT_TEMP_DIR)/Version.h",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "# Remember, this \"Run Script\" build phase will be executed from $SRCROOT\n/usr/bin/python Scripts/versiongenerate.py ../ $PROJECT_TEMP_DIR";
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		40899F400FFA7184000B29AE /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				40899F530FFA72A0000B29AE /* gtest_unittest.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		4089A0100FFACEFC000B29AE /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				4089A0440FFAD1BE000B29AE /* sample1.cc in Sources */,
+				4089A0460FFAD1BE000B29AE /* sample1_unittest.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		40C848F7101A209C0083642A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				40C848FF101A21150083642A /* gtest-all.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		40C84908101A217E0083642A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				40C84915101A21DF0083642A /* gtest_main.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		40C8497F101A36850083642A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				40C84980101A36850083642A /* gtest_unittest.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		40C8498E101A36A60083642A /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				40C8498F101A36A60083642A /* sample1.cc in Sources */,
+				40C84990101A36A60083642A /* sample1_unittest.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8D07F2C10486CC7A007CD1D0 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				40899F3A0FFA70D4000B29AE /* gtest-all.cc in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		40899F9D0FFA740F000B29AE /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 40899F420FFA7184000B29AE /* gtest_unittest-framework */;
+			targetProxy = 40899F9C0FFA740F000B29AE /* PBXContainerItemProxy */;
+		};
+		4089A0980FFAD34A000B29AE /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 4089A0120FFACEFC000B29AE /* sample1_unittest-framework */;
+			targetProxy = 4089A0970FFAD34A000B29AE /* PBXContainerItemProxy */;
+		};
+		408BEC101046CFE900DEF522 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 40C848F9101A209C0083642A /* gtest-static */;
+			targetProxy = 408BEC0F1046CFE900DEF522 /* PBXContainerItemProxy */;
+		};
+		40C44AE60E379922008FCC51 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 40C44ADC0E3798F4008FCC51 /* Version Info */;
+			targetProxy = 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */;
+		};
+		40C8497B101A36850083642A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 40C848F9101A209C0083642A /* gtest-static */;
+			targetProxy = 40C8497C101A36850083642A /* PBXContainerItemProxy */;
+		};
+		40C8497D101A36850083642A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 40C8490A101A217E0083642A /* gtest_main-static */;
+			targetProxy = 40C8497E101A36850083642A /* PBXContainerItemProxy */;
+		};
+		40C8498A101A36A60083642A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 40C848F9101A209C0083642A /* gtest-static */;
+			targetProxy = 40C8498B101A36A60083642A /* PBXContainerItemProxy */;
+		};
+		40C8498C101A36A60083642A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 40C8490A101A217E0083642A /* gtest_main-static */;
+			targetProxy = 40C8498D101A36A60083642A /* PBXContainerItemProxy */;
+		};
+		40C8499C101A36DC0083642A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 40C8490A101A217E0083642A /* gtest_main-static */;
+			targetProxy = 40C8499B101A36DC0083642A /* PBXContainerItemProxy */;
+		};
+		40C8499E101A36E50083642A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */;
+			targetProxy = 40C8499D101A36E50083642A /* PBXContainerItemProxy */;
+		};
+		40C849A0101A36F10083642A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 8D07F2BC0486CC7A007CD1D0 /* gtest-framework */;
+			targetProxy = 40C8499F101A36F10083642A /* PBXContainerItemProxy */;
+		};
+		40C849F7101A43440083642A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 40C8497A101A36850083642A /* gtest_unittest-static */;
+			targetProxy = 40C849F6101A43440083642A /* PBXContainerItemProxy */;
+		};
+		40C849F9101A43490083642A /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 40C84989101A36A60083642A /* sample1_unittest-static */;
+			targetProxy = 40C849F8101A43490083642A /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+		3B238F600E828B5400846E11 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				PRODUCT_NAME = Check;
+			};
+			name = Debug;
+		};
+		3B238F610E828B5400846E11 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				PRODUCT_NAME = Check;
+				ZERO_LINK = NO;
+			};
+			name = Release;
+		};
+		40899F450FFA7185000B29AE /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				HEADER_SEARCH_PATHS = ../;
+				PRODUCT_NAME = "gtest_unittest-framework";
+			};
+			name = Debug;
+		};
+		40899F460FFA7185000B29AE /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				HEADER_SEARCH_PATHS = ../;
+				PRODUCT_NAME = "gtest_unittest-framework";
+			};
+			name = Release;
+		};
+		4089A0150FFACEFD000B29AE /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "sample1_unittest-framework";
+			};
+			name = Debug;
+		};
+		4089A0160FFACEFD000B29AE /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "sample1_unittest-framework";
+			};
+			name = Release;
+		};
+		40C44ADF0E3798F4008FCC51 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = gtest;
+				TARGET_NAME = gtest;
+			};
+			name = Debug;
+		};
+		40C44AE00E3798F4008FCC51 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = gtest;
+				TARGET_NAME = gtest;
+			};
+			name = Release;
+		};
+		40C848FB101A209D0083642A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */;
+			buildSettings = {
+				GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+				HEADER_SEARCH_PATHS = (
+					../,
+					../include/,
+				);
+				PRODUCT_NAME = gtest;
+			};
+			name = Debug;
+		};
+		40C848FC101A209D0083642A /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */;
+			buildSettings = {
+				GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
+				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+				HEADER_SEARCH_PATHS = (
+					../,
+					../include/,
+				);
+				PRODUCT_NAME = gtest;
+			};
+			name = Release;
+		};
+		40C8490E101A217F0083642A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */;
+			buildSettings = {
+				HEADER_SEARCH_PATHS = (
+					../,
+					../include/,
+				);
+				PRODUCT_NAME = gtest_main;
+			};
+			name = Debug;
+		};
+		40C8490F101A217F0083642A /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 40899FB30FFA7567000B29AE /* StaticLibraryTarget.xcconfig */;
+			buildSettings = {
+				HEADER_SEARCH_PATHS = (
+					../,
+					../include/,
+				);
+				PRODUCT_NAME = gtest_main;
+			};
+			name = Release;
+		};
+		40C84985101A36850083642A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				HEADER_SEARCH_PATHS = ../;
+				PRODUCT_NAME = gtest_unittest;
+			};
+			name = Debug;
+		};
+		40C84986101A36850083642A /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				HEADER_SEARCH_PATHS = ../;
+				PRODUCT_NAME = gtest_unittest;
+			};
+			name = Release;
+		};
+		40C84995101A36A60083642A /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "sample1_unittest-static";
+			};
+			name = Debug;
+		};
+		40C84996101A36A60083642A /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "sample1_unittest-static";
+			};
+			name = Release;
+		};
+		4FADC24308B4156D00ABE55E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */;
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				HEADER_SEARCH_PATHS = (
+					../,
+					../include/,
+				);
+				INFOPLIST_FILE = Resources/Info.plist;
+				INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h";
+				INFOPLIST_PREPROCESS = YES;
+				PRODUCT_NAME = gtest;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Debug;
+		};
+		4FADC24408B4156D00ABE55E /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */;
+			buildSettings = {
+				DYLIB_COMPATIBILITY_VERSION = 1;
+				DYLIB_CURRENT_VERSION = 1;
+				HEADER_SEARCH_PATHS = (
+					../,
+					../include/,
+				);
+				INFOPLIST_FILE = Resources/Info.plist;
+				INFOPLIST_PREFIX_HEADER = "$(PROJECT_TEMP_DIR)/Version.h";
+				INFOPLIST_PREPROCESS = YES;
+				PRODUCT_NAME = gtest;
+				VERSIONING_SYSTEM = "apple-generic";
+			};
+			name = Release;
+		};
+		4FADC24708B4156D00ABE55E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */;
+			buildSettings = {
+			};
+			name = Debug;
+		};
+		4FADC24808B4156D00ABE55E /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */;
+			buildSettings = {
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		3B238FA30E828BB600846E11 /* Build configuration list for PBXAggregateTarget "Check" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				3B238F600E828B5400846E11 /* Debug */,
+				3B238F610E828B5400846E11 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		40899F4A0FFA71BC000B29AE /* Build configuration list for PBXNativeTarget "gtest_unittest-framework" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				40899F450FFA7185000B29AE /* Debug */,
+				40899F460FFA7185000B29AE /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4089A0240FFACF01000B29AE /* Build configuration list for PBXNativeTarget "sample1_unittest-framework" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4089A0150FFACEFD000B29AE /* Debug */,
+				4089A0160FFACEFD000B29AE /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		40C44AE40E379905008FCC51 /* Build configuration list for PBXAggregateTarget "Version Info" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				40C44ADF0E3798F4008FCC51 /* Debug */,
+				40C44AE00E3798F4008FCC51 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		40C84902101A212E0083642A /* Build configuration list for PBXNativeTarget "gtest-static" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				40C848FB101A209D0083642A /* Debug */,
+				40C848FC101A209D0083642A /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		40C84912101A21D20083642A /* Build configuration list for PBXNativeTarget "gtest_main-static" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				40C8490E101A217F0083642A /* Debug */,
+				40C8490F101A217F0083642A /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		40C84984101A36850083642A /* Build configuration list for PBXNativeTarget "gtest_unittest-static" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				40C84985101A36850083642A /* Debug */,
+				40C84986101A36850083642A /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		40C84994101A36A60083642A /* Build configuration list for PBXNativeTarget "sample1_unittest-static" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				40C84995101A36A60083642A /* Debug */,
+				40C84996101A36A60083642A /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest-framework" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4FADC24308B4156D00ABE55E /* Debug */,
+				4FADC24408B4156D00ABE55E /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		4FADC24608B4156D00ABE55E /* Build configuration list for PBXProject "gtest" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				4FADC24708B4156D00ABE55E /* Debug */,
+				4FADC24808B4156D00ABE55E /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
+}
diff --git a/protobuf/install-sh b/protobuf/install-sh
new file mode 100755
index 0000000..377bb86
--- /dev/null
+++ b/protobuf/install-sh
@@ -0,0 +1,527 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2011-11-20.07; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	# Protect names problematic for 'test' and other utilities.
+	case $dst_arg in
+	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
+	esac
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call 'install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names problematic for 'test' and other utilities.
+  case $src in
+    -* | [=\(\)!]) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+    dst=$dst_arg
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	[-=\(\)!]*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test X"$d" = X && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/protobuf/java/README.txt b/protobuf/java/README.txt
new file mode 100644
index 0000000..b02e88b
--- /dev/null
+++ b/protobuf/java/README.txt
@@ -0,0 +1,685 @@
+Protocol Buffers - Google's data interchange format
+Copyright 2008 Google Inc.
+
+This directory contains the Java Protocol Buffers runtime library.
+
+Installation - With Maven
+=========================
+
+The Protocol Buffers build is managed using Maven.  If you would
+rather build without Maven, see below.
+
+1) Install Apache Maven if you don't have it:
+
+     http://maven.apache.org/
+
+2) Build the C++ code, or obtain a binary distribution of protoc.  If
+   you install a binary distribution, make sure that it is the same
+   version as this package.  If in doubt, run:
+
+     $ protoc --version
+
+   You will need to place the protoc executable in ../src.  (If you
+   built it yourself, it should already be there.)
+
+3) Run the tests:
+
+     $ mvn test
+
+   If some tests fail, this library may not work correctly on your
+   system.  Continue at your own risk.
+
+4) Install the library into your Maven repository:
+
+     $ mvn install
+
+5) If you do not use Maven to manage your own build, you can build a
+   .jar file to use:
+
+     $ mvn package
+
+   The .jar will be placed in the "target" directory.
+
+Installation - 'Lite' Version - With Maven
+==========================================
+
+Building the 'lite' version of the Java Protocol Buffers library is
+the same as building the full version, except that all commands are
+run using the 'lite' profile.  (see
+http://maven.apache.org/guides/introduction/introduction-to-profiles.html)
+
+E.g. to install the lite version of the jar, you would run:
+
+  $ mvn install -P lite
+
+The resulting artifact has the 'lite' classifier.  To reference it
+for dependency resolution, you would specify it as:
+
+  <dependency>
+    <groupId>com.google.protobuf</groupId>
+    <artifactId>protobuf-java</artifactId>
+    <version>${version}</version>
+    <classifier>lite</classifier>
+  </dependency>
+
+Installation - Without Maven
+============================
+
+If you would rather not install Maven to build the library, you may
+follow these instructions instead.  Note that these instructions skip
+running unit tests.
+
+1) Build the C++ code, or obtain a binary distribution of protoc.  If
+   you install a binary distribution, make sure that it is the same
+   version as this package.  If in doubt, run:
+
+     $ protoc --version
+
+   If you built the C++ code without installing, the compiler binary
+   should be located in ../src.
+
+2) Invoke protoc to build DescriptorProtos.java:
+
+     $ protoc --java_out=src/main/java -I../src \
+         ../src/google/protobuf/descriptor.proto
+
+3) Compile the code in src/main/java using whatever means you prefer.
+
+4) Install the classes wherever you prefer.
+
+Micro version
+============================
+
+The runtime and generated code for MICRO_RUNTIME is smaller
+because it does not include support for the descriptor and
+reflection, and enums are generated as integer constants in
+the parent message or the file's outer class, with no
+protection against invalid values set to enum fields. Also,
+not currently supported are packed repeated elements or
+extensions.
+
+To create a jar file for the runtime and run tests invoke
+"mvn package -P micro" from the <protobuf-root>/java
+directory. The generated jar file is
+<protobuf-root>java/target/protobuf-java-2.6.0-micro.jar.
+
+If you wish to compile the MICRO_RUNTIME your self, place
+the 7 files below, in <root>/com/google/protobuf and
+create a jar file for use with your code and the generated
+code:
+
+ByteStringMicro.java
+CodedInputStreamMicro.java
+CodedOutputStreamMicro.java
+InvalidProtocolBufferException.java
+MessageMicro.java
+WireFormatMicro.java
+
+If you wish to change on the code generator it is located
+in /src/google/protobuf/compiler/javamicro.
+
+To generate code for the MICRO_RUNTIME invoke protoc with
+--javamicro_out command line parameter. javamicro_out takes
+a series of optional sub-parameters separated by commas
+and a final parameter, with a colon separator, which defines
+the source directory. Sub-parameters begin with a name
+followed by an equal and if that sub-parameter has multiple
+parameters they are seperated by "|". The command line options
+are:
+
+opt                  -> speed or space
+java_use_vector      -> true or false
+java_package         -> <file-name>|<package-name>
+java_outer_classname -> <file-name>|<package-name>
+java_multiple_files  -> true or false
+
+opt={speed,space} (default: space)
+  This changes the code generation to optimize for speed or
+  space. When opt=speed this changes the code generation
+  for strings so that multiple conversions to Utf8 are
+  eliminated.
+
+java_use_vector={true,false} (default: false)
+  This specifies the collection class for repeated elements.
+  If false, repeated elements use java.util.ArrayList<> and
+  the code must be compiled with Java 1.5 or above. If true,
+  repeated elements use java.util.Vector and the code can
+  be compiled with Java 1.3 or above. The 'source'
+  parameter of 'javac' may be used to control the version
+  of the source: "javac -source 1.3". You can also change
+  the <source> xml element for the maven-compiler-plugin.
+  Below is for 1.5 sources:
+
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+
+  And below would be for 1.3 sources (note when changing
+  to 1.3 you must also set java_use_vector=true):
+
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.3</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+
+java_package=<file-name>|<package-name> (no default)
+  This allows overriding the 'java_package' option value
+  for the given file from the command line. Use multiple
+  java_package options to override the option for multiple
+  files. The final Java package for each file is the value
+  of this command line option if present, or the value of
+  the same option defined in the file if present, or the
+  proto package if present, or the default Java package.
+
+java_outer_classname=<file-name>|<outer-classname> (no default)
+  This allows overriding the 'java_outer_classname' option
+  for the given file from the command line. Use multiple
+  java_outer_classname options to override the option for
+  multiple files. The final Java outer class name for each
+  file is the value of this command line option if present,
+  or the value of the same option defined in the file if
+  present, or the file name converted to CamelCase. This
+  outer class will nest all classes and integer constants
+  generated from file-scope messages and enums.
+
+java_multiple_files={true,false} (no default)
+  This allows overriding the 'java_multiple_files' option
+  in all source files and their imported files from the
+  command line. The final value of this option for each
+  file is the value defined in this command line option, or
+  the value of the same option defined in the file if
+  present, or false. This specifies whether to generate
+  package-level classes for the file-scope messages in the
+  same Java package as the outer class (instead of nested
+  classes in the outer class). File-scope enum constants
+  are still generated as integer constants in the outer
+  class. This affects the fully qualified references in the
+  Java code. NOTE: because the command line option
+  overrides the value for all files and their imported
+  files, using this option inconsistently may result in
+  incorrect references to the imported messages and enum
+  constants.
+
+
+IMPORTANT: change of javamicro_out behavior:
+
+In previous versions, if the outer class name has not been
+given explicitly, javamicro_out would not infer the outer
+class name from the file name, and would skip the outer
+class generation. This makes the compilation succeed only
+if the source file contains a single message and no enums,
+and the generated class for that message is placed at the
+package level. To re-align with java_out, javamicro_out
+will now always generate the outer class, inferring its
+name from the file name if not given, as a container of the
+message classes and enum constants. To keep any existing
+single-message source file from causing the generation of
+an unwanted outer class, you can set the option
+java_multiple_files to true, either in the file or as a
+command line option.
+
+
+Below are a series of examples for clarification of the
+various parameters and options. Assuming this file:
+
+src/proto/simple-data-protos.proto:
+
+    package testprotobuf;
+
+    message SimpleData {
+      optional fixed64 id = 1;
+      optional string description = 2;
+      optional bool ok = 3 [default = false];
+    };
+
+and the compiled protoc in the current working directory,
+then a simple command line to compile this file would be:
+
+./protoc --javamicro_out=. src/proto/simple-data-protos.proto
+
+This will create testprotobuf/SimpleDataProtos.java, which
+has the following content (extremely simplified):
+
+    package testprotobuf;
+
+    public final class SimpleDataProtos {
+      public static final class SimpleData
+          extends MessageMicro {
+        ...
+      }
+    }
+
+The message SimpleData is compiled into the SimpleData
+class, nested in the file's outer class SimpleDataProtos,
+whose name is implicitly defined by the proto file name
+"simple-data-protos".
+
+The directory, aka Java package, testprotobuf is created
+because on line 1 of simple-data-protos.proto is
+"package testprotobuf;". If you wanted a different
+package name you could use the java_package option in the
+file:
+
+    option java_package = "my_package";
+
+or in command line sub-parameter:
+
+./protoc '--javamicro_out=\
+java_package=src/proto/simple-data-protos.proto|my_package:\
+.' src/proto/simple-data-protos.proto
+
+Here you see the new java_package sub-parameter which
+itself needs two parameters the file name and the
+package name, these are separated by "|". The value set
+in the command line overrides the value set in the file.
+Now you'll find SimpleDataProtos.java in the my_package/
+directory.
+
+If you wanted to also change the optimization for
+speed you'd add opt=speed with the comma seperator
+as follows:
+
+./protoc '--javamicro_out=\
+opt=speed,\
+java_package=src/proto/simple-data-protos.proto|my_package:
+.' src/proto/simple-data-protos.proto
+
+If you also wanted a different outer class name you'd
+do the following:
+
+./protoc '--javamicro_out=\
+opt=speed,\
+java_package=src/proto/simple-data-protos.proto|my_package,\
+java_outer_classname=src/proto/simple-data-protos.proto|OuterName:\
+.' src/proto/simple-data-protos.proto
+
+Now you'll find my_package/OuterName.java and the
+message class SimpleData nested in it.
+
+As mentioned java_package, java_outer_classname and
+java_multiple_files may also be specified in the file.
+In the example below we must define
+java_outer_classname because otherwise the outer class
+and one of the message classes will have the same name,
+which is forbidden to prevent name ambiguity:
+
+src/proto/sample-message.proto:
+
+    package testmicroruntime;
+
+    option java_package = "com.example";
+    option java_outer_classname = "SampleMessageProtos";
+
+    enum MessageType {
+      SAMPLE = 1;
+      EXAMPLE = 2;
+    }
+
+    message SampleMessage {
+      required int32 id = 1;
+      required MessageType type = 2;
+    }
+
+    message SampleMessageContainer {
+      required SampleMessage message = 1;
+    }
+
+This could be compiled using:
+
+./protoc --javamicro_out=. src/proto/sample-message.proto
+
+and the output will be:
+
+com/example/SampleMessageProtos.java:
+
+    package com.example;
+
+    public final class SampleMessageProtos {
+      public static final int SAMPLE = 1;
+      public static final int EXAMPLE = 2;
+      public static final class SampleMessage
+          extends MessageMicro {
+        ...
+      }
+      public static final class SampleMessageContainer
+          extends MessageMicro {
+        ...
+      }
+    }
+
+As you can see the file-scope enum MessageType is
+disassembled into two integer constants in the outer class.
+In javamicro_out, all enums are disassembled and compiled
+into integer constants in the parent scope (the containing
+message's class or the file's (i.e. outer) class).
+
+You may prefer the file-scope messages to be saved in
+separate files. You can do this by setting the option
+java_multiple_files to true, in either the file like this:
+
+    option java_multiple_files = true;
+
+or the command line like this:
+
+./protoc --javamicro_out=\
+java_multiple_files=true:\
+. src/proto/sample-message.proto
+
+The java_multiple_files option causes javamicro to use a
+separate file for each file-scope message, which resides
+directly in the Java package alongside the outer class:
+
+com/example/SampleMessageProtos.java:
+
+    package com.example;
+    public final class SampleMessageProtos {
+      public static final int SAMPLE = 1;
+      public static final int EXAMPLE = 2;
+    }
+
+com/example/SampleMessage.java:
+
+    package com.example;
+    public final class SampleMessage
+        extends MessageMicro {
+      ...
+    }
+
+com/example/SampleMessageContainer.java:
+
+    package com.example;
+    public final class SampleMessageContainer
+        extends MessageMicro {
+      ...
+    }
+
+As you can see, the outer class now contains only the
+integer constants, generated from the file-scope enum
+"MessageType". Please note that message-scope enums are
+still generated as integer constants in the message class.
+
+
+Nano version
+============================
+
+Nano is a special code generator and runtime library designed specially
+for Android, and is very resource-friendly in both the amount of code
+and the runtime overhead. An overview of Nano features:
+
+- No descriptors or message builders.
+- All messages are mutable; fields are public Java fields.
+- For optional fields only, encapsulation behind setter/getter/hazzer/
+  clearer functions is opt-in, which provide proper 'has' state support.
+- If not opted in, has state is not available. Serialization outputs
+  all fields not equal to their defaults (see important implications
+  below).
+- Required fields are always serialized.
+- Enum constants are integers; protection against invalid values only
+  when parsing from the wire.
+- Enum constants can be generated into container interfaces bearing
+  the enum's name (so the referencing code is in Java style).
+- CodedInputByteBufferNano can only take byte[] (not InputStream).
+- Similarly CodedOutputByteBufferNano can only write to byte[].
+- Repeated fields are in arrays, not ArrayList or Vector. Null array
+  elements are allowed and silently ignored.
+- Full support of serializing/deserializing repeated packed fields.
+- Support of extensions.
+- Unset messages/groups are null, not an immutable empty default
+  instance.
+- toByteArray(...) and mergeFrom(...) are now static functions of
+  MessageNano.
+- The 'bytes' type translates to the Java type byte[].
+
+The generated messages are not thread-safe for writes, but may be
+used simultaneously from multiple threads in a read-only manner.
+In other words, an appropriate synchronization mechanism (such as
+a ReadWriteLock) must be used to ensure that a message, its
+ancestors, and descendants are not accessed by any other threads
+while the message is being modified. Field reads, getter methods
+(but not getExtension(...)), toByteArray(...), writeTo(...),
+getCachedSize(), and getSerializedSize() are all considered read-only
+operations.
+
+IMPORTANT: If you have fields with defaults and opt out of accessors
+
+How fields with defaults are serialized has changed. Because we don't
+keep "has" state, any field equal to its default is assumed to be not
+set and therefore is not serialized. Consider the situation where we
+change the default value of a field. Senders compiled against an older
+version of the proto continue to match against the old default, and
+don't send values to the receiver even though the receiver assumes the
+new default value. Therefore, think carefully about the implications
+of changing the default value. Alternatively, turn on accessors and
+enjoy the benefit of the explicit has() checks.
+
+IMPORTANT: If you have "bytes" fields with non-empty defaults
+
+Because the byte buffer is now of mutable type byte[], the default
+static final cannot be exposed through a public field. Each time a
+message's constructor or clear() function is called, the default value
+(kept in a private byte[]) is cloned. This causes a small memory
+penalty. This is not a problem if the field has no default or is an
+empty default.
+
+Nano Generator options
+
+java_package           -> <file-name>|<package-name>
+java_outer_classname   -> <file-name>|<package-name>
+java_multiple_files    -> true or false
+java_nano_generate_has -> true or false [DEPRECATED]
+optional_field_style   -> default or accessors
+enum_style             -> c or java
+ignore_services        -> true or false
+parcelable_messages    -> true or false
+
+java_package:
+java_outer_classname:
+java_multiple_files:
+  Same as Micro version.
+
+java_nano_generate_has={true,false} (default: false)
+  DEPRECATED. Use optional_field_style=accessors.
+
+  If true, generates a public boolean variable has<fieldname>
+  accompanying each optional or required field (not present for
+  repeated fields, groups or messages). It is set to false initially
+  and upon clear(). If parseFrom(...) reads the field from the wire,
+  it is set to true. This is a way for clients to inspect the "has"
+  value upon parse. If it is set to true, writeTo(...) will ALWAYS
+  output that field (even if field value is equal to its
+  default).
+
+  IMPORTANT: This option costs an extra 4 bytes per primitive field in
+  the message. Think carefully about whether you really need this. In
+  many cases reading the default works and determining whether the
+  field was received over the wire is irrelevant.
+
+optional_field_style={default,accessors,reftypes} (default: default)
+  Defines the style of the generated code for fields.
+
+  * default *
+
+  In the default style, optional fields translate into public mutable
+  Java fields, and the serialization process is as discussed in the
+  "IMPORTANT" section above. 
+
+  * accessors *
+
+  When set to 'accessors', each optional field is encapsulated behind
+  4 accessors, namely get<fieldname>(), set<fieldname>(), has<fieldname>()
+  and clear<fieldname>() methods, with the standard semantics. The hazzer's
+  return value determines whether a field is serialized, so this style is
+  useful when you need to serialize a field with the default value, or check
+  if a field has been explicitly set to its default value from the wire.
+
+  In the 'accessors' style, required and nested message fields are still
+  translated to one public mutable Java field each, repeated fields are still
+  translated to arrays. No accessors are generated for them.
+
+  IMPORTANT: When using the 'accessors' style, ProGuard should always
+  be enabled with optimization (don't use -dontoptimize) and allowing
+  access modification (use -allowaccessmodification). This removes the
+  unused accessors and maybe inline the rest at the call sites,
+  reducing the final code size.
+  TODO(maxtroy): find ProGuard config that would work the best.
+
+  * reftypes *
+
+  When set to 'reftypes', each proto field is generated as a public Java
+  field. For primitive types, these fields use the Java reference types
+  such as java.lang.Integer instead of primitive types such as int.
+
+  In the 'reftypes' style, fields are initialized to null (or empty
+  arrays for repeated fields), and their default values are not available.
+  They are serialized over the wire based on equality to null.
+
+  The 'reftypes' mode has some additional cost due to autoboxing and usage
+  of reference types. In practice, many boxed types are cached, and so don't
+  result in object creation. However, references do take slightly more memory
+  than primitives.
+
+  The 'reftypes' mode is useful when you want to be able to serialize fields
+  with default values, or check if a field has been explicitly set to the
+  default over the wire without paying the extra method cost of the
+  'accessors' mode.
+
+  Note that if you attempt to write null to a required field in the reftypes
+  mode, serialization of the proto will cause a NullPointerException. This is
+  an intentional indicator that you must set required fields.
+
+  NOTE
+  optional_field_style=accessors or reftypes cannot be used together with
+  java_nano_generate_has=true. If you need the 'has' flag for any
+  required field (you have no reason to), you can only use
+  java_nano_generate_has=true.
+
+enum_style={c,java} (default: c)
+  Defines where to put the int constants generated from enum members.
+
+  * c *
+
+  Use C-style, so the enum constants are available at the scope where
+  the enum is defined. A file-scope enum's members are referenced like
+  'FileOuterClass.ENUM_VALUE'; a message-scope enum's members are
+  referenced as 'Message.ENUM_VALUE'. The enum name is unavailable.
+  This complies with the Micro code generator's behavior.
+
+  * java *
+
+  Use Java-style, so the enum constants are available under the enum
+  name and referenced like 'EnumName.ENUM_VALUE' (they are still int
+  constants). The enum name becomes the name of a public interface, at
+  the scope where the enum is defined. If the enum is file-scope and
+  the java_multiple_files option is on, the interface will be defined
+  in its own file. To reduce code size, this interface should not be
+  implemented and ProGuard shrinking should be used, so after the Java
+  compiler inlines all referenced enum constants into the call sites,
+  the interface remains unused and can be removed by ProGuard.
+
+ignore_services={true,false} (default: false)
+  Skips services definitions.
+
+  Nano doesn't support services. By default, if a service is defined
+  it will generate a compilation error. If this flag is set to true,
+  services will be silently ignored, instead.
+
+parcelable_messages={true,false} (default: false)
+  Android-specific option to generate Parcelable messages.
+
+generate_intdefs={true,false} (default: false)
+  Android-specific option to generate @IntDef annotations for enums.
+
+  If turned on, an @IntDef annotation (a public @interface) will be
+  generated for each enum, and every integer parameter and return
+  value in the generated code meant for this enum will be annotated
+  with it. This interface is generated with the same name and at the
+  same place as the enum members' container interfaces described
+  above under enum_style=java, regardless of the enum_style option
+  used. When this is combined with enum_style=java, the interface
+  will be both the @IntDef annotation and the container of the enum
+  members; otherwise the interface has an empty body.
+
+  Your app must declare a compile-time dependency on the
+  android-support-annotations library.
+
+  For more information on how these @IntDef annotations help with
+  compile-time type safety, see:
+  https://sites.google.com/a/android.com/tools/tech-docs/support-annotations
+  and
+  https://developer.android.com/reference/android/support/annotation/IntDef.html
+
+
+To use nano protobufs within the Android repo:
+
+- Set 'LOCAL_PROTOC_OPTIMIZE_TYPE := nano' in your local .mk file.
+  When building a Java library or an app (package) target, the build
+  system will add the Java nano runtime library to the
+  LOCAL_STATIC_JAVA_LIBRARIES variable, so you don't need to.
+- Set 'LOCAL_PROTO_JAVA_OUTPUT_PARAMS := ...' in your local .mk file
+  for any command-line options you need. Use commas to join multiple
+  options. In the nano flavor only, whitespace surrounding the option
+  names and values are ignored, so you can use backslash-newline or
+  '+=' to structure your make files nicely.
+- The options will be applied to *all* proto files in LOCAL_SRC_FILES
+  when you build a Java library or package. In case different options
+  are needed for different proto files, build separate Java libraries
+  and reference them in your main target. Note: you should make sure
+  that, for each separate target, all proto files imported from any
+  proto file in LOCAL_SRC_FILES are included in LOCAL_SRC_FILES. This
+  is because the generator has to assume that the imported files are
+  built using the same options, and will generate code that reference
+  the fields and enums from the imported files using the same code
+  style.
+- Hint: 'include $(CLEAR_VARS)' resets all LOCAL_ variables, including
+  the two above.
+
+To use nano protobufs outside of Android repo:
+
+- Link with the generated jar file
+  <protobuf-root>java/target/protobuf-java-2.6.0-nano.jar.
+- Invoke with --javanano_out, e.g.:
+
+./protoc '--javanano_out=\
+    java_package=src/proto/simple-data.proto|my_package,\
+    java_outer_classname=src/proto/simple-data.proto|OuterName\
+  :.' src/proto/simple-data.proto
+
+Contributing to nano:
+
+Please add/edit tests in NanoTest.java.
+
+Please run the following steps to test:
+
+- cd external/protobuf
+- ./configure
+- Run "make -j12 check" and verify all tests pass.
+- cd java
+- Run "mvn test" and verify all tests pass.
+- cd ../../..
+- . build/envsetup.sh
+- lunch 1
+- "make -j12 aprotoc libprotobuf-java-nano aprotoc-test-nano-params NanoAndroidTest" and
+  check for build errors.
+- Plug in an Android device or start an emulator.
+- adb install -r out/target/product/generic/data/app/NanoAndroidTest/NanoAndroidTest.apk
+- Run:
+  "adb shell am instrument -w com.google.protobuf.nano.test/android.test.InstrumentationTestRunner"
+  and verify all tests pass.
+- repo sync -c -j256
+- "make -j12" and check for build errors
+
+
+Usage
+=====
+
+The complete documentation for Protocol Buffers is available via the
+web at:
+
+  https://developers.google.com/protocol-buffers/
diff --git a/protobuf/java/pom.xml b/protobuf/java/pom.xml
new file mode 100644
index 0000000..59083c2
--- /dev/null
+++ b/protobuf/java/pom.xml
@@ -0,0 +1,413 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.google</groupId>
+    <artifactId>google</artifactId>
+    <version>1</version>
+  </parent>
+  <groupId>com.google.protobuf</groupId>
+  <artifactId>protobuf-java</artifactId>
+  <version>2.6.1</version>
+  <packaging>bundle</packaging>
+  <name>Protocol Buffer Java API</name>
+  <description>
+    Protocol Buffers are a way of encoding structured data in an efficient yet
+    extensible format.
+  </description>
+  <inceptionYear>2008</inceptionYear>
+  <url>https://developers.google.com/protocol-buffers/</url>
+  <licenses>
+    <license>
+      <name>New BSD license</name>
+      <url>http://www.opensource.org/licenses/bsd-license.php</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <scm>
+    <url>https://github.com/google/protobuf</url>
+    <connection>
+      scm:git:https://github.com/google/protobuf.git
+    </connection>
+  </scm>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.4</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <version>2.2</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <version>2.2.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <includes>
+            <include>**/*Test.java</include>
+          </includes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>generate-sources</id>
+            <phase>generate-sources</phase>
+            <configuration>
+              <tasks>
+                <mkdir dir="target/generated-sources" />
+                <exec executable="../src/protoc">
+                  <arg value="--java_out=target/generated-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="../src/google/protobuf/descriptor.proto" />
+                </exec>
+              </tasks>
+              <sourceRoot>target/generated-sources</sourceRoot>
+            </configuration>
+            <goals>
+              <goal>run</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>generate-test-sources</id>
+            <phase>generate-test-sources</phase>
+            <configuration>
+              <tasks>
+                <mkdir dir="target/generated-test-sources" />
+                <exec executable="../src/protoc">
+                  <arg value="--java_out=target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest.proto" />
+                  <arg value="../src/google/protobuf/unittest_import.proto" />
+                  <arg value="../src/google/protobuf/unittest_import_public.proto" />
+                  <arg value="../src/google/protobuf/unittest_mset.proto" />
+                  <arg value="src/test/java/com/google/protobuf/lazy_fields_lite.proto" />
+                  <arg value="src/test/java/com/google/protobuf/lite_equals_and_hash.proto" />
+                  <arg
+                    value="src/test/java/com/google/protobuf/multiple_files_test.proto" />
+                  <arg value="src/test/java/com/google/protobuf/nested_builders_test.proto" />
+                  <arg value="src/test/java/com/google/protobuf/nested_extension.proto" />
+                  <arg value="src/test/java/com/google/protobuf/nested_extension_lite.proto" />
+                  <arg value="src/test/java/com/google/protobuf/non_nested_extension.proto" />
+                  <arg value="src/test/java/com/google/protobuf/non_nested_extension_lite.proto" />
+                  <arg value="src/test/java/com/google/protobuf/outer_class_name_test.proto" />
+                  <arg value="src/test/java/com/google/protobuf/outer_class_name_test2.proto" />
+                  <arg value="src/test/java/com/google/protobuf/outer_class_name_test3.proto" />
+                  <arg value="src/test/java/com/google/protobuf/test_bad_identifiers.proto" />
+                  <arg value="src/test/java/com/google/protobuf/test_check_utf8.proto" />
+                  <arg value="src/test/java/com/google/protobuf/test_check_utf8_size.proto" />
+                  <arg value="src/test/java/com/google/protobuf/test_custom_options.proto" />
+                  <arg
+                    value="../src/google/protobuf/unittest_optimize_for.proto" />
+                  <arg
+                    value="../src/google/protobuf/unittest_custom_options.proto" />
+                  <arg value="../src/google/protobuf/unittest_lite.proto" />
+                  <arg value="../src/google/protobuf/unittest_import_lite.proto" />
+                  <arg value="../src/google/protobuf/unittest_import_public_lite.proto" />
+                  <arg value="../src/google/protobuf/unittest_lite_imports_nonlite.proto" />
+                  <arg value="../src/google/protobuf/unittest_enormous_descriptor.proto" />
+                  <arg value="../src/google/protobuf/unittest_no_generic_services.proto" />
+                </exec>
+		<!-- java micro -->
+                <exec executable="../src/protoc">
+                  <arg value="--javamicro_out=opt=speed,java_use_vector=false,java_package=google/protobuf/unittest_import_micro.proto|com.google.protobuf.micro,java_outer_classname=google/protobuf/unittest_import_micro.proto|UnittestImportMicro:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_micro.proto" />
+                  <arg value="../src/google/protobuf/unittest_simple_micro.proto" />
+                  <arg value="../src/google/protobuf/unittest_stringutf8_micro.proto" />
+                  <arg value="../src/google/protobuf/unittest_recursive_micro.proto" />
+                  <arg value="../src/google/protobuf/unittest_import_micro.proto" />
+                  <arg value="../src/google/protobuf/unittest_single_micro.proto" />
+                  <arg value="../src/google/protobuf/unittest_multiple_micro.proto" />
+                  <arg value="../src/google/protobuf/unittest_multiple_nameclash_micro.proto" />
+                </exec>
+		<!-- java nano -->
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=
+                                  java_package = google/protobuf/unittest_import_nano.proto|com.google.protobuf.nano.testimport,
+                                  java_outer_classname = google/protobuf/unittest_import_nano.proto|UnittestImportNano,
+                                  generate_equals = true
+                                :target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_simple_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_stringutf8_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_recursive_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_import_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_single_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_multiple_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_multiple_nameclash_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_enum_class_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_repeated_merge_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=store_unknown_fields=true,generate_equals=true,generate_clone=true:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_extension_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=store_unknown_fields=true,generate_equals=true,generate_clone=true:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_extension_singular_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=store_unknown_fields=true,generate_equals=true,generate_clone=true:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_extension_repeated_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=store_unknown_fields=true:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_extension_packed_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=store_unknown_fields=true:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_unknown_enum_values_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=java_nano_generate_has=true,generate_equals=true:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_has_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=optional_field_style=accessors,generate_equals=true:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_accessors_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=enum_style=java:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_enum_class_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_enum_class_multiple_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_repeated_packables_nano.proto" />
+                  <arg value="../src/google/protobuf/unittest_enum_validity_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=
+                                  optional_field_style=accessors,
+                                  java_outer_classname=google/protobuf/unittest_enum_validity_nano.proto|EnumValidityAccessors
+                                :target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_enum_validity_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=optional_field_style=reftypes,generate_equals=true:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_reference_types_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=optional_field_style=reftypes_compat_mode,generate_equals=true,java_outer_classname=google/protobuf/unittest_reference_types_nano.proto|NanoReferenceTypesCompat:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_reference_types_nano.proto" />
+                </exec>
+                <exec executable="../src/protoc">
+                  <arg value="--javanano_out=bytes_offset_length=true:target/generated-test-sources" />
+                  <arg value="--proto_path=../src" />
+                  <arg value="--proto_path=src/test/java" />
+                  <arg value="../src/google/protobuf/unittest_bytes_offset_length_nano.proto" />
+                </exec>
+              </tasks>
+              <testSourceRoot>target/generated-test-sources</testSourceRoot>
+            </configuration>
+            <goals>
+              <goal>run</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
+            <Bundle-SymbolicName>com.google.protobuf</Bundle-SymbolicName>
+            <Export-Package>com.google.protobuf;version=2.6.1</Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>lite</id>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-compiler-plugin</artifactId>
+            <configuration>
+              <includes>
+                <include>**/AbstractMessageLite.java</include>
+                <include>**/ByteString.java</include>
+                <include>**/CodedInputStream.java</include>
+                <include>**/CodedOutputStream.java</include>
+                <include>**/ExtensionRegistryLite.java</include>
+                <include>**/FieldSet.java</include>
+                <include>**/GeneratedMessageLite.java</include>
+                <include>**/Internal.java</include>
+                <include>**/InvalidProtocolBufferException.java</include>
+                <include>**/LazyStringArrayList.java</include>
+                <include>**/LazyStringList.java</include>
+                <include>**/MessageLite.java</include>
+                <include>**/MessageLiteOrBuilder.java</include>
+                <include>**/SmallSortedMap.java</include>
+                <include>**/UninitializedMessageException.java</include>
+                <include>**/UnmodifiableLazyStringList.java</include>
+                <include>**/WireFormat.java</include>
+                <include>**/Parser.java</include>
+                <include>**/AbstractParser.java</include>
+                <include>**/BoundedByteString.java</include>
+                <include>**/LiteralByteString.java</include>
+                <include>**/RopeByteString.java</include>
+                <include>**/Utf8.java</include>
+                <include>**/LazyField.java</include>
+                <include>**/LazyFieldLite.java</include>
+                <include>**/ProtocolStringList.java</include>
+              </includes>
+              <testIncludes>
+                <testInclude>**/LiteTest.java</testInclude>
+                <testInclude>**/*Lite.java</testInclude>
+              </testIncludes>
+            </configuration>
+          </plugin>
+          <plugin>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <includes>
+                <include>**/LiteTest.java</include>
+              </includes>
+            </configuration>
+          </plugin>
+          <plugin>
+            <artifactId>maven-jar-plugin</artifactId>
+            <configuration>
+              <classifier>lite</classifier>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>micro</id>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-compiler-plugin</artifactId>
+            <configuration>
+              <includes>
+                <include>**/MessageMicro.java</include>
+                <include>**/ByteStringMicro.java</include>
+                <include>**/CodedInputStreamMicro.java</include>
+                <include>**/CodedOutputStreamMicro.java</include>
+                <include>**/InvalidProtocolBufferMicroException.java</include>
+                <include>**/WireFormatMicro.java</include>
+              </includes>
+              <testIncludes>
+                <testInclude>**/MicroTest.java</testInclude>
+                <testInclude>**/MicroOuterClass.java</testInclude>
+                <testInclude>**/SimpleMessageMicro.java</testInclude>
+                <testInclude>**/StringUtf8.java</testInclude>
+                <testInclude>**/RecursiveMessageMicro.java</testInclude>
+                <testInclude>**/UnittestImportMicro.java</testInclude>
+              </testIncludes>
+            </configuration>
+          </plugin>
+          <plugin>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <includes>
+                <include>**/MicroTest.java</include>
+              </includes>
+            </configuration>
+          </plugin>
+          <plugin>
+            <artifactId>maven-jar-plugin</artifactId>
+            <configuration>
+              <classifier>micro</classifier>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>nano</id>
+      <build>
+        <plugins>
+          <plugin>
+            <artifactId>maven-compiler-plugin</artifactId>
+            <configuration>
+              <includes>
+                <include>**/MessageNano.java</include>
+                <include>**/CodedInputByteBufferNano.java</include>
+                <include>**/CodedOutputByteBufferNano.java</include>
+                <include>**/InternalNano.java</include>
+                <include>**/InvalidProtocolBufferNanoException.java</include>
+                <include>**/WireFormatNano.java</include>
+              </includes>
+              <testIncludes>
+                <testInclude>**/NanoTest.java</testInclude>
+                <testInclude>**/NanoOuterClass.java</testInclude>
+                <testInclude>**/SimpleMessageNano.java</testInclude>
+                <testInclude>**/StringUtf8.java</testInclude>
+                <testInclude>**/RecursiveMessageNano.java</testInclude>
+                <testInclude>**/UnittestImportNano.java</testInclude>
+              </testIncludes>
+            </configuration>
+          </plugin>
+          <plugin>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <includes>
+                <include>**/NanoTest.java</include>
+              </includes>
+            </configuration>
+          </plugin>
+          <plugin>
+            <artifactId>maven-jar-plugin</artifactId>
+            <configuration>
+              <classifier>nano</classifier>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>
diff --git a/protobuf/java/src/device/main/java/com/google/protobuf/nano/android/ParcelableExtendableMessageNano.java b/protobuf/java/src/device/main/java/com/google/protobuf/nano/android/ParcelableExtendableMessageNano.java
new file mode 100644
index 0000000..739ff18
--- /dev/null
+++ b/protobuf/java/src/device/main/java/com/google/protobuf/nano/android/ParcelableExtendableMessageNano.java
@@ -0,0 +1,54 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2014 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano.android;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.protobuf.nano.ExtendableMessageNano;
+
+/**
+ * Base class for Parcelable Protocol Buffer messages which also need to store unknown
+ * fields, such as extensions.
+ */
+public abstract class ParcelableExtendableMessageNano<M extends ExtendableMessageNano<M>>
+        extends ExtendableMessageNano<M> implements Parcelable {
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        ParcelableMessageNanoCreator.writeToParcel(getClass(), this, out);
+    }
+}
diff --git a/protobuf/java/src/device/main/java/com/google/protobuf/nano/android/ParcelableMessageNano.java b/protobuf/java/src/device/main/java/com/google/protobuf/nano/android/ParcelableMessageNano.java
new file mode 100644
index 0000000..83f973d
--- /dev/null
+++ b/protobuf/java/src/device/main/java/com/google/protobuf/nano/android/ParcelableMessageNano.java
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2014 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano.android;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.google.protobuf.nano.MessageNano;
+
+/**
+ * Base class for Parcelable Protocol Buffer messages.
+ */
+public abstract class ParcelableMessageNano extends MessageNano implements Parcelable {
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        ParcelableMessageNanoCreator.writeToParcel(getClass(), this, out);
+    }
+}
diff --git a/protobuf/java/src/device/main/java/com/google/protobuf/nano/android/ParcelableMessageNanoCreator.java b/protobuf/java/src/device/main/java/com/google/protobuf/nano/android/ParcelableMessageNanoCreator.java
new file mode 100644
index 0000000..5a4b70c
--- /dev/null
+++ b/protobuf/java/src/device/main/java/com/google/protobuf/nano/android/ParcelableMessageNanoCreator.java
@@ -0,0 +1,89 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano.android;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
+import com.google.protobuf.nano.MessageNano;
+
+import java.lang.reflect.Array;
+
+public final class ParcelableMessageNanoCreator<T extends MessageNano>
+        implements Parcelable.Creator<T> {
+    private static final String TAG = "PMNCreator";
+
+    private final Class<T> mClazz;
+
+    public ParcelableMessageNanoCreator(Class<T> clazz) {
+        mClazz = clazz;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public T createFromParcel(Parcel in) {
+        String className = in.readString();
+        byte[] data = in.createByteArray();
+
+        T proto = null;
+
+        try {
+            Class<?> clazz = Class.forName(className);
+            Object instance = clazz.newInstance();
+            proto = (T) instance;
+            MessageNano.mergeFrom(proto, data);
+        } catch (ClassNotFoundException e) {
+            Log.e(TAG, "Exception trying to create proto from parcel", e);
+        } catch (IllegalAccessException e) {
+            Log.e(TAG, "Exception trying to create proto from parcel", e);
+        } catch (InstantiationException e) {
+            Log.e(TAG, "Exception trying to create proto from parcel", e);
+        } catch (InvalidProtocolBufferNanoException e) {
+            Log.e(TAG, "Exception trying to create proto from parcel", e);
+        }
+
+        return proto;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public T[] newArray(int i) {
+        return (T[]) Array.newInstance(mClazz, i);
+    }
+
+    static <T extends MessageNano> void writeToParcel(Class<T> clazz, MessageNano message,
+            Parcel out) {
+        out.writeString(clazz.getName());
+        out.writeByteArray(MessageNano.toByteArray(message));
+    }
+}
diff --git a/protobuf/java/src/device/test/AndroidManifest.xml b/protobuf/java/src/device/test/AndroidManifest.xml
new file mode 100644
index 0000000..cc54e57
--- /dev/null
+++ b/protobuf/java/src/device/test/AndroidManifest.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Protocol Buffers - Google's data interchange format
+  Copyright 2014 Google Inc.  All rights reserved.
+  http://code.google.com/p/protobuf/
+
+  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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.protobuf.nano.test"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk
+        android:minSdkVersion="8"
+        android:targetSdkVersion="8" />
+
+    <instrumentation
+        android:name="android.test.InstrumentationTestRunner"
+        android:targetPackage="com.google.protobuf.nano.test" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+</manifest>
diff --git a/protobuf/java/src/device/test/java/com/google/protobuf/nano/NanoAndroidTest.java b/protobuf/java/src/device/test/java/com/google/protobuf/nano/NanoAndroidTest.java
new file mode 100644
index 0000000..4b53607
--- /dev/null
+++ b/protobuf/java/src/device/test/java/com/google/protobuf/nano/NanoAndroidTest.java
@@ -0,0 +1,87 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2014 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import android.os.Parcel;
+
+import com.google.protobuf.nano.UnittestSimpleNano.SimpleMessageNano;
+import com.google.protobuf.nano.UnittestSimpleNano.SimpleMessageNano.NestedMessage;
+import com.google.protobuf.nano.testext.Extensions.ContainerMessage;
+import com.google.protobuf.nano.testext.Extensions.ExtendableMessage;
+
+import junit.framework.TestCase;
+
+public class NanoAndroidTest extends TestCase {
+    public void testParceling() {
+        SimpleMessageNano message = new SimpleMessageNano();
+        message.d = 54321;
+        message.nestedMsg = new NestedMessage();
+        message.nestedMsg.bb = 12345;
+        message.defaultNestedEnum = SimpleMessageNano.FOO;
+
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            parcel.writeParcelable(message, 0);
+            parcel.setDataPosition(0);
+            message = parcel.readParcelable(getClass().getClassLoader());
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+
+        assertEquals(54321, message.d);
+        assertEquals(12345, message.nestedMsg.bb);
+        assertEquals(SimpleMessageNano.FOO, message.defaultNestedEnum);
+    }
+
+    public void testExtendableParceling() {
+        ExtendableMessage message = new ExtendableMessage();
+        message.field = 12345;
+        message.setExtension(ContainerMessage.anotherThing, true);
+
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            parcel.writeParcelable(message, 0);
+            parcel.setDataPosition(0);
+            message = parcel.readParcelable(getClass().getClassLoader());
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+
+        assertEquals(12345, message.field);
+        assertTrue((boolean) message.getExtension(ContainerMessage.anotherThing));
+    }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java b/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java
new file mode 100644
index 0000000..ae9d5e3
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -0,0 +1,466 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.OneofDescriptor;
+import com.google.protobuf.Internal.EnumLite;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A partial implementation of the {@link Message} interface which implements
+ * as many methods of that interface as possible in terms of other methods.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class AbstractMessage extends AbstractMessageLite
+                                      implements Message {
+  public boolean isInitialized() {
+    return MessageReflection.isInitialized(this);
+  }
+
+
+  public List<String> findInitializationErrors() {
+    return MessageReflection.findMissingFields(this);
+  }
+
+  public String getInitializationErrorString() {
+    return MessageReflection.delimitWithCommas(findInitializationErrors());
+  }
+
+  /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+  @Override
+  public boolean hasOneof(OneofDescriptor oneof) {
+    throw new UnsupportedOperationException("hasOneof() is not implemented.");
+  }
+
+  /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+  @Override
+  public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
+    throw new UnsupportedOperationException(
+        "getOneofFieldDescriptor() is not implemented.");
+  }
+
+  @Override
+  public final String toString() {
+    return TextFormat.printToString(this);
+  }
+
+  public void writeTo(final CodedOutputStream output) throws IOException {
+    MessageReflection.writeMessageTo(this, output, false);
+  }
+
+  private int memoizedSize = -1;
+
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) {
+      return size;
+    }
+
+    memoizedSize = MessageReflection.getSerializedSize(this);
+    return memoizedSize;
+  }
+
+  @Override
+  public boolean equals(final Object other) {
+    if (other == this) {
+      return true;
+    }
+    if (!(other instanceof Message)) {
+      return false;
+    }
+    final Message otherMessage = (Message) other;
+    if (getDescriptorForType() != otherMessage.getDescriptorForType()) {
+      return false;
+    }
+    return compareFields(getAllFields(), otherMessage.getAllFields()) &&
+        getUnknownFields().equals(otherMessage.getUnknownFields());
+  }
+
+  @Override
+  public int hashCode() {
+    int hash = memoizedHashCode;
+    if (hash == 0) {
+      hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      hash = hashFields(hash, getAllFields());
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+    }
+    return hash;
+  }
+  
+  private static ByteString toByteString(Object value) {
+    if (value instanceof byte[]) {
+      return ByteString.copyFrom((byte[]) value);
+    } else {
+      return (ByteString) value;
+    }
+  }
+ 
+  /**
+   * Compares two bytes fields. The parameters must be either a byte array or a
+   * ByteString object. They can be of different type though.
+   */
+  private static boolean compareBytes(Object a, Object b) {
+    if (a instanceof byte[] && b instanceof byte[]) {
+      return Arrays.equals((byte[])a, (byte[])b);
+    }
+    return toByteString(a).equals(toByteString(b));
+  }
+  
+  /**
+   * Compares two set of fields.
+   * This method is used to implement {@link AbstractMessage#equals(Object)}
+   * and {@link AbstractMutableMessage#equals(Object)}. It takes special care
+   * of bytes fields because immutable messages and mutable messages use
+   * different Java type to reprensent a bytes field and this method should be
+   * able to compare immutable messages, mutable messages and also an immutable
+   * message to a mutable message.
+   */
+  static boolean compareFields(Map<FieldDescriptor, Object> a,
+      Map<FieldDescriptor, Object> b) {
+    if (a.size() != b.size()) {
+      return false;
+    }
+    for (FieldDescriptor descriptor : a.keySet()) {
+      if (!b.containsKey(descriptor)) {
+        return false;
+      }
+      Object value1 = a.get(descriptor);
+      Object value2 = b.get(descriptor);
+      if (descriptor.getType() == FieldDescriptor.Type.BYTES) {
+        if (descriptor.isRepeated()) {
+          List list1 = (List) value1;
+          List list2 = (List) value2;
+          if (list1.size() != list2.size()) {
+            return false;
+          }
+          for (int i = 0; i < list1.size(); i++) {
+            if (!compareBytes(list1.get(i), list2.get(i))) {
+              return false;
+            }
+          }
+        } else {
+          // Compares a singular bytes field.
+          if (!compareBytes(value1, value2)) {
+            return false;
+          }
+        }
+      } else {
+        // Compare non-bytes fields.
+        if (!value1.equals(value2)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /** Get a hash code for given fields and values, using the given seed. */
+  @SuppressWarnings("unchecked")
+  protected static int hashFields(int hash, Map<FieldDescriptor, Object> map) {
+    for (Map.Entry<FieldDescriptor, Object> entry : map.entrySet()) {
+      FieldDescriptor field = entry.getKey();
+      Object value = entry.getValue();
+      hash = (37 * hash) + field.getNumber();
+      if (field.getType() != FieldDescriptor.Type.ENUM){
+        hash = (53 * hash) + value.hashCode();
+      } else if (field.isRepeated()) {
+        List<? extends EnumLite> list = (List<? extends EnumLite>) value;
+        hash = (53 * hash) + Internal.hashEnumList(list);
+      } else {
+        hash = (53 * hash) + Internal.hashEnum((EnumLite) value);
+      }
+    }
+    return hash;
+  }
+
+  /**
+   * Package private helper method for AbstractParser to create
+   * UninitializedMessageException with missing field information.
+   */
+  @Override
+  UninitializedMessageException newUninitializedMessageException() {
+    return Builder.newUninitializedMessageException(this);
+  }
+
+  // =================================================================
+
+  /**
+   * A partial implementation of the {@link Message.Builder} interface which
+   * implements as many methods of that interface as possible in terms of
+   * other methods.
+   */
+  @SuppressWarnings("unchecked")
+  public static abstract class Builder<BuilderType extends Builder>
+      extends AbstractMessageLite.Builder<BuilderType>
+      implements Message.Builder {
+    // The compiler produces an error if this is not declared explicitly.
+    @Override
+    public abstract BuilderType clone();
+
+    /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+    @Override
+    public boolean hasOneof(OneofDescriptor oneof) {
+      throw new UnsupportedOperationException("hasOneof() is not implemented.");
+    }
+
+    /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+    @Override
+    public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
+      throw new UnsupportedOperationException(
+          "getOneofFieldDescriptor() is not implemented.");
+    }
+
+    /** TODO(jieluo): Clear it when all subclasses have implemented this method. */
+    @Override
+    public BuilderType clearOneof(OneofDescriptor oneof) {
+      throw new UnsupportedOperationException("clearOneof() is not implemented.");
+    }
+
+    public BuilderType clear() {
+      for (final Map.Entry<FieldDescriptor, Object> entry :
+           getAllFields().entrySet()) {
+        clearField(entry.getKey());
+      }
+      return (BuilderType) this;
+    }
+
+    public List<String> findInitializationErrors() {
+      return MessageReflection.findMissingFields(this);
+    }
+
+    public String getInitializationErrorString() {
+      return MessageReflection.delimitWithCommas(findInitializationErrors());
+    }
+
+    public BuilderType mergeFrom(final Message other) {
+      if (other.getDescriptorForType() != getDescriptorForType()) {
+        throw new IllegalArgumentException(
+          "mergeFrom(Message) can only merge messages of the same type.");
+      }
+
+      // Note:  We don't attempt to verify that other's fields have valid
+      //   types.  Doing so would be a losing battle.  We'd have to verify
+      //   all sub-messages as well, and we'd have to make copies of all of
+      //   them to insure that they don't change after verification (since
+      //   the Message interface itself cannot enforce immutability of
+      //   implementations).
+      // TODO(kenton):  Provide a function somewhere called makeDeepCopy()
+      //   which allows people to make secure deep copies of messages.
+
+      for (final Map.Entry<FieldDescriptor, Object> entry :
+           other.getAllFields().entrySet()) {
+        final FieldDescriptor field = entry.getKey();
+        if (field.isRepeated()) {
+          for (final Object element : (List)entry.getValue()) {
+            addRepeatedField(field, element);
+          }
+        } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+          final Message existingValue = (Message)getField(field);
+          if (existingValue == existingValue.getDefaultInstanceForType()) {
+            setField(field, entry.getValue());
+          } else {
+            setField(field,
+              existingValue.newBuilderForType()
+                .mergeFrom(existingValue)
+                .mergeFrom((Message)entry.getValue())
+                .build());
+          }
+        } else {
+          setField(field, entry.getValue());
+        }
+      }
+
+      mergeUnknownFields(other.getUnknownFields());
+
+      return (BuilderType) this;
+    }
+
+    @Override
+    public BuilderType mergeFrom(final CodedInputStream input)
+                                 throws IOException {
+      return mergeFrom(input, ExtensionRegistry.getEmptyRegistry());
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final CodedInputStream input,
+        final ExtensionRegistryLite extensionRegistry)
+        throws IOException {
+      final UnknownFieldSet.Builder unknownFields =
+        UnknownFieldSet.newBuilder(getUnknownFields());
+      while (true) {
+        final int tag = input.readTag();
+        if (tag == 0) {
+          break;
+        }
+
+        MessageReflection.BuilderAdapter builderAdapter =
+            new MessageReflection.BuilderAdapter(this);
+        if (!MessageReflection.mergeFieldFrom(input, unknownFields,
+                                              extensionRegistry,
+                                              getDescriptorForType(),
+                                              builderAdapter,
+                                              tag)) {
+          // end group tag
+          break;
+        }
+      }
+      setUnknownFields(unknownFields.build());
+      return (BuilderType) this;
+    }
+
+    public BuilderType mergeUnknownFields(final UnknownFieldSet unknownFields) {
+      setUnknownFields(
+        UnknownFieldSet.newBuilder(getUnknownFields())
+                       .mergeFrom(unknownFields)
+                       .build());
+      return (BuilderType) this;
+    }
+
+    public Message.Builder getFieldBuilder(final FieldDescriptor field) {
+      throw new UnsupportedOperationException(
+          "getFieldBuilder() called on an unsupported message type.");
+    }
+
+    public String toString() {
+      return TextFormat.printToString(this);
+    }
+
+    /**
+     * Construct an UninitializedMessageException reporting missing fields in
+     * the given message.
+     */
+    protected static UninitializedMessageException
+        newUninitializedMessageException(Message message) {
+      return new UninitializedMessageException(
+          MessageReflection.findMissingFields(message));
+    }
+
+    // ===============================================================
+    // The following definitions seem to be required in order to make javac
+    // not produce weird errors like:
+    //
+    // java/com/google/protobuf/DynamicMessage.java:203: types
+    //   com.google.protobuf.AbstractMessage.Builder<
+    //     com.google.protobuf.DynamicMessage.Builder> and
+    //   com.google.protobuf.AbstractMessage.Builder<
+    //     com.google.protobuf.DynamicMessage.Builder> are incompatible; both
+    //   define mergeFrom(com.google.protobuf.ByteString), but with unrelated
+    //   return types.
+    //
+    // Strangely, these lines are only needed if javac is invoked separately
+    // on AbstractMessage.java and AbstractMessageLite.java.  If javac is
+    // invoked on both simultaneously, it works.  (Or maybe the important
+    // point is whether or not DynamicMessage.java is compiled together with
+    // AbstractMessageLite.java -- not sure.)  I suspect this is a compiler
+    // bug.
+
+    @Override
+    public BuilderType mergeFrom(final ByteString data)
+        throws InvalidProtocolBufferException {
+      return super.mergeFrom(data);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final ByteString data,
+        final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      return super.mergeFrom(data, extensionRegistry);
+    }
+
+    @Override
+    public BuilderType mergeFrom(final byte[] data)
+        throws InvalidProtocolBufferException {
+      return super.mergeFrom(data);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final byte[] data, final int off, final int len)
+        throws InvalidProtocolBufferException {
+      return super.mergeFrom(data, off, len);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final byte[] data,
+        final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      return super.mergeFrom(data, extensionRegistry);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final byte[] data, final int off, final int len,
+        final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      return super.mergeFrom(data, off, len, extensionRegistry);
+    }
+
+    @Override
+    public BuilderType mergeFrom(final InputStream input)
+        throws IOException {
+      return super.mergeFrom(input);
+    }
+
+    @Override
+    public BuilderType mergeFrom(
+        final InputStream input,
+        final ExtensionRegistryLite extensionRegistry)
+        throws IOException {
+      return super.mergeFrom(input, extensionRegistry);
+    }
+
+    @Override
+    public boolean mergeDelimitedFrom(final InputStream input)
+        throws IOException {
+      return super.mergeDelimitedFrom(input);
+    }
+
+    @Override
+    public boolean mergeDelimitedFrom(
+        final InputStream input,
+        final ExtensionRegistryLite extensionRegistry)
+        throws IOException {
+      return super.mergeDelimitedFrom(input, extensionRegistry);
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/AbstractMessageLite.java b/protobuf/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
new file mode 100644
index 0000000..aac4fa7
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/AbstractMessageLite.java
@@ -0,0 +1,355 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collection;
+
+/**
+ * A partial implementation of the {@link MessageLite} interface which
+ * implements as many methods of that interface as possible in terms of other
+ * methods.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class AbstractMessageLite implements MessageLite {
+  protected int memoizedHashCode = 0;
+
+  public ByteString toByteString() {
+    try {
+      final ByteString.CodedBuilder out =
+        ByteString.newCodedBuilder(getSerializedSize());
+      writeTo(out.getCodedOutput());
+      return out.build();
+    } catch (IOException e) {
+      throw new RuntimeException(
+        "Serializing to a ByteString threw an IOException (should " +
+        "never happen).", e);
+    }
+  }
+
+  public byte[] toByteArray() {
+    try {
+      final byte[] result = new byte[getSerializedSize()];
+      final CodedOutputStream output = CodedOutputStream.newInstance(result);
+      writeTo(output);
+      output.checkNoSpaceLeft();
+      return result;
+    } catch (IOException e) {
+      throw new RuntimeException(
+        "Serializing to a byte array threw an IOException " +
+        "(should never happen).", e);
+    }
+  }
+
+  public void writeTo(final OutputStream output) throws IOException {
+    final int bufferSize =
+        CodedOutputStream.computePreferredBufferSize(getSerializedSize());
+    final CodedOutputStream codedOutput =
+        CodedOutputStream.newInstance(output, bufferSize);
+    writeTo(codedOutput);
+    codedOutput.flush();
+  }
+
+  public void writeDelimitedTo(final OutputStream output) throws IOException {
+    final int serialized = getSerializedSize();
+    final int bufferSize = CodedOutputStream.computePreferredBufferSize(
+        CodedOutputStream.computeRawVarint32Size(serialized) + serialized);
+    final CodedOutputStream codedOutput =
+        CodedOutputStream.newInstance(output, bufferSize);
+    codedOutput.writeRawVarint32(serialized);
+    writeTo(codedOutput);
+    codedOutput.flush();
+  }
+
+
+  /**
+   * Package private helper method for AbstractParser to create
+   * UninitializedMessageException.
+   */
+  UninitializedMessageException newUninitializedMessageException() {
+    return new UninitializedMessageException(this);
+  }
+
+  protected static void checkByteStringIsUtf8(ByteString byteString)
+      throws IllegalArgumentException {
+    if (!byteString.isValidUtf8()) {
+      throw new IllegalArgumentException("Byte string is not UTF-8.");
+    }
+  }
+
+  /**
+   * A partial implementation of the {@link Message.Builder} interface which
+   * implements as many methods of that interface as possible in terms of
+   * other methods.
+   */
+  @SuppressWarnings("unchecked")
+  public static abstract class Builder<BuilderType extends Builder>
+      implements MessageLite.Builder {
+    // The compiler produces an error if this is not declared explicitly.
+    @Override
+    public abstract BuilderType clone();
+
+    public BuilderType mergeFrom(final CodedInputStream input)
+                                 throws IOException {
+      return mergeFrom(input, ExtensionRegistryLite.getEmptyRegistry());
+    }
+
+    // Re-defined here for return type covariance.
+    public abstract BuilderType mergeFrom(
+        final CodedInputStream input,
+        final ExtensionRegistryLite extensionRegistry)
+        throws IOException;
+
+    public BuilderType mergeFrom(final ByteString data)
+        throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input = data.newCodedInput();
+        mergeFrom(input);
+        input.checkLastTagWas(0);
+        return (BuilderType) this;
+      } catch (InvalidProtocolBufferException e) {
+        throw e;
+      } catch (IOException e) {
+        throw new RuntimeException(
+          "Reading from a ByteString threw an IOException (should " +
+          "never happen).", e);
+      }
+    }
+
+    public BuilderType mergeFrom(
+        final ByteString data,
+        final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input = data.newCodedInput();
+        mergeFrom(input, extensionRegistry);
+        input.checkLastTagWas(0);
+        return (BuilderType) this;
+      } catch (InvalidProtocolBufferException e) {
+        throw e;
+      } catch (IOException e) {
+        throw new RuntimeException(
+          "Reading from a ByteString threw an IOException (should " +
+          "never happen).", e);
+      }
+    }
+
+    public BuilderType mergeFrom(final byte[] data)
+        throws InvalidProtocolBufferException {
+      return mergeFrom(data, 0, data.length);
+    }
+
+    public BuilderType mergeFrom(final byte[] data, final int off,
+                                 final int len)
+                                 throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input =
+            CodedInputStream.newInstance(data, off, len);
+        mergeFrom(input);
+        input.checkLastTagWas(0);
+        return (BuilderType) this;
+      } catch (InvalidProtocolBufferException e) {
+        throw e;
+      } catch (IOException e) {
+        throw new RuntimeException(
+          "Reading from a byte array threw an IOException (should " +
+          "never happen).", e);
+      }
+    }
+
+    public BuilderType mergeFrom(
+        final byte[] data,
+        final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      return mergeFrom(data, 0, data.length, extensionRegistry);
+    }
+
+    public BuilderType mergeFrom(
+        final byte[] data, final int off, final int len,
+        final ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input =
+            CodedInputStream.newInstance(data, off, len);
+        mergeFrom(input, extensionRegistry);
+        input.checkLastTagWas(0);
+        return (BuilderType) this;
+      } catch (InvalidProtocolBufferException e) {
+        throw e;
+      } catch (IOException e) {
+        throw new RuntimeException(
+          "Reading from a byte array threw an IOException (should " +
+          "never happen).", e);
+      }
+    }
+
+    public BuilderType mergeFrom(final InputStream input) throws IOException {
+      final CodedInputStream codedInput = CodedInputStream.newInstance(input);
+      mergeFrom(codedInput);
+      codedInput.checkLastTagWas(0);
+      return (BuilderType) this;
+    }
+
+    public BuilderType mergeFrom(
+        final InputStream input,
+        final ExtensionRegistryLite extensionRegistry)
+        throws IOException {
+      final CodedInputStream codedInput = CodedInputStream.newInstance(input);
+      mergeFrom(codedInput, extensionRegistry);
+      codedInput.checkLastTagWas(0);
+      return (BuilderType) this;
+    }
+
+    /**
+     * An InputStream implementations which reads from some other InputStream
+     * but is limited to a particular number of bytes.  Used by
+     * mergeDelimitedFrom().  This is intentionally package-private so that
+     * UnknownFieldSet can share it.
+     */
+    static final class LimitedInputStream extends FilterInputStream {
+      private int limit;
+
+      LimitedInputStream(InputStream in, int limit) {
+        super(in);
+        this.limit = limit;
+      }
+
+      @Override
+      public int available() throws IOException {
+        return Math.min(super.available(), limit);
+      }
+
+      @Override
+      public int read() throws IOException {
+        if (limit <= 0) {
+          return -1;
+        }
+        final int result = super.read();
+        if (result >= 0) {
+          --limit;
+        }
+        return result;
+      }
+
+      @Override
+      public int read(final byte[] b, final int off, int len)
+                      throws IOException {
+        if (limit <= 0) {
+          return -1;
+        }
+        len = Math.min(len, limit);
+        final int result = super.read(b, off, len);
+        if (result >= 0) {
+          limit -= result;
+        }
+        return result;
+      }
+
+      @Override
+      public long skip(final long n) throws IOException {
+        final long result = super.skip(Math.min(n, limit));
+        if (result >= 0) {
+          limit -= result;
+        }
+        return result;
+      }
+    }
+
+    public boolean mergeDelimitedFrom(
+        final InputStream input,
+        final ExtensionRegistryLite extensionRegistry)
+        throws IOException {
+      final int firstByte = input.read();
+      if (firstByte == -1) {
+        return false;
+      }
+      final int size = CodedInputStream.readRawVarint32(firstByte, input);
+      final InputStream limitedInput = new LimitedInputStream(input, size);
+      mergeFrom(limitedInput, extensionRegistry);
+      return true;
+    }
+
+    public boolean mergeDelimitedFrom(final InputStream input)
+        throws IOException {
+      return mergeDelimitedFrom(input,
+          ExtensionRegistryLite.getEmptyRegistry());
+    }
+
+    /**
+     * Construct an UninitializedMessageException reporting missing fields in
+     * the given message.
+     */
+    protected static UninitializedMessageException
+        newUninitializedMessageException(MessageLite message) {
+      return new UninitializedMessageException(message);
+    }
+
+    /**
+     * Adds the {@code values} to the {@code list}.  This is a helper method
+     * used by generated code.  Users should ignore it.
+     *
+     * @throws NullPointerException if any of the elements of {@code values} is
+     * null. When that happens, some elements of {@code values} may have already
+     * been added to the result {@code list}.
+     */
+    protected static <T> void addAll(final Iterable<T> values,
+                                     final Collection<? super T> list) {
+      if (values instanceof LazyStringList) {
+        // For StringOrByteStringLists, check the underlying elements to avoid
+        // forcing conversions of ByteStrings to Strings.
+        checkForNullValues(((LazyStringList) values).getUnderlyingElements());
+        list.addAll((Collection<T>) values);
+      } else if (values instanceof Collection) {
+        checkForNullValues(values);
+        list.addAll((Collection<T>) values);
+      } else {
+        for (final T value : values) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          list.add(value);
+        }
+      }
+    }
+
+    private static void checkForNullValues(final Iterable<?> values) {
+      for (final Object value : values) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+      }
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/AbstractParser.java b/protobuf/java/src/main/java/com/google/protobuf/AbstractParser.java
new file mode 100644
index 0000000..1a4c631
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/AbstractParser.java
@@ -0,0 +1,253 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A partial implementation of the {@link Parser} interface which implements
+ * as many methods of that interface as possible in terms of other methods.
+ *
+ * Note: This class implements all the convenience methods in the
+ * {@link Parser} interface. See {@link Parser} for related javadocs.
+ * Subclasses need to implement
+ * {@link Parser#parsePartialFrom(CodedInputStream, ExtensionRegistryLite)}
+ *
+ * @author liujisi@google.com (Pherl Liu)
+ */
+public abstract class AbstractParser<MessageType extends MessageLite>
+    implements Parser<MessageType> {
+  /**
+   * Creates an UninitializedMessageException for MessageType.
+   */
+  private UninitializedMessageException
+      newUninitializedMessageException(MessageType message) {
+    if (message instanceof AbstractMessageLite) {
+      return ((AbstractMessageLite) message).newUninitializedMessageException();
+    }
+    return new UninitializedMessageException(message);
+  }
+
+  /**
+   * Helper method to check if message is initialized.
+   *
+   * @throws InvalidProtocolBufferException if it is not initialized.
+   * @return The message to check.
+   */
+  private MessageType checkMessageInitialized(MessageType message)
+      throws InvalidProtocolBufferException {
+    if (message != null && !message.isInitialized()) {
+      throw newUninitializedMessageException(message)
+          .asInvalidProtocolBufferException()
+          .setUnfinishedMessage(message);
+    }
+    return message;
+  }
+
+  private static final ExtensionRegistryLite EMPTY_REGISTRY
+      = ExtensionRegistryLite.getEmptyRegistry();
+
+  public MessageType parsePartialFrom(CodedInputStream input)
+      throws InvalidProtocolBufferException {
+    return parsePartialFrom(input, EMPTY_REGISTRY);
+  }
+
+  public MessageType parseFrom(CodedInputStream input,
+                               ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(
+        parsePartialFrom(input, extensionRegistry));
+  }
+
+  public MessageType parseFrom(CodedInputStream input)
+      throws InvalidProtocolBufferException {
+    return parseFrom(input, EMPTY_REGISTRY);
+  }
+
+  public MessageType parsePartialFrom(ByteString data,
+                                      ExtensionRegistryLite extensionRegistry)
+    throws InvalidProtocolBufferException {
+    MessageType message;
+    try {
+      CodedInputStream input = data.newCodedInput();
+      message = parsePartialFrom(input, extensionRegistry);
+      try {
+        input.checkLastTagWas(0);
+      } catch (InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(message);
+      }
+      return message;
+    } catch (InvalidProtocolBufferException e) {
+      throw e;
+    }
+  }
+
+  public MessageType parsePartialFrom(ByteString data)
+      throws InvalidProtocolBufferException {
+    return parsePartialFrom(data, EMPTY_REGISTRY);
+  }
+
+  public MessageType parseFrom(ByteString data,
+                               ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(parsePartialFrom(data, extensionRegistry));
+  }
+
+  public MessageType parseFrom(ByteString data)
+      throws InvalidProtocolBufferException {
+    return parseFrom(data, EMPTY_REGISTRY);
+  }
+
+  public MessageType parsePartialFrom(byte[] data, int off, int len,
+                                      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    try {
+      CodedInputStream input = CodedInputStream.newInstance(data, off, len);
+      MessageType message = parsePartialFrom(input, extensionRegistry);
+      try {
+        input.checkLastTagWas(0);
+      } catch (InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(message);
+      }
+      return message;
+    } catch (InvalidProtocolBufferException e) {
+      throw e;
+    }
+  }
+
+  public MessageType parsePartialFrom(byte[] data, int off, int len)
+      throws InvalidProtocolBufferException {
+    return parsePartialFrom(data, off, len, EMPTY_REGISTRY);
+  }
+
+  public MessageType parsePartialFrom(byte[] data,
+                                      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return parsePartialFrom(data, 0, data.length, extensionRegistry);
+  }
+
+  public MessageType parsePartialFrom(byte[] data)
+      throws InvalidProtocolBufferException {
+    return parsePartialFrom(data, 0, data.length, EMPTY_REGISTRY);
+  }
+
+  public MessageType parseFrom(byte[] data, int off, int len,
+                               ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(
+        parsePartialFrom(data, off, len, extensionRegistry));
+  }
+
+  public MessageType parseFrom(byte[] data, int off, int len)
+      throws InvalidProtocolBufferException {
+    return parseFrom(data, off, len, EMPTY_REGISTRY);
+  }
+
+  public MessageType parseFrom(byte[] data,
+                               ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return parseFrom(data, 0, data.length, extensionRegistry);
+  }
+
+  public MessageType parseFrom(byte[] data)
+      throws InvalidProtocolBufferException {
+    return parseFrom(data, EMPTY_REGISTRY);
+  }
+
+  public MessageType parsePartialFrom(InputStream input,
+                                      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    CodedInputStream codedInput = CodedInputStream.newInstance(input);
+    MessageType message = parsePartialFrom(codedInput, extensionRegistry);
+    try {
+      codedInput.checkLastTagWas(0);
+    } catch (InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(message);
+    }
+    return message;
+  }
+
+  public MessageType parsePartialFrom(InputStream input)
+      throws InvalidProtocolBufferException {
+    return parsePartialFrom(input, EMPTY_REGISTRY);
+  }
+
+  public MessageType parseFrom(InputStream input,
+                               ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(
+        parsePartialFrom(input, extensionRegistry));
+  }
+
+  public MessageType parseFrom(InputStream input)
+      throws InvalidProtocolBufferException {
+    return parseFrom(input, EMPTY_REGISTRY);
+  }
+
+  public MessageType parsePartialDelimitedFrom(
+      InputStream input,
+      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    int size;
+    try {
+      int firstByte = input.read();
+      if (firstByte == -1) {
+        return null;
+      }
+      size = CodedInputStream.readRawVarint32(firstByte, input);
+    } catch (IOException e) {
+      throw new InvalidProtocolBufferException(e.getMessage());
+    }
+    InputStream limitedInput = new LimitedInputStream(input, size);
+    return parsePartialFrom(limitedInput, extensionRegistry);
+  }
+
+  public MessageType parsePartialDelimitedFrom(InputStream input)
+      throws InvalidProtocolBufferException {
+    return parsePartialDelimitedFrom(input, EMPTY_REGISTRY);
+  }
+
+  public MessageType parseDelimitedFrom(
+      InputStream input,
+      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException {
+    return checkMessageInitialized(
+        parsePartialDelimitedFrom(input, extensionRegistry));
+  }
+
+  public MessageType parseDelimitedFrom(InputStream input)
+      throws InvalidProtocolBufferException {
+    return parseDelimitedFrom(input, EMPTY_REGISTRY);
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java b/protobuf/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java
new file mode 100644
index 0000000..d535efb
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/BlockingRpcChannel.java
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * <p>Abstract interface for a blocking RPC channel.  {@code BlockingRpcChannel}
+ * is the blocking equivalent to {@link RpcChannel}.
+ *
+ * @author kenton@google.com Kenton Varda
+ * @author cpovirk@google.com Chris Povirk
+ */
+public interface BlockingRpcChannel {
+  /**
+   * Call the given method of the remote service and blocks until it returns.
+   * {@code callBlockingMethod()} is the blocking equivalent to
+   * {@link RpcChannel#callMethod}.
+   */
+  Message callBlockingMethod(
+      Descriptors.MethodDescriptor method,
+      RpcController controller,
+      Message request,
+      Message responsePrototype) throws ServiceException;
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/BlockingService.java b/protobuf/java/src/main/java/com/google/protobuf/BlockingService.java
new file mode 100644
index 0000000..d01f0b8
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/BlockingService.java
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Blocking equivalent to {@link Service}.
+ *
+ * @author kenton@google.com Kenton Varda
+ * @author cpovirk@google.com Chris Povirk
+ */
+public interface BlockingService {
+  /**
+   * Equivalent to {@link Service#getDescriptorForType}.
+   */
+  Descriptors.ServiceDescriptor getDescriptorForType();
+
+  /**
+   * Equivalent to {@link Service#callMethod}, except that
+   * {@code callBlockingMethod()} returns the result of the RPC or throws a
+   * {@link ServiceException} if there is a failure, rather than passing the
+   * information to a callback.
+   */
+  Message callBlockingMethod(Descriptors.MethodDescriptor method,
+                             RpcController controller,
+                             Message request) throws ServiceException;
+
+  /**
+   * Equivalent to {@link Service#getRequestPrototype}.
+   */
+  Message getRequestPrototype(Descriptors.MethodDescriptor method);
+
+  /**
+   * Equivalent to {@link Service#getResponsePrototype}.
+   */
+  Message getResponsePrototype(Descriptors.MethodDescriptor method);
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/BoundedByteString.java b/protobuf/java/src/main/java/com/google/protobuf/BoundedByteString.java
new file mode 100644
index 0000000..2828e9c
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/BoundedByteString.java
@@ -0,0 +1,163 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.NoSuchElementException;
+
+/**
+ * This class is used to represent the substring of a {@link ByteString} over a
+ * single byte array. In terms of the public API of {@link ByteString}, you end
+ * up here by calling {@link ByteString#copyFrom(byte[])} followed by {@link
+ * ByteString#substring(int, int)}.
+ *
+ * <p>This class contains most of the overhead involved in creating a substring
+ * from a {@link LiteralByteString}.  The overhead involves some range-checking
+ * and two extra fields.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+class BoundedByteString extends LiteralByteString {
+
+  private final int bytesOffset;
+  private final int bytesLength;
+
+  /**
+   * Creates a {@code BoundedByteString} backed by the sub-range of given array,
+   * without copying.
+   *
+   * @param bytes  array to wrap
+   * @param offset index to first byte to use in bytes
+   * @param length number of bytes to use from bytes
+   * @throws IllegalArgumentException if {@code offset < 0}, {@code length < 0},
+   *                                  or if {@code offset + length >
+   *                                  bytes.length}.
+   */
+  BoundedByteString(byte[] bytes, int offset, int length) {
+    super(bytes);
+    if (offset < 0) {
+      throw new IllegalArgumentException("Offset too small: " + offset);
+    }
+    if (length < 0) {
+      throw new IllegalArgumentException("Length too small: " + offset);
+    }
+    if ((long) offset + length > bytes.length) {
+      throw new IllegalArgumentException(
+          "Offset+Length too large: " + offset + "+" + length);
+    }
+
+    this.bytesOffset = offset;
+    this.bytesLength = length;
+  }
+
+  /**
+   * Gets the byte at the given index.
+   * Throws {@link ArrayIndexOutOfBoundsException}
+   * for backwards-compatibility reasons although it would more properly be
+   * {@link IndexOutOfBoundsException}.
+   *
+   * @param index index of byte
+   * @return the value
+   * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
+   */
+  @Override
+  public byte byteAt(int index) {
+    // We must check the index ourselves as we cannot rely on Java array index
+    // checking for substrings.
+    if (index < 0) {
+      throw new ArrayIndexOutOfBoundsException("Index too small: " + index);
+    }
+    if (index >= size()) {
+      throw new ArrayIndexOutOfBoundsException(
+          "Index too large: " + index + ", " + size());
+    }
+
+    return bytes[bytesOffset + index];
+  }
+
+  @Override
+  public int size() {
+    return bytesLength;
+  }
+
+  @Override
+  protected int getOffsetIntoBytes() {
+    return bytesOffset;
+  }
+
+  // =================================================================
+  // ByteString -> byte[]
+
+  @Override
+  protected void copyToInternal(byte[] target, int sourceOffset, 
+      int targetOffset, int numberToCopy) {
+    System.arraycopy(bytes, getOffsetIntoBytes() + sourceOffset, target,
+        targetOffset, numberToCopy);
+  }
+
+  // =================================================================
+  // ByteIterator
+
+  @Override
+  public ByteIterator iterator() {
+    return new BoundedByteIterator();
+  }
+
+  private class BoundedByteIterator implements ByteIterator {
+
+    private int position;
+    private final int limit;
+
+    private BoundedByteIterator() {
+      position = getOffsetIntoBytes();
+      limit = position + size();
+    }
+
+    public boolean hasNext() {
+      return (position < limit);
+    }
+
+    public Byte next() {
+      // Boxing calls Byte.valueOf(byte), which does not instantiate.
+      return nextByte();
+    }
+
+    public byte nextByte() {
+      if (position >= limit) {
+        throw new NoSuchElementException();
+      }
+      return bytes[position++];
+    }
+
+    public void remove() {
+      throw new UnsupportedOperationException();
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/ByteString.java b/protobuf/java/src/main/java/com/google/protobuf/ByteString.java
new file mode 100644
index 0000000..7da5612
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/ByteString.java
@@ -0,0 +1,1022 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Immutable sequence of bytes.  Substring is supported by sharing the reference
+ * to the immutable underlying bytes, as with {@link String}.  Concatenation is
+ * likewise supported without copying (long strings) by building a tree of
+ * pieces in {@link RopeByteString}.
+ * <p>
+ * Like {@link String}, the contents of a {@link ByteString} can never be
+ * observed to change, not even in the presence of a data race or incorrect
+ * API usage in the client code.
+ *
+ * @author crazybob@google.com Bob Lee
+ * @author kenton@google.com Kenton Varda
+ * @author carlanton@google.com Carl Haverl
+ * @author martinrb@google.com Martin Buchholz
+ */
+public abstract class ByteString implements Iterable<Byte> {
+
+  /**
+   * When two strings to be concatenated have a combined length shorter than
+   * this, we just copy their bytes on {@link #concat(ByteString)}.
+   * The trade-off is copy size versus the overhead of creating tree nodes
+   * in {@link RopeByteString}.
+   */
+  static final int CONCATENATE_BY_COPY_SIZE = 128;
+
+  /**
+   * When copying an InputStream into a ByteString with .readFrom(),
+   * the chunks in the underlying rope start at 256 bytes, but double
+   * each iteration up to 8192 bytes.
+   */
+  static final int MIN_READ_FROM_CHUNK_SIZE = 0x100;  // 256b
+  static final int MAX_READ_FROM_CHUNK_SIZE = 0x2000;  // 8k
+
+  /**
+   * Empty {@code ByteString}.
+   */
+  public static final ByteString EMPTY = new LiteralByteString(new byte[0]);
+
+  // This constructor is here to prevent subclassing outside of this package,
+  ByteString() {}
+
+  /**
+   * Gets the byte at the given index. This method should be used only for
+   * random access to individual bytes. To access bytes sequentially, use the
+   * {@link ByteIterator} returned by {@link #iterator()}, and call {@link
+   * #substring(int, int)} first if necessary.
+   *
+   * @param index index of byte
+   * @return the value
+   * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
+   */
+  public abstract byte byteAt(int index);
+
+  /**
+   * Return a {@link ByteString.ByteIterator} over the bytes in the ByteString.
+   * To avoid auto-boxing, you may get the iterator manually and call
+   * {@link ByteIterator#nextByte()}.
+   *
+   * @return the iterator
+   */
+  public abstract ByteIterator iterator();
+
+  /**
+   * This interface extends {@code Iterator<Byte>}, so that we can return an
+   * unboxed {@code byte}.
+   */
+  public interface ByteIterator extends Iterator<Byte> {
+    /**
+     * An alternative to {@link Iterator#next()} that returns an
+     * unboxed primitive {@code byte}.
+     *
+     * @return the next {@code byte} in the iteration
+     * @throws NoSuchElementException if the iteration has no more elements
+     */
+    byte nextByte();
+  }
+
+  /**
+   * Gets the number of bytes.
+   *
+   * @return size in bytes
+   */
+  public abstract int size();
+
+  /**
+   * Returns {@code true} if the size is {@code 0}, {@code false} otherwise.
+   *
+   * @return true if this is zero bytes long
+   */
+  public boolean isEmpty() {
+    return size() == 0;
+  }
+
+  // =================================================================
+  // ByteString -> substring
+
+  /**
+   * Return the substring from {@code beginIndex}, inclusive, to the end of the
+   * string.
+   *
+   * @param beginIndex start at this index
+   * @return substring sharing underlying data
+   * @throws IndexOutOfBoundsException if {@code beginIndex < 0} or
+   *     {@code beginIndex > size()}.
+   */
+  public ByteString substring(int beginIndex) {
+    return substring(beginIndex, size());
+  }
+
+  /**
+   * Return the substring from {@code beginIndex}, inclusive, to {@code
+   * endIndex}, exclusive.
+   *
+   * @param beginIndex start at this index
+   * @param endIndex   the last character is the one before this index
+   * @return substring sharing underlying data
+   * @throws IndexOutOfBoundsException if {@code beginIndex < 0},
+   *     {@code endIndex > size()}, or {@code beginIndex > endIndex}.
+   */
+  public abstract ByteString substring(int beginIndex, int endIndex);
+
+  /**
+   * Tests if this bytestring starts with the specified prefix.
+   * Similar to {@link String#startsWith(String)}
+   *
+   * @param prefix the prefix.
+   * @return <code>true</code> if the byte sequence represented by the
+   *         argument is a prefix of the byte sequence represented by
+   *         this string; <code>false</code> otherwise.
+   */
+  public boolean startsWith(ByteString prefix) {
+    return size() >= prefix.size() &&
+           substring(0, prefix.size()).equals(prefix);
+  }
+
+  /**
+   * Tests if this bytestring ends with the specified suffix.
+   * Similar to {@link String#endsWith(String)}
+   *
+   * @param suffix the suffix.
+   * @return <code>true</code> if the byte sequence represented by the
+   *         argument is a suffix of the byte sequence represented by
+   *         this string; <code>false</code> otherwise.
+   */
+  public boolean endsWith(ByteString suffix) {
+    return size() >= suffix.size() &&
+        substring(size() - suffix.size()).equals(suffix);
+  }
+
+  // =================================================================
+  // byte[] -> ByteString
+
+  /**
+   * Copies the given bytes into a {@code ByteString}.
+   *
+   * @param bytes source array
+   * @param offset offset in source array
+   * @param size number of bytes to copy
+   * @return new {@code ByteString}
+   */
+  public static ByteString copyFrom(byte[] bytes, int offset, int size) {
+    byte[] copy = new byte[size];
+    System.arraycopy(bytes, offset, copy, 0, size);
+    return new LiteralByteString(copy);
+  }
+
+  /**
+   * Copies the given bytes into a {@code ByteString}.
+   *
+   * @param bytes to copy
+   * @return new {@code ByteString}
+   */
+  public static ByteString copyFrom(byte[] bytes) {
+    return copyFrom(bytes, 0, bytes.length);
+  }
+
+  /**
+   * Copies the next {@code size} bytes from a {@code java.nio.ByteBuffer} into
+   * a {@code ByteString}.
+   *
+   * @param bytes source buffer
+   * @param size number of bytes to copy
+   * @return new {@code ByteString}
+   */
+  public static ByteString copyFrom(ByteBuffer bytes, int size) {
+    byte[] copy = new byte[size];
+    bytes.get(copy);
+    return new LiteralByteString(copy);
+  }
+
+  /**
+   * Copies the remaining bytes from a {@code java.nio.ByteBuffer} into
+   * a {@code ByteString}.
+   *
+   * @param bytes sourceBuffer
+   * @return new {@code ByteString}
+   */
+  public static ByteString copyFrom(ByteBuffer bytes) {
+    return copyFrom(bytes, bytes.remaining());
+  }
+
+  /**
+   * Encodes {@code text} into a sequence of bytes using the named charset
+   * and returns the result as a {@code ByteString}.
+   *
+   * @param text source string
+   * @param charsetName encoding to use
+   * @return new {@code ByteString}
+   * @throws UnsupportedEncodingException if the encoding isn't found
+   */
+  public static ByteString copyFrom(String text, String charsetName)
+      throws UnsupportedEncodingException {
+    return new LiteralByteString(text.getBytes(charsetName));
+  }
+
+  /**
+   * Encodes {@code text} into a sequence of UTF-8 bytes and returns the
+   * result as a {@code ByteString}.
+   *
+   * @param text source string
+   * @return new {@code ByteString}
+   */
+  public static ByteString copyFromUtf8(String text) {
+    try {
+      return new LiteralByteString(text.getBytes("UTF-8"));
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 not supported?", e);
+    }
+  }
+
+  // =================================================================
+  // InputStream -> ByteString
+
+  /**
+   * Completely reads the given stream's bytes into a
+   * {@code ByteString}, blocking if necessary until all bytes are
+   * read through to the end of the stream.
+   *
+   * <b>Performance notes:</b> The returned {@code ByteString} is an
+   * immutable tree of byte arrays ("chunks") of the stream data.  The
+   * first chunk is small, with subsequent chunks each being double
+   * the size, up to 8K.  If the caller knows the precise length of
+   * the stream and wishes to avoid all unnecessary copies and
+   * allocations, consider using the two-argument version of this
+   * method, below.
+   *
+   * @param streamToDrain The source stream, which is read completely
+   *     but not closed.
+   * @return A new {@code ByteString} which is made up of chunks of
+   *     various sizes, depending on the behavior of the underlying
+   *     stream.
+   * @throws IOException IOException is thrown if there is a problem
+   *     reading the underlying stream.
+   */
+  public static ByteString readFrom(InputStream streamToDrain)
+      throws IOException {
+    return readFrom(
+        streamToDrain, MIN_READ_FROM_CHUNK_SIZE, MAX_READ_FROM_CHUNK_SIZE);
+  }
+
+  /**
+   * Completely reads the given stream's bytes into a
+   * {@code ByteString}, blocking if necessary until all bytes are
+   * read through to the end of the stream.
+   *
+   * <b>Performance notes:</b> The returned {@code ByteString} is an
+   * immutable tree of byte arrays ("chunks") of the stream data.  The
+   * chunkSize parameter sets the size of these byte arrays. In
+   * particular, if the chunkSize is precisely the same as the length
+   * of the stream, unnecessary allocations and copies will be
+   * avoided. Otherwise, the chunks will be of the given size, except
+   * for the last chunk, which will be resized (via a reallocation and
+   * copy) to contain the remainder of the stream.
+   *
+   * @param streamToDrain The source stream, which is read completely
+   *     but not closed.
+   * @param chunkSize The size of the chunks in which to read the
+   *     stream.
+   * @return A new {@code ByteString} which is made up of chunks of
+   *     the given size.
+   * @throws IOException IOException is thrown if there is a problem
+   *     reading the underlying stream.
+   */
+  public static ByteString readFrom(InputStream streamToDrain, int chunkSize)
+      throws IOException {
+    return readFrom(streamToDrain, chunkSize, chunkSize);
+  }
+
+  // Helper method that takes the chunk size range as a parameter.
+  public static ByteString readFrom(InputStream streamToDrain, int minChunkSize,
+      int maxChunkSize) throws IOException {
+    Collection<ByteString> results = new ArrayList<ByteString>();
+
+    // copy the inbound bytes into a list of chunks; the chunk size
+    // grows exponentially to support both short and long streams.
+    int chunkSize = minChunkSize;
+    while (true) {
+      ByteString chunk = readChunk(streamToDrain, chunkSize);
+      if (chunk == null) {
+        break;
+      }
+      results.add(chunk);
+      chunkSize = Math.min(chunkSize * 2, maxChunkSize);
+    }
+
+    return ByteString.copyFrom(results);
+  }
+
+  /**
+   * Blocks until a chunk of the given size can be made from the
+   * stream, or EOF is reached.  Calls read() repeatedly in case the
+   * given stream implementation doesn't completely fill the given
+   * buffer in one read() call.
+   *
+   * @return A chunk of the desired size, or else a chunk as large as
+   * was available when end of stream was reached. Returns null if the
+   * given stream had no more data in it.
+   */
+  private static ByteString readChunk(InputStream in, final int chunkSize)
+      throws IOException {
+      final byte[] buf = new byte[chunkSize];
+      int bytesRead = 0;
+      while (bytesRead < chunkSize) {
+        final int count = in.read(buf, bytesRead, chunkSize - bytesRead);
+        if (count == -1) {
+          break;
+        }
+        bytesRead += count;
+      }
+
+      if (bytesRead == 0) {
+        return null;
+      } else {
+        return ByteString.copyFrom(buf, 0, bytesRead);
+      }
+  }
+
+  // =================================================================
+  // Multiple ByteStrings -> One ByteString
+
+  /**
+   * Concatenate the given {@code ByteString} to this one. Short concatenations,
+   * of total size smaller than {@link ByteString#CONCATENATE_BY_COPY_SIZE}, are
+   * produced by copying the underlying bytes (as per Rope.java, <a
+   * href="http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">
+   * BAP95 </a>. In general, the concatenate involves no copying.
+   *
+   * @param other string to concatenate
+   * @return a new {@code ByteString} instance
+   */
+  public ByteString concat(ByteString other) {
+    int thisSize = size();
+    int otherSize = other.size();
+    if ((long) thisSize + otherSize >= Integer.MAX_VALUE) {
+      throw new IllegalArgumentException("ByteString would be too long: " +
+                                         thisSize + "+" + otherSize);
+    }
+
+    return RopeByteString.concatenate(this, other);
+  }
+
+  /**
+   * Concatenates all byte strings in the iterable and returns the result.
+   * This is designed to run in O(list size), not O(total bytes).
+   *
+   * <p>The returned {@code ByteString} is not necessarily a unique object.
+   * If the list is empty, the returned object is the singleton empty
+   * {@code ByteString}.  If the list has only one element, that
+   * {@code ByteString} will be returned without copying.
+   *
+   * @param byteStrings strings to be concatenated
+   * @return new {@code ByteString}
+   */
+  public static ByteString copyFrom(Iterable<ByteString> byteStrings) {
+    Collection<ByteString> collection;
+    if (!(byteStrings instanceof Collection)) {
+      collection = new ArrayList<ByteString>();
+      for (ByteString byteString : byteStrings) {
+        collection.add(byteString);
+      }
+    } else {
+      collection = (Collection<ByteString>) byteStrings;
+    }
+    ByteString result;
+    if (collection.isEmpty()) {
+      result = EMPTY;
+    } else {
+      result = balancedConcat(collection.iterator(), collection.size());
+    }
+    return result;
+  }
+
+  // Internal function used by copyFrom(Iterable<ByteString>).
+  // Create a balanced concatenation of the next "length" elements from the
+  // iterable.
+  private static ByteString balancedConcat(Iterator<ByteString> iterator,
+      int length) {
+    assert length >= 1;
+    ByteString result;
+    if (length == 1) {
+      result = iterator.next();
+    } else {
+      int halfLength = length >>> 1;
+      ByteString left = balancedConcat(iterator, halfLength);
+      ByteString right = balancedConcat(iterator, length - halfLength);
+      result = left.concat(right);
+    }
+    return result;
+  }
+
+  // =================================================================
+  // ByteString -> byte[]
+
+  /**
+   * Copies bytes into a buffer at the given offset.
+   *
+   * @param target buffer to copy into
+   * @param offset in the target buffer
+   * @throws IndexOutOfBoundsException if the offset is negative or too large
+   */
+  public void copyTo(byte[] target, int offset) {
+    copyTo(target, 0, offset, size());
+  }
+
+  /**
+   * Copies bytes into a buffer.
+   *
+   * @param target       buffer to copy into
+   * @param sourceOffset offset within these bytes
+   * @param targetOffset offset within the target buffer
+   * @param numberToCopy number of bytes to copy
+   * @throws IndexOutOfBoundsException if an offset or size is negative or too
+   *     large
+   */
+  public void copyTo(byte[] target, int sourceOffset, int targetOffset,
+      int numberToCopy) {
+    if (sourceOffset < 0) {
+      throw new IndexOutOfBoundsException("Source offset < 0: " + sourceOffset);
+    }
+    if (targetOffset < 0) {
+      throw new IndexOutOfBoundsException("Target offset < 0: " + targetOffset);
+    }
+    if (numberToCopy < 0) {
+      throw new IndexOutOfBoundsException("Length < 0: " + numberToCopy);
+    }
+    if (sourceOffset + numberToCopy > size()) {
+      throw new IndexOutOfBoundsException(
+          "Source end offset < 0: " + (sourceOffset + numberToCopy));
+    }
+    if (targetOffset + numberToCopy > target.length) {
+      throw new IndexOutOfBoundsException(
+          "Target end offset < 0: " + (targetOffset + numberToCopy));
+    }
+    if (numberToCopy > 0) {
+      copyToInternal(target, sourceOffset, targetOffset, numberToCopy);
+    }
+  }
+
+  /**
+   * Internal (package private) implementation of
+   * @link{#copyTo(byte[],int,int,int}.
+   * It assumes that all error checking has already been performed and that 
+   * @code{numberToCopy > 0}.
+   */
+  protected abstract void copyToInternal(byte[] target, int sourceOffset,
+      int targetOffset, int numberToCopy);
+
+  /**
+   * Copies bytes into a ByteBuffer.
+   *
+   * @param target ByteBuffer to copy into.
+   * @throws java.nio.ReadOnlyBufferException if the {@code target} is read-only
+   * @throws java.nio.BufferOverflowException if the {@code target}'s
+   *     remaining() space is not large enough to hold the data.
+   */
+  public abstract void copyTo(ByteBuffer target);
+
+  /**
+   * Copies bytes to a {@code byte[]}.
+   *
+   * @return copied bytes
+   */
+  public byte[] toByteArray() {
+    int size = size();
+    if (size == 0) {
+      return Internal.EMPTY_BYTE_ARRAY;
+    }
+    byte[] result = new byte[size];
+    copyToInternal(result, 0, 0, size);
+    return result;
+  }
+
+  /**
+   * Writes the complete contents of this byte string to
+   * the specified output stream argument.
+   *
+   * @param  out  the output stream to which to write the data.
+   * @throws IOException  if an I/O error occurs.
+   */
+  public abstract void writeTo(OutputStream out) throws IOException;
+  
+  /**
+   * Writes a specified part of this byte string to an output stream.
+   *
+   * @param  out  the output stream to which to write the data.
+   * @param  sourceOffset offset within these bytes
+   * @param  numberToWrite number of bytes to write
+   * @throws IOException  if an I/O error occurs.
+   * @throws IndexOutOfBoundsException if an offset or size is negative or too
+   *     large
+   */
+  void writeTo(OutputStream out, int sourceOffset, int numberToWrite)
+      throws IOException {
+    if (sourceOffset < 0) {
+      throw new IndexOutOfBoundsException("Source offset < 0: " + sourceOffset);
+    }
+    if (numberToWrite < 0) {
+      throw new IndexOutOfBoundsException("Length < 0: " + numberToWrite);
+    }
+    if (sourceOffset + numberToWrite > size()) {
+      throw new IndexOutOfBoundsException(
+          "Source end offset exceeded: " + (sourceOffset + numberToWrite));
+    }
+    if (numberToWrite > 0) {
+      writeToInternal(out, sourceOffset, numberToWrite);
+    }
+    
+  }
+
+  /**
+   * Internal version of {@link #writeTo(OutputStream,int,int)} that assumes
+   * all error checking has already been done.
+   */
+  abstract void writeToInternal(OutputStream out, int sourceOffset,
+      int numberToWrite) throws IOException;
+
+  /**
+   * Constructs a read-only {@code java.nio.ByteBuffer} whose content
+   * is equal to the contents of this byte string.
+   * The result uses the same backing array as the byte string, if possible.
+   *
+   * @return wrapped bytes
+   */
+  public abstract ByteBuffer asReadOnlyByteBuffer();
+
+  /**
+   * Constructs a list of read-only {@code java.nio.ByteBuffer} objects
+   * such that the concatenation of their contents is equal to the contents
+   * of this byte string.  The result uses the same backing arrays as the
+   * byte string.
+   * <p>
+   * By returning a list, implementations of this method may be able to avoid
+   * copying even when there are multiple backing arrays.
+   * 
+   * @return a list of wrapped bytes
+   */
+  public abstract List<ByteBuffer> asReadOnlyByteBufferList();
+
+  /**
+   * Constructs a new {@code String} by decoding the bytes using the
+   * specified charset.
+   *
+   * @param charsetName encode using this charset
+   * @return new string
+   * @throws UnsupportedEncodingException if charset isn't recognized
+   */
+  public abstract String toString(String charsetName)
+      throws UnsupportedEncodingException;
+
+  // =================================================================
+  // UTF-8 decoding
+
+  /**
+   * Constructs a new {@code String} by decoding the bytes as UTF-8.
+   *
+   * @return new string using UTF-8 encoding
+   */
+  public String toStringUtf8() {
+    try {
+      return toString("UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 not supported?", e);
+    }
+  }
+
+  /**
+   * Tells whether this {@code ByteString} represents a well-formed UTF-8
+   * byte sequence, such that the original bytes can be converted to a
+   * String object and then round tripped back to bytes without loss.
+   *
+   * <p>More precisely, returns {@code true} whenever: <pre> {@code
+   * Arrays.equals(byteString.toByteArray(),
+   *     new String(byteString.toByteArray(), "UTF-8").getBytes("UTF-8"))
+   * }</pre>
+   *
+   * <p>This method returns {@code false} for "overlong" byte sequences,
+   * as well as for 3-byte sequences that would map to a surrogate
+   * character, in accordance with the restricted definition of UTF-8
+   * introduced in Unicode 3.1.  Note that the UTF-8 decoder included in
+   * Oracle's JDK has been modified to also reject "overlong" byte
+   * sequences, but (as of 2011) still accepts 3-byte surrogate
+   * character byte sequences.
+   *
+   * <p>See the Unicode Standard,</br>
+   * Table 3-6. <em>UTF-8 Bit Distribution</em>,</br>
+   * Table 3-7. <em>Well Formed UTF-8 Byte Sequences</em>.
+   *
+   * @return whether the bytes in this {@code ByteString} are a
+   * well-formed UTF-8 byte sequence
+   */
+  public abstract boolean isValidUtf8();
+
+  /**
+   * Tells whether the given byte sequence is a well-formed, malformed, or
+   * incomplete UTF-8 byte sequence.  This method accepts and returns a partial
+   * state result, allowing the bytes for a complete UTF-8 byte sequence to be
+   * composed from multiple {@code ByteString} segments.
+   *
+   * @param state either {@code 0} (if this is the initial decoding operation)
+   *     or the value returned from a call to a partial decoding method for the
+   *     previous bytes
+   * @param offset offset of the first byte to check
+   * @param length number of bytes to check
+   *
+   * @return {@code -1} if the partial byte sequence is definitely malformed,
+   * {@code 0} if it is well-formed (no additional input needed), or, if the
+   * byte sequence is "incomplete", i.e. apparently terminated in the middle of
+   * a character, an opaque integer "state" value containing enough information
+   * to decode the character when passed to a subsequent invocation of a
+   * partial decoding method.
+   */
+  protected abstract int partialIsValidUtf8(int state, int offset, int length);
+
+  // =================================================================
+  // equals() and hashCode()
+
+  @Override
+  public abstract boolean equals(Object o);
+
+  /**
+   * Return a non-zero hashCode depending only on the sequence of bytes
+   * in this ByteString.
+   *
+   * @return hashCode value for this object
+   */
+  @Override
+  public abstract int hashCode();
+
+  // =================================================================
+  // Input stream
+
+  /**
+   * Creates an {@code InputStream} which can be used to read the bytes.
+   * <p>
+   * The {@link InputStream} returned by this method is guaranteed to be
+   * completely non-blocking.  The method {@link InputStream#available()}
+   * returns the number of bytes remaining in the stream. The methods
+   * {@link InputStream#read(byte[]), {@link InputStream#read(byte[],int,int)}
+   * and {@link InputStream#skip(long)} will read/skip as many bytes as are
+   * available.
+   * <p>
+   * The methods in the returned {@link InputStream} might <b>not</b> be
+   * thread safe.
+   *
+   * @return an input stream that returns the bytes of this byte string.
+   */
+  public abstract InputStream newInput();
+
+  /**
+   * Creates a {@link CodedInputStream} which can be used to read the bytes.
+   * Using this is often more efficient than creating a {@link CodedInputStream}
+   * that wraps the result of {@link #newInput()}.
+   *
+   * @return stream based on wrapped data
+   */
+  public abstract CodedInputStream newCodedInput();
+
+  // =================================================================
+  // Output stream
+
+  /**
+   * Creates a new {@link Output} with the given initial capacity. Call {@link
+   * Output#toByteString()} to create the {@code ByteString} instance.
+   * <p>
+   * A {@link ByteString.Output} offers the same functionality as a
+   * {@link ByteArrayOutputStream}, except that it returns a {@link ByteString}
+   * rather than a {@code byte} array.
+   *
+   * @param initialCapacity estimate of number of bytes to be written
+   * @return {@code OutputStream} for building a {@code ByteString}
+   */
+  public static Output newOutput(int initialCapacity) {
+    return new Output(initialCapacity);
+  }
+
+  /**
+   * Creates a new {@link Output}. Call {@link Output#toByteString()} to create
+   * the {@code ByteString} instance.
+   * <p>
+   * A {@link ByteString.Output} offers the same functionality as a
+   * {@link ByteArrayOutputStream}, except that it returns a {@link ByteString}
+   * rather than a {@code byte array}.
+   *
+   * @return {@code OutputStream} for building a {@code ByteString}
+   */
+  public static Output newOutput() {
+    return new Output(CONCATENATE_BY_COPY_SIZE);
+  }
+
+  /**
+   * Outputs to a {@code ByteString} instance. Call {@link #toByteString()} to
+   * create the {@code ByteString} instance.
+   */
+  public static final class Output extends OutputStream {
+    // Implementation note.
+    // The public methods of this class must be synchronized.  ByteStrings
+    // are guaranteed to be immutable.  Without some sort of locking, it could
+    // be possible for one thread to call toByteSring(), while another thread
+    // is still modifying the underlying byte array.
+
+    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+    // argument passed by user, indicating initial capacity.
+    private final int initialCapacity;
+    // ByteStrings to be concatenated to create the result
+    private final ArrayList<ByteString> flushedBuffers;
+    // Total number of bytes in the ByteStrings of flushedBuffers
+    private int flushedBuffersTotalBytes;
+    // Current buffer to which we are writing
+    private byte[] buffer;
+    // Location in buffer[] to which we write the next byte.
+    private int bufferPos;
+
+    /**
+     * Creates a new ByteString output stream with the specified
+     * initial capacity.
+     *
+     * @param initialCapacity  the initial capacity of the output stream.
+     */
+    Output(int initialCapacity) {
+      if (initialCapacity < 0) {
+        throw new IllegalArgumentException("Buffer size < 0");
+      }
+      this.initialCapacity = initialCapacity;
+      this.flushedBuffers = new ArrayList<ByteString>();
+      this.buffer = new byte[initialCapacity];
+    }
+
+    @Override
+    public synchronized void write(int b) {
+      if (bufferPos == buffer.length) {
+        flushFullBuffer(1);
+      }
+      buffer[bufferPos++] = (byte)b;
+    }
+
+    @Override
+    public synchronized void write(byte[] b, int offset, int length)  {
+      if (length <= buffer.length - bufferPos) {
+        // The bytes can fit into the current buffer.
+        System.arraycopy(b, offset, buffer, bufferPos, length);
+        bufferPos += length;
+      } else {
+        // Use up the current buffer
+        int copySize  = buffer.length - bufferPos;
+        System.arraycopy(b, offset, buffer, bufferPos, copySize);
+        offset += copySize;
+        length -= copySize;
+        // Flush the buffer, and get a new buffer at least big enough to cover
+        // what we still need to output
+        flushFullBuffer(length);
+        System.arraycopy(b, offset, buffer, 0 /* count */, length);
+        bufferPos = length;
+      }
+    }
+
+    /**
+     * Creates a byte string. Its size is the current size of this output
+     * stream and its output has been copied to it.
+     *
+     * @return  the current contents of this output stream, as a byte string.
+     */
+    public synchronized ByteString toByteString() {
+      flushLastBuffer();
+      return ByteString.copyFrom(flushedBuffers);
+    }
+    
+    /**
+     * Implement java.util.Arrays.copyOf() for jdk 1.5.
+     */
+    private byte[] copyArray(byte[] buffer, int length) {
+      byte[] result = new byte[length];
+      System.arraycopy(buffer, 0, result, 0, Math.min(buffer.length, length));
+      return result;
+    }
+
+    /**
+     * Writes the complete contents of this byte array output stream to
+     * the specified output stream argument.
+     *
+     * @param out the output stream to which to write the data.
+     * @throws IOException  if an I/O error occurs.
+     */
+    public void writeTo(OutputStream out) throws IOException {
+      ByteString[] cachedFlushBuffers;
+      byte[] cachedBuffer;
+      int cachedBufferPos;
+      synchronized (this) {
+        // Copy the information we need into local variables so as to hold
+        // the lock for as short a time as possible.
+        cachedFlushBuffers =
+            flushedBuffers.toArray(new ByteString[flushedBuffers.size()]);
+        cachedBuffer = buffer;
+        cachedBufferPos = bufferPos;
+      }
+      for (ByteString byteString : cachedFlushBuffers) {
+        byteString.writeTo(out);
+      }
+
+      out.write(copyArray(cachedBuffer, cachedBufferPos));
+    }
+
+    /**
+     * Returns the current size of the output stream.
+     *
+     * @return  the current size of the output stream
+     */
+    public synchronized int size() {
+      return flushedBuffersTotalBytes + bufferPos;
+    }
+
+    /**
+     * Resets this stream, so that all currently accumulated output in the
+     * output stream is discarded. The output stream can be used again,
+     * reusing the already allocated buffer space.
+     */
+    public synchronized void reset() {
+      flushedBuffers.clear();
+      flushedBuffersTotalBytes = 0;
+      bufferPos = 0;
+    }
+
+    @Override
+    public String toString() {
+      return String.format("<ByteString.Output@%s size=%d>",
+          Integer.toHexString(System.identityHashCode(this)), size());
+    }
+
+    /**
+     * Internal function used by writers.  The current buffer is full, and the
+     * writer needs a new buffer whose size is at least the specified minimum
+     * size.
+     */
+    private void flushFullBuffer(int minSize)  {
+      flushedBuffers.add(new LiteralByteString(buffer));
+      flushedBuffersTotalBytes += buffer.length;
+      // We want to increase our total capacity by 50%, but as a minimum,
+      // the new buffer should also at least be >= minSize and
+      // >= initial Capacity.
+      int newSize = Math.max(initialCapacity,
+          Math.max(minSize, flushedBuffersTotalBytes >>> 1));
+      buffer = new byte[newSize];
+      bufferPos = 0;
+    }
+
+    /**
+     * Internal function used by {@link #toByteString()}. The current buffer may
+     * or may not be full, but it needs to be flushed.
+     */
+    private void flushLastBuffer()  {
+      if (bufferPos < buffer.length) {
+        if (bufferPos > 0) {
+          byte[] bufferCopy = copyArray(buffer, bufferPos);
+          flushedBuffers.add(new LiteralByteString(bufferCopy));
+        }
+        // We reuse this buffer for further writes.
+      } else {
+        // Buffer is completely full.  Huzzah.
+        flushedBuffers.add(new LiteralByteString(buffer));
+        // 99% of the time, we're not going to use this OutputStream again.
+        // We set buffer to an empty byte stream so that we're handling this
+        // case without wasting space.  In the rare case that more writes
+        // *do* occur, this empty buffer will be flushed and an appropriately
+        // sized new buffer will be created.
+        buffer = EMPTY_BYTE_ARRAY;
+      }
+      flushedBuffersTotalBytes += bufferPos;
+      bufferPos = 0;
+    }
+  }
+
+  /**
+   * Constructs a new {@code ByteString} builder, which allows you to
+   * efficiently construct a {@code ByteString} by writing to a {@link
+   * CodedOutputStream}. Using this is much more efficient than calling {@code
+   * newOutput()} and wrapping that in a {@code CodedOutputStream}.
+   *
+   * <p>This is package-private because it's a somewhat confusing interface.
+   * Users can call {@link Message#toByteString()} instead of calling this
+   * directly.
+   *
+   * @param size The target byte size of the {@code ByteString}.  You must write
+   *     exactly this many bytes before building the result.
+   * @return the builder
+   */
+  static CodedBuilder newCodedBuilder(int size) {
+    return new CodedBuilder(size);
+  }
+
+  /** See {@link ByteString#newCodedBuilder(int)}. */
+  static final class CodedBuilder {
+    private final CodedOutputStream output;
+    private final byte[] buffer;
+
+    private CodedBuilder(int size) {
+      buffer = new byte[size];
+      output = CodedOutputStream.newInstance(buffer);
+    }
+
+    public ByteString build() {
+      output.checkNoSpaceLeft();
+
+      // We can be confident that the CodedOutputStream will not modify the
+      // underlying bytes anymore because it already wrote all of them.  So,
+      // no need to make a copy.
+      return new LiteralByteString(buffer);
+    }
+
+    public CodedOutputStream getCodedOutput() {
+      return output;
+    }
+  }
+
+  // =================================================================
+  // Methods {@link RopeByteString} needs on instances, which aren't part of the
+  // public API.
+
+  /**
+   * Return the depth of the tree representing this {@code ByteString}, if any,
+   * whose root is this node. If this is a leaf node, return 0.
+   *
+   * @return tree depth or zero
+   */
+  protected abstract int getTreeDepth();
+
+  /**
+   * Return {@code true} if this ByteString is literal (a leaf node) or a
+   * flat-enough tree in the sense of {@link RopeByteString}.
+   *
+   * @return true if the tree is flat enough
+   */
+  protected abstract boolean isBalanced();
+
+  /**
+   * Return the cached hash code if available.
+   *
+   * @return value of cached hash code or 0 if not computed yet
+   */
+  protected abstract int peekCachedHashCode();
+
+  /**
+   * Compute the hash across the value bytes starting with the given hash, and
+   * return the result.  This is used to compute the hash across strings
+   * represented as a set of pieces by allowing the hash computation to be
+   * continued from piece to piece.
+   *
+   * @param h starting hash value
+   * @param offset offset into this value to start looking at data values
+   * @param length number of data values to include in the hash computation
+   * @return ending hash value
+   */
+  protected abstract int partialHash(int h, int offset, int length);
+
+  @Override
+  public String toString() {
+    return String.format("<ByteString@%s size=%d>",
+        Integer.toHexString(System.identityHashCode(this)), size());
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/CodedInputStream.java b/protobuf/java/src/main/java/com/google/protobuf/CodedInputStream.java
new file mode 100644
index 0000000..a00ae86
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -0,0 +1,1311 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Reads and decodes protocol message fields.
+ *
+ * This class contains two kinds of methods:  methods that read specific
+ * protocol message constructs and field types (e.g. {@link #readTag()} and
+ * {@link #readInt32()}) and methods that read low-level values (e.g.
+ * {@link #readRawVarint32()} and {@link #readRawBytes}).  If you are reading
+ * encoded protocol messages, you should use the former methods, but if you are
+ * reading some other format of your own design, use the latter.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class CodedInputStream {
+  /**
+   * Create a new CodedInputStream wrapping the given InputStream.
+   */
+  public static CodedInputStream newInstance(final InputStream input) {
+    return new CodedInputStream(input);
+  }
+
+  /**
+   * Create a new CodedInputStream wrapping the given byte array.
+   */
+  public static CodedInputStream newInstance(final byte[] buf) {
+    return newInstance(buf, 0, buf.length);
+  }
+
+  /**
+   * Create a new CodedInputStream wrapping the given byte array slice.
+   */
+  public static CodedInputStream newInstance(final byte[] buf, final int off,
+                                             final int len) {
+    CodedInputStream result = new CodedInputStream(buf, off, len);
+    try {
+      // Some uses of CodedInputStream can be more efficient if they know
+      // exactly how many bytes are available.  By pushing the end point of the
+      // buffer as a limit, we allow them to get this information via
+      // getBytesUntilLimit().  Pushing a limit that we know is at the end of
+      // the stream can never hurt, since we can never past that point anyway.
+      result.pushLimit(len);
+    } catch (InvalidProtocolBufferException ex) {
+      // The only reason pushLimit() might throw an exception here is if len
+      // is negative. Normally pushLimit()'s parameter comes directly off the
+      // wire, so it's important to catch exceptions in case of corrupt or
+      // malicious data. However, in this case, we expect that len is not a
+      // user-supplied value, so we can assume that it being negative indicates
+      // a programming error. Therefore, throwing an unchecked exception is
+      // appropriate.
+      throw new IllegalArgumentException(ex);
+    }
+    return result;
+  }
+
+  /**
+   * Create a new CodedInputStream wrapping the given ByteBuffer. The data
+   * starting from the ByteBuffer's current position to its limit will be read.
+   * The returned CodedInputStream may or may not share the underlying data
+   * in the ByteBuffer, therefore the ByteBuffer cannot be changed while the
+   * CodedInputStream is in use.
+   * Note that the ByteBuffer's position won't be changed by this function.
+   * Concurrent calls with the same ByteBuffer object are safe if no other
+   * thread is trying to alter the ByteBuffer's status.
+   */
+  public static CodedInputStream newInstance(ByteBuffer buf) {
+    if (buf.hasArray()) {
+      return newInstance(buf.array(), buf.arrayOffset() + buf.position(),
+          buf.remaining());
+    } else {
+      ByteBuffer temp = buf.duplicate();
+      byte[] buffer = new byte[temp.remaining()];
+      temp.get(buffer);
+      return newInstance(buffer);
+    }
+  }
+
+  /**
+   * Create a new CodedInputStream wrapping a LiteralByteString.
+   */
+  static CodedInputStream newInstance(LiteralByteString byteString) {
+    CodedInputStream result = new CodedInputStream(byteString);
+    try {
+      // Some uses of CodedInputStream can be more efficient if they know
+      // exactly how many bytes are available.  By pushing the end point of the
+      // buffer as a limit, we allow them to get this information via
+      // getBytesUntilLimit().  Pushing a limit that we know is at the end of
+      // the stream can never hurt, since we can never past that point anyway.
+      result.pushLimit(byteString.size());
+    } catch (InvalidProtocolBufferException ex) {
+      // The only reason pushLimit() might throw an exception here is if len
+      // is negative. Normally pushLimit()'s parameter comes directly off the
+      // wire, so it's important to catch exceptions in case of corrupt or
+      // malicious data. However, in this case, we expect that len is not a
+      // user-supplied value, so we can assume that it being negative indicates
+      // a programming error. Therefore, throwing an unchecked exception is
+      // appropriate.
+      throw new IllegalArgumentException(ex);
+    }
+    return result;
+  }
+
+  // -----------------------------------------------------------------
+
+  /**
+   * Attempt to read a field tag, returning zero if we have reached EOF.
+   * Protocol message parsers use this to read tags, since a protocol message
+   * may legally end wherever a tag occurs, and zero is not a valid tag number.
+   */
+  public int readTag() throws IOException {
+    if (isAtEnd()) {
+      lastTag = 0;
+      return 0;
+    }
+
+    lastTag = readRawVarint32();
+    if (WireFormat.getTagFieldNumber(lastTag) == 0) {
+      // If we actually read zero (or any tag number corresponding to field
+      // number zero), that's not a valid tag.
+      throw InvalidProtocolBufferException.invalidTag();
+    }
+    return lastTag;
+  }
+
+  /**
+   * Verifies that the last call to readTag() returned the given tag value.
+   * This is used to verify that a nested group ended with the correct
+   * end tag.
+   *
+   * @throws InvalidProtocolBufferException {@code value} does not match the
+   *                                        last tag.
+   */
+  public void checkLastTagWas(final int value)
+                              throws InvalidProtocolBufferException {
+    if (lastTag != value) {
+      throw InvalidProtocolBufferException.invalidEndTag();
+    }
+  }
+
+  public int getLastTag() {
+    return lastTag;
+  }
+
+  /**
+   * Reads and discards a single field, given its tag value.
+   *
+   * @return {@code false} if the tag is an endgroup tag, in which case
+   *         nothing is skipped.  Otherwise, returns {@code true}.
+   */
+  public boolean skipField(final int tag) throws IOException {
+    switch (WireFormat.getTagWireType(tag)) {
+      case WireFormat.WIRETYPE_VARINT:
+        skipRawVarint();
+        return true;
+      case WireFormat.WIRETYPE_FIXED64:
+        skipRawBytes(8);
+        return true;
+      case WireFormat.WIRETYPE_LENGTH_DELIMITED:
+        skipRawBytes(readRawVarint32());
+        return true;
+      case WireFormat.WIRETYPE_START_GROUP:
+        skipMessage();
+        checkLastTagWas(
+          WireFormat.makeTag(WireFormat.getTagFieldNumber(tag),
+                             WireFormat.WIRETYPE_END_GROUP));
+        return true;
+      case WireFormat.WIRETYPE_END_GROUP:
+        return false;
+      case WireFormat.WIRETYPE_FIXED32:
+        skipRawBytes(4);
+        return true;
+      default:
+        throw InvalidProtocolBufferException.invalidWireType();
+    }
+  }
+
+  /**
+   * Reads a single field and writes it to output in wire format,
+   * given its tag value.
+   *
+   * @return {@code false} if the tag is an endgroup tag, in which case
+   *         nothing is skipped.  Otherwise, returns {@code true}.
+   */
+  public boolean skipField(final int tag, final CodedOutputStream output)
+      throws IOException {
+    switch (WireFormat.getTagWireType(tag)) {
+      case WireFormat.WIRETYPE_VARINT: {
+        long value = readInt64();
+        output.writeRawVarint32(tag);
+        output.writeUInt64NoTag(value);
+        return true;
+      }
+      case WireFormat.WIRETYPE_FIXED64: {
+        long value = readRawLittleEndian64();
+        output.writeRawVarint32(tag);
+        output.writeFixed64NoTag(value);
+        return true;
+      }
+      case WireFormat.WIRETYPE_LENGTH_DELIMITED: {
+        ByteString value = readBytes();
+        output.writeRawVarint32(tag);
+        output.writeBytesNoTag(value);
+        return true;
+      }
+      case WireFormat.WIRETYPE_START_GROUP: {
+        output.writeRawVarint32(tag);
+        skipMessage(output);
+        int endtag = WireFormat.makeTag(WireFormat.getTagFieldNumber(tag),
+                                        WireFormat.WIRETYPE_END_GROUP);
+        checkLastTagWas(endtag);
+        output.writeRawVarint32(endtag);
+        return true;
+      }
+      case WireFormat.WIRETYPE_END_GROUP: {
+        return false;
+      }
+      case WireFormat.WIRETYPE_FIXED32: {
+        int value = readRawLittleEndian32();
+        output.writeRawVarint32(tag);
+        output.writeFixed32NoTag(value);
+        return true;
+      }
+      default:
+        throw InvalidProtocolBufferException.invalidWireType();
+    }
+  }
+
+  /**
+   * Reads and discards an entire message.  This will read either until EOF
+   * or until an endgroup tag, whichever comes first.
+   */
+  public void skipMessage() throws IOException {
+    while (true) {
+      final int tag = readTag();
+      if (tag == 0 || !skipField(tag)) {
+        return;
+      }
+    }
+  }
+
+  /**
+   * Reads an entire message and writes it to output in wire format.
+   * This will read either until EOF or until an endgroup tag,
+   * whichever comes first.
+   */
+  public void skipMessage(CodedOutputStream output) throws IOException {
+    while (true) {
+      final int tag = readTag();
+      if (tag == 0 || !skipField(tag, output)) {
+        return;
+      }
+    }
+  }
+
+  /**
+   * Collects the bytes skipped and returns the data in a ByteBuffer.
+   */
+  private class SkippedDataSink implements RefillCallback {
+    private int lastPos = bufferPos;
+    private ByteArrayOutputStream byteArrayStream;
+
+    @Override
+    public void onRefill() {
+      if (byteArrayStream == null) {
+        byteArrayStream = new ByteArrayOutputStream();
+      }
+      byteArrayStream.write(buffer, lastPos, bufferPos - lastPos);
+      lastPos = 0;
+    }
+
+    /**
+     * Gets skipped data in a ByteBuffer. This method should only be
+     * called once.
+     */
+    ByteBuffer getSkippedData() {
+      if (byteArrayStream == null) {
+        return ByteBuffer.wrap(buffer, lastPos, bufferPos - lastPos);
+      } else {
+        byteArrayStream.write(buffer, lastPos, bufferPos);
+        return ByteBuffer.wrap(byteArrayStream.toByteArray());
+      }
+    }
+  }
+
+
+  // -----------------------------------------------------------------
+
+  /** Read a {@code double} field value from the stream. */
+  public double readDouble() throws IOException {
+    return Double.longBitsToDouble(readRawLittleEndian64());
+  }
+
+  /** Read a {@code float} field value from the stream. */
+  public float readFloat() throws IOException {
+    return Float.intBitsToFloat(readRawLittleEndian32());
+  }
+
+  /** Read a {@code uint64} field value from the stream. */
+  public long readUInt64() throws IOException {
+    return readRawVarint64();
+  }
+
+  /** Read an {@code int64} field value from the stream. */
+  public long readInt64() throws IOException {
+    return readRawVarint64();
+  }
+
+  /** Read an {@code int32} field value from the stream. */
+  public int readInt32() throws IOException {
+    return readRawVarint32();
+  }
+
+  /** Read a {@code fixed64} field value from the stream. */
+  public long readFixed64() throws IOException {
+    return readRawLittleEndian64();
+  }
+
+  /** Read a {@code fixed32} field value from the stream. */
+  public int readFixed32() throws IOException {
+    return readRawLittleEndian32();
+  }
+
+  /** Read a {@code bool} field value from the stream. */
+  public boolean readBool() throws IOException {
+    return readRawVarint64() != 0;
+  }
+
+  /**
+   * Read a {@code string} field value from the stream.
+   * If the stream contains malformed UTF-8,
+   * replace the offending bytes with the standard UTF-8 replacement character.
+   */
+  public String readString() throws IOException {
+    final int size = readRawVarint32();
+    if (size <= (bufferSize - bufferPos) && size > 0) {
+      // Fast path:  We already have the bytes in a contiguous buffer, so
+      //   just copy directly from it.
+      final String result = new String(buffer, bufferPos, size, "UTF-8");
+      bufferPos += size;
+      return result;
+    } else if (size == 0) {
+      return "";
+    } else {
+      // Slow path:  Build a byte array first then copy it.
+      return new String(readRawBytesSlowPath(size), "UTF-8");
+    }
+  }
+
+  /**
+   * Read a {@code string} field value from the stream.
+   * If the stream contains malformed UTF-8,
+   * throw exception {@link InvalidProtocolBufferException}.
+   */
+  public String readStringRequireUtf8() throws IOException {
+    final int size = readRawVarint32();
+    final byte[] bytes;
+    int pos = bufferPos;
+    if (size <= (bufferSize - pos) && size > 0) {
+      // Fast path:  We already have the bytes in a contiguous buffer, so
+      //   just copy directly from it.
+      bytes = buffer;
+      bufferPos = pos + size;
+    } else if (size == 0) {
+      return "";
+    } else {
+      // Slow path:  Build a byte array first then copy it.
+      bytes = readRawBytesSlowPath(size);
+      pos = 0;
+    }
+    // TODO(martinrb): We could save a pass by validating while decoding.
+    if (!Utf8.isValidUtf8(bytes, pos, pos + size)) {
+      throw InvalidProtocolBufferException.invalidUtf8();
+    }
+    return new String(bytes, pos, size, "UTF-8");
+  }
+
+  /** Read a {@code group} field value from the stream. */
+  public void readGroup(final int fieldNumber,
+                        final MessageLite.Builder builder,
+                        final ExtensionRegistryLite extensionRegistry)
+      throws IOException {
+    if (recursionDepth >= recursionLimit) {
+      throw InvalidProtocolBufferException.recursionLimitExceeded();
+    }
+    ++recursionDepth;
+    builder.mergeFrom(this, extensionRegistry);
+    checkLastTagWas(
+      WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
+    --recursionDepth;
+  }
+
+
+  /** Read a {@code group} field value from the stream. */
+  public <T extends MessageLite> T readGroup(
+      final int fieldNumber,
+      final Parser<T> parser,
+      final ExtensionRegistryLite extensionRegistry)
+      throws IOException {
+    if (recursionDepth >= recursionLimit) {
+      throw InvalidProtocolBufferException.recursionLimitExceeded();
+    }
+    ++recursionDepth;
+    T result = parser.parsePartialFrom(this, extensionRegistry);
+    checkLastTagWas(
+      WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP));
+    --recursionDepth;
+    return result;
+  }
+
+  /**
+   * Reads a {@code group} field value from the stream and merges it into the
+   * given {@link UnknownFieldSet}.
+   *
+   * @deprecated UnknownFieldSet.Builder now implements MessageLite.Builder, so
+   *             you can just call {@link #readGroup}.
+   */
+  @Deprecated
+  public void readUnknownGroup(final int fieldNumber,
+                               final MessageLite.Builder builder)
+      throws IOException {
+    // We know that UnknownFieldSet will ignore any ExtensionRegistry so it
+    // is safe to pass null here.  (We can't call
+    // ExtensionRegistry.getEmptyRegistry() because that would make this
+    // class depend on ExtensionRegistry, which is not part of the lite
+    // library.)
+    readGroup(fieldNumber, builder, null);
+  }
+
+  /** Read an embedded message field value from the stream. */
+  public void readMessage(final MessageLite.Builder builder,
+                          final ExtensionRegistryLite extensionRegistry)
+      throws IOException {
+    final int length = readRawVarint32();
+    if (recursionDepth >= recursionLimit) {
+      throw InvalidProtocolBufferException.recursionLimitExceeded();
+    }
+    final int oldLimit = pushLimit(length);
+    ++recursionDepth;
+    builder.mergeFrom(this, extensionRegistry);
+    checkLastTagWas(0);
+    --recursionDepth;
+    popLimit(oldLimit);
+  }
+
+
+  /** Read an embedded message field value from the stream. */
+  public <T extends MessageLite> T readMessage(
+      final Parser<T> parser,
+      final ExtensionRegistryLite extensionRegistry)
+      throws IOException {
+    int length = readRawVarint32();
+    if (recursionDepth >= recursionLimit) {
+      throw InvalidProtocolBufferException.recursionLimitExceeded();
+    }
+    final int oldLimit = pushLimit(length);
+    ++recursionDepth;
+    T result = parser.parsePartialFrom(this, extensionRegistry);
+    checkLastTagWas(0);
+    --recursionDepth;
+    popLimit(oldLimit);
+    return result;
+  }
+
+  /** Read a {@code bytes} field value from the stream. */
+  public ByteString readBytes() throws IOException {
+    final int size = readRawVarint32();
+    if (size <= (bufferSize - bufferPos) && size > 0) {
+      // Fast path:  We already have the bytes in a contiguous buffer, so
+      //   just copy directly from it.
+      final ByteString result = bufferIsImmutable && enableAliasing
+          ? new BoundedByteString(buffer, bufferPos, size)
+          : ByteString.copyFrom(buffer, bufferPos, size);
+      bufferPos += size;
+      return result;
+    } else if (size == 0) {
+      return ByteString.EMPTY;
+    } else {
+      // Slow path:  Build a byte array first then copy it.
+      return new LiteralByteString(readRawBytesSlowPath(size));
+    }
+  }
+
+  /** Read a {@code bytes} field value from the stream. */
+  public byte[] readByteArray() throws IOException {
+    final int size = readRawVarint32();
+    if (size <= (bufferSize - bufferPos) && size > 0) {
+      // Fast path: We already have the bytes in a contiguous buffer, so
+      // just copy directly from it.
+      final byte[] result =
+          Arrays.copyOfRange(buffer, bufferPos, bufferPos + size);
+      bufferPos += size;
+      return result;
+    } else {
+      // Slow path: Build a byte array first then copy it.
+      return readRawBytesSlowPath(size);
+    }
+  }
+
+  /** Read a {@code bytes} field value from the stream. */
+  public ByteBuffer readByteBuffer() throws IOException {
+    final int size = readRawVarint32();
+    if (size <= (bufferSize - bufferPos) && size > 0) {
+      // Fast path: We already have the bytes in a contiguous buffer.
+      // When aliasing is enabled, we can return a ByteBuffer pointing directly
+      // into the underlying byte array without copy if the CodedInputStream is
+      // constructed from a byte array. If aliasing is disabled or the input is
+      // from an InputStream or ByteString, we have to make a copy of the bytes.
+      ByteBuffer result = input == null && !bufferIsImmutable && enableAliasing
+          ? ByteBuffer.wrap(buffer, bufferPos, size).slice()
+          : ByteBuffer.wrap(Arrays.copyOfRange(
+              buffer, bufferPos, bufferPos + size));
+      bufferPos += size;
+      return result;
+    } else if (size == 0) {
+      return Internal.EMPTY_BYTE_BUFFER;
+    } else {
+      // Slow path: Build a byte array first then copy it.
+      return ByteBuffer.wrap(readRawBytesSlowPath(size));
+    }
+  }
+
+  /** Read a {@code uint32} field value from the stream. */
+  public int readUInt32() throws IOException {
+    return readRawVarint32();
+  }
+
+  /**
+   * Read an enum field value from the stream.  Caller is responsible
+   * for converting the numeric value to an actual enum.
+   */
+  public int readEnum() throws IOException {
+    return readRawVarint32();
+  }
+
+  /** Read an {@code sfixed32} field value from the stream. */
+  public int readSFixed32() throws IOException {
+    return readRawLittleEndian32();
+  }
+
+  /** Read an {@code sfixed64} field value from the stream. */
+  public long readSFixed64() throws IOException {
+    return readRawLittleEndian64();
+  }
+
+  /** Read an {@code sint32} field value from the stream. */
+  public int readSInt32() throws IOException {
+    return decodeZigZag32(readRawVarint32());
+  }
+
+  /** Read an {@code sint64} field value from the stream. */
+  public long readSInt64() throws IOException {
+    return decodeZigZag64(readRawVarint64());
+  }
+
+  // =================================================================
+
+  /**
+   * Read a raw Varint from the stream.  If larger than 32 bits, discard the
+   * upper bits.
+   */
+  public int readRawVarint32() throws IOException {
+    // See implementation notes for readRawVarint64
+ fastpath: {
+      int pos = bufferPos;
+
+      if (bufferSize == pos) {
+        break fastpath;
+      }
+
+      final byte[] buffer = this.buffer;
+      int x;
+      if ((x = buffer[pos++]) >= 0) {
+        bufferPos = pos;
+        return x;
+      } else if (bufferSize - pos < 9) {
+        break fastpath;
+      } else if ((x ^= (buffer[pos++] << 7)) < 0L) {
+        x ^= (~0L << 7);
+      } else if ((x ^= (buffer[pos++] << 14)) >= 0L) {
+        x ^= (~0L << 7) ^ (~0L << 14);
+      } else if ((x ^= (buffer[pos++] << 21)) < 0L) {
+        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21);
+      } else {
+        int y = buffer[pos++];
+        x ^= y << 28;
+        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
+        if (y < 0 &&
+            buffer[pos++] < 0 &&
+            buffer[pos++] < 0 &&
+            buffer[pos++] < 0 &&
+            buffer[pos++] < 0 &&
+            buffer[pos++] < 0) {
+          break fastpath;  // Will throw malformedVarint()
+        }
+      }
+      bufferPos = pos;
+      return x;
+    }
+    return (int) readRawVarint64SlowPath();
+  }
+
+  private void skipRawVarint() throws IOException {
+    if (bufferSize - bufferPos >= 10) {
+      final byte[] buffer = this.buffer;
+      int pos = bufferPos;
+      for (int i = 0; i < 10; i++) {
+        if (buffer[pos++] >= 0) {
+          bufferPos = pos;
+          return;
+        }
+      }
+    }
+    skipRawVarintSlowPath();
+  }
+
+  private void skipRawVarintSlowPath() throws IOException {
+    for (int i = 0; i < 10; i++) {
+      if (readRawByte() >= 0) {
+        return;
+      }
+    }
+    throw InvalidProtocolBufferException.malformedVarint();
+  }
+
+  /**
+   * Reads a varint from the input one byte at a time, so that it does not
+   * read any bytes after the end of the varint.  If you simply wrapped the
+   * stream in a CodedInputStream and used {@link #readRawVarint32(InputStream)}
+   * then you would probably end up reading past the end of the varint since
+   * CodedInputStream buffers its input.
+   */
+  static int readRawVarint32(final InputStream input) throws IOException {
+    final int firstByte = input.read();
+    if (firstByte == -1) {
+      throw InvalidProtocolBufferException.truncatedMessage();
+    }
+    return readRawVarint32(firstByte, input);
+  }
+
+  /**
+   * Like {@link #readRawVarint32(InputStream)}, but expects that the caller
+   * has already read one byte.  This allows the caller to determine if EOF
+   * has been reached before attempting to read.
+   */
+  public static int readRawVarint32(
+      final int firstByte, final InputStream input) throws IOException {
+    if ((firstByte & 0x80) == 0) {
+      return firstByte;
+    }
+
+    int result = firstByte & 0x7f;
+    int offset = 7;
+    for (; offset < 32; offset += 7) {
+      final int b = input.read();
+      if (b == -1) {
+        throw InvalidProtocolBufferException.truncatedMessage();
+      }
+      result |= (b & 0x7f) << offset;
+      if ((b & 0x80) == 0) {
+        return result;
+      }
+    }
+    // Keep reading up to 64 bits.
+    for (; offset < 64; offset += 7) {
+      final int b = input.read();
+      if (b == -1) {
+        throw InvalidProtocolBufferException.truncatedMessage();
+      }
+      if ((b & 0x80) == 0) {
+        return result;
+      }
+    }
+    throw InvalidProtocolBufferException.malformedVarint();
+  }
+
+  /** Read a raw Varint from the stream. */
+  public long readRawVarint64() throws IOException {
+    // Implementation notes:
+    //
+    // Optimized for one-byte values, expected to be common.
+    // The particular code below was selected from various candidates
+    // empirically, by winning VarintBenchmark.
+    //
+    // Sign extension of (signed) Java bytes is usually a nuisance, but
+    // we exploit it here to more easily obtain the sign of bytes read.
+    // Instead of cleaning up the sign extension bits by masking eagerly,
+    // we delay until we find the final (positive) byte, when we clear all
+    // accumulated bits with one xor.  We depend on javac to constant fold.
+ fastpath: {
+      int pos = bufferPos;
+
+      if (bufferSize == pos) {
+        break fastpath;
+      }
+
+      final byte[] buffer = this.buffer;
+      long x;
+      int y;
+      if ((y = buffer[pos++]) >= 0) {
+        bufferPos = pos;
+        return y;
+      } else if (bufferSize - pos < 9) {
+        break fastpath;
+      } else if ((x = y ^ (buffer[pos++] << 7)) < 0L) {
+        x ^= (~0L << 7);
+      } else if ((x ^= (buffer[pos++] << 14)) >= 0L) {
+        x ^= (~0L << 7) ^ (~0L << 14);
+      } else if ((x ^= (buffer[pos++] << 21)) < 0L) {
+        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21);
+      } else if ((x ^= ((long) buffer[pos++] << 28)) >= 0L) {
+        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28);
+      } else if ((x ^= ((long) buffer[pos++] << 35)) < 0L) {
+        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35);
+      } else if ((x ^= ((long) buffer[pos++] << 42)) >= 0L) {
+        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42);
+      } else if ((x ^= ((long) buffer[pos++] << 49)) < 0L) {
+        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42)
+            ^ (~0L << 49);
+      } else {
+        x ^= ((long) buffer[pos++] << 56);
+        x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42)
+            ^ (~0L << 49) ^ (~0L << 56);
+        if (x < 0L) {
+          if (buffer[pos++] < 0L) {
+            break fastpath;  // Will throw malformedVarint()
+          }
+        }
+      }
+      bufferPos = pos;
+      return x;
+    }
+    return readRawVarint64SlowPath();
+  }
+
+  /** Variant of readRawVarint64 for when uncomfortably close to the limit. */
+  /* Visible for testing */
+  long readRawVarint64SlowPath() throws IOException {
+    long result = 0;
+    for (int shift = 0; shift < 64; shift += 7) {
+      final byte b = readRawByte();
+      result |= (long) (b & 0x7F) << shift;
+      if ((b & 0x80) == 0) {
+        return result;
+      }
+    }
+    throw InvalidProtocolBufferException.malformedVarint();
+  }
+
+  /** Read a 32-bit little-endian integer from the stream. */
+  public int readRawLittleEndian32() throws IOException {
+    int pos = bufferPos;
+
+    // hand-inlined ensureAvailable(4);
+    if (bufferSize - pos < 4) {
+      refillBuffer(4);
+      pos = bufferPos;
+    }
+
+    final byte[] buffer = this.buffer;
+    bufferPos = pos + 4;
+    return (((buffer[pos]     & 0xff))       |
+            ((buffer[pos + 1] & 0xff) <<  8) |
+            ((buffer[pos + 2] & 0xff) << 16) |
+            ((buffer[pos + 3] & 0xff) << 24));
+  }
+
+  /** Read a 64-bit little-endian integer from the stream. */
+  public long readRawLittleEndian64() throws IOException {
+    int pos = bufferPos;
+
+    // hand-inlined ensureAvailable(8);
+    if (bufferSize - pos < 8) {
+      refillBuffer(8);
+      pos = bufferPos;
+    }
+
+    final byte[] buffer = this.buffer;
+    bufferPos = pos + 8;
+    return ((((long) buffer[pos]     & 0xffL))       |
+            (((long) buffer[pos + 1] & 0xffL) <<  8) |
+            (((long) buffer[pos + 2] & 0xffL) << 16) |
+            (((long) buffer[pos + 3] & 0xffL) << 24) |
+            (((long) buffer[pos + 4] & 0xffL) << 32) |
+            (((long) buffer[pos + 5] & 0xffL) << 40) |
+            (((long) buffer[pos + 6] & 0xffL) << 48) |
+            (((long) buffer[pos + 7] & 0xffL) << 56));
+  }
+
+  /**
+   * Decode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n An unsigned 32-bit integer, stored in a signed int because
+   *          Java has no explicit unsigned support.
+   * @return A signed 32-bit integer.
+   */
+  public static int decodeZigZag32(final int n) {
+    return (n >>> 1) ^ -(n & 1);
+  }
+
+  /**
+   * Decode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n An unsigned 64-bit integer, stored in a signed int because
+   *          Java has no explicit unsigned support.
+   * @return A signed 64-bit integer.
+   */
+  public static long decodeZigZag64(final long n) {
+    return (n >>> 1) ^ -(n & 1);
+  }
+
+  // -----------------------------------------------------------------
+
+  private final byte[] buffer;
+  private final boolean bufferIsImmutable;
+  private int bufferSize;
+  private int bufferSizeAfterLimit;
+  private int bufferPos;
+  private final InputStream input;
+  private int lastTag;
+  private boolean enableAliasing = false;
+
+  /**
+   * The total number of bytes read before the current buffer.  The total
+   * bytes read up to the current position can be computed as
+   * {@code totalBytesRetired + bufferPos}.  This value may be negative if
+   * reading started in the middle of the current buffer (e.g. if the
+   * constructor that takes a byte array and an offset was used).
+   */
+  private int totalBytesRetired;
+
+  /** The absolute position of the end of the current message. */
+  private int currentLimit = Integer.MAX_VALUE;
+
+  /** See setRecursionLimit() */
+  private int recursionDepth;
+  private int recursionLimit = DEFAULT_RECURSION_LIMIT;
+
+  /** See setSizeLimit() */
+  private int sizeLimit = DEFAULT_SIZE_LIMIT;
+
+  private static final int DEFAULT_RECURSION_LIMIT = 64;
+  private static final int DEFAULT_SIZE_LIMIT = 64 << 20;  // 64MB
+  private static final int BUFFER_SIZE = 4096;
+
+  private CodedInputStream(final byte[] buffer, final int off, final int len) {
+    this.buffer = buffer;
+    bufferSize = off + len;
+    bufferPos = off;
+    totalBytesRetired = -off;
+    input = null;
+    bufferIsImmutable = false;
+  }
+
+  private CodedInputStream(final InputStream input) {
+    buffer = new byte[BUFFER_SIZE];
+    bufferSize = 0;
+    bufferPos = 0;
+    totalBytesRetired = 0;
+    this.input = input;
+    bufferIsImmutable = false;
+  }
+
+  private CodedInputStream(final LiteralByteString byteString) {
+    buffer = byteString.bytes;
+    bufferPos = byteString.getOffsetIntoBytes();
+    bufferSize = bufferPos + byteString.size();
+    totalBytesRetired = -bufferPos;
+    input = null;
+    bufferIsImmutable = true;
+  }
+
+  public void enableAliasing(boolean enabled) {
+    this.enableAliasing = enabled;
+  }
+
+  /**
+   * Set the maximum message recursion depth.  In order to prevent malicious
+   * messages from causing stack overflows, {@code CodedInputStream} limits
+   * how deeply messages may be nested.  The default limit is 64.
+   *
+   * @return the old limit.
+   */
+  public int setRecursionLimit(final int limit) {
+    if (limit < 0) {
+      throw new IllegalArgumentException(
+        "Recursion limit cannot be negative: " + limit);
+    }
+    final int oldLimit = recursionLimit;
+    recursionLimit = limit;
+    return oldLimit;
+  }
+
+  /**
+   * Set the maximum message size.  In order to prevent malicious
+   * messages from exhausting memory or causing integer overflows,
+   * {@code CodedInputStream} limits how large a message may be.
+   * The default limit is 64MB.  You should set this limit as small
+   * as you can without harming your app's functionality.  Note that
+   * size limits only apply when reading from an {@code InputStream}, not
+   * when constructed around a raw byte array (nor with
+   * {@link ByteString#newCodedInput}).
+   * <p>
+   * If you want to read several messages from a single CodedInputStream, you
+   * could call {@link #resetSizeCounter()} after each one to avoid hitting the
+   * size limit.
+   *
+   * @return the old limit.
+   */
+  public int setSizeLimit(final int limit) {
+    if (limit < 0) {
+      throw new IllegalArgumentException(
+        "Size limit cannot be negative: " + limit);
+    }
+    final int oldLimit = sizeLimit;
+    sizeLimit = limit;
+    return oldLimit;
+  }
+
+  /**
+   * Resets the current size counter to zero (see {@link #setSizeLimit(int)}).
+   */
+  public void resetSizeCounter() {
+    totalBytesRetired = -bufferPos;
+  }
+
+  /**
+   * Sets {@code currentLimit} to (current position) + {@code byteLimit}.  This
+   * is called when descending into a length-delimited embedded message.
+   *
+   * <p>Note that {@code pushLimit()} does NOT affect how many bytes the
+   * {@code CodedInputStream} reads from an underlying {@code InputStream} when
+   * refreshing its buffer.  If you need to prevent reading past a certain
+   * point in the underlying {@code InputStream} (e.g. because you expect it to
+   * contain more data after the end of the message which you need to handle
+   * differently) then you must place a wrapper around your {@code InputStream}
+   * which limits the amount of data that can be read from it.
+   *
+   * @return the old limit.
+   */
+  public int pushLimit(int byteLimit) throws InvalidProtocolBufferException {
+    if (byteLimit < 0) {
+      throw InvalidProtocolBufferException.negativeSize();
+    }
+    byteLimit += totalBytesRetired + bufferPos;
+    final int oldLimit = currentLimit;
+    if (byteLimit > oldLimit) {
+      throw InvalidProtocolBufferException.truncatedMessage();
+    }
+    currentLimit = byteLimit;
+
+    recomputeBufferSizeAfterLimit();
+
+    return oldLimit;
+  }
+
+  private void recomputeBufferSizeAfterLimit() {
+    bufferSize += bufferSizeAfterLimit;
+    final int bufferEnd = totalBytesRetired + bufferSize;
+    if (bufferEnd > currentLimit) {
+      // Limit is in current buffer.
+      bufferSizeAfterLimit = bufferEnd - currentLimit;
+      bufferSize -= bufferSizeAfterLimit;
+    } else {
+      bufferSizeAfterLimit = 0;
+    }
+  }
+
+  /**
+   * Discards the current limit, returning to the previous limit.
+   *
+   * @param oldLimit The old limit, as returned by {@code pushLimit}.
+   */
+  public void popLimit(final int oldLimit) {
+    currentLimit = oldLimit;
+    recomputeBufferSizeAfterLimit();
+  }
+
+  /**
+   * Returns the number of bytes to be read before the current limit.
+   * If no limit is set, returns -1.
+   */
+  public int getBytesUntilLimit() {
+    if (currentLimit == Integer.MAX_VALUE) {
+      return -1;
+    }
+
+    final int currentAbsolutePosition = totalBytesRetired + bufferPos;
+    return currentLimit - currentAbsolutePosition;
+  }
+
+  /**
+   * Returns true if the stream has reached the end of the input.  This is the
+   * case if either the end of the underlying input source has been reached or
+   * if the stream has reached a limit created using {@link #pushLimit(int)}.
+   */
+  public boolean isAtEnd() throws IOException {
+    return bufferPos == bufferSize && !tryRefillBuffer(1);
+  }
+
+  /**
+   * The total bytes read up to the current position. Calling
+   * {@link #resetSizeCounter()} resets this value to zero.
+   */
+  public int getTotalBytesRead() {
+      return totalBytesRetired + bufferPos;
+  }
+
+  private interface RefillCallback {
+    void onRefill();
+  }
+
+  private RefillCallback refillCallback = null;
+
+  /**
+   * Ensures that at least {@code n} bytes are available in the buffer, reading
+   * more bytes from the input if necessary to make it so.  Caller must ensure
+   * that the requested space is less than BUFFER_SIZE.
+   *
+   * @throws InvalidProtocolBufferException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  private void ensureAvailable(int n) throws IOException {
+    if (bufferSize - bufferPos < n) {
+      refillBuffer(n);
+    }
+  }
+
+  /**
+   * Reads more bytes from the input, making at least {@code n} bytes available
+   * in the buffer.  Caller must ensure that the requested space is not yet
+   * available, and that the requested space is less than BUFFER_SIZE.
+   *
+   * @throws InvalidProtocolBufferException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  private void refillBuffer(int n) throws IOException {
+    if (!tryRefillBuffer(n)) {
+      throw InvalidProtocolBufferException.truncatedMessage();
+    }
+  }
+
+  /**
+   * Tries to read more bytes from the input, making at least {@code n} bytes
+   * available in the buffer.  Caller must ensure that the requested space is
+   * not yet available, and that the requested space is less than BUFFER_SIZE.
+   *
+   * @return {@code true} if the bytes could be made available; {@code false}
+   *         if the end of the stream or the current limit was reached.
+   */
+  private boolean tryRefillBuffer(int n) throws IOException {
+    if (bufferPos + n <= bufferSize) {
+      throw new IllegalStateException(
+          "refillBuffer() called when " + n +
+          " bytes were already available in buffer");
+    }
+
+    if (totalBytesRetired + bufferPos + n > currentLimit) {
+      // Oops, we hit a limit.
+      return false;
+    }
+
+    if (refillCallback != null) {
+      refillCallback.onRefill();
+    }
+
+    if (input != null) {
+      int pos = bufferPos;
+      if (pos > 0) {
+        if (bufferSize > pos) {
+          System.arraycopy(buffer, pos, buffer, 0, bufferSize - pos);
+        }
+        totalBytesRetired += pos;
+        bufferSize -= pos;
+        bufferPos = 0;
+      }
+
+      int bytesRead = input.read(buffer, bufferSize, buffer.length - bufferSize);
+      if (bytesRead == 0 || bytesRead < -1 || bytesRead > buffer.length) {
+        throw new IllegalStateException(
+            "InputStream#read(byte[]) returned invalid result: " + bytesRead +
+            "\nThe InputStream implementation is buggy.");
+      }
+      if (bytesRead > 0) {
+        bufferSize += bytesRead;
+        // Integer-overflow-conscious check against sizeLimit
+        if (totalBytesRetired + n - sizeLimit > 0) {
+          throw InvalidProtocolBufferException.sizeLimitExceeded();
+        }
+        recomputeBufferSizeAfterLimit();
+        return (bufferSize >= n) ? true : tryRefillBuffer(n);
+      }
+    }
+
+    return false;
+  }
+
+  /**
+   * Read one byte from the input.
+   *
+   * @throws InvalidProtocolBufferException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  public byte readRawByte() throws IOException {
+    if (bufferPos == bufferSize) {
+      refillBuffer(1);
+    }
+    return buffer[bufferPos++];
+  }
+
+  /**
+   * Read a fixed size of bytes from the input.
+   *
+   * @throws InvalidProtocolBufferException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  public byte[] readRawBytes(final int size) throws IOException {
+    final int pos = bufferPos;
+    if (size <= (bufferSize - pos) && size > 0) {
+      bufferPos = pos + size;
+      return Arrays.copyOfRange(buffer, pos, pos + size);
+    } else {
+      return readRawBytesSlowPath(size);
+    }
+  }
+
+  /**
+   * Exactly like readRawBytes, but caller must have already checked the fast
+   * path: (size <= (bufferSize - pos) && size > 0)
+   */
+  private byte[] readRawBytesSlowPath(final int size) throws IOException {
+    if (size <= 0) {
+      if (size == 0) {
+        return Internal.EMPTY_BYTE_ARRAY;
+      } else {
+        throw InvalidProtocolBufferException.negativeSize();
+      }
+    }
+
+    if (totalBytesRetired + bufferPos + size > currentLimit) {
+      // Read to the end of the stream anyway.
+      skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+      // Then fail.
+      throw InvalidProtocolBufferException.truncatedMessage();
+    }
+
+    if (size < BUFFER_SIZE) {
+      // Reading more bytes than are in the buffer, but not an excessive number
+      // of bytes.  We can safely allocate the resulting array ahead of time.
+
+      // First copy what we have.
+      final byte[] bytes = new byte[size];
+      int pos = bufferSize - bufferPos;
+      System.arraycopy(buffer, bufferPos, bytes, 0, pos);
+      bufferPos = bufferSize;
+
+      // We want to refill the buffer and then copy from the buffer into our
+      // byte array rather than reading directly into our byte array because
+      // the input may be unbuffered.
+      ensureAvailable(size - pos);
+      System.arraycopy(buffer, 0, bytes, pos, size - pos);
+      bufferPos = size - pos;
+
+      return bytes;
+    } else {
+      // The size is very large.  For security reasons, we can't allocate the
+      // entire byte array yet.  The size comes directly from the input, so a
+      // maliciously-crafted message could provide a bogus very large size in
+      // order to trick the app into allocating a lot of memory.  We avoid this
+      // by allocating and reading only a small chunk at a time, so that the
+      // malicious message must actually *be* extremely large to cause
+      // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
+
+      // Remember the buffer markers since we'll have to copy the bytes out of
+      // it later.
+      final int originalBufferPos = bufferPos;
+      final int originalBufferSize = bufferSize;
+
+      // Mark the current buffer consumed.
+      totalBytesRetired += bufferSize;
+      bufferPos = 0;
+      bufferSize = 0;
+
+      // Read all the rest of the bytes we need.
+      int sizeLeft = size - (originalBufferSize - originalBufferPos);
+      final List<byte[]> chunks = new ArrayList<byte[]>();
+
+      while (sizeLeft > 0) {
+        final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)];
+        int pos = 0;
+        while (pos < chunk.length) {
+          final int n = (input == null) ? -1 :
+            input.read(chunk, pos, chunk.length - pos);
+          if (n == -1) {
+            throw InvalidProtocolBufferException.truncatedMessage();
+          }
+          totalBytesRetired += n;
+          pos += n;
+        }
+        sizeLeft -= chunk.length;
+        chunks.add(chunk);
+      }
+
+      // OK, got everything.  Now concatenate it all into one buffer.
+      final byte[] bytes = new byte[size];
+
+      // Start by copying the leftover bytes from this.buffer.
+      int pos = originalBufferSize - originalBufferPos;
+      System.arraycopy(buffer, originalBufferPos, bytes, 0, pos);
+
+      // And now all the chunks.
+      for (final byte[] chunk : chunks) {
+        System.arraycopy(chunk, 0, bytes, pos, chunk.length);
+        pos += chunk.length;
+      }
+
+      // Done.
+      return bytes;
+    }
+  }
+
+  /**
+   * Reads and discards {@code size} bytes.
+   *
+   * @throws InvalidProtocolBufferException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  public void skipRawBytes(final int size) throws IOException {
+    if (size <= (bufferSize - bufferPos) && size >= 0) {
+      // We have all the bytes we need already.
+      bufferPos += size;
+    } else {
+      skipRawBytesSlowPath(size);
+    }
+  }
+
+  /**
+   * Exactly like skipRawBytes, but caller must have already checked the fast
+   * path: (size <= (bufferSize - pos) && size >= 0)
+   */
+  private void skipRawBytesSlowPath(final int size) throws IOException {
+    if (size < 0) {
+      throw InvalidProtocolBufferException.negativeSize();
+    }
+
+    if (totalBytesRetired + bufferPos + size > currentLimit) {
+      // Read to the end of the stream anyway.
+      skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+      // Then fail.
+      throw InvalidProtocolBufferException.truncatedMessage();
+    }
+
+    // Skipping more bytes than are in the buffer.  First skip what we have.
+    int pos = bufferSize - bufferPos;
+    bufferPos = bufferSize;
+
+    // Keep refilling the buffer until we get to the point we wanted to skip to.
+    // This has the side effect of ensuring the limits are updated correctly.
+    refillBuffer(1);
+    while (size - pos > bufferSize) {
+      pos += bufferSize;
+      bufferPos = bufferSize;
+      refillBuffer(1);
+    }
+
+    bufferPos = size - pos;
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/CodedOutputStream.java b/protobuf/java/src/main/java/com/google/protobuf/CodedOutputStream.java
new file mode 100644
index 0000000..fafe035
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/CodedOutputStream.java
@@ -0,0 +1,1297 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+
+/**
+ * Encodes and writes protocol message fields.
+ *
+ * <p>This class contains two kinds of methods:  methods that write specific
+ * protocol message constructs and field types (e.g. {@link #writeTag} and
+ * {@link #writeInt32}) and methods that write low-level values (e.g.
+ * {@link #writeRawVarint32} and {@link #writeRawBytes}).  If you are
+ * writing encoded protocol messages, you should use the former methods, but if
+ * you are writing some other format of your own design, use the latter.
+ *
+ * <p>This class is totally unsynchronized.
+ *
+ * @author kneton@google.com Kenton Varda
+ */
+public final class CodedOutputStream {
+  private final byte[] buffer;
+  private final int limit;
+  private int position;
+  private int totalBytesWritten = 0;
+
+  private final OutputStream output;
+
+  /**
+   * The buffer size used in {@link #newInstance(OutputStream)}.
+   */
+  public static final int DEFAULT_BUFFER_SIZE = 4096;
+
+  /**
+   * Returns the buffer size to efficiently write dataLength bytes to this
+   * CodedOutputStream. Used by AbstractMessageLite.
+   *
+   * @return the buffer size to efficiently write dataLength bytes to this
+   *         CodedOutputStream.
+   */
+  static int computePreferredBufferSize(int dataLength) {
+    if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE;
+    return dataLength;
+  }
+
+  private CodedOutputStream(final byte[] buffer, final int offset,
+                            final int length) {
+    output = null;
+    this.buffer = buffer;
+    position = offset;
+    limit = offset + length;
+  }
+
+  private CodedOutputStream(final OutputStream output, final byte[] buffer) {
+    this.output = output;
+    this.buffer = buffer;
+    position = 0;
+    limit = buffer.length;
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} wrapping the given
+   * {@code OutputStream}.
+   */
+  public static CodedOutputStream newInstance(final OutputStream output) {
+    return newInstance(output, DEFAULT_BUFFER_SIZE);
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} wrapping the given
+   * {@code OutputStream} with a given buffer size.
+   */
+  public static CodedOutputStream newInstance(final OutputStream output,
+      final int bufferSize) {
+    return new CodedOutputStream(output, new byte[bufferSize]);
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} that writes directly to the given
+   * byte array.  If more bytes are written than fit in the array,
+   * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
+   * array is faster than writing to an {@code OutputStream}.  See also
+   * {@link ByteString#newCodedBuilder}.
+   */
+  public static CodedOutputStream newInstance(final byte[] flatArray) {
+    return newInstance(flatArray, 0, flatArray.length);
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} that writes directly to the given
+   * byte array slice.  If more bytes are written than fit in the slice,
+   * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
+   * array is faster than writing to an {@code OutputStream}.  See also
+   * {@link ByteString#newCodedBuilder}.
+   */
+  public static CodedOutputStream newInstance(final byte[] flatArray,
+                                              final int offset,
+                                              final int length) {
+    return new CodedOutputStream(flatArray, offset, length);
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} that writes to the given ByteBuffer.
+   */
+  public static CodedOutputStream newInstance(ByteBuffer byteBuffer) {
+    return newInstance(byteBuffer, DEFAULT_BUFFER_SIZE);
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} that writes to the given ByteBuffer.
+   */
+  public static CodedOutputStream newInstance(ByteBuffer byteBuffer,
+      int bufferSize) {
+    return newInstance(new ByteBufferOutputStream(byteBuffer), bufferSize);
+  }
+  
+  private static class ByteBufferOutputStream extends OutputStream {
+    private final ByteBuffer byteBuffer;
+    public ByteBufferOutputStream(ByteBuffer byteBuffer) {
+      this.byteBuffer = byteBuffer;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+      byteBuffer.put((byte) b);
+    }
+
+    @Override
+    public void write(byte[] data, int offset, int length) throws IOException {
+      byteBuffer.put(data, offset, length);
+    }
+  }
+
+  // -----------------------------------------------------------------
+
+  /** Write a {@code double} field, including tag, to the stream. */
+  public void writeDouble(final int fieldNumber, final double value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+    writeDoubleNoTag(value);
+  }
+
+  /** Write a {@code float} field, including tag, to the stream. */
+  public void writeFloat(final int fieldNumber, final float value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+    writeFloatNoTag(value);
+  }
+
+  /** Write a {@code uint64} field, including tag, to the stream. */
+  public void writeUInt64(final int fieldNumber, final long value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+    writeUInt64NoTag(value);
+  }
+
+  /** Write an {@code int64} field, including tag, to the stream. */
+  public void writeInt64(final int fieldNumber, final long value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+    writeInt64NoTag(value);
+  }
+
+  /** Write an {@code int32} field, including tag, to the stream. */
+  public void writeInt32(final int fieldNumber, final int value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+    writeInt32NoTag(value);
+  }
+
+  /** Write a {@code fixed64} field, including tag, to the stream. */
+  public void writeFixed64(final int fieldNumber, final long value)
+                           throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+    writeFixed64NoTag(value);
+  }
+
+  /** Write a {@code fixed32} field, including tag, to the stream. */
+  public void writeFixed32(final int fieldNumber, final int value)
+                           throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+    writeFixed32NoTag(value);
+  }
+
+  /** Write a {@code bool} field, including tag, to the stream. */
+  public void writeBool(final int fieldNumber, final boolean value)
+                        throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+    writeBoolNoTag(value);
+  }
+
+  /** Write a {@code string} field, including tag, to the stream. */
+  public void writeString(final int fieldNumber, final String value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+    writeStringNoTag(value);
+  }
+
+  /** Write a {@code group} field, including tag, to the stream. */
+  public void writeGroup(final int fieldNumber, final MessageLite value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
+    writeGroupNoTag(value);
+    writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
+  }
+
+
+  /**
+   * Write a group represented by an {@link UnknownFieldSet}.
+   *
+   * @deprecated UnknownFieldSet now implements MessageLite, so you can just
+   *             call {@link #writeGroup}.
+   */
+  @Deprecated
+  public void writeUnknownGroup(final int fieldNumber,
+                                final MessageLite value)
+                                throws IOException {
+    writeGroup(fieldNumber, value);
+  }
+
+  /** Write an embedded message field, including tag, to the stream. */
+  public void writeMessage(final int fieldNumber, final MessageLite value)
+                           throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+    writeMessageNoTag(value);
+  }
+
+
+  /** Write a {@code bytes} field, including tag, to the stream. */
+  public void writeBytes(final int fieldNumber, final ByteString value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+    writeBytesNoTag(value);
+  }
+
+  /** Write a {@code bytes} field, including tag, to the stream. */
+  public void writeByteArray(final int fieldNumber, final byte[] value)
+                             throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+    writeByteArrayNoTag(value);
+  }
+
+  /** Write a {@code bytes} field, including tag, to the stream. */
+  public void writeByteArray(final int fieldNumber,
+                             final byte[] value,
+                             final int offset,
+                             final int length)
+                             throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+    writeByteArrayNoTag(value, offset, length);
+  }
+
+  /**
+   * Write a {@code bytes} field, including tag, to the stream.
+   * This method will write all content of the ByteBuffer regardless of the
+   * current position and limit (i.e., the number of bytes to be written is
+   * value.capacity(), not value.remaining()). Furthermore, this method doesn't
+   * alter the state of the passed-in ByteBuffer. Its position, limit, mark,
+   * etc. will remain unchanged. If you only want to write the remaining bytes
+   * of a ByteBuffer, you can call
+   * {@code writeByteBuffer(fieldNumber, byteBuffer.slice())}.
+   */
+  public void writeByteBuffer(final int fieldNumber, final ByteBuffer value)
+      throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+    writeByteBufferNoTag(value);
+  }
+
+  /** Write a {@code uint32} field, including tag, to the stream. */
+  public void writeUInt32(final int fieldNumber, final int value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+    writeUInt32NoTag(value);
+  }
+
+  /**
+   * Write an enum field, including tag, to the stream.  Caller is responsible
+   * for converting the enum value to its numeric value.
+   */
+  public void writeEnum(final int fieldNumber, final int value)
+                        throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+    writeEnumNoTag(value);
+  }
+
+  /** Write an {@code sfixed32} field, including tag, to the stream. */
+  public void writeSFixed32(final int fieldNumber, final int value)
+                            throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
+    writeSFixed32NoTag(value);
+  }
+
+  /** Write an {@code sfixed64} field, including tag, to the stream. */
+  public void writeSFixed64(final int fieldNumber, final long value)
+                            throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
+    writeSFixed64NoTag(value);
+  }
+
+  /** Write an {@code sint32} field, including tag, to the stream. */
+  public void writeSInt32(final int fieldNumber, final int value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+    writeSInt32NoTag(value);
+  }
+
+  /** Write an {@code sint64} field, including tag, to the stream. */
+  public void writeSInt64(final int fieldNumber, final long value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
+    writeSInt64NoTag(value);
+  }
+
+  /**
+   * Write a MessageSet extension field to the stream.  For historical reasons,
+   * the wire format differs from normal fields.
+   */
+  public void writeMessageSetExtension(final int fieldNumber,
+                                       final MessageLite value)
+                                       throws IOException {
+    writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+    writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+    writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
+    writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+  }
+
+  /**
+   * Write an unparsed MessageSet extension field to the stream.  For
+   * historical reasons, the wire format differs from normal fields.
+   */
+  public void writeRawMessageSetExtension(final int fieldNumber,
+                                          final ByteString value)
+                                          throws IOException {
+    writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
+    writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
+    writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
+    writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
+  }
+
+  // -----------------------------------------------------------------
+
+  /** Write a {@code double} field to the stream. */
+  public void writeDoubleNoTag(final double value) throws IOException {
+    writeRawLittleEndian64(Double.doubleToRawLongBits(value));
+  }
+
+  /** Write a {@code float} field to the stream. */
+  public void writeFloatNoTag(final float value) throws IOException {
+    writeRawLittleEndian32(Float.floatToRawIntBits(value));
+  }
+
+  /** Write a {@code uint64} field to the stream. */
+  public void writeUInt64NoTag(final long value) throws IOException {
+    writeRawVarint64(value);
+  }
+
+  /** Write an {@code int64} field to the stream. */
+  public void writeInt64NoTag(final long value) throws IOException {
+    writeRawVarint64(value);
+  }
+
+  /** Write an {@code int32} field to the stream. */
+  public void writeInt32NoTag(final int value) throws IOException {
+    if (value >= 0) {
+      writeRawVarint32(value);
+    } else {
+      // Must sign-extend.
+      writeRawVarint64(value);
+    }
+  }
+
+  /** Write a {@code fixed64} field to the stream. */
+  public void writeFixed64NoTag(final long value) throws IOException {
+    writeRawLittleEndian64(value);
+  }
+
+  /** Write a {@code fixed32} field to the stream. */
+  public void writeFixed32NoTag(final int value) throws IOException {
+    writeRawLittleEndian32(value);
+  }
+
+  /** Write a {@code bool} field to the stream. */
+  public void writeBoolNoTag(final boolean value) throws IOException {
+    writeRawByte(value ? 1 : 0);
+  }
+
+  /** Write a {@code string} field to the stream. */
+  public void writeStringNoTag(final String value) throws IOException {
+    // Unfortunately there does not appear to be any way to tell Java to encode
+    // UTF-8 directly into our buffer, so we have to let it create its own byte
+    // array and then copy.
+    final byte[] bytes = value.getBytes("UTF-8");
+    writeRawVarint32(bytes.length);
+    writeRawBytes(bytes);
+  }
+
+  /** Write a {@code group} field to the stream. */
+  public void writeGroupNoTag(final MessageLite value) throws IOException {
+    value.writeTo(this);
+  }
+
+
+  /**
+   * Write a group represented by an {@link UnknownFieldSet}.
+   *
+   * @deprecated UnknownFieldSet now implements MessageLite, so you can just
+   *             call {@link #writeGroupNoTag}.
+   */
+  @Deprecated
+  public void writeUnknownGroupNoTag(final MessageLite value)
+      throws IOException {
+    writeGroupNoTag(value);
+  }
+
+  /** Write an embedded message field to the stream. */
+  public void writeMessageNoTag(final MessageLite value) throws IOException {
+    writeRawVarint32(value.getSerializedSize());
+    value.writeTo(this);
+  }
+
+
+  /** Write a {@code bytes} field to the stream. */
+  public void writeBytesNoTag(final ByteString value) throws IOException {
+    writeRawVarint32(value.size());
+    writeRawBytes(value);
+  }
+
+  /** Write a {@code bytes} field to the stream. */
+  public void writeByteArrayNoTag(final byte[] value) throws IOException {
+    writeRawVarint32(value.length);
+    writeRawBytes(value);
+  }
+
+  /** Write a {@code bytes} field to the stream. */
+  public void writeByteArrayNoTag(final byte[] value,
+                                  final int offset,
+                                  final int length) throws IOException {
+    writeRawVarint32(length);
+    writeRawBytes(value, offset, length);
+  }
+
+  /**
+   * Write a {@code bytes} field to the stream.  This method will write all
+   * content of the ByteBuffer regardless of the current position and limit
+   * (i.e., the number of bytes to be written is value.capacity(), not
+   * value.remaining()). Furthermore, this method doesn't alter the state of
+   * the passed-in ByteBuffer. Its position, limit, mark, etc. will remain
+   * unchanged. If you only want to write the remaining bytes of a ByteBuffer,
+   * you can call {@code writeByteBufferNoTag(byteBuffer.slice())}.
+   */
+  public void writeByteBufferNoTag(final ByteBuffer value) throws IOException {
+    writeRawVarint32(value.capacity());
+    writeRawBytes(value);
+  }
+
+  /** Write a {@code uint32} field to the stream. */
+  public void writeUInt32NoTag(final int value) throws IOException {
+    writeRawVarint32(value);
+  }
+
+  /**
+   * Write an enum field to the stream.  Caller is responsible
+   * for converting the enum value to its numeric value.
+   */
+  public void writeEnumNoTag(final int value) throws IOException {
+    writeInt32NoTag(value);
+  }
+
+  /** Write an {@code sfixed32} field to the stream. */
+  public void writeSFixed32NoTag(final int value) throws IOException {
+    writeRawLittleEndian32(value);
+  }
+
+  /** Write an {@code sfixed64} field to the stream. */
+  public void writeSFixed64NoTag(final long value) throws IOException {
+    writeRawLittleEndian64(value);
+  }
+
+  /** Write an {@code sint32} field to the stream. */
+  public void writeSInt32NoTag(final int value) throws IOException {
+    writeRawVarint32(encodeZigZag32(value));
+  }
+
+  /** Write an {@code sint64} field to the stream. */
+  public void writeSInt64NoTag(final long value) throws IOException {
+    writeRawVarint64(encodeZigZag64(value));
+  }
+
+  // =================================================================
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code double} field, including tag.
+   */
+  public static int computeDoubleSize(final int fieldNumber,
+                                      final double value) {
+    return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code float} field, including tag.
+   */
+  public static int computeFloatSize(final int fieldNumber, final float value) {
+    return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint64} field, including tag.
+   */
+  public static int computeUInt64Size(final int fieldNumber, final long value) {
+    return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int64} field, including tag.
+   */
+  public static int computeInt64Size(final int fieldNumber, final long value) {
+    return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int32} field, including tag.
+   */
+  public static int computeInt32Size(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed64} field, including tag.
+   */
+  public static int computeFixed64Size(final int fieldNumber,
+                                       final long value) {
+    return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed32} field, including tag.
+   */
+  public static int computeFixed32Size(final int fieldNumber,
+                                       final int value) {
+    return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bool} field, including tag.
+   */
+  public static int computeBoolSize(final int fieldNumber,
+                                    final boolean value) {
+    return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code string} field, including tag.
+   */
+  public static int computeStringSize(final int fieldNumber,
+                                      final String value) {
+    return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code group} field, including tag.
+   */
+  public static int computeGroupSize(final int fieldNumber,
+                                     final MessageLite value) {
+    return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code group} field represented by an {@code UnknownFieldSet}, including
+   * tag.
+   *
+   * @deprecated UnknownFieldSet now implements MessageLite, so you can just
+   *             call {@link #computeGroupSize}.
+   */
+  @Deprecated
+  public static int computeUnknownGroupSize(final int fieldNumber,
+                                            final MessageLite value) {
+    return computeGroupSize(fieldNumber, value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * embedded message field, including tag.
+   */
+  public static int computeMessageSize(final int fieldNumber,
+                                       final MessageLite value) {
+    return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field, including tag.
+   */
+  public static int computeBytesSize(final int fieldNumber,
+                                     final ByteString value) {
+    return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field, including tag.
+   */
+  public static int computeByteArraySize(final int fieldNumber,
+                                         final byte[] value) {
+    return computeTagSize(fieldNumber) + computeByteArraySizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field, including tag.
+   */
+  public static int computeByteBufferSize(final int fieldNumber,
+                                         final ByteBuffer value) {
+    return computeTagSize(fieldNumber) + computeByteBufferSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * embedded message in lazy field, including tag.
+   */
+  public static int computeLazyFieldSize(final int fieldNumber,
+                                         final LazyFieldLite value) {
+    return computeTagSize(fieldNumber) + computeLazyFieldSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint32} field, including tag.
+   */
+  public static int computeUInt32Size(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * enum field, including tag.  Caller is responsible for converting the
+   * enum value to its numeric value.
+   */
+  public static int computeEnumSize(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed32} field, including tag.
+   */
+  public static int computeSFixed32Size(final int fieldNumber,
+                                        final int value) {
+    return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed64} field, including tag.
+   */
+  public static int computeSFixed64Size(final int fieldNumber,
+                                        final long value) {
+    return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint32} field, including tag.
+   */
+  public static int computeSInt32Size(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint64} field, including tag.
+   */
+  public static int computeSInt64Size(final int fieldNumber, final long value) {
+    return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * MessageSet extension to the stream.  For historical reasons,
+   * the wire format differs from normal fields.
+   */
+  public static int computeMessageSetExtensionSize(
+      final int fieldNumber, final MessageLite value) {
+    return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
+           computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
+           computeMessageSize(WireFormat.MESSAGE_SET_MESSAGE, value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * unparsed MessageSet extension field to the stream.  For
+   * historical reasons, the wire format differs from normal fields.
+   */
+  public static int computeRawMessageSetExtensionSize(
+      final int fieldNumber, final ByteString value) {
+    return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
+           computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
+           computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * lazily parsed MessageSet extension field to the stream.  For
+   * historical reasons, the wire format differs from normal fields.
+   */
+  public static int computeLazyFieldMessageSetExtensionSize(
+      final int fieldNumber, final LazyFieldLite value) {
+    return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
+           computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
+           computeLazyFieldSize(WireFormat.MESSAGE_SET_MESSAGE, value);
+  }
+  
+  // -----------------------------------------------------------------
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code double} field, including tag.
+   */
+  public static int computeDoubleSizeNoTag(final double value) {
+    return LITTLE_ENDIAN_64_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code float} field, including tag.
+   */
+  public static int computeFloatSizeNoTag(final float value) {
+    return LITTLE_ENDIAN_32_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint64} field, including tag.
+   */
+  public static int computeUInt64SizeNoTag(final long value) {
+    return computeRawVarint64Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int64} field, including tag.
+   */
+  public static int computeInt64SizeNoTag(final long value) {
+    return computeRawVarint64Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int32} field, including tag.
+   */
+  public static int computeInt32SizeNoTag(final int value) {
+    if (value >= 0) {
+      return computeRawVarint32Size(value);
+    } else {
+      // Must sign-extend.
+      return 10;
+    }
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed64} field.
+   */
+  public static int computeFixed64SizeNoTag(final long value) {
+    return LITTLE_ENDIAN_64_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed32} field.
+   */
+  public static int computeFixed32SizeNoTag(final int value) {
+    return LITTLE_ENDIAN_32_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bool} field.
+   */
+  public static int computeBoolSizeNoTag(final boolean value) {
+    return 1;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code string} field.
+   */
+  public static int computeStringSizeNoTag(final String value) {
+    try {
+      final byte[] bytes = value.getBytes("UTF-8");
+      return computeRawVarint32Size(bytes.length) +
+             bytes.length;
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 not supported.", e);
+    }
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code group} field.
+   */
+  public static int computeGroupSizeNoTag(final MessageLite value) {
+    return value.getSerializedSize();
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code group} field represented by an {@code UnknownFieldSet}, including
+   * tag.
+   *
+   * @deprecated UnknownFieldSet now implements MessageLite, so you can just
+   *             call {@link #computeUnknownGroupSizeNoTag}.
+   */
+  @Deprecated
+  public static int computeUnknownGroupSizeNoTag(final MessageLite value) {
+    return computeGroupSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an embedded
+   * message field.
+   */
+  public static int computeMessageSizeNoTag(final MessageLite value) {
+    final int size = value.getSerializedSize();
+    return computeRawVarint32Size(size) + size;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an embedded
+   * message stored in lazy field.
+   */
+  public static int computeLazyFieldSizeNoTag(final LazyFieldLite value) {
+    final int size = value.getSerializedSize();
+    return computeRawVarint32Size(size) + size;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field.
+   */
+  public static int computeBytesSizeNoTag(final ByteString value) {
+    return computeRawVarint32Size(value.size()) +
+           value.size();
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field.
+   */
+  public static int computeByteArraySizeNoTag(final byte[] value) {
+    return computeRawVarint32Size(value.length) + value.length;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field.
+   */
+  public static int computeByteBufferSizeNoTag(final ByteBuffer value) {
+    return computeRawVarint32Size(value.capacity()) + value.capacity();
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint32} field.
+   */
+  public static int computeUInt32SizeNoTag(final int value) {
+    return computeRawVarint32Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an enum field.
+   * Caller is responsible for converting the enum value to its numeric value.
+   */
+  public static int computeEnumSizeNoTag(final int value) {
+    return computeInt32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed32} field.
+   */
+  public static int computeSFixed32SizeNoTag(final int value) {
+    return LITTLE_ENDIAN_32_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed64} field.
+   */
+  public static int computeSFixed64SizeNoTag(final long value) {
+    return LITTLE_ENDIAN_64_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint32} field.
+   */
+  public static int computeSInt32SizeNoTag(final int value) {
+    return computeRawVarint32Size(encodeZigZag32(value));
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint64} field.
+   */
+  public static int computeSInt64SizeNoTag(final long value) {
+    return computeRawVarint64Size(encodeZigZag64(value));
+  }
+
+  // =================================================================
+
+  /**
+   * Internal helper that writes the current buffer to the output. The
+   * buffer position is reset to its initial value when this returns.
+   */
+  private void refreshBuffer() throws IOException {
+    if (output == null) {
+      // We're writing to a single buffer.
+      throw new OutOfSpaceException();
+    }
+
+    // Since we have an output stream, this is our buffer
+    // and buffer offset == 0
+    output.write(buffer, 0, position);
+    position = 0;
+  }
+
+  /**
+   * Flushes the stream and forces any buffered bytes to be written.  This
+   * does not flush the underlying OutputStream.
+   */
+  public void flush() throws IOException {
+    if (output != null) {
+      refreshBuffer();
+    }
+  }
+
+  /**
+   * If writing to a flat array, return the space left in the array.
+   * Otherwise, throws {@code UnsupportedOperationException}.
+   */
+  public int spaceLeft() {
+    if (output == null) {
+      return limit - position;
+    } else {
+      throw new UnsupportedOperationException(
+        "spaceLeft() can only be called on CodedOutputStreams that are " +
+        "writing to a flat array.");
+    }
+  }
+
+  /**
+   * Verifies that {@link #spaceLeft()} returns zero.  It's common to create
+   * a byte array that is exactly big enough to hold a message, then write to
+   * it with a {@code CodedOutputStream}.  Calling {@code checkNoSpaceLeft()}
+   * after writing verifies that the message was actually as big as expected,
+   * which can help catch bugs.
+   */
+  public void checkNoSpaceLeft() {
+    if (spaceLeft() != 0) {
+      throw new IllegalStateException(
+        "Did not write as much data as expected.");
+    }
+  }
+
+  /**
+   * If you create a CodedOutputStream around a simple flat array, you must
+   * not attempt to write more bytes than the array has space.  Otherwise,
+   * this exception will be thrown.
+   */
+  public static class OutOfSpaceException extends IOException {
+    private static final long serialVersionUID = -6947486886997889499L;
+
+    OutOfSpaceException() {
+      super("CodedOutputStream was writing to a flat byte array and ran " +
+            "out of space.");
+    }
+  }
+
+  /**
+   * Get the total number of bytes successfully written to this stream.  The
+   * returned value is not guaranteed to be accurate if exceptions have been
+   * found in the middle of writing.
+   */
+  public int getTotalBytesWritten() {
+    return totalBytesWritten;
+  }
+
+  /** Write a single byte. */
+  public void writeRawByte(final byte value) throws IOException {
+    if (position == limit) {
+      refreshBuffer();
+    }
+
+    buffer[position++] = value;
+    ++totalBytesWritten;
+  }
+
+  /** Write a single byte, represented by an integer value. */
+  public void writeRawByte(final int value) throws IOException {
+    writeRawByte((byte) value);
+  }
+
+  /** Write a byte string. */
+  public void writeRawBytes(final ByteString value) throws IOException {
+    writeRawBytes(value, 0, value.size());
+  }
+
+  /** Write an array of bytes. */
+  public void writeRawBytes(final byte[] value) throws IOException {
+    writeRawBytes(value, 0, value.length);
+  }
+
+  /**
+   * Write a ByteBuffer. This method will write all content of the ByteBuffer
+   * regardless of the current position and limit (i.e., the number of bytes
+   * to be written is value.capacity(), not value.remaining()). Furthermore,
+   * this method doesn't alter the state of the passed-in ByteBuffer. Its
+   * position, limit, mark, etc. will remain unchanged. If you only want to
+   * write the remaining bytes of a ByteBuffer, you can call
+   * {@code writeRawBytes(byteBuffer.slice())}.
+   */
+  public void writeRawBytes(final ByteBuffer value) throws IOException {
+    if (value.hasArray()) {
+      writeRawBytes(value.array(), value.arrayOffset(), value.capacity());
+    } else {
+      ByteBuffer duplicated = value.duplicate();
+      duplicated.clear();
+      writeRawBytesInternal(duplicated);
+    }
+  }
+
+  /** Write a ByteBuffer that isn't backed by an array. */
+  private void writeRawBytesInternal(final ByteBuffer value)
+      throws IOException {
+    int length = value.remaining();
+    if (limit - position >= length) {
+      // We have room in the current buffer.
+      value.get(buffer, position, length);
+      position += length;
+      totalBytesWritten += length;
+    } else {
+      // Write extends past current buffer.  Fill the rest of this buffer and
+      // flush.
+      final int bytesWritten = limit - position;
+      value.get(buffer, position, bytesWritten);
+      length -= bytesWritten;
+      position = limit;
+      totalBytesWritten += bytesWritten;
+      refreshBuffer();
+
+      // Now deal with the rest.
+      // Since we have an output stream, this is our buffer
+      // and buffer offset == 0
+      while (length > limit) {
+        // Copy data into the buffer before writing it to OutputStream.
+        // TODO(xiaofeng): Introduce ZeroCopyOutputStream to avoid this copy.
+        value.get(buffer, 0, limit);
+        output.write(buffer, 0, limit);
+        length -= limit;
+        totalBytesWritten += limit;
+      }
+      value.get(buffer, 0, length);
+      position = length;
+      totalBytesWritten += length;
+    }
+  }
+
+  /** Write part of an array of bytes. */
+  public void writeRawBytes(final byte[] value, int offset, int length)
+                            throws IOException {
+    if (limit - position >= length) {
+      // We have room in the current buffer.
+      System.arraycopy(value, offset, buffer, position, length);
+      position += length;
+      totalBytesWritten += length;
+    } else {
+      // Write extends past current buffer.  Fill the rest of this buffer and
+      // flush.
+      final int bytesWritten = limit - position;
+      System.arraycopy(value, offset, buffer, position, bytesWritten);
+      offset += bytesWritten;
+      length -= bytesWritten;
+      position = limit;
+      totalBytesWritten += bytesWritten;
+      refreshBuffer();
+
+      // Now deal with the rest.
+      // Since we have an output stream, this is our buffer
+      // and buffer offset == 0
+      if (length <= limit) {
+        // Fits in new buffer.
+        System.arraycopy(value, offset, buffer, 0, length);
+        position = length;
+      } else {
+        // Write is very big.  Let's do it all at once.
+        output.write(value, offset, length);
+      }
+      totalBytesWritten += length;
+    }
+  }
+
+  /** Write part of a byte string. */
+  public void writeRawBytes(final ByteString value, int offset, int length)
+                            throws IOException {
+    if (limit - position >= length) {
+      // We have room in the current buffer.
+      value.copyTo(buffer, offset, position, length);
+      position += length;
+      totalBytesWritten += length;
+    } else {
+      // Write extends past current buffer.  Fill the rest of this buffer and
+      // flush.
+      final int bytesWritten = limit - position;
+      value.copyTo(buffer, offset, position, bytesWritten);
+      offset += bytesWritten;
+      length -= bytesWritten;
+      position = limit;
+      totalBytesWritten += bytesWritten;
+      refreshBuffer();
+
+      // Now deal with the rest.
+      // Since we have an output stream, this is our buffer
+      // and buffer offset == 0
+      if (length <= limit) {
+        // Fits in new buffer.
+        value.copyTo(buffer, offset, 0, length);
+        position = length;
+      } else {
+        value.writeTo(output, offset, length);
+      }
+      totalBytesWritten += length;
+    }
+  }
+
+  /** Encode and write a tag. */
+  public void writeTag(final int fieldNumber, final int wireType)
+                       throws IOException {
+    writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType));
+  }
+
+  /** Compute the number of bytes that would be needed to encode a tag. */
+  public static int computeTagSize(final int fieldNumber) {
+    return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0));
+  }
+
+  /**
+   * Encode and write a varint.  {@code value} is treated as
+   * unsigned, so it won't be sign-extended if negative.
+   */
+  public void writeRawVarint32(int value) throws IOException {
+    while (true) {
+      if ((value & ~0x7F) == 0) {
+        writeRawByte(value);
+        return;
+      } else {
+        writeRawByte((value & 0x7F) | 0x80);
+        value >>>= 7;
+      }
+    }
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a varint.
+   * {@code value} is treated as unsigned, so it won't be sign-extended if
+   * negative.
+   */
+  public static int computeRawVarint32Size(final int value) {
+    if ((value & (0xffffffff <<  7)) == 0) return 1;
+    if ((value & (0xffffffff << 14)) == 0) return 2;
+    if ((value & (0xffffffff << 21)) == 0) return 3;
+    if ((value & (0xffffffff << 28)) == 0) return 4;
+    return 5;
+  }
+
+  /** Encode and write a varint. */
+  public void writeRawVarint64(long value) throws IOException {
+    while (true) {
+      if ((value & ~0x7FL) == 0) {
+        writeRawByte((int)value);
+        return;
+      } else {
+        writeRawByte(((int)value & 0x7F) | 0x80);
+        value >>>= 7;
+      }
+    }
+  }
+
+  /** Compute the number of bytes that would be needed to encode a varint. */
+  public static int computeRawVarint64Size(final long value) {
+    if ((value & (0xffffffffffffffffL <<  7)) == 0) return 1;
+    if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
+    if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
+    if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
+    if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
+    if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
+    if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
+    if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
+    if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
+    return 10;
+  }
+
+  /** Write a little-endian 32-bit integer. */
+  public void writeRawLittleEndian32(final int value) throws IOException {
+    writeRawByte((value      ) & 0xFF);
+    writeRawByte((value >>  8) & 0xFF);
+    writeRawByte((value >> 16) & 0xFF);
+    writeRawByte((value >> 24) & 0xFF);
+  }
+
+  public static final int LITTLE_ENDIAN_32_SIZE = 4;
+
+  /** Write a little-endian 64-bit integer. */
+  public void writeRawLittleEndian64(final long value) throws IOException {
+    writeRawByte((int)(value      ) & 0xFF);
+    writeRawByte((int)(value >>  8) & 0xFF);
+    writeRawByte((int)(value >> 16) & 0xFF);
+    writeRawByte((int)(value >> 24) & 0xFF);
+    writeRawByte((int)(value >> 32) & 0xFF);
+    writeRawByte((int)(value >> 40) & 0xFF);
+    writeRawByte((int)(value >> 48) & 0xFF);
+    writeRawByte((int)(value >> 56) & 0xFF);
+  }
+
+  public static final int LITTLE_ENDIAN_64_SIZE = 8;
+
+  /**
+   * Encode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n A signed 32-bit integer.
+   * @return An unsigned 32-bit integer, stored in a signed int because
+   *         Java has no explicit unsigned support.
+   */
+  public static int encodeZigZag32(final int n) {
+    // Note:  the right-shift must be arithmetic
+    return (n << 1) ^ (n >> 31);
+  }
+
+  /**
+   * Encode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n A signed 64-bit integer.
+   * @return An unsigned 64-bit integer, stored in a signed int because
+   *         Java has no explicit unsigned support.
+   */
+  public static long encodeZigZag64(final long n) {
+    // Note:  the right-shift must be arithmetic
+    return (n << 1) ^ (n >> 63);
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/Descriptors.java b/protobuf/java/src/main/java/com/google/protobuf/Descriptors.java
new file mode 100644
index 0000000..caae0f7
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/Descriptors.java
@@ -0,0 +1,2238 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.DescriptorProtos.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Contains a collection of classes which describe protocol message types.
+ *
+ * Every message type has a {@link Descriptor}, which lists all
+ * its fields and other information about a type.  You can get a message
+ * type's descriptor by calling {@code MessageType.getDescriptor()}, or
+ * (given a message object of the type) {@code message.getDescriptorForType()}.
+ * Furthermore, each message is associated with a {@link FileDescriptor} for
+ * a relevant {@code .proto} file. You can obtain it by calling
+ * {@code Descriptor.getFile()}. A {@link FileDescriptor} contains descriptors
+ * for all the messages defined in that file, and file descriptors for all the
+ * imported {@code .proto} files.
+ *
+ * Descriptors are built from DescriptorProtos, as defined in
+ * {@code google/protobuf/descriptor.proto}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class Descriptors {
+  private static final Logger logger =
+      Logger.getLogger(Descriptors.class.getName());
+  /**
+   * Describes a {@code .proto} file, including everything defined within.
+   * That includes, in particular, descriptors for all the messages and
+   * file descriptors for all other imported {@code .proto} files
+   * (dependencies).
+   */
+  public static final class FileDescriptor extends GenericDescriptor {
+    /** Convert the descriptor to its protocol message representation. */
+    public FileDescriptorProto toProto() { return proto; }
+
+    /** Get the file name. */
+    public String getName() { return proto.getName(); }
+
+    /** Returns this object. */
+    public FileDescriptor getFile() { return this; }
+
+    /** Returns the same as getName(). */
+    public String getFullName() { return proto.getName(); }
+
+    /**
+     * Get the proto package name.  This is the package name given by the
+     * {@code package} statement in the {@code .proto} file, which differs
+     * from the Java package.
+     */
+    public String getPackage() { return proto.getPackage(); }
+
+    /** Get the {@code FileOptions}, defined in {@code descriptor.proto}. */
+    public FileOptions getOptions() { return proto.getOptions(); }
+
+    /** Get a list of top-level message types declared in this file. */
+    public List<Descriptor> getMessageTypes() {
+      return Collections.unmodifiableList(Arrays.asList(messageTypes));
+    }
+
+    /** Get a list of top-level enum types declared in this file. */
+    public List<EnumDescriptor> getEnumTypes() {
+      return Collections.unmodifiableList(Arrays.asList(enumTypes));
+    }
+
+    /** Get a list of top-level services declared in this file. */
+    public List<ServiceDescriptor> getServices() {
+      return Collections.unmodifiableList(Arrays.asList(services));
+    }
+
+    /** Get a list of top-level extensions declared in this file. */
+    public List<FieldDescriptor> getExtensions() {
+      return Collections.unmodifiableList(Arrays.asList(extensions));
+    }
+
+    /** Get a list of this file's dependencies (imports). */
+    public List<FileDescriptor> getDependencies() {
+      return Collections.unmodifiableList(Arrays.asList(dependencies));
+    }
+
+    /** Get a list of this file's public dependencies (public imports). */
+    public List<FileDescriptor> getPublicDependencies() {
+      return Collections.unmodifiableList(Arrays.asList(publicDependencies));
+    }
+
+    /**
+     * Find a message type in the file by name.  Does not find nested types.
+     *
+     * @param name The unqualified type name to look for.
+     * @return The message type's descriptor, or {@code null} if not found.
+     */
+    public Descriptor findMessageTypeByName(String name) {
+      // Don't allow looking up nested types.  This will make optimization
+      // easier later.
+      if (name.indexOf('.') != -1) {
+        return null;
+      }
+      if (getPackage().length() > 0) {
+        name = getPackage() + '.' + name;
+      }
+      final GenericDescriptor result = pool.findSymbol(name);
+      if (result != null && result instanceof Descriptor &&
+          result.getFile() == this) {
+        return (Descriptor)result;
+      } else {
+        return null;
+      }
+    }
+
+    /**
+     * Find an enum type in the file by name.  Does not find nested types.
+     *
+     * @param name The unqualified type name to look for.
+     * @return The enum type's descriptor, or {@code null} if not found.
+     */
+    public EnumDescriptor findEnumTypeByName(String name) {
+      // Don't allow looking up nested types.  This will make optimization
+      // easier later.
+      if (name.indexOf('.') != -1) {
+        return null;
+      }
+      if (getPackage().length() > 0) {
+        name = getPackage() + '.' + name;
+      }
+      final GenericDescriptor result = pool.findSymbol(name);
+      if (result != null && result instanceof EnumDescriptor &&
+          result.getFile() == this) {
+        return (EnumDescriptor)result;
+      } else {
+        return null;
+      }
+    }
+
+    /**
+     * Find a service type in the file by name.
+     *
+     * @param name The unqualified type name to look for.
+     * @return The service type's descriptor, or {@code null} if not found.
+     */
+    public ServiceDescriptor findServiceByName(String name) {
+      // Don't allow looking up nested types.  This will make optimization
+      // easier later.
+      if (name.indexOf('.') != -1) {
+        return null;
+      }
+      if (getPackage().length() > 0) {
+        name = getPackage() + '.' + name;
+      }
+      final GenericDescriptor result = pool.findSymbol(name);
+      if (result != null && result instanceof ServiceDescriptor &&
+          result.getFile() == this) {
+        return (ServiceDescriptor)result;
+      } else {
+        return null;
+      }
+    }
+
+    /**
+     * Find an extension in the file by name.  Does not find extensions nested
+     * inside message types.
+     *
+     * @param name The unqualified extension name to look for.
+     * @return The extension's descriptor, or {@code null} if not found.
+     */
+    public FieldDescriptor findExtensionByName(String name) {
+      if (name.indexOf('.') != -1) {
+        return null;
+      }
+      if (getPackage().length() > 0) {
+        name = getPackage() + '.' + name;
+      }
+      final GenericDescriptor result = pool.findSymbol(name);
+      if (result != null && result instanceof FieldDescriptor &&
+          result.getFile() == this) {
+        return (FieldDescriptor)result;
+      } else {
+        return null;
+      }
+    }
+
+    /**
+     * Construct a {@code FileDescriptor}.
+     *
+     * @param proto The protocol message form of the FileDescriptor.
+     * @param dependencies {@code FileDescriptor}s corresponding to all of
+     *                     the file's dependencies.
+     * @throws DescriptorValidationException {@code proto} is not a valid
+     *           descriptor.  This can occur for a number of reasons, e.g.
+     *           because a field has an undefined type or because two messages
+     *           were defined with the same name.
+     */
+    public static FileDescriptor buildFrom(final FileDescriptorProto proto,
+                                           final FileDescriptor[] dependencies)
+                                    throws DescriptorValidationException {
+      return buildFrom(proto, dependencies, false);
+    }
+    
+
+    /**
+     * Construct a {@code FileDescriptor}.
+     *
+     * @param proto The protocol message form of the FileDescriptor.
+     * @param dependencies {@code FileDescriptor}s corresponding to all of
+     *                     the file's dependencies.
+     * @param allowUnknownDependencies If true, non-exist dependenncies will be
+     *           ignored and undefined message types will be replaced with a
+     *           placeholder type.
+     * @throws DescriptorValidationException {@code proto} is not a valid
+     *           descriptor.  This can occur for a number of reasons, e.g.
+     *           because a field has an undefined type or because two messages
+     *           were defined with the same name.
+     */
+    private static FileDescriptor buildFrom(
+        final FileDescriptorProto proto, final FileDescriptor[] dependencies,
+        final boolean allowUnknownDependencies)
+        throws DescriptorValidationException {
+      // Building descriptors involves two steps:  translating and linking.
+      // In the translation step (implemented by FileDescriptor's
+      // constructor), we build an object tree mirroring the
+      // FileDescriptorProto's tree and put all of the descriptors into the
+      // DescriptorPool's lookup tables.  In the linking step, we look up all
+      // type references in the DescriptorPool, so that, for example, a
+      // FieldDescriptor for an embedded message contains a pointer directly
+      // to the Descriptor for that message's type.  We also detect undefined
+      // types in the linking step.
+      final DescriptorPool pool = new DescriptorPool(
+          dependencies, allowUnknownDependencies);
+      final FileDescriptor result = new FileDescriptor(
+          proto, dependencies, pool, allowUnknownDependencies);
+      result.crossLink();
+      return result;
+    }
+
+    /**
+     * This method is to be called by generated code only.  It is equivalent
+     * to {@code buildFrom} except that the {@code FileDescriptorProto} is
+     * encoded in protocol buffer wire format.
+     */
+    public static void internalBuildGeneratedFileFrom(
+        final String[] descriptorDataParts,
+        final FileDescriptor[] dependencies,
+        final InternalDescriptorAssigner descriptorAssigner) {
+      // Hack:  We can't embed a raw byte array inside generated Java code
+      //   (at least, not efficiently), but we can embed Strings.  So, the
+      //   protocol compiler embeds the FileDescriptorProto as a giant
+      //   string literal which is passed to this function to construct the
+      //   file's FileDescriptor.  The string literal contains only 8-bit
+      //   characters, each one representing a byte of the FileDescriptorProto's
+      //   serialized form.  So, if we convert it to bytes in ISO-8859-1, we
+      //   should get the original bytes that we want.
+
+      // descriptorData may contain multiple strings in order to get around the
+      // Java 64k string literal limit.
+      StringBuilder descriptorData = new StringBuilder();
+      for (String part : descriptorDataParts) {
+        descriptorData.append(part);
+      }
+
+      final byte[] descriptorBytes;
+      try {
+        descriptorBytes = descriptorData.toString().getBytes("ISO-8859-1");
+      } catch (UnsupportedEncodingException e) {
+        throw new RuntimeException(
+          "Standard encoding ISO-8859-1 not supported by JVM.", e);
+      }
+
+      FileDescriptorProto proto;
+      try {
+        proto = FileDescriptorProto.parseFrom(descriptorBytes);
+      } catch (InvalidProtocolBufferException e) {
+        throw new IllegalArgumentException(
+          "Failed to parse protocol buffer descriptor for generated code.", e);
+      }
+
+      final FileDescriptor result;
+      try {
+        // When building descriptors for generated code, we allow unknown
+        // dependencies by default.
+        result = buildFrom(proto, dependencies, true);
+      } catch (DescriptorValidationException e) {
+        throw new IllegalArgumentException(
+          "Invalid embedded descriptor for \"" + proto.getName() + "\".", e);
+      }
+
+      final ExtensionRegistry registry =
+          descriptorAssigner.assignDescriptors(result);
+
+      if (registry != null) {
+        // We must re-parse the proto using the registry.
+        try {
+          proto = FileDescriptorProto.parseFrom(descriptorBytes, registry);
+        } catch (InvalidProtocolBufferException e) {
+          throw new IllegalArgumentException(
+            "Failed to parse protocol buffer descriptor for generated code.",
+            e);
+        }
+
+        result.setProto(proto);
+      }
+    }
+
+    /**
+     * This method is to be called by generated code only.  It uses Java
+     * reflection to load the dependencies' descriptors.
+     */
+    public static void internalBuildGeneratedFileFrom(
+        final String[] descriptorDataParts,
+        final Class<?> descriptorOuterClass,
+        final String[] dependencies,
+        final String[] dependencyFileNames,
+        final InternalDescriptorAssigner descriptorAssigner) {
+      List<FileDescriptor> descriptors = new ArrayList<FileDescriptor>();
+      for (int i = 0; i < dependencies.length; i++) {
+        try {
+          Class<?> clazz =
+              descriptorOuterClass.getClassLoader().loadClass(dependencies[i]);
+          descriptors.add(
+              (FileDescriptor) clazz.getField("descriptor").get(null));
+        } catch (Exception e) {
+          // We allow unknown dependencies by default. If a dependency cannot
+          // be found we only generate a warning.
+          logger.warning("Descriptors for \"" + dependencyFileNames[i] +
+              "\" can not be found.");
+        }
+      }
+      FileDescriptor[] descriptorArray = new FileDescriptor[descriptors.size()];
+      descriptors.toArray(descriptorArray);
+      internalBuildGeneratedFileFrom(
+          descriptorDataParts, descriptorArray, descriptorAssigner);
+    }
+
+    /**
+     * This method is to be called by generated code only.  It is used to
+     * update the FileDescriptorProto associated with the descriptor by
+     * parsing it again with the given ExtensionRegistry. This is needed to
+     * recognize custom options.
+     */
+    public static void internalUpdateFileDescriptor(
+        final FileDescriptor descriptor,
+        final ExtensionRegistry registry) {
+      ByteString bytes = descriptor.proto.toByteString();
+      FileDescriptorProto proto;
+      try {
+        proto = FileDescriptorProto.parseFrom(bytes, registry);
+      } catch (InvalidProtocolBufferException e) {
+        throw new IllegalArgumentException(
+          "Failed to parse protocol buffer descriptor for generated code.", e);
+      }
+      descriptor.setProto(proto);
+    }
+
+    /**
+     * This class should be used by generated code only.  When calling
+     * {@link FileDescriptor#internalBuildGeneratedFileFrom}, the caller
+     * provides a callback implementing this interface.  The callback is called
+     * after the FileDescriptor has been constructed, in order to assign all
+     * the global variables defined in the generated code which point at parts
+     * of the FileDescriptor.  The callback returns an ExtensionRegistry which
+     * contains any extensions which might be used in the descriptor -- that
+     * is, extensions of the various "Options" messages defined in
+     * descriptor.proto.  The callback may also return null to indicate that
+     * no extensions are used in the descriptor.
+     */
+    public interface InternalDescriptorAssigner {
+      ExtensionRegistry assignDescriptors(FileDescriptor root);
+    }
+
+    private FileDescriptorProto proto;
+    private final Descriptor[] messageTypes;
+    private final EnumDescriptor[] enumTypes;
+    private final ServiceDescriptor[] services;
+    private final FieldDescriptor[] extensions;
+    private final FileDescriptor[] dependencies;
+    private final FileDescriptor[] publicDependencies;
+    private final DescriptorPool pool;
+
+    private FileDescriptor(final FileDescriptorProto proto,
+                           final FileDescriptor[] dependencies,
+                           final DescriptorPool pool,
+                           boolean allowUnknownDependencies)
+                    throws DescriptorValidationException {
+      this.pool = pool;
+      this.proto = proto;
+      this.dependencies = dependencies.clone();
+      HashMap<String, FileDescriptor> nameToFileMap =
+          new HashMap<String, FileDescriptor>();
+      for (FileDescriptor file : dependencies) {
+        nameToFileMap.put(file.getName(), file);
+      }
+      List<FileDescriptor> publicDependencies = new ArrayList<FileDescriptor>();
+      for (int i = 0; i < proto.getPublicDependencyCount(); i++) {
+        int index = proto.getPublicDependency(i);
+        if (index < 0 || index >= proto.getDependencyCount()) {
+          throw new DescriptorValidationException(this,
+              "Invalid public dependency index.");
+        }
+        String name = proto.getDependency(index);
+        FileDescriptor file = nameToFileMap.get(name);
+        if (file == null) {
+          if (!allowUnknownDependencies) {
+            throw new DescriptorValidationException(this,
+                "Invalid public dependency: " + name);
+          }
+          // Ignore unknown dependencies.
+        } else {
+          publicDependencies.add(file);
+        }
+      }
+      this.publicDependencies = new FileDescriptor[publicDependencies.size()];
+      publicDependencies.toArray(this.publicDependencies);
+
+      pool.addPackage(getPackage(), this);
+
+      messageTypes = new Descriptor[proto.getMessageTypeCount()];
+      for (int i = 0; i < proto.getMessageTypeCount(); i++) {
+        messageTypes[i] =
+          new Descriptor(proto.getMessageType(i), this, null, i);
+      }
+
+      enumTypes = new EnumDescriptor[proto.getEnumTypeCount()];
+      for (int i = 0; i < proto.getEnumTypeCount(); i++) {
+        enumTypes[i] = new EnumDescriptor(proto.getEnumType(i), this, null, i);
+      }
+
+      services = new ServiceDescriptor[proto.getServiceCount()];
+      for (int i = 0; i < proto.getServiceCount(); i++) {
+        services[i] = new ServiceDescriptor(proto.getService(i), this, i);
+      }
+
+      extensions = new FieldDescriptor[proto.getExtensionCount()];
+      for (int i = 0; i < proto.getExtensionCount(); i++) {
+        extensions[i] = new FieldDescriptor(
+          proto.getExtension(i), this, null, i, true);
+      }
+    }
+    
+    /**
+     * Create a placeholder FileDescriptor for a message Descriptor. 
+     */
+    FileDescriptor(String packageName, Descriptor message)
+        throws DescriptorValidationException {
+      this.pool = new DescriptorPool(new FileDescriptor[0], true);
+      this.proto = FileDescriptorProto.newBuilder()
+          .setName(message.getFullName() + ".placeholder.proto")
+          .setPackage(packageName).addMessageType(message.toProto()).build();
+      this.dependencies = new FileDescriptor[0];
+      this.publicDependencies = new FileDescriptor[0];
+
+      messageTypes = new Descriptor[] {message};
+      enumTypes = new EnumDescriptor[0];
+      services = new ServiceDescriptor[0];
+      extensions = new FieldDescriptor[0];
+
+      pool.addPackage(packageName, this);
+      pool.addSymbol(message);
+    }
+
+    /** Look up and cross-link all field types, etc. */
+    private void crossLink() throws DescriptorValidationException {
+      for (final Descriptor messageType : messageTypes) {
+        messageType.crossLink();
+      }
+
+      for (final ServiceDescriptor service : services) {
+        service.crossLink();
+      }
+
+      for (final FieldDescriptor extension : extensions) {
+        extension.crossLink();
+      }
+    }
+
+    /**
+     * Replace our {@link FileDescriptorProto} with the given one, which is
+     * identical except that it might contain extensions that weren't present
+     * in the original.  This method is needed for bootstrapping when a file
+     * defines custom options.  The options may be defined in the file itself,
+     * so we can't actually parse them until we've constructed the descriptors,
+     * but to construct the descriptors we have to have parsed the descriptor
+     * protos.  So, we have to parse the descriptor protos a second time after
+     * constructing the descriptors.
+     */
+    private void setProto(final FileDescriptorProto proto) {
+      this.proto = proto;
+
+      for (int i = 0; i < messageTypes.length; i++) {
+        messageTypes[i].setProto(proto.getMessageType(i));
+      }
+
+      for (int i = 0; i < enumTypes.length; i++) {
+        enumTypes[i].setProto(proto.getEnumType(i));
+      }
+
+      for (int i = 0; i < services.length; i++) {
+        services[i].setProto(proto.getService(i));
+      }
+
+      for (int i = 0; i < extensions.length; i++) {
+        extensions[i].setProto(proto.getExtension(i));
+      }
+    }
+  }
+
+  // =================================================================
+
+  /** Describes a message type. */
+  public static final class Descriptor extends GenericDescriptor {
+    /**
+     * Get the index of this descriptor within its parent.  In other words,
+     * given a {@link FileDescriptor} {@code file}, the following is true:
+     * <pre>
+     *   for all i in [0, file.getMessageTypeCount()):
+     *     file.getMessageType(i).getIndex() == i
+     * </pre>
+     * Similarly, for a {@link Descriptor} {@code messageType}:
+     * <pre>
+     *   for all i in [0, messageType.getNestedTypeCount()):
+     *     messageType.getNestedType(i).getIndex() == i
+     * </pre>
+     */
+    public int getIndex() { return index; }
+
+    /** Convert the descriptor to its protocol message representation. */
+    public DescriptorProto toProto() { return proto; }
+
+    /** Get the type's unqualified name. */
+    public String getName() { return proto.getName(); }
+
+    /**
+     * Get the type's fully-qualified name, within the proto language's
+     * namespace.  This differs from the Java name.  For example, given this
+     * {@code .proto}:
+     * <pre>
+     *   package foo.bar;
+     *   option java_package = "com.example.protos"
+     *   message Baz {}
+     * </pre>
+     * {@code Baz}'s full name is "foo.bar.Baz".
+     */
+    public String getFullName() { return fullName; }
+
+    /** Get the {@link FileDescriptor} containing this descriptor. */
+    public FileDescriptor getFile() { return file; }
+
+    /** If this is a nested type, get the outer descriptor, otherwise null. */
+    public Descriptor getContainingType() { return containingType; }
+
+    /** Get the {@code MessageOptions}, defined in {@code descriptor.proto}. */
+    public MessageOptions getOptions() { return proto.getOptions(); }
+
+    /** Get a list of this message type's fields. */
+    public List<FieldDescriptor> getFields() {
+      return Collections.unmodifiableList(Arrays.asList(fields));
+    }
+
+    /** Get a list of this message type's oneofs. */
+    public List<OneofDescriptor> getOneofs() {
+      return Collections.unmodifiableList(Arrays.asList(oneofs));
+    }
+
+    /** Get a list of this message type's extensions. */
+    public List<FieldDescriptor> getExtensions() {
+      return Collections.unmodifiableList(Arrays.asList(extensions));
+    }
+
+    /** Get a list of message types nested within this one. */
+    public List<Descriptor> getNestedTypes() {
+      return Collections.unmodifiableList(Arrays.asList(nestedTypes));
+    }
+
+    /** Get a list of enum types nested within this one. */
+    public List<EnumDescriptor> getEnumTypes() {
+      return Collections.unmodifiableList(Arrays.asList(enumTypes));
+    }
+
+    /** Determines if the given field number is an extension. */
+    public boolean isExtensionNumber(final int number) {
+      for (final DescriptorProto.ExtensionRange range :
+          proto.getExtensionRangeList()) {
+        if (range.getStart() <= number && number < range.getEnd()) {
+          return true;
+        }
+      }
+      return false;
+    }
+
+    /**
+     * Indicates whether the message can be extended.  That is, whether it has
+     * any "extensions x to y" ranges declared on it.
+     */
+    public boolean isExtendable() {
+      return proto.getExtensionRangeList().size() != 0;
+    }
+
+    /**
+     * Finds a field by name.
+     * @param name The unqualified name of the field (e.g. "foo").
+     * @return The field's descriptor, or {@code null} if not found.
+     */
+    public FieldDescriptor findFieldByName(final String name) {
+      final GenericDescriptor result =
+          file.pool.findSymbol(fullName + '.' + name);
+      if (result != null && result instanceof FieldDescriptor) {
+        return (FieldDescriptor)result;
+      } else {
+        return null;
+      }
+    }
+
+    /**
+     * Finds a field by field number.
+     * @param number The field number within this message type.
+     * @return The field's descriptor, or {@code null} if not found.
+     */
+    public FieldDescriptor findFieldByNumber(final int number) {
+      return file.pool.fieldsByNumber.get(
+        new DescriptorPool.DescriptorIntPair(this, number));
+    }
+
+    /**
+     * Finds a nested message type by name.
+     * @param name The unqualified name of the nested type (e.g. "Foo").
+     * @return The types's descriptor, or {@code null} if not found.
+     */
+    public Descriptor findNestedTypeByName(final String name) {
+      final GenericDescriptor result =
+          file.pool.findSymbol(fullName + '.' + name);
+      if (result != null && result instanceof Descriptor) {
+        return (Descriptor)result;
+      } else {
+        return null;
+      }
+    }
+
+    /**
+     * Finds a nested enum type by name.
+     * @param name The unqualified name of the nested type (e.g. "Foo").
+     * @return The types's descriptor, or {@code null} if not found.
+     */
+    public EnumDescriptor findEnumTypeByName(final String name) {
+      final GenericDescriptor result =
+          file.pool.findSymbol(fullName + '.' + name);
+      if (result != null && result instanceof EnumDescriptor) {
+        return (EnumDescriptor)result;
+      } else {
+        return null;
+      }
+    }
+
+    private final int index;
+    private DescriptorProto proto;
+    private final String fullName;
+    private final FileDescriptor file;
+    private final Descriptor containingType;
+    private final Descriptor[] nestedTypes;
+    private final EnumDescriptor[] enumTypes;
+    private final FieldDescriptor[] fields;
+    private final FieldDescriptor[] extensions;
+    private final OneofDescriptor[] oneofs;
+
+    // Used to create a placeholder when the type cannot be found.
+    Descriptor(final String fullname) throws DescriptorValidationException {
+      String name = fullname;
+      String packageName = "";
+      int pos = fullname.lastIndexOf('.');
+      if (pos != -1) {
+        name = fullname.substring(pos + 1);
+        packageName = fullname.substring(0, pos);
+      }
+      this.index = 0;
+      this.proto = DescriptorProto.newBuilder().setName(name).addExtensionRange(
+          DescriptorProto.ExtensionRange.newBuilder().setStart(1)
+          .setEnd(536870912).build()).build();
+      this.fullName = fullname;
+      this.containingType = null;
+
+      this.nestedTypes = new Descriptor[0];
+      this.enumTypes = new EnumDescriptor[0];
+      this.fields = new FieldDescriptor[0];
+      this.extensions = new FieldDescriptor[0];
+      this.oneofs = new OneofDescriptor[0];
+      
+      // Create a placeholder FileDescriptor to hold this message.
+      this.file = new FileDescriptor(packageName, this);
+    }
+
+    private Descriptor(final DescriptorProto proto,
+                       final FileDescriptor file,
+                       final Descriptor parent,
+                       final int index)
+                throws DescriptorValidationException {
+      this.index = index;
+      this.proto = proto;
+      fullName = computeFullName(file, parent, proto.getName());
+      this.file = file;
+      containingType = parent;
+
+      oneofs = new OneofDescriptor[proto.getOneofDeclCount()];
+      for (int i = 0; i < proto.getOneofDeclCount(); i++) {
+        oneofs[i] = new OneofDescriptor(
+          proto.getOneofDecl(i), file, this, i);
+      }
+
+      nestedTypes = new Descriptor[proto.getNestedTypeCount()];
+      for (int i = 0; i < proto.getNestedTypeCount(); i++) {
+        nestedTypes[i] = new Descriptor(
+          proto.getNestedType(i), file, this, i);
+      }
+
+      enumTypes = new EnumDescriptor[proto.getEnumTypeCount()];
+      for (int i = 0; i < proto.getEnumTypeCount(); i++) {
+        enumTypes[i] = new EnumDescriptor(
+          proto.getEnumType(i), file, this, i);
+      }
+
+      fields = new FieldDescriptor[proto.getFieldCount()];
+      for (int i = 0; i < proto.getFieldCount(); i++) {
+        fields[i] = new FieldDescriptor(
+          proto.getField(i), file, this, i, false);
+      }
+
+      extensions = new FieldDescriptor[proto.getExtensionCount()];
+      for (int i = 0; i < proto.getExtensionCount(); i++) {
+        extensions[i] = new FieldDescriptor(
+          proto.getExtension(i), file, this, i, true);
+      }
+
+      for (int i = 0; i < proto.getOneofDeclCount(); i++) {
+        oneofs[i].fields = new FieldDescriptor[oneofs[i].getFieldCount()];
+        oneofs[i].fieldCount = 0;
+      }
+      for (int i = 0; i < proto.getFieldCount(); i++) {
+        OneofDescriptor oneofDescriptor = fields[i].getContainingOneof();
+        if (oneofDescriptor != null) {
+          oneofDescriptor.fields[oneofDescriptor.fieldCount++] = fields[i];
+        }
+      }
+
+      file.pool.addSymbol(this);
+    }
+
+    /** Look up and cross-link all field types, etc. */
+    private void crossLink() throws DescriptorValidationException {
+      for (final Descriptor nestedType : nestedTypes) {
+        nestedType.crossLink();
+      }
+
+      for (final FieldDescriptor field : fields) {
+        field.crossLink();
+      }
+
+      for (final FieldDescriptor extension : extensions) {
+        extension.crossLink();
+      }
+    }
+
+    /** See {@link FileDescriptor#setProto}. */
+    private void setProto(final DescriptorProto proto) {
+      this.proto = proto;
+
+      for (int i = 0; i < nestedTypes.length; i++) {
+        nestedTypes[i].setProto(proto.getNestedType(i));
+      }
+
+      for (int i = 0; i < enumTypes.length; i++) {
+        enumTypes[i].setProto(proto.getEnumType(i));
+      }
+
+      for (int i = 0; i < fields.length; i++) {
+        fields[i].setProto(proto.getField(i));
+      }
+
+      for (int i = 0; i < extensions.length; i++) {
+        extensions[i].setProto(proto.getExtension(i));
+      }
+    }
+  }
+
+  // =================================================================
+
+  /** Describes a field of a message type. */
+  public static final class FieldDescriptor
+        extends GenericDescriptor
+        implements Comparable<FieldDescriptor>,
+                 FieldSet.FieldDescriptorLite<FieldDescriptor> {
+    /**
+     * Get the index of this descriptor within its parent.
+     * @see Descriptors.Descriptor#getIndex()
+     */
+    public int getIndex() { return index; }
+
+    /** Convert the descriptor to its protocol message representation. */
+    public FieldDescriptorProto toProto() { return proto; }
+
+    /** Get the field's unqualified name. */
+    public String getName() { return proto.getName(); }
+
+    /** Get the field's number. */
+    public int getNumber() { return proto.getNumber(); }
+
+    /**
+     * Get the field's fully-qualified name.
+     * @see Descriptors.Descriptor#getFullName()
+     */
+    public String getFullName() { return fullName; }
+
+    /**
+     * Get the field's java type.  This is just for convenience.  Every
+     * {@code FieldDescriptorProto.Type} maps to exactly one Java type.
+     */
+    public JavaType getJavaType() { return type.getJavaType(); }
+
+    /** For internal use only. */
+    public WireFormat.JavaType getLiteJavaType() {
+      return getLiteType().getJavaType();
+    }
+
+    /** Get the {@code FileDescriptor} containing this descriptor. */
+    public FileDescriptor getFile() { return file; }
+
+    /** Get the field's declared type. */
+    public Type getType() { return type; }
+
+    /** For internal use only. */
+    public WireFormat.FieldType getLiteType() {
+      return table[type.ordinal()];
+    }
+
+    /** For internal use only. */
+    public boolean needsUtf8Check() {
+      return (type == Type.STRING) && (getFile().getOptions().getJavaStringCheckUtf8());
+    }
+
+    // I'm pretty sure values() constructs a new array every time, since there
+    // is nothing stopping the caller from mutating the array.  Therefore we
+    // make a static copy here.
+    private static final WireFormat.FieldType[] table =
+        WireFormat.FieldType.values();
+
+    /** Is this field declared required? */
+    public boolean isRequired() {
+      return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REQUIRED;
+    }
+
+    /** Is this field declared optional? */
+    public boolean isOptional() {
+      return proto.getLabel() == FieldDescriptorProto.Label.LABEL_OPTIONAL;
+    }
+
+    /** Is this field declared repeated? */
+    public boolean isRepeated() {
+      return proto.getLabel() == FieldDescriptorProto.Label.LABEL_REPEATED;
+    }
+
+    /** Does this field have the {@code [packed = true]} option? */
+    public boolean isPacked() {
+      return getOptions().getPacked();
+    }
+
+    /** Can this field be packed? i.e. is it a repeated primitive field? */
+    public boolean isPackable() {
+      return isRepeated() && getLiteType().isPackable();
+    }
+
+    /** Returns true if the field had an explicitly-defined default value. */
+    public boolean hasDefaultValue() { return proto.hasDefaultValue(); }
+
+    /**
+     * Returns the field's default value.  Valid for all types except for
+     * messages and groups.  For all other types, the object returned is of
+     * the same class that would returned by Message.getField(this).
+     */
+    public Object getDefaultValue() {
+      if (getJavaType() == JavaType.MESSAGE) {
+        throw new UnsupportedOperationException(
+          "FieldDescriptor.getDefaultValue() called on an embedded message " +
+          "field.");
+      }
+      return defaultValue;
+    }
+
+    /** Get the {@code FieldOptions}, defined in {@code descriptor.proto}. */
+    public FieldOptions getOptions() { return proto.getOptions(); }
+
+    /** Is this field an extension? */
+    public boolean isExtension() { return proto.hasExtendee(); }
+
+    /**
+     * Get the field's containing type. For extensions, this is the type being
+     * extended, not the location where the extension was defined.  See
+     * {@link #getExtensionScope()}.
+     */
+    public Descriptor getContainingType() { return containingType; }
+
+    /** Get the field's containing oneof. */
+    public OneofDescriptor getContainingOneof() { return containingOneof; }
+
+    /**
+     * For extensions defined nested within message types, gets the outer
+     * type.  Not valid for non-extension fields.  For example, consider
+     * this {@code .proto} file:
+     * <pre>
+     *   message Foo {
+     *     extensions 1000 to max;
+     *   }
+     *   extend Foo {
+     *     optional int32 baz = 1234;
+     *   }
+     *   message Bar {
+     *     extend Foo {
+     *       optional int32 qux = 4321;
+     *     }
+     *   }
+     * </pre>
+     * Both {@code baz}'s and {@code qux}'s containing type is {@code Foo}.
+     * However, {@code baz}'s extension scope is {@code null} while
+     * {@code qux}'s extension scope is {@code Bar}.
+     */
+    public Descriptor getExtensionScope() {
+      if (!isExtension()) {
+        throw new UnsupportedOperationException(
+          "This field is not an extension.");
+      }
+      return extensionScope;
+    }
+
+    /** For embedded message and group fields, gets the field's type. */
+    public Descriptor getMessageType() {
+      if (getJavaType() != JavaType.MESSAGE) {
+        throw new UnsupportedOperationException(
+          "This field is not of message type.");
+      }
+      return messageType;
+    }
+
+    /** For enum fields, gets the field's type. */
+    public EnumDescriptor getEnumType() {
+      if (getJavaType() != JavaType.ENUM) {
+        throw new UnsupportedOperationException(
+          "This field is not of enum type.");
+      }
+      return enumType;
+    }
+
+    /**
+     * Compare with another {@code FieldDescriptor}.  This orders fields in
+     * "canonical" order, which simply means ascending order by field number.
+     * {@code other} must be a field of the same type -- i.e.
+     * {@code getContainingType()} must return the same {@code Descriptor} for
+     * both fields.
+     *
+     * @return negative, zero, or positive if {@code this} is less than,
+     *         equal to, or greater than {@code other}, respectively.
+     */
+    public int compareTo(final FieldDescriptor other) {
+      if (other.containingType != containingType) {
+        throw new IllegalArgumentException(
+          "FieldDescriptors can only be compared to other FieldDescriptors " +
+          "for fields of the same message type.");
+      }
+      return getNumber() - other.getNumber();
+    }
+
+    private final int index;
+
+    private FieldDescriptorProto proto;
+    private final String fullName;
+    private final FileDescriptor file;
+    private final Descriptor extensionScope;
+
+    // Possibly initialized during cross-linking.
+    private Type type;
+    private Descriptor containingType;
+    private Descriptor messageType;
+    private OneofDescriptor containingOneof;
+    private EnumDescriptor enumType;
+    private Object defaultValue;
+
+    public enum Type {
+      DOUBLE  (JavaType.DOUBLE     ),
+      FLOAT   (JavaType.FLOAT      ),
+      INT64   (JavaType.LONG       ),
+      UINT64  (JavaType.LONG       ),
+      INT32   (JavaType.INT        ),
+      FIXED64 (JavaType.LONG       ),
+      FIXED32 (JavaType.INT        ),
+      BOOL    (JavaType.BOOLEAN    ),
+      STRING  (JavaType.STRING     ),
+      GROUP   (JavaType.MESSAGE    ),
+      MESSAGE (JavaType.MESSAGE    ),
+      BYTES   (JavaType.BYTE_STRING),
+      UINT32  (JavaType.INT        ),
+      ENUM    (JavaType.ENUM       ),
+      SFIXED32(JavaType.INT        ),
+      SFIXED64(JavaType.LONG       ),
+      SINT32  (JavaType.INT        ),
+      SINT64  (JavaType.LONG       );
+
+      Type(final JavaType javaType) {
+        this.javaType = javaType;
+      }
+
+      private JavaType javaType;
+
+      public FieldDescriptorProto.Type toProto() {
+        return FieldDescriptorProto.Type.valueOf(ordinal() + 1);
+      }
+      public JavaType getJavaType() { return javaType; }
+
+      public static Type valueOf(final FieldDescriptorProto.Type type) {
+        return values()[type.getNumber() - 1];
+      }
+    }
+
+    static {
+      // Refuse to init if someone added a new declared type.
+      if (Type.values().length != FieldDescriptorProto.Type.values().length) {
+        throw new RuntimeException(
+          "descriptor.proto has a new declared type but Desrciptors.java " +
+          "wasn't updated.");
+      }
+    }
+
+    public enum JavaType {
+      INT(0),
+      LONG(0L),
+      FLOAT(0F),
+      DOUBLE(0D),
+      BOOLEAN(false),
+      STRING(""),
+      BYTE_STRING(ByteString.EMPTY),
+      ENUM(null),
+      MESSAGE(null);
+
+      JavaType(final Object defaultDefault) {
+        this.defaultDefault = defaultDefault;
+      }
+
+      /**
+       * The default default value for fields of this type, if it's a primitive
+       * type.  This is meant for use inside this file only, hence is private.
+       */
+      private final Object defaultDefault;
+    }
+
+    private FieldDescriptor(final FieldDescriptorProto proto,
+                            final FileDescriptor file,
+                            final Descriptor parent,
+                            final int index,
+                            final boolean isExtension)
+                     throws DescriptorValidationException {
+      this.index = index;
+      this.proto = proto;
+      fullName = computeFullName(file, parent, proto.getName());
+      this.file = file;
+
+      if (proto.hasType()) {
+        type = Type.valueOf(proto.getType());
+      }
+
+      if (getNumber() <= 0) {
+        throw new DescriptorValidationException(this,
+          "Field numbers must be positive integers.");
+      }
+
+      if (isExtension) {
+        if (!proto.hasExtendee()) {
+          throw new DescriptorValidationException(this,
+            "FieldDescriptorProto.extendee not set for extension field.");
+        }
+        containingType = null;  // Will be filled in when cross-linking
+        if (parent != null) {
+          extensionScope = parent;
+        } else {
+          extensionScope = null;
+        }
+
+        if (proto.hasOneofIndex()) {
+          throw new DescriptorValidationException(this,
+            "FieldDescriptorProto.oneof_index set for extension field.");
+        }
+        containingOneof = null;
+      } else {
+        if (proto.hasExtendee()) {
+          throw new DescriptorValidationException(this,
+            "FieldDescriptorProto.extendee set for non-extension field.");
+        }
+        containingType = parent;
+
+        if (proto.hasOneofIndex()) {
+          if (proto.getOneofIndex() < 0 ||
+              proto.getOneofIndex() >= parent.toProto().getOneofDeclCount()) {
+            throw new DescriptorValidationException(this,
+              "FieldDescriptorProto.oneof_index is out of range for type "
+              + parent.getName());
+          }
+          containingOneof = parent.getOneofs().get(proto.getOneofIndex());
+          containingOneof.fieldCount++;
+        } else {
+          containingOneof = null;
+        }
+        extensionScope = null;
+      }
+
+      file.pool.addSymbol(this);
+    }
+
+    /** Look up and cross-link all field types, etc. */
+    private void crossLink() throws DescriptorValidationException {
+      if (proto.hasExtendee()) {
+        final GenericDescriptor extendee =
+          file.pool.lookupSymbol(proto.getExtendee(), this,
+              DescriptorPool.SearchFilter.TYPES_ONLY);
+        if (!(extendee instanceof Descriptor)) {
+          throw new DescriptorValidationException(this,
+              '\"' + proto.getExtendee() + "\" is not a message type.");
+        }
+        containingType = (Descriptor)extendee;
+
+        if (!getContainingType().isExtensionNumber(getNumber())) {
+          throw new DescriptorValidationException(this,
+              '\"' + getContainingType().getFullName() +
+              "\" does not declare " + getNumber() +
+              " as an extension number.");
+        }
+      }
+
+      if (proto.hasTypeName()) {
+        final GenericDescriptor typeDescriptor =
+          file.pool.lookupSymbol(proto.getTypeName(), this,
+              DescriptorPool.SearchFilter.TYPES_ONLY);
+
+        if (!proto.hasType()) {
+          // Choose field type based on symbol.
+          if (typeDescriptor instanceof Descriptor) {
+            type = Type.MESSAGE;
+          } else if (typeDescriptor instanceof EnumDescriptor) {
+            type = Type.ENUM;
+          } else {
+            throw new DescriptorValidationException(this,
+                '\"' + proto.getTypeName() + "\" is not a type.");
+          }
+        }
+
+        if (getJavaType() == JavaType.MESSAGE) {
+          if (!(typeDescriptor instanceof Descriptor)) {
+            throw new DescriptorValidationException(this,
+                '\"' + proto.getTypeName() + "\" is not a message type.");
+          }
+          messageType = (Descriptor)typeDescriptor;
+
+          if (proto.hasDefaultValue()) {
+            throw new DescriptorValidationException(this,
+              "Messages can't have default values.");
+          }
+        } else if (getJavaType() == JavaType.ENUM) {
+          if (!(typeDescriptor instanceof EnumDescriptor)) {
+            throw new DescriptorValidationException(this,
+                '\"' + proto.getTypeName() + "\" is not an enum type.");
+          }
+          enumType = (EnumDescriptor)typeDescriptor;
+        } else {
+          throw new DescriptorValidationException(this,
+            "Field with primitive type has type_name.");
+        }
+      } else {
+        if (getJavaType() == JavaType.MESSAGE ||
+            getJavaType() == JavaType.ENUM) {
+          throw new DescriptorValidationException(this,
+            "Field with message or enum type missing type_name.");
+        }
+      }
+
+      // Only repeated primitive fields may be packed.
+      if (proto.getOptions().getPacked() && !isPackable()) {
+        throw new DescriptorValidationException(this,
+          "[packed = true] can only be specified for repeated primitive " +
+          "fields.");
+      }
+
+      // We don't attempt to parse the default value until here because for
+      // enums we need the enum type's descriptor.
+      if (proto.hasDefaultValue()) {
+        if (isRepeated()) {
+          throw new DescriptorValidationException(this,
+            "Repeated fields cannot have default values.");
+        }
+
+        try {
+          switch (getType()) {
+            case INT32:
+            case SINT32:
+            case SFIXED32:
+              defaultValue = TextFormat.parseInt32(proto.getDefaultValue());
+              break;
+            case UINT32:
+            case FIXED32:
+              defaultValue = TextFormat.parseUInt32(proto.getDefaultValue());
+              break;
+            case INT64:
+            case SINT64:
+            case SFIXED64:
+              defaultValue = TextFormat.parseInt64(proto.getDefaultValue());
+              break;
+            case UINT64:
+            case FIXED64:
+              defaultValue = TextFormat.parseUInt64(proto.getDefaultValue());
+              break;
+            case FLOAT:
+              if (proto.getDefaultValue().equals("inf")) {
+                defaultValue = Float.POSITIVE_INFINITY;
+              } else if (proto.getDefaultValue().equals("-inf")) {
+                defaultValue = Float.NEGATIVE_INFINITY;
+              } else if (proto.getDefaultValue().equals("nan")) {
+                defaultValue = Float.NaN;
+              } else {
+                defaultValue = Float.valueOf(proto.getDefaultValue());
+              }
+              break;
+            case DOUBLE:
+              if (proto.getDefaultValue().equals("inf")) {
+                defaultValue = Double.POSITIVE_INFINITY;
+              } else if (proto.getDefaultValue().equals("-inf")) {
+                defaultValue = Double.NEGATIVE_INFINITY;
+              } else if (proto.getDefaultValue().equals("nan")) {
+                defaultValue = Double.NaN;
+              } else {
+                defaultValue = Double.valueOf(proto.getDefaultValue());
+              }
+              break;
+            case BOOL:
+              defaultValue = Boolean.valueOf(proto.getDefaultValue());
+              break;
+            case STRING:
+              defaultValue = proto.getDefaultValue();
+              break;
+            case BYTES:
+              try {
+                defaultValue =
+                  TextFormat.unescapeBytes(proto.getDefaultValue());
+              } catch (TextFormat.InvalidEscapeSequenceException e) {
+                throw new DescriptorValidationException(this,
+                  "Couldn't parse default value: " + e.getMessage(), e);
+              }
+              break;
+            case ENUM:
+              defaultValue = enumType.findValueByName(proto.getDefaultValue());
+              if (defaultValue == null) {
+                throw new DescriptorValidationException(this,
+                  "Unknown enum default value: \"" +
+                  proto.getDefaultValue() + '\"');
+              }
+              break;
+            case MESSAGE:
+            case GROUP:
+              throw new DescriptorValidationException(this,
+                "Message type had default value.");
+          }
+        } catch (NumberFormatException e) {
+          throw new DescriptorValidationException(this, 
+              "Could not parse default value: \"" + 
+              proto.getDefaultValue() + '\"', e);
+        }
+      } else {
+        // Determine the default default for this field.
+        if (isRepeated()) {
+          defaultValue = Collections.emptyList();
+        } else {
+          switch (getJavaType()) {
+            case ENUM:
+              // We guarantee elsewhere that an enum type always has at least
+              // one possible value.
+              defaultValue = enumType.getValues().get(0);
+              break;
+            case MESSAGE:
+              defaultValue = null;
+              break;
+            default:
+              defaultValue = getJavaType().defaultDefault;
+              break;
+          }
+        }
+      }
+
+      if (!isExtension()) {
+        file.pool.addFieldByNumber(this);
+      }
+
+      if (containingType != null &&
+          containingType.getOptions().getMessageSetWireFormat()) {
+        if (isExtension()) {
+          if (!isOptional() || getType() != Type.MESSAGE) {
+            throw new DescriptorValidationException(this,
+              "Extensions of MessageSets must be optional messages.");
+          }
+        } else {
+          throw new DescriptorValidationException(this,
+            "MessageSets cannot have fields, only extensions.");
+        }
+      }
+    }
+
+    /** See {@link FileDescriptor#setProto}. */
+    private void setProto(final FieldDescriptorProto proto) {
+      this.proto = proto;
+    }
+
+    /**
+     * For internal use only.  This is to satisfy the FieldDescriptorLite
+     * interface.
+     */
+    public MessageLite.Builder internalMergeFrom(
+        MessageLite.Builder to, MessageLite from) {
+      // FieldDescriptors are only used with non-lite messages so we can just
+      // down-cast and call mergeFrom directly.
+      return ((Message.Builder) to).mergeFrom((Message) from);
+    }
+
+  }
+
+  // =================================================================
+
+  /** Describes an enum type. */
+  public static final class EnumDescriptor extends GenericDescriptor
+      implements Internal.EnumLiteMap<EnumValueDescriptor> {
+    /**
+     * Get the index of this descriptor within its parent.
+     * @see Descriptors.Descriptor#getIndex()
+     */
+    public int getIndex() { return index; }
+
+    /** Convert the descriptor to its protocol message representation. */
+    public EnumDescriptorProto toProto() { return proto; }
+
+    /** Get the type's unqualified name. */
+    public String getName() { return proto.getName(); }
+
+    /**
+     * Get the type's fully-qualified name.
+     * @see Descriptors.Descriptor#getFullName()
+     */
+    public String getFullName() { return fullName; }
+
+    /** Get the {@link FileDescriptor} containing this descriptor. */
+    public FileDescriptor getFile() { return file; }
+
+    /** If this is a nested type, get the outer descriptor, otherwise null. */
+    public Descriptor getContainingType() { return containingType; }
+
+    /** Get the {@code EnumOptions}, defined in {@code descriptor.proto}. */
+    public EnumOptions getOptions() { return proto.getOptions(); }
+
+    /** Get a list of defined values for this enum. */
+    public List<EnumValueDescriptor> getValues() {
+      return Collections.unmodifiableList(Arrays.asList(values));
+    }
+
+    /**
+     * Find an enum value by name.
+     * @param name The unqualified name of the value (e.g. "FOO").
+     * @return the value's descriptor, or {@code null} if not found.
+     */
+    public EnumValueDescriptor findValueByName(final String name) {
+      final GenericDescriptor result =
+          file.pool.findSymbol(fullName + '.' + name);
+      if (result != null && result instanceof EnumValueDescriptor) {
+        return (EnumValueDescriptor)result;
+      } else {
+        return null;
+      }
+    }
+
+    /**
+     * Find an enum value by number.  If multiple enum values have the same
+     * number, this returns the first defined value with that number.
+     * @param number The value's number.
+     * @return the value's descriptor, or {@code null} if not found.
+     */
+    public EnumValueDescriptor findValueByNumber(final int number) {
+      return file.pool.enumValuesByNumber.get(
+        new DescriptorPool.DescriptorIntPair(this, number));
+    }
+
+    private final int index;
+    private EnumDescriptorProto proto;
+    private final String fullName;
+    private final FileDescriptor file;
+    private final Descriptor containingType;
+    private EnumValueDescriptor[] values;
+
+    private EnumDescriptor(final EnumDescriptorProto proto,
+                           final FileDescriptor file,
+                           final Descriptor parent,
+                           final int index)
+                    throws DescriptorValidationException {
+      this.index = index;
+      this.proto = proto;
+      fullName = computeFullName(file, parent, proto.getName());
+      this.file = file;
+      containingType = parent;
+
+      if (proto.getValueCount() == 0) {
+        // We cannot allow enums with no values because this would mean there
+        // would be no valid default value for fields of this type.
+        throw new DescriptorValidationException(this,
+          "Enums must contain at least one value.");
+      }
+
+      values = new EnumValueDescriptor[proto.getValueCount()];
+      for (int i = 0; i < proto.getValueCount(); i++) {
+        values[i] = new EnumValueDescriptor(
+          proto.getValue(i), file, this, i);
+      }
+
+      file.pool.addSymbol(this);
+    }
+
+    /** See {@link FileDescriptor#setProto}. */
+    private void setProto(final EnumDescriptorProto proto) {
+      this.proto = proto;
+
+      for (int i = 0; i < values.length; i++) {
+        values[i].setProto(proto.getValue(i));
+      }
+    }
+  }
+
+  // =================================================================
+
+  /**
+   * Describes one value within an enum type.  Note that multiple defined
+   * values may have the same number.  In generated Java code, all values
+   * with the same number after the first become aliases of the first.
+   * However, they still have independent EnumValueDescriptors.
+   */
+  public static final class EnumValueDescriptor extends GenericDescriptor
+      implements Internal.EnumLite {
+    /**
+     * Get the index of this descriptor within its parent.
+     * @see Descriptors.Descriptor#getIndex()
+     */
+    public int getIndex() { return index; }
+
+    /** Convert the descriptor to its protocol message representation. */
+    public EnumValueDescriptorProto toProto() { return proto; }
+
+    /** Get the value's unqualified name. */
+    public String getName() { return proto.getName(); }
+
+    /** Get the value's number. */
+    public int getNumber() { return proto.getNumber(); }
+    
+    @Override
+    public String toString() { return proto.getName(); }
+
+    /**
+     * Get the value's fully-qualified name.
+     * @see Descriptors.Descriptor#getFullName()
+     */
+    public String getFullName() { return fullName; }
+
+    /** Get the {@link FileDescriptor} containing this descriptor. */
+    public FileDescriptor getFile() { return file; }
+
+    /** Get the value's enum type. */
+    public EnumDescriptor getType() { return type; }
+
+    /**
+     * Get the {@code EnumValueOptions}, defined in {@code descriptor.proto}.
+     */
+    public EnumValueOptions getOptions() { return proto.getOptions(); }
+
+    private final int index;
+    private EnumValueDescriptorProto proto;
+    private final String fullName;
+    private final FileDescriptor file;
+    private final EnumDescriptor type;
+
+    private EnumValueDescriptor(final EnumValueDescriptorProto proto,
+                                final FileDescriptor file,
+                                final EnumDescriptor parent,
+                                final int index)
+                         throws DescriptorValidationException {
+      this.index = index;
+      this.proto = proto;
+      this.file = file;
+      type = parent;
+
+      fullName = parent.getFullName() + '.' + proto.getName();
+
+      file.pool.addSymbol(this);
+      file.pool.addEnumValueByNumber(this);
+    }
+
+    /** See {@link FileDescriptor#setProto}. */
+    private void setProto(final EnumValueDescriptorProto proto) {
+      this.proto = proto;
+    }
+  }
+
+  // =================================================================
+
+  /** Describes a service type. */
+  public static final class ServiceDescriptor extends GenericDescriptor {
+    /**
+     * Get the index of this descriptor within its parent.
+     * * @see Descriptors.Descriptor#getIndex()
+     */
+    public int getIndex() { return index; }
+
+    /** Convert the descriptor to its protocol message representation. */
+    public ServiceDescriptorProto toProto() { return proto; }
+
+    /** Get the type's unqualified name. */
+    public String getName() { return proto.getName(); }
+
+    /**
+     * Get the type's fully-qualified name.
+     * @see Descriptors.Descriptor#getFullName()
+     */
+    public String getFullName() { return fullName; }
+
+    /** Get the {@link FileDescriptor} containing this descriptor. */
+    public FileDescriptor getFile() { return file; }
+
+    /** Get the {@code ServiceOptions}, defined in {@code descriptor.proto}. */
+    public ServiceOptions getOptions() { return proto.getOptions(); }
+
+    /** Get a list of methods for this service. */
+    public List<MethodDescriptor> getMethods() {
+      return Collections.unmodifiableList(Arrays.asList(methods));
+    }
+
+    /**
+     * Find a method by name.
+     * @param name The unqualified name of the method (e.g. "Foo").
+     * @return the method's descriptor, or {@code null} if not found.
+     */
+    public MethodDescriptor findMethodByName(final String name) {
+      final GenericDescriptor result =
+          file.pool.findSymbol(fullName + '.' + name);
+      if (result != null && result instanceof MethodDescriptor) {
+        return (MethodDescriptor)result;
+      } else {
+        return null;
+      }
+    }
+
+    private final int index;
+    private ServiceDescriptorProto proto;
+    private final String fullName;
+    private final FileDescriptor file;
+    private MethodDescriptor[] methods;
+
+    private ServiceDescriptor(final ServiceDescriptorProto proto,
+                              final FileDescriptor file,
+                              final int index)
+                       throws DescriptorValidationException {
+      this.index = index;
+      this.proto = proto;
+      fullName = computeFullName(file, null, proto.getName());
+      this.file = file;
+
+      methods = new MethodDescriptor[proto.getMethodCount()];
+      for (int i = 0; i < proto.getMethodCount(); i++) {
+        methods[i] = new MethodDescriptor(
+          proto.getMethod(i), file, this, i);
+      }
+
+      file.pool.addSymbol(this);
+    }
+
+    private void crossLink() throws DescriptorValidationException {
+      for (final MethodDescriptor method : methods) {
+        method.crossLink();
+      }
+    }
+
+    /** See {@link FileDescriptor#setProto}. */
+    private void setProto(final ServiceDescriptorProto proto) {
+      this.proto = proto;
+
+      for (int i = 0; i < methods.length; i++) {
+        methods[i].setProto(proto.getMethod(i));
+      }
+    }
+  }
+
+  // =================================================================
+
+  /**
+   * Describes one method within a service type.
+   */
+  public static final class MethodDescriptor extends GenericDescriptor {
+    /**
+     * Get the index of this descriptor within its parent.
+     * * @see Descriptors.Descriptor#getIndex()
+     */
+    public int getIndex() { return index; }
+
+    /** Convert the descriptor to its protocol message representation. */
+    public MethodDescriptorProto toProto() { return proto; }
+
+    /** Get the method's unqualified name. */
+    public String getName() { return proto.getName(); }
+
+    /**
+     * Get the method's fully-qualified name.
+     * @see Descriptors.Descriptor#getFullName()
+     */
+    public String getFullName() { return fullName; }
+
+    /** Get the {@link FileDescriptor} containing this descriptor. */
+    public FileDescriptor getFile() { return file; }
+
+    /** Get the method's service type. */
+    public ServiceDescriptor getService() { return service; }
+
+    /** Get the method's input type. */
+    public Descriptor getInputType() { return inputType; }
+
+    /** Get the method's output type. */
+    public Descriptor getOutputType() { return outputType; }
+
+    /**
+     * Get the {@code MethodOptions}, defined in {@code descriptor.proto}.
+     */
+    public MethodOptions getOptions() { return proto.getOptions(); }
+
+    private final int index;
+    private MethodDescriptorProto proto;
+    private final String fullName;
+    private final FileDescriptor file;
+    private final ServiceDescriptor service;
+
+    // Initialized during cross-linking.
+    private Descriptor inputType;
+    private Descriptor outputType;
+
+    private MethodDescriptor(final MethodDescriptorProto proto,
+                             final FileDescriptor file,
+                             final ServiceDescriptor parent,
+                             final int index)
+                      throws DescriptorValidationException {
+      this.index = index;
+      this.proto = proto;
+      this.file = file;
+      service = parent;
+
+      fullName = parent.getFullName() + '.' + proto.getName();
+
+      file.pool.addSymbol(this);
+    }
+
+    private void crossLink() throws DescriptorValidationException {
+      final GenericDescriptor input =
+        file.pool.lookupSymbol(proto.getInputType(), this,
+            DescriptorPool.SearchFilter.TYPES_ONLY);
+      if (!(input instanceof Descriptor)) {
+        throw new DescriptorValidationException(this,
+            '\"' + proto.getInputType() + "\" is not a message type.");
+      }
+      inputType = (Descriptor)input;
+
+      final GenericDescriptor output =
+        file.pool.lookupSymbol(proto.getOutputType(), this,
+            DescriptorPool.SearchFilter.TYPES_ONLY);
+      if (!(output instanceof Descriptor)) {
+        throw new DescriptorValidationException(this,
+            '\"' + proto.getOutputType() + "\" is not a message type.");
+      }
+      outputType = (Descriptor)output;
+    }
+
+    /** See {@link FileDescriptor#setProto}. */
+    private void setProto(final MethodDescriptorProto proto) {
+      this.proto = proto;
+    }
+  }
+
+  // =================================================================
+
+  private static String computeFullName(final FileDescriptor file,
+                                        final Descriptor parent,
+                                        final String name) {
+    if (parent != null) {
+      return parent.getFullName() + '.' + name;
+    } else if (file.getPackage().length() > 0) {
+      return file.getPackage() + '.' + name;
+    } else {
+      return name;
+    }
+  }
+
+  // =================================================================
+
+  /**
+   * All descriptors implement this to make it easier to implement tools like
+   * {@code DescriptorPool}.<p>
+   *
+   * This class is public so that the methods it exposes can be called from
+   * outside of this package. However, it should only be subclassed from
+   * nested classes of Descriptors.
+   */
+  public abstract static class GenericDescriptor {
+    public abstract Message toProto();
+    public abstract String getName();
+    public abstract String getFullName();
+    public abstract FileDescriptor getFile();
+  }
+
+  /**
+   * Thrown when building descriptors fails because the source DescriptorProtos
+   * are not valid.
+   */
+  public static class DescriptorValidationException extends Exception {
+    private static final long serialVersionUID = 5750205775490483148L;
+
+    /** Gets the full name of the descriptor where the error occurred. */
+    public String getProblemSymbolName() { return name; }
+
+    /**
+     * Gets the protocol message representation of the invalid descriptor.
+     */
+    public Message getProblemProto() { return proto; }
+
+    /**
+     * Gets a human-readable description of the error.
+     */
+    public String getDescription() { return description; }
+
+    private final String name;
+    private final Message proto;
+    private final String description;
+
+    private DescriptorValidationException(
+        final GenericDescriptor problemDescriptor,
+        final String description) {
+      super(problemDescriptor.getFullName() + ": " + description);
+
+      // Note that problemDescriptor may be partially uninitialized, so we
+      // don't want to expose it directly to the user.  So, we only provide
+      // the name and the original proto.
+      name = problemDescriptor.getFullName();
+      proto = problemDescriptor.toProto();
+      this.description = description;
+    }
+
+    private DescriptorValidationException(
+        final GenericDescriptor problemDescriptor,
+        final String description,
+        final Throwable cause) {
+      this(problemDescriptor, description);
+      initCause(cause);
+    }
+
+    private DescriptorValidationException(
+        final FileDescriptor problemDescriptor,
+        final String description) {
+      super(problemDescriptor.getName() + ": " + description);
+
+      // Note that problemDescriptor may be partially uninitialized, so we
+      // don't want to expose it directly to the user.  So, we only provide
+      // the name and the original proto.
+      name = problemDescriptor.getName();
+      proto = problemDescriptor.toProto();
+      this.description = description;
+    }
+  }
+
+  // =================================================================
+
+  /**
+   * A private helper class which contains lookup tables containing all the
+   * descriptors defined in a particular file.
+   */
+  private static final class DescriptorPool {
+    
+    /** Defines what subclass of descriptors to search in the descriptor pool. 
+     */
+    enum SearchFilter {
+      TYPES_ONLY, AGGREGATES_ONLY, ALL_SYMBOLS
+    }
+    
+    DescriptorPool(final FileDescriptor[] dependencies,
+        boolean allowUnknownDependencies) {
+      this.dependencies = new HashSet<FileDescriptor>();
+      this.allowUnknownDependencies = allowUnknownDependencies;
+
+      for (int i = 0; i < dependencies.length; i++) {
+        this.dependencies.add(dependencies[i]);
+        importPublicDependencies(dependencies[i]);
+      }
+
+      for (final FileDescriptor dependency : this.dependencies) {
+        try {
+          addPackage(dependency.getPackage(), dependency);
+        } catch (DescriptorValidationException e) {
+          // Can't happen, because addPackage() only fails when the name
+          // conflicts with a non-package, but we have not yet added any
+          // non-packages at this point.
+          assert false;
+        }
+      }
+    }
+
+    /** Find and put public dependencies of the file into dependencies set.*/
+    private void importPublicDependencies(final FileDescriptor file) {
+      for (FileDescriptor dependency : file.getPublicDependencies()) {
+        if (dependencies.add(dependency)) {
+          importPublicDependencies(dependency);
+        }
+      }
+    }
+
+    private final Set<FileDescriptor> dependencies;
+    private boolean allowUnknownDependencies;
+
+    private final Map<String, GenericDescriptor> descriptorsByName =
+      new HashMap<String, GenericDescriptor>();
+    private final Map<DescriptorIntPair, FieldDescriptor> fieldsByNumber =
+      new HashMap<DescriptorIntPair, FieldDescriptor>();
+    private final Map<DescriptorIntPair, EnumValueDescriptor> enumValuesByNumber
+        = new HashMap<DescriptorIntPair, EnumValueDescriptor>();
+
+    /** Find a generic descriptor by fully-qualified name. */
+    GenericDescriptor findSymbol(final String fullName) {
+      return findSymbol(fullName, SearchFilter.ALL_SYMBOLS);
+    }
+    
+    /** Find a descriptor by fully-qualified name and given option to only 
+     * search valid field type descriptors. 
+     */
+    GenericDescriptor findSymbol(final String fullName,
+                                 final SearchFilter filter) {
+      GenericDescriptor result = descriptorsByName.get(fullName);
+      if (result != null) {
+        if ((filter==SearchFilter.ALL_SYMBOLS) ||
+            ((filter==SearchFilter.TYPES_ONLY) && isType(result)) ||
+            ((filter==SearchFilter.AGGREGATES_ONLY) && isAggregate(result))) {
+          return result;
+        }
+      }
+
+      for (final FileDescriptor dependency : dependencies) {
+        result = dependency.pool.descriptorsByName.get(fullName);
+        if (result != null) {
+          if ((filter==SearchFilter.ALL_SYMBOLS) ||
+              ((filter==SearchFilter.TYPES_ONLY) && isType(result)) ||
+              ((filter==SearchFilter.AGGREGATES_ONLY) && isAggregate(result))) {
+            return result;
+          }
+        }
+      }
+
+      return null;
+    }
+
+    /** Checks if the descriptor is a valid type for a message field. */
+    boolean isType(GenericDescriptor descriptor) {
+      return (descriptor instanceof Descriptor) || 
+        (descriptor instanceof EnumDescriptor);
+    }
+    
+    /** Checks if the descriptor is a valid namespace type. */
+    boolean isAggregate(GenericDescriptor descriptor) {
+      return (descriptor instanceof Descriptor) || 
+        (descriptor instanceof EnumDescriptor) || 
+        (descriptor instanceof PackageDescriptor) || 
+        (descriptor instanceof ServiceDescriptor);
+    }
+       
+    /**
+     * Look up a type descriptor by name, relative to some other descriptor.
+     * The name may be fully-qualified (with a leading '.'),
+     * partially-qualified, or unqualified.  C++-like name lookup semantics
+     * are used to search for the matching descriptor.
+     */
+    GenericDescriptor lookupSymbol(final String name,
+                                   final GenericDescriptor relativeTo,
+                                   final DescriptorPool.SearchFilter filter)
+                            throws DescriptorValidationException {
+      // TODO(kenton):  This could be optimized in a number of ways.
+
+      GenericDescriptor result;
+      String fullname;
+      if (name.startsWith(".")) {
+        // Fully-qualified name.
+        fullname = name.substring(1);
+        result = findSymbol(fullname, filter);
+      } else {
+        // If "name" is a compound identifier, we want to search for the
+        // first component of it, then search within it for the rest.
+        // 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.
+        final int firstPartLength = name.indexOf('.');
+        final String firstPart;
+        if (firstPartLength == -1) {
+          firstPart = name;
+        } else {
+          firstPart = name.substring(0, firstPartLength);
+        }
+
+        // We will search each parent scope of "relativeTo" looking for the
+        // symbol.
+        final StringBuilder scopeToTry =
+            new StringBuilder(relativeTo.getFullName());
+
+        while (true) {
+          // Chop off the last component of the scope.
+          final int dotpos = scopeToTry.lastIndexOf(".");
+          if (dotpos == -1) {
+            fullname = name;
+            result = findSymbol(name, filter);
+            break;
+          } else {
+            scopeToTry.setLength(dotpos + 1);
+
+            // Append firstPart and try to find
+            scopeToTry.append(firstPart);
+            result = findSymbol(scopeToTry.toString(), 
+                DescriptorPool.SearchFilter.AGGREGATES_ONLY);
+
+            if (result != null) {
+              if (firstPartLength != -1) {
+                // We only found the first part of the symbol.  Now look for
+                // the whole thing.  If this fails, we *don't* want to keep
+                // searching parent scopes.
+                scopeToTry.setLength(dotpos + 1);
+                scopeToTry.append(name);
+                result = findSymbol(scopeToTry.toString(), filter);
+              }
+              fullname = scopeToTry.toString();
+              break;
+            }
+
+            // Not found.  Remove the name so we can try again.
+            scopeToTry.setLength(dotpos);
+          }
+        }
+      }
+
+      if (result == null) {
+        if (allowUnknownDependencies && filter == SearchFilter.TYPES_ONLY) {
+          logger.warning("The descriptor for message type \"" + name +
+              "\" can not be found and a placeholder is created for it");
+          // We create a dummy message descriptor here regardless of the
+          // expected type. If the type should be message, this dummy
+          // descriptor will work well and if the type should be enum, a
+          // DescriptorValidationException will be thrown latter. In either
+          // case, the code works as expected: we allow unknown message types
+          // but not unknwon enum types.
+          result = new Descriptor(fullname);
+          // Add the placeholder file as a dependency so we can find the
+          // placeholder symbol when resolving other references.
+          this.dependencies.add(result.getFile());
+          return result;
+        } else {
+          throw new DescriptorValidationException(relativeTo,
+              '\"' + name + "\" is not defined.");
+        }
+      } else {
+        return result;
+      }
+    }
+
+    /**
+     * Adds a symbol to the symbol table.  If a symbol with the same name
+     * already exists, throws an error.
+     */
+    void addSymbol(final GenericDescriptor descriptor)
+            throws DescriptorValidationException {
+      validateSymbolName(descriptor);
+
+      final String fullName = descriptor.getFullName();
+      final int dotpos = fullName.lastIndexOf('.');
+
+      final GenericDescriptor old = descriptorsByName.put(fullName, descriptor);
+      if (old != null) {
+        descriptorsByName.put(fullName, old);
+
+        if (descriptor.getFile() == old.getFile()) {
+          if (dotpos == -1) {
+            throw new DescriptorValidationException(descriptor,
+                '\"' + fullName + "\" is already defined.");
+          } else {
+            throw new DescriptorValidationException(descriptor,
+                '\"' + fullName.substring(dotpos + 1) +
+              "\" is already defined in \"" +
+              fullName.substring(0, dotpos) + "\".");
+          }
+        } else {
+          throw new DescriptorValidationException(descriptor,
+              '\"' + fullName + "\" is already defined in file \"" +
+            old.getFile().getName() + "\".");
+        }
+      }
+    }
+
+    /**
+     * Represents a package in the symbol table.  We use PackageDescriptors
+     * just as placeholders so that someone cannot define, say, a message type
+     * that has the same name as an existing package.
+     */
+    private static final class PackageDescriptor extends GenericDescriptor {
+      public Message toProto()        { return file.toProto(); }
+      public String getName()         { return name;           }
+      public String getFullName()     { return fullName;       }
+      public FileDescriptor getFile() { return file;           }
+
+      PackageDescriptor(final String name, final String fullName,
+                        final FileDescriptor file) {
+        this.file = file;
+        this.fullName = fullName;
+        this.name = name;
+      }
+
+      private final String name;
+      private final String fullName;
+      private final FileDescriptor file;
+    }
+
+    /**
+     * Adds a package to the symbol tables.  If a package by the same name
+     * already exists, that is fine, but if some other kind of symbol exists
+     * under the same name, an exception is thrown.  If the package has
+     * multiple components, this also adds the parent package(s).
+     */
+    void addPackage(final String fullName, final FileDescriptor file)
+             throws DescriptorValidationException {
+      final int dotpos = fullName.lastIndexOf('.');
+      final String name;
+      if (dotpos == -1) {
+        name = fullName;
+      } else {
+        addPackage(fullName.substring(0, dotpos), file);
+        name = fullName.substring(dotpos + 1);
+      }
+
+      final GenericDescriptor old =
+        descriptorsByName.put(fullName,
+          new PackageDescriptor(name, fullName, file));
+      if (old != null) {
+        descriptorsByName.put(fullName, old);
+        if (!(old instanceof PackageDescriptor)) {
+          throw new DescriptorValidationException(file,
+              '\"' + name + "\" is already defined (as something other than a "
+              + "package) in file \"" + old.getFile().getName() + "\".");
+        }
+      }
+    }
+
+    /** A (GenericDescriptor, int) pair, used as a map key. */
+    private static final class DescriptorIntPair {
+      private final GenericDescriptor descriptor;
+      private final int number;
+
+      DescriptorIntPair(final GenericDescriptor descriptor, final int number) {
+        this.descriptor = descriptor;
+        this.number = number;
+      }
+
+      @Override
+      public int hashCode() {
+        return descriptor.hashCode() * ((1 << 16) - 1) + number;
+      }
+      @Override
+      public boolean equals(final Object obj) {
+        if (!(obj instanceof DescriptorIntPair)) {
+          return false;
+        }
+        final DescriptorIntPair other = (DescriptorIntPair)obj;
+        return descriptor == other.descriptor && number == other.number;
+      }
+    }
+
+    /**
+     * Adds a field to the fieldsByNumber table.  Throws an exception if a
+     * field with the same containing type and number already exists.
+     */
+    void addFieldByNumber(final FieldDescriptor field)
+                   throws DescriptorValidationException {
+      final DescriptorIntPair key =
+        new DescriptorIntPair(field.getContainingType(), field.getNumber());
+      final FieldDescriptor old = fieldsByNumber.put(key, field);
+      if (old != null) {
+        fieldsByNumber.put(key, old);
+        throw new DescriptorValidationException(field,
+          "Field number " + field.getNumber() +
+          " has already been used in \"" +
+          field.getContainingType().getFullName() +
+          "\" by field \"" + old.getName() + "\".");
+      }
+    }
+
+    /**
+     * Adds an enum value to the enumValuesByNumber table.  If an enum value
+     * with the same type and number already exists, does nothing.  (This is
+     * allowed; the first value define with the number takes precedence.)
+     */
+    void addEnumValueByNumber(final EnumValueDescriptor value) {
+      final DescriptorIntPair key =
+        new DescriptorIntPair(value.getType(), value.getNumber());
+      final EnumValueDescriptor old = enumValuesByNumber.put(key, value);
+      if (old != null) {
+        enumValuesByNumber.put(key, old);
+        // Not an error:  Multiple enum values may have the same number, but
+        // we only want the first one in the map.
+      }
+    }
+
+    /**
+     * Verifies that the descriptor's name is valid (i.e. it contains only
+     * letters, digits, and underscores, and does not start with a digit).
+     */
+    static void validateSymbolName(final GenericDescriptor descriptor)
+                                   throws DescriptorValidationException {
+      final String name = descriptor.getName();
+      if (name.length() == 0) {
+        throw new DescriptorValidationException(descriptor, "Missing name.");
+      } else {
+        boolean valid = true;
+        for (int i = 0; i < name.length(); i++) {
+          final char c = name.charAt(i);
+          // Non-ASCII characters are not valid in protobuf identifiers, even
+          // if they are letters or digits.
+          if (c >= 128) {
+            valid = false;
+          }
+          // First character must be letter or _.  Subsequent characters may
+          // be letters, numbers, or digits.
+          if (Character.isLetter(c) || c == '_' ||
+              (Character.isDigit(c) && i > 0)) {
+            // Valid
+          } else {
+            valid = false;
+          }
+        }
+        if (!valid) {
+          throw new DescriptorValidationException(descriptor,
+              '\"' + name + "\" is not a valid identifier.");
+        }
+      }
+    }
+  }
+
+  /** Describes an oneof of a message type. */
+  public static final class OneofDescriptor {
+    /** Get the index of this descriptor within its parent. */
+    public int getIndex() { return index; }
+
+    public String getName() { return proto.getName(); }
+
+    public FileDescriptor getFile() { return file; }
+
+    public String getFullName() { return fullName; }
+
+    public Descriptor getContainingType() { return containingType; }
+
+    public int getFieldCount() { return fieldCount; }
+
+    public FieldDescriptor getField(int index) {
+      return fields[index];
+    }
+
+    private OneofDescriptor(final OneofDescriptorProto proto,
+                            final FileDescriptor file,
+                            final Descriptor parent,
+                            final int index)
+                     throws DescriptorValidationException {
+      this.proto = proto;
+      fullName = computeFullName(file, parent, proto.getName());
+      this.file = file;
+      this.index = index;
+
+      containingType = parent;
+      fieldCount = 0;
+    }
+
+    private final int index;
+    private OneofDescriptorProto proto;
+    private final String fullName;
+    private final FileDescriptor file;
+
+    private Descriptor containingType;
+    private int fieldCount;
+    private FieldDescriptor[] fields;
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/DynamicMessage.java b/protobuf/java/src/main/java/com/google/protobuf/DynamicMessage.java
new file mode 100644
index 0000000..c9ce667
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/DynamicMessage.java
@@ -0,0 +1,622 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.OneofDescriptor;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * An implementation of {@link Message} that can represent arbitrary types,
+ * given a {@link Descriptors.Descriptor}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class DynamicMessage extends AbstractMessage {
+  private final Descriptor type;
+  private final FieldSet<FieldDescriptor> fields;
+  private final FieldDescriptor[] oneofCases;
+  private final UnknownFieldSet unknownFields;
+  private int memoizedSize = -1;
+
+  /**
+   * Construct a {@code DynamicMessage} using the given {@code FieldSet}.
+   * oneofCases stores the FieldDescriptor for each oneof to indicate
+   * which field is set. Caller should make sure the array is immutable.
+   *
+   * This contructor is package private and will be used in
+   * {@code DynamicMutableMessage} to convert a mutable message to an immutable
+   * message.
+   */
+  DynamicMessage(Descriptor type, FieldSet<FieldDescriptor> fields,
+                 FieldDescriptor[] oneofCases,
+                 UnknownFieldSet unknownFields) {
+    this.type = type;
+    this.fields = fields;
+    this.oneofCases = oneofCases;
+    this.unknownFields = unknownFields;
+  }
+
+  /**
+   * Get a {@code DynamicMessage} representing the default instance of the
+   * given type.
+   */
+  public static DynamicMessage getDefaultInstance(Descriptor type) {
+    int oneofDeclCount = type.toProto().getOneofDeclCount();
+    FieldDescriptor[] oneofCases = new FieldDescriptor[oneofDeclCount];
+    return new DynamicMessage(type, FieldSet.<FieldDescriptor>emptySet(),
+                              oneofCases,
+                              UnknownFieldSet.getDefaultInstance());
+  }
+
+
+  /** Parse a message of the given type from the given input stream. */
+  public static DynamicMessage parseFrom(Descriptor type,
+                                         CodedInputStream input)
+                                         throws IOException {
+    return newBuilder(type).mergeFrom(input).buildParsed();
+  }
+
+  /** Parse a message of the given type from the given input stream. */
+  public static DynamicMessage parseFrom(
+      Descriptor type,
+      CodedInputStream input,
+      ExtensionRegistry extensionRegistry)
+      throws IOException {
+    return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed();
+  }
+
+  /** Parse {@code data} as a message of the given type and return it. */
+  public static DynamicMessage parseFrom(Descriptor type, ByteString data)
+                                         throws InvalidProtocolBufferException {
+    return newBuilder(type).mergeFrom(data).buildParsed();
+  }
+
+  /** Parse {@code data} as a message of the given type and return it. */
+  public static DynamicMessage parseFrom(Descriptor type, ByteString data,
+                                         ExtensionRegistry extensionRegistry)
+                                         throws InvalidProtocolBufferException {
+    return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed();
+  }
+
+  /** Parse {@code data} as a message of the given type and return it. */
+  public static DynamicMessage parseFrom(Descriptor type, byte[] data)
+                                         throws InvalidProtocolBufferException {
+    return newBuilder(type).mergeFrom(data).buildParsed();
+  }
+
+  /** Parse {@code data} as a message of the given type and return it. */
+  public static DynamicMessage parseFrom(Descriptor type, byte[] data,
+                                         ExtensionRegistry extensionRegistry)
+                                         throws InvalidProtocolBufferException {
+    return newBuilder(type).mergeFrom(data, extensionRegistry).buildParsed();
+  }
+
+  /** Parse a message of the given type from {@code input} and return it. */
+  public static DynamicMessage parseFrom(Descriptor type, InputStream input)
+                                         throws IOException {
+    return newBuilder(type).mergeFrom(input).buildParsed();
+  }
+
+  /** Parse a message of the given type from {@code input} and return it. */
+  public static DynamicMessage parseFrom(Descriptor type, InputStream input,
+                                         ExtensionRegistry extensionRegistry)
+                                         throws IOException {
+    return newBuilder(type).mergeFrom(input, extensionRegistry).buildParsed();
+  }
+
+  /** Construct a {@link Message.Builder} for the given type. */
+  public static Builder newBuilder(Descriptor type) {
+    return new Builder(type);
+  }
+
+  /**
+   * Construct a {@link Message.Builder} for a message of the same type as
+   * {@code prototype}, and initialize it with {@code prototype}'s contents.
+   */
+  public static Builder newBuilder(Message prototype) {
+    return new Builder(prototype.getDescriptorForType()).mergeFrom(prototype);
+  }
+
+  // -----------------------------------------------------------------
+  // Implementation of Message interface.
+
+  public Descriptor getDescriptorForType() {
+    return type;
+  }
+
+  public DynamicMessage getDefaultInstanceForType() {
+    return getDefaultInstance(type);
+  }
+
+  public Map<FieldDescriptor, Object> getAllFields() {
+    return fields.getAllFields();
+  }
+
+  public boolean hasOneof(OneofDescriptor oneof) {
+    verifyOneofContainingType(oneof);
+    FieldDescriptor field = oneofCases[oneof.getIndex()];
+    if (field == null) {
+      return false;
+    }
+    return true;
+  }
+
+  public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
+    verifyOneofContainingType(oneof);
+    return oneofCases[oneof.getIndex()];
+  }
+
+  public boolean hasField(FieldDescriptor field) {
+    verifyContainingType(field);
+    return fields.hasField(field);
+  }
+
+  public Object getField(FieldDescriptor field) {
+    verifyContainingType(field);
+    Object result = fields.getField(field);
+    if (result == null) {
+      if (field.isRepeated()) {
+        result = Collections.emptyList();
+      } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+        result = getDefaultInstance(field.getMessageType());
+      } else {
+        result = field.getDefaultValue();
+      }
+    }
+    return result;
+  }
+
+  public int getRepeatedFieldCount(FieldDescriptor field) {
+    verifyContainingType(field);
+    return fields.getRepeatedFieldCount(field);
+  }
+
+  public Object getRepeatedField(FieldDescriptor field, int index) {
+    verifyContainingType(field);
+    return fields.getRepeatedField(field, index);
+  }
+
+  public UnknownFieldSet getUnknownFields() {
+    return unknownFields;
+  }
+
+  static boolean isInitialized(Descriptor type,
+                               FieldSet<FieldDescriptor> fields) {
+    // Check that all required fields are present.
+    for (final FieldDescriptor field : type.getFields()) {
+      if (field.isRequired()) {
+        if (!fields.hasField(field)) {
+          return false;
+        }
+      }
+    }
+
+    // Check that embedded messages are initialized.
+    return fields.isInitialized();
+  }
+
+  @Override
+  public boolean isInitialized() {
+    return isInitialized(type, fields);
+  }
+
+  @Override
+  public void writeTo(CodedOutputStream output) throws IOException {
+    if (type.getOptions().getMessageSetWireFormat()) {
+      fields.writeMessageSetTo(output);
+      unknownFields.writeAsMessageSetTo(output);
+    } else {
+      fields.writeTo(output);
+      unknownFields.writeTo(output);
+    }
+  }
+
+  @Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    if (type.getOptions().getMessageSetWireFormat()) {
+      size = fields.getMessageSetSerializedSize();
+      size += unknownFields.getSerializedSizeAsMessageSet();
+    } else {
+      size = fields.getSerializedSize();
+      size += unknownFields.getSerializedSize();
+    }
+
+    memoizedSize = size;
+    return size;
+  }
+
+  public Builder newBuilderForType() {
+    return new Builder(type);
+  }
+
+  public Builder toBuilder() {
+    return newBuilderForType().mergeFrom(this);
+  }
+
+  public Parser<DynamicMessage> getParserForType() {
+    return new AbstractParser<DynamicMessage>() {
+      public DynamicMessage parsePartialFrom(
+          CodedInputStream input,
+          ExtensionRegistryLite extensionRegistry)
+          throws InvalidProtocolBufferException {
+        Builder builder = newBuilder(type);
+        try {
+          builder.mergeFrom(input, extensionRegistry);
+        } catch (InvalidProtocolBufferException e) {
+          throw e.setUnfinishedMessage(builder.buildPartial());
+        } catch (IOException e) {
+          throw new InvalidProtocolBufferException(e.getMessage())
+              .setUnfinishedMessage(builder.buildPartial());
+        }
+        return builder.buildPartial();
+      }
+    };
+  }
+
+  /** Verifies that the field is a field of this message. */
+  private void verifyContainingType(FieldDescriptor field) {
+    if (field.getContainingType() != type) {
+      throw new IllegalArgumentException(
+        "FieldDescriptor does not match message type.");
+    }
+  }
+
+  /** Verifies that the oneof is an oneof of this message. */
+  private void verifyOneofContainingType(OneofDescriptor oneof) {
+    if (oneof.getContainingType() != type) {
+      throw new IllegalArgumentException(
+        "OneofDescriptor does not match message type.");
+    }
+  }
+
+  // =================================================================
+
+  /**
+   * Builder for {@link DynamicMessage}s.
+   */
+  public static final class Builder extends AbstractMessage.Builder<Builder> {
+    private final Descriptor type;
+    private FieldSet<FieldDescriptor> fields;
+    private final FieldDescriptor[] oneofCases;
+    private UnknownFieldSet unknownFields;
+
+    /** Construct a {@code Builder} for the given type. */
+    private Builder(Descriptor type) {
+      this.type = type;
+      this.fields = FieldSet.newFieldSet();
+      this.unknownFields = UnknownFieldSet.getDefaultInstance();
+      this.oneofCases = new FieldDescriptor[type.toProto().getOneofDeclCount()];
+    }
+
+    // ---------------------------------------------------------------
+    // Implementation of Message.Builder interface.
+
+    @Override
+    public Builder clear() {
+      if (fields.isImmutable()) {
+        fields = FieldSet.newFieldSet();
+      } else {
+        fields.clear();
+      }
+      unknownFields = UnknownFieldSet.getDefaultInstance();
+      return this;
+    }
+
+    @Override
+    public Builder mergeFrom(Message other) {
+      if (other instanceof DynamicMessage) {
+        // This should be somewhat faster than calling super.mergeFrom().
+        DynamicMessage otherDynamicMessage = (DynamicMessage) other;
+        if (otherDynamicMessage.type != type) {
+          throw new IllegalArgumentException(
+            "mergeFrom(Message) can only merge messages of the same type.");
+        }
+        ensureIsMutable();
+        fields.mergeFrom(otherDynamicMessage.fields);
+        mergeUnknownFields(otherDynamicMessage.unknownFields);
+        for (int i = 0; i < oneofCases.length; i++) {
+          if (oneofCases[i] == null) {
+            oneofCases[i] = otherDynamicMessage.oneofCases[i];
+          } else {
+            if ((otherDynamicMessage.oneofCases[i] != null)
+                && (oneofCases[i] != otherDynamicMessage.oneofCases[i])) {
+              fields.clearField(oneofCases[i]);
+              oneofCases[i] = otherDynamicMessage.oneofCases[i];
+            }
+          }
+        }
+        return this;
+      } else {
+        return super.mergeFrom(other);
+      }
+    }
+
+    public DynamicMessage build() {
+      if (!isInitialized()) {
+        throw newUninitializedMessageException(
+          new DynamicMessage(type, fields,
+              java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields));
+      }
+      return buildPartial();
+    }
+
+    /**
+     * Helper for DynamicMessage.parseFrom() methods to call.  Throws
+     * {@link InvalidProtocolBufferException} instead of
+     * {@link UninitializedMessageException}.
+     */
+    private DynamicMessage buildParsed() throws InvalidProtocolBufferException {
+      if (!isInitialized()) {
+        throw newUninitializedMessageException(
+          new DynamicMessage(type, fields,
+              java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields))
+          .asInvalidProtocolBufferException();
+      }
+      return buildPartial();
+    }
+
+    public DynamicMessage buildPartial() {
+      fields.makeImmutable();
+      DynamicMessage result =
+        new DynamicMessage(type, fields,
+            java.util.Arrays.copyOf(oneofCases, oneofCases.length), unknownFields);
+      return result;
+    }
+
+    @Override
+    public Builder clone() {
+      Builder result = new Builder(type);
+      result.fields.mergeFrom(fields);
+      result.mergeUnknownFields(unknownFields);
+      System.arraycopy(oneofCases, 0, result.oneofCases, 0 , oneofCases.length);
+      return result;
+    }
+
+    public boolean isInitialized() {
+      return DynamicMessage.isInitialized(type, fields);
+    }
+
+    public Descriptor getDescriptorForType() {
+      return type;
+    }
+
+    public DynamicMessage getDefaultInstanceForType() {
+      return getDefaultInstance(type);
+    }
+
+    public Map<FieldDescriptor, Object> getAllFields() {
+      return fields.getAllFields();
+    }
+
+    public Builder newBuilderForField(FieldDescriptor field) {
+      verifyContainingType(field);
+
+      if (field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
+        throw new IllegalArgumentException(
+          "newBuilderForField is only valid for fields with message type.");
+      }
+
+      return new Builder(field.getMessageType());
+    }
+
+    public boolean hasOneof(OneofDescriptor oneof) {
+      verifyOneofContainingType(oneof);
+      FieldDescriptor field = oneofCases[oneof.getIndex()];
+      if (field == null) {
+        return false;
+      }
+      return true;
+    }
+
+    public FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof) {
+      verifyOneofContainingType(oneof);
+      return oneofCases[oneof.getIndex()];
+    }
+
+    public Builder clearOneof(OneofDescriptor oneof) {
+      verifyOneofContainingType(oneof);
+      FieldDescriptor field = oneofCases[oneof.getIndex()];
+      if (field != null) {
+        clearField(field);
+      }
+      return this;
+    }
+
+    public boolean hasField(FieldDescriptor field) {
+      verifyContainingType(field);
+      return fields.hasField(field);
+    }
+
+    public Object getField(FieldDescriptor field) {
+      verifyContainingType(field);
+      Object result = fields.getField(field);
+      if (result == null) {
+        if (field.isRepeated()) {
+          result = Collections.emptyList();
+        } else if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+          result = getDefaultInstance(field.getMessageType());
+        } else {
+          result = field.getDefaultValue();
+        }
+      }
+      return result;
+    }
+
+    public Builder setField(FieldDescriptor field, Object value) {
+      verifyContainingType(field);
+      ensureIsMutable();
+      // TODO(xiaofeng): This check should really be put in FieldSet.setField()
+      // where all other such checks are done. However, currently
+      // FieldSet.setField() permits Integer value for enum fields probably
+      // because of some internal features we support. Should figure it out
+      // and move this check to a more appropriate place.
+      if (field.getType() == FieldDescriptor.Type.ENUM) {
+        ensureEnumValueDescriptor(field, value);
+      }
+      OneofDescriptor oneofDescriptor = field.getContainingOneof();
+      if (oneofDescriptor != null) {
+        int index = oneofDescriptor.getIndex();
+        FieldDescriptor oldField = oneofCases[index];
+        if ((oldField != null) && (oldField != field)) {
+          fields.clearField(oldField);
+        }
+        oneofCases[index] = field;
+      }
+      fields.setField(field, value);
+      return this;
+    }
+
+    public Builder clearField(FieldDescriptor field) {
+      verifyContainingType(field);
+      ensureIsMutable();
+      OneofDescriptor oneofDescriptor = field.getContainingOneof();
+      if (oneofDescriptor != null) {
+        int index = oneofDescriptor.getIndex();
+        if (oneofCases[index] == field) {
+          oneofCases[index] = null;
+        }
+      }
+      fields.clearField(field);
+      return this;
+    }
+
+    public int getRepeatedFieldCount(FieldDescriptor field) {
+      verifyContainingType(field);
+      return fields.getRepeatedFieldCount(field);
+    }
+
+    public Object getRepeatedField(FieldDescriptor field, int index) {
+      verifyContainingType(field);
+      return fields.getRepeatedField(field, index);
+    }
+
+    public Builder setRepeatedField(FieldDescriptor field,
+                                    int index, Object value) {
+      verifyContainingType(field);
+      ensureIsMutable();
+      fields.setRepeatedField(field, index, value);
+      return this;
+    }
+
+    public Builder addRepeatedField(FieldDescriptor field, Object value) {
+      verifyContainingType(field);
+      ensureIsMutable();
+      fields.addRepeatedField(field, value);
+      return this;
+    }
+
+    public UnknownFieldSet getUnknownFields() {
+      return unknownFields;
+    }
+
+    public Builder setUnknownFields(UnknownFieldSet unknownFields) {
+      this.unknownFields = unknownFields;
+      return this;
+    }
+
+    @Override
+    public Builder mergeUnknownFields(UnknownFieldSet unknownFields) {
+      this.unknownFields =
+        UnknownFieldSet.newBuilder(this.unknownFields)
+                       .mergeFrom(unknownFields)
+                       .build();
+      return this;
+    }
+
+    /** Verifies that the field is a field of this message. */
+    private void verifyContainingType(FieldDescriptor field) {
+      if (field.getContainingType() != type) {
+        throw new IllegalArgumentException(
+          "FieldDescriptor does not match message type.");
+      }
+    }
+
+    /** Verifies that the oneof is an oneof of this message. */
+    private void verifyOneofContainingType(OneofDescriptor oneof) {
+      if (oneof.getContainingType() != type) {
+        throw new IllegalArgumentException(
+          "OneofDescriptor does not match message type.");
+      }
+    }
+
+    /** Verifies that the value is EnumValueDescriptor and matches Enum Type. */
+    private void ensureSingularEnumValueDescriptor(
+        FieldDescriptor field, Object value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      if (!(value instanceof EnumValueDescriptor)) {
+        throw new IllegalArgumentException(
+          "DynamicMessage should use EnumValueDescriptor to set Enum Value.");
+      }
+      if (field.getEnumType() != ((EnumValueDescriptor) value).getType()) {
+        throw new IllegalArgumentException(
+          "EnumValueDescriptor doesn't much Enum Field.");
+      }
+    }
+
+    /** Verifies the value for an enum field. */
+    private void ensureEnumValueDescriptor(
+        FieldDescriptor field, Object value) {
+      if (field.isRepeated()) {
+        for (Object item : (List) value) {
+          ensureSingularEnumValueDescriptor(field, item);
+        }
+      } else {
+         ensureSingularEnumValueDescriptor(field, value);
+      }
+    }
+
+    private void ensureIsMutable() {
+      if (fields.isImmutable()) {
+        fields = fields.clone();
+      }
+    }
+
+    @Override
+    public com.google.protobuf.Message.Builder getFieldBuilder(FieldDescriptor field) {
+      // TODO(xiangl): need implementation for dynamic message
+      throw new UnsupportedOperationException(
+        "getFieldBuilder() called on a dynamic message type.");
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/Extension.java b/protobuf/java/src/main/java/com/google/protobuf/Extension.java
new file mode 100644
index 0000000..0baa22b
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/Extension.java
@@ -0,0 +1,96 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Interface that generated extensions implement.
+ *
+ * @author liujisi@google.com (Jisi Liu)
+ */
+public abstract class Extension<ContainingType extends MessageLite, Type> {
+  /** Returns the field number of the extension. */
+  public abstract int getNumber();
+
+  /** Returns the type of the field. */
+  public abstract WireFormat.FieldType getLiteType();
+
+  /** Returns whether it is a repeated field. */
+  public abstract boolean isRepeated();
+
+  /** Returns the descriptor of the extension. */
+  public abstract Descriptors.FieldDescriptor getDescriptor();
+
+  /** Returns the default value of the extension field. */
+  public abstract Type getDefaultValue();
+
+  /**
+   * Returns the default instance of the extension field, if it's a message
+   * extension.
+   */
+  public abstract MessageLite getMessageDefaultInstance();
+
+  // All the methods below are extension implementation details.
+
+  /**
+   * The API type that the extension is used for.
+   */
+  protected enum ExtensionType {
+    IMMUTABLE,
+    MUTABLE,
+    PROTO1,
+  }
+
+  protected ExtensionType getExtensionType() {
+    // TODO(liujisi): make this abstract after we fix proto1.
+    return ExtensionType.IMMUTABLE;
+  }
+
+  /**
+   * Type of a message extension.
+   */
+  public enum MessageType {
+    PROTO1,
+    PROTO2,
+  }
+  
+  /**
+   * If the extension is a message extension (i.e., getLiteType() == MESSAGE),
+   * returns the type of the message, otherwise undefined.
+   */
+  public MessageType getMessageType() {
+    return MessageType.PROTO2;
+  }
+
+  protected abstract Object fromReflectionType(Object value);
+  protected abstract Object singularFromReflectionType(Object value);
+  protected abstract Object toReflectionType(Object value);
+  protected abstract Object singularToReflectionType(Object value);
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistry.java b/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
new file mode 100644
index 0000000..0067392
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistry.java
@@ -0,0 +1,392 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A table of known extensions, searchable by name or field number.  When
+ * parsing a protocol message that might have extensions, you must provide
+ * an {@code ExtensionRegistry} in which you have registered any extensions
+ * that you want to be able to parse.  Otherwise, those extensions will just
+ * be treated like unknown fields.
+ *
+ * <p>For example, if you had the {@code .proto} file:
+ *
+ * <pre>
+ * option java_class = "MyProto";
+ *
+ * message Foo {
+ *   extensions 1000 to max;
+ * }
+ *
+ * extend Foo {
+ *   optional int32 bar;
+ * }
+ * </pre>
+ *
+ * Then you might write code like:
+ *
+ * <pre>
+ * ExtensionRegistry registry = ExtensionRegistry.newInstance();
+ * registry.add(MyProto.bar);
+ * MyProto.Foo message = MyProto.Foo.parseFrom(input, registry);
+ * </pre>
+ *
+ * <p>Background:
+ *
+ * <p>You might wonder why this is necessary.  Two alternatives might come to
+ * mind.  First, you might imagine a system where generated extensions are
+ * automatically registered when their containing classes are loaded.  This
+ * is a popular technique, but is bad design; among other things, it creates a
+ * situation where behavior can change depending on what classes happen to be
+ * loaded.  It also introduces a security vulnerability, because an
+ * unprivileged class could cause its code to be called unexpectedly from a
+ * privileged class by registering itself as an extension of the right type.
+ *
+ * <p>Another option you might consider is lazy parsing: do not parse an
+ * extension until it is first requested, at which point the caller must
+ * provide a type to use.  This introduces a different set of problems.  First,
+ * it would require a mutex lock any time an extension was accessed, which
+ * would be slow.  Second, corrupt data would not be detected until first
+ * access, at which point it would be much harder to deal with it.  Third, it
+ * could violate the expectation that message objects are immutable, since the
+ * type provided could be any arbitrary message class.  An unprivileged user
+ * could take advantage of this to inject a mutable object into a message
+ * belonging to privileged code and create mischief.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class ExtensionRegistry extends ExtensionRegistryLite {
+  /** Construct a new, empty instance. */
+  public static ExtensionRegistry newInstance() {
+    return new ExtensionRegistry();
+  }
+
+  /** Get the unmodifiable singleton empty instance. */
+  public static ExtensionRegistry getEmptyRegistry() {
+    return EMPTY;
+  }
+
+
+  /** Returns an unmodifiable view of the registry. */
+  @Override
+  public ExtensionRegistry getUnmodifiable() {
+    return new ExtensionRegistry(this);
+  }
+
+  /** A (Descriptor, Message) pair, returned by lookup methods. */
+  public static final class ExtensionInfo {
+    /** The extension's descriptor. */
+    public final FieldDescriptor descriptor;
+
+    /**
+     * A default instance of the extension's type, if it has a message type.
+     * Otherwise, {@code null}.
+     */
+    public final Message defaultInstance;
+
+    private ExtensionInfo(final FieldDescriptor descriptor) {
+      this.descriptor = descriptor;
+      defaultInstance = null;
+    }
+    private ExtensionInfo(final FieldDescriptor descriptor,
+                          final Message defaultInstance) {
+      this.descriptor = descriptor;
+      this.defaultInstance = defaultInstance;
+    }
+  }
+
+  /**
+   * Deprecated. Use {@link #findImmutableExtensionByName(String)} instead.
+   */
+  public ExtensionInfo findExtensionByName(final String fullName) {
+    return findImmutableExtensionByName(fullName);
+  }
+
+  /**
+   * Find an extension for immutable APIs by fully-qualified field name,
+   * in the proto namespace. i.e. {@code result.descriptor.fullName()} will
+   * match {@code fullName} if a match is found.
+   *
+   * @return Information about the extension if found, or {@code null}
+   *         otherwise.
+   */
+  public ExtensionInfo findImmutableExtensionByName(final String fullName) {
+    return immutableExtensionsByName.get(fullName);
+  }
+
+  /**
+   * Find an extension for mutable APIs by fully-qualified field name,
+   * in the proto namespace. i.e. {@code result.descriptor.fullName()} will
+   * match {@code fullName} if a match is found.
+   *
+   * @return Information about the extension if found, or {@code null}
+   *         otherwise.
+   */
+  public ExtensionInfo findMutableExtensionByName(final String fullName) {
+    return mutableExtensionsByName.get(fullName);
+  }
+
+  /**
+   * Deprecated. Use {@link #findImmutableExtensionByNumber(
+   * Descriptors.Descriptor, int)}
+   */
+  public ExtensionInfo findExtensionByNumber(
+      final Descriptor containingType, final int fieldNumber) {
+    return findImmutableExtensionByNumber(containingType, fieldNumber);
+  }
+
+  /**
+   * Find an extension by containing type and field number for immutable APIs.
+   *
+   * @return Information about the extension if found, or {@code null}
+   *         otherwise.
+   */
+  public ExtensionInfo findImmutableExtensionByNumber(
+      final Descriptor containingType, final int fieldNumber) {
+    return immutableExtensionsByNumber.get(
+      new DescriptorIntPair(containingType, fieldNumber));
+  }
+
+  /**
+   * Find an extension by containing type and field number for mutable APIs.
+   *
+   * @return Information about the extension if found, or {@code null}
+   *         otherwise.
+   */
+  public ExtensionInfo findMutableExtensionByNumber(
+      final Descriptor containingType, final int fieldNumber) {
+    return mutableExtensionsByNumber.get(
+        new DescriptorIntPair(containingType, fieldNumber));
+  }
+
+  /**
+   * Find all extensions for mutable APIs by fully-qualified name of
+   * extended class. Note that this method is more computationally expensive
+   * than getting a single extension by name or number.
+   *
+   * @return Information about the extensions found, or {@code null} if there
+   *     are none.
+   */
+  public Set<ExtensionInfo> getAllMutableExtensionsByExtendedType(final String fullName) {
+    HashSet<ExtensionInfo> extensions = new HashSet<ExtensionInfo>();
+    for (DescriptorIntPair pair : mutableExtensionsByNumber.keySet()) {
+      if (pair.descriptor.getFullName().equals(fullName)) {
+        extensions.add(mutableExtensionsByNumber.get(pair));
+      }
+    }
+    return extensions;
+  }
+
+  /**
+   * Find all extensions for immutable APIs by fully-qualified name of
+   * extended class. Note that this method is more computationally expensive
+   * than getting a single extension by name or number.
+   *
+   * @return Information about the extensions found, or {@code null} if there
+   *     are none.
+   */
+  public Set<ExtensionInfo> getAllImmutableExtensionsByExtendedType(final String fullName) {
+    HashSet<ExtensionInfo> extensions = new HashSet<ExtensionInfo>();
+    for (DescriptorIntPair pair : immutableExtensionsByNumber.keySet()) {
+      if (pair.descriptor.getFullName().equals(fullName)) {
+        extensions.add(immutableExtensionsByNumber.get(pair));
+      }
+    }
+    return extensions;
+  }
+
+  /** Add an extension from a generated file to the registry. */
+  public void add(final Extension<?, ?> extension) {
+    if (extension.getExtensionType() != Extension.ExtensionType.IMMUTABLE &&
+        extension.getExtensionType() != Extension.ExtensionType.MUTABLE) {
+      // do not support other extension types. ignore
+      return;
+    }
+    add(newExtensionInfo(extension), extension.getExtensionType());
+  }
+
+  static ExtensionInfo newExtensionInfo(final Extension<?, ?> extension) {
+    if (extension.getDescriptor().getJavaType() ==
+        FieldDescriptor.JavaType.MESSAGE) {
+      if (extension.getMessageDefaultInstance() == null) {
+        throw new IllegalStateException(
+            "Registered message-type extension had null default instance: " +
+                extension.getDescriptor().getFullName());
+      }
+      return new ExtensionInfo(extension.getDescriptor(),
+          (Message) extension.getMessageDefaultInstance());
+    } else {
+      return new ExtensionInfo(extension.getDescriptor(), null);
+    }
+  }
+
+  /** Add a non-message-type extension to the registry by descriptor. */
+  public void add(final FieldDescriptor type) {
+    if (type.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+      throw new IllegalArgumentException(
+        "ExtensionRegistry.add() must be provided a default instance when " +
+        "adding an embedded message extension.");
+    }
+    ExtensionInfo info = new ExtensionInfo(type, null);
+    add(info, Extension.ExtensionType.IMMUTABLE);
+    add(info, Extension.ExtensionType.MUTABLE);
+  }
+
+  /** Add a message-type extension to the registry by descriptor. */
+  public void add(final FieldDescriptor type, final Message defaultInstance) {
+    if (type.getJavaType() != FieldDescriptor.JavaType.MESSAGE) {
+      throw new IllegalArgumentException(
+        "ExtensionRegistry.add() provided a default instance for a " +
+        "non-message extension.");
+    }
+      add(new ExtensionInfo(type, defaultInstance),
+          Extension.ExtensionType.IMMUTABLE);
+  }
+
+  // =================================================================
+  // Private stuff.
+
+  private ExtensionRegistry() {
+    this.immutableExtensionsByName = new HashMap<String, ExtensionInfo>();
+    this.mutableExtensionsByName = new HashMap<String, ExtensionInfo>();
+    this.immutableExtensionsByNumber =
+        new HashMap<DescriptorIntPair, ExtensionInfo>();
+    this.mutableExtensionsByNumber =
+        new HashMap<DescriptorIntPair, ExtensionInfo>();
+  }
+
+  private ExtensionRegistry(ExtensionRegistry other) {
+    super(other);
+    this.immutableExtensionsByName =
+        Collections.unmodifiableMap(other.immutableExtensionsByName);
+    this.mutableExtensionsByName =
+        Collections.unmodifiableMap(other.mutableExtensionsByName);
+    this.immutableExtensionsByNumber =
+        Collections.unmodifiableMap(other.immutableExtensionsByNumber);
+    this.mutableExtensionsByNumber =
+            Collections.unmodifiableMap(other.mutableExtensionsByNumber);
+  }
+
+  private final Map<String, ExtensionInfo> immutableExtensionsByName;
+  private final Map<String, ExtensionInfo> mutableExtensionsByName;
+  private final Map<DescriptorIntPair, ExtensionInfo> immutableExtensionsByNumber;
+  private final Map<DescriptorIntPair, ExtensionInfo> mutableExtensionsByNumber;
+
+  ExtensionRegistry(boolean empty) {
+    super(ExtensionRegistryLite.getEmptyRegistry());
+    this.immutableExtensionsByName =
+        Collections.<String, ExtensionInfo>emptyMap();
+    this.mutableExtensionsByName =
+        Collections.<String, ExtensionInfo>emptyMap();
+    this.immutableExtensionsByNumber =
+        Collections.<DescriptorIntPair, ExtensionInfo>emptyMap();
+    this.mutableExtensionsByNumber =
+            Collections.<DescriptorIntPair, ExtensionInfo>emptyMap();
+  }
+  private static final ExtensionRegistry EMPTY = new ExtensionRegistry(true);
+
+  private void add(
+      final ExtensionInfo extension,
+      final Extension.ExtensionType extensionType) {
+    if (!extension.descriptor.isExtension()) {
+      throw new IllegalArgumentException(
+          "ExtensionRegistry.add() was given a FieldDescriptor for a regular " +
+              "(non-extension) field.");
+    }
+
+    Map<String, ExtensionInfo> extensionsByName;
+    Map<DescriptorIntPair, ExtensionInfo> extensionsByNumber;
+    switch (extensionType) {
+      case IMMUTABLE:
+        extensionsByName = immutableExtensionsByName;
+        extensionsByNumber = immutableExtensionsByNumber;
+        break;
+      case MUTABLE:
+        extensionsByName = mutableExtensionsByName;
+        extensionsByNumber = mutableExtensionsByNumber;
+        break;
+      default:
+        // Ignore the unknown supported type.
+        return;
+    }
+
+    extensionsByName.put(extension.descriptor.getFullName(), extension);
+    extensionsByNumber.put(
+      new DescriptorIntPair(extension.descriptor.getContainingType(),
+                            extension.descriptor.getNumber()),
+      extension);
+
+    final FieldDescriptor field = extension.descriptor;
+    if (field.getContainingType().getOptions().getMessageSetWireFormat() &&
+        field.getType() == FieldDescriptor.Type.MESSAGE &&
+        field.isOptional() &&
+        field.getExtensionScope() == field.getMessageType()) {
+      // This is an extension of a MessageSet type defined within the extension
+      // type's own scope.  For backwards-compatibility, allow it to be looked
+      // up by type name.
+      extensionsByName.put(field.getMessageType().getFullName(), extension);
+    }
+  }
+
+  /** A (GenericDescriptor, int) pair, used as a map key. */
+  private static final class DescriptorIntPair {
+    private final Descriptor descriptor;
+    private final int number;
+
+    DescriptorIntPair(final Descriptor descriptor, final int number) {
+      this.descriptor = descriptor;
+      this.number = number;
+    }
+
+    @Override
+    public int hashCode() {
+      return descriptor.hashCode() * ((1 << 16) - 1) + number;
+    }
+    @Override
+    public boolean equals(final Object obj) {
+      if (!(obj instanceof DescriptorIntPair)) {
+        return false;
+      }
+      final DescriptorIntPair other = (DescriptorIntPair)obj;
+      return descriptor == other.descriptor && number == other.number;
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java b/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
new file mode 100644
index 0000000..65cf738
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
@@ -0,0 +1,185 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Equivalent to {@link ExtensionRegistry} but supports only "lite" types.
+ * <p>
+ * If all of your types are lite types, then you only need to use
+ * {@code ExtensionRegistryLite}.  Similarly, if all your types are regular
+ * types, then you only need {@link ExtensionRegistry}.  Typically it does not
+ * make sense to mix the two, since if you have any regular types in your
+ * program, you then require the full runtime and lose all the benefits of
+ * the lite runtime, so you might as well make all your types be regular types.
+ * However, in some cases (e.g. when depending on multiple third-party libraries
+ * where one uses lite types and one uses regular), you may find yourself
+ * wanting to mix the two.  In this case things get more complicated.
+ * <p>
+ * There are three factors to consider:  Whether the type being extended is
+ * lite, whether the embedded type (in the case of a message-typed extension)
+ * is lite, and whether the extension itself is lite.  Since all three are
+ * declared in different files, they could all be different.  Here are all
+ * the combinations and which type of registry to use:
+ * <pre>
+ *   Extended type     Inner type    Extension         Use registry
+ *   =======================================================================
+ *   lite              lite          lite              ExtensionRegistryLite
+ *   lite              regular       lite              ExtensionRegistry
+ *   regular           regular       regular           ExtensionRegistry
+ *   all other combinations                            not supported
+ * </pre>
+ * <p>
+ * Note that just as regular types are not allowed to contain lite-type fields,
+ * they are also not allowed to contain lite-type extensions.  This is because
+ * regular types must be fully accessible via reflection, which in turn means
+ * that all the inner messages must also support reflection.  On the other hand,
+ * since regular types implement the entire lite interface, there is no problem
+ * with embedding regular types inside lite types.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class ExtensionRegistryLite {
+
+  // Set true to enable lazy parsing feature for MessageSet.
+  //
+  // TODO(xiangl): Now we use a global flag to control whether enable lazy
+  // parsing feature for MessageSet, which may be too crude for some
+  // applications. Need to support this feature on smaller granularity.
+  private static volatile boolean eagerlyParseMessageSets = false;
+
+  public static boolean isEagerlyParseMessageSets() {
+    return eagerlyParseMessageSets;
+  }
+
+  public static void setEagerlyParseMessageSets(boolean isEagerlyParse) {
+    eagerlyParseMessageSets = isEagerlyParse;
+  }
+
+  /** Construct a new, empty instance. */
+  public static ExtensionRegistryLite newInstance() {
+    return new ExtensionRegistryLite();
+  }
+
+  /** Get the unmodifiable singleton empty instance. */
+  public static ExtensionRegistryLite getEmptyRegistry() {
+    return EMPTY;
+  }
+
+  /** Returns an unmodifiable view of the registry. */
+  public ExtensionRegistryLite getUnmodifiable() {
+    return new ExtensionRegistryLite(this);
+  }
+
+  /**
+   * Find an extension by containing type and field number.
+   *
+   * @return Information about the extension if found, or {@code null}
+   *         otherwise.
+   */
+  @SuppressWarnings("unchecked")
+  public <ContainingType extends MessageLite>
+      GeneratedMessageLite.GeneratedExtension<ContainingType, ?>
+        findLiteExtensionByNumber(
+          final ContainingType containingTypeDefaultInstance,
+          final int fieldNumber) {
+    return (GeneratedMessageLite.GeneratedExtension<ContainingType, ?>)
+      extensionsByNumber.get(
+        new ObjectIntPair(containingTypeDefaultInstance, fieldNumber));
+  }
+
+  /** Add an extension from a lite generated file to the registry. */
+  public final void add(
+      final GeneratedMessageLite.GeneratedExtension<?, ?> extension) {
+    extensionsByNumber.put(
+      new ObjectIntPair(extension.getContainingTypeDefaultInstance(),
+                        extension.getNumber()),
+      extension);
+  }
+
+  // =================================================================
+  // Private stuff.
+
+  // Constructors are package-private so that ExtensionRegistry can subclass
+  // this.
+
+  ExtensionRegistryLite() {
+    this.extensionsByNumber =
+        new HashMap<ObjectIntPair,
+                    GeneratedMessageLite.GeneratedExtension<?, ?>>();
+  }
+
+  ExtensionRegistryLite(ExtensionRegistryLite other) {
+    if (other == EMPTY) {
+      this.extensionsByNumber = Collections.emptyMap();
+    } else {
+      this.extensionsByNumber =
+        Collections.unmodifiableMap(other.extensionsByNumber);
+    }
+  }
+
+  private final Map<ObjectIntPair,
+                    GeneratedMessageLite.GeneratedExtension<?, ?>>
+      extensionsByNumber;
+
+  private ExtensionRegistryLite(boolean empty) {
+    this.extensionsByNumber = Collections.emptyMap();
+  }
+  private static final ExtensionRegistryLite EMPTY =
+    new ExtensionRegistryLite(true);
+
+  /** A (Object, int) pair, used as a map key. */
+  private static final class ObjectIntPair {
+    private final Object object;
+    private final int number;
+
+    ObjectIntPair(final Object object, final int number) {
+      this.object = object;
+      this.number = number;
+    }
+
+    @Override
+    public int hashCode() {
+      return System.identityHashCode(object) * ((1 << 16) - 1) + number;
+    }
+    @Override
+    public boolean equals(final Object obj) {
+      if (!(obj instanceof ObjectIntPair)) {
+        return false;
+      }
+      final ObjectIntPair other = (ObjectIntPair)obj;
+      return object == other.object && number == other.number;
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/FieldSet.java b/protobuf/java/src/main/java/com/google/protobuf/FieldSet.java
new file mode 100644
index 0000000..392f4ef
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/FieldSet.java
@@ -0,0 +1,907 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.LazyField.LazyIterator;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A class which represents an arbitrary set of fields of some message type.
+ * This is used to implement {@link DynamicMessage}, and also to represent
+ * extensions in {@link GeneratedMessage}.  This class is package-private,
+ * since outside users should probably be using {@link DynamicMessage}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+final class FieldSet<FieldDescriptorType extends
+      FieldSet.FieldDescriptorLite<FieldDescriptorType>> {
+  /**
+   * Interface for a FieldDescriptor or lite extension descriptor.  This
+   * prevents FieldSet from depending on {@link Descriptors.FieldDescriptor}.
+   */
+  public interface FieldDescriptorLite<T extends FieldDescriptorLite<T>>
+      extends Comparable<T> {
+    int getNumber();
+    WireFormat.FieldType getLiteType();
+    WireFormat.JavaType getLiteJavaType();
+    boolean isRepeated();
+    boolean isPacked();
+    Internal.EnumLiteMap<?> getEnumType();
+
+    // If getLiteJavaType() == MESSAGE, this merges a message object of the
+    // type into a builder of the type.  Returns {@code to}.
+    MessageLite.Builder internalMergeFrom(
+        MessageLite.Builder to, MessageLite from);
+  }
+
+  private final SmallSortedMap<FieldDescriptorType, Object> fields;
+  private boolean isImmutable;
+  private boolean hasLazyField = false;
+
+  /** Construct a new FieldSet. */
+  private FieldSet() {
+    this.fields = SmallSortedMap.newFieldMap(16);
+  }
+
+  /**
+   * Construct an empty FieldSet.  This is only used to initialize
+   * DEFAULT_INSTANCE.
+   */
+  private FieldSet(final boolean dummy) {
+    this.fields = SmallSortedMap.newFieldMap(0);
+    makeImmutable();
+  }
+
+  /** Construct a new FieldSet. */
+  public static <T extends FieldSet.FieldDescriptorLite<T>>
+      FieldSet<T> newFieldSet() {
+    return new FieldSet<T>();
+  }
+
+  /** Get an immutable empty FieldSet. */
+  @SuppressWarnings("unchecked")
+  public static <T extends FieldSet.FieldDescriptorLite<T>>
+      FieldSet<T> emptySet() {
+    return DEFAULT_INSTANCE;
+  }
+  @SuppressWarnings("rawtypes")
+  private static final FieldSet DEFAULT_INSTANCE = new FieldSet(true);
+
+  /** Make this FieldSet immutable from this point forward. */
+  @SuppressWarnings("unchecked")
+  public void makeImmutable() {
+    if (isImmutable) {
+      return;
+    }
+    fields.makeImmutable();
+    isImmutable = true;
+  }
+
+  /**
+   * Returns whether the FieldSet is immutable. This is true if it is the
+   * {@link #emptySet} or if {@link #makeImmutable} were called.
+   *
+   * @return whether the FieldSet is immutable.
+   */
+  public boolean isImmutable() {
+    return isImmutable;
+  }
+
+  /**
+   * Clones the FieldSet. The returned FieldSet will be mutable even if the
+   * original FieldSet was immutable.
+   *
+   * @return the newly cloned FieldSet
+   */
+  @Override
+  public FieldSet<FieldDescriptorType> clone() {
+    // We can't just call fields.clone because List objects in the map
+    // should not be shared.
+    FieldSet<FieldDescriptorType> clone = FieldSet.newFieldSet();
+    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+      Map.Entry<FieldDescriptorType, Object> entry = fields.getArrayEntryAt(i);
+      FieldDescriptorType descriptor = entry.getKey();
+      clone.setField(descriptor, entry.getValue());
+    }
+    for (Map.Entry<FieldDescriptorType, Object> entry :
+             fields.getOverflowEntries()) {
+      FieldDescriptorType descriptor = entry.getKey();
+      clone.setField(descriptor, entry.getValue());
+    }
+    clone.hasLazyField = hasLazyField;
+    return clone;
+  }
+
+
+  // =================================================================
+
+  /** See {@link Message.Builder#clear()}. */
+  public void clear() {
+    fields.clear();
+    hasLazyField = false;
+  }
+
+  /**
+   * Get a simple map containing all the fields.
+   */
+  public Map<FieldDescriptorType, Object> getAllFields() {
+    if (hasLazyField) {
+      SmallSortedMap<FieldDescriptorType, Object> result =
+          SmallSortedMap.newFieldMap(16);
+      for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+        cloneFieldEntry(result, fields.getArrayEntryAt(i));
+      }
+      for (Map.Entry<FieldDescriptorType, Object> entry :
+          fields.getOverflowEntries()) {
+        cloneFieldEntry(result, entry);
+      }
+      if (fields.isImmutable()) {
+        result.makeImmutable();
+      }
+      return result;
+    }
+    return fields.isImmutable() ? fields : Collections.unmodifiableMap(fields);
+  }
+
+  private void cloneFieldEntry(Map<FieldDescriptorType, Object> map,
+      Map.Entry<FieldDescriptorType, Object> entry) {
+    FieldDescriptorType key = entry.getKey();
+    Object value = entry.getValue();
+    if (value instanceof LazyField) {
+      map.put(key, ((LazyField) value).getValue());
+    } else {
+      map.put(key, value);
+    }
+  }
+
+  /**
+   * Get an iterator to the field map. This iterator should not be leaked out
+   * of the protobuf library as it is not protected from mutation when fields
+   * is not immutable.
+   */
+  public Iterator<Map.Entry<FieldDescriptorType, Object>> iterator() {
+    if (hasLazyField) {
+      return new LazyIterator<FieldDescriptorType>(
+          fields.entrySet().iterator());
+    }
+    return fields.entrySet().iterator();
+  }
+
+  /**
+   * Useful for implementing
+   * {@link Message#hasField(Descriptors.FieldDescriptor)}.
+   */
+  public boolean hasField(final FieldDescriptorType descriptor) {
+    if (descriptor.isRepeated()) {
+      throw new IllegalArgumentException(
+        "hasField() can only be called on non-repeated fields.");
+    }
+
+    return fields.get(descriptor) != null;
+  }
+
+  /**
+   * Useful for implementing
+   * {@link Message#getField(Descriptors.FieldDescriptor)}.  This method
+   * returns {@code null} if the field is not set; in this case it is up
+   * to the caller to fetch the field's default value.
+   */
+  public Object getField(final FieldDescriptorType descriptor) {
+    Object o = fields.get(descriptor);
+    if (o instanceof LazyField) {
+      return ((LazyField) o).getValue();
+    }
+    return o;
+  }
+
+  /**
+   * Useful for implementing
+   * {@link Message.Builder#setField(Descriptors.FieldDescriptor,Object)}.
+   */
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  public void setField(final FieldDescriptorType descriptor,
+                       Object value) {
+    if (descriptor.isRepeated()) {
+      if (!(value instanceof List)) {
+        throw new IllegalArgumentException(
+          "Wrong object type used with protocol message reflection.");
+      }
+
+      // Wrap the contents in a new list so that the caller cannot change
+      // the list's contents after setting it.
+      final List newList = new ArrayList();
+      newList.addAll((List) value);
+      for (final Object element : newList) {
+        verifyType(descriptor.getLiteType(), element);
+      }
+      value = newList;
+    } else {
+      verifyType(descriptor.getLiteType(), value);
+    }
+
+    if (value instanceof LazyField) {
+      hasLazyField = true;
+    }
+    fields.put(descriptor, value);
+  }
+
+  /**
+   * Useful for implementing
+   * {@link Message.Builder#clearField(Descriptors.FieldDescriptor)}.
+   */
+  public void clearField(final FieldDescriptorType descriptor) {
+    fields.remove(descriptor);
+    if (fields.isEmpty()) {
+      hasLazyField = false;
+    }
+  }
+
+  /**
+   * Useful for implementing
+   * {@link Message#getRepeatedFieldCount(Descriptors.FieldDescriptor)}.
+   */
+  public int getRepeatedFieldCount(final FieldDescriptorType descriptor) {
+    if (!descriptor.isRepeated()) {
+      throw new IllegalArgumentException(
+        "getRepeatedField() can only be called on repeated fields.");
+    }
+
+    final Object value = getField(descriptor);
+    if (value == null) {
+      return 0;
+    } else {
+      return ((List<?>) value).size();
+    }
+  }
+
+  /**
+   * Useful for implementing
+   * {@link Message#getRepeatedField(Descriptors.FieldDescriptor,int)}.
+   */
+  public Object getRepeatedField(final FieldDescriptorType descriptor,
+                                 final int index) {
+    if (!descriptor.isRepeated()) {
+      throw new IllegalArgumentException(
+        "getRepeatedField() can only be called on repeated fields.");
+    }
+
+    final Object value = getField(descriptor);
+
+    if (value == null) {
+      throw new IndexOutOfBoundsException();
+    } else {
+      return ((List<?>) value).get(index);
+    }
+  }
+
+  /**
+   * Useful for implementing
+   * {@link Message.Builder#setRepeatedField(Descriptors.FieldDescriptor,int,Object)}.
+   */
+  @SuppressWarnings("unchecked")
+  public void setRepeatedField(final FieldDescriptorType descriptor,
+                               final int index,
+                               final Object value) {
+    if (!descriptor.isRepeated()) {
+      throw new IllegalArgumentException(
+        "getRepeatedField() can only be called on repeated fields.");
+    }
+
+    final Object list = getField(descriptor);
+    if (list == null) {
+      throw new IndexOutOfBoundsException();
+    }
+
+    verifyType(descriptor.getLiteType(), value);
+    ((List<Object>) list).set(index, value);
+  }
+
+  /**
+   * Useful for implementing
+   * {@link Message.Builder#addRepeatedField(Descriptors.FieldDescriptor,Object)}.
+   */
+  @SuppressWarnings("unchecked")
+  public void addRepeatedField(final FieldDescriptorType descriptor,
+                               final Object value) {
+    if (!descriptor.isRepeated()) {
+      throw new IllegalArgumentException(
+        "addRepeatedField() can only be called on repeated fields.");
+    }
+
+    verifyType(descriptor.getLiteType(), value);
+
+    final Object existingValue = getField(descriptor);
+    List<Object> list;
+    if (existingValue == null) {
+      list = new ArrayList<Object>();
+      fields.put(descriptor, list);
+    } else {
+      list = (List<Object>) existingValue;
+    }
+
+    list.add(value);
+  }
+
+  /**
+   * Verifies that the given object is of the correct type to be a valid
+   * value for the given field.  (For repeated fields, this checks if the
+   * object is the right type to be one element of the field.)
+   *
+   * @throws IllegalArgumentException The value is not of the right type.
+   */
+  private static void verifyType(final WireFormat.FieldType type,
+                                 final Object value) {
+    if (value == null) {
+      throw new NullPointerException();
+    }
+
+    boolean isValid = false;
+    switch (type.getJavaType()) {
+      case INT:          isValid = value instanceof Integer   ; break;
+      case LONG:         isValid = value instanceof Long      ; break;
+      case FLOAT:        isValid = value instanceof Float     ; break;
+      case DOUBLE:       isValid = value instanceof Double    ; break;
+      case BOOLEAN:      isValid = value instanceof Boolean   ; break;
+      case STRING:       isValid = value instanceof String    ; break;
+      case BYTE_STRING:
+        isValid = value instanceof ByteString || value instanceof byte[];
+        break;
+      case ENUM:
+        // TODO(kenton):  Caller must do type checking here, I guess.
+        isValid =
+            (value instanceof Integer || value instanceof Internal.EnumLite);
+        break;
+      case MESSAGE:
+        // TODO(kenton):  Caller must do type checking here, I guess.
+        isValid =
+            (value instanceof MessageLite) || (value instanceof LazyField);
+        break;
+    }
+
+    if (!isValid) {
+      // TODO(kenton):  When chaining calls to setField(), it can be hard to
+      //   tell from the stack trace which exact call failed, since the whole
+      //   chain is considered one line of code.  It would be nice to print
+      //   more information here, e.g. naming the field.  We used to do that.
+      //   But we can't now that FieldSet doesn't use descriptors.  Maybe this
+      //   isn't a big deal, though, since it would only really apply when using
+      //   reflection and generally people don't chain reflection setters.
+      throw new IllegalArgumentException(
+        "Wrong object type used with protocol message reflection.");
+    }
+  }
+
+  // =================================================================
+  // Parsing and serialization
+
+  /**
+   * See {@link Message#isInitialized()}.  Note:  Since {@code FieldSet}
+   * itself does not have any way of knowing about required fields that
+   * aren't actually present in the set, it is up to the caller to check
+   * that all required fields are present.
+   */
+  public boolean isInitialized() {
+    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+      if (!isInitialized(fields.getArrayEntryAt(i))) {
+        return false;
+      }
+    }
+    for (final Map.Entry<FieldDescriptorType, Object> entry :
+             fields.getOverflowEntries()) {
+      if (!isInitialized(entry)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @SuppressWarnings("unchecked")
+  private boolean isInitialized(
+      final Map.Entry<FieldDescriptorType, Object> entry) {
+    final FieldDescriptorType descriptor = entry.getKey();
+    if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
+      if (descriptor.isRepeated()) {
+        for (final MessageLite element:
+                 (List<MessageLite>) entry.getValue()) {
+          if (!element.isInitialized()) {
+            return false;
+          }
+        }
+      } else {
+        Object value = entry.getValue();
+        if (value instanceof MessageLite) {
+          if (!((MessageLite) value).isInitialized()) {
+            return false;
+          }
+        } else if (value instanceof LazyField) {
+          return true;
+        } else {
+          throw new IllegalArgumentException(
+              "Wrong object type used with protocol message reflection.");
+        }
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Given a field type, return the wire type.
+   *
+   * @returns One of the {@code WIRETYPE_} constants defined in
+   *          {@link WireFormat}.
+   */
+  static int getWireFormatForFieldType(final WireFormat.FieldType type,
+                                       boolean isPacked) {
+    if (isPacked) {
+      return WireFormat.WIRETYPE_LENGTH_DELIMITED;
+    } else {
+      return type.getWireType();
+    }
+  }
+
+  /**
+   * Like {@link Message.Builder#mergeFrom(Message)}, but merges from another 
+   * {@link FieldSet}.
+   */
+  public void mergeFrom(final FieldSet<FieldDescriptorType> other) {
+    for (int i = 0; i < other.fields.getNumArrayEntries(); i++) {
+      mergeFromField(other.fields.getArrayEntryAt(i));
+    }
+    for (final Map.Entry<FieldDescriptorType, Object> entry :
+             other.fields.getOverflowEntries()) {
+      mergeFromField(entry);
+    }
+  }
+
+  private Object cloneIfMutable(Object value) {
+    if (value instanceof byte[]) {
+      byte[] bytes = (byte[]) value;
+      byte[] copy = new byte[bytes.length];
+      System.arraycopy(bytes, 0, copy, 0, bytes.length);
+      return copy;
+    } else {
+      return value;
+    }
+  }
+
+  @SuppressWarnings({"unchecked", "rawtypes"})
+  private void mergeFromField(
+      final Map.Entry<FieldDescriptorType, Object> entry) {
+    final FieldDescriptorType descriptor = entry.getKey();
+    Object otherValue = entry.getValue();
+    if (otherValue instanceof LazyField) {
+      otherValue = ((LazyField) otherValue).getValue();
+    }
+
+    if (descriptor.isRepeated()) {
+      Object value = getField(descriptor);
+      if (value == null) {
+        value = new ArrayList();
+      }
+      for (Object element : (List) otherValue) {
+        ((List) value).add(cloneIfMutable(element));
+      }
+      fields.put(descriptor, value);
+    } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) {
+      Object value = getField(descriptor);
+      if (value == null) {
+        fields.put(descriptor, cloneIfMutable(otherValue));
+      } else {
+        // Merge the messages.
+          value = descriptor.internalMergeFrom(
+                ((MessageLite) value).toBuilder(), (MessageLite) otherValue)
+                .build();
+
+        fields.put(descriptor, value);
+      }
+    } else {
+      fields.put(descriptor, cloneIfMutable(otherValue));
+    }
+  }
+
+  // TODO(kenton):  Move static parsing and serialization methods into some
+  //   other class.  Probably WireFormat.
+
+  /**
+   * Read a field of any primitive type for immutable messages from a
+   * CodedInputStream. Enums, groups, and embedded messages are not handled by
+   * this method.
+   *
+   * @param input The stream from which to read.
+   * @param type Declared type of the field.
+   * @param checkUtf8 When true, check that the input is valid utf8.
+   * @return An object representing the field's value, of the exact
+   *         type which would be returned by
+   *         {@link Message#getField(Descriptors.FieldDescriptor)} for
+   *         this field.
+   */
+  public static Object readPrimitiveField(
+      CodedInputStream input,
+      final WireFormat.FieldType type,
+      boolean checkUtf8) throws IOException {
+    switch (type) {
+      case DOUBLE  : return input.readDouble  ();
+      case FLOAT   : return input.readFloat   ();
+      case INT64   : return input.readInt64   ();
+      case UINT64  : return input.readUInt64  ();
+      case INT32   : return input.readInt32   ();
+      case FIXED64 : return input.readFixed64 ();
+      case FIXED32 : return input.readFixed32 ();
+      case BOOL    : return input.readBool    ();
+      case STRING  : if (checkUtf8) {
+                       return input.readStringRequireUtf8();
+                     } else {
+                       return input.readString();
+                     }
+      case BYTES   : return input.readBytes   ();
+      case UINT32  : return input.readUInt32  ();
+      case SFIXED32: return input.readSFixed32();
+      case SFIXED64: return input.readSFixed64();
+      case SINT32  : return input.readSInt32  ();
+      case SINT64  : return input.readSInt64  ();
+
+      case GROUP:
+        throw new IllegalArgumentException(
+          "readPrimitiveField() cannot handle nested groups.");
+      case MESSAGE:
+        throw new IllegalArgumentException(
+          "readPrimitiveField() cannot handle embedded messages.");
+      case ENUM:
+        // We don't handle enums because we don't know what to do if the
+        // value is not recognized.
+        throw new IllegalArgumentException(
+          "readPrimitiveField() cannot handle enums.");
+    }
+
+    throw new RuntimeException(
+      "There is no way to get here, but the compiler thinks otherwise.");
+  }
+
+
+  /** See {@link Message#writeTo(CodedOutputStream)}. */
+  public void writeTo(final CodedOutputStream output)
+                      throws IOException {
+    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+      final Map.Entry<FieldDescriptorType, Object> entry =
+          fields.getArrayEntryAt(i);
+      writeField(entry.getKey(), entry.getValue(), output);
+    }
+    for (final Map.Entry<FieldDescriptorType, Object> entry :
+         fields.getOverflowEntries()) {
+      writeField(entry.getKey(), entry.getValue(), output);
+    }
+  }
+
+  /**
+   * Like {@link #writeTo} but uses MessageSet wire format.
+   */
+  public void writeMessageSetTo(final CodedOutputStream output)
+                                throws IOException {
+    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+      writeMessageSetTo(fields.getArrayEntryAt(i), output);
+    }
+    for (final Map.Entry<FieldDescriptorType, Object> entry :
+             fields.getOverflowEntries()) {
+      writeMessageSetTo(entry, output);
+    }
+  }
+
+  private void writeMessageSetTo(
+      final Map.Entry<FieldDescriptorType, Object> entry,
+      final CodedOutputStream output) throws IOException {
+    final FieldDescriptorType descriptor = entry.getKey();
+    if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE &&
+        !descriptor.isRepeated() && !descriptor.isPacked()) {
+      Object value = entry.getValue();
+      if (value instanceof LazyField) {
+        value = ((LazyField) value).getValue();
+      }
+      output.writeMessageSetExtension(entry.getKey().getNumber(),
+                                      (MessageLite) value);
+    } else {
+      writeField(descriptor, entry.getValue(), output);
+    }
+  }
+
+  /**
+   * Write a single tag-value pair to the stream.
+   *
+   * @param output The output stream.
+   * @param type   The field's type.
+   * @param number The field's number.
+   * @param value  Object representing the field's value.  Must be of the exact
+   *               type which would be returned by
+   *               {@link Message#getField(Descriptors.FieldDescriptor)} for
+   *               this field.
+   */
+  private static void writeElement(final CodedOutputStream output,
+                                   final WireFormat.FieldType type,
+                                   final int number,
+                                   final Object value) throws IOException {
+    // Special case for groups, which need a start and end tag; other fields
+    // can just use writeTag() and writeFieldNoTag().
+    if (type == WireFormat.FieldType.GROUP) {
+        output.writeGroup(number, (MessageLite) value);
+    } else {
+      output.writeTag(number, getWireFormatForFieldType(type, false));
+      writeElementNoTag(output, type, value);
+    }
+  }
+
+  /**
+   * Write a field of arbitrary type, without its tag, to the stream.
+   *
+   * @param output The output stream.
+   * @param type The field's type.
+   * @param value  Object representing the field's value.  Must be of the exact
+   *               type which would be returned by
+   *               {@link Message#getField(Descriptors.FieldDescriptor)} for
+   *               this field.
+   */
+  private static void writeElementNoTag(
+      final CodedOutputStream output,
+      final WireFormat.FieldType type,
+      final Object value) throws IOException {
+    switch (type) {
+      case DOUBLE  : output.writeDoubleNoTag  ((Double     ) value); break;
+      case FLOAT   : output.writeFloatNoTag   ((Float      ) value); break;
+      case INT64   : output.writeInt64NoTag   ((Long       ) value); break;
+      case UINT64  : output.writeUInt64NoTag  ((Long       ) value); break;
+      case INT32   : output.writeInt32NoTag   ((Integer    ) value); break;
+      case FIXED64 : output.writeFixed64NoTag ((Long       ) value); break;
+      case FIXED32 : output.writeFixed32NoTag ((Integer    ) value); break;
+      case BOOL    : output.writeBoolNoTag    ((Boolean    ) value); break;
+      case STRING  : output.writeStringNoTag  ((String     ) value); break;
+      case GROUP   : output.writeGroupNoTag   ((MessageLite) value); break;
+      case MESSAGE : output.writeMessageNoTag ((MessageLite) value); break;
+      case BYTES:
+        if (value instanceof ByteString) {
+          output.writeBytesNoTag((ByteString) value);
+        } else {
+          output.writeByteArrayNoTag((byte[]) value);
+        }
+        break;
+      case UINT32  : output.writeUInt32NoTag  ((Integer    ) value); break;
+      case SFIXED32: output.writeSFixed32NoTag((Integer    ) value); break;
+      case SFIXED64: output.writeSFixed64NoTag((Long       ) value); break;
+      case SINT32  : output.writeSInt32NoTag  ((Integer    ) value); break;
+      case SINT64  : output.writeSInt64NoTag  ((Long       ) value); break;
+
+      case ENUM:
+        if (value instanceof Internal.EnumLite) {
+          output.writeEnumNoTag(((Internal.EnumLite) value).getNumber());
+        } else {
+          output.writeEnumNoTag(((Integer) value).intValue());
+        }
+        break;
+    }
+  }
+
+  /** Write a single field. */
+  public static void writeField(final FieldDescriptorLite<?> descriptor,
+                                final Object value,
+                                final CodedOutputStream output)
+                                throws IOException {
+    WireFormat.FieldType type = descriptor.getLiteType();
+    int number = descriptor.getNumber();
+    if (descriptor.isRepeated()) {
+      final List<?> valueList = (List<?>)value;
+      if (descriptor.isPacked()) {
+        output.writeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+        // Compute the total data size so the length can be written.
+        int dataSize = 0;
+        for (final Object element : valueList) {
+          dataSize += computeElementSizeNoTag(type, element);
+        }
+        output.writeRawVarint32(dataSize);
+        // Write the data itself, without any tags.
+        for (final Object element : valueList) {
+          writeElementNoTag(output, type, element);
+        }
+      } else {
+        for (final Object element : valueList) {
+          writeElement(output, type, number, element);
+        }
+      }
+    } else {
+      if (value instanceof LazyField) {
+        writeElement(output, type, number, ((LazyField) value).getValue());
+      } else {
+        writeElement(output, type, number, value);
+      }
+    }
+  }
+
+  /**
+   * See {@link Message#getSerializedSize()}.  It's up to the caller to cache
+   * the resulting size if desired.
+   */
+  public int getSerializedSize() {
+    int size = 0;
+    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+      final Map.Entry<FieldDescriptorType, Object> entry =
+          fields.getArrayEntryAt(i);
+      size += computeFieldSize(entry.getKey(), entry.getValue());
+    }
+    for (final Map.Entry<FieldDescriptorType, Object> entry :
+         fields.getOverflowEntries()) {
+      size += computeFieldSize(entry.getKey(), entry.getValue());
+    }
+    return size;
+  }
+
+  /**
+   * Like {@link #getSerializedSize} but uses MessageSet wire format.
+   */
+  public int getMessageSetSerializedSize() {
+    int size = 0;
+    for (int i = 0; i < fields.getNumArrayEntries(); i++) {
+      size += getMessageSetSerializedSize(fields.getArrayEntryAt(i));
+    }
+    for (final Map.Entry<FieldDescriptorType, Object> entry :
+             fields.getOverflowEntries()) {
+      size += getMessageSetSerializedSize(entry);
+    }
+    return size;
+  }
+
+  private int getMessageSetSerializedSize(
+      final Map.Entry<FieldDescriptorType, Object> entry) {
+    final FieldDescriptorType descriptor = entry.getKey();
+    Object value = entry.getValue();
+    if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE
+        && !descriptor.isRepeated() && !descriptor.isPacked()) {
+      if (value instanceof LazyField) {
+        return CodedOutputStream.computeLazyFieldMessageSetExtensionSize(
+            entry.getKey().getNumber(), (LazyField) value);
+      } else {
+        return CodedOutputStream.computeMessageSetExtensionSize(
+            entry.getKey().getNumber(), (MessageLite) value);
+      }
+    } else {
+      return computeFieldSize(descriptor, value);
+    }
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * single tag/value pair of arbitrary type.
+   *
+   * @param type   The field's type.
+   * @param number The field's number.
+   * @param value  Object representing the field's value.  Must be of the exact
+   *               type which would be returned by
+   *               {@link Message#getField(Descriptors.FieldDescriptor)} for
+   *               this field.
+   */
+  private static int computeElementSize(
+      final WireFormat.FieldType type,
+      final int number, final Object value) {
+    int tagSize = CodedOutputStream.computeTagSize(number);
+    if (type == WireFormat.FieldType.GROUP) {
+      // Only count the end group tag for proto2 messages as for proto1 the end
+      // group tag will be counted as a part of getSerializedSize().
+        tagSize *= 2;
+    }
+    return tagSize + computeElementSizeNoTag(type, value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * particular value of arbitrary type, excluding tag.
+   *
+   * @param type   The field's type.
+   * @param value  Object representing the field's value.  Must be of the exact
+   *               type which would be returned by
+   *               {@link Message#getField(Descriptors.FieldDescriptor)} for
+   *               this field.
+   */
+  private static int computeElementSizeNoTag(
+      final WireFormat.FieldType type, final Object value) {
+    switch (type) {
+      // Note:  Minor violation of 80-char limit rule here because this would
+      //   actually be harder to read if we wrapped the lines.
+      case DOUBLE  : return CodedOutputStream.computeDoubleSizeNoTag  ((Double     )value);
+      case FLOAT   : return CodedOutputStream.computeFloatSizeNoTag   ((Float      )value);
+      case INT64   : return CodedOutputStream.computeInt64SizeNoTag   ((Long       )value);
+      case UINT64  : return CodedOutputStream.computeUInt64SizeNoTag  ((Long       )value);
+      case INT32   : return CodedOutputStream.computeInt32SizeNoTag   ((Integer    )value);
+      case FIXED64 : return CodedOutputStream.computeFixed64SizeNoTag ((Long       )value);
+      case FIXED32 : return CodedOutputStream.computeFixed32SizeNoTag ((Integer    )value);
+      case BOOL    : return CodedOutputStream.computeBoolSizeNoTag    ((Boolean    )value);
+      case STRING  : return CodedOutputStream.computeStringSizeNoTag  ((String     )value);
+      case GROUP   : return CodedOutputStream.computeGroupSizeNoTag   ((MessageLite)value);
+      case BYTES   :
+        if (value instanceof ByteString) {
+          return CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
+        } else {
+          return CodedOutputStream.computeByteArraySizeNoTag((byte[]) value);
+        }
+      case UINT32  : return CodedOutputStream.computeUInt32SizeNoTag  ((Integer    )value);
+      case SFIXED32: return CodedOutputStream.computeSFixed32SizeNoTag((Integer    )value);
+      case SFIXED64: return CodedOutputStream.computeSFixed64SizeNoTag((Long       )value);
+      case SINT32  : return CodedOutputStream.computeSInt32SizeNoTag  ((Integer    )value);
+      case SINT64  : return CodedOutputStream.computeSInt64SizeNoTag  ((Long       )value);
+
+      case MESSAGE:
+        if (value instanceof LazyField) {
+          return CodedOutputStream.computeLazyFieldSizeNoTag((LazyField) value);
+        } else {
+          return CodedOutputStream.computeMessageSizeNoTag((MessageLite) value);
+        }
+
+      case ENUM:
+        if (value instanceof Internal.EnumLite) {
+          return CodedOutputStream.computeEnumSizeNoTag(
+              ((Internal.EnumLite) value).getNumber());
+        } else {
+          return CodedOutputStream.computeEnumSizeNoTag((Integer) value);
+        }
+    }
+
+    throw new RuntimeException(
+      "There is no way to get here, but the compiler thinks otherwise.");
+  }
+
+  /**
+   * Compute the number of bytes needed to encode a particular field.
+   */
+  public static int computeFieldSize(final FieldDescriptorLite<?> descriptor,
+                                     final Object value) {
+    WireFormat.FieldType type = descriptor.getLiteType();
+    int number = descriptor.getNumber();
+    if (descriptor.isRepeated()) {
+      if (descriptor.isPacked()) {
+        int dataSize = 0;
+        for (final Object element : (List<?>)value) {
+          dataSize += computeElementSizeNoTag(type, element);
+        }
+        return dataSize +
+            CodedOutputStream.computeTagSize(number) +
+            CodedOutputStream.computeRawVarint32Size(dataSize);
+      } else {
+        int size = 0;
+        for (final Object element : (List<?>)value) {
+          size += computeElementSize(type, number, element);
+        }
+        return size;
+      }
+    } else {
+      return computeElementSize(type, number, value);
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessage.java b/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessage.java
new file mode 100644
index 0000000..a6101cb
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -0,0 +1,2213 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.FileDescriptor;
+import com.google.protobuf.Descriptors.OneofDescriptor;
+
+import java.io.IOException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * All generated protocol message classes extend this class.  This class
+ * implements most of the Message and Builder interfaces using Java reflection.
+ * Users can ignore this class and pretend that generated messages implement
+ * the Message interface directly.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class GeneratedMessage extends AbstractMessage
+    implements Serializable {
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * For testing. Allows a test to disable the optimization that avoids using
+   * field builders for nested messages until they are requested. By disabling
+   * this optimization, existing tests can be reused to test the field builders.
+   */
+  protected static boolean alwaysUseFieldBuilders = false;
+
+  protected GeneratedMessage() {
+  }
+
+  protected GeneratedMessage(Builder<?> builder) {
+  }
+
+  public Parser<? extends GeneratedMessage> getParserForType() {
+    throw new UnsupportedOperationException(
+        "This is supposed to be overridden by subclasses.");
+  }
+
+ /**
+  * For testing. Allows a test to disable the optimization that avoids using
+  * field builders for nested messages until they are requested. By disabling
+  * this optimization, existing tests can be reused to test the field builders.
+  * See {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder}.
+  */
+  static void enableAlwaysUseFieldBuildersForTesting() {
+    alwaysUseFieldBuilders = true;
+  }
+
+  /**
+   * Get the FieldAccessorTable for this type.  We can't have the message
+   * class pass this in to the constructor because of bootstrapping trouble
+   * with DescriptorProtos.
+   */
+  protected abstract FieldAccessorTable internalGetFieldAccessorTable();
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public Descriptor getDescriptorForType() {
+    return internalGetFieldAccessorTable().descriptor;
+  }
+
+  /** Internal helper which returns a mutable map. */
+  private Map<FieldDescriptor, Object> getAllFieldsMutable() {
+    final TreeMap<FieldDescriptor, Object> result =
+      new TreeMap<FieldDescriptor, Object>();
+    final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
+    for (final FieldDescriptor field : descriptor.getFields()) {
+      if (field.isRepeated()) {
+        final List<?> value = (List<?>) getField(field);
+        if (!value.isEmpty()) {
+          result.put(field, value);
+        }
+      } else {
+        if (hasField(field)) {
+          result.put(field, getField(field));
+        }
+      }
+    }
+    return result;
+  }
+
+  @Override
+  public boolean isInitialized() {
+    for (final FieldDescriptor field : getDescriptorForType().getFields()) {
+      // Check that all required fields are present.
+      if (field.isRequired()) {
+        if (!hasField(field)) {
+          return false;
+        }
+      }
+      // Check that embedded messages are initialized.
+      if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+        if (field.isRepeated()) {
+          @SuppressWarnings("unchecked") final
+          List<Message> messageList = (List<Message>) getField(field);
+          for (final Message element : messageList) {
+            if (!element.isInitialized()) {
+              return false;
+            }
+          }
+        } else {
+          if (hasField(field) && !((Message) getField(field)).isInitialized()) {
+            return false;
+          }
+        }
+      }
+    }
+
+    return true;
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public Map<FieldDescriptor, Object> getAllFields() {
+    return Collections.unmodifiableMap(getAllFieldsMutable());
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public boolean hasOneof(final OneofDescriptor oneof) {
+    return internalGetFieldAccessorTable().getOneof(oneof).has(this);
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
+    return internalGetFieldAccessorTable().getOneof(oneof).get(this);
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public boolean hasField(final FieldDescriptor field) {
+    return internalGetFieldAccessorTable().getField(field).has(this);
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public Object getField(final FieldDescriptor field) {
+    return internalGetFieldAccessorTable().getField(field).get(this);
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public int getRepeatedFieldCount(final FieldDescriptor field) {
+    return internalGetFieldAccessorTable().getField(field)
+      .getRepeatedCount(this);
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public Object getRepeatedField(final FieldDescriptor field, final int index) {
+    return internalGetFieldAccessorTable().getField(field)
+      .getRepeated(this, index);
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public UnknownFieldSet getUnknownFields() {
+    throw new UnsupportedOperationException(
+        "This is supposed to be overridden by subclasses.");
+  }
+
+  /**
+   * Called by subclasses to parse an unknown field.
+   * @return {@code true} unless the tag is an end-group tag.
+   */
+  protected boolean parseUnknownField(
+      CodedInputStream input,
+      UnknownFieldSet.Builder unknownFields,
+      ExtensionRegistryLite extensionRegistry,
+      int tag) throws IOException {
+    return unknownFields.mergeFieldFrom(tag, input);
+  }
+
+
+  /**
+   * Used by parsing constructors in generated classes.
+   */
+  protected void makeExtensionsImmutable() {
+    // Noop for messages without extensions.
+  }
+
+  protected abstract Message.Builder newBuilderForType(BuilderParent parent);
+
+  /**
+   * Interface for the parent of a Builder that allows the builder to
+   * communicate invalidations back to the parent for use when using nested
+   * builders.
+   */
+  protected interface BuilderParent {
+
+    /**
+     * A builder becomes dirty whenever a field is modified -- including fields
+     * in nested builders -- and becomes clean when build() is called.  Thus,
+     * when a builder becomes dirty, all its parents become dirty as well, and
+     * when it becomes clean, all its children become clean.  The dirtiness
+     * state is used to invalidate certain cached values.
+     * <br>
+     * To this end, a builder calls markAsDirty() on its parent whenever it
+     * transitions from clean to dirty.  The parent must propagate this call to
+     * its own parent, unless it was already dirty, in which case the
+     * grandparent must necessarily already be dirty as well.  The parent can
+     * only transition back to "clean" after calling build() on all children.
+     */
+    void markDirty();
+  }
+
+  @SuppressWarnings("unchecked")
+  public abstract static class Builder <BuilderType extends Builder>
+      extends AbstractMessage.Builder<BuilderType> {
+
+    private BuilderParent builderParent;
+
+    private BuilderParentImpl meAsParent;
+
+    // Indicates that we've built a message and so we are now obligated
+    // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener.
+    private boolean isClean;
+
+    private UnknownFieldSet unknownFields =
+        UnknownFieldSet.getDefaultInstance();
+
+    protected Builder() {
+      this(null);
+    }
+
+    protected Builder(BuilderParent builderParent) {
+      this.builderParent = builderParent;
+    }
+
+    void dispose() {
+      builderParent = null;
+    }
+
+    /**
+     * Called by the subclass when a message is built.
+     */
+    protected void onBuilt() {
+      if (builderParent != null) {
+        markClean();
+      }
+    }
+
+    /**
+     * Called by the subclass or a builder to notify us that a message was
+     * built and may be cached and therefore invalidations are needed.
+     */
+    protected void markClean() {
+      this.isClean = true;
+    }
+
+    /**
+     * Gets whether invalidations are needed
+     *
+     * @return whether invalidations are needed
+     */
+    protected boolean isClean() {
+      return isClean;
+    }
+
+    // This is implemented here only to work around an apparent bug in the
+    // Java compiler and/or build system.  See bug #1898463.  The mere presence
+    // of this dummy clone() implementation makes it go away.
+    @Override
+    public BuilderType clone() {
+      throw new UnsupportedOperationException(
+          "This is supposed to be overridden by subclasses.");
+    }
+
+    /**
+     * Called by the initialization and clear code paths to allow subclasses to
+     * reset any of their builtin fields back to the initial values.
+     */
+    public BuilderType clear() {
+      unknownFields = UnknownFieldSet.getDefaultInstance();
+      onChanged();
+      return (BuilderType) this;
+    }
+
+    /**
+     * Get the FieldAccessorTable for this type.  We can't have the message
+     * class pass this in to the constructor because of bootstrapping trouble
+     * with DescriptorProtos.
+     */
+    protected abstract FieldAccessorTable internalGetFieldAccessorTable();
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public Descriptor getDescriptorForType() {
+      return internalGetFieldAccessorTable().descriptor;
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public Map<FieldDescriptor, Object> getAllFields() {
+      return Collections.unmodifiableMap(getAllFieldsMutable());
+    }
+
+    /** Internal helper which returns a mutable map. */
+    private Map<FieldDescriptor, Object> getAllFieldsMutable() {
+      final TreeMap<FieldDescriptor, Object> result =
+        new TreeMap<FieldDescriptor, Object>();
+      final Descriptor descriptor = internalGetFieldAccessorTable().descriptor;
+      for (final FieldDescriptor field : descriptor.getFields()) {
+        if (field.isRepeated()) {
+          final List value = (List) getField(field);
+          if (!value.isEmpty()) {
+            result.put(field, value);
+          }
+        } else {
+          if (hasField(field)) {
+            result.put(field, getField(field));
+          }
+        }
+      }
+      return result;
+    }
+
+    public Message.Builder newBuilderForField(
+        final FieldDescriptor field) {
+      return internalGetFieldAccessorTable().getField(field).newBuilder();
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public Message.Builder getFieldBuilder(final FieldDescriptor field) {
+      return internalGetFieldAccessorTable().getField(field).getBuilder(this);
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public boolean hasOneof(final OneofDescriptor oneof) {
+      return internalGetFieldAccessorTable().getOneof(oneof).has(this);
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public FieldDescriptor getOneofFieldDescriptor(final OneofDescriptor oneof) {
+      return internalGetFieldAccessorTable().getOneof(oneof).get(this);
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public boolean hasField(final FieldDescriptor field) {
+      return internalGetFieldAccessorTable().getField(field).has(this);
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public Object getField(final FieldDescriptor field) {
+      Object object = internalGetFieldAccessorTable().getField(field).get(this);
+      if (field.isRepeated()) {
+        // The underlying list object is still modifiable at this point.
+        // Make sure not to expose the modifiable list to the caller.
+        return Collections.unmodifiableList((List) object);
+      } else {
+        return object;
+      }
+    }
+
+    public BuilderType setField(final FieldDescriptor field,
+                                final Object value) {
+      internalGetFieldAccessorTable().getField(field).set(this, value);
+      return (BuilderType) this;
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public BuilderType clearField(final FieldDescriptor field) {
+      internalGetFieldAccessorTable().getField(field).clear(this);
+      return (BuilderType) this;
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public BuilderType clearOneof(final OneofDescriptor oneof) {
+      internalGetFieldAccessorTable().getOneof(oneof).clear(this);
+      return (BuilderType) this;
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public int getRepeatedFieldCount(final FieldDescriptor field) {
+      return internalGetFieldAccessorTable().getField(field)
+          .getRepeatedCount(this);
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public Object getRepeatedField(final FieldDescriptor field,
+                                   final int index) {
+      return internalGetFieldAccessorTable().getField(field)
+          .getRepeated(this, index);
+    }
+
+    public BuilderType setRepeatedField(final FieldDescriptor field,
+                                        final int index, final Object value) {
+      internalGetFieldAccessorTable().getField(field)
+        .setRepeated(this, index, value);
+      return (BuilderType) this;
+    }
+
+    public BuilderType addRepeatedField(final FieldDescriptor field,
+                                        final Object value) {
+      internalGetFieldAccessorTable().getField(field).addRepeated(this, value);
+      return (BuilderType) this;
+    }
+
+    public final BuilderType setUnknownFields(
+        final UnknownFieldSet unknownFields) {
+      this.unknownFields = unknownFields;
+      onChanged();
+      return (BuilderType) this;
+    }
+
+    @Override
+    public final BuilderType mergeUnknownFields(
+        final UnknownFieldSet unknownFields) {
+      this.unknownFields =
+        UnknownFieldSet.newBuilder(this.unknownFields)
+                       .mergeFrom(unknownFields)
+                       .build();
+      onChanged();
+      return (BuilderType) this;
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public boolean isInitialized() {
+      for (final FieldDescriptor field : getDescriptorForType().getFields()) {
+        // Check that all required fields are present.
+        if (field.isRequired()) {
+          if (!hasField(field)) {
+            return false;
+          }
+        }
+        // Check that embedded messages are initialized.
+        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+          if (field.isRepeated()) {
+            @SuppressWarnings("unchecked") final
+            List<Message> messageList = (List<Message>) getField(field);
+            for (final Message element : messageList) {
+              if (!element.isInitialized()) {
+                return false;
+              }
+            }
+          } else {
+            if (hasField(field) &&
+                !((Message) getField(field)).isInitialized()) {
+              return false;
+            }
+          }
+        }
+      }
+      return true;
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final UnknownFieldSet getUnknownFields() {
+      return unknownFields;
+    }
+
+    /**
+     * Called by subclasses to parse an unknown field.
+     * @return {@code true} unless the tag is an end-group tag.
+     */
+    protected boolean parseUnknownField(
+        final CodedInputStream input,
+        final UnknownFieldSet.Builder unknownFields,
+        final ExtensionRegistryLite extensionRegistry,
+        final int tag) throws IOException {
+      return unknownFields.mergeFieldFrom(tag, input);
+    }
+
+    /**
+     * Implementation of {@link BuilderParent} for giving to our children. This
+     * small inner class makes it so we don't publicly expose the BuilderParent
+     * methods.
+     */
+    private class BuilderParentImpl implements BuilderParent {
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public void markDirty() {
+        onChanged();
+      }
+    }
+
+    /**
+     * Gets the {@link BuilderParent} for giving to our children.
+     * @return The builder parent for our children.
+     */
+    protected BuilderParent getParentForChildren() {
+      if (meAsParent == null) {
+        meAsParent = new BuilderParentImpl();
+      }
+      return meAsParent;
+    }
+
+    /**
+     * Called when a the builder or one of its nested children has changed
+     * and any parent should be notified of its invalidation.
+     */
+    protected final void onChanged() {
+      if (isClean && builderParent != null) {
+        builderParent.markDirty();
+
+        // Don't keep dispatching invalidations until build is called again.
+        isClean = false;
+      }
+    }
+  }
+
+  // =================================================================
+  // Extensions-related stuff
+
+  public interface ExtendableMessageOrBuilder<
+      MessageType extends ExtendableMessage> extends MessageOrBuilder {
+    // Re-define for return type covariance.
+    Message getDefaultInstanceForType();
+
+    /** Check if a singular extension is present. */
+    <Type> boolean hasExtension(
+        Extension<MessageType, Type> extension);
+
+    /** Get the number of elements in a repeated extension. */
+    <Type> int getExtensionCount(
+        Extension<MessageType, List<Type>> extension);
+
+    /** Get the value of an extension. */
+    <Type> Type getExtension(
+        Extension<MessageType, Type> extension);
+
+    /** Get one element of a repeated extension. */
+    <Type> Type getExtension(
+        Extension<MessageType, List<Type>> extension,
+        int index);
+  }
+
+  /**
+   * Generated message classes for message types that contain extension ranges
+   * subclass this.
+   *
+   * <p>This class implements type-safe accessors for extensions.  They
+   * implement all the same operations that you can do with normal fields --
+   * e.g. "has", "get", and "getCount" -- but for extensions.  The extensions
+   * are identified using instances of the class {@link GeneratedExtension};
+   * the protocol compiler generates a static instance of this class for every
+   * extension in its input.  Through the magic of generics, all is made
+   * type-safe.
+   *
+   * <p>For example, imagine you have the {@code .proto} file:
+   *
+   * <pre>
+   * option java_class = "MyProto";
+   *
+   * message Foo {
+   *   extensions 1000 to max;
+   * }
+   *
+   * extend Foo {
+   *   optional int32 bar;
+   * }
+   * </pre>
+   *
+   * <p>Then you might write code like:
+   *
+   * <pre>
+   * MyProto.Foo foo = getFoo();
+   * int i = foo.getExtension(MyProto.bar);
+   * </pre>
+   *
+   * <p>See also {@link ExtendableBuilder}.
+   */
+  public abstract static class ExtendableMessage<
+        MessageType extends ExtendableMessage>
+      extends GeneratedMessage
+      implements ExtendableMessageOrBuilder<MessageType> {
+
+    private final FieldSet<FieldDescriptor> extensions;
+
+    protected ExtendableMessage() {
+      this.extensions = FieldSet.newFieldSet();
+    }
+
+    protected ExtendableMessage(
+        ExtendableBuilder<MessageType, ?> builder) {
+      super(builder);
+      this.extensions = builder.buildExtensions();
+    }
+
+    private void verifyExtensionContainingType(
+        final Extension<MessageType, ?> extension) {
+      if (extension.getDescriptor().getContainingType() !=
+          getDescriptorForType()) {
+        // This can only happen if someone uses unchecked operations.
+        throw new IllegalArgumentException(
+          "Extension is for type \"" +
+          extension.getDescriptor().getContainingType().getFullName() +
+          "\" which does not match message type \"" +
+          getDescriptorForType().getFullName() + "\".");
+      }
+    }
+
+    /** Check if a singular extension is present. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> boolean hasExtension(
+        final Extension<MessageType, Type> extension) {
+      verifyExtensionContainingType(extension);
+      return extensions.hasField(extension.getDescriptor());
+    }
+
+    /** Get the number of elements in a repeated extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> int getExtensionCount(
+        final Extension<MessageType, List<Type>> extension) {
+      verifyExtensionContainingType(extension);
+      final FieldDescriptor descriptor = extension.getDescriptor();
+      return extensions.getRepeatedFieldCount(descriptor);
+    }
+
+    /** Get the value of an extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @SuppressWarnings("unchecked")
+    public final <Type> Type getExtension(
+        final Extension<MessageType, Type> extension) {
+      verifyExtensionContainingType(extension);
+      FieldDescriptor descriptor = extension.getDescriptor();
+      final Object value = extensions.getField(descriptor);
+      if (value == null) {
+        if (descriptor.isRepeated()) {
+          return (Type) Collections.emptyList();
+        } else if (descriptor.getJavaType() ==
+                   FieldDescriptor.JavaType.MESSAGE) {
+          return (Type) extension.getMessageDefaultInstance();
+        } else {
+          return (Type) extension.fromReflectionType(
+              descriptor.getDefaultValue());
+        }
+      } else {
+        return (Type) extension.fromReflectionType(value);
+      }
+    }
+
+    /** Get one element of a repeated extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @SuppressWarnings("unchecked")
+    public final <Type> Type getExtension(
+        final Extension<MessageType, List<Type>> extension,
+        final int index) {
+      verifyExtensionContainingType(extension);
+      FieldDescriptor descriptor = extension.getDescriptor();
+      return (Type) extension.singularFromReflectionType(
+          extensions.getRepeatedField(descriptor, index));
+    }
+
+    /** Called by subclasses to check if all extensions are initialized. */
+    protected boolean extensionsAreInitialized() {
+      return extensions.isInitialized();
+    }
+
+    @Override
+    public boolean isInitialized() {
+      return super.isInitialized() && extensionsAreInitialized();
+    }
+
+    @Override
+    protected boolean parseUnknownField(
+        CodedInputStream input,
+        UnknownFieldSet.Builder unknownFields,
+        ExtensionRegistryLite extensionRegistry,
+        int tag) throws IOException {
+      return MessageReflection.mergeFieldFrom(
+          input, unknownFields, extensionRegistry, getDescriptorForType(),
+          new MessageReflection.ExtensionAdapter(extensions), tag);
+    }
+
+
+    /**
+     * Used by parsing constructors in generated classes.
+     */
+    @Override
+    protected void makeExtensionsImmutable() {
+      extensions.makeImmutable();
+    }
+
+    /**
+     * Used by subclasses to serialize extensions.  Extension ranges may be
+     * interleaved with field numbers, but we must write them in canonical
+     * (sorted by field number) order.  ExtensionWriter helps us write
+     * individual ranges of extensions at once.
+     */
+    protected class ExtensionWriter {
+      // Imagine how much simpler this code would be if Java iterators had
+      // a way to get the next element without advancing the iterator.
+
+      private final Iterator<Map.Entry<FieldDescriptor, Object>> iter =
+        extensions.iterator();
+      private Map.Entry<FieldDescriptor, Object> next;
+      private final boolean messageSetWireFormat;
+
+      private ExtensionWriter(final boolean messageSetWireFormat) {
+        if (iter.hasNext()) {
+          next = iter.next();
+        }
+        this.messageSetWireFormat = messageSetWireFormat;
+      }
+
+      public void writeUntil(final int end, final CodedOutputStream output)
+                             throws IOException {
+        while (next != null && next.getKey().getNumber() < end) {
+          FieldDescriptor descriptor = next.getKey();
+          if (messageSetWireFormat && descriptor.getLiteJavaType() ==
+                  WireFormat.JavaType.MESSAGE &&
+              !descriptor.isRepeated()) {
+            if (next instanceof LazyField.LazyEntry<?>) {
+              output.writeRawMessageSetExtension(descriptor.getNumber(),
+                  ((LazyField.LazyEntry<?>) next).getField().toByteString());
+            } else {
+              output.writeMessageSetExtension(descriptor.getNumber(),
+                                              (Message) next.getValue());
+            }
+          } else {
+            // TODO(xiangl): Taken care of following code, it may cause
+            // problem when we use LazyField for normal fields/extensions.
+            // Due to the optional field can be duplicated at the end of
+            // serialized bytes, which will make the serialized size change
+            // after lazy field parsed. So when we use LazyField globally,
+            // we need to change the following write method to write cached
+            // bytes directly rather than write the parsed message.
+            FieldSet.writeField(descriptor, next.getValue(), output);
+          }
+          if (iter.hasNext()) {
+            next = iter.next();
+          } else {
+            next = null;
+          }
+        }
+      }
+    }
+
+    protected ExtensionWriter newExtensionWriter() {
+      return new ExtensionWriter(false);
+    }
+    protected ExtensionWriter newMessageSetExtensionWriter() {
+      return new ExtensionWriter(true);
+    }
+
+    /** Called by subclasses to compute the size of extensions. */
+    protected int extensionsSerializedSize() {
+      return extensions.getSerializedSize();
+    }
+    protected int extensionsSerializedSizeAsMessageSet() {
+      return extensions.getMessageSetSerializedSize();
+    }
+
+    // ---------------------------------------------------------------
+    // Reflection
+
+    protected Map<FieldDescriptor, Object> getExtensionFields() {
+      return extensions.getAllFields();
+    }
+
+    @Override
+    public Map<FieldDescriptor, Object> getAllFields() {
+      final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
+      result.putAll(getExtensionFields());
+      return Collections.unmodifiableMap(result);
+    }
+
+    @Override
+    public boolean hasField(final FieldDescriptor field) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        return extensions.hasField(field);
+      } else {
+        return super.hasField(field);
+      }
+    }
+
+    @Override
+    public Object getField(final FieldDescriptor field) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        final Object value = extensions.getField(field);
+        if (value == null) {
+          if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+            // Lacking an ExtensionRegistry, we have no way to determine the
+            // extension's real type, so we return a DynamicMessage.
+            return DynamicMessage.getDefaultInstance(field.getMessageType());
+          } else {
+            return field.getDefaultValue();
+          }
+        } else {
+          return value;
+        }
+      } else {
+        return super.getField(field);
+      }
+    }
+
+    @Override
+    public int getRepeatedFieldCount(final FieldDescriptor field) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        return extensions.getRepeatedFieldCount(field);
+      } else {
+        return super.getRepeatedFieldCount(field);
+      }
+    }
+
+    @Override
+    public Object getRepeatedField(final FieldDescriptor field,
+                                   final int index) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        return extensions.getRepeatedField(field, index);
+      } else {
+        return super.getRepeatedField(field, index);
+      }
+    }
+
+    private void verifyContainingType(final FieldDescriptor field) {
+      if (field.getContainingType() != getDescriptorForType()) {
+        throw new IllegalArgumentException(
+          "FieldDescriptor does not match message type.");
+      }
+    }
+  }
+
+  /**
+   * Generated message builders for message types that contain extension ranges
+   * subclass this.
+   *
+   * <p>This class implements type-safe accessors for extensions.  They
+   * implement all the same operations that you can do with normal fields --
+   * e.g. "get", "set", and "add" -- but for extensions.  The extensions are
+   * identified using instances of the class {@link GeneratedExtension}; the
+   * protocol compiler generates a static instance of this class for every
+   * extension in its input.  Through the magic of generics, all is made
+   * type-safe.
+   *
+   * <p>For example, imagine you have the {@code .proto} file:
+   *
+   * <pre>
+   * option java_class = "MyProto";
+   *
+   * message Foo {
+   *   extensions 1000 to max;
+   * }
+   *
+   * extend Foo {
+   *   optional int32 bar;
+   * }
+   * </pre>
+   *
+   * <p>Then you might write code like:
+   *
+   * <pre>
+   * MyProto.Foo foo =
+   *   MyProto.Foo.newBuilder()
+   *     .setExtension(MyProto.bar, 123)
+   *     .build();
+   * </pre>
+   *
+   * <p>See also {@link ExtendableMessage}.
+   */
+  @SuppressWarnings("unchecked")
+  public abstract static class ExtendableBuilder<
+        MessageType extends ExtendableMessage,
+        BuilderType extends ExtendableBuilder>
+      extends Builder<BuilderType>
+      implements ExtendableMessageOrBuilder<MessageType> {
+
+    private FieldSet<FieldDescriptor> extensions = FieldSet.emptySet();
+
+    protected ExtendableBuilder() {}
+
+    protected ExtendableBuilder(
+        BuilderParent parent) {
+      super(parent);
+    }
+
+    // For immutable message conversion.
+    void internalSetExtensionSet(FieldSet<FieldDescriptor> extensions) {
+      this.extensions = extensions;
+    }
+
+    @Override
+    public BuilderType clear() {
+      extensions = FieldSet.emptySet();
+      return super.clear();
+    }
+
+    // This is implemented here only to work around an apparent bug in the
+    // Java compiler and/or build system.  See bug #1898463.  The mere presence
+    // of this dummy clone() implementation makes it go away.
+    @Override
+    public BuilderType clone() {
+      throw new UnsupportedOperationException(
+          "This is supposed to be overridden by subclasses.");
+    }
+
+    private void ensureExtensionsIsMutable() {
+      if (extensions.isImmutable()) {
+        extensions = extensions.clone();
+      }
+    }
+
+    private void verifyExtensionContainingType(
+        final Extension<MessageType, ?> extension) {
+      if (extension.getDescriptor().getContainingType() !=
+          getDescriptorForType()) {
+        // This can only happen if someone uses unchecked operations.
+        throw new IllegalArgumentException(
+          "Extension is for type \"" +
+          extension.getDescriptor().getContainingType().getFullName() +
+          "\" which does not match message type \"" +
+          getDescriptorForType().getFullName() + "\".");
+      }
+    }
+
+    /** Check if a singular extension is present. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> boolean hasExtension(
+        final Extension<MessageType, Type> extension) {
+      verifyExtensionContainingType(extension);
+      return extensions.hasField(extension.getDescriptor());
+    }
+
+    /** Get the number of elements in a repeated extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> int getExtensionCount(
+        final Extension<MessageType, List<Type>> extension) {
+      verifyExtensionContainingType(extension);
+      final FieldDescriptor descriptor = extension.getDescriptor();
+      return extensions.getRepeatedFieldCount(descriptor);
+    }
+
+    /** Get the value of an extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> Type getExtension(
+        final Extension<MessageType, Type> extension) {
+      verifyExtensionContainingType(extension);
+      FieldDescriptor descriptor = extension.getDescriptor();
+      final Object value = extensions.getField(descriptor);
+      if (value == null) {
+        if (descriptor.isRepeated()) {
+          return (Type) Collections.emptyList();
+        } else if (descriptor.getJavaType() ==
+                   FieldDescriptor.JavaType.MESSAGE) {
+          return (Type) extension.getMessageDefaultInstance();
+        } else {
+          return (Type) extension.fromReflectionType(
+              descriptor.getDefaultValue());
+        }
+      } else {
+        return (Type) extension.fromReflectionType(value);
+      }
+    }
+
+    /** Get one element of a repeated extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> Type getExtension(
+        final Extension<MessageType, List<Type>> extension,
+        final int index) {
+      verifyExtensionContainingType(extension);
+      FieldDescriptor descriptor = extension.getDescriptor();
+      return (Type) extension.singularFromReflectionType(
+          extensions.getRepeatedField(descriptor, index));
+    }
+
+    /** Set the value of an extension. */
+    public final <Type> BuilderType setExtension(
+        final Extension<MessageType, Type> extension,
+        final Type value) {
+      verifyExtensionContainingType(extension);
+      ensureExtensionsIsMutable();
+      final FieldDescriptor descriptor = extension.getDescriptor();
+      extensions.setField(descriptor, extension.toReflectionType(value));
+      onChanged();
+      return (BuilderType) this;
+    }
+
+    /** Set the value of one element of a repeated extension. */
+    public final <Type> BuilderType setExtension(
+        final Extension<MessageType, List<Type>> extension,
+        final int index, final Type value) {
+      verifyExtensionContainingType(extension);
+      ensureExtensionsIsMutable();
+      final FieldDescriptor descriptor = extension.getDescriptor();
+      extensions.setRepeatedField(
+        descriptor, index,
+        extension.singularToReflectionType(value));
+      onChanged();
+      return (BuilderType) this;
+    }
+
+    /** Append a value to a repeated extension. */
+    public final <Type> BuilderType addExtension(
+        final Extension<MessageType, List<Type>> extension,
+        final Type value) {
+      verifyExtensionContainingType(extension);
+      ensureExtensionsIsMutable();
+      final FieldDescriptor descriptor = extension.getDescriptor();
+      extensions.addRepeatedField(
+          descriptor, extension.singularToReflectionType(value));
+      onChanged();
+      return (BuilderType) this;
+    }
+
+    /** Clear an extension. */
+    public final <Type> BuilderType clearExtension(
+        final Extension<MessageType, ?> extension) {
+      verifyExtensionContainingType(extension);
+      ensureExtensionsIsMutable();
+      extensions.clearField(extension.getDescriptor());
+      onChanged();
+      return (BuilderType) this;
+    }
+
+    /** Called by subclasses to check if all extensions are initialized. */
+    protected boolean extensionsAreInitialized() {
+      return extensions.isInitialized();
+    }
+
+    /**
+     * Called by the build code path to create a copy of the extensions for
+     * building the message.
+     */
+    private FieldSet<FieldDescriptor> buildExtensions() {
+      extensions.makeImmutable();
+      return extensions;
+    }
+
+    @Override
+    public boolean isInitialized() {
+      return super.isInitialized() && extensionsAreInitialized();
+    }
+
+    /**
+     * Called by subclasses to parse an unknown field or an extension.
+     * @return {@code true} unless the tag is an end-group tag.
+     */
+    @Override
+    protected boolean parseUnknownField(
+        final CodedInputStream input,
+        final UnknownFieldSet.Builder unknownFields,
+        final ExtensionRegistryLite extensionRegistry,
+        final int tag) throws IOException {
+      return MessageReflection.mergeFieldFrom(
+          input, unknownFields, extensionRegistry, getDescriptorForType(),
+          new MessageReflection.BuilderAdapter(this), tag);
+    }
+
+    // ---------------------------------------------------------------
+    // Reflection
+
+    @Override
+    public Map<FieldDescriptor, Object> getAllFields() {
+      final Map<FieldDescriptor, Object> result = super.getAllFieldsMutable();
+      result.putAll(extensions.getAllFields());
+      return Collections.unmodifiableMap(result);
+    }
+
+    @Override
+    public Object getField(final FieldDescriptor field) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        final Object value = extensions.getField(field);
+        if (value == null) {
+          if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+            // Lacking an ExtensionRegistry, we have no way to determine the
+            // extension's real type, so we return a DynamicMessage.
+            return DynamicMessage.getDefaultInstance(field.getMessageType());
+          } else {
+            return field.getDefaultValue();
+          }
+        } else {
+          return value;
+        }
+      } else {
+        return super.getField(field);
+      }
+    }
+
+    @Override
+    public int getRepeatedFieldCount(final FieldDescriptor field) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        return extensions.getRepeatedFieldCount(field);
+      } else {
+        return super.getRepeatedFieldCount(field);
+      }
+    }
+
+    @Override
+    public Object getRepeatedField(final FieldDescriptor field,
+                                   final int index) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        return extensions.getRepeatedField(field, index);
+      } else {
+        return super.getRepeatedField(field, index);
+      }
+    }
+
+    @Override
+    public boolean hasField(final FieldDescriptor field) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        return extensions.hasField(field);
+      } else {
+        return super.hasField(field);
+      }
+    }
+
+    @Override
+    public BuilderType setField(final FieldDescriptor field,
+                                final Object value) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        ensureExtensionsIsMutable();
+        extensions.setField(field, value);
+        onChanged();
+        return (BuilderType) this;
+      } else {
+        return super.setField(field, value);
+      }
+    }
+
+    @Override
+    public BuilderType clearField(final FieldDescriptor field) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        ensureExtensionsIsMutable();
+        extensions.clearField(field);
+        onChanged();
+        return (BuilderType) this;
+      } else {
+        return super.clearField(field);
+      }
+    }
+
+    @Override
+    public BuilderType setRepeatedField(final FieldDescriptor field,
+                                        final int index, final Object value) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        ensureExtensionsIsMutable();
+        extensions.setRepeatedField(field, index, value);
+        onChanged();
+        return (BuilderType) this;
+      } else {
+        return super.setRepeatedField(field, index, value);
+      }
+    }
+
+    @Override
+    public BuilderType addRepeatedField(final FieldDescriptor field,
+                                        final Object value) {
+      if (field.isExtension()) {
+        verifyContainingType(field);
+        ensureExtensionsIsMutable();
+        extensions.addRepeatedField(field, value);
+        onChanged();
+        return (BuilderType) this;
+      } else {
+        return super.addRepeatedField(field, value);
+      }
+    }
+
+    protected final void mergeExtensionFields(final ExtendableMessage other) {
+      ensureExtensionsIsMutable();
+      extensions.mergeFrom(other.extensions);
+      onChanged();
+    }
+
+    private void verifyContainingType(final FieldDescriptor field) {
+      if (field.getContainingType() != getDescriptorForType()) {
+        throw new IllegalArgumentException(
+          "FieldDescriptor does not match message type.");
+      }
+    }
+  }
+
+  // -----------------------------------------------------------------
+
+  /**
+   * Gets the descriptor for an extension. The implementation depends on whether
+   * the extension is scoped in the top level of a file or scoped in a Message.
+   */
+  static interface ExtensionDescriptorRetriever {
+    FieldDescriptor getDescriptor();
+  }
+
+  /** For use by generated code only. */
+  public static <ContainingType extends Message, Type>
+      GeneratedExtension<ContainingType, Type>
+      newMessageScopedGeneratedExtension(final Message scope,
+                                         final int descriptorIndex,
+                                         final Class singularType,
+                                         final Message defaultInstance) {
+    // For extensions scoped within a Message, we use the Message to resolve
+    // the outer class's descriptor, from which the extension descriptor is
+    // obtained.
+    return new GeneratedExtension<ContainingType, Type>(
+        new CachedDescriptorRetriever() {
+          //@Override (Java 1.6 override semantics, but we must support 1.5)
+          public FieldDescriptor loadDescriptor() {
+            return scope.getDescriptorForType().getExtensions()
+                .get(descriptorIndex);
+          }
+        },
+        singularType,
+        defaultInstance,
+        Extension.ExtensionType.IMMUTABLE);
+  }
+
+  /** For use by generated code only. */
+  public static <ContainingType extends Message, Type>
+     GeneratedExtension<ContainingType, Type>
+     newFileScopedGeneratedExtension(final Class singularType,
+                                     final Message defaultInstance) {
+    // For extensions scoped within a file, we rely on the outer class's
+    // static initializer to call internalInit() on the extension when the
+    // descriptor is available.
+    return new GeneratedExtension<ContainingType, Type>(
+        null,  // ExtensionDescriptorRetriever is initialized in internalInit();
+        singularType,
+        defaultInstance,
+        Extension.ExtensionType.IMMUTABLE);
+  }
+
+  private abstract static class CachedDescriptorRetriever
+      implements ExtensionDescriptorRetriever {
+    private volatile FieldDescriptor descriptor;
+    protected abstract FieldDescriptor loadDescriptor();
+    
+    public FieldDescriptor getDescriptor() {
+      if (descriptor == null) {
+        synchronized (this) {
+          if (descriptor == null) {
+            descriptor = loadDescriptor();
+          }
+        }
+      }
+      return descriptor;
+    }
+  }
+
+  /**
+   * Used in proto1 generated code only.
+   *
+   * After enabling bridge, we can define proto2 extensions (the extended type
+   * is a proto2 mutable message) in a proto1 .proto file. For these extensions
+   * we should generate proto2 GeneratedExtensions.
+   */
+  public static <ContainingType extends Message, Type>
+      GeneratedExtension<ContainingType, Type>
+      newMessageScopedGeneratedExtension(
+          final Message scope, final String name,
+          final Class singularType, final Message defaultInstance) {
+    // For extensions scoped within a Message, we use the Message to resolve
+    // the outer class's descriptor, from which the extension descriptor is
+    // obtained.
+    return new GeneratedExtension<ContainingType, Type>(
+        new CachedDescriptorRetriever() {
+          protected FieldDescriptor loadDescriptor() {
+            return scope.getDescriptorForType().findFieldByName(name);
+          }
+        },
+        singularType,
+        defaultInstance,
+        Extension.ExtensionType.MUTABLE);
+  }
+
+  /**
+   * Used in proto1 generated code only.
+   *
+   * After enabling bridge, we can define proto2 extensions (the extended type
+   * is a proto2 mutable message) in a proto1 .proto file. For these extensions
+   * we should generate proto2 GeneratedExtensions.
+   */
+  public static <ContainingType extends Message, Type>
+     GeneratedExtension<ContainingType, Type>
+     newFileScopedGeneratedExtension(
+         final Class singularType, final Message defaultInstance,
+         final String descriptorOuterClass, final String extensionName) {
+    // For extensions scoped within a file, we load the descriptor outer
+    // class and rely on it to get the FileDescriptor which then can be
+    // used to obtain the extension's FieldDescriptor.
+    return new GeneratedExtension<ContainingType, Type>(
+        new CachedDescriptorRetriever() {
+          protected FieldDescriptor loadDescriptor() {
+            try {
+              Class clazz =
+                  singularType.getClassLoader().loadClass(descriptorOuterClass);
+              FileDescriptor file =
+                  (FileDescriptor) clazz.getField("descriptor").get(null);
+              return file.findExtensionByName(extensionName);
+            } catch (Exception e) {
+              throw new RuntimeException(
+                  "Cannot load descriptors: " + descriptorOuterClass +
+                  " is not a valid descriptor class name", e);
+            }
+          }
+        },
+        singularType,
+        defaultInstance,
+        Extension.ExtensionType.MUTABLE);
+  }
+
+  /**
+   * Type used to represent generated extensions.  The protocol compiler
+   * generates a static singleton instance of this class for each extension.
+   *
+   * <p>For example, imagine you have the {@code .proto} file:
+   *
+   * <pre>
+   * option java_class = "MyProto";
+   *
+   * message Foo {
+   *   extensions 1000 to max;
+   * }
+   *
+   * extend Foo {
+   *   optional int32 bar;
+   * }
+   * </pre>
+   *
+   * <p>Then, {@code MyProto.Foo.bar} has type
+   * {@code GeneratedExtension<MyProto.Foo, Integer>}.
+   *
+   * <p>In general, users should ignore the details of this type, and simply use
+   * these static singletons as parameters to the extension accessors defined
+   * in {@link ExtendableMessage} and {@link ExtendableBuilder}.
+   */
+  public static class GeneratedExtension<
+      ContainingType extends Message, Type> extends
+      Extension<ContainingType, Type> {
+    // TODO(kenton):  Find ways to avoid using Java reflection within this
+    //   class.  Also try to avoid suppressing unchecked warnings.
+
+    // We can't always initialize the descriptor of a GeneratedExtension when
+    // we first construct it due to initialization order difficulties (namely,
+    // the descriptor may not have been constructed yet, since it is often
+    // constructed by the initializer of a separate module).
+    //
+    // In the case of nested extensions, we initialize the
+    // ExtensionDescriptorRetriever with an instance that uses the scoping
+    // Message's default instance to retrieve the extension's descriptor.
+    //
+    // In the case of non-nested extensions, we initialize the
+    // ExtensionDescriptorRetriever to null and rely on the outer class's static
+    // initializer to call internalInit() after the descriptor has been parsed.
+    GeneratedExtension(ExtensionDescriptorRetriever descriptorRetriever,
+        Class singularType,
+        Message messageDefaultInstance,
+        ExtensionType extensionType) {
+      if (Message.class.isAssignableFrom(singularType) &&
+          !singularType.isInstance(messageDefaultInstance)) {
+        throw new IllegalArgumentException(
+            "Bad messageDefaultInstance for " + singularType.getName());
+      }
+      this.descriptorRetriever = descriptorRetriever;
+      this.singularType = singularType;
+      this.messageDefaultInstance = messageDefaultInstance;
+
+      if (ProtocolMessageEnum.class.isAssignableFrom(singularType)) {
+        this.enumValueOf = getMethodOrDie(singularType, "valueOf",
+                                          EnumValueDescriptor.class);
+        this.enumGetValueDescriptor =
+            getMethodOrDie(singularType, "getValueDescriptor");
+      } else {
+        this.enumValueOf = null;
+        this.enumGetValueDescriptor = null;
+      }
+      this.extensionType = extensionType;
+    }
+
+    /** For use by generated code only. */
+    public void internalInit(final FieldDescriptor descriptor) {
+      if (descriptorRetriever != null) {
+        throw new IllegalStateException("Already initialized.");
+      }
+      descriptorRetriever = new ExtensionDescriptorRetriever() {
+          //@Override (Java 1.6 override semantics, but we must support 1.5)
+          public FieldDescriptor getDescriptor() {
+            return descriptor;
+          }
+        };
+    }
+
+    private ExtensionDescriptorRetriever descriptorRetriever;
+    private final Class singularType;
+    private final Message messageDefaultInstance;
+    private final Method enumValueOf;
+    private final Method enumGetValueDescriptor;
+    private final ExtensionType extensionType;
+
+    public FieldDescriptor getDescriptor() {
+      if (descriptorRetriever == null) {
+        throw new IllegalStateException(
+            "getDescriptor() called before internalInit()");
+      }
+      return descriptorRetriever.getDescriptor();
+    }
+
+    /**
+     * If the extension is an embedded message or group, returns the default
+     * instance of the message.
+     */
+    public Message getMessageDefaultInstance() {
+      return messageDefaultInstance;
+    }
+
+    protected ExtensionType getExtensionType() {
+      return extensionType;
+    }
+
+    /**
+     * Convert from the type used by the reflection accessors to the type used
+     * by native accessors.  E.g., for enums, the reflection accessors use
+     * EnumValueDescriptors but the native accessors use the generated enum
+     * type.
+     */
+    // @Override
+    @SuppressWarnings("unchecked")
+    protected Object fromReflectionType(final Object value) {
+      FieldDescriptor descriptor = getDescriptor();
+      if (descriptor.isRepeated()) {
+        if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE ||
+            descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
+          // Must convert the whole list.
+          final List result = new ArrayList();
+          for (final Object element : (List) value) {
+            result.add(singularFromReflectionType(element));
+          }
+          return result;
+        } else {
+          return value;
+        }
+      } else {
+        return singularFromReflectionType(value);
+      }
+    }
+
+    /**
+     * Like {@link #fromReflectionType(Object)}, but if the type is a repeated
+     * type, this converts a single element.
+     */
+    // @Override
+    protected Object singularFromReflectionType(final Object value) {
+      FieldDescriptor descriptor = getDescriptor();
+      switch (descriptor.getJavaType()) {
+        case MESSAGE:
+          if (singularType.isInstance(value)) {
+            return value;
+          } else {
+            return messageDefaultInstance.newBuilderForType()
+                .mergeFrom((Message) value).build();
+          }
+        case ENUM:
+          return invokeOrDie(enumValueOf, null, (EnumValueDescriptor) value);
+        default:
+          return value;
+      }
+    }
+
+    /**
+     * Convert from the type used by the native accessors to the type used
+     * by reflection accessors.  E.g., for enums, the reflection accessors use
+     * EnumValueDescriptors but the native accessors use the generated enum
+     * type.
+     */
+    // @Override
+    @SuppressWarnings("unchecked")
+    protected Object toReflectionType(final Object value) {
+      FieldDescriptor descriptor = getDescriptor();
+      if (descriptor.isRepeated()) {
+        if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) {
+          // Must convert the whole list.
+          final List result = new ArrayList();
+          for (final Object element : (List) value) {
+            result.add(singularToReflectionType(element));
+          }
+          return result;
+        } else {
+          return value;
+        }
+      } else {
+        return singularToReflectionType(value);
+      }
+    }
+
+    /**
+     * Like {@link #toReflectionType(Object)}, but if the type is a repeated
+     * type, this converts a single element.
+     */
+    // @Override
+    protected Object singularToReflectionType(final Object value) {
+      FieldDescriptor descriptor = getDescriptor();
+      switch (descriptor.getJavaType()) {
+        case ENUM:
+          return invokeOrDie(enumGetValueDescriptor, value);
+        default:
+          return value;
+      }
+    }
+
+    // @Override
+    public int getNumber() {
+      return getDescriptor().getNumber();
+    }
+
+    // @Override
+    public WireFormat.FieldType getLiteType() {
+      return getDescriptor().getLiteType();
+    }
+
+    // @Override
+    public boolean isRepeated() {
+      return getDescriptor().isRepeated();
+    }
+
+    // @Override
+    @SuppressWarnings("unchecked")
+    public Type getDefaultValue() {
+      if (isRepeated()) {
+        return (Type) Collections.emptyList();
+      }
+      if (getDescriptor().getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+        return (Type) messageDefaultInstance;
+      }
+      return (Type) singularFromReflectionType(
+          getDescriptor().getDefaultValue());
+    }
+  }
+
+  // =================================================================
+
+  /** Calls Class.getMethod and throws a RuntimeException if it fails. */
+  @SuppressWarnings("unchecked")
+  private static Method getMethodOrDie(
+      final Class clazz, final String name, final Class... params) {
+    try {
+      return clazz.getMethod(name, params);
+    } catch (NoSuchMethodException e) {
+      throw new RuntimeException(
+        "Generated message class \"" + clazz.getName() +
+        "\" missing method \"" + name + "\".", e);
+    }
+  }
+
+  /** Calls invoke and throws a RuntimeException if it fails. */
+  private static Object invokeOrDie(
+      final Method method, final Object object, final Object... params) {
+    try {
+      return method.invoke(object, params);
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(
+        "Couldn't use Java reflection to implement protocol message " +
+        "reflection.", e);
+    } catch (InvocationTargetException e) {
+      final Throwable cause = e.getCause();
+      if (cause instanceof RuntimeException) {
+        throw (RuntimeException) cause;
+      } else if (cause instanceof Error) {
+        throw (Error) cause;
+      } else {
+        throw new RuntimeException(
+          "Unexpected exception thrown by generated accessor method.", cause);
+      }
+    }
+  }
+
+  /**
+   * Users should ignore this class.  This class provides the implementation
+   * with access to the fields of a message object using Java reflection.
+   */
+  public static final class FieldAccessorTable {
+
+    /**
+     * Construct a FieldAccessorTable for a particular message class.  Only
+     * one FieldAccessorTable should ever be constructed per class.
+     *
+     * @param descriptor     The type's descriptor.
+     * @param camelCaseNames The camelcase names of all fields in the message.
+     *                       These are used to derive the accessor method names.
+     * @param messageClass   The message type.
+     * @param builderClass   The builder type.
+     */
+    public FieldAccessorTable(
+        final Descriptor descriptor,
+        final String[] camelCaseNames,
+        final Class<? extends GeneratedMessage> messageClass,
+        final Class<? extends Builder> builderClass) {
+      this(descriptor, camelCaseNames);
+      ensureFieldAccessorsInitialized(messageClass, builderClass);
+    }
+
+    /**
+     * Construct a FieldAccessorTable for a particular message class without
+     * initializing FieldAccessors.
+     */
+    public FieldAccessorTable(
+        final Descriptor descriptor,
+        final String[] camelCaseNames) {
+      this.descriptor = descriptor;
+      this.camelCaseNames = camelCaseNames;
+      fields = new FieldAccessor[descriptor.getFields().size()];
+      oneofs = new OneofAccessor[descriptor.getOneofs().size()];
+      initialized = false;
+    }
+
+    /**
+     * Ensures the field accessors are initialized. This method is thread-safe.
+     *
+     * @param messageClass   The message type.
+     * @param builderClass   The builder type.
+     * @return this
+     */
+    public FieldAccessorTable ensureFieldAccessorsInitialized(
+        Class<? extends GeneratedMessage> messageClass,
+        Class<? extends Builder> builderClass) {
+      if (initialized) { return this; }
+      synchronized (this) {
+        if (initialized) { return this; }
+        int fieldsSize = fields.length;
+        for (int i = 0; i < fieldsSize; i++) {
+          FieldDescriptor field = descriptor.getFields().get(i);
+          String containingOneofCamelCaseName = null;
+          if (field.getContainingOneof() != null) {
+            containingOneofCamelCaseName =
+                camelCaseNames[fieldsSize + field.getContainingOneof().getIndex()];
+          }
+          if (field.isRepeated()) {
+            if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+              fields[i] = new RepeatedMessageFieldAccessor(
+                  field, camelCaseNames[i], messageClass, builderClass);
+            } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
+              fields[i] = new RepeatedEnumFieldAccessor(
+                  field, camelCaseNames[i], messageClass, builderClass);
+            } else {
+              fields[i] = new RepeatedFieldAccessor(
+                  field, camelCaseNames[i], messageClass, builderClass);
+            }
+          } else {
+            if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+              fields[i] = new SingularMessageFieldAccessor(
+                  field, camelCaseNames[i], messageClass, builderClass,
+                  containingOneofCamelCaseName);
+            } else if (field.getJavaType() == FieldDescriptor.JavaType.ENUM) {
+              fields[i] = new SingularEnumFieldAccessor(
+                  field, camelCaseNames[i], messageClass, builderClass,
+                  containingOneofCamelCaseName);
+            } else {
+              fields[i] = new SingularFieldAccessor(
+                  field, camelCaseNames[i], messageClass, builderClass,
+                  containingOneofCamelCaseName);
+            }
+          }
+        }
+
+        int oneofsSize = oneofs.length;
+        for (int i = 0; i < oneofsSize; i++) {
+          oneofs[i] = new OneofAccessor(
+              descriptor, camelCaseNames[i + fieldsSize],
+              messageClass, builderClass);
+        }
+        initialized = true;
+        camelCaseNames = null;
+        return this;
+      }
+    }
+
+    private final Descriptor descriptor;
+    private final FieldAccessor[] fields;
+    private String[] camelCaseNames;
+    private final OneofAccessor[] oneofs;
+    private volatile boolean initialized;
+
+    /** Get the FieldAccessor for a particular field. */
+    private FieldAccessor getField(final FieldDescriptor field) {
+      if (field.getContainingType() != descriptor) {
+        throw new IllegalArgumentException(
+          "FieldDescriptor does not match message type.");
+      } else if (field.isExtension()) {
+        // If this type had extensions, it would subclass ExtendableMessage,
+        // which overrides the reflection interface to handle extensions.
+        throw new IllegalArgumentException(
+          "This type does not have extensions.");
+      }
+      return fields[field.getIndex()];
+    }
+
+    /** Get the OneofAccessor for a particular oneof. */
+    private OneofAccessor getOneof(final OneofDescriptor oneof) {
+      if (oneof.getContainingType() != descriptor) {
+        throw new IllegalArgumentException(
+          "OneofDescriptor does not match message type.");
+      }
+      return oneofs[oneof.getIndex()];
+    }
+
+    /**
+     * Abstract interface that provides access to a single field.  This is
+     * implemented differently depending on the field type and cardinality.
+     */
+    private interface FieldAccessor {
+      Object get(GeneratedMessage message);
+      Object get(GeneratedMessage.Builder builder);
+      void set(Builder builder, Object value);
+      Object getRepeated(GeneratedMessage message, int index);
+      Object getRepeated(GeneratedMessage.Builder builder, int index);
+      void setRepeated(Builder builder,
+                       int index, Object value);
+      void addRepeated(Builder builder, Object value);
+      boolean has(GeneratedMessage message);
+      boolean has(GeneratedMessage.Builder builder);
+      int getRepeatedCount(GeneratedMessage message);
+      int getRepeatedCount(GeneratedMessage.Builder builder);
+      void clear(Builder builder);
+      Message.Builder newBuilder();
+      Message.Builder getBuilder(GeneratedMessage.Builder builder);
+    }
+
+    /** OneofAccessor provides access to a single oneof. */
+    private static class OneofAccessor {
+      OneofAccessor(
+          final Descriptor descriptor, final String camelCaseName,
+          final Class<? extends GeneratedMessage> messageClass,
+          final Class<? extends Builder> builderClass) {
+        this.descriptor = descriptor;
+        caseMethod =
+            getMethodOrDie(messageClass, "get" + camelCaseName + "Case");
+        caseMethodBuilder =
+            getMethodOrDie(builderClass, "get" + camelCaseName + "Case");
+        clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
+      }
+
+      private final Descriptor descriptor;
+      private final Method caseMethod;
+      private final Method caseMethodBuilder;
+      private final Method clearMethod;
+
+      public boolean has(final GeneratedMessage message) {
+        if (((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber() == 0) {
+          return false;
+        }
+        return true;
+      }
+
+      public boolean has(GeneratedMessage.Builder builder) {
+        if (((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber() == 0) {
+          return false;
+        }
+        return true;
+      }
+
+      public FieldDescriptor get(final GeneratedMessage message) {
+        int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber();
+        if (fieldNumber > 0) {
+          return descriptor.findFieldByNumber(fieldNumber);
+        }
+        return null;
+      }
+
+      public FieldDescriptor get(GeneratedMessage.Builder builder) {
+        int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
+        if (fieldNumber > 0) {
+          return descriptor.findFieldByNumber(fieldNumber);
+        }
+        return null;
+      }
+
+      public void clear(final Builder builder) {
+        invokeOrDie(clearMethod, builder);
+      }
+    }
+    
+    private static boolean supportFieldPresence(FileDescriptor file) {
+      return true;
+    }
+
+    // ---------------------------------------------------------------
+
+    private static class SingularFieldAccessor implements FieldAccessor {
+      SingularFieldAccessor(
+          final FieldDescriptor descriptor, final String camelCaseName,
+          final Class<? extends GeneratedMessage> messageClass,
+          final Class<? extends Builder> builderClass,
+          final String containingOneofCamelCaseName) {
+        field = descriptor;
+        isOneofField = descriptor.getContainingOneof() != null;
+        hasHasMethod = supportFieldPresence(descriptor.getFile())
+            || (!isOneofField && descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE);
+        getMethod = getMethodOrDie(messageClass, "get" + camelCaseName);
+        getMethodBuilder = getMethodOrDie(builderClass, "get" + camelCaseName);
+        type = getMethod.getReturnType();
+        setMethod = getMethodOrDie(builderClass, "set" + camelCaseName, type);
+        hasMethod =
+            hasHasMethod ? getMethodOrDie(messageClass, "has" + camelCaseName) : null;
+        hasMethodBuilder =
+            hasHasMethod ? getMethodOrDie(builderClass, "has" + camelCaseName) : null;
+        clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
+        caseMethod = isOneofField ? getMethodOrDie(
+            messageClass, "get" + containingOneofCamelCaseName + "Case") : null;
+        caseMethodBuilder = isOneofField ? getMethodOrDie(
+            builderClass, "get" + containingOneofCamelCaseName + "Case") : null;
+      }
+
+      // Note:  We use Java reflection to call public methods rather than
+      //   access private fields directly as this avoids runtime security
+      //   checks.
+      protected final Class<?> type;
+      protected final Method getMethod;
+      protected final Method getMethodBuilder;
+      protected final Method setMethod;
+      protected final Method hasMethod;
+      protected final Method hasMethodBuilder;
+      protected final Method clearMethod;
+      protected final Method caseMethod;
+      protected final Method caseMethodBuilder;
+      protected final FieldDescriptor field;
+      protected final boolean isOneofField;
+      protected final boolean hasHasMethod;
+      
+      private int getOneofFieldNumber(final GeneratedMessage message) {
+        return ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber();
+      }
+      
+      private int getOneofFieldNumber(final GeneratedMessage.Builder builder) {
+        return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber();
+      }
+
+      public Object get(final GeneratedMessage message) {
+        return invokeOrDie(getMethod, message);
+      }
+      public Object get(GeneratedMessage.Builder builder) {
+        return invokeOrDie(getMethodBuilder, builder);
+      }
+      public void set(final Builder builder, final Object value) {
+        invokeOrDie(setMethod, builder, value);
+      }
+      public Object getRepeated(final GeneratedMessage message,
+                                final int index) {
+        throw new UnsupportedOperationException(
+          "getRepeatedField() called on a singular field.");
+      }
+      public Object getRepeated(GeneratedMessage.Builder builder, int index) {
+        throw new UnsupportedOperationException(
+          "getRepeatedField() called on a singular field.");
+      }
+      public void setRepeated(final Builder builder,
+                              final int index, final Object value) {
+        throw new UnsupportedOperationException(
+          "setRepeatedField() called on a singular field.");
+      }
+      public void addRepeated(final Builder builder, final Object value) {
+        throw new UnsupportedOperationException(
+          "addRepeatedField() called on a singular field.");
+      }
+      public boolean has(final GeneratedMessage message) {
+        if (!hasHasMethod) {
+          if (isOneofField) {
+            return getOneofFieldNumber(message) == field.getNumber();
+          }
+          return !get(message).equals(field.getDefaultValue());
+        }
+        return (Boolean) invokeOrDie(hasMethod, message);
+      }
+      public boolean has(GeneratedMessage.Builder builder) {
+        if (!hasHasMethod) {
+          if (isOneofField) {
+            return getOneofFieldNumber(builder) == field.getNumber();
+          }
+          return !get(builder).equals(field.getDefaultValue());
+        }
+        return (Boolean) invokeOrDie(hasMethodBuilder, builder);
+      }
+      public int getRepeatedCount(final GeneratedMessage message) {
+        throw new UnsupportedOperationException(
+          "getRepeatedFieldSize() called on a singular field.");
+      }
+      public int getRepeatedCount(GeneratedMessage.Builder builder) {
+        throw new UnsupportedOperationException(
+          "getRepeatedFieldSize() called on a singular field.");
+      }
+      public void clear(final Builder builder) {
+        invokeOrDie(clearMethod, builder);
+      }
+      public Message.Builder newBuilder() {
+        throw new UnsupportedOperationException(
+          "newBuilderForField() called on a non-Message type.");
+      }
+      public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
+        throw new UnsupportedOperationException(
+          "getFieldBuilder() called on a non-Message type.");
+      }
+    }
+
+    private static class RepeatedFieldAccessor implements FieldAccessor {
+      protected final Class type;
+      protected final Method getMethod;
+      protected final Method getMethodBuilder;
+      protected final Method getRepeatedMethod;
+      protected final Method getRepeatedMethodBuilder;
+      protected final Method setRepeatedMethod;
+      protected final Method addRepeatedMethod;
+      protected final Method getCountMethod;
+      protected final Method getCountMethodBuilder;
+      protected final Method clearMethod;
+
+      RepeatedFieldAccessor(
+          final FieldDescriptor descriptor, final String camelCaseName,
+          final Class<? extends GeneratedMessage> messageClass,
+          final Class<? extends Builder> builderClass) {
+        getMethod = getMethodOrDie(messageClass,
+                                   "get" + camelCaseName + "List");
+        getMethodBuilder = getMethodOrDie(builderClass,
+                                   "get" + camelCaseName + "List");
+        getRepeatedMethod =
+            getMethodOrDie(messageClass, "get" + camelCaseName, Integer.TYPE);
+        getRepeatedMethodBuilder =
+            getMethodOrDie(builderClass, "get" + camelCaseName, Integer.TYPE);
+        type = getRepeatedMethod.getReturnType();
+        setRepeatedMethod =
+            getMethodOrDie(builderClass, "set" + camelCaseName,
+                           Integer.TYPE, type);
+        addRepeatedMethod =
+            getMethodOrDie(builderClass, "add" + camelCaseName, type);
+        getCountMethod =
+            getMethodOrDie(messageClass, "get" + camelCaseName + "Count");
+        getCountMethodBuilder =
+            getMethodOrDie(builderClass, "get" + camelCaseName + "Count");
+
+        clearMethod = getMethodOrDie(builderClass, "clear" + camelCaseName);
+      }
+
+      public Object get(final GeneratedMessage message) {
+        return invokeOrDie(getMethod, message);
+      }
+      public Object get(GeneratedMessage.Builder builder) {
+        return invokeOrDie(getMethodBuilder, builder);
+      }
+      public void set(final Builder builder, final Object value) {
+        // Add all the elements individually.  This serves two purposes:
+        // 1) Verifies that each element has the correct type.
+        // 2) Insures that the caller cannot modify the list later on and
+        //    have the modifications be reflected in the message.
+        clear(builder);
+        for (final Object element : (List<?>) value) {
+          addRepeated(builder, element);
+        }
+      }
+      public Object getRepeated(final GeneratedMessage message,
+                                final int index) {
+        return invokeOrDie(getRepeatedMethod, message, index);
+      }
+      public Object getRepeated(GeneratedMessage.Builder builder, int index) {
+        return invokeOrDie(getRepeatedMethodBuilder, builder, index);
+      }
+      public void setRepeated(final Builder builder,
+                              final int index, final Object value) {
+        invokeOrDie(setRepeatedMethod, builder, index, value);
+      }
+      public void addRepeated(final Builder builder, final Object value) {
+        invokeOrDie(addRepeatedMethod, builder, value);
+      }
+      public boolean has(final GeneratedMessage message) {
+        throw new UnsupportedOperationException(
+          "hasField() called on a repeated field.");
+      }
+      public boolean has(GeneratedMessage.Builder builder) {
+        throw new UnsupportedOperationException(
+          "hasField() called on a repeated field.");
+      }
+      public int getRepeatedCount(final GeneratedMessage message) {
+        return (Integer) invokeOrDie(getCountMethod, message);
+      }
+      public int getRepeatedCount(GeneratedMessage.Builder builder) {
+        return (Integer) invokeOrDie(getCountMethodBuilder, builder);
+      }
+      public void clear(final Builder builder) {
+        invokeOrDie(clearMethod, builder);
+      }
+      public Message.Builder newBuilder() {
+        throw new UnsupportedOperationException(
+          "newBuilderForField() called on a non-Message type.");
+      }
+      public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
+        throw new UnsupportedOperationException(
+          "getFieldBuilder() called on a non-Message type.");
+      }
+    }
+
+    // ---------------------------------------------------------------
+
+    private static final class SingularEnumFieldAccessor
+        extends SingularFieldAccessor {
+      SingularEnumFieldAccessor(
+          final FieldDescriptor descriptor, final String camelCaseName,
+          final Class<? extends GeneratedMessage> messageClass,
+          final Class<? extends Builder> builderClass,
+          final String containingOneofCamelCaseName) {
+        super(descriptor, camelCaseName, messageClass, builderClass, containingOneofCamelCaseName);
+
+        valueOfMethod = getMethodOrDie(type, "valueOf",
+                                       EnumValueDescriptor.class);
+        getValueDescriptorMethod =
+          getMethodOrDie(type, "getValueDescriptor");
+      }
+
+      private Method valueOfMethod;
+      private Method getValueDescriptorMethod;
+
+      @Override
+      public Object get(final GeneratedMessage message) {
+        return invokeOrDie(getValueDescriptorMethod, super.get(message));
+      }
+
+      @Override
+      public Object get(final GeneratedMessage.Builder builder) {
+        return invokeOrDie(getValueDescriptorMethod, super.get(builder));
+      }
+
+      @Override
+      public void set(final Builder builder, final Object value) {
+        super.set(builder, invokeOrDie(valueOfMethod, null, value));
+      }
+    }
+
+    private static final class RepeatedEnumFieldAccessor
+        extends RepeatedFieldAccessor {
+      RepeatedEnumFieldAccessor(
+          final FieldDescriptor descriptor, final String camelCaseName,
+          final Class<? extends GeneratedMessage> messageClass,
+          final Class<? extends Builder> builderClass) {
+        super(descriptor, camelCaseName, messageClass, builderClass);
+
+        valueOfMethod = getMethodOrDie(type, "valueOf",
+                                       EnumValueDescriptor.class);
+        getValueDescriptorMethod =
+          getMethodOrDie(type, "getValueDescriptor");
+      }
+
+      private final Method valueOfMethod;
+      private final Method getValueDescriptorMethod;
+
+      @Override
+      @SuppressWarnings("unchecked")
+      public Object get(final GeneratedMessage message) {
+        final List newList = new ArrayList();
+        for (final Object element : (List) super.get(message)) {
+          newList.add(invokeOrDie(getValueDescriptorMethod, element));
+        }
+        return Collections.unmodifiableList(newList);
+      }
+
+      @Override
+      @SuppressWarnings("unchecked")
+      public Object get(final GeneratedMessage.Builder builder) {
+        final List newList = new ArrayList();
+        for (final Object element : (List) super.get(builder)) {
+          newList.add(invokeOrDie(getValueDescriptorMethod, element));
+        }
+        return Collections.unmodifiableList(newList);
+      }
+
+      @Override
+      public Object getRepeated(final GeneratedMessage message,
+                                final int index) {
+        return invokeOrDie(getValueDescriptorMethod,
+          super.getRepeated(message, index));
+      }
+      @Override
+      public Object getRepeated(final GeneratedMessage.Builder builder,
+                                final int index) {
+        return invokeOrDie(getValueDescriptorMethod,
+          super.getRepeated(builder, index));
+      }
+      @Override
+      public void setRepeated(final Builder builder,
+                              final int index, final Object value) {
+        super.setRepeated(builder, index, invokeOrDie(valueOfMethod, null,
+                          value));
+      }
+      @Override
+      public void addRepeated(final Builder builder, final Object value) {
+        super.addRepeated(builder, invokeOrDie(valueOfMethod, null, value));
+      }
+    }
+
+    // ---------------------------------------------------------------
+
+    private static final class SingularMessageFieldAccessor
+        extends SingularFieldAccessor {
+      SingularMessageFieldAccessor(
+          final FieldDescriptor descriptor, final String camelCaseName,
+          final Class<? extends GeneratedMessage> messageClass,
+          final Class<? extends Builder> builderClass,
+          final String containingOneofCamelCaseName) {
+        super(descriptor, camelCaseName, messageClass, builderClass, containingOneofCamelCaseName);
+
+        newBuilderMethod = getMethodOrDie(type, "newBuilder");
+        getBuilderMethodBuilder =
+            getMethodOrDie(builderClass, "get" + camelCaseName + "Builder");
+      }
+
+      private final Method newBuilderMethod;
+      private final Method getBuilderMethodBuilder;
+
+      private Object coerceType(final Object value) {
+        if (type.isInstance(value)) {
+          return value;
+        } else {
+          // The value is not the exact right message type.  However, if it
+          // is an alternative implementation of the same type -- e.g. a
+          // DynamicMessage -- we should accept it.  In this case we can make
+          // a copy of the message.
+          return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
+                  .mergeFrom((Message) value).buildPartial();
+        }
+      }
+
+      @Override
+      public void set(final Builder builder, final Object value) {
+        super.set(builder, coerceType(value));
+      }
+      @Override
+      public Message.Builder newBuilder() {
+        return (Message.Builder) invokeOrDie(newBuilderMethod, null);
+      }
+      @Override
+      public Message.Builder getBuilder(GeneratedMessage.Builder builder) {
+        return (Message.Builder) invokeOrDie(getBuilderMethodBuilder, builder);
+      }
+    }
+
+    private static final class RepeatedMessageFieldAccessor
+        extends RepeatedFieldAccessor {
+      RepeatedMessageFieldAccessor(
+          final FieldDescriptor descriptor, final String camelCaseName,
+          final Class<? extends GeneratedMessage> messageClass,
+          final Class<? extends Builder> builderClass) {
+        super(descriptor, camelCaseName, messageClass, builderClass);
+
+        newBuilderMethod = getMethodOrDie(type, "newBuilder");
+      }
+
+      private final Method newBuilderMethod;
+
+      private Object coerceType(final Object value) {
+        if (type.isInstance(value)) {
+          return value;
+        } else {
+          // The value is not the exact right message type.  However, if it
+          // is an alternative implementation of the same type -- e.g. a
+          // DynamicMessage -- we should accept it.  In this case we can make
+          // a copy of the message.
+          return ((Message.Builder) invokeOrDie(newBuilderMethod, null))
+                  .mergeFrom((Message) value).build();
+        }
+      }
+
+      @Override
+      public void setRepeated(final Builder builder,
+                              final int index, final Object value) {
+        super.setRepeated(builder, index, coerceType(value));
+      }
+      @Override
+      public void addRepeated(final Builder builder, final Object value) {
+        super.addRepeated(builder, coerceType(value));
+      }
+      @Override
+      public Message.Builder newBuilder() {
+        return (Message.Builder) invokeOrDie(newBuilderMethod, null);
+      }
+    }
+  }
+
+  /**
+   * Replaces this object in the output stream with a serialized form.
+   * Part of Java's serialization magic.  Generated sub-classes must override
+   * this method by calling {@code return super.writeReplace();}
+   * @return a SerializedForm of this message
+   */
+  protected Object writeReplace() throws ObjectStreamException {
+    return new GeneratedMessageLite.SerializedForm(this);
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
new file mode 100644
index 0000000..6c5136f
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -0,0 +1,949 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Lite version of {@link GeneratedMessage}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public abstract class GeneratedMessageLite extends AbstractMessageLite
+    implements Serializable {
+  private static final long serialVersionUID = 1L;
+
+  protected GeneratedMessageLite() {
+  }
+
+  protected GeneratedMessageLite(Builder builder) {
+  }
+
+  public Parser<? extends MessageLite> getParserForType() {
+    throw new UnsupportedOperationException(
+        "This is supposed to be overridden by subclasses.");
+  }
+
+  /**
+   * Called by subclasses to parse an unknown field.
+   * @return {@code true} unless the tag is an end-group tag.
+   */
+  protected boolean parseUnknownField(
+      CodedInputStream input,
+      CodedOutputStream unknownFieldsCodedOutput,
+      ExtensionRegistryLite extensionRegistry,
+      int tag) throws IOException {
+    return input.skipField(tag, unknownFieldsCodedOutput);
+  }
+
+  /**
+   * Used by parsing constructors in generated classes.
+   */
+  protected void makeExtensionsImmutable() {
+    // Noop for messages without extensions.
+  }
+
+  @SuppressWarnings("unchecked")
+  public abstract static class Builder<MessageType extends GeneratedMessageLite,
+                                       BuilderType extends Builder>
+      extends AbstractMessageLite.Builder<BuilderType> {
+    protected Builder() {}
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public BuilderType clear() {
+      unknownFields = ByteString.EMPTY;
+      return (BuilderType) this;
+    }
+
+    // This is implemented here only to work around an apparent bug in the
+    // Java compiler and/or build system.  See bug #1898463.  The mere presence
+    // of this dummy clone() implementation makes it go away.
+    @Override
+    public BuilderType clone() {
+      throw new UnsupportedOperationException(
+          "This is supposed to be overridden by subclasses.");
+    }
+
+    /** All subclasses implement this. */
+    public abstract BuilderType mergeFrom(MessageType message);
+
+    // Defined here for return type covariance.
+    public abstract MessageType getDefaultInstanceForType();
+
+    /**
+     * Called by subclasses to parse an unknown field.
+     * @return {@code true} unless the tag is an end-group tag.
+     */
+    protected boolean parseUnknownField(
+        CodedInputStream input,
+        CodedOutputStream unknownFieldsCodedOutput,
+        ExtensionRegistryLite extensionRegistry,
+        int tag) throws IOException {
+      return input.skipField(tag, unknownFieldsCodedOutput);
+    }
+
+    public final ByteString getUnknownFields() {
+      return unknownFields;
+    }
+
+    public final BuilderType setUnknownFields(final ByteString unknownFields) {
+      this.unknownFields = unknownFields;
+      return (BuilderType) this;
+    }
+
+    private ByteString unknownFields = ByteString.EMPTY;
+  }
+
+
+  // =================================================================
+  // Extensions-related stuff
+
+  /**
+   * Lite equivalent of {@link com.google.protobuf.GeneratedMessage.ExtendableMessageOrBuilder}.
+   */
+  public interface ExtendableMessageOrBuilder<
+      MessageType extends ExtendableMessage> extends MessageLiteOrBuilder {
+
+    /** Check if a singular extension is present. */
+    <Type> boolean hasExtension(
+        GeneratedExtension<MessageType, Type> extension);
+
+    /** Get the number of elements in a repeated extension. */
+    <Type> int getExtensionCount(
+        GeneratedExtension<MessageType, List<Type>> extension);
+
+    /** Get the value of an extension. */
+    <Type> Type getExtension(GeneratedExtension<MessageType, Type> extension);
+
+    /** Get one element of a repeated extension. */
+    <Type> Type getExtension(
+        GeneratedExtension<MessageType, List<Type>> extension,
+        int index);
+  }
+
+  /**
+   * Lite equivalent of {@link GeneratedMessage.ExtendableMessage}.
+   */
+  public abstract static class ExtendableMessage<
+        MessageType extends ExtendableMessage<MessageType>>
+      extends GeneratedMessageLite
+      implements ExtendableMessageOrBuilder<MessageType> {
+
+    private final FieldSet<ExtensionDescriptor> extensions;
+
+    protected ExtendableMessage() {
+      this.extensions = FieldSet.newFieldSet();
+    }
+
+    protected ExtendableMessage(ExtendableBuilder<MessageType, ?> builder) {
+      this.extensions = builder.buildExtensions();
+    }
+
+    private void verifyExtensionContainingType(
+        final GeneratedExtension<MessageType, ?> extension) {
+      if (extension.getContainingTypeDefaultInstance() !=
+          getDefaultInstanceForType()) {
+        // This can only happen if someone uses unchecked operations.
+        throw new IllegalArgumentException(
+          "This extension is for a different message type.  Please make " +
+          "sure that you are not suppressing any generics type warnings.");
+      }
+    }
+
+    /** Check if a singular extension is present. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> boolean hasExtension(
+        final GeneratedExtension<MessageType, Type> extension) {
+      verifyExtensionContainingType(extension);
+      return extensions.hasField(extension.descriptor);
+    }
+
+    /** Get the number of elements in a repeated extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> int getExtensionCount(
+        final GeneratedExtension<MessageType, List<Type>> extension) {
+      verifyExtensionContainingType(extension);
+      return extensions.getRepeatedFieldCount(extension.descriptor);
+    }
+
+    /** Get the value of an extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @SuppressWarnings("unchecked")
+    public final <Type> Type getExtension(
+        final GeneratedExtension<MessageType, Type> extension) {
+      verifyExtensionContainingType(extension);
+      final Object value = extensions.getField(extension.descriptor);
+      if (value == null) {
+        return extension.defaultValue;
+      } else {
+        return (Type) extension.fromFieldSetType(value);
+      }
+    }
+
+    /** Get one element of a repeated extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @SuppressWarnings("unchecked")
+    public final <Type> Type getExtension(
+        final GeneratedExtension<MessageType, List<Type>> extension,
+        final int index) {
+      verifyExtensionContainingType(extension);
+      return (Type) extension.singularFromFieldSetType(
+          extensions.getRepeatedField(extension.descriptor, index));
+    }
+
+    /** Called by subclasses to check if all extensions are initialized. */
+    protected boolean extensionsAreInitialized() {
+      return extensions.isInitialized();
+    }
+
+    /**
+     * Called by subclasses to parse an unknown field or an extension.
+     * @return {@code true} unless the tag is an end-group tag.
+     */
+    @Override
+    protected boolean parseUnknownField(
+        CodedInputStream input,
+        CodedOutputStream unknownFieldsCodedOutput,
+        ExtensionRegistryLite extensionRegistry,
+        int tag) throws IOException {
+      return GeneratedMessageLite.parseUnknownField(
+          extensions,
+          getDefaultInstanceForType(),
+          input,
+          unknownFieldsCodedOutput,
+          extensionRegistry,
+          tag);
+    }
+
+
+    /**
+     * Used by parsing constructors in generated classes.
+     */
+    @Override
+    protected void makeExtensionsImmutable() {
+      extensions.makeImmutable();
+    }
+
+    /**
+     * Used by subclasses to serialize extensions.  Extension ranges may be
+     * interleaved with field numbers, but we must write them in canonical
+     * (sorted by field number) order.  ExtensionWriter helps us write
+     * individual ranges of extensions at once.
+     */
+    protected class ExtensionWriter {
+      // Imagine how much simpler this code would be if Java iterators had
+      // a way to get the next element without advancing the iterator.
+
+      private final Iterator<Map.Entry<ExtensionDescriptor, Object>> iter =
+            extensions.iterator();
+      private Map.Entry<ExtensionDescriptor, Object> next;
+      private final boolean messageSetWireFormat;
+
+      private ExtensionWriter(boolean messageSetWireFormat) {
+        if (iter.hasNext()) {
+          next = iter.next();
+        }
+        this.messageSetWireFormat = messageSetWireFormat;
+      }
+
+      public void writeUntil(final int end, final CodedOutputStream output)
+                             throws IOException {
+        while (next != null && next.getKey().getNumber() < end) {
+          ExtensionDescriptor extension = next.getKey();
+          if (messageSetWireFormat && extension.getLiteJavaType() ==
+                  WireFormat.JavaType.MESSAGE &&
+              !extension.isRepeated()) {
+            output.writeMessageSetExtension(extension.getNumber(),
+                                            (MessageLite) next.getValue());
+          } else {
+            FieldSet.writeField(extension, next.getValue(), output);
+          }
+          if (iter.hasNext()) {
+            next = iter.next();
+          } else {
+            next = null;
+          }
+        }
+      }
+    }
+
+    protected ExtensionWriter newExtensionWriter() {
+      return new ExtensionWriter(false);
+    }
+    protected ExtensionWriter newMessageSetExtensionWriter() {
+      return new ExtensionWriter(true);
+    }
+
+    /** Called by subclasses to compute the size of extensions. */
+    protected int extensionsSerializedSize() {
+      return extensions.getSerializedSize();
+    }
+    protected int extensionsSerializedSizeAsMessageSet() {
+      return extensions.getMessageSetSerializedSize();
+    }
+  }
+
+  /**
+   * Lite equivalent of {@link GeneratedMessage.ExtendableBuilder}.
+   */
+  @SuppressWarnings("unchecked")
+  public abstract static class ExtendableBuilder<
+        MessageType extends ExtendableMessage<MessageType>,
+        BuilderType extends ExtendableBuilder<MessageType, BuilderType>>
+      extends Builder<MessageType, BuilderType>
+      implements ExtendableMessageOrBuilder<MessageType> {
+    protected ExtendableBuilder() {}
+
+    private FieldSet<ExtensionDescriptor> extensions = FieldSet.emptySet();
+    private boolean extensionsIsMutable;
+
+    // For immutable message conversion.
+    void internalSetExtensionSet(FieldSet<ExtensionDescriptor> extensions) {
+      this.extensions = extensions;
+    }
+
+    @Override
+    public BuilderType clear() {
+      extensions.clear();
+      extensionsIsMutable = false;
+      return super.clear();
+    }
+
+    private void ensureExtensionsIsMutable() {
+      if (!extensionsIsMutable) {
+        extensions = extensions.clone();
+        extensionsIsMutable = true;
+      }
+    }
+
+    /**
+     * Called by the build code path to create a copy of the extensions for
+     * building the message.
+     */
+    private FieldSet<ExtensionDescriptor> buildExtensions() {
+      extensions.makeImmutable();
+      extensionsIsMutable = false;
+      return extensions;
+    }
+
+    private void verifyExtensionContainingType(
+        final GeneratedExtension<MessageType, ?> extension) {
+      if (extension.getContainingTypeDefaultInstance() !=
+          getDefaultInstanceForType()) {
+        // This can only happen if someone uses unchecked operations.
+        throw new IllegalArgumentException(
+          "This extension is for a different message type.  Please make " +
+          "sure that you are not suppressing any generics type warnings.");
+      }
+    }
+
+    /** Check if a singular extension is present. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> boolean hasExtension(
+        final GeneratedExtension<MessageType, Type> extension) {
+      verifyExtensionContainingType(extension);
+      return extensions.hasField(extension.descriptor);
+    }
+
+    /** Get the number of elements in a repeated extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> int getExtensionCount(
+        final GeneratedExtension<MessageType, List<Type>> extension) {
+      verifyExtensionContainingType(extension);
+      return extensions.getRepeatedFieldCount(extension.descriptor);
+    }
+
+    /** Get the value of an extension. */
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    @SuppressWarnings("unchecked")
+    public final <Type> Type getExtension(
+        final GeneratedExtension<MessageType, Type> extension) {
+      verifyExtensionContainingType(extension);
+      final Object value = extensions.getField(extension.descriptor);
+      if (value == null) {
+        return extension.defaultValue;
+      } else {
+        return (Type) extension.fromFieldSetType(value);
+      }
+    }
+
+    /** Get one element of a repeated extension. */
+    @SuppressWarnings("unchecked")
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public final <Type> Type getExtension(
+        final GeneratedExtension<MessageType, List<Type>> extension,
+        final int index) {
+      verifyExtensionContainingType(extension);
+      return (Type) extension.singularFromFieldSetType(
+          extensions.getRepeatedField(extension.descriptor, index));
+    }
+
+    // This is implemented here only to work around an apparent bug in the
+    // Java compiler and/or build system.  See bug #1898463.  The mere presence
+    // of this dummy clone() implementation makes it go away.
+    @Override
+    public BuilderType clone() {
+      throw new UnsupportedOperationException(
+          "This is supposed to be overridden by subclasses.");
+    }
+
+    /** Set the value of an extension. */
+    public final <Type> BuilderType setExtension(
+        final GeneratedExtension<MessageType, Type> extension,
+        final Type value) {
+      verifyExtensionContainingType(extension);
+      ensureExtensionsIsMutable();
+      extensions.setField(extension.descriptor,
+                          extension.toFieldSetType(value));
+      return (BuilderType) this;
+    }
+
+    /** Set the value of one element of a repeated extension. */
+    public final <Type> BuilderType setExtension(
+        final GeneratedExtension<MessageType, List<Type>> extension,
+        final int index, final Type value) {
+      verifyExtensionContainingType(extension);
+      ensureExtensionsIsMutable();
+      extensions.setRepeatedField(extension.descriptor, index,
+                                  extension.singularToFieldSetType(value));
+      return (BuilderType) this;
+    }
+
+    /** Append a value to a repeated extension. */
+    public final <Type> BuilderType addExtension(
+        final GeneratedExtension<MessageType, List<Type>> extension,
+        final Type value) {
+      verifyExtensionContainingType(extension);
+      ensureExtensionsIsMutable();
+      extensions.addRepeatedField(extension.descriptor,
+                                  extension.singularToFieldSetType(value));
+      return (BuilderType) this;
+    }
+
+    /** Clear an extension. */
+    public final <Type> BuilderType clearExtension(
+        final GeneratedExtension<MessageType, ?> extension) {
+      verifyExtensionContainingType(extension);
+      ensureExtensionsIsMutable();
+      extensions.clearField(extension.descriptor);
+      return (BuilderType) this;
+    }
+
+    /** Called by subclasses to check if all extensions are initialized. */
+    protected boolean extensionsAreInitialized() {
+      return extensions.isInitialized();
+    }
+
+    /**
+     * Called by subclasses to parse an unknown field or an extension.
+     * @return {@code true} unless the tag is an end-group tag.
+     */
+    @Override
+    protected boolean parseUnknownField(
+        CodedInputStream input,
+        CodedOutputStream unknownFieldsCodedOutput,
+        ExtensionRegistryLite extensionRegistry,
+        int tag) throws IOException {
+      ensureExtensionsIsMutable();
+      return GeneratedMessageLite.parseUnknownField(
+          extensions,
+          getDefaultInstanceForType(),
+          input,
+          unknownFieldsCodedOutput,
+          extensionRegistry,
+          tag);
+    }
+
+    protected final void mergeExtensionFields(final MessageType other) {
+      ensureExtensionsIsMutable();
+      extensions.mergeFrom(((ExtendableMessage) other).extensions);
+    }
+  }
+
+  // -----------------------------------------------------------------
+
+  /**
+   * Parse an unknown field or an extension.
+   * @return {@code true} unless the tag is an end-group tag.
+   */
+  private static <MessageType extends MessageLite>
+      boolean parseUnknownField(
+          FieldSet<ExtensionDescriptor> extensions,
+          MessageType defaultInstance,
+          CodedInputStream input,
+          CodedOutputStream unknownFieldsCodedOutput,
+          ExtensionRegistryLite extensionRegistry,
+          int tag) throws IOException {
+    int wireType = WireFormat.getTagWireType(tag);
+    int fieldNumber = WireFormat.getTagFieldNumber(tag);
+
+    GeneratedExtension<MessageType, ?> extension =
+      extensionRegistry.findLiteExtensionByNumber(
+          defaultInstance, fieldNumber);
+
+    boolean unknown = false;
+    boolean packed = false;
+    if (extension == null) {
+      unknown = true;  // Unknown field.
+    } else if (wireType == FieldSet.getWireFormatForFieldType(
+                 extension.descriptor.getLiteType(),
+                 false  /* isPacked */)) {
+      packed = false;  // Normal, unpacked value.
+    } else if (extension.descriptor.isRepeated &&
+               extension.descriptor.type.isPackable() &&
+               wireType == FieldSet.getWireFormatForFieldType(
+                 extension.descriptor.getLiteType(),
+                 true  /* isPacked */)) {
+      packed = true;  // Packed value.
+    } else {
+      unknown = true;  // Wrong wire type.
+    }
+
+    if (unknown) {  // Unknown field or wrong wire type.  Skip.
+      return input.skipField(tag, unknownFieldsCodedOutput);
+    }
+
+    if (packed) {
+      int length = input.readRawVarint32();
+      int limit = input.pushLimit(length);
+      if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
+        while (input.getBytesUntilLimit() > 0) {
+          int rawValue = input.readEnum();
+          Object value =
+              extension.descriptor.getEnumType().findValueByNumber(rawValue);
+          if (value == null) {
+            // If the number isn't recognized as a valid value for this
+            // enum, drop it (don't even add it to unknownFields).
+            return true;
+          }
+          extensions.addRepeatedField(extension.descriptor,
+                                      extension.singularToFieldSetType(value));
+        }
+      } else {
+        while (input.getBytesUntilLimit() > 0) {
+          Object value =
+              FieldSet.readPrimitiveField(input,
+                                          extension.descriptor.getLiteType(),
+                                          /*checkUtf8=*/ false);
+          extensions.addRepeatedField(extension.descriptor, value);
+        }
+      }
+      input.popLimit(limit);
+    } else {
+      Object value;
+      switch (extension.descriptor.getLiteJavaType()) {
+        case MESSAGE: {
+          MessageLite.Builder subBuilder = null;
+          if (!extension.descriptor.isRepeated()) {
+            MessageLite existingValue =
+                (MessageLite) extensions.getField(extension.descriptor);
+            if (existingValue != null) {
+              subBuilder = existingValue.toBuilder();
+            }
+          }
+          if (subBuilder == null) {
+            subBuilder = extension.getMessageDefaultInstance()
+                .newBuilderForType();
+          }
+          if (extension.descriptor.getLiteType() ==
+              WireFormat.FieldType.GROUP) {
+            input.readGroup(extension.getNumber(),
+                            subBuilder, extensionRegistry);
+          } else {
+            input.readMessage(subBuilder, extensionRegistry);
+          }
+          value = subBuilder.build();
+          break;
+        }
+        case ENUM:
+          int rawValue = input.readEnum();
+          value = extension.descriptor.getEnumType()
+                           .findValueByNumber(rawValue);
+          // If the number isn't recognized as a valid value for this enum,
+          // write it to unknown fields object.
+          if (value == null) {
+            unknownFieldsCodedOutput.writeRawVarint32(tag);
+            unknownFieldsCodedOutput.writeUInt32NoTag(rawValue);
+            return true;
+          }
+          break;
+        default:
+          value = FieldSet.readPrimitiveField(input,
+              extension.descriptor.getLiteType(),
+              /*checkUtf8=*/ false);
+          break;
+      }
+
+      if (extension.descriptor.isRepeated()) {
+        extensions.addRepeatedField(extension.descriptor,
+                                    extension.singularToFieldSetType(value));
+      } else {
+        extensions.setField(extension.descriptor,
+                            extension.singularToFieldSetType(value));
+      }
+    }
+
+    return true;
+  }
+
+  // -----------------------------------------------------------------
+
+  /** For use by generated code only. */
+  public static <ContainingType extends MessageLite, Type>
+      GeneratedExtension<ContainingType, Type>
+          newSingularGeneratedExtension(
+              final ContainingType containingTypeDefaultInstance,
+              final Type defaultValue,
+              final MessageLite messageDefaultInstance,
+              final Internal.EnumLiteMap<?> enumTypeMap,
+              final int number,
+              final WireFormat.FieldType type,
+              final Class singularType) {
+    return new GeneratedExtension<ContainingType, Type>(
+        containingTypeDefaultInstance,
+        defaultValue,
+        messageDefaultInstance,
+        new ExtensionDescriptor(enumTypeMap, number, type,
+                                false /* isRepeated */,
+                                false /* isPacked */),
+        singularType);
+  }
+
+  /** For use by generated code only. */
+  public static <ContainingType extends MessageLite, Type>
+      GeneratedExtension<ContainingType, Type>
+          newRepeatedGeneratedExtension(
+              final ContainingType containingTypeDefaultInstance,
+              final MessageLite messageDefaultInstance,
+              final Internal.EnumLiteMap<?> enumTypeMap,
+              final int number,
+              final WireFormat.FieldType type,
+              final boolean isPacked,
+              final Class singularType) {
+    @SuppressWarnings("unchecked")  // Subclasses ensure Type is a List
+    Type emptyList = (Type) Collections.emptyList();
+    return new GeneratedExtension<ContainingType, Type>(
+        containingTypeDefaultInstance,
+        emptyList,
+        messageDefaultInstance,
+        new ExtensionDescriptor(
+            enumTypeMap, number, type, true /* isRepeated */, isPacked),
+        singularType);
+  }
+
+  static final class ExtensionDescriptor
+      implements FieldSet.FieldDescriptorLite<
+        ExtensionDescriptor> {
+    ExtensionDescriptor(
+        final Internal.EnumLiteMap<?> enumTypeMap,
+        final int number,
+        final WireFormat.FieldType type,
+        final boolean isRepeated,
+        final boolean isPacked) {
+      this.enumTypeMap = enumTypeMap;
+      this.number = number;
+      this.type = type;
+      this.isRepeated = isRepeated;
+      this.isPacked = isPacked;
+    }
+
+    final Internal.EnumLiteMap<?> enumTypeMap;
+    final int number;
+    final WireFormat.FieldType type;
+    final boolean isRepeated;
+    final boolean isPacked;
+
+    public int getNumber() {
+      return number;
+    }
+
+    public WireFormat.FieldType getLiteType() {
+      return type;
+    }
+
+    public WireFormat.JavaType getLiteJavaType() {
+      return type.getJavaType();
+    }
+
+    public boolean isRepeated() {
+      return isRepeated;
+    }
+
+    public boolean isPacked() {
+      return isPacked;
+    }
+
+    public Internal.EnumLiteMap<?> getEnumType() {
+      return enumTypeMap;
+    }
+
+    @SuppressWarnings("unchecked")
+    public MessageLite.Builder internalMergeFrom(
+        MessageLite.Builder to, MessageLite from) {
+      return ((Builder) to).mergeFrom((GeneratedMessageLite) from);
+    }
+
+
+    public int compareTo(ExtensionDescriptor other) {
+      return number - other.number;
+    }
+  }
+
+  // =================================================================
+
+  /** Calls Class.getMethod and throws a RuntimeException if it fails. */
+  @SuppressWarnings("unchecked")
+  static Method getMethodOrDie(Class clazz, String name, Class... params) {
+    try {
+      return clazz.getMethod(name, params);
+    } catch (NoSuchMethodException e) {
+      throw new RuntimeException(
+        "Generated message class \"" + clazz.getName() +
+        "\" missing method \"" + name + "\".", e);
+    }
+  }
+
+  /** Calls invoke and throws a RuntimeException if it fails. */
+  static Object invokeOrDie(Method method, Object object, Object... params) {
+    try {
+      return method.invoke(object, params);
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(
+        "Couldn't use Java reflection to implement protocol message " +
+        "reflection.", e);
+    } catch (InvocationTargetException e) {
+      final Throwable cause = e.getCause();
+      if (cause instanceof RuntimeException) {
+        throw (RuntimeException) cause;
+      } else if (cause instanceof Error) {
+        throw (Error) cause;
+      } else {
+        throw new RuntimeException(
+          "Unexpected exception thrown by generated accessor method.", cause);
+      }
+    }
+  }
+
+  /**
+   * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}.
+   *
+   * Users should ignore the contents of this class and only use objects of
+   * this type as parameters to extension accessors and ExtensionRegistry.add().
+   */
+  public static class GeneratedExtension<
+      ContainingType extends MessageLite, Type> {
+
+    /**
+     * Create a new isntance with the given parameters.
+     *
+     * The last parameter {@code singularType} is only needed for enum types.
+     * We store integer values for enum types in a {@link ExtendableMessage}
+     * and use Java reflection to convert an integer value back into a concrete
+     * enum object.
+     */
+    GeneratedExtension(
+        final ContainingType containingTypeDefaultInstance,
+        final Type defaultValue,
+        final MessageLite messageDefaultInstance,
+        final ExtensionDescriptor descriptor,
+        Class singularType) {
+      // Defensive checks to verify the correct initialization order of
+      // GeneratedExtensions and their related GeneratedMessages.
+      if (containingTypeDefaultInstance == null) {
+        throw new IllegalArgumentException(
+            "Null containingTypeDefaultInstance");
+      }
+      if (descriptor.getLiteType() == WireFormat.FieldType.MESSAGE &&
+          messageDefaultInstance == null) {
+        throw new IllegalArgumentException(
+            "Null messageDefaultInstance");
+      }
+      this.containingTypeDefaultInstance = containingTypeDefaultInstance;
+      this.defaultValue = defaultValue;
+      this.messageDefaultInstance = messageDefaultInstance;
+      this.descriptor = descriptor;
+
+      // Use Java reflection to invoke the static method {@code valueOf} of
+      // enum types in order to convert integers to concrete enum objects.
+      this.singularType = singularType;
+      if (Internal.EnumLite.class.isAssignableFrom(singularType)) {
+        this.enumValueOf = getMethodOrDie(
+            singularType, "valueOf", int.class);
+      } else {
+        this.enumValueOf = null;
+      }
+    }
+
+    final ContainingType containingTypeDefaultInstance;
+    final Type defaultValue;
+    final MessageLite messageDefaultInstance;
+    final ExtensionDescriptor descriptor;
+    final Class singularType;
+    final Method enumValueOf;
+
+    /**
+     * Default instance of the type being extended, used to identify that type.
+     */
+    public ContainingType getContainingTypeDefaultInstance() {
+      return containingTypeDefaultInstance;
+    }
+
+    /** Get the field number. */
+    public int getNumber() {
+      return descriptor.getNumber();
+    }
+
+
+    /**
+     * If the extension is an embedded message or group, returns the default
+     * instance of the message.
+     */
+    public MessageLite getMessageDefaultInstance() {
+      return messageDefaultInstance;
+    }
+
+    @SuppressWarnings("unchecked")
+    Object fromFieldSetType(final Object value) {
+      if (descriptor.isRepeated()) {
+        if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
+          final List result = new ArrayList();
+          for (final Object element : (List) value) {
+            result.add(singularFromFieldSetType(element));
+          }
+          return result;
+        } else {
+          return value;
+        }
+      } else {
+        return singularFromFieldSetType(value);
+      }
+    }
+
+    Object singularFromFieldSetType(final Object value) {
+      if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
+        return invokeOrDie(enumValueOf, null, (Integer) value);
+      } else {
+        return value;
+      }
+    }
+
+    @SuppressWarnings("unchecked")
+    Object toFieldSetType(final Object value) {
+      if (descriptor.isRepeated()) {
+        if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
+          final List result = new ArrayList();
+          for (final Object element : (List) value) {
+            result.add(singularToFieldSetType(element));
+          }
+          return result;
+        } else {
+          return value;
+        }
+      } else {
+        return singularToFieldSetType(value);
+      }
+    }
+
+    Object singularToFieldSetType(final Object value) {
+      if (descriptor.getLiteJavaType() == WireFormat.JavaType.ENUM) {
+        return ((Internal.EnumLite) value).getNumber();
+      } else {
+        return value;
+      }
+    }
+  }
+
+  /**
+   * A serialized (serializable) form of the generated message.  Stores the
+   * message as a class name and a byte array.
+   */
+  static final class SerializedForm implements Serializable {
+    private static final long serialVersionUID = 0L;
+
+    private String messageClassName;
+    private byte[] asBytes;
+
+    /**
+     * Creates the serialized form by calling {@link com.google.protobuf.MessageLite#toByteArray}.
+     * @param regularForm the message to serialize
+     */
+    SerializedForm(MessageLite regularForm) {
+      messageClassName = regularForm.getClass().getName();
+      asBytes = regularForm.toByteArray();
+    }
+
+    /**
+     * When read from an ObjectInputStream, this method converts this object
+     * back to the regular form.  Part of Java's serialization magic.
+     * @return a GeneratedMessage of the type that was serialized
+     */
+    @SuppressWarnings("unchecked")
+    protected Object readResolve() throws ObjectStreamException {
+      try {
+        Class messageClass = Class.forName(messageClassName);
+        Method newBuilder = messageClass.getMethod("newBuilder");
+        MessageLite.Builder builder =
+            (MessageLite.Builder) newBuilder.invoke(null);
+        builder.mergeFrom(asBytes);
+        return builder.buildPartial();
+      } catch (ClassNotFoundException e) {
+        throw new RuntimeException("Unable to find proto buffer class", e);
+      } catch (NoSuchMethodException e) {
+        throw new RuntimeException("Unable to find newBuilder method", e);
+      } catch (IllegalAccessException e) {
+        throw new RuntimeException("Unable to call newBuilder method", e);
+      } catch (InvocationTargetException e) {
+        throw new RuntimeException("Error calling newBuilder", e.getCause());
+      } catch (InvalidProtocolBufferException e) {
+        throw new RuntimeException("Unable to understand proto buffer", e);
+      }
+    }
+  }
+
+  /**
+   * Replaces this object in the output stream with a serialized form.
+   * Part of Java's serialization magic.  Generated sub-classes must override
+   * this method by calling {@code return super.writeReplace();}
+   * @return a SerializedForm of this message
+   */
+  protected Object writeReplace() throws ObjectStreamException {
+    return new SerializedForm(this);
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/Internal.java b/protobuf/java/src/main/java/com/google/protobuf/Internal.java
new file mode 100644
index 0000000..48d29e6
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/Internal.java
@@ -0,0 +1,391 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * The classes contained within are used internally by the Protocol Buffer
+ * library and generated message implementations. They are public only because
+ * those generated messages do not reside in the {@code protobuf} package.
+ * Others should not use this class directly.
+ *
+ * @author kenton@google.com (Kenton Varda)
+ */
+public class Internal {
+  /**
+   * Helper called by generated code to construct default values for string
+   * fields.
+   * <p>
+   * The protocol compiler does not actually contain a UTF-8 decoder -- it
+   * just pushes UTF-8-encoded text around without touching it.  The one place
+   * where this presents a problem is when generating Java string literals.
+   * Unicode characters in the string literal would normally need to be encoded
+   * using a Unicode escape sequence, which would require decoding them.
+   * To get around this, protoc instead embeds the UTF-8 bytes into the
+   * generated code and leaves it to the runtime library to decode them.
+   * <p>
+   * It gets worse, though.  If protoc just generated a byte array, like:
+   *   new byte[] {0x12, 0x34, 0x56, 0x78}
+   * Java actually generates *code* which allocates an array and then fills
+   * in each value.  This is much less efficient than just embedding the bytes
+   * directly into the bytecode.  To get around this, we need another
+   * work-around.  String literals are embedded directly, so protoc actually
+   * generates a string literal corresponding to the bytes.  The easiest way
+   * to do this is to use the ISO-8859-1 character set, which corresponds to
+   * the first 256 characters of the Unicode range.  Protoc can then use
+   * good old CEscape to generate the string.
+   * <p>
+   * So we have a string literal which represents a set of bytes which
+   * represents another string.  This function -- stringDefaultValue --
+   * converts from the generated string to the string we actually want.  The
+   * generated code calls this automatically.
+   */
+  public static String stringDefaultValue(String bytes) {
+    try {
+      return new String(bytes.getBytes("ISO-8859-1"), "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      // This should never happen since all JVMs are required to implement
+      // both of the above character sets.
+      throw new IllegalStateException(
+          "Java VM does not support a standard character set.", e);
+    }
+  }
+
+  /**
+   * Helper called by generated code to construct default values for bytes
+   * fields.
+   * <p>
+   * This is a lot like {@link #stringDefaultValue}, but for bytes fields.
+   * In this case we only need the second of the two hacks -- allowing us to
+   * embed raw bytes as a string literal with ISO-8859-1 encoding.
+   */
+  public static ByteString bytesDefaultValue(String bytes) {
+    try {
+      return ByteString.copyFrom(bytes.getBytes("ISO-8859-1"));
+    } catch (UnsupportedEncodingException e) {
+      // This should never happen since all JVMs are required to implement
+      // ISO-8859-1.
+      throw new IllegalStateException(
+          "Java VM does not support a standard character set.", e);
+    }
+  }
+  /**
+   * Helper called by generated code to construct default values for bytes
+   * fields.
+   * <p>
+   * This is like {@link #bytesDefaultValue}, but returns a byte array. 
+   */
+  public static byte[] byteArrayDefaultValue(String bytes) {
+    try {
+      return bytes.getBytes("ISO-8859-1");
+    } catch (UnsupportedEncodingException e) {
+      // This should never happen since all JVMs are required to implement
+      // ISO-8859-1.
+      throw new IllegalStateException(
+          "Java VM does not support a standard character set.", e);
+    }
+  }
+
+  /**
+   * Helper called by generated code to construct default values for bytes
+   * fields.
+   * <p>
+   * This is like {@link #bytesDefaultValue}, but returns a ByteBuffer. 
+   */
+  public static ByteBuffer byteBufferDefaultValue(String bytes) {
+    return ByteBuffer.wrap(byteArrayDefaultValue(bytes));
+  }
+
+  /**
+   * Create a new ByteBuffer and copy all the content of {@code source}
+   * ByteBuffer to the new ByteBuffer. The new ByteBuffer's limit and
+   * capacity will be source.capacity(), and its position will be 0.
+   * Note that the state of {@code source} ByteBuffer won't be changed.
+   */
+  public static ByteBuffer copyByteBuffer(ByteBuffer source) {
+    // Make a duplicate of the source ByteBuffer and read data from the
+    // duplicate. This is to avoid affecting the source ByteBuffer's state.
+    ByteBuffer temp = source.duplicate();
+    // We want to copy all the data in the source ByteBuffer, not just the
+    // remaining bytes.
+    temp.clear();
+    ByteBuffer result = ByteBuffer.allocate(temp.capacity());
+    result.put(temp);
+    result.clear();
+    return result;
+  }
+
+  /**
+   * Helper called by generated code to determine if a byte array is a valid
+   * UTF-8 encoded string such that the original bytes can be converted to
+   * a String object and then back to a byte array round tripping the bytes
+   * without loss.  More precisely, returns {@code true} whenever:
+   * <pre>   {@code
+   * Arrays.equals(byteString.toByteArray(),
+   *     new String(byteString.toByteArray(), "UTF-8").getBytes("UTF-8"))
+   * }</pre>
+   *
+   * <p>This method rejects "overlong" byte sequences, as well as
+   * 3-byte sequences that would map to a surrogate character, in
+   * accordance with the restricted definition of UTF-8 introduced in
+   * Unicode 3.1.  Note that the UTF-8 decoder included in Oracle's
+   * JDK has been modified to also reject "overlong" byte sequences,
+   * but currently (2011) still accepts 3-byte surrogate character
+   * byte sequences.
+   *
+   * <p>See the Unicode Standard,</br>
+   * Table 3-6. <em>UTF-8 Bit Distribution</em>,</br>
+   * Table 3-7. <em>Well Formed UTF-8 Byte Sequences</em>.
+   *
+   * <p>As of 2011-02, this method simply returns the result of {@link
+   * ByteString#isValidUtf8()}.  Calling that method directly is preferred.
+   *
+   * @param byteString the string to check
+   * @return whether the byte array is round trippable
+   */
+  public static boolean isValidUtf8(ByteString byteString) {
+    return byteString.isValidUtf8();
+  }
+  
+  /**
+   * Like {@link #isValidUtf8(ByteString)} but for byte arrays.
+   */
+  public static boolean isValidUtf8(byte[] byteArray) {
+    return Utf8.isValidUtf8(byteArray);
+  }
+
+  /**
+   * Helper method to get the UTF-8 bytes of a string.
+   */
+  public static byte[] toByteArray(String value) {
+    try {
+      return value.getBytes("UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 not supported?", e);
+    }
+  }
+  
+  /**
+   * Helper method to convert a byte array to a string using UTF-8 encoding.
+   */
+  public static String toStringUtf8(byte[] bytes) {
+    try {
+      return new String(bytes, "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 not supported?", e);
+    }
+  }
+
+  /**
+   * Interface for an enum value or value descriptor, to be used in FieldSet.
+   * The lite library stores enum values directly in FieldSets but the full
+   * library stores EnumValueDescriptors in order to better support reflection.
+   */
+  public interface EnumLite {
+    int getNumber();
+  }
+
+  /**
+   * Interface for an object which maps integers to {@link EnumLite}s.
+   * {@link Descriptors.EnumDescriptor} implements this interface by mapping
+   * numbers to {@link Descriptors.EnumValueDescriptor}s.  Additionally,
+   * every generated enum type has a static method internalGetValueMap() which
+   * returns an implementation of this type that maps numbers to enum values.
+   */
+  public interface EnumLiteMap<T extends EnumLite> {
+    T findValueByNumber(int number);
+  }
+
+  /**
+   * Helper method for implementing {@link MessageLite#hashCode()} for longs.
+   * @see Long#hashCode()
+   */
+  public static int hashLong(long n) {
+    return (int) (n ^ (n >>> 32));
+  }
+
+  /**
+   * Helper method for implementing {@link MessageLite#hashCode()} for
+   * booleans.
+   * @see Boolean#hashCode()
+   */
+  public static int hashBoolean(boolean b) {
+    return b ? 1231 : 1237;
+  }
+
+  /**
+   * Helper method for implementing {@link MessageLite#hashCode()} for enums.
+   * <p>
+   * This is needed because {@link java.lang.Enum#hashCode()} is final, but we
+   * need to use the field number as the hash code to ensure compatibility
+   * between statically and dynamically generated enum objects.
+   */
+  public static int hashEnum(EnumLite e) {
+    return e.getNumber();
+  }
+
+  /**
+   * Helper method for implementing {@link MessageLite#hashCode()} for
+   * enum lists.
+   */
+  public static int hashEnumList(List<? extends EnumLite> list) {
+    int hash = 1;
+    for (EnumLite e : list) {
+      hash = 31 * hash + hashEnum(e);
+    }
+    return hash;
+  }
+  
+  /**
+   * Helper method for implementing {@link MessageLite#equals()} for bytes field.
+   */
+  public static boolean equals(List<byte[]> a, List<byte[]> b) {
+    if (a.size() != b.size()) return false;
+    for (int i = 0; i < a.size(); ++i) {
+      if (!Arrays.equals(a.get(i), b.get(i))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Helper method for implementing {@link MessageLite#hashCode()} for bytes field.
+   */
+  public static int hashCode(List<byte[]> list) {
+    int hash = 1;
+    for (byte[] bytes : list) {
+      hash = 31 * hash + hashCode(bytes);
+    }
+    return hash;
+  }
+  
+  /**
+   * Helper method for implementing {@link MessageLite#hashCode()} for bytes field.
+   */
+  public static int hashCode(byte[] bytes) {
+    // The hash code for a byte array should be the same as the hash code for a
+    // ByteString with the same content. This is to ensure that the generated
+    // hashCode() method will return the same value as the pure reflection
+    // based hashCode() method.
+    return LiteralByteString.hashCode(bytes);
+  }
+  
+  /**
+   * Helper method for implementing {@link MessageLite#equals()} for bytes
+   * field.
+   */
+  public static boolean equalsByteBuffer(ByteBuffer a, ByteBuffer b) {
+    if (a.capacity() != b.capacity()) {
+      return false;
+    }
+    // ByteBuffer.equals() will only compare the remaining bytes, but we want to
+    // compare all the content.
+    return a.duplicate().clear().equals(b.duplicate().clear());
+  }
+  
+  /**
+   * Helper method for implementing {@link MessageLite#equals()} for bytes
+   * field.
+   */
+  public static boolean equalsByteBuffer(
+      List<ByteBuffer> a, List<ByteBuffer> b) {
+    if (a.size() != b.size()) {
+      return false;
+    }
+    for (int i = 0; i < a.size(); ++i) {
+      if (!equalsByteBuffer(a.get(i), b.get(i))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Helper method for implementing {@link MessageLite#hashCode()} for bytes
+   * field.
+   */
+  public static int hashCodeByteBuffer(List<ByteBuffer> list) {
+    int hash = 1;
+    for (ByteBuffer bytes : list) {
+      hash = 31 * hash + hashCodeByteBuffer(bytes);
+    }
+    return hash;
+  }
+  
+  private static final int DEFAULT_BUFFER_SIZE = 4096;
+  
+  /**
+   * Helper method for implementing {@link MessageLite#hashCode()} for bytes
+   * field.
+   */
+  public static int hashCodeByteBuffer(ByteBuffer bytes) {
+    if (bytes.hasArray()) {
+      // Fast path.
+      int h = LiteralByteString.hashCode(bytes.capacity(), bytes.array(),
+          bytes.arrayOffset(), bytes.capacity());
+      return h == 0 ? 1 : h;
+    } else {
+      // Read the data into a temporary byte array before calculating the
+      // hash value.
+      final int bufferSize = bytes.capacity() > DEFAULT_BUFFER_SIZE
+          ? DEFAULT_BUFFER_SIZE : bytes.capacity();
+      final byte[] buffer = new byte[bufferSize];
+      final ByteBuffer duplicated = bytes.duplicate();
+      duplicated.clear();
+      int h = bytes.capacity();
+      while (duplicated.remaining() > 0) {
+        final int length = duplicated.remaining() <= bufferSize ?
+            duplicated.remaining() : bufferSize;
+        duplicated.get(buffer, 0, length);
+        h = LiteralByteString.hashCode(h, buffer, 0, length);
+      }
+      return h == 0 ? 1 : h;
+    }
+  }
+  
+  /**
+   * An empty byte array constant used in generated code.
+   */
+  public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+  
+  /**
+   * An empty byte array constant used in generated code.
+   */
+  public static final ByteBuffer EMPTY_BYTE_BUFFER =
+      ByteBuffer.wrap(EMPTY_BYTE_ARRAY);
+
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java b/protobuf/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
new file mode 100644
index 0000000..367fa23
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java
@@ -0,0 +1,122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+
+/**
+ * Thrown when a protocol message being parsed is invalid in some way,
+ * e.g. it contains a malformed varint or a negative byte length.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class InvalidProtocolBufferException extends IOException {
+  private static final long serialVersionUID = -1616151763072450476L;
+  private MessageLite unfinishedMessage = null;
+
+  public InvalidProtocolBufferException(final String description) {
+    super(description);
+  }
+
+  /**
+   * Attaches an unfinished message to the exception to support best-effort
+   * parsing in {@code Parser} interface.
+   *
+   * @return this
+   */
+  public InvalidProtocolBufferException setUnfinishedMessage(
+      MessageLite unfinishedMessage) {
+    this.unfinishedMessage = unfinishedMessage;
+    return this;
+  }
+
+  /**
+   * Returns the unfinished message attached to the exception, or null if
+   * no message is attached.
+   */
+  public MessageLite getUnfinishedMessage() {
+    return unfinishedMessage;
+  }
+
+  static InvalidProtocolBufferException truncatedMessage() {
+    return new InvalidProtocolBufferException(
+      "While parsing a protocol message, the input ended unexpectedly " +
+      "in the middle of a field.  This could mean either than the " +
+      "input has been truncated or that an embedded message " +
+      "misreported its own length.");
+  }
+
+  static InvalidProtocolBufferException negativeSize() {
+    return new InvalidProtocolBufferException(
+      "CodedInputStream encountered an embedded string or message " +
+      "which claimed to have negative size.");
+  }
+
+  static InvalidProtocolBufferException malformedVarint() {
+    return new InvalidProtocolBufferException(
+      "CodedInputStream encountered a malformed varint.");
+  }
+
+  static InvalidProtocolBufferException invalidTag() {
+    return new InvalidProtocolBufferException(
+      "Protocol message contained an invalid tag (zero).");
+  }
+
+  static InvalidProtocolBufferException invalidEndTag() {
+    return new InvalidProtocolBufferException(
+      "Protocol message end-group tag did not match expected tag.");
+  }
+
+  static InvalidProtocolBufferException invalidWireType() {
+    return new InvalidProtocolBufferException(
+      "Protocol message tag had invalid wire type.");
+  }
+
+  static InvalidProtocolBufferException recursionLimitExceeded() {
+    return new InvalidProtocolBufferException(
+      "Protocol message had too many levels of nesting.  May be malicious.  " +
+      "Use CodedInputStream.setRecursionLimit() to increase the depth limit.");
+  }
+
+  static InvalidProtocolBufferException sizeLimitExceeded() {
+    return new InvalidProtocolBufferException(
+      "Protocol message was too large.  May be malicious.  " +
+      "Use CodedInputStream.setSizeLimit() to increase the size limit.");
+  }
+
+  static InvalidProtocolBufferException parseFailure() {
+    return new InvalidProtocolBufferException("Failed to parse the message.");
+  }
+
+  static InvalidProtocolBufferException invalidUtf8() {
+    return new InvalidProtocolBufferException("Protocol message had invalid UTF-8.");
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/LazyField.java b/protobuf/java/src/main/java/com/google/protobuf/LazyField.java
new file mode 100644
index 0000000..3da8b90
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/LazyField.java
@@ -0,0 +1,154 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+
+/**
+ * LazyField encapsulates the logic of lazily parsing message fields. It stores
+ * the message in a ByteString initially and then parse it on-demand.
+ *
+ * Most of key methods are implemented in {@link LazyFieldLite} but this class
+ * can contain default instance of the message to provide {@code hashCode()},
+ * {@code euqals()} and {@code toString()}.
+ *
+ * @author xiangl@google.com (Xiang Li)
+ */
+public class LazyField extends LazyFieldLite {
+
+  /**
+   * Carry a message's default instance which is used by {@code hashCode()}, {@code euqals()} and
+   * {@code toString()}.
+   */
+  private final MessageLite defaultInstance;
+
+  public LazyField(MessageLite defaultInstance,
+      ExtensionRegistryLite extensionRegistry, ByteString bytes) {
+    super(extensionRegistry, bytes);
+
+    this.defaultInstance = defaultInstance;
+  }
+
+  @Override
+  public boolean containsDefaultInstance() {
+    return super.containsDefaultInstance() || value == defaultInstance;
+  }
+
+  public MessageLite getValue() {
+    return getValue(defaultInstance);
+  }
+
+  @Override
+  public int hashCode() {
+    return getValue().hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    return getValue().equals(obj);
+  }
+
+  @Override
+  public String toString() {
+    return getValue().toString();
+  }
+
+  // ====================================================
+
+  /**
+   * LazyEntry and LazyIterator are used to encapsulate the LazyField, when
+   * users iterate all fields from FieldSet.
+   */
+  static class LazyEntry<K> implements Entry<K, Object> {
+    private Entry<K, LazyField> entry;
+
+    private LazyEntry(Entry<K, LazyField> entry) {
+      this.entry = entry;
+    }
+
+    // @Override
+    public K getKey() {
+      return entry.getKey();
+    }
+
+    // @Override
+    public Object getValue() {
+      LazyField field = entry.getValue();
+      if (field == null) {
+        return null;
+      }
+      return field.getValue();
+    }
+
+    public LazyField getField() {
+      return entry.getValue();
+    }
+
+    // @Override
+    public Object setValue(Object value) {
+      if (!(value instanceof MessageLite)) {
+        throw new IllegalArgumentException(
+            "LazyField now only used for MessageSet, "
+            + "and the value of MessageSet must be an instance of MessageLite");
+      }
+      return entry.getValue().setValue((MessageLite) value);
+    }
+  }
+
+  static class LazyIterator<K> implements Iterator<Entry<K, Object>> {
+    private Iterator<Entry<K, Object>> iterator;
+
+    public LazyIterator(Iterator<Entry<K, Object>> iterator) {
+      this.iterator = iterator;
+    }
+
+    // @Override
+    public boolean hasNext() {
+      return iterator.hasNext();
+    }
+
+    @SuppressWarnings("unchecked")
+    // @Override
+    public Entry<K, Object> next() {
+      Entry<K, ?> entry = iterator.next();
+      if (entry.getValue() instanceof LazyField) {
+        return new LazyEntry<K>((Entry<K, LazyField>) entry);
+      }
+      return (Entry<K, Object>) entry;
+    }
+
+    // @Override
+    public void remove() {
+      iterator.remove();
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/LazyFieldLite.java b/protobuf/java/src/main/java/com/google/protobuf/LazyFieldLite.java
new file mode 100644
index 0000000..1fc80e8
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/LazyFieldLite.java
@@ -0,0 +1,176 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+
+/**
+ * LazyFieldLite encapsulates the logic of lazily parsing message fields. It stores
+ * the message in a ByteString initially and then parse it on-demand.
+ *
+ * LazyField is thread-compatible e.g. concurrent read are safe, however,
+ * synchronizations are needed under read/write situations.
+ *
+ * This class is internal implementation detail, so you don't need to use it directly.
+ *
+ * @author xiangl@google.com (Xiang Li)
+ */
+public class LazyFieldLite {
+  private ByteString bytes;
+  private ExtensionRegistryLite extensionRegistry;
+  private volatile boolean isDirty = false;
+
+  protected volatile MessageLite value;
+
+  public LazyFieldLite(ExtensionRegistryLite extensionRegistry, ByteString bytes) {
+    this.extensionRegistry = extensionRegistry;
+    this.bytes = bytes;
+  }
+
+  public LazyFieldLite() {
+  }
+
+  public static LazyFieldLite fromValue(MessageLite value) {
+    LazyFieldLite lf = new LazyFieldLite();
+    lf.setValue(value);
+    return lf;
+  }
+
+  public boolean containsDefaultInstance() {
+    return value == null && bytes == null;
+  }
+
+  public void clear() {
+    bytes = null;
+    value = null;
+    extensionRegistry = null;
+    isDirty = true;
+  }
+
+  /**
+   * Returns message instance. At first time, serialized data is parsed by
+   * {@code defaultInstance.getParserForType()}.
+   *
+   * @param defaultInstance its message's default instance. It's also used to get parser for the
+   * message type.
+   */
+  public MessageLite getValue(MessageLite defaultInstance) {
+    ensureInitialized(defaultInstance);
+    return value;
+  }
+
+  /**
+   * LazyField is not thread-safe for write access. Synchronizations are needed
+   * under read/write situations.
+   */
+  public MessageLite setValue(MessageLite value) {
+    MessageLite originalValue = this.value;
+    this.value = value;
+    bytes = null;
+    isDirty = true;
+    return originalValue;
+  }
+
+  public void merge(LazyFieldLite value) {
+    if (value.containsDefaultInstance()) {
+      return;
+    }
+
+    if (bytes == null) {
+      this.bytes = value.bytes;
+    } else {
+      this.bytes.concat(value.toByteString());
+    }
+    isDirty = false;
+  }
+
+  public void setByteString(ByteString bytes, ExtensionRegistryLite extensionRegistry) {
+    this.bytes = bytes;
+    this.extensionRegistry = extensionRegistry;
+    isDirty = false;
+  }
+
+  public ExtensionRegistryLite getExtensionRegistry() {
+    return extensionRegistry;
+  }
+
+  /**
+   * Due to the optional field can be duplicated at the end of serialized
+   * bytes, which will make the serialized size changed after LazyField
+   * parsed. Be careful when using this method.
+   */
+  public int getSerializedSize() {
+    if (isDirty) {
+      return value.getSerializedSize();
+    }
+    return bytes.size();
+  }
+
+  public ByteString toByteString() {
+    if (!isDirty) {
+      return bytes;
+    }
+    synchronized (this) {
+      if (!isDirty) {
+        return bytes;
+      }
+      if (value == null) {
+        bytes = ByteString.EMPTY;
+      } else {
+        bytes = value.toByteString();
+      }
+      isDirty = false;
+      return bytes;
+    }
+  }
+
+  protected void ensureInitialized(MessageLite defaultInstance) {
+    if (value != null) {
+      return;
+    }
+    synchronized (this) {
+      if (value != null) {
+        return;
+      }
+      try {
+        if (bytes != null) {
+          value = defaultInstance.getParserForType()
+              .parseFrom(bytes, extensionRegistry);
+        } else {
+          value = defaultInstance;
+        }
+      } catch (IOException e) {
+        // TODO(xiangl): Refactory the API to support the exception thrown from
+        // lazily load messages.
+      }
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/LazyStringArrayList.java b/protobuf/java/src/main/java/com/google/protobuf/LazyStringArrayList.java
new file mode 100644
index 0000000..61c7e1e
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/LazyStringArrayList.java
@@ -0,0 +1,367 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.RandomAccess;
+
+/**
+ * An implementation of {@link LazyStringList} that wraps an ArrayList. Each
+ * element is one of String, ByteString, or byte[]. It caches the last one
+ * requested which is most likely the one needed next. This minimizes memory
+ * usage while satisfying the most common use cases.
+ * <p>
+ * <strong>Note that this implementation is not synchronized.</strong>
+ * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
+ * and at least one of the threads modifies the list structurally, it
+ * <i>must</i> be synchronized externally.  (A structural modification is
+ * any operation that adds or deletes one or more elements, or explicitly
+ * resizes the backing array; merely setting the value of an element is not
+ * a structural modification.)  This is typically accomplished by
+ * synchronizing on some object that naturally encapsulates the list.
+ * <p>
+ * If the implementation is accessed via concurrent reads, this is thread safe.
+ * Conversions are done in a thread safe manner. It's possible that the
+ * conversion may happen more than once if two threads attempt to access the
+ * same element and the modifications were not visible to each other, but this
+ * will not result in any corruption of the list or change in behavior other
+ * than performance.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class LazyStringArrayList extends AbstractList<String>
+    implements LazyStringList, RandomAccess {
+
+  public static final LazyStringList EMPTY =
+      new LazyStringArrayList().getUnmodifiableView();
+
+  private final List<Object> list;
+
+  public LazyStringArrayList() {
+    list = new ArrayList<Object>();
+  }
+
+  public LazyStringArrayList(LazyStringList from) {
+    list = new ArrayList<Object>(from.size());
+    addAll(from);
+  }
+
+  public LazyStringArrayList(List<String> from) {
+    list = new ArrayList<Object>(from);
+  }
+
+  @Override
+  public String get(int index) {
+    Object o = list.get(index);
+    if (o instanceof String) {
+      return (String) o;
+    } else if (o instanceof ByteString) {
+      ByteString bs = (ByteString) o;
+      String s = bs.toStringUtf8();
+      if (bs.isValidUtf8()) {
+        list.set(index, s);
+      }
+      return s;
+    } else {
+      byte[] ba = (byte[]) o;
+      String s = Internal.toStringUtf8(ba);
+      if (Internal.isValidUtf8(ba)) {
+        list.set(index, s);
+      }
+      return s;
+    }
+  }
+
+  @Override
+  public int size() {
+    return list.size();
+  }
+
+  @Override
+  public String set(int index, String s) {
+    Object o = list.set(index, s);
+    return asString(o);
+  }
+
+  @Override
+  public void add(int index, String element) {
+    list.add(index, element);
+    modCount++;
+  }
+
+  @Override
+  public boolean addAll(Collection<? extends String> c) {
+    // The default implementation of AbstractCollection.addAll(Collection)
+    // delegates to add(Object). This implementation instead delegates to
+    // addAll(int, Collection), which makes a special case for Collections
+    // which are instances of LazyStringList.
+    return addAll(size(), c);
+  }
+
+  @Override
+  public boolean addAll(int index, Collection<? extends String> c) {
+    // When copying from another LazyStringList, directly copy the underlying
+    // elements rather than forcing each element to be decoded to a String.
+    Collection<?> collection = c instanceof LazyStringList
+        ? ((LazyStringList) c).getUnderlyingElements() : c;
+    boolean ret = list.addAll(index, collection);
+    modCount++;
+    return ret;
+  }
+
+  // @Override
+  public boolean addAllByteString(Collection<? extends ByteString> values) {
+    boolean ret = list.addAll(values);
+    modCount++;
+    return ret;
+  }
+
+  // @Override
+  public boolean addAllByteArray(Collection<byte[]> c) {
+    boolean ret = list.addAll(c);
+    modCount++;
+    return ret;
+  }
+
+  @Override
+  public String remove(int index) {
+    Object o = list.remove(index);
+    modCount++;
+    return asString(o);
+  }
+
+  @Override
+  public void clear() {
+    list.clear();
+    modCount++;
+  }
+
+  // @Override
+  public void add(ByteString element) {
+    list.add(element);
+    modCount++;
+  }
+  
+  // @Override
+  public void add(byte[] element) {
+    list.add(element);
+    modCount++;
+  }
+
+  // @Override
+  public ByteString getByteString(int index) {
+    Object o = list.get(index);
+    ByteString b = asByteString(o);
+    if (b != o) {
+      list.set(index, b);
+    }
+    return b;
+  }
+  
+  // @Override
+  public byte[] getByteArray(int index) {
+    Object o = list.get(index);
+    byte[] b = asByteArray(o);
+    if (b != o) {
+      list.set(index, b);
+    }
+    return b;
+  }
+
+  // @Override
+  public void set(int index, ByteString s) {
+    list.set(index, s);
+  }
+
+  // @Override
+  public void set(int index, byte[] s) {
+    list.set(index, s);
+  }
+
+
+  private static String asString(Object o) {
+    if (o instanceof String) {
+      return (String) o;
+    } else if (o instanceof ByteString) {
+      return ((ByteString) o).toStringUtf8();
+    } else {
+      return Internal.toStringUtf8((byte[]) o);
+    }
+  }
+  
+  private static ByteString asByteString(Object o) {
+    if (o instanceof ByteString) {
+      return (ByteString) o;
+    } else if (o instanceof String) {
+      return ByteString.copyFromUtf8((String) o);
+    } else {
+      return ByteString.copyFrom((byte[]) o);
+    }
+  }
+  
+  private static byte[] asByteArray(Object o) {
+    if (o instanceof byte[]) {
+      return (byte[]) o;
+    } else if (o instanceof String) {
+      return Internal.toByteArray((String) o);
+    } else {
+      return ((ByteString) o).toByteArray();
+    }
+  }
+
+  // @Override
+  public List<?> getUnderlyingElements() {
+    return Collections.unmodifiableList(list);
+  }
+
+  // @Override
+  public void mergeFrom(LazyStringList other) {
+    for (Object o : other.getUnderlyingElements()) {
+      if (o instanceof byte[]) {
+        byte[] b = (byte[]) o;
+        // Byte array's content is mutable so they should be copied rather than
+        // shared when merging from one message to another.
+        list.add(Arrays.copyOf(b, b.length));
+      } else {
+        list.add(o);
+      }
+    }
+  }
+
+  private static class ByteArrayListView extends AbstractList<byte[]>
+      implements RandomAccess {
+    private final List<Object> list;
+    
+    ByteArrayListView(List<Object> list) {
+      this.list = list;
+    }
+    
+    @Override
+    public byte[] get(int index) {
+      Object o = list.get(index);
+      byte[] b = asByteArray(o);
+      if (b != o) {
+        list.set(index, b);
+      }
+      return b;
+    }
+
+    @Override
+    public int size() {
+      return list.size();
+    }
+
+    @Override
+    public byte[] set(int index, byte[] s) {
+      Object o = list.set(index, s);
+      modCount++;
+      return asByteArray(o);
+    }
+
+    @Override
+    public void add(int index, byte[] s) {
+      list.add(index, s);
+      modCount++;
+    }
+
+    @Override
+    public byte[] remove(int index) {
+      Object o = list.remove(index);
+      modCount++;
+      return asByteArray(o);
+    }
+  }
+  
+  // @Override
+  public List<byte[]> asByteArrayList() {
+    return new ByteArrayListView(list);
+  }
+
+  private static class ByteStringListView extends AbstractList<ByteString>
+      implements RandomAccess {
+    private final List<Object> list;
+
+    ByteStringListView(List<Object> list) {
+      this.list = list;
+    }
+
+    @Override
+    public ByteString get(int index) {
+      Object o = list.get(index);
+      ByteString b = asByteString(o);
+      if (b != o) {
+        list.set(index, b);
+      }
+      return b;
+    }
+
+    @Override
+    public int size() {
+      return list.size();
+    }
+
+    @Override
+    public ByteString set(int index, ByteString s) {
+      Object o = list.set(index, s);
+      modCount++;
+      return asByteString(o);
+    }
+
+    @Override
+    public void add(int index, ByteString s) {
+      list.add(index, s);
+      modCount++;
+    }
+
+    @Override
+    public ByteString remove(int index) {
+      Object o = list.remove(index);
+      modCount++;
+      return asByteString(o);
+    }
+  }
+
+  // @Override
+  public List<ByteString> asByteStringList() {
+    return new ByteStringListView(list);
+  }
+
+  // @Override
+  public LazyStringList getUnmodifiableView() {
+    return new UnmodifiableLazyStringList(this);
+  }
+
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/LazyStringList.java b/protobuf/java/src/main/java/com/google/protobuf/LazyStringList.java
new file mode 100644
index 0000000..235126b
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/LazyStringList.java
@@ -0,0 +1,163 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * An interface extending {@code List<String>} that also provides access to the
+ * items of the list as UTF8-encoded ByteString or byte[] objects. This is
+ * used by the protocol buffer implementation to support lazily converting bytes
+ * parsed over the wire to String objects until needed and also increases the
+ * efficiency of serialization if the String was never requested as the
+ * ByteString or byte[] is already cached. The ByteString methods are used in
+ * immutable API only and byte[] methods used in mutable API only for they use
+ * different representations for string/bytes fields.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public interface LazyStringList extends ProtocolStringList {
+
+  /**
+   * Returns the element at the specified position in this list as a ByteString.
+   *
+   * @param index index of the element to return
+   * @return the element at the specified position in this list
+   * @throws IndexOutOfBoundsException if the index is out of range
+   *         ({@code index < 0 || index >= size()})
+   */
+  ByteString getByteString(int index);
+  
+  /**
+   * Returns the element at the specified position in this list as byte[].
+   *
+   * @param index index of the element to return
+   * @return the element at the specified position in this list
+   * @throws IndexOutOfBoundsException if the index is out of range
+   *         ({@code index < 0 || index >= size()})
+   */
+  byte[] getByteArray(int index);
+
+  /**
+   * Appends the specified element to the end of this list (optional
+   * operation).
+   *
+   * @param element element to be appended to this list
+   * @throws UnsupportedOperationException if the <tt>add</tt> operation
+   *         is not supported by this list
+   */
+  void add(ByteString element);
+
+  /**
+   * Appends the specified element to the end of this list (optional
+   * operation).
+   *
+   * @param element element to be appended to this list
+   * @throws UnsupportedOperationException if the <tt>add</tt> operation
+   *         is not supported by this list
+   */
+  void add(byte[] element);
+
+  /**
+   * Replaces the element at the specified position in this list with the
+   * specified element (optional operation).
+   *
+   * @param index index of the element to replace
+   * @param element the element to be stored at the specified position
+   * @throws UnsupportedOperationException if the <tt>set</tt> operation
+   *         is not supported by this list
+   *         IndexOutOfBoundsException if the index is out of range
+   *         ({@code index < 0 || index >= size()})
+   */
+  void set(int index, ByteString element);
+  
+  /**
+   * Replaces the element at the specified position in this list with the
+   * specified element (optional operation).
+   *
+   * @param index index of the element to replace
+   * @param element the element to be stored at the specified position
+   * @throws UnsupportedOperationException if the <tt>set</tt> operation
+   *         is not supported by this list
+   *         IndexOutOfBoundsException if the index is out of range
+   *         ({@code index < 0 || index >= size()})
+   */
+  void set(int index, byte[] element);
+
+  /**
+   * Appends all elements in the specified ByteString collection to the end of
+   * this list.
+   *
+   * @param c collection whose elements are to be added to this list
+   * @return true if this list changed as a result of the call
+   * @throws UnsupportedOperationException if the <tt>addAllByteString</tt>
+   *         operation is not supported by this list
+   */
+  boolean addAllByteString(Collection<? extends ByteString> c);
+
+  /**
+   * Appends all elements in the specified byte[] collection to the end of
+   * this list.
+   *
+   * @param c collection whose elements are to be added to this list
+   * @return true if this list changed as a result of the call
+   * @throws UnsupportedOperationException if the <tt>addAllByteArray</tt>
+   *         operation is not supported by this list
+   */
+  boolean addAllByteArray(Collection<byte[]> c);
+
+  /**
+   * Returns an unmodifiable List of the underlying elements, each of which is
+   * either a {@code String} or its equivalent UTF-8 encoded {@code ByteString}
+   * or byte[]. It is an error for the caller to modify the returned
+   * List, and attempting to do so will result in an
+   * {@link UnsupportedOperationException}.
+   */
+  List<?> getUnderlyingElements();
+
+  /**
+   * Merges all elements from another LazyStringList into this one. This method
+   * differs from {@link #addAll(Collection)} on that underlying byte arrays are
+   * copied instead of reference shared. Immutable API doesn't need to use this
+   * method as byte[] is not used there at all.
+   */
+  void mergeFrom(LazyStringList other);
+
+  /**
+   * Returns a mutable view of this list. Changes to the view will be made into
+   * the original list. This method is used in mutable API only.
+   */
+  List<byte[]> asByteArrayList();
+
+  /** Returns an unmodifiable view of the list. */
+  LazyStringList getUnmodifiableView();
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/LiteralByteString.java b/protobuf/java/src/main/java/com/google/protobuf/LiteralByteString.java
new file mode 100644
index 0000000..83e71e9
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/LiteralByteString.java
@@ -0,0 +1,362 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * This class implements a {@link com.google.protobuf.ByteString} backed by a
+ * single array of bytes, contiguous in memory. It supports substring by
+ * pointing to only a sub-range of the underlying byte array, meaning that a
+ * substring will reference the full byte-array of the string it's made from,
+ * exactly as with {@link String}.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+class LiteralByteString extends ByteString {
+
+  protected final byte[] bytes;
+
+  /**
+   * Creates a {@code LiteralByteString} backed by the given array, without
+   * copying.
+   *
+   * @param bytes array to wrap
+   */
+  LiteralByteString(byte[] bytes) {
+    this.bytes = bytes;
+  }
+
+  @Override
+  public byte byteAt(int index) {
+    // Unlike most methods in this class, this one is a direct implementation
+    // ignoring the potential offset because we need to do range-checking in the
+    // substring case anyway.
+    return bytes[index];
+  }
+
+  @Override
+  public int size() {
+    return bytes.length;
+  }
+
+  // =================================================================
+  // ByteString -> substring
+
+  @Override
+  public ByteString substring(int beginIndex, int endIndex) {
+    if (beginIndex < 0) {
+      throw new IndexOutOfBoundsException(
+          "Beginning index: " + beginIndex + " < 0");
+    }
+    if (endIndex > size()) {
+      throw new IndexOutOfBoundsException("End index: " + endIndex + " > " +
+          size());
+    }
+    int substringLength = endIndex - beginIndex;
+    if (substringLength < 0) {
+      throw new IndexOutOfBoundsException(
+          "Beginning index larger than ending index: " + beginIndex + ", "
+              + endIndex);
+    }
+
+    ByteString result;
+    if (substringLength == 0) {
+      result = ByteString.EMPTY;
+    } else {
+      result = new BoundedByteString(bytes, getOffsetIntoBytes() + beginIndex,
+          substringLength);
+    }
+    return result;
+  }
+
+  // =================================================================
+  // ByteString -> byte[]
+
+  @Override
+  protected void copyToInternal(byte[] target, int sourceOffset, 
+      int targetOffset, int numberToCopy) {
+    // Optimized form, not for subclasses, since we don't call
+    // getOffsetIntoBytes() or check the 'numberToCopy' parameter.
+    System.arraycopy(bytes, sourceOffset, target, targetOffset, numberToCopy);
+  }
+
+  @Override
+  public void copyTo(ByteBuffer target) {
+    target.put(bytes, getOffsetIntoBytes(), size());  // Copies bytes
+  }
+
+  @Override
+  public ByteBuffer asReadOnlyByteBuffer() {
+    ByteBuffer byteBuffer =
+        ByteBuffer.wrap(bytes, getOffsetIntoBytes(), size());
+    return byteBuffer.asReadOnlyBuffer();
+  }
+
+  @Override
+  public List<ByteBuffer> asReadOnlyByteBufferList() {
+    // Return the ByteBuffer generated by asReadOnlyByteBuffer() as a singleton
+    List<ByteBuffer> result = new ArrayList<ByteBuffer>(1);
+    result.add(asReadOnlyByteBuffer());
+    return result;
+ }
+
+ @Override
+  public void writeTo(OutputStream outputStream) throws IOException {
+    outputStream.write(toByteArray());
+  }
+
+  @Override
+  void writeToInternal(OutputStream outputStream, int sourceOffset,
+      int numberToWrite) throws IOException {
+    outputStream.write(bytes, getOffsetIntoBytes() + sourceOffset,
+        numberToWrite);
+  }
+
+  @Override
+  public String toString(String charsetName)
+      throws UnsupportedEncodingException {
+    return new String(bytes, getOffsetIntoBytes(), size(), charsetName);
+  }
+
+  // =================================================================
+  // UTF-8 decoding
+
+  @Override
+  public boolean isValidUtf8() {
+    int offset = getOffsetIntoBytes();
+    return Utf8.isValidUtf8(bytes, offset, offset + size());
+  }
+
+  @Override
+  protected int partialIsValidUtf8(int state, int offset, int length) {
+    int index = getOffsetIntoBytes() + offset;
+    return Utf8.partialIsValidUtf8(state, bytes, index, index + length);
+  }
+
+  // =================================================================
+  // equals() and hashCode()
+
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) {
+      return true;
+    }
+    if (!(other instanceof ByteString)) {
+      return false;
+    }
+
+    if (size() != ((ByteString) other).size()) {
+      return false;
+    }
+    if (size() == 0) {
+      return true;
+    }
+
+    if (other instanceof LiteralByteString) {
+      return equalsRange((LiteralByteString) other, 0, size());
+    } else if (other instanceof RopeByteString) {
+      return other.equals(this);
+    } else {
+      throw new IllegalArgumentException(
+          "Has a new type of ByteString been created? Found "
+              + other.getClass());
+    }
+  }
+
+  /**
+   * Check equality of the substring of given length of this object starting at
+   * zero with another {@code LiteralByteString} substring starting at offset.
+   *
+   * @param other  what to compare a substring in
+   * @param offset offset into other
+   * @param length number of bytes to compare
+   * @return true for equality of substrings, else false.
+   */
+  boolean equalsRange(LiteralByteString other, int offset, int length) {
+    if (length > other.size()) {
+      throw new IllegalArgumentException(
+          "Length too large: " + length + size());
+    }
+    if (offset + length > other.size()) {
+      throw new IllegalArgumentException(
+          "Ran off end of other: " + offset + ", " + length + ", " +
+              other.size());
+    }
+
+    byte[] thisBytes = bytes;
+    byte[] otherBytes = other.bytes;
+    int thisLimit = getOffsetIntoBytes() + length;
+    for (int thisIndex = getOffsetIntoBytes(), otherIndex =
+        other.getOffsetIntoBytes() + offset;
+        (thisIndex < thisLimit); ++thisIndex, ++otherIndex) {
+      if (thisBytes[thisIndex] != otherBytes[otherIndex]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Cached hash value.  Intentionally accessed via a data race, which
+   * is safe because of the Java Memory Model's "no out-of-thin-air values"
+   * guarantees for ints.
+   */
+  private int hash = 0;
+
+  /**
+   * Compute the hashCode using the traditional algorithm from {@link
+   * ByteString}.
+   *
+   * @return hashCode value
+   */
+  @Override
+  public int hashCode() {
+    int h = hash;
+
+    if (h == 0) {
+      int size = size();
+      h = partialHash(size, 0, size);
+      if (h == 0) {
+        h = 1;
+      }
+      hash = h;
+    }
+    return h;
+  }
+
+  @Override
+  protected int peekCachedHashCode() {
+    return hash;
+  }
+
+  @Override
+  protected int partialHash(int h, int offset, int length) {
+    return hashCode(h, bytes, getOffsetIntoBytes() + offset, length);
+  }
+  
+  static int hashCode(int h, byte[] bytes, int offset, int length) {
+    for (int i = offset; i < offset + length; i++) {
+      h = h * 31 + bytes[i];
+    }
+    return h;
+  }
+  
+  static int hashCode(byte[] bytes) {
+    int h = hashCode(bytes.length, bytes, 0, bytes.length);
+    return h == 0 ? 1 : h;
+  }
+
+  // =================================================================
+  // Input stream
+
+  @Override
+  public InputStream newInput() {
+    return new ByteArrayInputStream(bytes, getOffsetIntoBytes(),
+        size());  // No copy
+  }
+
+  @Override
+  public CodedInputStream newCodedInput() {
+    // We trust CodedInputStream not to modify the bytes, or to give anyone
+    // else access to them.
+    return CodedInputStream.newInstance(this);
+  }
+
+  // =================================================================
+  // ByteIterator
+
+  @Override
+  public ByteIterator iterator() {
+    return new LiteralByteIterator();
+  }
+
+  private class LiteralByteIterator implements ByteIterator {
+    private int position;
+    private final int limit;
+
+    private LiteralByteIterator() {
+      position = 0;
+      limit = size();
+    }
+
+    public boolean hasNext() {
+      return (position < limit);
+    }
+
+    public Byte next() {
+      // Boxing calls Byte.valueOf(byte), which does not instantiate.
+      return nextByte();
+    }
+
+    public byte nextByte() {
+      try {
+        return bytes[position++];
+      } catch (ArrayIndexOutOfBoundsException e) {
+        throw new NoSuchElementException(e.getMessage());
+      }
+    }
+
+    public void remove() {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  // =================================================================
+  // Internal methods
+
+  @Override
+  protected int getTreeDepth() {
+    return 0;
+  }
+
+  @Override
+  protected boolean isBalanced() {
+    return true;
+  }
+
+  /**
+   * Offset into {@code bytes[]} to use, non-zero for substrings.
+   *
+   * @return always 0 for this class
+   */
+  protected int getOffsetIntoBytes() {
+    return 0;
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/Message.java b/protobuf/java/src/main/java/com/google/protobuf/Message.java
new file mode 100644
index 0000000..5673d3b
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/Message.java
@@ -0,0 +1,244 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// TODO(kenton):  Use generics?  E.g. Builder<BuilderType extends Builder>, then
+//   mergeFrom*() could return BuilderType for better type-safety.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * Abstract interface implemented by Protocol Message objects.
+ * <p>
+ * See also {@link MessageLite}, which defines most of the methods that typical
+ * users care about.  {@link Message} adds to it methods that are not available
+ * in the "lite" runtime.  The biggest added features are introspection and
+ * reflection -- i.e., getting descriptors for the message type and accessing
+ * the field values dynamically.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface Message extends MessageLite, MessageOrBuilder {
+
+  // (From MessageLite, re-declared here only for return type covariance.)
+  Parser<? extends Message> getParserForType();
+
+
+  // -----------------------------------------------------------------
+  // Comparison and hashing
+
+  /**
+   * Compares the specified object with this message for equality.  Returns
+   * {@code true} if the given object is a message of the same type (as
+   * defined by {@code getDescriptorForType()}) and has identical values for
+   * all of its fields.  Subclasses must implement this; inheriting
+   * {@code Object.equals()} is incorrect.
+   *
+   * @param other object to be compared for equality with this message
+   * @return {@code true} if the specified object is equal to this message
+   */
+  @Override
+  boolean equals(Object other);
+
+  /**
+   * Returns the hash code value for this message.  The hash code of a message
+   * should mix the message's type (object identity of the descriptor) with its
+   * contents (known and unknown field values).  Subclasses must implement this;
+   * inheriting {@code Object.hashCode()} is incorrect.
+   *
+   * @return the hash code value for this message
+   * @see Map#hashCode()
+   */
+  @Override
+  int hashCode();
+
+  // -----------------------------------------------------------------
+  // Convenience methods.
+
+  /**
+   * Converts the message to a string in protocol buffer text format. This is
+   * just a trivial wrapper around {@link
+   * TextFormat#printToString(MessageOrBuilder)}.
+   */
+  @Override
+  String toString();
+
+  // =================================================================
+  // Builders
+
+  // (From MessageLite, re-declared here only for return type covariance.)
+  Builder newBuilderForType();
+  Builder toBuilder();
+
+  /**
+   * Abstract interface implemented by Protocol Message builders.
+   */
+  interface Builder extends MessageLite.Builder, MessageOrBuilder {
+    // (From MessageLite.Builder, re-declared here only for return type
+    // covariance.)
+    Builder clear();
+
+    /**
+     * Merge {@code other} into the message being built.  {@code other} must
+     * have the exact same type as {@code this} (i.e.
+     * {@code getDescriptorForType() == other.getDescriptorForType()}).
+     *
+     * Merging occurs as follows.  For each field:<br>
+     * * For singular primitive fields, if the field is set in {@code other},
+     *   then {@code other}'s value overwrites the value in this message.<br>
+     * * For singular message fields, if the field is set in {@code other},
+     *   it is merged into the corresponding sub-message of this message
+     *   using the same merging rules.<br>
+     * * For repeated fields, the elements in {@code other} are concatenated
+     *   with the elements in this message.
+     *
+     * This is equivalent to the {@code Message::MergeFrom} method in C++.
+     */
+    Builder mergeFrom(Message other);
+
+    // (From MessageLite.Builder, re-declared here only for return type
+    // covariance.)
+    Message build();
+    Message buildPartial();
+    Builder clone();
+    Builder mergeFrom(CodedInputStream input) throws IOException;
+    Builder mergeFrom(CodedInputStream input,
+                      ExtensionRegistryLite extensionRegistry)
+                      throws IOException;
+
+    /**
+     * Get the message's type's descriptor.
+     * See {@link Message#getDescriptorForType()}.
+     */
+    Descriptors.Descriptor getDescriptorForType();
+
+    /**
+     * Create a Builder for messages of the appropriate type for the given
+     * field.  Messages built with this can then be passed to setField(),
+     * setRepeatedField(), or addRepeatedField().
+     */
+    Builder newBuilderForField(Descriptors.FieldDescriptor field);
+
+    /**
+     * Get a nested builder instance for the given field.
+     * <p>
+     * Normally, we hold a reference to the immutable message object for the
+     * message type field. Some implementations(the generated message builders),
+     * however, can also hold a reference to the builder object (a nested
+     * builder) for the field.
+     * <p>
+     * If the field is already backed up by a nested builder, the nested builder
+     * will be returned. Otherwise, a new field builder will be created and
+     * returned. The original message field (if exist) will be merged into the
+     * field builder, which will then be nested into its parent builder.
+     * <p>
+     * NOTE: implementations that do not support nested builders will throw
+     * <code>UnsupportedException</code>.
+     */
+    Builder getFieldBuilder(Descriptors.FieldDescriptor field);
+
+    /**
+     * Sets a field to the given value.  The value must be of the correct type
+     * for this field, i.e. the same type that
+     * {@link Message#getField(Descriptors.FieldDescriptor)} would return.
+     */
+    Builder setField(Descriptors.FieldDescriptor field, Object value);
+
+    /**
+     * Clears the field.  This is exactly equivalent to calling the generated
+     * "clear" accessor method corresponding to the field.
+     */
+    Builder clearField(Descriptors.FieldDescriptor field);
+
+    /**
+     * Clears the oneof.  This is exactly equivalent to calling the generated
+     * "clear" accessor method corresponding to the oneof.
+     */
+    Builder clearOneof(Descriptors.OneofDescriptor oneof);
+
+    /**
+     * Sets an element of a repeated field to the given value.  The value must
+     * be of the correct type for this field, i.e. the same type that
+     * {@link Message#getRepeatedField(Descriptors.FieldDescriptor,int)} would
+     * return.
+     * @throws IllegalArgumentException The field is not a repeated field, or
+     *           {@code field.getContainingType() != getDescriptorForType()}.
+     */
+    Builder setRepeatedField(Descriptors.FieldDescriptor field,
+                             int index, Object value);
+
+    /**
+     * Like {@code setRepeatedField}, but appends the value as a new element.
+     * @throws IllegalArgumentException The field is not a repeated field, or
+     *           {@code field.getContainingType() != getDescriptorForType()}.
+     */
+    Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value);
+
+    /** Set the {@link UnknownFieldSet} for this message. */
+    Builder setUnknownFields(UnknownFieldSet unknownFields);
+
+    /**
+     * Merge some unknown fields into the {@link UnknownFieldSet} for this
+     * message.
+     */
+    Builder mergeUnknownFields(UnknownFieldSet unknownFields);
+
+    // ---------------------------------------------------------------
+    // Convenience methods.
+
+    // (From MessageLite.Builder, re-declared here only for return type
+    // covariance.)
+    Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException;
+    Builder mergeFrom(ByteString data,
+                      ExtensionRegistryLite extensionRegistry)
+                      throws InvalidProtocolBufferException;
+    Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException;
+    Builder mergeFrom(byte[] data, int off, int len)
+                      throws InvalidProtocolBufferException;
+    Builder mergeFrom(byte[] data,
+                      ExtensionRegistryLite extensionRegistry)
+                      throws InvalidProtocolBufferException;
+    Builder mergeFrom(byte[] data, int off, int len,
+                      ExtensionRegistryLite extensionRegistry)
+                      throws InvalidProtocolBufferException;
+    Builder mergeFrom(InputStream input) throws IOException;
+    Builder mergeFrom(InputStream input,
+                      ExtensionRegistryLite extensionRegistry)
+                      throws IOException;
+    boolean mergeDelimitedFrom(InputStream input)
+                               throws IOException;
+    boolean mergeDelimitedFrom(InputStream input,
+                               ExtensionRegistryLite extensionRegistry)
+                               throws IOException;
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/MessageLite.java b/protobuf/java/src/main/java/com/google/protobuf/MessageLite.java
new file mode 100644
index 0000000..798b794
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/MessageLite.java
@@ -0,0 +1,320 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// TODO(kenton):  Use generics?  E.g. Builder<BuilderType extends Builder>, then
+//   mergeFrom*() could return BuilderType for better type-safety.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Abstract interface implemented by Protocol Message objects.
+ *
+ * <p>This interface is implemented by all protocol message objects.  Non-lite
+ * messages additionally implement the Message interface, which is a subclass
+ * of MessageLite.  Use MessageLite instead when you only need the subset of
+ * features which it supports -- namely, nothing that uses descriptors or
+ * reflection.  You can instruct the protocol compiler to generate classes
+ * which implement only MessageLite, not the full Message interface, by adding
+ * the follow line to the .proto file:
+ * <pre>
+ *   option optimize_for = LITE_RUNTIME;
+ * </pre>
+ *
+ * <p>This is particularly useful on resource-constrained systems where the
+ * full protocol buffers runtime library is too big.
+ *
+ * <p>Note that on non-constrained systems (e.g. servers) when you need to link
+ * in lots of protocol definitions, a better way to reduce total code footprint
+ * is to use {@code optimize_for = CODE_SIZE}.  This will make the generated
+ * code smaller while still supporting all the same features (at the expense of
+ * speed).  {@code optimize_for = LITE_RUNTIME} is best when you only have a
+ * small number of message types linked into your binary, in which case the
+ * size of the protocol buffers runtime itself is the biggest problem.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface MessageLite extends MessageLiteOrBuilder {
+
+
+  /**
+   * Serializes the message and writes it to {@code output}.  This does not
+   * flush or close the stream.
+   */
+  void writeTo(CodedOutputStream output) throws IOException;
+
+  /**
+   * Get the number of bytes required to encode this message.  The result
+   * is only computed on the first call and memoized after that.
+   */
+  int getSerializedSize();
+
+
+  /**
+   * Gets the parser for a message of the same type as this message.
+   */
+  Parser<? extends MessageLite> getParserForType();
+
+  // -----------------------------------------------------------------
+  // Convenience methods.
+
+  /**
+   * Serializes the message to a {@code ByteString} and returns it. This is
+   * just a trivial wrapper around
+   * {@link #writeTo(CodedOutputStream)}.
+   */
+  ByteString toByteString();
+
+  /**
+   * Serializes the message to a {@code byte} array and returns it.  This is
+   * just a trivial wrapper around
+   * {@link #writeTo(CodedOutputStream)}.
+   */
+  byte[] toByteArray();
+
+  /**
+   * Serializes the message and writes it to {@code output}.  This is just a
+   * trivial wrapper around {@link #writeTo(CodedOutputStream)}.  This does
+   * not flush or close the stream.
+   * <p>
+   * NOTE:  Protocol Buffers are not self-delimiting.  Therefore, if you write
+   * any more data to the stream after the message, you must somehow ensure
+   * that the parser on the receiving end does not interpret this as being
+   * part of the protocol message.  This can be done e.g. by writing the size
+   * of the message before the data, then making sure to limit the input to
+   * that size on the receiving end (e.g. by wrapping the InputStream in one
+   * which limits the input).  Alternatively, just use
+   * {@link #writeDelimitedTo(OutputStream)}.
+   */
+  void writeTo(OutputStream output) throws IOException;
+
+  /**
+   * Like {@link #writeTo(OutputStream)}, but writes the size of the message
+   * as a varint before writing the data.  This allows more data to be written
+   * to the stream after the message without the need to delimit the message
+   * data yourself.  Use {@link Builder#mergeDelimitedFrom(InputStream)} (or
+   * the static method {@code YourMessageType.parseDelimitedFrom(InputStream)})
+   * to parse messages written by this method.
+   */
+  void writeDelimitedTo(OutputStream output) throws IOException;
+
+
+  // =================================================================
+  // Builders
+
+  /**
+   * Constructs a new builder for a message of the same type as this message.
+   */
+  Builder newBuilderForType();
+
+  /**
+   * Constructs a builder initialized with the current message.  Use this to
+   * derive a new message from the current one.
+   */
+  Builder toBuilder();
+
+  /**
+   * Abstract interface implemented by Protocol Message builders.
+   */
+  interface Builder extends MessageLiteOrBuilder, Cloneable {
+    /** Resets all fields to their default values. */
+    Builder clear();
+
+    /**
+     * Constructs the message based on the state of the Builder. Subsequent
+     * changes to the Builder will not affect the returned message.
+     * @throws UninitializedMessageException The message is missing one or more
+     *         required fields (i.e. {@link #isInitialized()} returns false).
+     *         Use {@link #buildPartial()} to bypass this check.
+     */
+    MessageLite build();
+
+    /**
+     * Like {@link #build()}, but does not throw an exception if the message
+     * is missing required fields.  Instead, a partial message is returned.
+     * Subsequent changes to the Builder will not affect the returned message.
+     */
+    MessageLite buildPartial();
+
+    /**
+     * Clones the Builder.
+     * @see Object#clone()
+     */
+    Builder clone();
+
+    /**
+     * Parses a message of this type from the input and merges it with this
+     * message.
+     *
+     * <p>Warning:  This does not verify that all required fields are present in
+     * the input message.  If you call {@link #build()} without setting all
+     * required fields, it will throw an {@link UninitializedMessageException},
+     * which is a {@code RuntimeException} and thus might not be caught.  There
+     * are a few good ways to deal with this:
+     * <ul>
+     *   <li>Call {@link #isInitialized()} to verify that all required fields
+     *       are set before building.
+     *   <li>Use {@code buildPartial()} to build, which ignores missing
+     *       required fields.
+     * </ul>
+     *
+     * <p>Note:  The caller should call
+     * {@link CodedInputStream#checkLastTagWas(int)} after calling this to
+     * verify that the last tag seen was the appropriate end-group tag,
+     * or zero for EOF.
+     */
+    Builder mergeFrom(CodedInputStream input) throws IOException;
+
+    /**
+     * Like {@link Builder#mergeFrom(CodedInputStream)}, but also
+     * parses extensions.  The extensions that you want to be able to parse
+     * must be registered in {@code extensionRegistry}.  Extensions not in
+     * the registry will be treated as unknown fields.
+     */
+    Builder mergeFrom(CodedInputStream input,
+                      ExtensionRegistryLite extensionRegistry)
+                      throws IOException;
+
+    // ---------------------------------------------------------------
+    // Convenience methods.
+
+    /**
+     * Parse {@code data} as a message of this type and merge it with the
+     * message being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream)}.
+     *
+     * @return this
+     */
+    Builder mergeFrom(ByteString data) throws InvalidProtocolBufferException;
+
+    /**
+     * Parse {@code data} as a message of this type and merge it with the
+     * message being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
+     *
+     * @return this
+     */
+    Builder mergeFrom(ByteString data,
+                      ExtensionRegistryLite extensionRegistry)
+                      throws InvalidProtocolBufferException;
+
+    /**
+     * Parse {@code data} as a message of this type and merge it with the
+     * message being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream)}.
+     *
+     * @return this
+     */
+    Builder mergeFrom(byte[] data) throws InvalidProtocolBufferException;
+
+    /**
+     * Parse {@code data} as a message of this type and merge it with the
+     * message being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream)}.
+     *
+     * @return this
+     */
+    Builder mergeFrom(byte[] data, int off, int len)
+                      throws InvalidProtocolBufferException;
+
+    /**
+     * Parse {@code data} as a message of this type and merge it with the
+     * message being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
+     *
+     * @return this
+     */
+    Builder mergeFrom(byte[] data,
+                      ExtensionRegistryLite extensionRegistry)
+                      throws InvalidProtocolBufferException;
+
+    /**
+     * Parse {@code data} as a message of this type and merge it with the
+     * message being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
+     *
+     * @return this
+     */
+    Builder mergeFrom(byte[] data, int off, int len,
+                      ExtensionRegistryLite extensionRegistry)
+                      throws InvalidProtocolBufferException;
+
+    /**
+     * Parse a message of this type from {@code input} and merge it with the
+     * message being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream)}.  Note that this method always
+     * reads the <i>entire</i> input (unless it throws an exception).  If you
+     * want it to stop earlier, you will need to wrap your input in some
+     * wrapper stream that limits reading.  Or, use
+     * {@link MessageLite#writeDelimitedTo(OutputStream)} to write your message
+     * and {@link #mergeDelimitedFrom(InputStream)} to read it.
+     * <p>
+     * Despite usually reading the entire input, this does not close the stream.
+     *
+     * @return this
+     */
+    Builder mergeFrom(InputStream input) throws IOException;
+
+    /**
+     * Parse a message of this type from {@code input} and merge it with the
+     * message being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream,ExtensionRegistryLite)}.
+     *
+     * @return this
+     */
+    Builder mergeFrom(InputStream input,
+                      ExtensionRegistryLite extensionRegistry)
+                      throws IOException;
+
+    /**
+     * Like {@link #mergeFrom(InputStream)}, but does not read until EOF.
+     * Instead, the size of the message (encoded as a varint) is read first,
+     * then the message data.  Use
+     * {@link MessageLite#writeDelimitedTo(OutputStream)} to write messages in
+     * this format.
+     *
+     * @return True if successful, or false if the stream is at EOF when the
+     *         method starts.  Any other error (including reaching EOF during
+     *         parsing) will cause an exception to be thrown.
+     */
+    boolean mergeDelimitedFrom(InputStream input)
+                               throws IOException;
+
+    /**
+     * Like {@link #mergeDelimitedFrom(InputStream)} but supporting extensions.
+     */
+    boolean mergeDelimitedFrom(InputStream input,
+                               ExtensionRegistryLite extensionRegistry)
+                               throws IOException;
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java b/protobuf/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java
new file mode 100644
index 0000000..818386c
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java
@@ -0,0 +1,60 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Base interface for methods common to {@link MessageLite}
+ * and {@link MessageLite.Builder} to provide type equivalency.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public interface MessageLiteOrBuilder {
+  /**
+   * Get an instance of the type with no fields set. Because no fields are set,
+   * all getters for singular fields will return default values and repeated
+   * fields will appear empty.
+   * This may or may not be a singleton.  This differs from the
+   * {@code getDefaultInstance()} method of generated message classes in that
+   * this method is an abstract method of the {@code MessageLite} interface
+   * whereas {@code getDefaultInstance()} is a static method of a specific
+   * class.  They return the same thing.
+   */
+  MessageLite getDefaultInstanceForType();
+
+  /**
+   * Returns true if all required fields in the message and all embedded
+   * messages are set, false otherwise.
+   *
+   * <p>See also: {@link MessageOrBuilder#getInitializationErrorString()}
+   */
+  boolean isInitialized();
+
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/MessageOrBuilder.java b/protobuf/java/src/main/java/com/google/protobuf/MessageOrBuilder.java
new file mode 100644
index 0000000..f0fc485
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/MessageOrBuilder.java
@@ -0,0 +1,143 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base interface for methods common to {@link Message} and
+ * {@link Message.Builder} to provide type equivalency.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public interface MessageOrBuilder extends MessageLiteOrBuilder {
+
+  // (From MessageLite, re-declared here only for return type covariance.)
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  Message getDefaultInstanceForType();
+
+  /**
+   * Returns a list of field paths (e.g. "foo.bar.baz") of required fields
+   * which are not set in this message.  You should call
+   * {@link MessageLiteOrBuilder#isInitialized()} first to check if there
+   * are any missing fields, as that method is likely to be much faster
+   * than this one even when the message is fully-initialized.
+   */
+  List<String> findInitializationErrors();
+
+  /**
+   * Returns a comma-delimited list of required fields which are not set
+   * in this message object.  You should call
+   * {@link MessageLiteOrBuilder#isInitialized()} first to check if there
+   * are any missing fields, as that method is likely to be much faster
+   * than this one even when the message is fully-initialized.
+   */
+  String getInitializationErrorString();
+
+  /**
+   * Get the message's type's descriptor.  This differs from the
+   * {@code getDescriptor()} method of generated message classes in that
+   * this method is an abstract method of the {@code Message} interface
+   * whereas {@code getDescriptor()} is a static method of a specific class.
+   * They return the same thing.
+   */
+  Descriptors.Descriptor getDescriptorForType();
+
+  /**
+   * Returns a collection of all the fields in this message which are set
+   * and their corresponding values.  A singular ("required" or "optional")
+   * field is set iff hasField() returns true for that field.  A "repeated"
+   * field is set iff getRepeatedFieldCount() is greater than zero.  The
+   * values are exactly what would be returned by calling
+   * {@link #getField(Descriptors.FieldDescriptor)} for each field.  The map
+   * is guaranteed to be a sorted map, so iterating over it will return fields
+   * in order by field number.
+   * <br>
+   * If this is for a builder, the returned map may or may not reflect future
+   * changes to the builder.  Either way, the returned map is itself
+   * unmodifiable.
+   */
+  Map<Descriptors.FieldDescriptor, Object> getAllFields();
+
+  /**
+   * Returns true if the given oneof is set.
+   * @throws IllegalArgumentException if
+   *           {@code oneof.getContainingType() != getDescriptorForType()}.
+   */
+  boolean hasOneof(Descriptors.OneofDescriptor oneof);
+
+  /**
+   * Obtains the FieldDescriptor if the given oneof is set. Returns null
+   * if no field is set.
+   */
+  Descriptors.FieldDescriptor getOneofFieldDescriptor(
+      Descriptors.OneofDescriptor oneof);
+
+  /**
+   * Returns true if the given field is set.  This is exactly equivalent to
+   * calling the generated "has" accessor method corresponding to the field.
+   * @throws IllegalArgumentException The field is a repeated field, or
+   *           {@code field.getContainingType() != getDescriptorForType()}.
+   */
+  boolean hasField(Descriptors.FieldDescriptor field);
+
+  /**
+   * Obtains the value of the given field, or the default value if it is
+   * not set.  For primitive fields, the boxed primitive value is returned.
+   * For enum fields, the EnumValueDescriptor for the value is returned. For
+   * embedded message fields, the sub-message is returned.  For repeated
+   * fields, a java.util.List is returned.
+   */
+  Object getField(Descriptors.FieldDescriptor field);
+
+  /**
+   * Gets the number of elements of a repeated field.  This is exactly
+   * equivalent to calling the generated "Count" accessor method corresponding
+   * to the field.
+   * @throws IllegalArgumentException The field is not a repeated field, or
+   *           {@code field.getContainingType() != getDescriptorForType()}.
+   */
+  int getRepeatedFieldCount(Descriptors.FieldDescriptor field);
+
+  /**
+   * Gets an element of a repeated field.  For primitive fields, the boxed
+   * primitive value is returned.  For enum fields, the EnumValueDescriptor
+   * for the value is returned. For embedded message fields, the sub-message
+   * is returned.
+   * @throws IllegalArgumentException The field is not a repeated field, or
+   *           {@code field.getContainingType() != getDescriptorForType()}.
+   */
+  Object getRepeatedField(Descriptors.FieldDescriptor field, int index);
+
+  /** Get the {@link UnknownFieldSet} for this message. */
+  UnknownFieldSet getUnknownFields();
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/MessageReflection.java b/protobuf/java/src/main/java/com/google/protobuf/MessageReflection.java
new file mode 100644
index 0000000..edb5b5c
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/MessageReflection.java
@@ -0,0 +1,931 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.FieldDescriptor;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Reflection utility methods shared by both mutable and immutable messages.
+ *
+ * @author liujisi@google.com (Pherl Liu)
+ */
+class MessageReflection {
+
+  static void writeMessageTo(Message message, CodedOutputStream output,
+      boolean alwaysWriteRequiredFields)
+      throws IOException {
+    final boolean isMessageSet =
+        message.getDescriptorForType().getOptions().getMessageSetWireFormat();
+
+    Map<FieldDescriptor, Object> fields = message.getAllFields();
+    if (alwaysWriteRequiredFields) {
+      fields = new TreeMap<FieldDescriptor, Object>(fields);
+      for (final FieldDescriptor field :
+          message.getDescriptorForType().getFields()) {
+        if (field.isRequired() && !fields.containsKey(field)) {
+          fields.put(field, message.getField(field));
+        }
+      }
+    }
+    for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
+        fields.entrySet()) {
+      final Descriptors.FieldDescriptor field = entry.getKey();
+      final Object value = entry.getValue();
+      if (isMessageSet && field.isExtension() &&
+          field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE &&
+          !field.isRepeated()) {
+        output.writeMessageSetExtension(field.getNumber(), (Message) value);
+      } else {
+        FieldSet.writeField(field, value, output);
+      }
+    }
+
+    final UnknownFieldSet unknownFields = message.getUnknownFields();
+    if (isMessageSet) {
+      unknownFields.writeAsMessageSetTo(output);
+    } else {
+      unknownFields.writeTo(output);
+    }
+  }
+
+  static int getSerializedSize(Message message) {
+    int size = 0;
+    final boolean isMessageSet =
+        message.getDescriptorForType().getOptions().getMessageSetWireFormat();
+
+    for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
+        message.getAllFields().entrySet()) {
+      final Descriptors.FieldDescriptor field = entry.getKey();
+      final Object value = entry.getValue();
+      if (isMessageSet && field.isExtension() &&
+          field.getType() == Descriptors.FieldDescriptor.Type.MESSAGE &&
+          !field.isRepeated()) {
+        size += CodedOutputStream.computeMessageSetExtensionSize(
+            field.getNumber(), (Message) value);
+      } else {
+        size += FieldSet.computeFieldSize(field, value);
+      }
+    }
+
+    final UnknownFieldSet unknownFields = message.getUnknownFields();
+    if (isMessageSet) {
+      size += unknownFields.getSerializedSizeAsMessageSet();
+    } else {
+      size += unknownFields.getSerializedSize();
+    }
+    return size;
+  }
+
+  static String delimitWithCommas(List<String> parts) {
+    StringBuilder result = new StringBuilder();
+    for (String part : parts) {
+      if (result.length() > 0) {
+        result.append(", ");
+      }
+      result.append(part);
+    }
+    return result.toString();
+  }
+
+  @SuppressWarnings("unchecked")
+  static boolean isInitialized(MessageOrBuilder message) {
+    // Check that all required fields are present.
+    for (final Descriptors.FieldDescriptor field : message
+        .getDescriptorForType()
+        .getFields()) {
+      if (field.isRequired()) {
+        if (!message.hasField(field)) {
+          return false;
+        }
+      }
+    }
+
+    // Check that embedded messages are initialized.
+    for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
+        message.getAllFields().entrySet()) {
+      final Descriptors.FieldDescriptor field = entry.getKey();
+      if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
+        if (field.isRepeated()) {
+          for (final Message element
+              : (List<Message>) entry.getValue()) {
+            if (!element.isInitialized()) {
+              return false;
+            }
+          }
+        } else {
+          if (!((Message) entry.getValue()).isInitialized()) {
+            return false;
+          }
+        }
+      }
+    }
+
+    return true;
+  }
+
+  private static String subMessagePrefix(final String prefix,
+      final Descriptors.FieldDescriptor field,
+      final int index) {
+    final StringBuilder result = new StringBuilder(prefix);
+    if (field.isExtension()) {
+      result.append('(')
+          .append(field.getFullName())
+          .append(')');
+    } else {
+      result.append(field.getName());
+    }
+    if (index != -1) {
+      result.append('[')
+          .append(index)
+          .append(']');
+    }
+    result.append('.');
+    return result.toString();
+  }
+
+  private static void findMissingFields(final MessageOrBuilder message,
+      final String prefix,
+      final List<String> results) {
+    for (final Descriptors.FieldDescriptor field :
+        message.getDescriptorForType().getFields()) {
+      if (field.isRequired() && !message.hasField(field)) {
+        results.add(prefix + field.getName());
+      }
+    }
+
+    for (final Map.Entry<Descriptors.FieldDescriptor, Object> entry :
+        message.getAllFields().entrySet()) {
+      final Descriptors.FieldDescriptor field = entry.getKey();
+      final Object value = entry.getValue();
+
+      if (field.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
+        if (field.isRepeated()) {
+          int i = 0;
+          for (final Object element : (List) value) {
+            findMissingFields((MessageOrBuilder) element,
+                subMessagePrefix(prefix, field, i++),
+                results);
+          }
+        } else {
+          if (message.hasField(field)) {
+            findMissingFields((MessageOrBuilder) value,
+                subMessagePrefix(prefix, field, -1),
+                results);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Populates {@code this.missingFields} with the full "path" of each missing
+   * required field in the given message.
+   */
+  static List<String> findMissingFields(
+      final MessageOrBuilder message) {
+    final List<String> results = new ArrayList<String>();
+    findMissingFields(message, "", results);
+    return results;
+  }
+
+  static interface MergeTarget {
+    enum ContainerType {
+      MESSAGE, EXTENSION_SET
+    }
+
+    /**
+     * Returns the descriptor for the target.
+     */
+    public Descriptors.Descriptor getDescriptorForType();
+
+    public ContainerType getContainerType();
+
+    public ExtensionRegistry.ExtensionInfo findExtensionByName(
+        ExtensionRegistry registry, String name);
+
+    public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
+        ExtensionRegistry registry, Descriptors.Descriptor containingType,
+        int fieldNumber);
+
+    /**
+     * Obtains the value of the given field, or the default value if it is not
+     * set.  For primitive fields, the boxed primitive value is returned. For
+     * enum fields, the EnumValueDescriptor for the value is returned. For
+     * embedded message fields, the sub-message is returned.  For repeated
+     * fields, a java.util.List is returned.
+     */
+    public Object getField(Descriptors.FieldDescriptor field);
+
+    /**
+     * Returns true if the given field is set.  This is exactly equivalent to
+     * calling the generated "has" accessor method corresponding to the field.
+     *
+     * @throws IllegalArgumentException The field is a repeated field, or {@code
+     *     field.getContainingType() != getDescriptorForType()}.
+     */
+    boolean hasField(Descriptors.FieldDescriptor field);
+
+    /**
+     * Sets a field to the given value.  The value must be of the correct type
+     * for this field, i.e. the same type that
+     * {@link Message#getField(Descriptors.FieldDescriptor)}
+     * would return.
+     */
+    MergeTarget setField(Descriptors.FieldDescriptor field, Object value);
+
+    /**
+     * Clears the field.  This is exactly equivalent to calling the generated
+     * "clear" accessor method corresponding to the field.
+     */
+    MergeTarget clearField(Descriptors.FieldDescriptor field);
+
+    /**
+     * Sets an element of a repeated field to the given value.  The value must
+     * be of the correct type for this field, i.e. the same type that {@link
+     * Message#getRepeatedField(Descriptors.FieldDescriptor, int)} would return.
+     *
+     * @throws IllegalArgumentException The field is not a repeated field, or
+     *                                  {@code field.getContainingType() !=
+     *                                  getDescriptorForType()}.
+     */
+    MergeTarget setRepeatedField(Descriptors.FieldDescriptor field,
+        int index, Object value);
+
+    /**
+     * Like {@code setRepeatedField}, but appends the value as a new element.
+     *
+     * @throws IllegalArgumentException The field is not a repeated field, or
+     *                                  {@code field.getContainingType() !=
+     *                                  getDescriptorForType()}.
+     */
+    MergeTarget addRepeatedField(Descriptors.FieldDescriptor field,
+        Object value);
+
+    /**
+     * Returns true if the given oneof is set.
+     *
+     * @throws IllegalArgumentException if
+     *           {@code oneof.getContainingType() != getDescriptorForType()}.
+     */
+    boolean hasOneof(Descriptors.OneofDescriptor oneof);
+
+    /**
+     * Clears the oneof.  This is exactly equivalent to calling the generated
+     * "clear" accessor method corresponding to the oneof.
+     */
+    MergeTarget clearOneof(Descriptors.OneofDescriptor oneof);
+
+    /**
+     * Obtains the FieldDescriptor if the given oneof is set. Returns null
+     * if no field is set.
+     */
+    Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof);
+
+    /**
+     * Parse the input stream into a sub field group defined based on either
+     * FieldDescriptor or the default instance.
+     */
+    Object parseGroup(CodedInputStream input, ExtensionRegistryLite registry,
+        Descriptors.FieldDescriptor descriptor, Message defaultInstance)
+        throws IOException;
+
+    /**
+     * Parse the input stream into a sub field message defined based on either
+     * FieldDescriptor or the default instance.
+     */
+    Object parseMessage(CodedInputStream input, ExtensionRegistryLite registry,
+        Descriptors.FieldDescriptor descriptor, Message defaultInstance)
+        throws IOException;
+
+    /**
+     * Parse from a ByteString into a sub field message defined based on either
+     * FieldDescriptor or the default instance.  There isn't a varint indicating
+     * the length of the message at the beginning of the input ByteString.
+     */
+    Object parseMessageFromBytes(
+        ByteString bytes, ExtensionRegistryLite registry,
+        Descriptors.FieldDescriptor descriptor, Message defaultInstance)
+        throws IOException;
+    
+    /**
+     * Read a primitive field from input. Note that builders and mutable
+     * messages may use different Java types to represent a primtive field.
+     */
+    Object readPrimitiveField(
+        CodedInputStream input, WireFormat.FieldType type,
+        boolean checkUtf8) throws IOException;
+
+    /**
+     * Returns a new merge target for a sub-field. When defaultInstance is
+     * provided, it indicates the descriptor is for an extension type, and
+     * implementations should create a new instance from the defaultInstance
+     * prototype directly.
+     */
+    MergeTarget newMergeTargetForField(
+        Descriptors.FieldDescriptor descriptor,
+        Message defaultInstance);
+
+    /**
+     * Finishes the merge and returns the underlying object.
+     */
+    Object finish();
+  }
+
+  static class BuilderAdapter implements MergeTarget {
+
+    private final Message.Builder builder;
+
+    public Descriptors.Descriptor getDescriptorForType() {
+      return builder.getDescriptorForType();
+    }
+
+    public BuilderAdapter(Message.Builder builder) {
+      this.builder = builder;
+    }
+
+    public Object getField(Descriptors.FieldDescriptor field) {
+      return builder.getField(field);
+    }
+
+    @Override
+    public boolean hasField(Descriptors.FieldDescriptor field) {
+      return builder.hasField(field);
+    }
+
+    public MergeTarget setField(Descriptors.FieldDescriptor field,
+        Object value) {
+      builder.setField(field, value);
+      return this;
+    }
+
+    public MergeTarget clearField(Descriptors.FieldDescriptor field) {
+      builder.clearField(field);
+      return this;
+    }
+
+    public MergeTarget setRepeatedField(
+        Descriptors.FieldDescriptor field, int index, Object value) {
+      builder.setRepeatedField(field, index, value);
+      return this;
+    }
+
+    public MergeTarget addRepeatedField(
+        Descriptors.FieldDescriptor field, Object value) {
+      builder.addRepeatedField(field, value);
+      return this;
+    }
+
+    @Override
+    public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
+      return builder.hasOneof(oneof);
+    }
+
+    @Override
+    public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
+      builder.clearOneof(oneof);
+      return this;
+    }
+
+    @Override
+    public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
+      return builder.getOneofFieldDescriptor(oneof);
+    }
+
+    public ContainerType getContainerType() {
+      return ContainerType.MESSAGE;
+    }
+
+    public ExtensionRegistry.ExtensionInfo findExtensionByName(
+        ExtensionRegistry registry, String name) {
+      return registry.findImmutableExtensionByName(name);
+    }
+
+    public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
+        ExtensionRegistry registry, Descriptors.Descriptor containingType,
+        int fieldNumber) {
+      return registry.findImmutableExtensionByNumber(containingType,
+          fieldNumber);
+    }
+
+    public Object parseGroup(CodedInputStream input,
+        ExtensionRegistryLite extensionRegistry,
+        Descriptors.FieldDescriptor field, Message defaultInstance)
+        throws IOException {
+      Message.Builder subBuilder;
+      // When default instance is not null. The field is an extension field.
+      if (defaultInstance != null) {
+        subBuilder = defaultInstance.newBuilderForType();
+      } else {
+        subBuilder = builder.newBuilderForField(field);
+      }
+      if (!field.isRepeated()) {
+        Message originalMessage = (Message) getField(field);
+        if (originalMessage != null) {
+          subBuilder.mergeFrom(originalMessage);
+        }
+      }
+      input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
+      return subBuilder.buildPartial();
+    }
+
+    public Object parseMessage(CodedInputStream input,
+        ExtensionRegistryLite extensionRegistry,
+        Descriptors.FieldDescriptor field, Message defaultInstance)
+        throws IOException {
+      Message.Builder subBuilder;
+      // When default instance is not null. The field is an extension field.
+      if (defaultInstance != null) {
+        subBuilder = defaultInstance.newBuilderForType();
+      } else {
+        subBuilder = builder.newBuilderForField(field);
+      }
+      if (!field.isRepeated()) {
+        Message originalMessage = (Message) getField(field);
+        if (originalMessage != null) {
+          subBuilder.mergeFrom(originalMessage);
+        }
+      }
+      input.readMessage(subBuilder, extensionRegistry);
+      return subBuilder.buildPartial();
+    }
+
+    public Object parseMessageFromBytes(ByteString bytes,
+        ExtensionRegistryLite extensionRegistry,
+        Descriptors.FieldDescriptor field, Message defaultInstance)
+        throws IOException {
+      Message.Builder subBuilder;
+      // When default instance is not null. The field is an extension field.
+      if (defaultInstance != null) {
+        subBuilder = defaultInstance.newBuilderForType();
+      } else {
+        subBuilder = builder.newBuilderForField(field);
+      }
+      if (!field.isRepeated()) {
+        Message originalMessage = (Message) getField(field);
+        if (originalMessage != null) {
+          subBuilder.mergeFrom(originalMessage);
+        }
+      }
+      subBuilder.mergeFrom(bytes, extensionRegistry);
+      return subBuilder.buildPartial();
+    }
+
+    public MergeTarget newMergeTargetForField(Descriptors.FieldDescriptor field,
+        Message defaultInstance) {
+      if (defaultInstance != null) {
+        return new BuilderAdapter(
+            defaultInstance.newBuilderForType());
+      } else {
+        return new BuilderAdapter(builder.newBuilderForField(field));
+      }
+    }
+    
+    public Object readPrimitiveField(
+        CodedInputStream input, WireFormat.FieldType type,
+        boolean checkUtf8) throws IOException {
+      return FieldSet.readPrimitiveField(input, type, checkUtf8);
+    }
+
+    public Object finish() {
+      return builder.buildPartial();
+    }
+  }
+
+
+  static class ExtensionAdapter implements MergeTarget {
+
+    private final FieldSet<Descriptors.FieldDescriptor> extensions;
+
+    ExtensionAdapter(FieldSet<Descriptors.FieldDescriptor> extensions) {
+      this.extensions = extensions;
+    }
+
+    public Descriptors.Descriptor getDescriptorForType() {
+      throw new UnsupportedOperationException(
+          "getDescriptorForType() called on FieldSet object");
+    }
+
+    public Object getField(Descriptors.FieldDescriptor field) {
+      return extensions.getField(field);
+    }
+
+    public boolean hasField(Descriptors.FieldDescriptor field) {
+      return extensions.hasField(field);
+    }
+
+    public MergeTarget setField(Descriptors.FieldDescriptor field,
+        Object value) {
+      extensions.setField(field, value);
+      return this;
+    }
+
+    public MergeTarget clearField(Descriptors.FieldDescriptor field) {
+      extensions.clearField(field);
+      return this;
+    }
+
+    public MergeTarget setRepeatedField(
+        Descriptors.FieldDescriptor field, int index, Object value) {
+      extensions.setRepeatedField(field, index, value);
+      return this;
+    }
+
+    public MergeTarget addRepeatedField(
+        Descriptors.FieldDescriptor field, Object value) {
+      extensions.addRepeatedField(field, value);
+      return this;
+    }
+
+    @Override
+    public boolean hasOneof(Descriptors.OneofDescriptor oneof) {
+      return false;
+    }
+
+    @Override
+    public MergeTarget clearOneof(Descriptors.OneofDescriptor oneof) {
+      // Nothing to clear.
+      return this;
+    }
+
+    @Override
+    public Descriptors.FieldDescriptor getOneofFieldDescriptor(Descriptors.OneofDescriptor oneof) {
+      return null;
+    }
+
+    public ContainerType getContainerType() {
+      return ContainerType.EXTENSION_SET;
+    }
+
+    public ExtensionRegistry.ExtensionInfo findExtensionByName(
+        ExtensionRegistry registry, String name) {
+      return registry.findImmutableExtensionByName(name);
+    }
+
+    public ExtensionRegistry.ExtensionInfo findExtensionByNumber(
+        ExtensionRegistry registry, Descriptors.Descriptor containingType,
+        int fieldNumber) {
+      return registry.findImmutableExtensionByNumber(containingType,
+          fieldNumber);
+    }
+
+    public Object parseGroup(CodedInputStream input,
+        ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
+        Message defaultInstance) throws IOException {
+      Message.Builder subBuilder =
+          defaultInstance.newBuilderForType();
+      if (!field.isRepeated()) {
+        Message originalMessage = (Message) getField(field);
+        if (originalMessage != null) {
+          subBuilder.mergeFrom(originalMessage);
+        }
+      }
+      input.readGroup(field.getNumber(), subBuilder, registry);
+      return subBuilder.buildPartial();
+    }
+
+    public Object parseMessage(CodedInputStream input,
+        ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
+        Message defaultInstance) throws IOException {
+      Message.Builder subBuilder =
+          defaultInstance.newBuilderForType();
+      if (!field.isRepeated()) {
+        Message originalMessage = (Message) getField(field);
+        if (originalMessage != null) {
+          subBuilder.mergeFrom(originalMessage);
+        }
+      }
+      input.readMessage(subBuilder, registry);
+      return subBuilder.buildPartial();
+    }
+
+    public Object parseMessageFromBytes(ByteString bytes,
+        ExtensionRegistryLite registry, Descriptors.FieldDescriptor field,
+        Message defaultInstance) throws IOException {
+      Message.Builder subBuilder =  defaultInstance.newBuilderForType();
+      if (!field.isRepeated()) {
+        Message originalMessage = (Message) getField(field);
+        if (originalMessage != null) {
+          subBuilder.mergeFrom(originalMessage);
+        }
+      }
+      subBuilder.mergeFrom(bytes, registry);
+      return subBuilder.buildPartial();
+    }
+
+    public MergeTarget newMergeTargetForField(
+        Descriptors.FieldDescriptor descriptor, Message defaultInstance) {
+      throw new UnsupportedOperationException(
+          "newMergeTargetForField() called on FieldSet object");
+    }
+    
+    public Object readPrimitiveField(
+        CodedInputStream input, WireFormat.FieldType type,
+        boolean checkUtf8) throws IOException {
+      return FieldSet.readPrimitiveField(input, type, checkUtf8);
+    }
+
+    public Object finish() {
+      throw new UnsupportedOperationException(
+          "finish() called on FieldSet object");
+    }
+  }
+
+  /**
+   * Parses a single field into MergeTarget. The target can be Message.Builder,
+   * FieldSet or MutableMessage.
+   *
+   * Package-private because it is used by GeneratedMessage.ExtendableMessage.
+   *
+   * @param tag The tag, which should have already been read.
+   * @return {@code true} unless the tag is an end-group tag.
+   */
+  static boolean mergeFieldFrom(
+      CodedInputStream input,
+      UnknownFieldSet.Builder unknownFields,
+      ExtensionRegistryLite extensionRegistry,
+      Descriptors.Descriptor type,
+      MergeTarget target,
+      int tag) throws IOException {
+    if (type.getOptions().getMessageSetWireFormat() &&
+        tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
+      mergeMessageSetExtensionFromCodedStream(
+          input, unknownFields, extensionRegistry, type, target);
+      return true;
+    }
+
+    final int wireType = WireFormat.getTagWireType(tag);
+    final int fieldNumber = WireFormat.getTagFieldNumber(tag);
+
+    final Descriptors.FieldDescriptor field;
+    Message defaultInstance = null;
+
+    if (type.isExtensionNumber(fieldNumber)) {
+      // extensionRegistry may be either ExtensionRegistry or
+      // ExtensionRegistryLite.  Since the type we are parsing is a full
+      // message, only a full ExtensionRegistry could possibly contain
+      // extensions of it.  Otherwise we will treat the registry as if it
+      // were empty.
+      if (extensionRegistry instanceof ExtensionRegistry) {
+        final ExtensionRegistry.ExtensionInfo extension =
+            target.findExtensionByNumber((ExtensionRegistry) extensionRegistry,
+                type, fieldNumber);
+        if (extension == null) {
+          field = null;
+        } else {
+          field = extension.descriptor;
+          defaultInstance = extension.defaultInstance;
+          if (defaultInstance == null &&
+              field.getJavaType()
+                  == Descriptors.FieldDescriptor.JavaType.MESSAGE) {
+            throw new IllegalStateException(
+                "Message-typed extension lacked default instance: " +
+                    field.getFullName());
+          }
+        }
+      } else {
+        field = null;
+      }
+    } else if (target.getContainerType() == MergeTarget.ContainerType.MESSAGE) {
+      field = type.findFieldByNumber(fieldNumber);
+    } else {
+      field = null;
+    }
+
+    boolean unknown = false;
+    boolean packed = false;
+    if (field == null) {
+      unknown = true;  // Unknown field.
+    } else if (wireType == FieldSet.getWireFormatForFieldType(
+        field.getLiteType(),
+        false  /* isPacked */)) {
+      packed = false;
+    } else if (field.isPackable() &&
+        wireType == FieldSet.getWireFormatForFieldType(
+            field.getLiteType(),
+            true  /* isPacked */)) {
+      packed = true;
+    } else {
+      unknown = true;  // Unknown wire type.
+    }
+
+    if (unknown) {  // Unknown field or wrong wire type.  Skip.
+      return unknownFields.mergeFieldFrom(tag, input);
+    }
+
+    if (packed) {
+      final int length = input.readRawVarint32();
+      final int limit = input.pushLimit(length);
+      if (field.getLiteType() == WireFormat.FieldType.ENUM) {
+        while (input.getBytesUntilLimit() > 0) {
+          final int rawValue = input.readEnum();
+          final Object value = field.getEnumType().findValueByNumber(rawValue);
+          if (value == null) {
+            // If the number isn't recognized as a valid value for this
+            // enum, drop it (don't even add it to unknownFields).
+            return true;
+          }
+          target.addRepeatedField(field, value);
+        }
+      } else {
+        while (input.getBytesUntilLimit() > 0) {
+          final Object value =
+              target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check());
+          target.addRepeatedField(field, value);
+        }
+      }
+      input.popLimit(limit);
+    } else {
+      final Object value;
+      switch (field.getType()) {
+        case GROUP: {
+          value = target
+              .parseGroup(input, extensionRegistry, field, defaultInstance);
+          break;
+        }
+        case MESSAGE: {
+          value = target
+              .parseMessage(input, extensionRegistry, field, defaultInstance);
+          break;
+        }
+        case ENUM:
+          final int rawValue = input.readEnum();
+          value = field.getEnumType().findValueByNumber(rawValue);
+          // If the number isn't recognized as a valid value for this enum,
+          // drop it.
+          if (value == null) {
+            unknownFields.mergeVarintField(fieldNumber, rawValue);
+            return true;
+          }
+          break;
+        default:
+          value = target.readPrimitiveField(input, field.getLiteType(), field.needsUtf8Check());
+          break;
+      }
+
+      if (field.isRepeated()) {
+        target.addRepeatedField(field, value);
+      } else {
+        target.setField(field, value);
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * Called by {@code #mergeFieldFrom()} to parse a MessageSet extension into
+   * MergeTarget.
+   */
+  private static void mergeMessageSetExtensionFromCodedStream(
+      CodedInputStream input,
+      UnknownFieldSet.Builder unknownFields,
+      ExtensionRegistryLite extensionRegistry,
+      Descriptors.Descriptor type,
+      MergeTarget target) throws IOException {
+
+    // The wire format for MessageSet is:
+    //   message MessageSet {
+    //     repeated group Item = 1 {
+    //       required int32 typeId = 2;
+    //       required bytes message = 3;
+    //     }
+    //   }
+    // "typeId" is the extension's field number.  The extension can only be
+    // a message type, where "message" contains the encoded bytes of that
+    // message.
+    //
+    // In practice, we will probably never see a MessageSet item in which
+    // the message appears before the type ID, or where either field does not
+    // appear exactly once.  However, in theory such cases are valid, so we
+    // should be prepared to accept them.
+
+    int typeId = 0;
+    ByteString rawBytes = null; // If we encounter "message" before "typeId"
+    ExtensionRegistry.ExtensionInfo extension = null;
+
+    // Read bytes from input, if we get it's type first then parse it eagerly,
+    // otherwise we store the raw bytes in a local variable.
+    while (true) {
+      final int tag = input.readTag();
+      if (tag == 0) {
+        break;
+      }
+
+      if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
+        typeId = input.readUInt32();
+        if (typeId != 0) {
+          // extensionRegistry may be either ExtensionRegistry or
+          // ExtensionRegistryLite. Since the type we are parsing is a full
+          // message, only a full ExtensionRegistry could possibly contain
+          // extensions of it. Otherwise we will treat the registry as if it
+          // were empty.
+          if (extensionRegistry instanceof ExtensionRegistry) {
+            extension = target.findExtensionByNumber(
+                (ExtensionRegistry) extensionRegistry, type, typeId);
+          }
+        }
+
+      } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
+        if (typeId != 0) {
+          if (extension != null &&
+              ExtensionRegistryLite.isEagerlyParseMessageSets()) {
+            // We already know the type, so we can parse directly from the
+            // input with no copying.  Hooray!
+            eagerlyMergeMessageSetExtension(
+                input, extension, extensionRegistry, target);
+            rawBytes = null;
+            continue;
+          }
+        }
+        // We haven't seen a type ID yet or we want parse message lazily.
+        rawBytes = input.readBytes();
+
+      } else { // Unknown tag. Skip it.
+        if (!input.skipField(tag)) {
+          break; // End of group
+        }
+      }
+    }
+    input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);
+
+    // Process the raw bytes.
+    if (rawBytes != null && typeId != 0) { // Zero is not a valid type ID.
+      if (extension != null) { // We known the type
+        mergeMessageSetExtensionFromBytes(
+            rawBytes, extension, extensionRegistry, target);
+      } else { // We don't know how to parse this. Ignore it.
+        if (rawBytes != null) {
+          unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder()
+              .addLengthDelimited(rawBytes).build());
+        }
+      }
+    }
+  }
+
+  private static void mergeMessageSetExtensionFromBytes(
+      ByteString rawBytes,
+      ExtensionRegistry.ExtensionInfo extension,
+      ExtensionRegistryLite extensionRegistry,
+      MergeTarget target) throws IOException {
+
+    Descriptors.FieldDescriptor field = extension.descriptor;
+    boolean hasOriginalValue = target.hasField(field);
+
+    if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) {
+      // If the field already exists, we just parse the field.
+      Object value = target.parseMessageFromBytes(
+          rawBytes, extensionRegistry,field, extension.defaultInstance);
+      target.setField(field, value);
+    } else {
+      // Use LazyField to load MessageSet lazily.
+      LazyField lazyField = new LazyField(
+          extension.defaultInstance, extensionRegistry, rawBytes);
+      target.setField(field, lazyField);
+    }
+  }
+
+  private static void eagerlyMergeMessageSetExtension(
+      CodedInputStream input,
+      ExtensionRegistry.ExtensionInfo extension,
+      ExtensionRegistryLite extensionRegistry,
+      MergeTarget target) throws IOException {
+    Descriptors.FieldDescriptor field = extension.descriptor;
+    Object value = target.parseMessage(input, extensionRegistry, field,
+                                       extension.defaultInstance);
+    target.setField(field, value);
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/Parser.java b/protobuf/java/src/main/java/com/google/protobuf/Parser.java
new file mode 100644
index 0000000..f636014
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/Parser.java
@@ -0,0 +1,261 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.InputStream;
+
+/**
+ * Abstract interface for parsing Protocol Messages.
+ *
+ * The implementation should be stateless and thread-safe.
+ *
+ * @author liujisi@google.com (Pherl Liu)
+ */
+public interface Parser<MessageType> {
+  /**
+   * Parses a message of {@code MessageType} from the input.
+   *
+   * <p>Note:  The caller should call
+   * {@link CodedInputStream#checkLastTagWas(int)} after calling this to
+   * verify that the last tag seen was the appropriate end-group tag,
+   * or zero for EOF.
+   */
+  public MessageType parseFrom(CodedInputStream input)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(CodedInputStream)}, but also parses extensions.
+   * The extensions that you want to be able to parse must be registered in
+   * {@code extensionRegistry}. Extensions not in the registry will be treated
+   * as unknown fields.
+   */
+  public MessageType parseFrom(CodedInputStream input,
+                               ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(CodedInputStream)}, but does not throw an
+   * exception if the message is missing required fields. Instead, a partial
+   * message is returned.
+   */
+  public MessageType parsePartialFrom(CodedInputStream input)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(CodedInputStream input, ExtensionRegistryLite)},
+   * but does not throw an exception if the message is missing required fields.
+   * Instead, a partial message is returned.
+   */
+  public MessageType parsePartialFrom(CodedInputStream input,
+                                      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  // ---------------------------------------------------------------
+  // Convenience methods.
+
+  /**
+   * Parses {@code data} as a message of {@code MessageType}.
+   * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.
+   */
+  public MessageType parseFrom(ByteString data)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Parses {@code data} as a message of {@code MessageType}.
+   * This is just a small wrapper around
+   * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
+   */
+  public MessageType parseFrom(ByteString data,
+                               ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(ByteString)}, but does not throw an
+   * exception if the message is missing required fields. Instead, a partial
+   * message is returned.
+   */
+  public MessageType parsePartialFrom(ByteString data)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(ByteString, ExtensionRegistryLite)},
+   * but does not throw an exception if the message is missing required fields.
+   * Instead, a partial message is returned.
+   */
+  public MessageType parsePartialFrom(ByteString data,
+                                      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Parses {@code data} as a message of {@code MessageType}.
+   * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.
+   */
+  public MessageType parseFrom(byte[] data, int off, int len)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Parses {@code data} as a message of {@code MessageType}.
+   * This is just a small wrapper around
+   * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
+   */
+  public MessageType parseFrom(byte[] data, int off, int len,
+                               ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Parses {@code data} as a message of {@code MessageType}.
+   * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.
+   */
+  public MessageType parseFrom(byte[] data)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Parses {@code data} as a message of {@code MessageType}.
+   * This is just a small wrapper around
+   * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
+   */
+  public MessageType parseFrom(byte[] data,
+                               ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(byte[], int, int)}, but does not throw an
+   * exception if the message is missing required fields. Instead, a partial
+   * message is returned.
+   */
+  public MessageType parsePartialFrom(byte[] data, int off, int len)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(ByteString, ExtensionRegistryLite)},
+   * but does not throw an exception if the message is missing required fields.
+   * Instead, a partial message is returned.
+   */
+  public MessageType parsePartialFrom(byte[] data, int off, int len,
+                                      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(byte[])}, but does not throw an
+   * exception if the message is missing required fields. Instead, a partial
+   * message is returned.
+   */
+  public MessageType parsePartialFrom(byte[] data)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(byte[], ExtensionRegistryLite)},
+   * but does not throw an exception if the message is missing required fields.
+   * Instead, a partial message is returned.
+   */
+  public MessageType parsePartialFrom(byte[] data,
+                                      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Parse a message of {@code MessageType} from {@code input}.
+   * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}.
+   * Note that this method always reads the <i>entire</i> input (unless it
+   * throws an exception).  If you want it to stop earlier, you will need to
+   * wrap your input in some wrapper stream that limits reading.  Or, use
+   * {@link MessageLite#writeDelimitedTo(java.io.OutputStream)} to write your
+   * message and {@link #parseDelimitedFrom(InputStream)} to read it.
+   * <p>
+   * Despite usually reading the entire input, this does not close the stream.
+   */
+  public MessageType parseFrom(InputStream input)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Parses a message of {@code MessageType} from {@code input}.
+   * This is just a small wrapper around
+   * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}.
+   */
+  public MessageType parseFrom(InputStream input,
+                               ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(InputStream)}, but does not throw an
+   * exception if the message is missing required fields. Instead, a partial
+   * message is returned.
+   */
+  public MessageType parsePartialFrom(InputStream input)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(InputStream, ExtensionRegistryLite)},
+   * but does not throw an exception if the message is missing required fields.
+   * Instead, a partial message is returned.
+   */
+  public MessageType parsePartialFrom(InputStream input,
+                                      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseFrom(InputStream)}, but does not read util EOF.
+   * Instead, the size of message (encoded as a varint) is read first,
+   * then the message data. Use
+   * {@link MessageLite#writeDelimitedTo(java.io.OutputStream)} to write
+   * messages in this format.
+   *
+   * @return True if successful, or false if the stream is at EOF when the
+   *         method starts. Any other error (including reaching EOF during
+   *         parsing) will cause an exception to be thrown.
+   */
+  public MessageType parseDelimitedFrom(InputStream input)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseDelimitedFrom(InputStream)} but supporting extensions.
+   */
+  public MessageType parseDelimitedFrom(InputStream input,
+                                        ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseDelimitedFrom(InputStream)}, but does not throw an
+   * exception if the message is missing required fields. Instead, a partial
+   * message is returned.
+   */
+  public MessageType parsePartialDelimitedFrom(InputStream input)
+      throws InvalidProtocolBufferException;
+
+  /**
+   * Like {@link #parseDelimitedFrom(InputStream, ExtensionRegistryLite)},
+   * but does not throw an exception if the message is missing required fields.
+   * Instead, a partial message is returned.
+   */
+  public MessageType parsePartialDelimitedFrom(
+      InputStream input,
+      ExtensionRegistryLite extensionRegistry)
+      throws InvalidProtocolBufferException;
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java b/protobuf/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
new file mode 100644
index 0000000..0c8df98
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/ProtocolMessageEnum.java
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+
+/**
+ * Interface of useful methods added to all enums generated by the protocol
+ * compiler.
+ */
+public interface ProtocolMessageEnum extends Internal.EnumLite {
+
+  /**
+   * Return the value's numeric value as defined in the .proto file.
+   */
+  int getNumber();
+
+  /**
+   * Return the value's descriptor, which contains information such as
+   * value name, number, and type.
+   */
+  EnumValueDescriptor getValueDescriptor();
+
+  /**
+   * Return the enum type's descriptor, which contains information
+   * about each defined value, etc.
+   */
+  EnumDescriptor getDescriptorForType();
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/ProtocolStringList.java b/protobuf/java/src/main/java/com/google/protobuf/ProtocolStringList.java
new file mode 100644
index 0000000..d553b41
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/ProtocolStringList.java
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.List;
+
+/**
+ * An interface extending {@code List<String>} used for repeated string fields
+ * to provide optional access to the data as a list of ByteStrings. The
+ * underlying implementation stores values as either ByteStrings or Strings
+ * (see {@link LazyStringArrayList}) depending on how the value was initialized
+ * or last read, and it is often more efficient to deal with lists of
+ * ByteStrings when handling protos that have been deserialized from bytes.
+ */
+public interface ProtocolStringList extends List<String> {
+
+  /** Returns a view of the data as a list of ByteStrings. */
+  List<ByteString> asByteStringList();
+
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java b/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
new file mode 100644
index 0000000..22760d3
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java
@@ -0,0 +1,696 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * {@code RepeatedFieldBuilder} implements a structure that a protocol
+ * message uses to hold a repeated field of other protocol messages. It supports
+ * the classical use case of adding immutable {@link Message}'s to the
+ * repeated field and is highly optimized around this (no extra memory
+ * allocations and sharing of immutable arrays).
+ * <br>
+ * It also supports the additional use case of adding a {@link Message.Builder}
+ * to the repeated field and deferring conversion of that {@code Builder}
+ * to an immutable {@code Message}. In this way, it's possible to maintain
+ * a tree of {@code Builder}'s that acts as a fully read/write data
+ * structure.
+ * <br>
+ * Logically, one can think of a tree of builders as converting the entire tree
+ * to messages when build is called on the root or when any method is called
+ * that desires a Message instead of a Builder. In terms of the implementation,
+ * the {@code SingleFieldBuilder} and {@code RepeatedFieldBuilder}
+ * classes cache messages that were created so that messages only need to be
+ * created when some change occured in its builder or a builder for one of its
+ * descendants.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class RepeatedFieldBuilder
+    <MType extends GeneratedMessage,
+     BType extends GeneratedMessage.Builder,
+     IType extends MessageOrBuilder>
+    implements GeneratedMessage.BuilderParent {
+
+  // Parent to send changes to.
+  private GeneratedMessage.BuilderParent parent;
+
+  // List of messages. Never null. It may be immutable, in which case
+  // isMessagesListImmutable will be true. See note below.
+  private List<MType> messages;
+
+  // Whether messages is an mutable array that can be modified.
+  private boolean isMessagesListMutable;
+
+  // List of builders. May be null, in which case, no nested builders were
+  // created. If not null, entries represent the builder for that index.
+  private List<SingleFieldBuilder<MType, BType, IType>> builders;
+
+  // Here are the invariants for messages and builders:
+  // 1. messages is never null and its count corresponds to the number of items
+  //    in the repeated field.
+  // 2. If builders is non-null, messages and builders MUST always
+  //    contain the same number of items.
+  // 3. Entries in either array can be null, but for any index, there MUST be
+  //    either a Message in messages or a builder in builders.
+  // 4. If the builder at an index is non-null, the builder is
+  //    authoritative. This is the case where a Builder was set on the index.
+  //    Any message in the messages array MUST be ignored.
+  // t. If the builder at an index is null, the message in the messages
+  //    list is authoritative. This is the case where a Message (not a Builder)
+  //    was set directly for an index.
+
+  // Indicates that we've built a message and so we are now obligated
+  // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener.
+  private boolean isClean;
+
+  // A view of this builder that exposes a List interface of messages. This is
+  // initialized on demand. This is fully backed by this object and all changes
+  // are reflected in it. Access to any item converts it to a message if it
+  // was a builder.
+  private MessageExternalList<MType, BType, IType> externalMessageList;
+
+  // A view of this builder that exposes a List interface of builders. This is
+  // initialized on demand. This is fully backed by this object and all changes
+  // are reflected in it. Access to any item converts it to a builder if it
+  // was a message.
+  private BuilderExternalList<MType, BType, IType> externalBuilderList;
+
+  // A view of this builder that exposes a List interface of the interface
+  // implemented by messages and builders. This is initialized on demand. This
+  // is fully backed by this object and all changes are reflected in it.
+  // Access to any item returns either a builder or message depending on
+  // what is most efficient.
+  private MessageOrBuilderExternalList<MType, BType, IType>
+      externalMessageOrBuilderList;
+
+  /**
+   * Constructs a new builder with an empty list of messages.
+   *
+   * @param messages the current list of messages
+   * @param isMessagesListMutable Whether the messages list is mutable
+   * @param parent a listener to notify of changes
+   * @param isClean whether the builder is initially marked clean
+   */
+  public RepeatedFieldBuilder(
+      List<MType> messages,
+      boolean isMessagesListMutable,
+      GeneratedMessage.BuilderParent parent,
+      boolean isClean) {
+    this.messages = messages;
+    this.isMessagesListMutable = isMessagesListMutable;
+    this.parent = parent;
+    this.isClean = isClean;
+  }
+
+  public void dispose() {
+    // Null out parent so we stop sending it invalidations.
+    parent = null;
+  }
+
+  /**
+   * Ensures that the list of messages is mutable so it can be updated. If it's
+   * immutable, a copy is made.
+   */
+  private void ensureMutableMessageList() {
+    if (!isMessagesListMutable) {
+      messages = new ArrayList<MType>(messages);
+      isMessagesListMutable = true;
+    }
+  }
+
+  /**
+   * Ensures that the list of builders is not null. If it's null, the list is
+   * created and initialized to be the same size as the messages list with
+   * null entries.
+   */
+  private void ensureBuilders() {
+    if (this.builders == null) {
+      this.builders =
+          new ArrayList<SingleFieldBuilder<MType, BType, IType>>(
+              messages.size());
+      for (int i = 0; i < messages.size(); i++) {
+        builders.add(null);
+      }
+    }
+  }
+
+  /**
+   * Gets the count of items in the list.
+   *
+   * @return the count of items in the list.
+   */
+  public int getCount() {
+    return messages.size();
+  }
+
+  /**
+   * Gets whether the list is empty.
+   *
+   * @return whether the list is empty
+   */
+  public boolean isEmpty() {
+    return messages.isEmpty();
+  }
+
+  /**
+   * Get the message at the specified index. If the message is currently stored
+   * as a {@code Builder}, it is converted to a {@code Message} by
+   * calling {@link Message.Builder#buildPartial} on it.
+   *
+   * @param index the index of the message to get
+   * @return the message for the specified index
+   */
+  public MType getMessage(int index) {
+    return getMessage(index, false);
+  }
+
+  /**
+   * Get the message at the specified index. If the message is currently stored
+   * as a {@code Builder}, it is converted to a {@code Message} by
+   * calling {@link Message.Builder#buildPartial} on it.
+   *
+   * @param index the index of the message to get
+   * @param forBuild this is being called for build so we want to make sure
+   *     we SingleFieldBuilder.build to send dirty invalidations
+   * @return the message for the specified index
+   */
+  private MType getMessage(int index, boolean forBuild) {
+    if (this.builders == null) {
+      // We don't have any builders -- return the current Message.
+      // This is the case where no builder was created, so we MUST have a
+      // Message.
+      return messages.get(index);
+    }
+
+    SingleFieldBuilder<MType, BType, IType> builder = builders.get(index);
+    if (builder == null) {
+      // We don't have a builder -- return the current message.
+      // This is the case where no builder was created for the entry at index,
+      // so we MUST have a message.
+      return messages.get(index);
+
+    } else {
+      return forBuild ? builder.build() : builder.getMessage();
+    }
+  }
+
+  /**
+   * Gets a builder for the specified index. If no builder has been created for
+   * that index, a builder is created on demand by calling
+   * {@link Message#toBuilder}.
+   *
+   * @param index the index of the message to get
+   * @return The builder for that index
+   */
+  public BType getBuilder(int index) {
+    ensureBuilders();
+    SingleFieldBuilder<MType, BType, IType> builder = builders.get(index);
+    if (builder == null) {
+      MType message = messages.get(index);
+      builder = new SingleFieldBuilder<MType, BType, IType>(
+          message, this, isClean);
+      builders.set(index, builder);
+    }
+    return builder.getBuilder();
+  }
+
+  /**
+   * Gets the base class interface for the specified index. This may either be
+   * a builder or a message. It will return whatever is more efficient.
+   *
+   * @param index the index of the message to get
+   * @return the message or builder for the index as the base class interface
+   */
+  @SuppressWarnings("unchecked")
+  public IType getMessageOrBuilder(int index) {
+    if (this.builders == null) {
+      // We don't have any builders -- return the current Message.
+      // This is the case where no builder was created, so we MUST have a
+      // Message.
+      return (IType) messages.get(index);
+    }
+
+    SingleFieldBuilder<MType, BType, IType> builder = builders.get(index);
+    if (builder == null) {
+      // We don't have a builder -- return the current message.
+      // This is the case where no builder was created for the entry at index,
+      // so we MUST have a message.
+      return (IType) messages.get(index);
+
+    } else {
+      return builder.getMessageOrBuilder();
+    }
+  }
+
+  /**
+   * Sets a  message at the specified index replacing the existing item at
+   * that index.
+   *
+   * @param index the index to set.
+   * @param message the message to set
+   * @return the builder
+   */
+  public RepeatedFieldBuilder<MType, BType, IType> setMessage(
+      int index, MType message) {
+    if (message == null) {
+      throw new NullPointerException();
+    }
+    ensureMutableMessageList();
+    messages.set(index, message);
+    if (builders != null) {
+      SingleFieldBuilder<MType, BType, IType> entry =
+          builders.set(index, null);
+      if (entry != null) {
+        entry.dispose();
+      }
+    }
+    onChanged();
+    incrementModCounts();
+    return this;
+  }
+
+  /**
+   * Appends the specified element to the end of this list.
+   *
+   * @param message the message to add
+   * @return the builder
+   */
+  public RepeatedFieldBuilder<MType, BType, IType> addMessage(
+      MType message) {
+    if (message == null) {
+      throw new NullPointerException();
+    }
+    ensureMutableMessageList();
+    messages.add(message);
+    if (builders != null) {
+      builders.add(null);
+    }
+    onChanged();
+    incrementModCounts();
+    return this;
+  }
+
+  /**
+   * Inserts the specified message at the specified position in this list.
+   * Shifts the element currently at that position (if any) and any subsequent
+   * elements to the right (adds one to their indices).
+   *
+   * @param index the index at which to insert the message
+   * @param message the message to add
+   * @return the builder
+   */
+  public RepeatedFieldBuilder<MType, BType, IType> addMessage(
+      int index, MType message) {
+    if (message == null) {
+      throw new NullPointerException();
+    }
+    ensureMutableMessageList();
+    messages.add(index, message);
+    if (builders != null) {
+      builders.add(index, null);
+    }
+    onChanged();
+    incrementModCounts();
+    return this;
+  }
+
+  /**
+   * Appends all of the messages in the specified collection to the end of
+   * this list, in the order that they are returned by the specified
+   * collection's iterator.
+   *
+   * @param values the messages to add
+   * @return the builder
+   */
+  public RepeatedFieldBuilder<MType, BType, IType> addAllMessages(
+      Iterable<? extends MType> values) {
+    for (final MType value : values) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+    }
+    if (values instanceof Collection) {
+      @SuppressWarnings("unchecked") final
+      Collection<MType> collection = (Collection<MType>) values;
+      if (collection.size() == 0) {
+        return this;
+      }
+      ensureMutableMessageList();
+      for (MType value : values) {
+        addMessage(value);
+      }
+    } else {
+      ensureMutableMessageList();
+      for (MType value : values) {
+        addMessage(value);
+      }
+    }
+    onChanged();
+    incrementModCounts();
+    return this;
+  }
+
+  /**
+   * Appends a new builder to the end of this list and returns the builder.
+   *
+   * @param message the message to add which is the basis of the builder
+   * @return the new builder
+   */
+  public BType addBuilder(MType message) {
+    ensureMutableMessageList();
+    ensureBuilders();
+    SingleFieldBuilder<MType, BType, IType> builder =
+        new SingleFieldBuilder<MType, BType, IType>(
+            message, this, isClean);
+    messages.add(null);
+    builders.add(builder);
+    onChanged();
+    incrementModCounts();
+    return builder.getBuilder();
+  }
+
+  /**
+   * Inserts a new builder at the specified position in this list.
+   * Shifts the element currently at that position (if any) and any subsequent
+   * elements to the right (adds one to their indices).
+   *
+   * @param index the index at which to insert the builder
+   * @param message the message to add which is the basis of the builder
+   * @return the builder
+   */
+  public BType addBuilder(int index, MType message) {
+    ensureMutableMessageList();
+    ensureBuilders();
+    SingleFieldBuilder<MType, BType, IType> builder =
+        new SingleFieldBuilder<MType, BType, IType>(
+            message, this, isClean);
+    messages.add(index, null);
+    builders.add(index, builder);
+    onChanged();
+    incrementModCounts();
+    return builder.getBuilder();
+  }
+
+  /**
+   * Removes the element at the specified position in this list. Shifts any
+   * subsequent elements to the left (subtracts one from their indices).
+   * Returns the element that was removed from the list.
+   *
+   * @param index the index at which to remove the message
+   */
+  public void remove(int index) {
+    ensureMutableMessageList();
+    messages.remove(index);
+    if (builders != null) {
+      SingleFieldBuilder<MType, BType, IType> entry =
+          builders.remove(index);
+      if (entry != null) {
+        entry.dispose();
+      }
+    }
+    onChanged();
+    incrementModCounts();
+  }
+
+  /**
+   * Removes all of the elements from this list.
+   * The list will be empty after this call returns.
+   */
+  public void clear() {
+    messages = Collections.emptyList();
+    isMessagesListMutable = false;
+    if (builders != null) {
+      for (SingleFieldBuilder<MType, BType, IType> entry :
+          builders) {
+        if (entry != null) {
+          entry.dispose();
+        }
+      }
+      builders = null;
+    }
+    onChanged();
+    incrementModCounts();
+  }
+
+  /**
+   * Builds the list of messages from the builder and returns them.
+   *
+   * @return an immutable list of messages
+   */
+  public List<MType> build() {
+    // Now that build has been called, we are required to dispatch
+    // invalidations.
+    isClean = true;
+
+    if (!isMessagesListMutable && builders == null) {
+      // We still have an immutable list and we never created a builder.
+      return messages;
+    }
+
+    boolean allMessagesInSync = true;
+    if (!isMessagesListMutable) {
+      // We still have an immutable list. Let's see if any of them are out
+      // of sync with their builders.
+      for (int i = 0; i < messages.size(); i++) {
+        Message message = messages.get(i);
+        SingleFieldBuilder<MType, BType, IType> builder = builders.get(i);
+        if (builder != null) {
+          if (builder.build() != message) {
+            allMessagesInSync = false;
+            break;
+          }
+        }
+      }
+      if (allMessagesInSync) {
+        // Immutable list is still in sync.
+        return messages;
+      }
+    }
+
+    // Need to make sure messages is up to date
+    ensureMutableMessageList();
+    for (int i = 0; i < messages.size(); i++) {
+      messages.set(i, getMessage(i, true));
+    }
+
+    // We're going to return our list as immutable so we mark that we can
+    // no longer update it.
+    messages = Collections.unmodifiableList(messages);
+    isMessagesListMutable = false;
+    return messages;
+  }
+
+  /**
+   * Gets a view of the builder as a list of messages. The returned list is live
+   * and will reflect any changes to the underlying builder.
+   *
+   * @return the messages in the list
+   */
+  public List<MType> getMessageList() {
+    if (externalMessageList == null) {
+      externalMessageList =
+          new MessageExternalList<MType, BType, IType>(this);
+    }
+    return externalMessageList;
+  }
+
+  /**
+   * Gets a view of the builder as a list of builders. This returned list is
+   * live and will reflect any changes to the underlying builder.
+   *
+   * @return the builders in the list
+   */
+  public List<BType> getBuilderList() {
+    if (externalBuilderList == null) {
+      externalBuilderList =
+          new BuilderExternalList<MType, BType, IType>(this);
+    }
+    return externalBuilderList;
+  }
+
+  /**
+   * Gets a view of the builder as a list of MessageOrBuilders. This returned
+   * list is live and will reflect any changes to the underlying builder.
+   *
+   * @return the builders in the list
+   */
+  public List<IType> getMessageOrBuilderList() {
+    if (externalMessageOrBuilderList == null) {
+      externalMessageOrBuilderList =
+          new MessageOrBuilderExternalList<MType, BType, IType>(this);
+    }
+    return externalMessageOrBuilderList;
+  }
+
+  /**
+   * Called when a the builder or one of its nested children has changed
+   * and any parent should be notified of its invalidation.
+   */
+  private void onChanged() {
+    if (isClean && parent != null) {
+      parent.markDirty();
+
+      // Don't keep dispatching invalidations until build is called again.
+      isClean = false;
+    }
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public void markDirty() {
+    onChanged();
+  }
+
+  /**
+   * Increments the mod counts so that an ConcurrentModificationException can
+   * be thrown if calling code tries to modify the builder while its iterating
+   * the list.
+   */
+  private void incrementModCounts() {
+    if (externalMessageList != null) {
+      externalMessageList.incrementModCount();
+    }
+    if (externalBuilderList != null) {
+      externalBuilderList.incrementModCount();
+    }
+    if (externalMessageOrBuilderList != null) {
+      externalMessageOrBuilderList.incrementModCount();
+    }
+  }
+
+  /**
+   * Provides a live view of the builder as a list of messages.
+   *
+   * @param <MType> the type of message for the field
+   * @param <BType> the type of builder for the field
+   * @param <IType> the common interface for the message and the builder
+   */
+  private static class MessageExternalList<
+      MType extends GeneratedMessage,
+      BType extends GeneratedMessage.Builder,
+      IType extends MessageOrBuilder>
+      extends AbstractList<MType> implements List<MType> {
+
+    RepeatedFieldBuilder<MType, BType, IType> builder;
+
+    MessageExternalList(
+        RepeatedFieldBuilder<MType, BType, IType> builder) {
+      this.builder = builder;
+    }
+
+    public int size() {
+      return this.builder.getCount();
+    }
+
+    public MType get(int index) {
+      return builder.getMessage(index);
+    }
+
+    void incrementModCount() {
+      modCount++;
+    }
+  }
+
+  /**
+   * Provides a live view of the builder as a list of builders.
+   *
+   * @param <MType> the type of message for the field
+   * @param <BType> the type of builder for the field
+   * @param <IType> the common interface for the message and the builder
+   */
+  private static class BuilderExternalList<
+      MType extends GeneratedMessage,
+      BType extends GeneratedMessage.Builder,
+      IType extends MessageOrBuilder>
+      extends AbstractList<BType> implements List<BType> {
+
+    RepeatedFieldBuilder<MType, BType, IType> builder;
+
+    BuilderExternalList(
+        RepeatedFieldBuilder<MType, BType, IType> builder) {
+      this.builder = builder;
+    }
+
+    public int size() {
+      return this.builder.getCount();
+    }
+
+    public BType get(int index) {
+      return builder.getBuilder(index);
+    }
+
+    void incrementModCount() {
+      modCount++;
+    }
+  }
+
+  /**
+   * Provides a live view of the builder as a list of builders.
+   *
+   * @param <MType> the type of message for the field
+   * @param <BType> the type of builder for the field
+   * @param <IType> the common interface for the message and the builder
+   */
+  private static class MessageOrBuilderExternalList<
+      MType extends GeneratedMessage,
+      BType extends GeneratedMessage.Builder,
+      IType extends MessageOrBuilder>
+      extends AbstractList<IType> implements List<IType> {
+
+    RepeatedFieldBuilder<MType, BType, IType> builder;
+
+    MessageOrBuilderExternalList(
+        RepeatedFieldBuilder<MType, BType, IType> builder) {
+      this.builder = builder;
+    }
+
+    public int size() {
+      return this.builder.getCount();
+    }
+
+    public IType get(int index) {
+      return builder.getMessageOrBuilder(index);
+    }
+
+    void incrementModCount() {
+      modCount++;
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/RopeByteString.java b/protobuf/java/src/main/java/com/google/protobuf/RopeByteString.java
new file mode 100644
index 0000000..d1655b8
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/RopeByteString.java
@@ -0,0 +1,957 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.ByteArrayInputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Stack;
+
+/**
+ * Class to represent {@code ByteStrings} formed by concatenation of other
+ * ByteStrings, without copying the data in the pieces. The concatenation is
+ * represented as a tree whose leaf nodes are each a {@link LiteralByteString}.
+ *
+ * <p>Most of the operation here is inspired by the now-famous paper <a
+ * href="http://www.cs.ubc.ca/local/reading/proceedings/spe91-95/spe/vol25/issue12/spe986.pdf">
+ * BAP95 </a> Ropes: an Alternative to Strings hans-j. boehm, russ atkinson and
+ * michael plass
+ *
+ * <p>The algorithms described in the paper have been implemented for character
+ * strings in {@link com.google.common.string.Rope} and in the c++ class {@code
+ * cord.cc}.
+ *
+ * <p>Fundamentally the Rope algorithm represents the collection of pieces as a
+ * binary tree. BAP95 uses a Fibonacci bound relating depth to a minimum
+ * sequence length, sequences that are too short relative to their depth cause a
+ * tree rebalance.  More precisely, a tree of depth d is "balanced" in the
+ * terminology of BAP95 if its length is at least F(d+2), where F(n) is the
+ * n-the Fibonacci number. Thus for depths 0, 1, 2, 3, 4, 5,... we have minimum
+ * lengths 1, 2, 3, 5, 8, 13,...
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+class RopeByteString extends ByteString {
+
+  /**
+   * BAP95. Let Fn be the nth Fibonacci number. A {@link RopeByteString} of
+   * depth n is "balanced", i.e flat enough, if its length is at least Fn+2,
+   * e.g. a "balanced" {@link RopeByteString} of depth 1 must have length at
+   * least 2, of depth 4 must have length >= 8, etc.
+   *
+   * <p>There's nothing special about using the Fibonacci numbers for this, but
+   * they are a reasonable sequence for encapsulating the idea that we are OK
+   * with longer strings being encoded in deeper binary trees.
+   *
+   * <p>For 32-bit integers, this array has length 46.
+   */
+  private static final int[] minLengthByDepth;
+
+  static {
+    // Dynamically generate the list of Fibonacci numbers the first time this
+    // class is accessed.
+    List<Integer> numbers = new ArrayList<Integer>();
+
+    // we skip the first Fibonacci number (1).  So instead of: 1 1 2 3 5 8 ...
+    // we have: 1 2 3 5 8 ...
+    int f1 = 1;
+    int f2 = 1;
+
+    // get all the values until we roll over.
+    while (f2 > 0) {
+      numbers.add(f2);
+      int temp = f1 + f2;
+      f1 = f2;
+      f2 = temp;
+    }
+
+    // we include this here so that we can index this array to [x + 1] in the
+    // loops below.
+    numbers.add(Integer.MAX_VALUE);
+    minLengthByDepth = new int[numbers.size()];
+    for (int i = 0; i < minLengthByDepth.length; i++) {
+      // unbox all the values
+      minLengthByDepth[i] = numbers.get(i);
+    }
+  }
+
+  private final int totalLength;
+  private final ByteString left;
+  private final ByteString right;
+  private final int leftLength;
+  private final int treeDepth;
+
+  /**
+   * Create a new RopeByteString, which can be thought of as a new tree node, by
+   * recording references to the two given strings.
+   *
+   * @param left  string on the left of this node, should have {@code size() >
+   *              0}
+   * @param right string on the right of this node, should have {@code size() >
+   *              0}
+   */
+  private RopeByteString(ByteString left, ByteString right) {
+    this.left = left;
+    this.right = right;
+    leftLength = left.size();
+    totalLength = leftLength + right.size();
+    treeDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1;
+  }
+
+  /**
+   * Concatenate the given strings while performing various optimizations to
+   * slow the growth rate of tree depth and tree node count. The result is
+   * either a {@link LiteralByteString} or a {@link RopeByteString}
+   * depending on which optimizations, if any, were applied.
+   *
+   * <p>Small pieces of length less than {@link
+   * ByteString#CONCATENATE_BY_COPY_SIZE} may be copied by value here, as in
+   * BAP95.  Large pieces are referenced without copy.
+   *
+   * @param left  string on the left
+   * @param right string on the right
+   * @return concatenation representing the same sequence as the given strings
+   */
+  static ByteString concatenate(ByteString left, ByteString right) {
+    ByteString result;
+    RopeByteString leftRope =
+        (left instanceof RopeByteString) ? (RopeByteString) left : null;
+    if (right.size() == 0) {
+      result = left;
+    } else if (left.size() == 0) {
+      result = right;
+    } else {
+      int newLength = left.size() + right.size();
+      if (newLength < ByteString.CONCATENATE_BY_COPY_SIZE) {
+        // Optimization from BAP95: For short (leaves in paper, but just short
+        // here) total length, do a copy of data to a new leaf.
+        result = concatenateBytes(left, right);
+      } else if (leftRope != null
+          && leftRope.right.size() + right.size() < CONCATENATE_BY_COPY_SIZE) {
+        // Optimization from BAP95: As an optimization of the case where the
+        // ByteString is constructed by repeated concatenate, recognize the case
+        // where a short string is concatenated to a left-hand node whose
+        // right-hand branch is short.  In the paper this applies to leaves, but
+        // we just look at the length here. This has the advantage of shedding
+        // references to unneeded data when substrings have been taken.
+        //
+        // When we recognize this case, we do a copy of the data and create a
+        // new parent node so that the depth of the result is the same as the
+        // given left tree.
+        ByteString newRight = concatenateBytes(leftRope.right, right);
+        result = new RopeByteString(leftRope.left, newRight);
+      } else if (leftRope != null
+          && leftRope.left.getTreeDepth() > leftRope.right.getTreeDepth()
+          && leftRope.getTreeDepth() > right.getTreeDepth()) {
+        // Typically for concatenate-built strings the left-side is deeper than
+        // the right.  This is our final attempt to concatenate without
+        // increasing the tree depth.  We'll redo the the node on the RHS.  This
+        // is yet another optimization for building the string by repeatedly
+        // concatenating on the right.
+        ByteString newRight = new RopeByteString(leftRope.right, right);
+        result = new RopeByteString(leftRope.left, newRight);
+      } else {
+        // Fine, we'll add a node and increase the tree depth--unless we
+        // rebalance ;^)
+        int newDepth = Math.max(left.getTreeDepth(), right.getTreeDepth()) + 1;
+        if (newLength >= minLengthByDepth[newDepth]) {
+          // The tree is shallow enough, so don't rebalance
+          result = new RopeByteString(left, right);
+        } else {
+          result = new Balancer().balance(left, right);
+        }
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Concatenates two strings by copying data values. This is called in a few
+   * cases in order to reduce the growth of the number of tree nodes.
+   *
+   * @param left  string on the left
+   * @param right string on the right
+   * @return string formed by copying data bytes
+   */
+  private static LiteralByteString concatenateBytes(ByteString left,
+      ByteString right) {
+    int leftSize = left.size();
+    int rightSize = right.size();
+    byte[] bytes = new byte[leftSize + rightSize];
+    left.copyTo(bytes, 0, 0, leftSize);
+    right.copyTo(bytes, 0, leftSize, rightSize);
+    return new LiteralByteString(bytes);  // Constructor wraps bytes
+  }
+
+  /**
+   * Create a new RopeByteString for testing only while bypassing all the
+   * defenses of {@link #concatenate(ByteString, ByteString)}. This allows
+   * testing trees of specific structure. We are also able to insert empty
+   * leaves, though these are dis-allowed, so that we can make sure the
+   * implementation can withstand their presence.
+   *
+   * @param left  string on the left of this node
+   * @param right string on the right of this node
+   * @return an unsafe instance for testing only
+   */
+  static RopeByteString newInstanceForTest(ByteString left, ByteString right) {
+    return new RopeByteString(left, right);
+  }
+
+  /**
+   * Gets the byte at the given index.
+   * Throws {@link ArrayIndexOutOfBoundsException} for backwards-compatibility
+   * reasons although it would more properly be {@link
+   * IndexOutOfBoundsException}.
+   *
+   * @param index index of byte
+   * @return the value
+   * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
+   */
+  @Override
+  public byte byteAt(int index) {
+    if (index < 0) {
+      throw new ArrayIndexOutOfBoundsException("Index < 0: " + index);
+    }
+    if (index > totalLength) {
+      throw new ArrayIndexOutOfBoundsException(
+          "Index > length: " + index + ", " + totalLength);
+    }
+
+    byte result;
+    // Find the relevant piece by recursive descent
+    if (index < leftLength) {
+      result = left.byteAt(index);
+    } else {
+      result = right.byteAt(index - leftLength);
+    }
+    return result;
+  }
+
+  @Override
+  public int size() {
+    return totalLength;
+  }
+
+  // =================================================================
+  // Pieces
+
+  @Override
+  protected int getTreeDepth() {
+    return treeDepth;
+  }
+
+  /**
+   * Determines if the tree is balanced according to BAP95, which means the tree
+   * is flat-enough with respect to the bounds. Note that this definition of
+   * balanced is one where sub-trees of balanced trees are not necessarily
+   * balanced.
+   *
+   * @return true if the tree is balanced
+   */
+  @Override
+  protected boolean isBalanced() {
+    return totalLength >= minLengthByDepth[treeDepth];
+  }
+
+  /**
+   * Takes a substring of this one. This involves recursive descent along the
+   * left and right edges of the substring, and referencing any wholly contained
+   * segments in between. Any leaf nodes entirely uninvolved in the substring
+   * will not be referenced by the substring.
+   *
+   * <p>Substrings of {@code length < 2} should result in at most a single
+   * recursive call chain, terminating at a leaf node. Thus the result will be a
+   * {@link LiteralByteString}. {@link #RopeByteString(ByteString,
+   * ByteString)}.
+   *
+   * @param beginIndex start at this index
+   * @param endIndex   the last character is the one before this index
+   * @return substring leaf node or tree
+   */
+  @Override
+  public ByteString substring(int beginIndex, int endIndex) {
+    if (beginIndex < 0) {
+      throw new IndexOutOfBoundsException(
+          "Beginning index: " + beginIndex + " < 0");
+    }
+    if (endIndex > totalLength) {
+      throw new IndexOutOfBoundsException(
+          "End index: " + endIndex + " > " + totalLength);
+    }
+    int substringLength = endIndex - beginIndex;
+    if (substringLength < 0) {
+      throw new IndexOutOfBoundsException(
+          "Beginning index larger than ending index: " + beginIndex + ", "
+              + endIndex);
+    }
+
+    ByteString result;
+    if (substringLength == 0) {
+      // Empty substring
+      result = ByteString.EMPTY;
+    } else if (substringLength == totalLength) {
+      // The whole string
+      result = this;
+    } else {
+      // Proper substring
+      if (endIndex <= leftLength) {
+        // Substring on the left
+        result = left.substring(beginIndex, endIndex);
+      } else if (beginIndex >= leftLength) {
+        // Substring on the right
+        result = right
+            .substring(beginIndex - leftLength, endIndex - leftLength);
+      } else {
+        // Split substring
+        ByteString leftSub = left.substring(beginIndex);
+        ByteString rightSub = right.substring(0, endIndex - leftLength);
+        // Intentionally not rebalancing, since in many cases these two
+        // substrings will already be less deep than the top-level
+        // RopeByteString we're taking a substring of.
+        result = new RopeByteString(leftSub, rightSub);
+      }
+    }
+    return result;
+  }
+
+  // =================================================================
+  // ByteString -> byte[]
+
+  @Override
+  protected void copyToInternal(byte[] target, int sourceOffset,
+      int targetOffset, int numberToCopy) {
+   if (sourceOffset + numberToCopy <= leftLength) {
+      left.copyToInternal(target, sourceOffset, targetOffset, numberToCopy);
+    } else if (sourceOffset >= leftLength) {
+      right.copyToInternal(target, sourceOffset - leftLength, targetOffset,
+          numberToCopy);
+    } else {
+      int leftLength = this.leftLength - sourceOffset;
+      left.copyToInternal(target, sourceOffset, targetOffset, leftLength);
+      right.copyToInternal(target, 0, targetOffset + leftLength,
+          numberToCopy - leftLength);
+    }
+  }
+
+  @Override
+  public void copyTo(ByteBuffer target) {
+    left.copyTo(target);
+    right.copyTo(target);
+  }
+
+  @Override
+  public ByteBuffer asReadOnlyByteBuffer() {
+    ByteBuffer byteBuffer = ByteBuffer.wrap(toByteArray());
+    return byteBuffer.asReadOnlyBuffer();
+  }
+
+  @Override
+  public List<ByteBuffer> asReadOnlyByteBufferList() {
+    // Walk through the list of LiteralByteString's that make up this
+    // rope, and add each one as a read-only ByteBuffer.
+    List<ByteBuffer> result = new ArrayList<ByteBuffer>();
+    PieceIterator pieces = new PieceIterator(this);
+    while (pieces.hasNext()) {
+      LiteralByteString byteString = pieces.next();
+      result.add(byteString.asReadOnlyByteBuffer());
+    }
+    return result;
+  }
+
+  @Override
+  public void writeTo(OutputStream outputStream) throws IOException {
+    left.writeTo(outputStream);
+    right.writeTo(outputStream);
+  }
+
+  @Override
+  void writeToInternal(OutputStream out, int sourceOffset,
+      int numberToWrite) throws IOException {
+    if (sourceOffset + numberToWrite <= leftLength) {
+      left.writeToInternal(out, sourceOffset, numberToWrite);
+    } else if (sourceOffset >= leftLength) {
+      right.writeToInternal(out, sourceOffset - leftLength, numberToWrite);
+    } else {
+      int numberToWriteInLeft = leftLength - sourceOffset;
+      left.writeToInternal(out, sourceOffset, numberToWriteInLeft);
+      right.writeToInternal(out, 0, numberToWrite - numberToWriteInLeft);
+    }
+  }
+
+  @Override
+  public String toString(String charsetName)
+      throws UnsupportedEncodingException {
+    return new String(toByteArray(), charsetName);
+  }
+
+  // =================================================================
+  // UTF-8 decoding
+
+  @Override
+  public boolean isValidUtf8() {
+    int leftPartial = left.partialIsValidUtf8(Utf8.COMPLETE, 0, leftLength);
+    int state = right.partialIsValidUtf8(leftPartial, 0, right.size());
+    return state == Utf8.COMPLETE;
+  }
+
+  @Override
+  protected int partialIsValidUtf8(int state, int offset, int length) {
+    int toIndex = offset + length;
+    if (toIndex <= leftLength) {
+      return left.partialIsValidUtf8(state, offset, length);
+    } else if (offset >= leftLength) {
+      return right.partialIsValidUtf8(state, offset - leftLength, length);
+    } else {
+      int leftLength = this.leftLength - offset;
+      int leftPartial = left.partialIsValidUtf8(state, offset, leftLength);
+      return right.partialIsValidUtf8(leftPartial, 0, length - leftLength);
+    }
+  }
+
+  // =================================================================
+  // equals() and hashCode()
+
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) {
+      return true;
+    }
+    if (!(other instanceof ByteString)) {
+      return false;
+    }
+
+    ByteString otherByteString = (ByteString) other;
+    if (totalLength != otherByteString.size()) {
+      return false;
+    }
+    if (totalLength == 0) {
+      return true;
+    }
+
+    // You don't really want to be calling equals on long strings, but since
+    // we cache the hashCode, we effectively cache inequality. We use the cached
+    // hashCode if it's already computed.  It's arguable we should compute the
+    // hashCode here, and if we're going to be testing a bunch of byteStrings,
+    // it might even make sense.
+    if (hash != 0) {
+      int cachedOtherHash = otherByteString.peekCachedHashCode();
+      if (cachedOtherHash != 0 && hash != cachedOtherHash) {
+        return false;
+      }
+    }
+
+    return equalsFragments(otherByteString);
+  }
+
+  /**
+   * Determines if this string is equal to another of the same length by
+   * iterating over the leaf nodes. On each step of the iteration, the
+   * overlapping segments of the leaves are compared.
+   *
+   * @param other string of the same length as this one
+   * @return true if the values of this string equals the value of the given
+   *         one
+   */
+  private boolean equalsFragments(ByteString other) {
+    int thisOffset = 0;
+    Iterator<LiteralByteString> thisIter = new PieceIterator(this);
+    LiteralByteString thisString = thisIter.next();
+
+    int thatOffset = 0;
+    Iterator<LiteralByteString> thatIter = new PieceIterator(other);
+    LiteralByteString thatString = thatIter.next();
+
+    int pos = 0;
+    while (true) {
+      int thisRemaining = thisString.size() - thisOffset;
+      int thatRemaining = thatString.size() - thatOffset;
+      int bytesToCompare = Math.min(thisRemaining, thatRemaining);
+
+      // At least one of the offsets will be zero
+      boolean stillEqual = (thisOffset == 0)
+          ? thisString.equalsRange(thatString, thatOffset, bytesToCompare)
+          : thatString.equalsRange(thisString, thisOffset, bytesToCompare);
+      if (!stillEqual) {
+        return false;
+      }
+
+      pos += bytesToCompare;
+      if (pos >= totalLength) {
+        if (pos == totalLength) {
+          return true;
+        }
+        throw new IllegalStateException();
+      }
+      // We always get to the end of at least one of the pieces
+      if (bytesToCompare == thisRemaining) { // If reached end of this
+        thisOffset = 0;
+        thisString = thisIter.next();
+      } else {
+        thisOffset += bytesToCompare;
+      }
+      if (bytesToCompare == thatRemaining) { // If reached end of that
+        thatOffset = 0;
+        thatString = thatIter.next();
+      } else {
+        thatOffset += bytesToCompare;
+      }
+    }
+  }
+
+  /**
+   * Cached hash value.  Intentionally accessed via a data race, which is safe
+   * because of the Java Memory Model's "no out-of-thin-air values" guarantees
+   * for ints.
+   */
+  private int hash = 0;
+
+  @Override
+  public int hashCode() {
+    int h = hash;
+
+    if (h == 0) {
+      h = totalLength;
+      h = partialHash(h, 0, totalLength);
+      if (h == 0) {
+        h = 1;
+      }
+      hash = h;
+    }
+    return h;
+  }
+
+  @Override
+  protected int peekCachedHashCode() {
+    return hash;
+  }
+
+  @Override
+  protected int partialHash(int h, int offset, int length) {
+    int toIndex = offset + length;
+    if (toIndex <= leftLength) {
+      return left.partialHash(h, offset, length);
+    } else if (offset >= leftLength) {
+      return right.partialHash(h, offset - leftLength, length);
+    } else {
+      int leftLength = this.leftLength - offset;
+      int leftPartial = left.partialHash(h, offset, leftLength);
+      return right.partialHash(leftPartial, 0, length - leftLength);
+    }
+  }
+
+  // =================================================================
+  // Input stream
+
+  @Override
+  public CodedInputStream newCodedInput() {
+    return CodedInputStream.newInstance(new RopeInputStream());
+  }
+
+  @Override
+  public InputStream newInput() {
+    return new RopeInputStream();
+  }
+
+  /**
+   * This class implements the balancing algorithm of BAP95. In the paper the
+   * authors use an array to keep track of pieces, while here we use a stack.
+   * The tree is balanced by traversing subtrees in left to right order, and the
+   * stack always contains the part of the string we've traversed so far.
+   *
+   * <p>One surprising aspect of the algorithm is the result of balancing is not
+   * necessarily balanced, though it is nearly balanced.  For details, see
+   * BAP95.
+   */
+  private static class Balancer {
+    // Stack containing the part of the string, starting from the left, that
+    // we've already traversed.  The final string should be the equivalent of
+    // concatenating the strings on the stack from bottom to top.
+    private final Stack<ByteString> prefixesStack = new Stack<ByteString>();
+
+    private ByteString balance(ByteString left, ByteString right) {
+      doBalance(left);
+      doBalance(right);
+
+      // Sweep stack to gather the result
+      ByteString partialString = prefixesStack.pop();
+      while (!prefixesStack.isEmpty()) {
+        ByteString newLeft = prefixesStack.pop();
+        partialString = new RopeByteString(newLeft, partialString);
+      }
+      // We should end up with a RopeByteString since at a minimum we will
+      // create one from concatenating left and right
+      return partialString;
+    }
+
+    private void doBalance(ByteString root) {
+      // BAP95: Insert balanced subtrees whole. This means the result might not
+      // be balanced, leading to repeated rebalancings on concatenate. However,
+      // these rebalancings are shallow due to ignoring balanced subtrees, and
+      // relatively few calls to insert() result.
+      if (root.isBalanced()) {
+        insert(root);
+      } else if (root instanceof RopeByteString) {
+        RopeByteString rbs = (RopeByteString) root;
+        doBalance(rbs.left);
+        doBalance(rbs.right);
+      } else {
+        throw new IllegalArgumentException(
+            "Has a new type of ByteString been created? Found " +
+                root.getClass());
+      }
+    }
+
+    /**
+     * Push a string on the balance stack (BAP95).  BAP95 uses an array and
+     * calls the elements in the array 'bins'.  We instead use a stack, so the
+     * 'bins' of lengths are represented by differences between the elements of
+     * minLengthByDepth.
+     *
+     * <p>If the length bin for our string, and all shorter length bins, are
+     * empty, we just push it on the stack.  Otherwise, we need to start
+     * concatenating, putting the given string in the "middle" and continuing
+     * until we land in an empty length bin that matches the length of our
+     * concatenation.
+     *
+     * @param byteString string to place on the balance stack
+     */
+    private void insert(ByteString byteString) {
+      int depthBin = getDepthBinForLength(byteString.size());
+      int binEnd = minLengthByDepth[depthBin + 1];
+
+      // BAP95: Concatenate all trees occupying bins representing the length of
+      // our new piece or of shorter pieces, to the extent that is possible.
+      // The goal is to clear the bin which our piece belongs in, but that may
+      // not be entirely possible if there aren't enough longer bins occupied.
+      if (prefixesStack.isEmpty() || prefixesStack.peek().size() >= binEnd) {
+        prefixesStack.push(byteString);
+      } else {
+        int binStart = minLengthByDepth[depthBin];
+
+        // Concatenate the subtrees of shorter length
+        ByteString newTree = prefixesStack.pop();
+        while (!prefixesStack.isEmpty()
+            && prefixesStack.peek().size() < binStart) {
+          ByteString left = prefixesStack.pop();
+          newTree = new RopeByteString(left, newTree);
+        }
+
+        // Concatenate the given string
+        newTree = new RopeByteString(newTree, byteString);
+
+        // Continue concatenating until we land in an empty bin
+        while (!prefixesStack.isEmpty()) {
+          depthBin = getDepthBinForLength(newTree.size());
+          binEnd = minLengthByDepth[depthBin + 1];
+          if (prefixesStack.peek().size() < binEnd) {
+            ByteString left = prefixesStack.pop();
+            newTree = new RopeByteString(left, newTree);
+          } else {
+            break;
+          }
+        }
+        prefixesStack.push(newTree);
+      }
+    }
+
+    private int getDepthBinForLength(int length) {
+      int depth = Arrays.binarySearch(minLengthByDepth, length);
+      if (depth < 0) {
+        // It wasn't an exact match, so convert to the index of the containing
+        // fragment, which is one less even than the insertion point.
+        int insertionPoint = -(depth + 1);
+        depth = insertionPoint - 1;
+      }
+
+      return depth;
+    }
+  }
+
+  /**
+   * This class is a continuable tree traversal, which keeps the state
+   * information which would exist on the stack in a recursive traversal instead
+   * on a stack of "Bread Crumbs". The maximum depth of the stack in this
+   * iterator is the same as the depth of the tree being traversed.
+   *
+   * <p>This iterator is used to implement
+   * {@link RopeByteString#equalsFragments(ByteString)}.
+   */
+  private static class PieceIterator implements Iterator<LiteralByteString> {
+
+    private final Stack<RopeByteString> breadCrumbs =
+        new Stack<RopeByteString>();
+    private LiteralByteString next;
+
+    private PieceIterator(ByteString root) {
+      next = getLeafByLeft(root);
+    }
+
+    private LiteralByteString getLeafByLeft(ByteString root) {
+      ByteString pos = root;
+      while (pos instanceof RopeByteString) {
+        RopeByteString rbs = (RopeByteString) pos;
+        breadCrumbs.push(rbs);
+        pos = rbs.left;
+      }
+      return (LiteralByteString) pos;
+    }
+
+    private LiteralByteString getNextNonEmptyLeaf() {
+      while (true) {
+        // Almost always, we go through this loop exactly once.  However, if
+        // we discover an empty string in the rope, we toss it and try again.
+        if (breadCrumbs.isEmpty()) {
+          return null;
+        } else {
+          LiteralByteString result = getLeafByLeft(breadCrumbs.pop().right);
+          if (!result.isEmpty()) {
+            return result;
+          }
+        }
+      }
+    }
+
+    public boolean hasNext() {
+      return next != null;
+    }
+
+    /**
+     * Returns the next item and advances one {@code LiteralByteString}.
+     *
+     * @return next non-empty LiteralByteString or {@code null}
+     */
+    public LiteralByteString next() {
+      if (next == null) {
+        throw new NoSuchElementException();
+      }
+      LiteralByteString result = next;
+      next = getNextNonEmptyLeaf();
+      return result;
+    }
+
+    public void remove() {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  // =================================================================
+  // ByteIterator
+
+  @Override
+  public ByteIterator iterator() {
+    return new RopeByteIterator();
+  }
+
+  private class RopeByteIterator implements ByteString.ByteIterator {
+
+    private final PieceIterator pieces;
+    private ByteIterator bytes;
+    int bytesRemaining;
+
+    private RopeByteIterator() {
+      pieces = new PieceIterator(RopeByteString.this);
+      bytes = pieces.next().iterator();
+      bytesRemaining = size();
+    }
+
+    public boolean hasNext() {
+      return (bytesRemaining > 0);
+    }
+
+    public Byte next() {
+      return nextByte(); // Does not instantiate a Byte
+    }
+
+    public byte nextByte() {
+      if (!bytes.hasNext()) {
+        bytes = pieces.next().iterator();
+      }
+      --bytesRemaining;
+      return bytes.nextByte();
+    }
+
+    public void remove() {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  /**
+   * This class is the {@link RopeByteString} equivalent for
+   * {@link ByteArrayInputStream}.
+   */
+  private class RopeInputStream extends InputStream {
+    // Iterates through the pieces of the rope
+    private PieceIterator pieceIterator;
+    // The current piece
+    private LiteralByteString currentPiece;
+    // The size of the current piece
+    private int currentPieceSize;
+    // The index of the next byte to read in the current piece
+    private int currentPieceIndex;
+    // The offset of the start of the current piece in the rope byte string
+    private int currentPieceOffsetInRope;
+    // Offset in the buffer at which user called mark();
+    private int mark;
+
+    public RopeInputStream() {
+      initialize();
+    }
+
+    @Override
+    public int read(byte b[], int offset, int length)  {
+      if (b == null) {
+        throw new NullPointerException();
+      } else if (offset < 0 || length < 0 || length > b.length - offset) {
+        throw new IndexOutOfBoundsException();
+      }
+      return readSkipInternal(b, offset, length);
+    }
+
+    @Override
+    public long skip(long length) {
+      if (length < 0) {
+        throw new IndexOutOfBoundsException();
+      } else if (length > Integer.MAX_VALUE) {
+        length = Integer.MAX_VALUE;
+      }
+      return readSkipInternal(null, 0, (int) length);
+    }
+
+    /**
+     * Internal implementation of read and skip.  If b != null, then read the
+     * next {@code length} bytes into the buffer {@code b} at
+     * offset {@code offset}.  If b == null, then skip the next {@code length)
+     * bytes.
+     * <p>
+     * This method assumes that all error checking has already happened.
+     * <p>
+     * Returns the actual number of bytes read or skipped.
+     */
+    private int readSkipInternal(byte b[], int offset, int length)  {
+      int bytesRemaining = length;
+      while (bytesRemaining > 0) {
+        advanceIfCurrentPieceFullyRead();
+        if (currentPiece == null) {
+          if (bytesRemaining == length) {
+             // We didn't manage to read anything
+             return -1;
+           }
+          break;
+        } else {
+          // Copy the bytes from this piece.
+          int currentPieceRemaining = currentPieceSize - currentPieceIndex;
+          int count = Math.min(currentPieceRemaining, bytesRemaining);
+          if (b != null) {
+            currentPiece.copyTo(b, currentPieceIndex, offset, count);
+            offset += count;
+          }
+          currentPieceIndex += count;
+          bytesRemaining -= count;
+        }
+      }
+       // Return the number of bytes read.
+      return length - bytesRemaining;
+    }
+
+    @Override
+    public int read() throws IOException {
+      advanceIfCurrentPieceFullyRead();
+      if (currentPiece == null) {
+        return -1;
+      } else {
+        return currentPiece.byteAt(currentPieceIndex++) & 0xFF;
+      }
+    }
+
+    @Override
+    public int available() throws IOException {
+      int bytesRead = currentPieceOffsetInRope + currentPieceIndex;
+      return RopeByteString.this.size() - bytesRead;
+    }
+
+    @Override
+    public boolean markSupported() {
+      return true;
+    }
+
+    @Override
+    public void mark(int readAheadLimit) {
+      // Set the mark to our position in the byte string
+      mark = currentPieceOffsetInRope + currentPieceIndex;
+    }
+
+    @Override
+    public synchronized void reset() {
+      // Just reinitialize and skip the specified number of bytes.
+      initialize();
+      readSkipInternal(null, 0, mark);
+    }
+
+    /** Common initialization code used by both the constructor and reset() */
+    private void initialize() {
+      pieceIterator = new PieceIterator(RopeByteString.this);
+      currentPiece = pieceIterator.next();
+      currentPieceSize = currentPiece.size();
+      currentPieceIndex = 0;
+      currentPieceOffsetInRope = 0;
+    }
+
+    /**
+     * Skips to the next piece if we have read all the data in the current
+     * piece.  Sets currentPiece to null if we have reached the end of the
+     * input.
+     */
+    private void advanceIfCurrentPieceFullyRead() {
+      if (currentPiece != null && currentPieceIndex == currentPieceSize) {
+        // Generally, we can only go through this loop at most once, since
+        // empty strings can't end up in a rope.  But better to test.
+        currentPieceOffsetInRope += currentPieceSize;
+        currentPieceIndex = 0;
+        if (pieceIterator.hasNext()) {
+          currentPiece = pieceIterator.next();
+          currentPieceSize = currentPiece.size();
+        } else {
+          currentPiece = null;
+          currentPieceSize = 0;
+        }
+      }
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/RpcCallback.java b/protobuf/java/src/main/java/com/google/protobuf/RpcCallback.java
new file mode 100644
index 0000000..1075296
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/RpcCallback.java
@@ -0,0 +1,47 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Interface for an RPC callback, normally called when an RPC completes.
+ * {@code ParameterType} is normally the method's response message type.
+ *
+ * <p>Starting with version 2.3.0, RPC implementations should not try to build
+ * on this, but should instead provide code generator plugins which generate
+ * code specific to the particular RPC implementation.  This way the generated
+ * code can be more appropriate for the implementation in use and can avoid
+ * unnecessary layers of indirection.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface RpcCallback<ParameterType> {
+  void run(ParameterType parameter);
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/RpcChannel.java b/protobuf/java/src/main/java/com/google/protobuf/RpcChannel.java
new file mode 100644
index 0000000..f272f4a
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/RpcChannel.java
@@ -0,0 +1,71 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * <p>Abstract interface for an RPC channel.  An {@code RpcChannel} represents a
+ * communication line to a {@link Service} which can be used to call that
+ * {@link Service}'s methods.  The {@link Service} may be running on another
+ * machine.  Normally, you should not call an {@code RpcChannel} directly, but
+ * instead construct a stub {@link Service} wrapping it.  Example:
+ *
+ * <pre>
+ *   RpcChannel channel = rpcImpl.newChannel("remotehost.example.com:1234");
+ *   RpcController controller = rpcImpl.newController();
+ *   MyService service = MyService.newStub(channel);
+ *   service.myMethod(controller, request, callback);
+ * </pre>
+ *
+ * <p>Starting with version 2.3.0, RPC implementations should not try to build
+ * on this, but should instead provide code generator plugins which generate
+ * code specific to the particular RPC implementation.  This way the generated
+ * code can be more appropriate for the implementation in use and can avoid
+ * unnecessary layers of indirection.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface RpcChannel {
+  /**
+   * Call the given method of the remote service.  This method is similar to
+   * {@code Service.callMethod()} with one important difference:  the caller
+   * decides the types of the {@code Message} objects, not the callee.  The
+   * request may be of any type as long as
+   * {@code request.getDescriptor() == method.getInputType()}.
+   * The response passed to the callback will be of the same type as
+   * {@code responsePrototype} (which must have
+   * {@code getDescriptor() == method.getOutputType()}).
+   */
+  void callMethod(Descriptors.MethodDescriptor method,
+                  RpcController controller,
+                  Message request,
+                  Message responsePrototype,
+                  RpcCallback<Message> done);
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/RpcController.java b/protobuf/java/src/main/java/com/google/protobuf/RpcController.java
new file mode 100644
index 0000000..a92dd7b
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/RpcController.java
@@ -0,0 +1,118 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * <p>An {@code 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.
+ *
+ * <p>Starting with version 2.3.0, RPC implementations should not try to build
+ * on this, but should instead provide code generator plugins which generate
+ * code specific to the particular RPC implementation.  This way the generated
+ * code can be more appropriate for the implementation in use and can avoid
+ * unnecessary layers of indirection.
+ *
+ * <p>The methods provided by the {@code 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).
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface RpcController {
+  // -----------------------------------------------------------------
+  // These calls may be made from the client side only.  Their results
+  // are undefined on the server side (may throw RuntimeExceptions).
+
+  /**
+   * Resets the RpcController to its initial state so that it may be reused in
+   * a new call.  This can be called from the client side only.  It must not
+   * be called while an RPC is in progress.
+   */
+  void reset();
+
+  /**
+   * After a call has finished, returns true if the call failed.  The possible
+   * reasons for failure depend on the RPC implementation.  {@code failed()}
+   * most only be called on the client side, and must not be called before a
+   * call has finished.
+   */
+  boolean failed();
+
+  /**
+   * If {@code failed()} is {@code true}, returns a human-readable description
+   * of the error.
+   */
+  String errorText();
+
+  /**
+   * 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.
+   */
+  void startCancel();
+
+  // -----------------------------------------------------------------
+  // These calls may be made from the server side only.  Their results
+  // are undefined on the client side (may throw RuntimeExceptions).
+
+  /**
+   * Causes {@code failed()} to return true on the client side.  {@code reason}
+   * will be incorporated into the message returned by {@code 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 {@code setFailed()}.
+   */
+  void setFailed(String reason);
+
+  /**
+   * If {@code true}, indicates that the client canceled the RPC, so the server
+   * may as well give up on replying to it.  This method must be called on the
+   * server side only.  The server should still call the final "done" callback.
+   */
+  boolean isCanceled();
+
+  /**
+   * Asks that the given callback be called when the RPC is canceled.  The
+   * parameter passed to the callback will always be {@code null}.  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.
+   *
+   * <p>{@code notifyOnCancel()} must be called no more than once per request.
+   * It must be called on the server side only.
+   */
+  void notifyOnCancel(RpcCallback<Object> callback);
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/RpcUtil.java b/protobuf/java/src/main/java/com/google/protobuf/RpcUtil.java
new file mode 100644
index 0000000..694b8d1
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/RpcUtil.java
@@ -0,0 +1,134 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Grab-bag of utility functions useful when dealing with RPCs.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class RpcUtil {
+  private RpcUtil() {}
+
+  /**
+   * Take an {@code RpcCallback<Message>} and convert it to an
+   * {@code RpcCallback} accepting a specific message type.  This is always
+   * type-safe (parameter type contravariance).
+   */
+  @SuppressWarnings("unchecked")
+  public static <Type extends Message> RpcCallback<Type>
+  specializeCallback(final RpcCallback<Message> originalCallback) {
+    return (RpcCallback<Type>)originalCallback;
+    // The above cast works, but only due to technical details of the Java
+    // implementation.  A more theoretically correct -- but less efficient --
+    // implementation would be as follows:
+    //   return new RpcCallback<Type>() {
+    //     public void run(Type parameter) {
+    //       originalCallback.run(parameter);
+    //     }
+    //   };
+  }
+
+  /**
+   * Take an {@code RpcCallback} accepting a specific message type and convert
+   * it to an {@code RpcCallback<Message>}.  The generalized callback will
+   * accept any message object which has the same descriptor, and will convert
+   * it to the correct class before calling the original callback.  However,
+   * if the generalized callback is given a message with a different descriptor,
+   * an exception will be thrown.
+   */
+  public static <Type extends Message>
+  RpcCallback<Message> generalizeCallback(
+      final RpcCallback<Type> originalCallback,
+      final Class<Type> originalClass,
+      final Type defaultInstance) {
+    return new RpcCallback<Message>() {
+      public void run(final Message parameter) {
+        Type typedParameter;
+        try {
+          typedParameter = originalClass.cast(parameter);
+        } catch (ClassCastException ignored) {
+          typedParameter = copyAsType(defaultInstance, parameter);
+        }
+        originalCallback.run(typedParameter);
+      }
+    };
+  }
+
+  /**
+   * Creates a new message of type "Type" which is a copy of "source".  "source"
+   * must have the same descriptor but may be a different class (e.g.
+   * DynamicMessage).
+   */
+  @SuppressWarnings("unchecked")
+  private static <Type extends Message> Type copyAsType(
+      final Type typeDefaultInstance, final Message source) {
+    return (Type) typeDefaultInstance
+        .newBuilderForType().mergeFrom(source).build();
+  }
+
+  /**
+   * Creates a callback which can only be called once.  This may be useful for
+   * security, when passing a callback to untrusted code:  most callbacks do
+   * not expect to be called more than once, so doing so may expose bugs if it
+   * is not prevented.
+   */
+  public static <ParameterType>
+    RpcCallback<ParameterType> newOneTimeCallback(
+      final RpcCallback<ParameterType> originalCallback) {
+    return new RpcCallback<ParameterType>() {
+      private boolean alreadyCalled = false;
+
+      public void run(final ParameterType parameter) {
+        synchronized(this) {
+          if (alreadyCalled) {
+            throw new AlreadyCalledException();
+          }
+          alreadyCalled = true;
+        }
+
+        originalCallback.run(parameter);
+      }
+    };
+  }
+
+  /**
+   * Exception thrown when a one-time callback is called more than once.
+   */
+  public static final class AlreadyCalledException extends RuntimeException {
+    private static final long serialVersionUID = 5469741279507848266L;
+
+    public AlreadyCalledException() {
+      super("This RpcCallback was already called and cannot be called " +
+            "multiple times.");
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/Service.java b/protobuf/java/src/main/java/com/google/protobuf/Service.java
new file mode 100644
index 0000000..ba7b033
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/Service.java
@@ -0,0 +1,117 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Abstract base interface for protocol-buffer-based RPC services.  Services
+ * themselves are abstract classes (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 the Message interface).
+ *
+ * <p>Starting with version 2.3.0, RPC implementations should not try to build
+ * on this, but should instead provide code generator plugins which generate
+ * code specific to the particular RPC implementation.  This way the generated
+ * code can be more appropriate for the implementation in use and can avoid
+ * unnecessary layers of indirection.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public interface Service {
+  /**
+   * Get the {@code ServiceDescriptor} describing this service and its methods.
+   */
+  Descriptors.ServiceDescriptor getDescriptorForType();
+
+  /**
+   * <p>Call a method of the service specified by MethodDescriptor.  This is
+   * normally implemented as a simple {@code switch()} that calls the standard
+   * definitions of the service's methods.
+   *
+   * <p>Preconditions:
+   * <ul>
+   *   <li>{@code method.getService() == getDescriptorForType()}
+   *   <li>{@code request} is of the exact same class as the object returned by
+   *       {@code getRequestPrototype(method)}.
+   *   <li>{@code 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
+   *       {@code RpcController} the server-side RPC implementation uses.
+   * </ul>
+   *
+   * <p>Postconditions:
+   * <ul>
+   *   <li>{@code done} will be called when the method is complete.  This may be
+   *       before {@code callMethod()} returns or it may be at some point in
+   *       the future.
+   *   <li>The parameter to {@code done} is the response.  It must be of the
+   *       exact same type as would be returned by
+   *       {@code getResponsePrototype(method)}.
+   *   <li>If the RPC failed, the parameter to {@code done} will be
+   *       {@code null}.  Further details about the failure can be found by
+   *       querying {@code controller}.
+   * </ul>
+   */
+  void callMethod(Descriptors.MethodDescriptor method,
+                  RpcController controller,
+                  Message request,
+                  RpcCallback<Message> done);
+
+  /**
+   * <p>{@code callMethod()} requires that the request passed in is of a
+   * particular subclass of {@code Message}.  {@code getRequestPrototype()}
+   * gets the default instances of this type for a given method.  You can then
+   * call {@code Message.newBuilderForType()} on this instance to
+   * construct a builder to build an object which you can then pass to
+   * {@code callMethod()}.
+   *
+   * <p>Example:
+   * <pre>
+   *   MethodDescriptor method =
+   *     service.getDescriptorForType().findMethodByName("Foo");
+   *   Message request =
+   *     stub.getRequestPrototype(method).newBuilderForType()
+   *         .mergeFrom(input).build();
+   *   service.callMethod(method, request, callback);
+   * </pre>
+   */
+  Message getRequestPrototype(Descriptors.MethodDescriptor method);
+
+  /**
+   * Like {@code getRequestPrototype()}, but gets a prototype of the response
+   * message.  {@code getResponsePrototype()} is generally not needed because
+   * the {@code Service} implementation constructs the response message itself,
+   * but it may be useful in some cases to know ahead of time what type of
+   * object will be returned.
+   */
+  Message getResponsePrototype(Descriptors.MethodDescriptor method);
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/ServiceException.java b/protobuf/java/src/main/java/com/google/protobuf/ServiceException.java
new file mode 100644
index 0000000..00d5707
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/ServiceException.java
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * Thrown by blocking RPC methods when a failure occurs.
+ *
+ * @author cpovirk@google.com (Chris Povirk)
+ */
+public class ServiceException extends Exception {
+  private static final long serialVersionUID = -1219262335729891920L;
+
+  public ServiceException(final String message) {
+    super(message);
+  }
+
+  public ServiceException(final Throwable cause) {
+    super(cause);
+  }
+
+  public ServiceException(final String message, final Throwable cause) {
+    super(message, cause);
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java b/protobuf/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java
new file mode 100644
index 0000000..13a36d4
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/SingleFieldBuilder.java
@@ -0,0 +1,241 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * {@code SingleFieldBuilder} implements a structure that a protocol
+ * message uses to hold a single field of another protocol message. It supports
+ * the classical use case of setting an immutable {@link Message} as the value
+ * of the field and is highly optimized around this.
+ * <br>
+ * It also supports the additional use case of setting a {@link Message.Builder}
+ * as the field and deferring conversion of that {@code Builder}
+ * to an immutable {@code Message}. In this way, it's possible to maintain
+ * a tree of {@code Builder}'s that acts as a fully read/write data
+ * structure.
+ * <br>
+ * Logically, one can think of a tree of builders as converting the entire tree
+ * to messages when build is called on the root or when any method is called
+ * that desires a Message instead of a Builder. In terms of the implementation,
+ * the {@code SingleFieldBuilder} and {@code RepeatedFieldBuilder}
+ * classes cache messages that were created so that messages only need to be
+ * created when some change occured in its builder or a builder for one of its
+ * descendants.
+ *
+ * @param <MType> the type of message for the field
+ * @param <BType> the type of builder for the field
+ * @param <IType> the common interface for the message and the builder
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class SingleFieldBuilder
+    <MType extends GeneratedMessage,
+     BType extends GeneratedMessage.Builder,
+     IType extends MessageOrBuilder>
+    implements GeneratedMessage.BuilderParent {
+
+  // Parent to send changes to.
+  private GeneratedMessage.BuilderParent parent;
+
+  // Invariant: one of builder or message fields must be non-null.
+
+  // If set, this is the case where we are backed by a builder. In this case,
+  // message field represents a cached message for the builder (or null if
+  // there is no cached message).
+  private BType builder;
+
+  // If builder is non-null, this represents a cached message from the builder.
+  // If builder is null, this is the authoritative message for the field.
+  private MType message;
+
+  // Indicates that we've built a message and so we are now obligated
+  // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener.
+  private boolean isClean;
+
+  public SingleFieldBuilder(
+      MType message,
+      GeneratedMessage.BuilderParent parent,
+      boolean isClean) {
+    if (message == null) {
+      throw new NullPointerException();
+    }
+    this.message = message;
+    this.parent = parent;
+    this.isClean = isClean;
+  }
+
+  public void dispose() {
+    // Null out parent so we stop sending it invalidations.
+    parent = null;
+  }
+
+  /**
+   * Get the message for the field. If the message is currently stored
+   * as a {@code Builder}, it is converted to a {@code Message} by
+   * calling {@link Message.Builder#buildPartial} on it. If no message has
+   * been set, returns the default instance of the message.
+   *
+   * @return the message for the field
+   */
+  @SuppressWarnings("unchecked")
+  public MType getMessage() {
+    if (message == null) {
+      // If message is null, the invariant is that we must be have a builder.
+      message = (MType) builder.buildPartial();
+    }
+    return message;
+  }
+
+  /**
+   * Builds the message and returns it.
+   *
+   * @return the message
+   */
+  public MType build() {
+    // Now that build has been called, we are required to dispatch
+    // invalidations.
+    isClean = true;
+    return getMessage();
+  }
+
+  /**
+   * Gets a builder for the field. If no builder has been created yet, a
+   * builder is created on demand by calling {@link Message#toBuilder}.
+   *
+   * @return The builder for the field
+   */
+  @SuppressWarnings("unchecked")
+  public BType getBuilder() {
+    if (builder == null) {
+      // builder.mergeFrom() on a fresh builder
+      // does not create any sub-objects with independent clean/dirty states,
+      // therefore setting the builder itself to clean without actually calling
+      // build() cannot break any invariants.
+      builder = (BType) message.newBuilderForType(this);
+      builder.mergeFrom(message); // no-op if message is the default message
+      builder.markClean();
+    }
+    return builder;
+  }
+
+  /**
+   * Gets the base class interface for the field. This may either be a builder
+   * or a message. It will return whatever is more efficient.
+   *
+   * @return the message or builder for the field as the base class interface
+   */
+  @SuppressWarnings("unchecked")
+  public IType getMessageOrBuilder() {
+    if (builder != null) {
+      return  (IType) builder;
+    } else {
+      return (IType) message;
+    }
+  }
+
+  /**
+   * Sets a  message for the field replacing any existing value.
+   *
+   * @param message the message to set
+   * @return the builder
+   */
+  public SingleFieldBuilder<MType, BType, IType> setMessage(
+      MType message) {
+    if (message == null) {
+      throw new NullPointerException();
+    }
+    this.message = message;
+    if (builder != null) {
+      builder.dispose();
+      builder = null;
+    }
+    onChanged();
+    return this;
+  }
+
+  /**
+   * Merges the field from another field.
+   *
+   * @param value the value to merge from
+   * @return the builder
+   */
+  public SingleFieldBuilder<MType, BType, IType> mergeFrom(
+      MType value) {
+    if (builder == null && message == message.getDefaultInstanceForType()) {
+      message = value;
+    } else {
+      getBuilder().mergeFrom(value);
+    }
+    onChanged();
+    return this;
+  }
+
+  /**
+   * Clears the value of the field.
+   *
+   * @return the builder
+   */
+  @SuppressWarnings("unchecked")
+  public SingleFieldBuilder<MType, BType, IType> clear() {
+    message = (MType) (message != null ?
+        message.getDefaultInstanceForType() :
+        builder.getDefaultInstanceForType());
+    if (builder != null) {
+      builder.dispose();
+      builder = null;
+    }
+    onChanged();
+    return this;
+  }
+
+  /**
+   * Called when a the builder or one of its nested children has changed
+   * and any parent should be notified of its invalidation.
+   */
+  private void onChanged() {
+    // If builder is null, this is the case where onChanged is being called
+    // from setMessage or clear.
+    if (builder != null) {
+      message = null;
+    }
+    if (isClean && parent != null) {
+      parent.markDirty();
+
+      // Don't keep dispatching invalidations until build is called again.
+      isClean = false;
+    }
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public void markDirty() {
+    onChanged();
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java b/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java
new file mode 100644
index 0000000..0674d2e
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/SmallSortedMap.java
@@ -0,0 +1,618 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.TreeMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedMap;
+
+/**
+ * A custom map implementation from FieldDescriptor to Object optimized to
+ * minimize the number of memory allocations for instances with a small number
+ * of mappings. The implementation stores the first {@code k} mappings in an
+ * array for a configurable value of {@code k}, allowing direct access to the
+ * corresponding {@code Entry}s without the need to create an Iterator. The
+ * remaining entries are stored in an overflow map. Iteration over the entries
+ * in the map should be done as follows:
+ *
+ * <pre>   {@code
+ * for (int i = 0; i < fieldMap.getNumArrayEntries(); i++) {
+ *   process(fieldMap.getArrayEntryAt(i));
+ * }
+ * for (Map.Entry<K, V> entry : fieldMap.getOverflowEntries()) {
+ *   process(entry);
+ * }
+ * }</pre>
+ *
+ * The resulting iteration is in order of ascending field tag number. The
+ * object returned by {@link #entrySet()} adheres to the same contract but is
+ * less efficient as it necessarily involves creating an object for iteration.
+ * <p>
+ * The tradeoff for this memory efficiency is that the worst case running time
+ * of the {@code put()} operation is {@code O(k + lg n)}, which happens when
+ * entries are added in descending order. {@code k} should be chosen such that
+ * it covers enough common cases without adversely affecting larger maps. In
+ * practice, the worst case scenario does not happen for extensions because
+ * extension fields are serialized and deserialized in order of ascending tag
+ * number, but the worst case scenario can happen for DynamicMessages.
+ * <p>
+ * The running time for all other operations is similar to that of
+ * {@code TreeMap}.
+ * <p>
+ * Instances are not thread-safe until {@link #makeImmutable()} is called,
+ * after which any modifying operation will result in an
+ * {@link UnsupportedOperationException}.
+ *
+ * @author darick@google.com Darick Tong
+ */
+// This class is final for all intents and purposes because the constructor is
+// private. However, the FieldDescriptor-specific logic is encapsulated in
+// a subclass to aid testability of the core logic.
+class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
+
+  /**
+   * Creates a new instance for mapping FieldDescriptors to their values.
+   * The {@link #makeImmutable()} implementation will convert the List values
+   * of any repeated fields to unmodifiable lists.
+   *
+   * @param arraySize The size of the entry array containing the
+   *        lexicographically smallest mappings.
+   */
+  static <FieldDescriptorType extends
+      FieldSet.FieldDescriptorLite<FieldDescriptorType>>
+      SmallSortedMap<FieldDescriptorType, Object> newFieldMap(int arraySize) {
+    return new SmallSortedMap<FieldDescriptorType, Object>(arraySize) {
+      @Override
+      @SuppressWarnings("unchecked")
+      public void makeImmutable() {
+        if (!isImmutable()) {
+          for (int i = 0; i < getNumArrayEntries(); i++) {
+            final Map.Entry<FieldDescriptorType, Object> entry =
+                getArrayEntryAt(i);
+            if (entry.getKey().isRepeated()) {
+              final List value = (List) entry.getValue();
+              entry.setValue(Collections.unmodifiableList(value));
+            }
+          }
+          for (Map.Entry<FieldDescriptorType, Object> entry :
+                   getOverflowEntries()) {
+            if (entry.getKey().isRepeated()) {
+              final List value = (List) entry.getValue();
+              entry.setValue(Collections.unmodifiableList(value));
+            }
+          }
+        }
+        super.makeImmutable();
+      }
+    };
+  }
+
+  /**
+   * Creates a new instance for testing.
+   *
+   * @param arraySize The size of the entry array containing the
+   *        lexicographically smallest mappings.
+   */
+  static <K extends Comparable<K>, V> SmallSortedMap<K, V> newInstanceForTest(
+      int arraySize) {
+    return new SmallSortedMap<K, V>(arraySize);
+  }
+
+  private final int maxArraySize;
+  // The "entry array" is actually a List because generic arrays are not
+  // allowed. ArrayList also nicely handles the entry shifting on inserts and
+  // removes.
+  private List<Entry> entryList;
+  private Map<K, V> overflowEntries;
+  private boolean isImmutable;
+  // The EntrySet is a stateless view of the Map. It's initialized the first
+  // time it is requested and reused henceforth.
+  private volatile EntrySet lazyEntrySet;
+
+  /**
+   * @code arraySize Size of the array in which the lexicographically smallest
+   *       mappings are stored. (i.e. the {@code k} referred to in the class
+   *       documentation).
+   */
+  private SmallSortedMap(int arraySize) {
+    this.maxArraySize = arraySize;
+    this.entryList = Collections.emptyList();
+    this.overflowEntries = Collections.emptyMap();
+  }
+
+  /** Make this map immutable from this point forward. */
+  public void makeImmutable() {
+    if (!isImmutable) {
+      // Note: There's no need to wrap the entryList in an unmodifiableList
+      // because none of the list's accessors are exposed. The iterator() of
+      // overflowEntries, on the other hand, is exposed so it must be made
+      // unmodifiable.
+      overflowEntries = overflowEntries.isEmpty() ?
+          Collections.<K, V>emptyMap() :
+          Collections.unmodifiableMap(overflowEntries);
+      isImmutable = true;
+    }
+  }
+
+  /** @return Whether {@link #makeImmutable()} has been called. */
+  public boolean isImmutable() {
+    return isImmutable;
+  }
+
+  /** @return The number of entries in the entry array. */
+  public int getNumArrayEntries() {
+    return entryList.size();
+  }
+
+  /** @return The array entry at the given {@code index}. */
+  public Map.Entry<K, V> getArrayEntryAt(int index) {
+    return entryList.get(index);
+  }
+
+  /** @return There number of overflow entries. */
+  public int getNumOverflowEntries() {
+    return overflowEntries.size();
+  }
+
+  /** @return An iterable over the overflow entries. */
+  public Iterable<Map.Entry<K, V>> getOverflowEntries() {
+    return overflowEntries.isEmpty() ?
+        EmptySet.<Map.Entry<K, V>>iterable() :
+        overflowEntries.entrySet();
+  }
+
+  @Override
+  public int size() {
+    return entryList.size() + overflowEntries.size();
+  }
+
+  /**
+   * The implementation throws a {@code ClassCastException} if o is not an
+   * object of type {@code K}.
+   *
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean containsKey(Object o) {
+    @SuppressWarnings("unchecked")
+    final K key = (K) o;
+    return binarySearchInArray(key) >= 0 || overflowEntries.containsKey(key);
+  }
+
+  /**
+   * The implementation throws a {@code ClassCastException} if o is not an
+   * object of type {@code K}.
+   *
+   * {@inheritDoc}
+   */
+  @Override
+  public V get(Object o) {
+    @SuppressWarnings("unchecked")
+    final K key = (K) o;
+    final int index = binarySearchInArray(key);
+    if (index >= 0) {
+      return entryList.get(index).getValue();
+    }
+    return overflowEntries.get(key);
+  }
+
+  @Override
+  public V put(K key, V value) {
+    checkMutable();
+    final int index = binarySearchInArray(key);
+    if (index >= 0) {
+      // Replace existing array entry.
+      return entryList.get(index).setValue(value);
+    }
+    ensureEntryArrayMutable();
+    final int insertionPoint = -(index + 1);
+    if (insertionPoint >= maxArraySize) {
+      // Put directly in overflow.
+      return getOverflowEntriesMutable().put(key, value);
+    }
+    // Insert new Entry in array.
+    if (entryList.size() == maxArraySize) {
+      // Shift the last array entry into overflow.
+      final Entry lastEntryInArray = entryList.remove(maxArraySize - 1);
+      getOverflowEntriesMutable().put(lastEntryInArray.getKey(),
+                                      lastEntryInArray.getValue());
+    }
+    entryList.add(insertionPoint, new Entry(key, value));
+    return null;
+  }
+
+  @Override
+  public void clear() {
+    checkMutable();
+    if (!entryList.isEmpty()) {
+      entryList.clear();
+    }
+    if (!overflowEntries.isEmpty()) {
+      overflowEntries.clear();
+    }
+  }
+
+  /**
+   * The implementation throws a {@code ClassCastException} if o is not an
+   * object of type {@code K}.
+   *
+   * {@inheritDoc}
+   */
+  @Override
+  public V remove(Object o) {
+    checkMutable();
+    @SuppressWarnings("unchecked")
+    final K key = (K) o;
+    final int index = binarySearchInArray(key);
+    if (index >= 0) {
+      return removeArrayEntryAt(index);
+    }
+    // overflowEntries might be Collections.unmodifiableMap(), so only
+    // call remove() if it is non-empty.
+    if (overflowEntries.isEmpty()) {
+      return null;
+    } else {
+      return overflowEntries.remove(key);
+    }
+  }
+
+  private V removeArrayEntryAt(int index) {
+    checkMutable();
+    final V removed = entryList.remove(index).getValue();
+    if (!overflowEntries.isEmpty()) {
+      // Shift the first entry in the overflow to be the last entry in the
+      // array.
+      final Iterator<Map.Entry<K, V>> iterator =
+          getOverflowEntriesMutable().entrySet().iterator();
+      entryList.add(new Entry(iterator.next()));
+      iterator.remove();
+    }
+    return removed;
+  }
+
+  /**
+   * @param key The key to find in the entry array.
+   * @return The returned integer position follows the same semantics as the
+   *     value returned by {@link java.util.Arrays#binarySearch()}.
+   */
+  private int binarySearchInArray(K key) {
+    int left = 0;
+    int right = entryList.size() - 1;
+
+    // Optimization: For the common case in which entries are added in
+    // ascending tag order, check the largest element in the array before
+    // doing a full binary search.
+    if (right >= 0) {
+      int cmp = key.compareTo(entryList.get(right).getKey());
+      if (cmp > 0) {
+        return -(right + 2);  // Insert point is after "right".
+      } else if (cmp == 0) {
+        return right;
+      }
+    }
+
+    while (left <= right) {
+      int mid = (left + right) / 2;
+      int cmp = key.compareTo(entryList.get(mid).getKey());
+      if (cmp < 0) {
+        right = mid - 1;
+      } else if (cmp > 0) {
+        left = mid + 1;
+      } else {
+        return mid;
+      }
+    }
+    return -(left + 1);
+  }
+
+  /**
+   * Similar to the AbstractMap implementation of {@code keySet()} and
+   * {@code values()}, the entry set is created the first time this method is
+   * called, and returned in response to all subsequent calls.
+   *
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Map.Entry<K, V>> entrySet() {
+    if (lazyEntrySet == null) {
+      lazyEntrySet = new EntrySet();
+    }
+    return lazyEntrySet;
+  }
+
+  /**
+   * @throws UnsupportedOperationException if {@link #makeImmutable()} has
+   *         has been called.
+   */
+  private void checkMutable() {
+    if (isImmutable) {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  /**
+   * @return a {@link SortedMap} to which overflow entries mappings can be
+   *         added or removed.
+   * @throws UnsupportedOperationException if {@link #makeImmutable()} has been
+   *         called.
+   */
+  @SuppressWarnings("unchecked")
+  private SortedMap<K, V> getOverflowEntriesMutable() {
+    checkMutable();
+    if (overflowEntries.isEmpty() && !(overflowEntries instanceof TreeMap)) {
+      overflowEntries = new TreeMap<K, V>();
+    }
+    return (SortedMap<K, V>) overflowEntries;
+  }
+
+  /**
+   * Lazily creates the entry list. Any code that adds to the list must first
+   * call this method.
+   */
+  private void ensureEntryArrayMutable() {
+    checkMutable();
+    if (entryList.isEmpty() && !(entryList instanceof ArrayList)) {
+      entryList = new ArrayList<Entry>(maxArraySize);
+    }
+  }
+
+  /**
+   * Entry implementation that implements Comparable in order to support
+   * binary search within the entry array. Also checks mutability in
+   * {@link #setValue()}.
+   */
+  private class Entry implements Map.Entry<K, V>, Comparable<Entry> {
+
+    private final K key;
+    private V value;
+
+    Entry(Map.Entry<K, V> copy) {
+      this(copy.getKey(), copy.getValue());
+    }
+
+    Entry(K key, V value) {
+      this.key = key;
+      this.value = value;
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public K getKey() {
+      return key;
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public V getValue() {
+      return value;
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public int compareTo(Entry other) {
+      return getKey().compareTo(other.getKey());
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public V setValue(V newValue) {
+      checkMutable();
+      final V oldValue = this.value;
+      this.value = newValue;
+      return oldValue;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (o == this) {
+        return true;
+      }
+      if (!(o instanceof Map.Entry)) {
+        return false;
+      }
+      @SuppressWarnings("unchecked")
+      Map.Entry<?, ?> other = (Map.Entry<?, ?>) o;
+      return equals(key, other.getKey()) && equals(value, other.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+      return (key == null ? 0 : key.hashCode()) ^
+          (value == null ? 0 : value.hashCode());
+    }
+
+    @Override
+    public String toString() {
+      return key + "=" + value;
+    }
+
+    /** equals() that handles null values. */
+    private boolean equals(Object o1, Object o2) {
+      return o1 == null ? o2 == null : o1.equals(o2);
+    }
+  }
+
+  /**
+   * Stateless view of the entries in the field map.
+   */
+  private class EntrySet extends AbstractSet<Map.Entry<K, V>> {
+
+    @Override
+    public Iterator<Map.Entry<K, V>> iterator() {
+      return new EntryIterator();
+    }
+
+    @Override
+    public int size() {
+      return SmallSortedMap.this.size();
+    }
+
+    /**
+     * Throws a {@link ClassCastException} if o is not of the expected type.
+     *
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean contains(Object o) {
+      @SuppressWarnings("unchecked")
+      final Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
+      final V existing = get(entry.getKey());
+      final V value = entry.getValue();
+      return existing == value ||
+          (existing != null && existing.equals(value));
+    }
+
+    @Override
+    public boolean add(Map.Entry<K, V> entry) {
+      if (!contains(entry)) {
+        put(entry.getKey(), entry.getValue());
+        return true;
+      }
+      return false;
+    }
+
+    /**
+     * Throws a {@link ClassCastException} if o is not of the expected type.
+     *
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean remove(Object o) {
+      @SuppressWarnings("unchecked")
+      final Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
+      if (contains(entry)) {
+        SmallSortedMap.this.remove(entry.getKey());
+        return true;
+      }
+      return false;
+    }
+
+    @Override
+    public void clear() {
+      SmallSortedMap.this.clear();
+    }
+  }
+
+  /**
+   * Iterator implementation that switches from the entry array to the overflow
+   * entries appropriately.
+   */
+  private class EntryIterator implements Iterator<Map.Entry<K, V>> {
+
+    private int pos = -1;
+    private boolean nextCalledBeforeRemove;
+    private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public boolean hasNext() {
+      return (pos + 1) < entryList.size() ||
+          getOverflowIterator().hasNext();
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public Map.Entry<K, V> next() {
+      nextCalledBeforeRemove = true;
+      // Always increment pos so that we know whether the last returned value
+      // was from the array or from overflow.
+      if (++pos < entryList.size()) {
+        return entryList.get(pos);
+      }
+      return getOverflowIterator().next();
+    }
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public void remove() {
+      if (!nextCalledBeforeRemove) {
+        throw new IllegalStateException("remove() was called before next()");
+      }
+      nextCalledBeforeRemove = false;
+      checkMutable();
+
+      if (pos < entryList.size()) {
+        removeArrayEntryAt(pos--);
+      } else {
+        getOverflowIterator().remove();
+      }
+    }
+
+    /**
+     * It is important to create the overflow iterator only after the array
+     * entries have been iterated over because the overflow entry set changes
+     * when the client calls remove() on the array entries, which invalidates
+     * any existing iterators.
+     */
+    private Iterator<Map.Entry<K, V>> getOverflowIterator() {
+      if (lazyOverflowIterator == null) {
+        lazyOverflowIterator = overflowEntries.entrySet().iterator();
+      }
+      return lazyOverflowIterator;
+    }
+  }
+
+  /**
+   * Helper class that holds immutable instances of an Iterable/Iterator that
+   * we return when the overflow entries is empty. This eliminates the creation
+   * of an Iterator object when there is nothing to iterate over.
+   */
+  private static class EmptySet {
+
+    private static final Iterator<Object> ITERATOR = new Iterator<Object>() {
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public boolean hasNext() {
+        return false;
+      }
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public Object next() {
+        throw new NoSuchElementException();
+      }
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public void remove() {
+        throw new UnsupportedOperationException();
+      }
+    };
+
+    private static final Iterable<Object> ITERABLE = new Iterable<Object>() {
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public Iterator<Object> iterator() {
+        return ITERATOR;
+      }
+    };
+
+    @SuppressWarnings("unchecked")
+    static <T> Iterable<T> iterable() {
+      return (Iterable<T>) ITERABLE;
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/TextFormat.java b/protobuf/java/src/main/java/com/google/protobuf/TextFormat.java
new file mode 100644
index 0000000..57d0ca6
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/TextFormat.java
@@ -0,0 +1,1984 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.nio.CharBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Provide text parsing and formatting support for proto2 instances.
+ * The implementation largely follows google/protobuf/text_format.cc.
+ *
+ * @author wenboz@google.com Wenbo Zhu
+ * @author kenton@google.com Kenton Varda
+ */
+public final class TextFormat {
+  private TextFormat() {}
+
+  private static final Logger logger =
+      Logger.getLogger(TextFormat.class.getName());
+
+  private static final Printer DEFAULT_PRINTER = new Printer();
+  private static final Printer SINGLE_LINE_PRINTER =
+      (new Printer()).setSingleLineMode(true);
+  private static final Printer UNICODE_PRINTER =
+      (new Printer()).setEscapeNonAscii(false);
+
+  /**
+   * Outputs a textual representation of the Protocol Message supplied into
+   * the parameter output. (This representation is the new version of the
+   * classic "ProtocolPrinter" output from the original Protocol Buffer system)
+   */
+  public static void print(
+      final MessageOrBuilder message, final Appendable output)
+      throws IOException {
+    DEFAULT_PRINTER.print(message, new TextGenerator(output));
+  }
+
+  /** Outputs a textual representation of {@code fields} to {@code output}. */
+  public static void print(final UnknownFieldSet fields,
+                           final Appendable output)
+                           throws IOException {
+    DEFAULT_PRINTER.printUnknownFields(fields, new TextGenerator(output));
+  }
+
+  /**
+   * Same as {@code print()}, except that non-ASCII characters are not
+   * escaped.
+   */
+  public static void printUnicode(
+      final MessageOrBuilder message, final Appendable output)
+      throws IOException {
+    UNICODE_PRINTER.print(message, new TextGenerator(output));
+  }
+
+  /**
+   * Same as {@code print()}, except that non-ASCII characters are not
+   * escaped.
+   */
+  public static void printUnicode(final UnknownFieldSet fields,
+                                  final Appendable output)
+                                  throws IOException {
+    UNICODE_PRINTER.printUnknownFields(fields, new TextGenerator(output));
+  }
+
+  /**
+   * Generates a human readable form of this message, useful for debugging and
+   * other purposes, with no newline characters.
+   */
+  public static String shortDebugString(final MessageOrBuilder message) {
+    try {
+      final StringBuilder sb = new StringBuilder();
+      SINGLE_LINE_PRINTER.print(message, new TextGenerator(sb));
+      // Single line mode currently might have an extra space at the end.
+      return sb.toString().trim();
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  /**
+   * Generates a human readable form of the unknown fields, useful for debugging
+   * and other purposes, with no newline characters.
+   */
+  public static String shortDebugString(final UnknownFieldSet fields) {
+    try {
+      final StringBuilder sb = new StringBuilder();
+      SINGLE_LINE_PRINTER.printUnknownFields(fields, new TextGenerator(sb));
+      // Single line mode currently might have an extra space at the end.
+      return sb.toString().trim();
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  /**
+   * Like {@code print()}, but writes directly to a {@code String} and
+   * returns it.
+   */
+  public static String printToString(final MessageOrBuilder message) {
+    try {
+      final StringBuilder text = new StringBuilder();
+      print(message, text);
+      return text.toString();
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  /**
+   * Like {@code print()}, but writes directly to a {@code String} and
+   * returns it.
+   */
+  public static String printToString(final UnknownFieldSet fields) {
+    try {
+      final StringBuilder text = new StringBuilder();
+      print(fields, text);
+      return text.toString();
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  /**
+   * Same as {@code printToString()}, except that non-ASCII characters
+   * in string type fields are not escaped in backslash+octals.
+   */
+  public static String printToUnicodeString(final MessageOrBuilder message) {
+    try {
+      final StringBuilder text = new StringBuilder();
+      UNICODE_PRINTER.print(message, new TextGenerator(text));
+      return text.toString();
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  /**
+   * Same as {@code printToString()}, except that non-ASCII characters
+   * in string type fields are not escaped in backslash+octals.
+   */
+  public static String printToUnicodeString(final UnknownFieldSet fields) {
+    try {
+      final StringBuilder text = new StringBuilder();
+      UNICODE_PRINTER.printUnknownFields(fields, new TextGenerator(text));
+      return text.toString();
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  public static void printField(final FieldDescriptor field,
+                                final Object value,
+                                final Appendable output)
+                                throws IOException {
+    DEFAULT_PRINTER.printField(field, value, new TextGenerator(output));
+  }
+
+  public static String printFieldToString(final FieldDescriptor field,
+                                          final Object value) {
+    try {
+      final StringBuilder text = new StringBuilder();
+      printField(field, value, text);
+      return text.toString();
+    } catch (IOException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  /**
+   * Outputs a textual representation of the value of given field value.
+   *
+   * @param field the descriptor of the field
+   * @param value the value of the field
+   * @param output the output to which to append the formatted value
+   * @throws ClassCastException if the value is not appropriate for the
+   *     given field descriptor
+   * @throws IOException if there is an exception writing to the output
+   */
+  public static void printFieldValue(final FieldDescriptor field,
+                                     final Object value,
+                                     final Appendable output)
+                                     throws IOException {
+    DEFAULT_PRINTER.printFieldValue(field, value, new TextGenerator(output));
+  }
+
+  /**
+   * Outputs a textual representation of the value of an unknown field.
+   *
+   * @param tag the field's tag number
+   * @param value the value of the field
+   * @param output the output to which to append the formatted value
+   * @throws ClassCastException if the value is not appropriate for the
+   *     given field descriptor
+   * @throws IOException if there is an exception writing to the output
+   */
+  public static void printUnknownFieldValue(final int tag,
+                                            final Object value,
+                                            final Appendable output)
+                                            throws IOException {
+    printUnknownFieldValue(tag, value, new TextGenerator(output));
+  }
+
+  private static void printUnknownFieldValue(final int tag,
+                                             final Object value,
+                                             final TextGenerator generator)
+                                             throws IOException {
+    switch (WireFormat.getTagWireType(tag)) {
+      case WireFormat.WIRETYPE_VARINT:
+        generator.print(unsignedToString((Long) value));
+        break;
+      case WireFormat.WIRETYPE_FIXED32:
+        generator.print(
+            String.format((Locale) null, "0x%08x", (Integer) value));
+        break;
+      case WireFormat.WIRETYPE_FIXED64:
+        generator.print(String.format((Locale) null, "0x%016x", (Long) value));
+        break;
+      case WireFormat.WIRETYPE_LENGTH_DELIMITED:
+        generator.print("\"");
+        generator.print(escapeBytes((ByteString) value));
+        generator.print("\"");
+        break;
+      case WireFormat.WIRETYPE_START_GROUP:
+        DEFAULT_PRINTER.printUnknownFields((UnknownFieldSet) value, generator);
+        break;
+      default:
+        throw new IllegalArgumentException("Bad tag: " + tag);
+    }
+  }
+
+  /** Helper class for converting protobufs to text. */
+  private static final class Printer {
+    /** Whether to omit newlines from the output. */
+    boolean singleLineMode = false;
+
+    /** Whether to escape non ASCII characters with backslash and octal. */
+    boolean escapeNonAscii = true;
+
+    private Printer() {}
+
+    /** Setter of singleLineMode */
+    private Printer setSingleLineMode(boolean singleLineMode) {
+      this.singleLineMode = singleLineMode;
+      return this;
+    }
+
+    /** Setter of escapeNonAscii */
+    private Printer setEscapeNonAscii(boolean escapeNonAscii) {
+      this.escapeNonAscii = escapeNonAscii;
+      return this;
+    }
+
+    private void print(
+        final MessageOrBuilder message, final TextGenerator generator)
+        throws IOException {
+      for (Map.Entry<FieldDescriptor, Object> field
+          : message.getAllFields().entrySet()) {
+        printField(field.getKey(), field.getValue(), generator);
+      }
+      printUnknownFields(message.getUnknownFields(), generator);
+    }
+
+    private void printField(final FieldDescriptor field, final Object value,
+        final TextGenerator generator) throws IOException {
+      if (field.isRepeated()) {
+        // Repeated field.  Print each element.
+        for (Object element : (List<?>) value) {
+          printSingleField(field, element, generator);
+        }
+      } else {
+        printSingleField(field, value, generator);
+      }
+    }
+
+    private void printSingleField(final FieldDescriptor field,
+                                  final Object value,
+                                  final TextGenerator generator)
+                                  throws IOException {
+      if (field.isExtension()) {
+        generator.print("[");
+        // We special-case MessageSet elements for compatibility with proto1.
+        if (field.getContainingType().getOptions().getMessageSetWireFormat()
+            && (field.getType() == FieldDescriptor.Type.MESSAGE)
+            && (field.isOptional())
+            // object equality
+            && (field.getExtensionScope() == field.getMessageType())) {
+          generator.print(field.getMessageType().getFullName());
+        } else {
+          generator.print(field.getFullName());
+        }
+        generator.print("]");
+      } else {
+        if (field.getType() == FieldDescriptor.Type.GROUP) {
+          // Groups must be serialized with their original capitalization.
+          generator.print(field.getMessageType().getName());
+        } else {
+          generator.print(field.getName());
+        }
+      }
+
+      if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+        if (singleLineMode) {
+          generator.print(" { ");
+        } else {
+          generator.print(" {\n");
+          generator.indent();
+        }
+      } else {
+        generator.print(": ");
+      }
+
+      printFieldValue(field, value, generator);
+
+      if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+        if (singleLineMode) {
+          generator.print("} ");
+        } else {
+          generator.outdent();
+          generator.print("}\n");
+        }
+      } else {
+        if (singleLineMode) {
+          generator.print(" ");
+        } else {
+          generator.print("\n");
+        }
+      }
+    }
+
+    private void printFieldValue(final FieldDescriptor field,
+                                 final Object value,
+                                 final TextGenerator generator)
+                                 throws IOException {
+      switch (field.getType()) {
+        case INT32:
+        case SINT32:
+        case SFIXED32:
+          generator.print(((Integer) value).toString());
+          break;
+
+        case INT64:
+        case SINT64:
+        case SFIXED64:
+          generator.print(((Long) value).toString());
+          break;
+
+        case BOOL:
+          generator.print(((Boolean) value).toString());
+          break;
+
+        case FLOAT:
+          generator.print(((Float) value).toString());
+          break;
+
+        case DOUBLE:
+          generator.print(((Double) value).toString());
+          break;
+
+        case UINT32:
+        case FIXED32:
+          generator.print(unsignedToString((Integer) value));
+          break;
+
+        case UINT64:
+        case FIXED64:
+          generator.print(unsignedToString((Long) value));
+          break;
+
+        case STRING:
+          generator.print("\"");
+          generator.print(escapeNonAscii ?
+              escapeText((String) value) :
+              escapeDoubleQuotesAndBackslashes((String) value));
+          generator.print("\"");
+          break;
+
+        case BYTES:
+          generator.print("\"");
+          if (value instanceof ByteString) {
+            generator.print(escapeBytes((ByteString) value));
+          } else {
+            generator.print(escapeBytes((byte[]) value));
+          }
+          generator.print("\"");
+          break;
+
+        case ENUM:
+          generator.print(((EnumValueDescriptor) value).getName());
+          break;
+
+        case MESSAGE:
+        case GROUP:
+          print((Message) value, generator);
+          break;
+      }
+    }
+
+    private void printUnknownFields(final UnknownFieldSet unknownFields,
+                                    final TextGenerator generator)
+                                    throws IOException {
+      for (Map.Entry<Integer, UnknownFieldSet.Field> entry :
+               unknownFields.asMap().entrySet()) {
+        final int number = entry.getKey();
+        final UnknownFieldSet.Field field = entry.getValue();
+        printUnknownField(number, WireFormat.WIRETYPE_VARINT,
+            field.getVarintList(), generator);
+        printUnknownField(number, WireFormat.WIRETYPE_FIXED32,
+            field.getFixed32List(), generator);
+        printUnknownField(number, WireFormat.WIRETYPE_FIXED64,
+            field.getFixed64List(), generator);
+        printUnknownField(number, WireFormat.WIRETYPE_LENGTH_DELIMITED,
+            field.getLengthDelimitedList(), generator);
+        for (final UnknownFieldSet value : field.getGroupList()) {
+          generator.print(entry.getKey().toString());
+          if (singleLineMode) {
+            generator.print(" { ");
+          } else {
+            generator.print(" {\n");
+            generator.indent();
+          }
+          printUnknownFields(value, generator);
+          if (singleLineMode) {
+            generator.print("} ");
+          } else {
+            generator.outdent();
+            generator.print("}\n");
+          }
+        }
+      }
+    }
+
+    private void printUnknownField(final int number,
+                                   final int wireType,
+                                   final List<?> values,
+                                   final TextGenerator generator)
+                                   throws IOException {
+      for (final Object value : values) {
+        generator.print(String.valueOf(number));
+        generator.print(": ");
+        printUnknownFieldValue(wireType, value, generator);
+        generator.print(singleLineMode ? " " : "\n");
+      }
+    }
+  }
+
+  /** Convert an unsigned 32-bit integer to a string. */
+  public static String unsignedToString(final int value) {
+    if (value >= 0) {
+      return Integer.toString(value);
+    } else {
+      return Long.toString(value & 0x00000000FFFFFFFFL);
+    }
+  }
+
+  /** Convert an unsigned 64-bit integer to a string. */
+  public static String unsignedToString(final long value) {
+    if (value >= 0) {
+      return Long.toString(value);
+    } else {
+      // Pull off the most-significant bit so that BigInteger doesn't think
+      // the number is negative, then set it again using setBit().
+      return BigInteger.valueOf(value & 0x7FFFFFFFFFFFFFFFL)
+                       .setBit(63).toString();
+    }
+  }
+
+  /**
+   * An inner class for writing text to the output stream.
+   */
+  private static final class TextGenerator {
+    private final Appendable output;
+    private final StringBuilder indent = new StringBuilder();
+    private boolean atStartOfLine = true;
+
+    private TextGenerator(final Appendable output) {
+      this.output = output;
+    }
+
+    /**
+     * 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.
+     */
+    public void indent() {
+      indent.append("  ");
+    }
+
+    /**
+     * Reduces the current indent level by two spaces, or crashes if the indent
+     * level is zero.
+     */
+    public void outdent() {
+      final int length = indent.length();
+      if (length == 0) {
+        throw new IllegalArgumentException(
+            " Outdent() without matching Indent().");
+      }
+      indent.delete(length - 2, length);
+    }
+
+    /**
+     * Print text to the output stream.
+     */
+    public void print(final CharSequence text) throws IOException {
+      final int size = text.length();
+      int pos = 0;
+
+      for (int i = 0; i < size; i++) {
+        if (text.charAt(i) == '\n') {
+          write(text.subSequence(pos, i + 1));
+          pos = i + 1;
+          atStartOfLine = true;
+        }
+      }
+      write(text.subSequence(pos, size));
+    }
+
+    private void write(final CharSequence data) throws IOException {
+      if (data.length() == 0) {
+        return;
+      }
+      if (atStartOfLine) {
+        atStartOfLine = false;
+        output.append(indent);
+      }
+      output.append(data);
+    }
+  }
+
+  // =================================================================
+  // Parsing
+
+  /**
+   * Represents a stream of tokens parsed from a {@code String}.
+   *
+   * <p>The Java standard library provides many classes that you might think
+   * would be useful for implementing this, but aren't.  For example:
+   *
+   * <ul>
+   * <li>{@code java.io.StreamTokenizer}:  This almost does what we want -- or,
+   *   at least, something that would get us close to what we want -- except
+   *   for one fatal flaw:  It automatically un-escapes strings using Java
+   *   escape sequences, which do not include all the escape sequences we
+   *   need to support (e.g. '\x').
+   * <li>{@code java.util.Scanner}:  This seems like a great way at least to
+   *   parse regular expressions out of a stream (so we wouldn't have to load
+   *   the entire input into a single string before parsing).  Sadly,
+   *   {@code Scanner} requires that tokens be delimited with some delimiter.
+   *   Thus, although the text "foo:" should parse to two tokens ("foo" and
+   *   ":"), {@code Scanner} would recognize it only as a single token.
+   *   Furthermore, {@code Scanner} provides no way to inspect the contents
+   *   of delimiters, making it impossible to keep track of line and column
+   *   numbers.
+   * </ul>
+   *
+   * <p>Luckily, Java's regular expression support does manage to be useful to
+   * us.  (Barely:  We need {@code Matcher.usePattern()}, which is new in
+   * Java 1.5.)  So, we can use that, at least.  Unfortunately, this implies
+   * that we need to have the entire input in one contiguous string.
+   */
+  private static final class Tokenizer {
+    private final CharSequence text;
+    private final Matcher matcher;
+    private String currentToken;
+
+    // The character index within this.text at which the current token begins.
+    private int pos = 0;
+
+    // The line and column numbers of the current token.
+    private int line = 0;
+    private int column = 0;
+
+    // The line and column numbers of the previous token (allows throwing
+    // errors *after* consuming).
+    private int previousLine = 0;
+    private int previousColumn = 0;
+
+    // We use possessive quantifiers (*+ and ++) because otherwise the Java
+    // regex matcher has stack overflows on large inputs.
+    private static final Pattern WHITESPACE =
+      Pattern.compile("(\\s|(#.*$))++", Pattern.MULTILINE);
+    private static final Pattern TOKEN = Pattern.compile(
+      "[a-zA-Z_][0-9a-zA-Z_+-]*+|" +                // an identifier
+      "[.]?[0-9+-][0-9a-zA-Z_.+-]*+|" +             // a number
+      "\"([^\"\n\\\\]|\\\\.)*+(\"|\\\\?$)|" +       // a double-quoted string
+      "\'([^\'\n\\\\]|\\\\.)*+(\'|\\\\?$)",         // a single-quoted string
+      Pattern.MULTILINE);
+
+    private static final Pattern DOUBLE_INFINITY = Pattern.compile(
+      "-?inf(inity)?",
+      Pattern.CASE_INSENSITIVE);
+    private static final Pattern FLOAT_INFINITY = Pattern.compile(
+      "-?inf(inity)?f?",
+      Pattern.CASE_INSENSITIVE);
+    private static final Pattern FLOAT_NAN = Pattern.compile(
+      "nanf?",
+      Pattern.CASE_INSENSITIVE);
+
+    /** Construct a tokenizer that parses tokens from the given text. */
+    private Tokenizer(final CharSequence text) {
+      this.text = text;
+      this.matcher = WHITESPACE.matcher(text);
+      skipWhitespace();
+      nextToken();
+    }
+
+    /** Are we at the end of the input? */
+    public boolean atEnd() {
+      return currentToken.length() == 0;
+    }
+
+    /** Advance to the next token. */
+    public void nextToken() {
+      previousLine = line;
+      previousColumn = column;
+
+      // Advance the line counter to the current position.
+      while (pos < matcher.regionStart()) {
+        if (text.charAt(pos) == '\n') {
+          ++line;
+          column = 0;
+        } else {
+          ++column;
+        }
+        ++pos;
+      }
+
+      // Match the next token.
+      if (matcher.regionStart() == matcher.regionEnd()) {
+        // EOF
+        currentToken = "";
+      } else {
+        matcher.usePattern(TOKEN);
+        if (matcher.lookingAt()) {
+          currentToken = matcher.group();
+          matcher.region(matcher.end(), matcher.regionEnd());
+        } else {
+          // Take one character.
+          currentToken = String.valueOf(text.charAt(pos));
+          matcher.region(pos + 1, matcher.regionEnd());
+        }
+
+        skipWhitespace();
+      }
+    }
+
+    /**
+     * Skip over any whitespace so that the matcher region starts at the next
+     * token.
+     */
+    private void skipWhitespace() {
+      matcher.usePattern(WHITESPACE);
+      if (matcher.lookingAt()) {
+        matcher.region(matcher.end(), matcher.regionEnd());
+      }
+    }
+
+    /**
+     * If the next token exactly matches {@code token}, consume it and return
+     * {@code true}.  Otherwise, return {@code false} without doing anything.
+     */
+    public boolean tryConsume(final String token) {
+      if (currentToken.equals(token)) {
+        nextToken();
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    /**
+     * If the next token exactly matches {@code token}, consume it.  Otherwise,
+     * throw a {@link ParseException}.
+     */
+    public void consume(final String token) throws ParseException {
+      if (!tryConsume(token)) {
+        throw parseException("Expected \"" + token + "\".");
+      }
+    }
+
+    /**
+     * Returns {@code true} if the next token is an integer, but does
+     * not consume it.
+     */
+    public boolean lookingAtInteger() {
+      if (currentToken.length() == 0) {
+        return false;
+      }
+
+      final char c = currentToken.charAt(0);
+      return ('0' <= c && c <= '9') ||
+             c == '-' || c == '+';
+    }
+
+    /**
+     * Returns {@code true} if the current token's text is equal to that
+     * specified.
+     */
+    public boolean lookingAt(String text) {
+      return currentToken.equals(text);
+    }
+
+    /**
+     * If the next token is an identifier, consume it and return its value.
+     * Otherwise, throw a {@link ParseException}.
+     */
+    public String consumeIdentifier() throws ParseException {
+      for (int i = 0; i < currentToken.length(); i++) {
+        final char c = currentToken.charAt(i);
+        if (('a' <= c && c <= 'z') ||
+            ('A' <= c && c <= 'Z') ||
+            ('0' <= c && c <= '9') ||
+            (c == '_') || (c == '.')) {
+          // OK
+        } else {
+          throw parseException(
+              "Expected identifier. Found '" + currentToken + "'");
+        }
+      }
+
+      final String result = currentToken;
+      nextToken();
+      return result;
+    }
+
+    /**
+     * If the next token is an identifier, consume it and return {@code true}.
+     * Otherwise, return {@code false} without doing anything.
+     */
+    public boolean tryConsumeIdentifier() {
+      try {
+        consumeIdentifier();
+        return true;
+      } catch (ParseException e) {
+        return false;
+      }
+    }
+
+    /**
+     * If the next token is a 32-bit signed integer, consume it and return its
+     * value.  Otherwise, throw a {@link ParseException}.
+     */
+    public int consumeInt32() throws ParseException {
+      try {
+        final int result = parseInt32(currentToken);
+        nextToken();
+        return result;
+      } catch (NumberFormatException e) {
+        throw integerParseException(e);
+      }
+    }
+
+    /**
+     * If the next token is a 32-bit unsigned integer, consume it and return its
+     * value.  Otherwise, throw a {@link ParseException}.
+     */
+    public int consumeUInt32() throws ParseException {
+      try {
+        final int result = parseUInt32(currentToken);
+        nextToken();
+        return result;
+      } catch (NumberFormatException e) {
+        throw integerParseException(e);
+      }
+    }
+
+    /**
+     * If the next token is a 64-bit signed integer, consume it and return its
+     * value.  Otherwise, throw a {@link ParseException}.
+     */
+    public long consumeInt64() throws ParseException {
+      try {
+        final long result = parseInt64(currentToken);
+        nextToken();
+        return result;
+      } catch (NumberFormatException e) {
+        throw integerParseException(e);
+      }
+    }
+
+    /**
+     * If the next token is a 64-bit signed integer, consume it and return
+     * {@code true}.  Otherwise, return {@code false} without doing anything.
+     */
+    public boolean tryConsumeInt64() {
+      try {
+        consumeInt64();
+        return true;
+      } catch (ParseException e) {
+        return false;
+      }
+    }
+
+    /**
+     * If the next token is a 64-bit unsigned integer, consume it and return its
+     * value.  Otherwise, throw a {@link ParseException}.
+     */
+    public long consumeUInt64() throws ParseException {
+      try {
+        final long result = parseUInt64(currentToken);
+        nextToken();
+        return result;
+      } catch (NumberFormatException e) {
+        throw integerParseException(e);
+      }
+    }
+
+    /**
+     * If the next token is a 64-bit unsigned integer, consume it and return
+     * {@code true}.  Otherwise, return {@code false} without doing anything.
+     */
+    public boolean tryConsumeUInt64() {
+      try {
+        consumeUInt64();
+        return true;
+      } catch (ParseException e) {
+        return false;
+      }
+    }
+
+    /**
+     * If the next token is a double, consume it and return its value.
+     * Otherwise, throw a {@link ParseException}.
+     */
+    public double consumeDouble() throws ParseException {
+      // We need to parse infinity and nan separately because
+      // Double.parseDouble() does not accept "inf", "infinity", or "nan".
+      if (DOUBLE_INFINITY.matcher(currentToken).matches()) {
+        final boolean negative = currentToken.startsWith("-");
+        nextToken();
+        return negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
+      }
+      if (currentToken.equalsIgnoreCase("nan")) {
+        nextToken();
+        return Double.NaN;
+      }
+      try {
+        final double result = Double.parseDouble(currentToken);
+        nextToken();
+        return result;
+      } catch (NumberFormatException e) {
+        throw floatParseException(e);
+      }
+    }
+
+    /**
+     * If the next token is a double, consume it and return {@code true}.
+     * Otherwise, return {@code false} without doing anything.
+     */
+    public boolean tryConsumeDouble() {
+      try {
+        consumeDouble();
+        return true;
+      } catch (ParseException e) {
+        return false;
+      }
+    }
+
+    /**
+     * If the next token is a float, consume it and return its value.
+     * Otherwise, throw a {@link ParseException}.
+     */
+    public float consumeFloat() throws ParseException {
+      // We need to parse infinity and nan separately because
+      // Float.parseFloat() does not accept "inf", "infinity", or "nan".
+      if (FLOAT_INFINITY.matcher(currentToken).matches()) {
+        final boolean negative = currentToken.startsWith("-");
+        nextToken();
+        return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
+      }
+      if (FLOAT_NAN.matcher(currentToken).matches()) {
+        nextToken();
+        return Float.NaN;
+      }
+      try {
+        final float result = Float.parseFloat(currentToken);
+        nextToken();
+        return result;
+      } catch (NumberFormatException e) {
+        throw floatParseException(e);
+      }
+    }
+
+    /**
+     * If the next token is a float, consume it and return {@code true}.
+     * Otherwise, return {@code false} without doing anything.
+     */
+    public boolean tryConsumeFloat() {
+      try {
+        consumeFloat();
+        return true;
+      } catch (ParseException e) {
+        return false;
+      }
+    }
+
+    /**
+     * If the next token is a boolean, consume it and return its value.
+     * Otherwise, throw a {@link ParseException}.
+     */
+    public boolean consumeBoolean() throws ParseException {
+      if (currentToken.equals("true") ||
+          currentToken.equals("t") ||
+          currentToken.equals("1")) {
+        nextToken();
+        return true;
+      } else if (currentToken.equals("false") ||
+                 currentToken.equals("f") ||
+                 currentToken.equals("0")) {
+        nextToken();
+        return false;
+      } else {
+        throw parseException("Expected \"true\" or \"false\".");
+      }
+    }
+
+    /**
+     * If the next token is a string, consume it and return its (unescaped)
+     * value.  Otherwise, throw a {@link ParseException}.
+     */
+    public String consumeString() throws ParseException {
+      return consumeByteString().toStringUtf8();
+    }
+
+    /**
+     * If the next token is a string, consume it and return true.  Otherwise,
+     * return false.
+     */
+    public boolean tryConsumeString() {
+      try {
+        consumeString();
+        return true;
+      } catch (ParseException e) {
+        return false;
+      }
+    }
+
+    /**
+     * If the next token is a string, consume it, unescape it as a
+     * {@link ByteString}, and return it.  Otherwise, throw a
+     * {@link ParseException}.
+     */
+    public ByteString consumeByteString() throws ParseException {
+      List<ByteString> list = new ArrayList<ByteString>();
+      consumeByteString(list);
+      while (currentToken.startsWith("'") || currentToken.startsWith("\"")) {
+        consumeByteString(list);
+      }
+      return ByteString.copyFrom(list);
+    }
+
+    /**
+     * Like {@link #consumeByteString()} but adds each token of the string to
+     * the given list.  String literals (whether bytes or text) may come in
+     * multiple adjacent tokens which are automatically concatenated, like in
+     * C or Python.
+     */
+    private void consumeByteString(List<ByteString> list)
+        throws ParseException {
+      final char quote = currentToken.length() > 0 ? currentToken.charAt(0)
+                                                   : '\0';
+      if (quote != '\"' && quote != '\'') {
+        throw parseException("Expected string.");
+      }
+
+      if (currentToken.length() < 2 ||
+          currentToken.charAt(currentToken.length() - 1) != quote) {
+        throw parseException("String missing ending quote.");
+      }
+
+      try {
+        final String escaped =
+            currentToken.substring(1, currentToken.length() - 1);
+        final ByteString result = unescapeBytes(escaped);
+        nextToken();
+        list.add(result);
+      } catch (InvalidEscapeSequenceException e) {
+        throw parseException(e.getMessage());
+      }
+    }
+
+    /**
+     * Returns a {@link ParseException} with the current line and column
+     * numbers in the description, suitable for throwing.
+     */
+    public ParseException parseException(final String description) {
+      // Note:  People generally prefer one-based line and column numbers.
+      return new ParseException(
+        line + 1, column + 1, description);
+    }
+
+    /**
+     * Returns a {@link ParseException} with the line and column numbers of
+     * the previous token in the description, suitable for throwing.
+     */
+    public ParseException parseExceptionPreviousToken(
+        final String description) {
+      // Note:  People generally prefer one-based line and column numbers.
+      return new ParseException(
+        previousLine + 1, previousColumn + 1, description);
+    }
+
+    /**
+     * Constructs an appropriate {@link ParseException} for the given
+     * {@code NumberFormatException} when trying to parse an integer.
+     */
+    private ParseException integerParseException(
+        final NumberFormatException e) {
+      return parseException("Couldn't parse integer: " + e.getMessage());
+    }
+
+    /**
+     * Constructs an appropriate {@link ParseException} for the given
+     * {@code NumberFormatException} when trying to parse a float or double.
+     */
+    private ParseException floatParseException(final NumberFormatException e) {
+      return parseException("Couldn't parse number: " + e.getMessage());
+    }
+  }
+
+  /** Thrown when parsing an invalid text format message. */
+  public static class ParseException extends IOException {
+    private static final long serialVersionUID = 3196188060225107702L;
+
+    private final int line;
+    private final int column;
+
+    /** Create a new instance, with -1 as the line and column numbers. */
+    public ParseException(final String message) {
+      this(-1, -1, message);
+    }
+
+    /**
+     * Create a new instance
+     *
+     * @param line the line number where the parse error occurred,
+     * using 1-offset.
+     * @param column the column number where the parser error occurred,
+     * using 1-offset.
+     */
+    public ParseException(final int line, final int column,
+        final String message) {
+      super(Integer.toString(line) + ":" + column + ": " + message);
+      this.line = line;
+      this.column = column;
+    }
+
+    /**
+     * Return the line where the parse exception occurred, or -1 when
+     * none is provided. The value is specified as 1-offset, so the first
+     * line is line 1.
+     */
+    public int getLine() {
+      return line;
+    }
+
+    /**
+     * Return the column where the parse exception occurred, or -1 when
+     * none is provided. The value is specified as 1-offset, so the first
+     * line is line 1.
+     */
+    public int getColumn() {
+      return column;
+    }
+  }
+
+  private static final Parser PARSER = Parser.newBuilder().build();
+
+  /**
+   * Return a {@link Parser} instance which can parse text-format
+   * messages. The returned instance is thread-safe.
+   */
+  public static Parser getParser() {
+    return PARSER;
+  }
+
+  /**
+   * Parse a text-format message from {@code input} and merge the contents
+   * into {@code builder}.
+   */
+  public static void merge(final Readable input,
+                           final Message.Builder builder)
+                           throws IOException {
+    PARSER.merge(input, builder);
+  }
+
+  /**
+   * Parse a text-format message from {@code input} and merge the contents
+   * into {@code builder}.
+   */
+  public static void merge(final CharSequence input,
+                           final Message.Builder builder)
+                           throws ParseException {
+    PARSER.merge(input, builder);
+  }
+
+  /**
+   * Parse a text-format message from {@code input} and merge the contents
+   * into {@code builder}.  Extensions will be recognized if they are
+   * registered in {@code extensionRegistry}.
+   */
+  public static void merge(final Readable input,
+                           final ExtensionRegistry extensionRegistry,
+                           final Message.Builder builder)
+                           throws IOException {
+    PARSER.merge(input, extensionRegistry, builder);
+  }
+
+
+  /**
+   * Parse a text-format message from {@code input} and merge the contents
+   * into {@code builder}.  Extensions will be recognized if they are
+   * registered in {@code extensionRegistry}.
+   */
+  public static void merge(final CharSequence input,
+                           final ExtensionRegistry extensionRegistry,
+                           final Message.Builder builder)
+                           throws ParseException {
+    PARSER.merge(input, extensionRegistry, builder);
+  }
+
+
+  /**
+   * Parser for text-format proto2 instances. This class is thread-safe.
+   * The implementation largely follows google/protobuf/text_format.cc.
+   *
+   * <p>Use {@link TextFormat#getParser()} to obtain the default parser, or
+   * {@link Builder} to control the parser behavior.
+   */
+  public static class Parser {
+    /**
+     * Determines if repeated values for non-repeated fields and
+     * oneofs are permitted. For example, given required/optional field "foo"
+     * and a oneof containing "baz" and "qux":
+     * <li>
+     * <ul>"foo: 1 foo: 2"
+     * <ul>"baz: 1 qux: 2"
+     * <ul>merging "foo: 2" into a proto in which foo is already set, or
+     * <ul>merging "qux: 2" into a proto in which baz is already set.
+     * </li>
+     */
+    public enum SingularOverwritePolicy {
+      /** The last value is retained. */
+      ALLOW_SINGULAR_OVERWRITES,
+      /** An error is issued. */
+      FORBID_SINGULAR_OVERWRITES
+    }
+
+    private final boolean allowUnknownFields;
+    private final SingularOverwritePolicy singularOverwritePolicy;
+
+    private Parser(boolean allowUnknownFields,
+        SingularOverwritePolicy singularOverwritePolicy) {
+      this.allowUnknownFields = allowUnknownFields;
+      this.singularOverwritePolicy = singularOverwritePolicy;
+    }
+
+    /**
+     * Returns a new instance of {@link Builder}.
+     */
+    public static Builder newBuilder() {
+      return new Builder();
+    }
+
+    /**
+     * Builder that can be used to obtain new instances of {@link Parser}.
+     */
+    public static class Builder {
+      private boolean allowUnknownFields = false;
+      private SingularOverwritePolicy singularOverwritePolicy =
+          SingularOverwritePolicy.ALLOW_SINGULAR_OVERWRITES;
+
+      /**
+       * Sets parser behavior when a non-repeated field appears more than once.
+       */
+      public Builder setSingularOverwritePolicy(SingularOverwritePolicy p) {
+        this.singularOverwritePolicy = p;
+        return this;
+      }
+
+      public Parser build() {
+        return new Parser(allowUnknownFields, singularOverwritePolicy);
+      }
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents
+     * into {@code builder}.
+     */
+    public void merge(final Readable input,
+                      final Message.Builder builder)
+                      throws IOException {
+      merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents
+     * into {@code builder}.
+     */
+    public void merge(final CharSequence input,
+                      final Message.Builder builder)
+                      throws ParseException {
+      merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents
+     * into {@code builder}.  Extensions will be recognized if they are
+     * registered in {@code extensionRegistry}.
+     */
+    public void merge(final Readable input,
+                      final ExtensionRegistry extensionRegistry,
+                      final Message.Builder builder)
+                      throws IOException {
+      // Read the entire input to a String then parse that.
+
+      // If StreamTokenizer were not quite so crippled, or if there were a kind
+      // of Reader that could read in chunks that match some particular regex,
+      // or if we wanted to write a custom Reader to tokenize our stream, then
+      // we would not have to read to one big String.  Alas, none of these is
+      // the case.  Oh well.
+
+      merge(toStringBuilder(input), extensionRegistry, builder);
+    }
+
+
+    private static final int BUFFER_SIZE = 4096;
+
+    // TODO(chrisn): See if working around java.io.Reader#read(CharBuffer)
+    // overhead is worthwhile
+    private static StringBuilder toStringBuilder(final Readable input)
+        throws IOException {
+      final StringBuilder text = new StringBuilder();
+      final CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
+      while (true) {
+        final int n = input.read(buffer);
+        if (n == -1) {
+          break;
+        }
+        buffer.flip();
+        text.append(buffer, 0, n);
+      }
+      return text;
+    }
+
+    /**
+     * Parse a text-format message from {@code input} and merge the contents
+     * into {@code builder}.  Extensions will be recognized if they are
+     * registered in {@code extensionRegistry}.
+     */
+    public void merge(final CharSequence input,
+                      final ExtensionRegistry extensionRegistry,
+                      final Message.Builder builder)
+                      throws ParseException {
+      final Tokenizer tokenizer = new Tokenizer(input);
+      MessageReflection.BuilderAdapter target =
+          new MessageReflection.BuilderAdapter(builder);
+
+      while (!tokenizer.atEnd()) {
+        mergeField(tokenizer, extensionRegistry, target);
+      }
+    }
+
+
+    /**
+     * Parse a single field from {@code tokenizer} and merge it into
+     * {@code builder}.
+     */
+    private void mergeField(final Tokenizer tokenizer,
+                            final ExtensionRegistry extensionRegistry,
+                            final MessageReflection.MergeTarget target)
+                            throws ParseException {
+      FieldDescriptor field = null;
+      final Descriptor type = target.getDescriptorForType();
+      ExtensionRegistry.ExtensionInfo extension = null;
+
+      if (tokenizer.tryConsume("[")) {
+        // An extension.
+        final StringBuilder name =
+            new StringBuilder(tokenizer.consumeIdentifier());
+        while (tokenizer.tryConsume(".")) {
+          name.append('.');
+          name.append(tokenizer.consumeIdentifier());
+        }
+
+        extension = target.findExtensionByName(
+            extensionRegistry, name.toString());
+
+        if (extension == null) {
+          if (!allowUnknownFields) {
+            throw tokenizer.parseExceptionPreviousToken(
+              "Extension \"" + name + "\" not found in the ExtensionRegistry.");
+          } else {
+            logger.warning(
+              "Extension \"" + name + "\" not found in the ExtensionRegistry.");
+          }
+        } else {
+          if (extension.descriptor.getContainingType() != type) {
+            throw tokenizer.parseExceptionPreviousToken(
+              "Extension \"" + name + "\" does not extend message type \"" +
+              type.getFullName() + "\".");
+          }
+          field = extension.descriptor;
+        }
+
+        tokenizer.consume("]");
+      } else {
+        final String name = tokenizer.consumeIdentifier();
+        field = type.findFieldByName(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) {
+          // Explicitly specify US locale so that this code does not break when
+          // executing in Turkey.
+          final String lowerName = name.toLowerCase(Locale.US);
+          field = type.findFieldByName(lowerName);
+          // If the case-insensitive match worked but the field is NOT a group,
+          if (field != null && field.getType() != FieldDescriptor.Type.GROUP) {
+            field = null;
+          }
+        }
+        // Again, special-case group names as described above.
+        if (field != null && field.getType() == FieldDescriptor.Type.GROUP &&
+            !field.getMessageType().getName().equals(name)) {
+          field = null;
+        }
+
+        if (field == null) {
+          if (!allowUnknownFields) {
+            throw tokenizer.parseExceptionPreviousToken(
+              "Message type \"" + type.getFullName() +
+              "\" has no field named \"" + name + "\".");
+          } else {
+            logger.warning(
+              "Message type \"" + type.getFullName() +
+              "\" has no field named \"" + name + "\".");
+          }
+        }
+      }
+
+      // Skips unknown fields.
+      if (field == null) {
+        // Try to guess the type of this field.
+        // If this field is not a message, there should be a ":" between the
+        // field name and the field value and also the field value should not
+        // start with "{" or "<" which indicates the begining of a message body.
+        // If there is no ":" or there is a "{" or "<" after ":", this field has
+        // to be a message or the input is ill-formed.
+        if (tokenizer.tryConsume(":") && !tokenizer.lookingAt("{") &&
+            !tokenizer.lookingAt("<")) {
+          skipFieldValue(tokenizer);
+        } else {
+          skipFieldMessage(tokenizer);
+        }
+        return;
+      }
+
+      // Handle potential ':'.
+      if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+        tokenizer.tryConsume(":");  // optional
+      } else {
+        tokenizer.consume(":");  // required
+      }
+      // Support specifying repeated field values as a comma-separated list.
+      // Ex."foo: [1, 2, 3]"
+      if (field.isRepeated() && tokenizer.tryConsume("[")) {
+        while (true) {
+          consumeFieldValue(tokenizer, extensionRegistry, target, field, extension);
+          if (tokenizer.tryConsume("]")) {
+            // End of list.
+            break;
+          }
+          tokenizer.consume(",");
+        }
+      } else {
+        consumeFieldValue(tokenizer, extensionRegistry, target, field, extension);
+      }
+    }
+
+    /**
+     * Parse a single field value from {@code tokenizer} and merge it into
+     * {@code builder}.
+     */
+    private void consumeFieldValue(
+        final Tokenizer tokenizer,
+        final ExtensionRegistry extensionRegistry,
+        final MessageReflection.MergeTarget target,
+        final FieldDescriptor field,
+        final ExtensionRegistry.ExtensionInfo extension)
+        throws ParseException {
+      Object value = null;
+
+      if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+        final String endToken;
+        if (tokenizer.tryConsume("<")) {
+          endToken = ">";
+        } else {
+          tokenizer.consume("{");
+          endToken = "}";
+        }
+
+        final MessageReflection.MergeTarget subField;
+        subField = target.newMergeTargetForField(field,
+            (extension == null) ? null : extension.defaultInstance);
+
+        while (!tokenizer.tryConsume(endToken)) {
+          if (tokenizer.atEnd()) {
+            throw tokenizer.parseException(
+              "Expected \"" + endToken + "\".");
+          }
+          mergeField(tokenizer, extensionRegistry, subField);
+        }
+
+        value = subField.finish();
+
+      } else {
+        switch (field.getType()) {
+          case INT32:
+          case SINT32:
+          case SFIXED32:
+            value = tokenizer.consumeInt32();
+            break;
+
+          case INT64:
+          case SINT64:
+          case SFIXED64:
+            value = tokenizer.consumeInt64();
+            break;
+
+          case UINT32:
+          case FIXED32:
+            value = tokenizer.consumeUInt32();
+            break;
+
+          case UINT64:
+          case FIXED64:
+            value = tokenizer.consumeUInt64();
+            break;
+
+          case FLOAT:
+            value = tokenizer.consumeFloat();
+            break;
+
+          case DOUBLE:
+            value = tokenizer.consumeDouble();
+            break;
+
+          case BOOL:
+            value = tokenizer.consumeBoolean();
+            break;
+
+          case STRING:
+            value = tokenizer.consumeString();
+            break;
+
+          case BYTES:
+            value = tokenizer.consumeByteString();
+            break;
+
+          case ENUM:
+            final EnumDescriptor enumType = field.getEnumType();
+
+            if (tokenizer.lookingAtInteger()) {
+              final int number = tokenizer.consumeInt32();
+              value = enumType.findValueByNumber(number);
+              if (value == null) {
+                throw tokenizer.parseExceptionPreviousToken(
+                  "Enum type \"" + enumType.getFullName() +
+                  "\" has no value with number " + number + '.');
+              }
+            } else {
+              final String id = tokenizer.consumeIdentifier();
+              value = enumType.findValueByName(id);
+              if (value == null) {
+                throw tokenizer.parseExceptionPreviousToken(
+                  "Enum type \"" + enumType.getFullName() +
+                  "\" has no value named \"" + id + "\".");
+              }
+            }
+
+            break;
+
+          case MESSAGE:
+          case GROUP:
+            throw new RuntimeException("Can't get here.");
+        }
+      }
+
+      if (field.isRepeated()) {
+        target.addRepeatedField(field, value);
+      } else if ((singularOverwritePolicy
+              == SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES)
+          && target.hasField(field)) {
+        throw tokenizer.parseExceptionPreviousToken("Non-repeated field \""
+            + field.getFullName() + "\" cannot be overwritten.");
+      } else if ((singularOverwritePolicy
+              == SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES)
+          && field.getContainingOneof() != null
+          && target.hasOneof(field.getContainingOneof())) {
+        Descriptors.OneofDescriptor oneof = field.getContainingOneof();
+        throw tokenizer.parseExceptionPreviousToken("Field \""
+            + field.getFullName() + "\" is specified along with field \""
+            + target.getOneofFieldDescriptor(oneof).getFullName()
+            + "\", another member of oneof \"" + oneof.getName() + "\".");
+      } else {
+        target.setField(field, value);
+      }
+    }
+
+    /**
+     * Skips the next field including the field's name and value.
+     */
+    private void skipField(Tokenizer tokenizer) throws ParseException {
+      if (tokenizer.tryConsume("[")) {
+        // Extension name.
+        do {
+          tokenizer.consumeIdentifier();
+        } while (tokenizer.tryConsume("."));
+        tokenizer.consume("]");
+      } else {
+        tokenizer.consumeIdentifier();
+      }
+
+      // Try to guess the type of this field.
+      // If this field is not a message, there should be a ":" between the
+      // field name and the field value and also the field value should not
+      // start with "{" or "<" which indicates the begining of a message body.
+      // If there is no ":" or there is a "{" or "<" after ":", this field has
+      // to be a message or the input is ill-formed.
+      if (tokenizer.tryConsume(":") && !tokenizer.lookingAt("<") &&
+          !tokenizer.lookingAt("{")) {
+        skipFieldValue(tokenizer);
+      } else {
+        skipFieldMessage(tokenizer);
+      }
+      // For historical reasons, fields may optionally be separated by commas or
+      // semicolons.
+      if (!tokenizer.tryConsume(";")) {
+        tokenizer.tryConsume(",");
+      }
+    }
+
+    /**
+     * Skips the whole body of a message including the beginning delimeter and
+     * the ending delimeter.
+     */
+    private void skipFieldMessage(Tokenizer tokenizer) throws ParseException {
+      final String delimiter;
+      if (tokenizer.tryConsume("<")) {
+        delimiter = ">";
+      } else {
+        tokenizer.consume("{");
+        delimiter = "}";
+      }
+      while (!tokenizer.lookingAt(">") && !tokenizer.lookingAt("}")) {
+        skipField(tokenizer);
+      }
+      tokenizer.consume(delimiter);
+    }
+
+    /**
+     * Skips a field value.
+     */
+    private void skipFieldValue(Tokenizer tokenizer) throws ParseException {
+      if (tokenizer.tryConsumeString()) {
+        while (tokenizer.tryConsumeString()) {}
+        return;
+      }
+      if (!tokenizer.tryConsumeIdentifier() &&  // includes enum & boolean
+          !tokenizer.tryConsumeInt64() &&       // includes int32
+          !tokenizer.tryConsumeUInt64() &&      // includes uint32
+          !tokenizer.tryConsumeDouble() &&
+          !tokenizer.tryConsumeFloat()) {
+        throw tokenizer.parseException(
+            "Invalid field value: " + tokenizer.currentToken);
+      }
+    }
+  }
+
+  // =================================================================
+  // Utility functions
+  //
+  // Some of these methods are package-private because Descriptors.java uses
+  // them.
+
+  private interface ByteSequence {
+    int size();
+    byte byteAt(int offset);
+  }
+
+  /**
+   * Escapes bytes in the format used in protocol buffer text format, which
+   * is the same as the format used for C string literals.  All bytes
+   * that are not printable 7-bit ASCII characters are escaped, as well as
+   * backslash, single-quote, and double-quote characters.  Characters for
+   * which no defined short-hand escape sequence is defined will be escaped
+   * using 3-digit octal sequences.
+   */
+  private static String escapeBytes(final ByteSequence input) {
+    final StringBuilder builder = new StringBuilder(input.size());
+    for (int i = 0; i < input.size(); i++) {
+      final byte b = input.byteAt(i);
+      switch (b) {
+        // Java does not recognize \a or \v, apparently.
+        case 0x07: builder.append("\\a" ); break;
+        case '\b': builder.append("\\b" ); break;
+        case '\f': builder.append("\\f" ); break;
+        case '\n': builder.append("\\n" ); break;
+        case '\r': builder.append("\\r" ); break;
+        case '\t': builder.append("\\t" ); break;
+        case 0x0b: builder.append("\\v" ); break;
+        case '\\': builder.append("\\\\"); break;
+        case '\'': builder.append("\\\'"); break;
+        case '"' : builder.append("\\\""); break;
+        default:
+          // Note:  Bytes with the high-order bit set should be escaped.  Since
+          //   bytes are signed, such bytes will compare less than 0x20, hence
+          //   the following line is correct.
+          if (b >= 0x20) {
+            builder.append((char) b);
+          } else {
+            builder.append('\\');
+            builder.append((char) ('0' + ((b >>> 6) & 3)));
+            builder.append((char) ('0' + ((b >>> 3) & 7)));
+            builder.append((char) ('0' + (b & 7)));
+          }
+          break;
+      }
+    }
+    return builder.toString();
+  }
+
+  /**
+   * Escapes bytes in the format used in protocol buffer text format, which
+   * is the same as the format used for C string literals.  All bytes
+   * that are not printable 7-bit ASCII characters are escaped, as well as
+   * backslash, single-quote, and double-quote characters.  Characters for
+   * which no defined short-hand escape sequence is defined will be escaped
+   * using 3-digit octal sequences.
+   */
+  static String escapeBytes(final ByteString input) {
+    return escapeBytes(new ByteSequence() {
+      public int size() {
+        return input.size();
+      }
+      public byte byteAt(int offset) {
+        return input.byteAt(offset);
+      }
+    });
+  }
+
+  /**
+   * Like {@link #escapeBytes(ByteString)}, but used for byte array.
+   */
+  static String escapeBytes(final byte[] input) {
+    return escapeBytes(new ByteSequence() {
+      public int size() {
+        return input.length;
+      }
+      public byte byteAt(int offset) {
+        return input[offset];
+      }
+    });
+  }
+
+  /**
+   * Un-escape a byte sequence as escaped using
+   * {@link #escapeBytes(ByteString)}.  Two-digit hex escapes (starting with
+   * "\x") are also recognized.
+   */
+  static ByteString unescapeBytes(final CharSequence charString)
+      throws InvalidEscapeSequenceException {
+    // First convert the Java character sequence to UTF-8 bytes.
+    ByteString input = ByteString.copyFromUtf8(charString.toString());
+    // Then unescape certain byte sequences introduced by ASCII '\\'.  The valid
+    // escapes can all be expressed with ASCII characters, so it is safe to
+    // operate on bytes here.
+    //
+    // Unescaping the input byte array will result in a byte sequence that's no
+    // longer than the input.  That's because each escape sequence is between
+    // two and four bytes long and stands for a single byte.
+    final byte[] result = new byte[input.size()];
+    int pos = 0;
+    for (int i = 0; i < input.size(); i++) {
+      byte c = input.byteAt(i);
+      if (c == '\\') {
+        if (i + 1 < input.size()) {
+          ++i;
+          c = input.byteAt(i);
+          if (isOctal(c)) {
+            // Octal escape.
+            int code = digitValue(c);
+            if (i + 1 < input.size() && isOctal(input.byteAt(i + 1))) {
+              ++i;
+              code = code * 8 + digitValue(input.byteAt(i));
+            }
+            if (i + 1 < input.size() && isOctal(input.byteAt(i + 1))) {
+              ++i;
+              code = code * 8 + digitValue(input.byteAt(i));
+            }
+            // TODO: Check that 0 <= code && code <= 0xFF.
+            result[pos++] = (byte)code;
+          } else {
+            switch (c) {
+              case 'a' : result[pos++] = 0x07; break;
+              case 'b' : result[pos++] = '\b'; break;
+              case 'f' : result[pos++] = '\f'; break;
+              case 'n' : result[pos++] = '\n'; break;
+              case 'r' : result[pos++] = '\r'; break;
+              case 't' : result[pos++] = '\t'; break;
+              case 'v' : result[pos++] = 0x0b; break;
+              case '\\': result[pos++] = '\\'; break;
+              case '\'': result[pos++] = '\''; break;
+              case '"' : result[pos++] = '\"'; break;
+
+              case 'x':
+                // hex escape
+                int code = 0;
+                if (i + 1 < input.size() && isHex(input.byteAt(i + 1))) {
+                  ++i;
+                  code = digitValue(input.byteAt(i));
+                } else {
+                  throw new InvalidEscapeSequenceException(
+                      "Invalid escape sequence: '\\x' with no digits");
+                }
+                if (i + 1 < input.size() && isHex(input.byteAt(i + 1))) {
+                  ++i;
+                  code = code * 16 + digitValue(input.byteAt(i));
+                }
+                result[pos++] = (byte)code;
+                break;
+
+              default:
+                throw new InvalidEscapeSequenceException(
+                    "Invalid escape sequence: '\\" + (char)c + '\'');
+            }
+          }
+        } else {
+          throw new InvalidEscapeSequenceException(
+              "Invalid escape sequence: '\\' at end of string.");
+        }
+      } else {
+        result[pos++] = c;
+      }
+    }
+
+    return ByteString.copyFrom(result, 0, pos);
+  }
+
+  /**
+   * Thrown by {@link TextFormat#unescapeBytes} and
+   * {@link TextFormat#unescapeText} when an invalid escape sequence is seen.
+   */
+  static class InvalidEscapeSequenceException extends IOException {
+    private static final long serialVersionUID = -8164033650142593304L;
+
+    InvalidEscapeSequenceException(final String description) {
+      super(description);
+    }
+  }
+
+  /**
+   * Like {@link #escapeBytes(ByteString)}, but escapes a text string.
+   * Non-ASCII characters are first encoded as UTF-8, then each byte is escaped
+   * individually as a 3-digit octal escape.  Yes, it's weird.
+   */
+  static String escapeText(final String input) {
+    return escapeBytes(ByteString.copyFromUtf8(input));
+  }
+
+  /**
+   * Escape double quotes and backslashes in a String for unicode output of a message.
+   */
+  public static String escapeDoubleQuotesAndBackslashes(final String input) {
+    return input.replace("\\", "\\\\").replace("\"", "\\\"");
+  }
+
+  /**
+   * Un-escape a text string as escaped using {@link #escapeText(String)}.
+   * Two-digit hex escapes (starting with "\x") are also recognized.
+   */
+  static String unescapeText(final String input)
+                             throws InvalidEscapeSequenceException {
+    return unescapeBytes(input).toStringUtf8();
+  }
+
+  /** Is this an octal digit? */
+  private static boolean isOctal(final byte c) {
+    return '0' <= c && c <= '7';
+  }
+
+  /** Is this a hex digit? */
+  private static boolean isHex(final byte c) {
+    return ('0' <= c && c <= '9') ||
+           ('a' <= c && c <= 'f') ||
+           ('A' <= c && c <= 'F');
+  }
+
+  /**
+   * Interpret a character as a digit (in any base up to 36) and return the
+   * numeric value.  This is like {@code Character.digit()} but we don't accept
+   * non-ASCII digits.
+   */
+  private static int digitValue(final byte c) {
+    if ('0' <= c && c <= '9') {
+      return c - '0';
+    } else if ('a' <= c && c <= 'z') {
+      return c - 'a' + 10;
+    } else {
+      return c - 'A' + 10;
+    }
+  }
+
+  /**
+   * Parse a 32-bit signed integer from the text.  Unlike the Java standard
+   * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+   * and "0" to signify hexadecimal and octal numbers, respectively.
+   */
+  static int parseInt32(final String text) throws NumberFormatException {
+    return (int) parseInteger(text, true, false);
+  }
+
+  /**
+   * Parse a 32-bit unsigned integer from the text.  Unlike the Java standard
+   * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+   * and "0" to signify hexadecimal and octal numbers, respectively.  The
+   * result is coerced to a (signed) {@code int} when returned since Java has
+   * no unsigned integer type.
+   */
+  static int parseUInt32(final String text) throws NumberFormatException {
+    return (int) parseInteger(text, false, false);
+  }
+
+  /**
+   * Parse a 64-bit signed integer from the text.  Unlike the Java standard
+   * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+   * and "0" to signify hexadecimal and octal numbers, respectively.
+   */
+  static long parseInt64(final String text) throws NumberFormatException {
+    return parseInteger(text, true, true);
+  }
+
+  /**
+   * Parse a 64-bit unsigned integer from the text.  Unlike the Java standard
+   * {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
+   * and "0" to signify hexadecimal and octal numbers, respectively.  The
+   * result is coerced to a (signed) {@code long} when returned since Java has
+   * no unsigned long type.
+   */
+  static long parseUInt64(final String text) throws NumberFormatException {
+    return parseInteger(text, false, true);
+  }
+
+  private static long parseInteger(final String text,
+                                   final boolean isSigned,
+                                   final boolean isLong)
+                                   throws NumberFormatException {
+    int pos = 0;
+
+    boolean negative = false;
+    if (text.startsWith("-", pos)) {
+      if (!isSigned) {
+        throw new NumberFormatException("Number must be positive: " + text);
+      }
+      ++pos;
+      negative = true;
+    }
+
+    int radix = 10;
+    if (text.startsWith("0x", pos)) {
+      pos += 2;
+      radix = 16;
+    } else if (text.startsWith("0", pos)) {
+      radix = 8;
+    }
+
+    final String numberText = text.substring(pos);
+
+    long result = 0;
+    if (numberText.length() < 16) {
+      // Can safely assume no overflow.
+      result = Long.parseLong(numberText, radix);
+      if (negative) {
+        result = -result;
+      }
+
+      // Check bounds.
+      // No need to check for 64-bit numbers since they'd have to be 16 chars
+      // or longer to overflow.
+      if (!isLong) {
+        if (isSigned) {
+          if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
+            throw new NumberFormatException(
+              "Number out of range for 32-bit signed integer: " + text);
+          }
+        } else {
+          if (result >= (1L << 32) || result < 0) {
+            throw new NumberFormatException(
+              "Number out of range for 32-bit unsigned integer: " + text);
+          }
+        }
+      }
+    } else {
+      BigInteger bigValue = new BigInteger(numberText, radix);
+      if (negative) {
+        bigValue = bigValue.negate();
+      }
+
+      // Check bounds.
+      if (!isLong) {
+        if (isSigned) {
+          if (bigValue.bitLength() > 31) {
+            throw new NumberFormatException(
+              "Number out of range for 32-bit signed integer: " + text);
+          }
+        } else {
+          if (bigValue.bitLength() > 32) {
+            throw new NumberFormatException(
+              "Number out of range for 32-bit unsigned integer: " + text);
+          }
+        }
+      } else {
+        if (isSigned) {
+          if (bigValue.bitLength() > 63) {
+            throw new NumberFormatException(
+              "Number out of range for 64-bit signed integer: " + text);
+          }
+        } else {
+          if (bigValue.bitLength() > 64) {
+            throw new NumberFormatException(
+              "Number out of range for 64-bit unsigned integer: " + text);
+          }
+        }
+      }
+
+      result = bigValue.longValue();
+    }
+
+    return result;
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/UninitializedMessageException.java b/protobuf/java/src/main/java/com/google/protobuf/UninitializedMessageException.java
new file mode 100644
index 0000000..5714c06
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/UninitializedMessageException.java
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Thrown when attempting to build a protocol message that is missing required
+ * fields.  This is a {@code RuntimeException} because it normally represents
+ * a programming error:  it happens when some code which constructs a message
+ * fails to set all the fields.  {@code parseFrom()} methods <b>do not</b>
+ * throw this; they throw an {@link InvalidProtocolBufferException} if
+ * required fields are missing, because it is not a programming error to
+ * receive an incomplete message.  In other words,
+ * {@code UninitializedMessageException} should never be thrown by correct
+ * code, but {@code InvalidProtocolBufferException} might be.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class UninitializedMessageException extends RuntimeException {
+  private static final long serialVersionUID = -7466929953374883507L;
+
+  public UninitializedMessageException(final MessageLite message) {
+    super("Message was missing required fields.  (Lite runtime could not " +
+          "determine which fields were missing).");
+    missingFields = null;
+  }
+
+  public UninitializedMessageException(final List<String> missingFields) {
+    super(buildDescription(missingFields));
+    this.missingFields = missingFields;
+  }
+
+  private final List<String> missingFields;
+
+  /**
+   * Get a list of human-readable names of required fields missing from this
+   * message.  Each name is a full path to a field, e.g. "foo.bar[5].baz".
+   * Returns null if the lite runtime was used, since it lacks the ability to
+   * find missing fields.
+   */
+  public List<String> getMissingFields() {
+    return Collections.unmodifiableList(missingFields);
+  }
+
+  /**
+   * Converts this exception to an {@link InvalidProtocolBufferException}.
+   * When a parsed message is missing required fields, this should be thrown
+   * instead of {@code UninitializedMessageException}.
+   */
+  public InvalidProtocolBufferException asInvalidProtocolBufferException() {
+    return new InvalidProtocolBufferException(getMessage());
+  }
+
+  /** Construct the description string for this exception. */
+  private static String buildDescription(final List<String> missingFields) {
+    final StringBuilder description =
+      new StringBuilder("Message missing required fields: ");
+    boolean first = true;
+    for (final String field : missingFields) {
+      if (first) {
+        first = false;
+      } else {
+        description.append(", ");
+      }
+      description.append(field);
+    }
+    return description.toString();
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/UnknownFieldSet.java b/protobuf/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
new file mode 100644
index 0000000..99de373
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/UnknownFieldSet.java
@@ -0,0 +1,995 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * {@code UnknownFieldSet} is used to keep track of fields which were seen when
+ * parsing a protocol message but whose field numbers or types are unrecognized.
+ * This most frequently occurs when new fields are added to a message type
+ * and then messages containing those fields are read by old software that was
+ * compiled before the new types were added.
+ *
+ * <p>Every {@link Message} contains an {@code UnknownFieldSet} (and every
+ * {@link Message.Builder} contains an {@link Builder}).
+ *
+ * <p>Most users will never need to use this class.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class UnknownFieldSet implements MessageLite {
+  private UnknownFieldSet() {}
+
+  /** Create a new {@link Builder}. */
+  public static Builder newBuilder() {
+    return Builder.create();
+  }
+
+  /**
+   * Create a new {@link Builder} and initialize it to be a copy
+   * of {@code copyFrom}.
+   */
+  public static Builder newBuilder(final UnknownFieldSet copyFrom) {
+    return newBuilder().mergeFrom(copyFrom);
+  }
+
+  /** Get an empty {@code UnknownFieldSet}. */
+  public static UnknownFieldSet getDefaultInstance() {
+    return defaultInstance;
+  }
+  public UnknownFieldSet getDefaultInstanceForType() {
+    return defaultInstance;
+  }
+  private static final UnknownFieldSet defaultInstance =
+    new UnknownFieldSet(Collections.<Integer, Field>emptyMap());
+
+  /**
+   * Construct an {@code UnknownFieldSet} around the given map.  The map is
+   * expected to be immutable.
+   */
+  private UnknownFieldSet(final Map<Integer, Field> fields) {
+    this.fields = fields;
+  }
+  private Map<Integer, Field> fields;
+
+
+  @Override
+  public boolean equals(final Object other) {
+    if (this == other) {
+      return true;
+    }
+    return (other instanceof UnknownFieldSet) &&
+           fields.equals(((UnknownFieldSet) other).fields);
+  }
+
+  @Override
+  public int hashCode() {
+    return fields.hashCode();
+  }
+
+  /** Get a map of fields in the set by number. */
+  public Map<Integer, Field> asMap() {
+    return fields;
+  }
+
+  /** Check if the given field number is present in the set. */
+  public boolean hasField(final int number) {
+    return fields.containsKey(number);
+  }
+
+  /**
+   * Get a field by number.  Returns an empty field if not present.  Never
+   * returns {@code null}.
+   */
+  public Field getField(final int number) {
+    final Field result = fields.get(number);
+    return (result == null) ? Field.getDefaultInstance() : result;
+  }
+
+  /** Serializes the set and writes it to {@code output}. */
+  public void writeTo(final CodedOutputStream output) throws IOException {
+    for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
+      entry.getValue().writeTo(entry.getKey(), output);
+    }
+  }
+
+  /**
+   * Converts the set to a string in protocol buffer text format. This is
+   * just a trivial wrapper around
+   * {@link TextFormat#printToString(UnknownFieldSet)}.
+   */
+  @Override
+  public String toString() {
+    return TextFormat.printToString(this);
+  }
+
+  /**
+   * Serializes the message to a {@code ByteString} and returns it. This is
+   * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
+   */
+  public ByteString toByteString() {
+    try {
+      final ByteString.CodedBuilder out =
+        ByteString.newCodedBuilder(getSerializedSize());
+      writeTo(out.getCodedOutput());
+      return out.build();
+    } catch (final IOException e) {
+      throw new RuntimeException(
+        "Serializing to a ByteString threw an IOException (should " +
+        "never happen).", e);
+    }
+  }
+
+  /**
+   * Serializes the message to a {@code byte} array and returns it.  This is
+   * just a trivial wrapper around {@link #writeTo(CodedOutputStream)}.
+   */
+  public byte[] toByteArray() {
+    try {
+      final byte[] result = new byte[getSerializedSize()];
+      final CodedOutputStream output = CodedOutputStream.newInstance(result);
+      writeTo(output);
+      output.checkNoSpaceLeft();
+      return result;
+    } catch (final IOException e) {
+      throw new RuntimeException(
+        "Serializing to a byte array threw an IOException " +
+        "(should never happen).", e);
+    }
+  }
+
+  /**
+   * Serializes the message and writes it to {@code output}.  This is just a
+   * trivial wrapper around {@link #writeTo(CodedOutputStream)}.
+   */
+  public void writeTo(final OutputStream output) throws IOException {
+    final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
+    writeTo(codedOutput);
+    codedOutput.flush();
+  }
+
+  public void writeDelimitedTo(OutputStream output) throws IOException {
+    final CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
+    codedOutput.writeRawVarint32(getSerializedSize());
+    writeTo(codedOutput);
+    codedOutput.flush();
+  }
+
+  /** Get the number of bytes required to encode this set. */
+  public int getSerializedSize() {
+    int result = 0;
+    for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
+      result += entry.getValue().getSerializedSize(entry.getKey());
+    }
+    return result;
+  }
+
+  /**
+   * Serializes the set and writes it to {@code output} using
+   * {@code MessageSet} wire format.
+   */
+  public void writeAsMessageSetTo(final CodedOutputStream output)
+      throws IOException {
+    for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
+      entry.getValue().writeAsMessageSetExtensionTo(
+        entry.getKey(), output);
+    }
+  }
+
+  /**
+   * Get the number of bytes required to encode this set using
+   * {@code MessageSet} wire format.
+   */
+  public int getSerializedSizeAsMessageSet() {
+    int result = 0;
+    for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
+      result += entry.getValue().getSerializedSizeAsMessageSetExtension(
+        entry.getKey());
+    }
+    return result;
+  }
+
+  public boolean isInitialized() {
+    // UnknownFieldSets do not have required fields, so they are always
+    // initialized.
+    return true;
+  }
+
+  /** Parse an {@code UnknownFieldSet} from the given input stream. */
+  public static UnknownFieldSet parseFrom(final CodedInputStream input)
+                                          throws IOException {
+    return newBuilder().mergeFrom(input).build();
+  }
+
+  /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */
+  public static UnknownFieldSet parseFrom(final ByteString data)
+      throws InvalidProtocolBufferException {
+    return newBuilder().mergeFrom(data).build();
+  }
+
+  /** Parse {@code data} as an {@code UnknownFieldSet} and return it. */
+  public static UnknownFieldSet parseFrom(final byte[] data)
+      throws InvalidProtocolBufferException {
+    return newBuilder().mergeFrom(data).build();
+  }
+
+  /** Parse an {@code UnknownFieldSet} from {@code input} and return it. */
+  public static UnknownFieldSet parseFrom(final InputStream input)
+                                          throws IOException {
+    return newBuilder().mergeFrom(input).build();
+  }
+
+  public Builder newBuilderForType() {
+    return newBuilder();
+  }
+
+  public Builder toBuilder() {
+    return newBuilder().mergeFrom(this);
+  }
+
+  /**
+   * Builder for {@link UnknownFieldSet}s.
+   *
+   * <p>Note that this class maintains {@link Field.Builder}s for all fields
+   * in the set.  Thus, adding one element to an existing {@link Field} does not
+   * require making a copy.  This is important for efficient parsing of
+   * unknown repeated fields.  However, it implies that {@link Field}s cannot
+   * be constructed independently, nor can two {@link UnknownFieldSet}s share
+   * the same {@code Field} object.
+   *
+   * <p>Use {@link UnknownFieldSet#newBuilder()} to construct a {@code Builder}.
+   */
+  public static final class Builder implements MessageLite.Builder {
+    // This constructor should never be called directly (except from 'create').
+    private Builder() {}
+
+    private Map<Integer, Field> fields;
+
+    // Optimization:  We keep around a builder for the last field that was
+    //   modified so that we can efficiently add to it multiple times in a
+    //   row (important when parsing an unknown repeated field).
+    private int lastFieldNumber;
+    private Field.Builder lastField;
+
+    private static Builder create() {
+      Builder builder = new Builder();
+      builder.reinitialize();
+      return builder;
+    }
+
+    /**
+     * Get a field builder for the given field number which includes any
+     * values that already exist.
+     */
+    private Field.Builder getFieldBuilder(final int number) {
+      if (lastField != null) {
+        if (number == lastFieldNumber) {
+          return lastField;
+        }
+        // Note:  addField() will reset lastField and lastFieldNumber.
+        addField(lastFieldNumber, lastField.build());
+      }
+      if (number == 0) {
+        return null;
+      } else {
+        final Field existing = fields.get(number);
+        lastFieldNumber = number;
+        lastField = Field.newBuilder();
+        if (existing != null) {
+          lastField.mergeFrom(existing);
+        }
+        return lastField;
+      }
+    }
+
+    /**
+     * Build the {@link UnknownFieldSet} and return it.
+     *
+     * <p>Once {@code build()} has been called, the {@code Builder} will no
+     * longer be usable.  Calling any method after {@code build()} will result
+     * in undefined behavior and can cause a {@code NullPointerException} to be
+     * thrown.
+     */
+    public UnknownFieldSet build() {
+      getFieldBuilder(0);  // Force lastField to be built.
+      final UnknownFieldSet result;
+      if (fields.isEmpty()) {
+        result = getDefaultInstance();
+      } else {
+        result = new UnknownFieldSet(Collections.unmodifiableMap(fields));
+      }
+      fields = null;
+      return result;
+    }
+
+    public UnknownFieldSet buildPartial() {
+      // No required fields, so this is the same as build().
+      return build();
+    }
+
+    @Override
+    public Builder clone() {
+      getFieldBuilder(0);  // Force lastField to be built.
+      return UnknownFieldSet.newBuilder().mergeFrom(
+          new UnknownFieldSet(fields));
+    }
+
+    public UnknownFieldSet getDefaultInstanceForType() {
+      return UnknownFieldSet.getDefaultInstance();
+    }
+
+    private void reinitialize() {
+      fields = Collections.emptyMap();
+      lastFieldNumber = 0;
+      lastField = null;
+    }
+
+    /** Reset the builder to an empty set. */
+    public Builder clear() {
+      reinitialize();
+      return this;
+    }
+    
+    /** Clear fields from the set with a given field number. */
+    public Builder clearField(final int number) {
+      if (number == 0) {
+        throw new IllegalArgumentException("Zero is not a valid field number.");
+      }
+      if (lastField != null && lastFieldNumber == number) {
+        // Discard this.
+        lastField = null;
+        lastFieldNumber = 0;
+      }
+      if (fields.containsKey(number)) {
+        fields.remove(number);
+      }
+      return this;
+    }
+
+    /**
+     * Merge the fields from {@code other} into this set.  If a field number
+     * exists in both sets, {@code other}'s values for that field will be
+     * appended to the values in this set.
+     */
+    public Builder mergeFrom(final UnknownFieldSet other) {
+      if (other != getDefaultInstance()) {
+        for (final Map.Entry<Integer, Field> entry : other.fields.entrySet()) {
+          mergeField(entry.getKey(), entry.getValue());
+        }
+      }
+      return this;
+    }
+
+    /**
+     * Add a field to the {@code UnknownFieldSet}.  If a field with the same
+     * number already exists, the two are merged.
+     */
+    public Builder mergeField(final int number, final Field field) {
+      if (number == 0) {
+        throw new IllegalArgumentException("Zero is not a valid field number.");
+      }
+      if (hasField(number)) {
+        getFieldBuilder(number).mergeFrom(field);
+      } else {
+        // Optimization:  We could call getFieldBuilder(number).mergeFrom(field)
+        // in this case, but that would create a copy of the Field object.
+        // We'd rather reuse the one passed to us, so call addField() instead.
+        addField(number, field);
+      }
+      return this;
+    }
+
+    /**
+     * Convenience method for merging a new field containing a single varint
+     * value.  This is used in particular when an unknown enum value is
+     * encountered.
+     */
+    public Builder mergeVarintField(final int number, final int value) {
+      if (number == 0) {
+        throw new IllegalArgumentException("Zero is not a valid field number.");
+      }
+      getFieldBuilder(number).addVarint(value);
+      return this;
+    }
+
+    /** Check if the given field number is present in the set. */
+    public boolean hasField(final int number) {
+      if (number == 0) {
+        throw new IllegalArgumentException("Zero is not a valid field number.");
+      }
+      return number == lastFieldNumber || fields.containsKey(number);
+    }
+
+    /**
+     * Add a field to the {@code UnknownFieldSet}.  If a field with the same
+     * number already exists, it is removed.
+     */
+    public Builder addField(final int number, final Field field) {
+      if (number == 0) {
+        throw new IllegalArgumentException("Zero is not a valid field number.");
+      }
+      if (lastField != null && lastFieldNumber == number) {
+        // Discard this.
+        lastField = null;
+        lastFieldNumber = 0;
+      }
+      if (fields.isEmpty()) {
+        fields = new TreeMap<Integer,Field>();
+      }
+      fields.put(number, field);
+      return this;
+    }
+
+    /**
+     * Get all present {@code Field}s as an immutable {@code Map}.  If more
+     * fields are added, the changes may or may not be reflected in this map.
+     */
+    public Map<Integer, Field> asMap() {
+      getFieldBuilder(0);  // Force lastField to be built.
+      return Collections.unmodifiableMap(fields);
+    }
+
+    /**
+     * Parse an entire message from {@code input} and merge its fields into
+     * this set.
+     */
+    public Builder mergeFrom(final CodedInputStream input) throws IOException {
+      while (true) {
+        final int tag = input.readTag();
+        if (tag == 0 || !mergeFieldFrom(tag, input)) {
+          break;
+        }
+      }
+      return this;
+    }
+
+    /**
+     * Parse a single field from {@code input} and merge it into this set.
+     * @param tag The field's tag number, which was already parsed.
+     * @return {@code false} if the tag is an end group tag.
+     */
+    public boolean mergeFieldFrom(final int tag, final CodedInputStream input)
+                                  throws IOException {
+      final int number = WireFormat.getTagFieldNumber(tag);
+      switch (WireFormat.getTagWireType(tag)) {
+        case WireFormat.WIRETYPE_VARINT:
+          getFieldBuilder(number).addVarint(input.readInt64());
+          return true;
+        case WireFormat.WIRETYPE_FIXED64:
+          getFieldBuilder(number).addFixed64(input.readFixed64());
+          return true;
+        case WireFormat.WIRETYPE_LENGTH_DELIMITED:
+          getFieldBuilder(number).addLengthDelimited(input.readBytes());
+          return true;
+        case WireFormat.WIRETYPE_START_GROUP:
+          final Builder subBuilder = newBuilder();
+          input.readGroup(number, subBuilder,
+                          ExtensionRegistry.getEmptyRegistry());
+          getFieldBuilder(number).addGroup(subBuilder.build());
+          return true;
+        case WireFormat.WIRETYPE_END_GROUP:
+          return false;
+        case WireFormat.WIRETYPE_FIXED32:
+          getFieldBuilder(number).addFixed32(input.readFixed32());
+          return true;
+        default:
+          throw InvalidProtocolBufferException.invalidWireType();
+      }
+    }
+
+    /**
+     * Parse {@code data} as an {@code UnknownFieldSet} and merge it with the
+     * set being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream)}.
+     */
+    public Builder mergeFrom(final ByteString data)
+        throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input = data.newCodedInput();
+        mergeFrom(input);
+        input.checkLastTagWas(0);
+        return this;
+      } catch (final InvalidProtocolBufferException e) {
+        throw e;
+      } catch (final IOException e) {
+        throw new RuntimeException(
+          "Reading from a ByteString threw an IOException (should " +
+          "never happen).", e);
+      }
+    }
+
+    /**
+     * Parse {@code data} as an {@code UnknownFieldSet} and merge it with the
+     * set being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream)}.
+     */
+    public Builder mergeFrom(final byte[] data)
+        throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input = CodedInputStream.newInstance(data);
+        mergeFrom(input);
+        input.checkLastTagWas(0);
+        return this;
+      } catch (final InvalidProtocolBufferException e) {
+        throw e;
+      } catch (final IOException e) {
+        throw new RuntimeException(
+          "Reading from a byte array threw an IOException (should " +
+          "never happen).", e);
+      }
+    }
+
+    /**
+     * Parse an {@code UnknownFieldSet} from {@code input} and merge it with the
+     * set being built.  This is just a small wrapper around
+     * {@link #mergeFrom(CodedInputStream)}.
+     */
+    public Builder mergeFrom(final InputStream input) throws IOException {
+      final CodedInputStream codedInput = CodedInputStream.newInstance(input);
+      mergeFrom(codedInput);
+      codedInput.checkLastTagWas(0);
+      return this;
+    }
+
+    public boolean mergeDelimitedFrom(InputStream input)
+        throws IOException {
+      final int firstByte = input.read();
+      if (firstByte == -1) {
+        return false;
+      }
+      final int size = CodedInputStream.readRawVarint32(firstByte, input);
+      final InputStream limitedInput = new LimitedInputStream(input, size);
+      mergeFrom(limitedInput);
+      return true;
+    }
+
+    public boolean mergeDelimitedFrom(
+        InputStream input,
+        ExtensionRegistryLite extensionRegistry) throws IOException {
+      // UnknownFieldSet has no extensions.
+      return mergeDelimitedFrom(input);
+    }
+
+    public Builder mergeFrom(
+        CodedInputStream input,
+        ExtensionRegistryLite extensionRegistry) throws IOException {
+      // UnknownFieldSet has no extensions.
+      return mergeFrom(input);
+    }
+
+    public Builder mergeFrom(
+        ByteString data,
+        ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      // UnknownFieldSet has no extensions.
+      return mergeFrom(data);
+    }
+
+    public Builder mergeFrom(byte[] data, int off, int len)
+        throws InvalidProtocolBufferException {
+      try {
+        final CodedInputStream input =
+            CodedInputStream.newInstance(data, off, len);
+        mergeFrom(input);
+        input.checkLastTagWas(0);
+        return this;
+      } catch (InvalidProtocolBufferException e) {
+        throw e;
+      } catch (IOException e) {
+        throw new RuntimeException(
+          "Reading from a byte array threw an IOException (should " +
+          "never happen).", e);
+      }
+    }
+
+    public Builder mergeFrom(
+        byte[] data,
+        ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      // UnknownFieldSet has no extensions.
+      return mergeFrom(data);
+    }
+
+    public Builder mergeFrom(
+        byte[] data, int off, int len,
+        ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      // UnknownFieldSet has no extensions.
+      return mergeFrom(data, off, len);
+    }
+
+    public Builder mergeFrom(
+        InputStream input,
+        ExtensionRegistryLite extensionRegistry) throws IOException {
+      // UnknownFieldSet has no extensions.
+      return mergeFrom(input);
+    }
+
+    public boolean isInitialized() {
+      // UnknownFieldSets do not have required fields, so they are always
+      // initialized.
+      return true;
+    }
+  }
+
+  /**
+   * Represents a single field in an {@code UnknownFieldSet}.
+   *
+   * <p>A {@code Field} consists of five lists of values.  The lists correspond
+   * to the five "wire types" used in the protocol buffer binary format.
+   * The wire type of each field can be determined from the encoded form alone,
+   * without knowing the field's declared type.  So, we are able to parse
+   * unknown values at least this far and separate them.  Normally, only one
+   * of the five lists will contain any values, since it is impossible to
+   * define a valid message type that declares two different types for the
+   * same field number.  However, the code is designed to allow for the case
+   * where the same unknown field number is encountered using multiple different
+   * wire types.
+   *
+   * <p>{@code Field} is an immutable class.  To construct one, you must use a
+   * {@link Builder}.
+   *
+   * @see UnknownFieldSet
+   */
+  public static final class Field {
+    private Field() {}
+
+    /** Construct a new {@link Builder}. */
+    public static Builder newBuilder() {
+      return Builder.create();
+    }
+
+    /**
+     * Construct a new {@link Builder} and initialize it to a copy of
+     * {@code copyFrom}.
+     */
+    public static Builder newBuilder(final Field copyFrom) {
+      return newBuilder().mergeFrom(copyFrom);
+    }
+
+    /** Get an empty {@code Field}. */
+    public static Field getDefaultInstance() {
+      return fieldDefaultInstance;
+    }
+    private static final Field fieldDefaultInstance = newBuilder().build();
+
+    /** Get the list of varint values for this field. */
+    public List<Long> getVarintList()               { return varint;          }
+
+    /** Get the list of fixed32 values for this field. */
+    public List<Integer> getFixed32List()           { return fixed32;         }
+
+    /** Get the list of fixed64 values for this field. */
+    public List<Long> getFixed64List()              { return fixed64;         }
+
+    /** Get the list of length-delimited values for this field. */
+    public List<ByteString> getLengthDelimitedList() { return lengthDelimited; }
+
+    /**
+     * Get the list of embedded group values for this field.  These are
+     * represented using {@link UnknownFieldSet}s rather than {@link Message}s
+     * since the group's type is presumably unknown.
+     */
+    public List<UnknownFieldSet> getGroupList()      { return group;           }
+
+    @Override
+    public boolean equals(final Object other) {
+      if (this == other) {
+        return true;
+      }
+      if (!(other instanceof Field)) {
+        return false;
+      }
+      return Arrays.equals(getIdentityArray(),
+          ((Field) other).getIdentityArray());
+    }
+
+    @Override
+    public int hashCode() {
+      return Arrays.hashCode(getIdentityArray());
+    }
+
+    /**
+     * Returns the array of objects to be used to uniquely identify this
+     * {@link Field} instance.
+     */
+    private Object[] getIdentityArray() {
+      return new Object[] {
+          varint,
+          fixed32,
+          fixed64,
+          lengthDelimited,
+          group};
+    }
+
+    /**
+     * Serializes the field, including field number, and writes it to
+     * {@code output}.
+     */
+    public void writeTo(final int fieldNumber, final CodedOutputStream output)
+                        throws IOException {
+      for (final long value : varint) {
+        output.writeUInt64(fieldNumber, value);
+      }
+      for (final int value : fixed32) {
+        output.writeFixed32(fieldNumber, value);
+      }
+      for (final long value : fixed64) {
+        output.writeFixed64(fieldNumber, value);
+      }
+      for (final ByteString value : lengthDelimited) {
+        output.writeBytes(fieldNumber, value);
+      }
+      for (final UnknownFieldSet value : group) {
+        output.writeGroup(fieldNumber, value);
+      }
+    }
+
+    /**
+     * Get the number of bytes required to encode this field, including field
+     * number.
+     */
+    public int getSerializedSize(final int fieldNumber) {
+      int result = 0;
+      for (final long value : varint) {
+        result += CodedOutputStream.computeUInt64Size(fieldNumber, value);
+      }
+      for (final int value : fixed32) {
+        result += CodedOutputStream.computeFixed32Size(fieldNumber, value);
+      }
+      for (final long value : fixed64) {
+        result += CodedOutputStream.computeFixed64Size(fieldNumber, value);
+      }
+      for (final ByteString value : lengthDelimited) {
+        result += CodedOutputStream.computeBytesSize(fieldNumber, value);
+      }
+      for (final UnknownFieldSet value : group) {
+        result += CodedOutputStream.computeGroupSize(fieldNumber, value);
+      }
+      return result;
+    }
+
+    /**
+     * Serializes the field, including field number, and writes it to
+     * {@code output}, using {@code MessageSet} wire format.
+     */
+    public void writeAsMessageSetExtensionTo(
+        final int fieldNumber,
+        final CodedOutputStream output)
+        throws IOException {
+      for (final ByteString value : lengthDelimited) {
+        output.writeRawMessageSetExtension(fieldNumber, value);
+      }
+    }
+
+    /**
+     * Get the number of bytes required to encode this field, including field
+     * number, using {@code MessageSet} wire format.
+     */
+    public int getSerializedSizeAsMessageSetExtension(final int fieldNumber) {
+      int result = 0;
+      for (final ByteString value : lengthDelimited) {
+        result += CodedOutputStream.computeRawMessageSetExtensionSize(
+          fieldNumber, value);
+      }
+      return result;
+    }
+
+    private List<Long> varint;
+    private List<Integer> fixed32;
+    private List<Long> fixed64;
+    private List<ByteString> lengthDelimited;
+    private List<UnknownFieldSet> group;
+
+    /**
+     * Used to build a {@link Field} within an {@link UnknownFieldSet}.
+     *
+     * <p>Use {@link Field#newBuilder()} to construct a {@code Builder}.
+     */
+    public static final class Builder {
+      // This constructor should never be called directly (except from 'create').
+      private Builder() {}
+
+      private static Builder create() {
+        Builder builder = new Builder();
+        builder.result = new Field();
+        return builder;
+      }
+
+      private Field result;
+
+      /**
+       * Build the field.  After {@code build()} has been called, the
+       * {@code Builder} is no longer usable.  Calling any other method will
+       * result in undefined behavior and can cause a
+       * {@code NullPointerException} to be thrown.
+       */
+      public Field build() {
+        if (result.varint == null) {
+          result.varint = Collections.emptyList();
+        } else {
+          result.varint = Collections.unmodifiableList(result.varint);
+        }
+        if (result.fixed32 == null) {
+          result.fixed32 = Collections.emptyList();
+        } else {
+          result.fixed32 = Collections.unmodifiableList(result.fixed32);
+        }
+        if (result.fixed64 == null) {
+          result.fixed64 = Collections.emptyList();
+        } else {
+          result.fixed64 = Collections.unmodifiableList(result.fixed64);
+        }
+        if (result.lengthDelimited == null) {
+          result.lengthDelimited = Collections.emptyList();
+        } else {
+          result.lengthDelimited =
+            Collections.unmodifiableList(result.lengthDelimited);
+        }
+        if (result.group == null) {
+          result.group = Collections.emptyList();
+        } else {
+          result.group = Collections.unmodifiableList(result.group);
+        }
+
+        final Field returnMe = result;
+        result = null;
+        return returnMe;
+      }
+
+      /** Discard the field's contents. */
+      public Builder clear() {
+        result = new Field();
+        return this;
+      }
+
+      /**
+       * Merge the values in {@code other} into this field.  For each list
+       * of values, {@code other}'s values are append to the ones in this
+       * field.
+       */
+      public Builder mergeFrom(final Field other) {
+        if (!other.varint.isEmpty()) {
+          if (result.varint == null) {
+            result.varint = new ArrayList<Long>();
+          }
+          result.varint.addAll(other.varint);
+        }
+        if (!other.fixed32.isEmpty()) {
+          if (result.fixed32 == null) {
+            result.fixed32 = new ArrayList<Integer>();
+          }
+          result.fixed32.addAll(other.fixed32);
+        }
+        if (!other.fixed64.isEmpty()) {
+          if (result.fixed64 == null) {
+            result.fixed64 = new ArrayList<Long>();
+          }
+          result.fixed64.addAll(other.fixed64);
+        }
+        if (!other.lengthDelimited.isEmpty()) {
+          if (result.lengthDelimited == null) {
+            result.lengthDelimited = new ArrayList<ByteString>();
+          }
+          result.lengthDelimited.addAll(other.lengthDelimited);
+        }
+        if (!other.group.isEmpty()) {
+          if (result.group == null) {
+            result.group = new ArrayList<UnknownFieldSet>();
+          }
+          result.group.addAll(other.group);
+        }
+        return this;
+      }
+
+      /** Add a varint value. */
+      public Builder addVarint(final long value) {
+        if (result.varint == null) {
+          result.varint = new ArrayList<Long>();
+        }
+        result.varint.add(value);
+        return this;
+      }
+
+      /** Add a fixed32 value. */
+      public Builder addFixed32(final int value) {
+        if (result.fixed32 == null) {
+          result.fixed32 = new ArrayList<Integer>();
+        }
+        result.fixed32.add(value);
+        return this;
+      }
+
+      /** Add a fixed64 value. */
+      public Builder addFixed64(final long value) {
+        if (result.fixed64 == null) {
+          result.fixed64 = new ArrayList<Long>();
+        }
+        result.fixed64.add(value);
+        return this;
+      }
+
+      /** Add a length-delimited value. */
+      public Builder addLengthDelimited(final ByteString value) {
+        if (result.lengthDelimited == null) {
+          result.lengthDelimited = new ArrayList<ByteString>();
+        }
+        result.lengthDelimited.add(value);
+        return this;
+      }
+
+      /** Add an embedded group. */
+      public Builder addGroup(final UnknownFieldSet value) {
+        if (result.group == null) {
+          result.group = new ArrayList<UnknownFieldSet>();
+        }
+        result.group.add(value);
+        return this;
+      }
+    }
+  }
+
+  /**
+   * Parser to implement MessageLite interface.
+   */
+  public static final class Parser extends AbstractParser<UnknownFieldSet> {
+    public UnknownFieldSet parsePartialFrom(
+        CodedInputStream input, ExtensionRegistryLite extensionRegistry)
+        throws InvalidProtocolBufferException {
+      Builder builder = newBuilder();
+      try {
+        builder.mergeFrom(input);
+      } catch (InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(builder.buildPartial());
+      } catch (IOException e) {
+        throw new InvalidProtocolBufferException(e.getMessage())
+            .setUnfinishedMessage(builder.buildPartial());
+      }
+      return builder.buildPartial();
+    }
+  }
+
+  private static final Parser PARSER = new Parser();
+  public final Parser getParserForType() {
+    return PARSER;
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java b/protobuf/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
new file mode 100644
index 0000000..5cc005d
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java
@@ -0,0 +1,205 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.util.AbstractList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.RandomAccess;
+
+/**
+ * An implementation of {@link LazyStringList} that wraps another
+ * {@link LazyStringList} such that it cannot be modified via the wrapper.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class UnmodifiableLazyStringList extends AbstractList<String>
+    implements LazyStringList, RandomAccess {
+
+  private final LazyStringList list;
+
+  public UnmodifiableLazyStringList(LazyStringList list) {
+    this.list = list;
+  }
+
+  @Override
+  public String get(int index) {
+    return list.get(index);
+  }
+
+  @Override
+  public int size() {
+    return list.size();
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public ByteString getByteString(int index) {
+    return list.getByteString(index);
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public void add(ByteString element) {
+    throw new UnsupportedOperationException();
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public void set(int index, ByteString element) {
+    throw new UnsupportedOperationException();
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public boolean addAllByteString(Collection<? extends ByteString> element) {
+    throw new UnsupportedOperationException();
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public byte[] getByteArray(int index) {
+    return list.getByteArray(index);
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public void add(byte[] element) {
+    throw new UnsupportedOperationException();
+  }
+  
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public void set(int index, byte[] element) {
+    throw new UnsupportedOperationException();
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public boolean addAllByteArray(Collection<byte[]> element) {
+    throw new UnsupportedOperationException();
+  }
+
+  @Override
+  public ListIterator<String> listIterator(final int index) {
+    return new ListIterator<String>() {
+      ListIterator<String> iter = list.listIterator(index);
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public boolean hasNext() {
+        return iter.hasNext();
+      }
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public String next() {
+        return iter.next();
+      }
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public boolean hasPrevious() {
+        return iter.hasPrevious();
+      }
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public String previous() {
+        return iter.previous();
+      }
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public int nextIndex() {
+        return iter.nextIndex();
+      }
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public int previousIndex() {
+        return iter.previousIndex();
+      }
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public void remove() {
+        throw new UnsupportedOperationException();
+      }
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public void set(String o) {
+        throw new UnsupportedOperationException();
+      }
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public void add(String o) {
+        throw new UnsupportedOperationException();
+      }
+    };
+  }
+
+  @Override
+  public Iterator<String> iterator() {
+    return new Iterator<String>() {
+      Iterator<String> iter = list.iterator();
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public boolean hasNext() {
+        return iter.hasNext();
+      }
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public String next() {
+        return iter.next();
+      }
+
+      //@Override (Java 1.6 override semantics, but we must support 1.5)
+      public void remove() {
+        throw new UnsupportedOperationException();
+      }
+    };
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public List<?> getUnderlyingElements() {
+    // The returned value is already unmodifiable.
+    return list.getUnderlyingElements();
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public void mergeFrom(LazyStringList other) {
+    throw new UnsupportedOperationException();
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public List<byte[]> asByteArrayList() {
+    return Collections.unmodifiableList(list.asByteArrayList());
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public List<ByteString> asByteStringList() {
+    return Collections.unmodifiableList(list.asByteStringList());
+  }
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public LazyStringList getUnmodifiableView() {
+    return this;
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/Utf8.java b/protobuf/java/src/main/java/com/google/protobuf/Utf8.java
new file mode 100644
index 0000000..4d0ef53
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/Utf8.java
@@ -0,0 +1,349 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * A set of low-level, high-performance static utility methods related
+ * to the UTF-8 character encoding.  This class has no dependencies
+ * outside of the core JDK libraries.
+ *
+ * <p>There are several variants of UTF-8.  The one implemented by
+ * this class is the restricted definition of UTF-8 introduced in
+ * Unicode 3.1, which mandates the rejection of "overlong" byte
+ * sequences as well as rejection of 3-byte surrogate codepoint byte
+ * sequences.  Note that the UTF-8 decoder included in Oracle's JDK
+ * has been modified to also reject "overlong" byte sequences, but (as
+ * of 2011) still accepts 3-byte surrogate codepoint byte sequences.
+ *
+ * <p>The byte sequences considered valid by this class are exactly
+ * those that can be roundtrip converted to Strings and back to bytes
+ * using the UTF-8 charset, without loss: <pre> {@code
+ * Arrays.equals(bytes, new String(bytes, "UTF-8").getBytes("UTF-8"))
+ * }</pre>
+ *
+ * <p>See the Unicode Standard,</br>
+ * Table 3-6. <em>UTF-8 Bit Distribution</em>,</br>
+ * Table 3-7. <em>Well Formed UTF-8 Byte Sequences</em>.
+ *
+ * <p>This class supports decoding of partial byte sequences, so that the
+ * bytes in a complete UTF-8 byte sequences can be stored in multiple
+ * segments.  Methods typically return {@link #MALFORMED} if the partial
+ * byte sequence is definitely not well-formed, {@link #COMPLETE} if it is
+ * well-formed in the absence of additional input, or if the byte sequence
+ * apparently terminated in the middle of a character, an opaque integer
+ * "state" value containing enough information to decode the character when
+ * passed to a subsequent invocation of a partial decoding method.
+ *
+ * @author martinrb@google.com (Martin Buchholz)
+ */
+final class Utf8 {
+  private Utf8() {}
+
+  /**
+   * State value indicating that the byte sequence is well-formed and
+   * complete (no further bytes are needed to complete a character).
+   */
+  public static final int COMPLETE = 0;
+
+  /**
+   * State value indicating that the byte sequence is definitely not
+   * well-formed.
+   */
+  public static final int MALFORMED = -1;
+
+  // Other state values include the partial bytes of the incomplete
+  // character to be decoded in the simplest way: we pack the bytes
+  // into the state int in little-endian order.  For example:
+  //
+  // int state = byte1 ^ (byte2 << 8) ^ (byte3 << 16);
+  //
+  // Such a state is unpacked thus (note the ~ operation for byte2 to
+  // undo byte1's sign-extension bits):
+  //
+  // int byte1 = (byte) state;
+  // int byte2 = (byte) ~(state >> 8);
+  // int byte3 = (byte) (state >> 16);
+  //
+  // We cannot store a zero byte in the state because it would be
+  // indistinguishable from the absence of a byte.  But we don't need
+  // to, because partial bytes must always be negative.  When building
+  // a state, we ensure that byte1 is negative and subsequent bytes
+  // are valid trailing bytes.
+
+  /**
+   * Returns {@code true} if the given byte array is a well-formed
+   * UTF-8 byte sequence.
+   *
+   * <p>This is a convenience method, equivalent to a call to {@code
+   * isValidUtf8(bytes, 0, bytes.length)}.
+   */
+  public static boolean isValidUtf8(byte[] bytes) {
+    return isValidUtf8(bytes, 0, bytes.length);
+  }
+
+  /**
+   * Returns {@code true} if the given byte array slice is a
+   * well-formed UTF-8 byte sequence.  The range of bytes to be
+   * checked extends from index {@code index}, inclusive, to {@code
+   * limit}, exclusive.
+   *
+   * <p>This is a convenience method, equivalent to {@code
+   * partialIsValidUtf8(bytes, index, limit) == Utf8.COMPLETE}.
+   */
+  public static boolean isValidUtf8(byte[] bytes, int index, int limit) {
+    return partialIsValidUtf8(bytes, index, limit) == COMPLETE;
+  }
+
+  /**
+   * Tells whether the given byte array slice is a well-formed,
+   * malformed, or incomplete UTF-8 byte sequence.  The range of bytes
+   * to be checked extends from index {@code index}, inclusive, to
+   * {@code limit}, exclusive.
+   *
+   * @param state either {@link Utf8#COMPLETE} (if this is the initial decoding
+   * operation) or the value returned from a call to a partial decoding method
+   * for the previous bytes
+   *
+   * @return {@link #MALFORMED} if the partial byte sequence is
+   * definitely not well-formed, {@link #COMPLETE} if it is well-formed
+   * (no additional input needed), or if the byte sequence is
+   * "incomplete", i.e. apparently terminated in the middle of a character,
+   * an opaque integer "state" value containing enough information to
+   * decode the character when passed to a subsequent invocation of a
+   * partial decoding method.
+   */
+  public static int partialIsValidUtf8(
+      int state, byte[] bytes, int index, int limit) {
+    if (state != COMPLETE) {
+      // The previous decoding operation was incomplete (or malformed).
+      // We look for a well-formed sequence consisting of bytes from
+      // the previous decoding operation (stored in state) together
+      // with bytes from the array slice.
+      //
+      // We expect such "straddler characters" to be rare.
+
+      if (index >= limit) {  // No bytes? No progress.
+        return state;
+      }
+      int byte1 = (byte) state;
+      // byte1 is never ASCII.
+      if (byte1 < (byte) 0xE0) {
+        // two-byte form
+
+        // Simultaneously checks for illegal trailing-byte in
+        // leading position and overlong 2-byte form.
+        if (byte1 < (byte) 0xC2 ||
+            // byte2 trailing-byte test
+            bytes[index++] > (byte) 0xBF) {
+          return MALFORMED;
+        }
+      } else if (byte1 < (byte) 0xF0) {
+        // three-byte form
+
+        // Get byte2 from saved state or array
+        int byte2 = (byte) ~(state >> 8);
+        if (byte2 == 0) {
+          byte2 = bytes[index++];
+          if (index >= limit) {
+            return incompleteStateFor(byte1, byte2);
+          }
+        }
+        if (byte2 > (byte) 0xBF ||
+            // overlong? 5 most significant bits must not all be zero
+            (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0) ||
+            // illegal surrogate codepoint?
+            (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0) ||
+            // byte3 trailing-byte test
+            bytes[index++] > (byte) 0xBF) {
+          return MALFORMED;
+        }
+      } else {
+        // four-byte form
+
+        // Get byte2 and byte3 from saved state or array
+        int byte2 = (byte) ~(state >> 8);
+        int byte3 = 0;
+        if (byte2 == 0) {
+          byte2 = bytes[index++];
+          if (index >= limit) {
+            return incompleteStateFor(byte1, byte2);
+          }
+        } else {
+          byte3 = (byte) (state >> 16);
+        }
+        if (byte3 == 0) {
+          byte3 = bytes[index++];
+          if (index >= limit) {
+            return incompleteStateFor(byte1, byte2, byte3);
+          }
+        }
+
+        // If we were called with state == MALFORMED, then byte1 is 0xFF,
+        // which never occurs in well-formed UTF-8, and so we will return
+        // MALFORMED again below.
+
+        if (byte2 > (byte) 0xBF ||
+            // Check that 1 <= plane <= 16.  Tricky optimized form of:
+            // if (byte1 > (byte) 0xF4 ||
+            //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+            //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+            (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0 ||
+            // byte3 trailing-byte test
+            byte3 > (byte) 0xBF ||
+            // byte4 trailing-byte test
+             bytes[index++] > (byte) 0xBF) {
+          return MALFORMED;
+        }
+      }
+    }
+
+    return partialIsValidUtf8(bytes, index, limit);
+  }
+
+  /**
+   * Tells whether the given byte array slice is a well-formed,
+   * malformed, or incomplete UTF-8 byte sequence.  The range of bytes
+   * to be checked extends from index {@code index}, inclusive, to
+   * {@code limit}, exclusive.
+   *
+   * <p>This is a convenience method, equivalent to a call to {@code
+   * partialIsValidUtf8(Utf8.COMPLETE, bytes, index, limit)}.
+   *
+   * @return {@link #MALFORMED} if the partial byte sequence is
+   * definitely not well-formed, {@link #COMPLETE} if it is well-formed
+   * (no additional input needed), or if the byte sequence is
+   * "incomplete", i.e. apparently terminated in the middle of a character,
+   * an opaque integer "state" value containing enough information to
+   * decode the character when passed to a subsequent invocation of a
+   * partial decoding method.
+   */
+  public static int partialIsValidUtf8(
+      byte[] bytes, int index, int limit) {
+    // Optimize for 100% ASCII.
+    // Hotspot loves small simple top-level loops like this.
+    while (index < limit && bytes[index] >= 0) {
+      index++;
+    }
+
+    return (index >= limit) ? COMPLETE :
+        partialIsValidUtf8NonAscii(bytes, index, limit);
+  }
+
+  private static int partialIsValidUtf8NonAscii(
+      byte[] bytes, int index, int limit) {
+    for (;;) {
+      int byte1, byte2;
+
+      // Optimize for interior runs of ASCII bytes.
+      do {
+        if (index >= limit) {
+          return COMPLETE;
+        }
+      } while ((byte1 = bytes[index++]) >= 0);
+
+      if (byte1 < (byte) 0xE0) {
+        // two-byte form
+
+        if (index >= limit) {
+          return byte1;
+        }
+
+        // Simultaneously checks for illegal trailing-byte in
+        // leading position and overlong 2-byte form.
+        if (byte1 < (byte) 0xC2 ||
+            bytes[index++] > (byte) 0xBF) {
+          return MALFORMED;
+        }
+      } else if (byte1 < (byte) 0xF0) {
+        // three-byte form
+
+        if (index >= limit - 1) { // incomplete sequence
+          return incompleteStateFor(bytes, index, limit);
+        }
+        if ((byte2 = bytes[index++]) > (byte) 0xBF ||
+            // overlong? 5 most significant bits must not all be zero
+            (byte1 == (byte) 0xE0 && byte2 < (byte) 0xA0) ||
+            // check for illegal surrogate codepoints
+            (byte1 == (byte) 0xED && byte2 >= (byte) 0xA0) ||
+            // byte3 trailing-byte test
+            bytes[index++] > (byte) 0xBF) {
+          return MALFORMED;
+        }
+      } else {
+        // four-byte form
+
+        if (index >= limit - 2) {  // incomplete sequence
+          return incompleteStateFor(bytes, index, limit);
+        }
+        if ((byte2 = bytes[index++]) > (byte) 0xBF ||
+            // Check that 1 <= plane <= 16.  Tricky optimized form of:
+            // if (byte1 > (byte) 0xF4 ||
+            //     byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 ||
+            //     byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F)
+            (((byte1 << 28) + (byte2 - (byte) 0x90)) >> 30) != 0 ||
+            // byte3 trailing-byte test
+            bytes[index++] > (byte) 0xBF ||
+            // byte4 trailing-byte test
+            bytes[index++] > (byte) 0xBF) {
+          return MALFORMED;
+        }
+      }
+    }
+  }
+
+  private static int incompleteStateFor(int byte1) {
+    return (byte1 > (byte) 0xF4) ?
+        MALFORMED : byte1;
+  }
+
+  private static int incompleteStateFor(int byte1, int byte2) {
+    return (byte1 > (byte) 0xF4 ||
+            byte2 > (byte) 0xBF) ?
+        MALFORMED : byte1 ^ (byte2 << 8);
+  }
+
+  private static int incompleteStateFor(int byte1, int byte2, int byte3) {
+    return (byte1 > (byte) 0xF4 ||
+            byte2 > (byte) 0xBF ||
+            byte3 > (byte) 0xBF) ?
+        MALFORMED : byte1 ^ (byte2 << 8) ^ (byte3 << 16);
+  }
+
+  private static int incompleteStateFor(byte[] bytes, int index, int limit) {
+    int byte1 = bytes[index - 1];
+    switch (limit - index) {
+      case 0: return incompleteStateFor(byte1);
+      case 1: return incompleteStateFor(byte1, bytes[index]);
+      case 2: return incompleteStateFor(byte1, bytes[index], bytes[index + 1]);
+      default: throw new AssertionError();
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/WireFormat.java b/protobuf/java/src/main/java/com/google/protobuf/WireFormat.java
new file mode 100644
index 0000000..eba2528
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/WireFormat.java
@@ -0,0 +1,163 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * This class is used internally by the Protocol Buffer library and generated
+ * message implementations.  It is public only because those generated messages
+ * do not reside in the {@code protobuf} package.  Others should not use this
+ * class directly.
+ *
+ * This class contains constants and helper functions useful for dealing with
+ * the Protocol Buffer wire format.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class WireFormat {
+  // Do not allow instantiation.
+  private WireFormat() {}
+
+  public static final int WIRETYPE_VARINT           = 0;
+  public static final int WIRETYPE_FIXED64          = 1;
+  public static final int WIRETYPE_LENGTH_DELIMITED = 2;
+  public static final int WIRETYPE_START_GROUP      = 3;
+  public static final int WIRETYPE_END_GROUP        = 4;
+  public static final int WIRETYPE_FIXED32          = 5;
+
+  static final int TAG_TYPE_BITS = 3;
+  static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;
+
+  /** Given a tag value, determines the wire type (the lower 3 bits). */
+  static int getTagWireType(final int tag) {
+    return tag & TAG_TYPE_MASK;
+  }
+
+  /** Given a tag value, determines the field number (the upper 29 bits). */
+  public static int getTagFieldNumber(final int tag) {
+    return tag >>> TAG_TYPE_BITS;
+  }
+
+  /** Makes a tag value given a field number and wire type. */
+  static int makeTag(final int fieldNumber, final int wireType) {
+    return (fieldNumber << TAG_TYPE_BITS) | wireType;
+  }
+
+  /**
+   * Lite equivalent to {@link Descriptors.FieldDescriptor.JavaType}.  This is
+   * only here to support the lite runtime and should not be used by users.
+   */
+  public enum JavaType {
+    INT(0),
+    LONG(0L),
+    FLOAT(0F),
+    DOUBLE(0D),
+    BOOLEAN(false),
+    STRING(""),
+    BYTE_STRING(ByteString.EMPTY),
+    ENUM(null),
+    MESSAGE(null);
+
+    JavaType(final Object defaultDefault) {
+      this.defaultDefault = defaultDefault;
+    }
+
+    /**
+     * The default default value for fields of this type, if it's a primitive
+     * type.
+     */
+    Object getDefaultDefault() {
+      return defaultDefault;
+    }
+
+    private final Object defaultDefault;
+  }
+
+  /**
+   * Lite equivalent to {@link Descriptors.FieldDescriptor.Type}.  This is
+   * only here to support the lite runtime and should not be used by users.
+   */
+  public enum FieldType {
+    DOUBLE  (JavaType.DOUBLE     , WIRETYPE_FIXED64         ),
+    FLOAT   (JavaType.FLOAT      , WIRETYPE_FIXED32         ),
+    INT64   (JavaType.LONG       , WIRETYPE_VARINT          ),
+    UINT64  (JavaType.LONG       , WIRETYPE_VARINT          ),
+    INT32   (JavaType.INT        , WIRETYPE_VARINT          ),
+    FIXED64 (JavaType.LONG       , WIRETYPE_FIXED64         ),
+    FIXED32 (JavaType.INT        , WIRETYPE_FIXED32         ),
+    BOOL    (JavaType.BOOLEAN    , WIRETYPE_VARINT          ),
+    STRING  (JavaType.STRING     , WIRETYPE_LENGTH_DELIMITED) {
+      public boolean isPackable() { return false; }
+    },
+    GROUP   (JavaType.MESSAGE    , WIRETYPE_START_GROUP     ) {
+      public boolean isPackable() { return false; }
+    },
+    MESSAGE (JavaType.MESSAGE    , WIRETYPE_LENGTH_DELIMITED) {
+      public boolean isPackable() { return false; }
+    },
+    BYTES   (JavaType.BYTE_STRING, WIRETYPE_LENGTH_DELIMITED) {
+      public boolean isPackable() { return false; }
+    },
+    UINT32  (JavaType.INT        , WIRETYPE_VARINT          ),
+    ENUM    (JavaType.ENUM       , WIRETYPE_VARINT          ),
+    SFIXED32(JavaType.INT        , WIRETYPE_FIXED32         ),
+    SFIXED64(JavaType.LONG       , WIRETYPE_FIXED64         ),
+    SINT32  (JavaType.INT        , WIRETYPE_VARINT          ),
+    SINT64  (JavaType.LONG       , WIRETYPE_VARINT          );
+
+    FieldType(final JavaType javaType, final int wireType) {
+      this.javaType = javaType;
+      this.wireType = wireType;
+    }
+
+    private final JavaType javaType;
+    private final int wireType;
+
+    public JavaType getJavaType() { return javaType; }
+    public int getWireType() { return wireType; }
+
+    public boolean isPackable() { return true; }
+  }
+
+  // Field numbers for fields in MessageSet wire format.
+  static final int MESSAGE_SET_ITEM    = 1;
+  static final int MESSAGE_SET_TYPE_ID = 2;
+  static final int MESSAGE_SET_MESSAGE = 3;
+
+  // Tag numbers.
+  static final int MESSAGE_SET_ITEM_TAG =
+    makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP);
+  static final int MESSAGE_SET_ITEM_END_TAG =
+    makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP);
+  static final int MESSAGE_SET_TYPE_ID_TAG =
+    makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT);
+  static final int MESSAGE_SET_MESSAGE_TAG =
+    makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED);
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/micro/ByteStringMicro.java b/protobuf/java/src/main/java/com/google/protobuf/micro/ByteStringMicro.java
new file mode 100644
index 0000000..6e87dc9
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/micro/ByteStringMicro.java
@@ -0,0 +1,227 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.micro;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Immutable array of bytes.
+ *
+ * @author crazybob@google.com Bob Lee
+ * @author kenton@google.com Kenton Varda
+ */
+public final class ByteStringMicro {
+  private final byte[] bytes;
+
+  private ByteStringMicro(final byte[] bytes) {
+    this.bytes = bytes;
+  }
+
+  /**
+   * Gets the byte at the given index.
+   *
+   * @throws ArrayIndexOutOfBoundsException {@code index} is < 0 or >= size
+   */
+  public byte byteAt(final int index) {
+    return bytes[index];
+  }
+
+  /**
+   * Gets the number of bytes.
+   */
+  public int size() {
+    return bytes.length;
+  }
+
+  /**
+   * Returns {@code true} if the size is {@code 0}, {@code false} otherwise.
+   */
+  public boolean isEmpty() {
+    return bytes.length == 0;
+  }
+
+  // =================================================================
+  // byte[] -> ByteStringMicro
+
+  /**
+   * Empty ByteStringMicro.
+   */
+  public static final ByteStringMicro EMPTY = new ByteStringMicro(new byte[0]);
+
+  /**
+   * Copies the given bytes into a {@code ByteStringMicro}.
+   */
+  public static ByteStringMicro copyFrom(final byte[] bytes, final int offset,
+                                    final int size) {
+    final byte[] copy = new byte[size];
+    System.arraycopy(bytes, offset, copy, 0, size);
+    return new ByteStringMicro(copy);
+  }
+
+  /**
+   * Copies the given bytes into a {@code ByteStringMicro}.
+   */
+  public static ByteStringMicro copyFrom(final byte[] bytes) {
+    return copyFrom(bytes, 0, bytes.length);
+  }
+
+  /**
+   * Encodes {@code text} into a sequence of bytes using the named charset
+   * and returns the result as a {@code ByteStringMicro}.
+   */
+  public static ByteStringMicro copyFrom(final String text, final String charsetName)
+      throws UnsupportedEncodingException {
+    return new ByteStringMicro(text.getBytes(charsetName));
+  }
+
+  /**
+   * Encodes {@code text} into a sequence of UTF-8 bytes and returns the
+   * result as a {@code ByteStringMicro}.
+   */
+  public static ByteStringMicro copyFromUtf8(final String text) {
+    try {
+      return new ByteStringMicro(text.getBytes("UTF-8"));
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 not supported?");
+    }
+  }
+
+  // =================================================================
+  // ByteStringMicro -> byte[]
+
+  /**
+   * Copies bytes into a buffer at the given offset.
+   *
+   * @param target buffer to copy into
+   * @param offset in the target buffer
+   */
+  public void copyTo(final byte[] target, final int offset) {
+    System.arraycopy(bytes, 0, target, offset, bytes.length);
+  }
+
+  /**
+   * Copies bytes into a buffer.
+   *
+   * @param target buffer to copy into
+   * @param sourceOffset offset within these bytes
+   * @param targetOffset offset within the target buffer
+   * @param size number of bytes to copy
+   */
+  public void copyTo(final byte[] target, final int sourceOffset,
+                     final int targetOffset,
+      final int size) {
+    System.arraycopy(bytes, sourceOffset, target, targetOffset, size);
+  }
+
+  /**
+   * Copies bytes to a {@code byte[]}.
+   */
+  public byte[] toByteArray() {
+    final int size = bytes.length;
+    final byte[] copy = new byte[size];
+    System.arraycopy(bytes, 0, copy, 0, size);
+    return copy;
+  }
+
+  /**
+   * Constructs a new {@code String} by decoding the bytes using the
+   * specified charset.
+   */
+  public String toString(final String charsetName)
+      throws UnsupportedEncodingException {
+    return new String(bytes, charsetName);
+  }
+
+  /**
+   * Constructs a new {@code String} by decoding the bytes as UTF-8.
+   */
+  public String toStringUtf8() {
+    try {
+      return new String(bytes, "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 not supported?");
+    }
+  }
+
+  // =================================================================
+  // equals() and hashCode()
+
+  //@Override for compatibility with Java 1.3 code we can't use annotations
+  public boolean equals(final Object o) {
+    if (o == this) {
+      return true;
+    }
+
+    if (!(o instanceof ByteStringMicro)) {
+      return false;
+    }
+
+    final ByteStringMicro other = (ByteStringMicro) o;
+    final int size = bytes.length;
+    if (size != other.bytes.length) {
+      return false;
+    }
+
+    final byte[] thisBytes = bytes;
+    final byte[] otherBytes = other.bytes;
+    for (int i = 0; i < size; i++) {
+      if (thisBytes[i] != otherBytes[i]) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  private volatile int hash = 0;
+
+  //@Override for compatibility with Java 1.3 code we can't use annotations
+  public int hashCode() {
+    int h = hash;
+
+    if (h == 0) {
+      final byte[] thisBytes = bytes;
+      final int size = bytes.length;
+
+      h = size;
+      for (int i = 0; i < size; i++) {
+        h = h * 31 + thisBytes[i];
+      }
+      if (h == 0) {
+        h = 1;
+      }
+
+      hash = h;
+    }
+
+    return h;
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/micro/CodedInputStreamMicro.java b/protobuf/java/src/main/java/com/google/protobuf/micro/CodedInputStreamMicro.java
new file mode 100644
index 0000000..cf1dc67
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/micro/CodedInputStreamMicro.java
@@ -0,0 +1,806 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.micro;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Reads and decodes protocol message fields.
+ *
+ * This class contains two kinds of methods:  methods that read specific
+ * protocol message constructs and field types (e.g. {@link #readTag()} and
+ * {@link #readInt32()}) and methods that read low-level values (e.g.
+ * {@link #readRawVarint32()} and {@link #readRawBytes}).  If you are reading
+ * encoded protocol messages, you should use the former methods, but if you are
+ * reading some other format of your own design, use the latter.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class CodedInputStreamMicro {
+  /**
+   * Create a new CodedInputStream wrapping the given InputStream.
+   */
+  public static CodedInputStreamMicro newInstance(final InputStream input) {
+    return new CodedInputStreamMicro(input);
+  }
+
+  /**
+   * Create a new CodedInputStream wrapping the given byte array.
+   */
+  public static CodedInputStreamMicro newInstance(final byte[] buf) {
+    return newInstance(buf, 0, buf.length);
+  }
+
+  /**
+   * Create a new CodedInputStream wrapping the given byte array slice.
+   */
+  public static CodedInputStreamMicro newInstance(final byte[] buf, final int off,
+                                             final int len) {
+    return new CodedInputStreamMicro(buf, off, len);
+  }
+
+  // -----------------------------------------------------------------
+
+  /**
+   * Attempt to read a field tag, returning zero if we have reached EOF.
+   * Protocol message parsers use this to read tags, since a protocol message
+   * may legally end wherever a tag occurs, and zero is not a valid tag number.
+   */
+  public int readTag() throws IOException {
+    if (isAtEnd()) {
+      lastTag = 0;
+      return 0;
+    }
+
+    lastTag = readRawVarint32();
+    if (lastTag == 0) {
+      // If we actually read zero, that's not a valid tag.
+      throw InvalidProtocolBufferMicroException.invalidTag();
+    }
+    return lastTag;
+  }
+
+  /**
+   * Verifies that the last call to readTag() returned the given tag value.
+   * This is used to verify that a nested group ended with the correct
+   * end tag.
+   *
+   * @throws InvalidProtocolBufferMicroException {@code value} does not match the
+   *                                        last tag.
+   */
+  public void checkLastTagWas(final int value)
+                              throws InvalidProtocolBufferMicroException {
+    if (lastTag != value) {
+      throw InvalidProtocolBufferMicroException.invalidEndTag();
+    }
+  }
+
+  /**
+   * Reads and discards a single field, given its tag value.
+   *
+   * @return {@code false} if the tag is an endgroup tag, in which case
+   *         nothing is skipped.  Otherwise, returns {@code true}.
+   */
+  public boolean skipField(final int tag) throws IOException {
+    switch (WireFormatMicro.getTagWireType(tag)) {
+      case WireFormatMicro.WIRETYPE_VARINT:
+        readInt32();
+        return true;
+      case WireFormatMicro.WIRETYPE_FIXED64:
+        readRawLittleEndian64();
+        return true;
+      case WireFormatMicro.WIRETYPE_LENGTH_DELIMITED:
+        skipRawBytes(readRawVarint32());
+        return true;
+      case WireFormatMicro.WIRETYPE_START_GROUP:
+        skipMessage();
+        checkLastTagWas(
+          WireFormatMicro.makeTag(WireFormatMicro.getTagFieldNumber(tag),
+                             WireFormatMicro.WIRETYPE_END_GROUP));
+        return true;
+      case WireFormatMicro.WIRETYPE_END_GROUP:
+        return false;
+      case WireFormatMicro.WIRETYPE_FIXED32:
+        readRawLittleEndian32();
+        return true;
+      default:
+        throw InvalidProtocolBufferMicroException.invalidWireType();
+    }
+  }
+
+  /**
+   * Reads and discards an entire message.  This will read either until EOF
+   * or until an endgroup tag, whichever comes first.
+   */
+  public void skipMessage() throws IOException {
+    while (true) {
+      final int tag = readTag();
+      if (tag == 0 || !skipField(tag)) {
+        return;
+      }
+    }
+  }
+
+  // -----------------------------------------------------------------
+
+  /** Read a {@code double} field value from the stream. */
+  public double readDouble() throws IOException {
+    return Double.longBitsToDouble(readRawLittleEndian64());
+  }
+
+  /** Read a {@code float} field value from the stream. */
+  public float readFloat() throws IOException {
+    return Float.intBitsToFloat(readRawLittleEndian32());
+  }
+
+  /** Read a {@code uint64} field value from the stream. */
+  public long readUInt64() throws IOException {
+    return readRawVarint64();
+  }
+
+  /** Read an {@code int64} field value from the stream. */
+  public long readInt64() throws IOException {
+    return readRawVarint64();
+  }
+
+  /** Read an {@code int32} field value from the stream. */
+  public int readInt32() throws IOException {
+    return readRawVarint32();
+  }
+
+  /** Read a {@code fixed64} field value from the stream. */
+  public long readFixed64() throws IOException {
+    return readRawLittleEndian64();
+  }
+
+  /** Read a {@code fixed32} field value from the stream. */
+  public int readFixed32() throws IOException {
+    return readRawLittleEndian32();
+  }
+
+  /** Read a {@code bool} field value from the stream. */
+  public boolean readBool() throws IOException {
+    return readRawVarint32() != 0;
+  }
+
+  /** Read a {@code string} field value from the stream. */
+  public String readString() throws IOException {
+    final int size = readRawVarint32();
+    if (size <= (bufferSize - bufferPos) && size > 0) {
+      // Fast path:  We already have the bytes in a contiguous buffer, so
+      //   just copy directly from it.
+      final String result = new String(buffer, bufferPos, size, "UTF-8");
+      bufferPos += size;
+      return result;
+    } else {
+      // Slow path:  Build a byte array first then copy it.
+      return new String(readRawBytes(size), "UTF-8");
+    }
+  }
+
+  /** Read a {@code group} field value from the stream. */
+  public void readGroup(final MessageMicro msg, final int fieldNumber)
+      throws IOException {
+    if (recursionDepth >= recursionLimit) {
+      throw InvalidProtocolBufferMicroException.recursionLimitExceeded();
+    }
+    ++recursionDepth;
+    msg.mergeFrom(this);
+    checkLastTagWas(
+      WireFormatMicro.makeTag(fieldNumber, WireFormatMicro.WIRETYPE_END_GROUP));
+    --recursionDepth;
+  }
+
+  public void readMessage(final MessageMicro msg)
+      throws IOException {
+    final int length = readRawVarint32();
+    if (recursionDepth >= recursionLimit) {
+      throw InvalidProtocolBufferMicroException.recursionLimitExceeded();
+    }
+    final int oldLimit = pushLimit(length);
+    ++recursionDepth;
+    msg.mergeFrom(this);
+    checkLastTagWas(0);
+    --recursionDepth;
+    popLimit(oldLimit);
+  }
+
+  /** Read a {@code bytes} field value from the stream. */
+  public ByteStringMicro readBytes() throws IOException {
+    final int size = readRawVarint32();
+    if (size <= (bufferSize - bufferPos) && size > 0) {
+      // Fast path:  We already have the bytes in a contiguous buffer, so
+      //   just copy directly from it.
+      final ByteStringMicro result = ByteStringMicro.copyFrom(buffer, bufferPos, size);
+      bufferPos += size;
+      return result;
+    } else if (size == 0) {
+      return ByteStringMicro.EMPTY;
+    } else {
+      // Slow path:  Build a byte array first then copy it.
+      return ByteStringMicro.copyFrom(readRawBytes(size));
+    }
+  }
+
+  /** Read a {@code uint32} field value from the stream. */
+  public int readUInt32() throws IOException {
+    return readRawVarint32();
+  }
+
+  /**
+   * Read an enum field value from the stream.  Caller is responsible
+   * for converting the numeric value to an actual enum.
+   */
+  public int readEnum() throws IOException {
+    return readRawVarint32();
+  }
+
+  /** Read an {@code sfixed32} field value from the stream. */
+  public int readSFixed32() throws IOException {
+    return readRawLittleEndian32();
+  }
+
+  /** Read an {@code sfixed64} field value from the stream. */
+  public long readSFixed64() throws IOException {
+    return readRawLittleEndian64();
+  }
+
+  /** Read an {@code sint32} field value from the stream. */
+  public int readSInt32() throws IOException {
+    return decodeZigZag32(readRawVarint32());
+  }
+
+  /** Read an {@code sint64} field value from the stream. */
+  public long readSInt64() throws IOException {
+    return decodeZigZag64(readRawVarint64());
+  }
+
+  // =================================================================
+
+  /**
+   * Read a raw Varint from the stream.  If larger than 32 bits, discard the
+   * upper bits.
+   */
+  public int readRawVarint32() throws IOException {
+    byte tmp = readRawByte();
+    if (tmp >= 0) {
+      return tmp;
+    }
+    int result = tmp & 0x7f;
+    if ((tmp = readRawByte()) >= 0) {
+      result |= tmp << 7;
+    } else {
+      result |= (tmp & 0x7f) << 7;
+      if ((tmp = readRawByte()) >= 0) {
+        result |= tmp << 14;
+      } else {
+        result |= (tmp & 0x7f) << 14;
+        if ((tmp = readRawByte()) >= 0) {
+          result |= tmp << 21;
+        } else {
+          result |= (tmp & 0x7f) << 21;
+          result |= (tmp = readRawByte()) << 28;
+          if (tmp < 0) {
+            // Discard upper 32 bits.
+            for (int i = 0; i < 5; i++) {
+              if (readRawByte() >= 0) {
+                return result;
+              }
+            }
+            throw InvalidProtocolBufferMicroException.malformedVarint();
+          }
+        }
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Reads a varint from the input one byte at a time, so that it does not
+   * read any bytes after the end of the varint.  If you simply wrapped the
+   * stream in a CodedInputStream and used {@link #readRawVarint32(InputStream)}
+   * then you would probably end up reading past the end of the varint since
+   * CodedInputStream buffers its input.
+   */
+  static int readRawVarint32(final InputStream input) throws IOException {
+    int result = 0;
+    int offset = 0;
+    for (; offset < 32; offset += 7) {
+      final int b = input.read();
+      if (b == -1) {
+        throw InvalidProtocolBufferMicroException.truncatedMessage();
+      }
+      result |= (b & 0x7f) << offset;
+      if ((b & 0x80) == 0) {
+        return result;
+      }
+    }
+    // Keep reading up to 64 bits.
+    for (; offset < 64; offset += 7) {
+      final int b = input.read();
+      if (b == -1) {
+        throw InvalidProtocolBufferMicroException.truncatedMessage();
+      }
+      if ((b & 0x80) == 0) {
+        return result;
+      }
+    }
+    throw InvalidProtocolBufferMicroException.malformedVarint();
+  }
+
+  /** Read a raw Varint from the stream. */
+  public long readRawVarint64() throws IOException {
+    int shift = 0;
+    long result = 0;
+    while (shift < 64) {
+      final byte b = readRawByte();
+      result |= (long)(b & 0x7F) << shift;
+      if ((b & 0x80) == 0) {
+        return result;
+      }
+      shift += 7;
+    }
+    throw InvalidProtocolBufferMicroException.malformedVarint();
+  }
+
+  /** Read a 32-bit little-endian integer from the stream. */
+  public int readRawLittleEndian32() throws IOException {
+    final byte b1 = readRawByte();
+    final byte b2 = readRawByte();
+    final byte b3 = readRawByte();
+    final byte b4 = readRawByte();
+    return ((b1 & 0xff)      ) |
+           ((b2 & 0xff) <<  8) |
+           ((b3 & 0xff) << 16) |
+           ((b4 & 0xff) << 24);
+  }
+
+  /** Read a 64-bit little-endian integer from the stream. */
+  public long readRawLittleEndian64() throws IOException {
+    final byte b1 = readRawByte();
+    final byte b2 = readRawByte();
+    final byte b3 = readRawByte();
+    final byte b4 = readRawByte();
+    final byte b5 = readRawByte();
+    final byte b6 = readRawByte();
+    final byte b7 = readRawByte();
+    final byte b8 = readRawByte();
+    return (((long)b1 & 0xff)      ) |
+           (((long)b2 & 0xff) <<  8) |
+           (((long)b3 & 0xff) << 16) |
+           (((long)b4 & 0xff) << 24) |
+           (((long)b5 & 0xff) << 32) |
+           (((long)b6 & 0xff) << 40) |
+           (((long)b7 & 0xff) << 48) |
+           (((long)b8 & 0xff) << 56);
+  }
+
+  /**
+   * Decode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n An unsigned 32-bit integer, stored in a signed int because
+   *          Java has no explicit unsigned support.
+   * @return A signed 32-bit integer.
+   */
+  public static int decodeZigZag32(final int n) {
+    return (n >>> 1) ^ -(n & 1);
+  }
+
+  /**
+   * Decode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n An unsigned 64-bit integer, stored in a signed int because
+   *          Java has no explicit unsigned support.
+   * @return A signed 64-bit integer.
+   */
+  public static long decodeZigZag64(final long n) {
+    return (n >>> 1) ^ -(n & 1);
+  }
+
+  // -----------------------------------------------------------------
+
+  private final byte[] buffer;
+  private int bufferSize;
+  private int bufferSizeAfterLimit;
+  private int bufferPos;
+  private final InputStream input;
+  private int lastTag;
+
+  /**
+   * The total number of bytes read before the current buffer.  The total
+   * bytes read up to the current position can be computed as
+   * {@code totalBytesRetired + bufferPos}.
+   */
+  private int totalBytesRetired;
+
+  /** The absolute position of the end of the current message. */
+  private int currentLimit = Integer.MAX_VALUE;
+
+  /** See setRecursionLimit() */
+  private int recursionDepth;
+  private int recursionLimit = DEFAULT_RECURSION_LIMIT;
+
+  /** See setSizeLimit() */
+  private int sizeLimit = DEFAULT_SIZE_LIMIT;
+
+  private static final int DEFAULT_RECURSION_LIMIT = 64;
+  private static final int DEFAULT_SIZE_LIMIT = 64 << 20;  // 64MB
+  private static final int BUFFER_SIZE = 4096;
+
+  private CodedInputStreamMicro(final byte[] buffer, final int off, final int len) {
+    this.buffer = buffer;
+    bufferSize = off + len;
+    bufferPos = off;
+    input = null;
+  }
+
+  private CodedInputStreamMicro(final InputStream input) {
+    buffer = new byte[BUFFER_SIZE];
+    bufferSize = 0;
+    bufferPos = 0;
+    this.input = input;
+  }
+
+  /**
+   * Set the maximum message recursion depth.  In order to prevent malicious
+   * messages from causing stack overflows, {@code CodedInputStream} limits
+   * how deeply messages may be nested.  The default limit is 64.
+   *
+   * @return the old limit.
+   */
+  public int setRecursionLimit(final int limit) {
+    if (limit < 0) {
+      throw new IllegalArgumentException(
+        "Recursion limit cannot be negative: " + limit);
+    }
+    final int oldLimit = recursionLimit;
+    recursionLimit = limit;
+    return oldLimit;
+  }
+
+  /**
+   * Set the maximum message size.  In order to prevent malicious
+   * messages from exhausting memory or causing integer overflows,
+   * {@code CodedInputStream} limits how large a message may be.
+   * The default limit is 64MB.  You should set this limit as small
+   * as you can without harming your app's functionality.  Note that
+   * size limits only apply when reading from an {@code InputStream}, not
+   * when constructed around a raw byte array (nor with
+   * {@link ByteStringMicro#newCodedInput}).
+   * <p>
+   * If you want to read several messages from a single CodedInputStream, you
+   * could call {@link #resetSizeCounter()} after each one to avoid hitting the
+   * size limit.
+   *
+   * @return the old limit.
+   */
+  public int setSizeLimit(final int limit) {
+    if (limit < 0) {
+      throw new IllegalArgumentException(
+        "Size limit cannot be negative: " + limit);
+    }
+    final int oldLimit = sizeLimit;
+    sizeLimit = limit;
+    return oldLimit;
+  }
+
+  /**
+   * Resets the current size counter to zero (see {@link #setSizeLimit(int)}).
+   */
+  public void resetSizeCounter() {
+    totalBytesRetired = 0;
+  }
+
+  /**
+   * Sets {@code currentLimit} to (current position) + {@code byteLimit}.  This
+   * is called when descending into a length-delimited embedded message.
+   *
+   * @return the old limit.
+   */
+  public int pushLimit(int byteLimit) throws InvalidProtocolBufferMicroException {
+    if (byteLimit < 0) {
+      throw InvalidProtocolBufferMicroException.negativeSize();
+    }
+    byteLimit += totalBytesRetired + bufferPos;
+    final int oldLimit = currentLimit;
+    if (byteLimit > oldLimit) {
+      throw InvalidProtocolBufferMicroException.truncatedMessage();
+    }
+    currentLimit = byteLimit;
+
+    recomputeBufferSizeAfterLimit();
+
+    return oldLimit;
+  }
+
+  private void recomputeBufferSizeAfterLimit() {
+    bufferSize += bufferSizeAfterLimit;
+    final int bufferEnd = totalBytesRetired + bufferSize;
+    if (bufferEnd > currentLimit) {
+      // Limit is in current buffer.
+      bufferSizeAfterLimit = bufferEnd - currentLimit;
+      bufferSize -= bufferSizeAfterLimit;
+    } else {
+      bufferSizeAfterLimit = 0;
+    }
+  }
+
+  /**
+   * Discards the current limit, returning to the previous limit.
+   *
+   * @param oldLimit The old limit, as returned by {@code pushLimit}.
+   */
+  public void popLimit(final int oldLimit) {
+    currentLimit = oldLimit;
+    recomputeBufferSizeAfterLimit();
+  }
+
+  /**
+   * Returns the number of bytes to be read before the current limit.
+   * If no limit is set, returns -1.
+   */
+  public int getBytesUntilLimit() {
+    if (currentLimit == Integer.MAX_VALUE) {
+      return -1;
+    }
+
+    final int currentAbsolutePosition = totalBytesRetired + bufferPos;
+    return currentLimit - currentAbsolutePosition;
+  }
+
+  /**
+   * Returns true if the stream has reached the end of the input.  This is the
+   * case if either the end of the underlying input source has been reached or
+   * if the stream has reached a limit created using {@link #pushLimit(int)}.
+   */
+  public boolean isAtEnd() throws IOException {
+    return bufferPos == bufferSize && !refillBuffer(false);
+  }
+
+  /**
+   * Called with {@code this.buffer} is empty to read more bytes from the
+   * input.  If {@code mustSucceed} is true, refillBuffer() gurantees that
+   * either there will be at least one byte in the buffer when it returns
+   * or it will throw an exception.  If {@code mustSucceed} is false,
+   * refillBuffer() returns false if no more bytes were available.
+   */
+  private boolean refillBuffer(final boolean mustSucceed) throws IOException {
+    if (bufferPos < bufferSize) {
+      throw new IllegalStateException(
+        "refillBuffer() called when buffer wasn't empty.");
+    }
+
+    if (totalBytesRetired + bufferSize == currentLimit) {
+      // Oops, we hit a limit.
+      if (mustSucceed) {
+        throw InvalidProtocolBufferMicroException.truncatedMessage();
+      } else {
+        return false;
+      }
+    }
+
+    totalBytesRetired += bufferSize;
+
+    bufferPos = 0;
+    bufferSize = (input == null) ? -1 : input.read(buffer);
+    if (bufferSize == 0 || bufferSize < -1) {
+      throw new IllegalStateException(
+          "InputStream#read(byte[]) returned invalid result: " + bufferSize +
+          "\nThe InputStream implementation is buggy.");
+    }
+    if (bufferSize == -1) {
+      bufferSize = 0;
+      if (mustSucceed) {
+        throw InvalidProtocolBufferMicroException.truncatedMessage();
+      } else {
+        return false;
+      }
+    } else {
+      recomputeBufferSizeAfterLimit();
+      final int totalBytesRead =
+        totalBytesRetired + bufferSize + bufferSizeAfterLimit;
+      if (totalBytesRead > sizeLimit || totalBytesRead < 0) {
+        throw InvalidProtocolBufferMicroException.sizeLimitExceeded();
+      }
+      return true;
+    }
+  }
+
+  /**
+   * Read one byte from the input.
+   *
+   * @throws InvalidProtocolBufferMicroException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  public byte readRawByte() throws IOException {
+    if (bufferPos == bufferSize) {
+      refillBuffer(true);
+    }
+    return buffer[bufferPos++];
+  }
+
+  /**
+   * Read a fixed size of bytes from the input.
+   *
+   * @throws InvalidProtocolBufferMicroException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  public byte[] readRawBytes(final int size) throws IOException {
+    if (size < 0) {
+      throw InvalidProtocolBufferMicroException.negativeSize();
+    }
+
+    if (totalBytesRetired + bufferPos + size > currentLimit) {
+      // Read to the end of the stream anyway.
+      skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+      // Then fail.
+      throw InvalidProtocolBufferMicroException.truncatedMessage();
+    }
+
+    if (size <= bufferSize - bufferPos) {
+      // We have all the bytes we need already.
+      final byte[] bytes = new byte[size];
+      System.arraycopy(buffer, bufferPos, bytes, 0, size);
+      bufferPos += size;
+      return bytes;
+    } else if (size < BUFFER_SIZE) {
+      // Reading more bytes than are in the buffer, but not an excessive number
+      // of bytes.  We can safely allocate the resulting array ahead of time.
+
+      // First copy what we have.
+      final byte[] bytes = new byte[size];
+      int pos = bufferSize - bufferPos;
+      System.arraycopy(buffer, bufferPos, bytes, 0, pos);
+      bufferPos = bufferSize;
+
+      // We want to use refillBuffer() and then copy from the buffer into our
+      // byte array rather than reading directly into our byte array because
+      // the input may be unbuffered.
+      refillBuffer(true);
+
+      while (size - pos > bufferSize) {
+        System.arraycopy(buffer, 0, bytes, pos, bufferSize);
+        pos += bufferSize;
+        bufferPos = bufferSize;
+        refillBuffer(true);
+      }
+
+      System.arraycopy(buffer, 0, bytes, pos, size - pos);
+      bufferPos = size - pos;
+
+      return bytes;
+    } else {
+      // The size is very large.  For security reasons, we can't allocate the
+      // entire byte array yet.  The size comes directly from the input, so a
+      // maliciously-crafted message could provide a bogus very large size in
+      // order to trick the app into allocating a lot of memory.  We avoid this
+      // by allocating and reading only a small chunk at a time, so that the
+      // malicious message must actually *be* extremely large to cause
+      // problems.  Meanwhile, we limit the allowed size of a message elsewhere.
+
+      // Remember the buffer markers since we'll have to copy the bytes out of
+      // it later.
+      final int originalBufferPos = bufferPos;
+      final int originalBufferSize = bufferSize;
+
+      // Mark the current buffer consumed.
+      totalBytesRetired += bufferSize;
+      bufferPos = 0;
+      bufferSize = 0;
+
+      // Read all the rest of the bytes we need.
+      int sizeLeft = size - (originalBufferSize - originalBufferPos);
+
+      // For compatibility with Java 1.3 use Vector
+      final java.util.Vector chunks = new java.util.Vector();
+
+      while (sizeLeft > 0) {
+        final byte[] chunk = new byte[Math.min(sizeLeft, BUFFER_SIZE)];
+        int pos = 0;
+        while (pos < chunk.length) {
+          final int n = (input == null) ? -1 :
+            input.read(chunk, pos, chunk.length - pos);
+          if (n == -1) {
+            throw InvalidProtocolBufferMicroException.truncatedMessage();
+          }
+          totalBytesRetired += n;
+          pos += n;
+        }
+        sizeLeft -= chunk.length;
+        chunks.addElement(chunk);
+      }
+
+      // OK, got everything.  Now concatenate it all into one buffer.
+      final byte[] bytes = new byte[size];
+
+      // Start by copying the leftover bytes from this.buffer.
+      int pos = originalBufferSize - originalBufferPos;
+      System.arraycopy(buffer, originalBufferPos, bytes, 0, pos);
+
+      // And now all the chunks.
+      for (int i = 0; i < chunks.size(); i++) {
+        byte [] chunk = (byte [])chunks.elementAt(i);
+        System.arraycopy(chunk, 0, bytes, pos, chunk.length);
+        pos += chunk.length;
+      }
+
+      // Done.
+      return bytes;
+    }
+  }
+
+  /**
+   * Reads and discards {@code size} bytes.
+   *
+   * @throws InvalidProtocolBufferMicroException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  public void skipRawBytes(final int size) throws IOException {
+    if (size < 0) {
+      throw InvalidProtocolBufferMicroException.negativeSize();
+    }
+
+    if (totalBytesRetired + bufferPos + size > currentLimit) {
+      // Read to the end of the stream anyway.
+      skipRawBytes(currentLimit - totalBytesRetired - bufferPos);
+      // Then fail.
+      throw InvalidProtocolBufferMicroException.truncatedMessage();
+    }
+
+    if (size <= bufferSize - bufferPos) {
+      // We have all the bytes we need already.
+      bufferPos += size;
+    } else {
+      // Skipping more bytes than are in the buffer.  First skip what we have.
+      int pos = bufferSize - bufferPos;
+      totalBytesRetired += bufferSize;
+      bufferPos = 0;
+      bufferSize = 0;
+
+      // Then skip directly from the InputStream for the rest.
+      while (pos < size) {
+        final int n = (input == null) ? -1 : (int) input.skip(size - pos);
+        if (n <= 0) {
+          throw InvalidProtocolBufferMicroException.truncatedMessage();
+        }
+        pos += n;
+        totalBytesRetired += n;
+      }
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java b/protobuf/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java
new file mode 100644
index 0000000..dd722ba
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/micro/CodedOutputStreamMicro.java
@@ -0,0 +1,993 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.micro;
+
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Encodes and writes protocol message fields.
+ *
+ * <p>This class contains two kinds of methods:  methods that write specific
+ * protocol message constructs and field types (e.g. {@link #writeTag} and
+ * {@link #writeInt32}) and methods that write low-level values (e.g.
+ * {@link #writeRawVarint32} and {@link #writeRawBytes}).  If you are
+ * writing encoded protocol messages, you should use the former methods, but if
+ * you are writing some other format of your own design, use the latter.
+ *
+ * <p>This class is totally unsynchronized.
+ *
+ * @author kneton@google.com Kenton Varda
+ */
+public final class CodedOutputStreamMicro {
+  private final byte[] buffer;
+  private final int limit;
+  private int position;
+
+  private final OutputStream output;
+
+  /**
+   * The buffer size used in {@link #newInstance(OutputStream)}.
+   */
+  public static final int DEFAULT_BUFFER_SIZE = 4096;
+
+  private CodedOutputStreamMicro(final byte[] buffer, final int offset,
+                            final int length) {
+    output = null;
+    this.buffer = buffer;
+    position = offset;
+    limit = offset + length;
+  }
+
+  private CodedOutputStreamMicro(final OutputStream output, final byte[] buffer) {
+    this.output = output;
+    this.buffer = buffer;
+    position = 0;
+    limit = buffer.length;
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} wrapping the given
+   * {@code OutputStream}.
+   */
+  public static CodedOutputStreamMicro newInstance(final OutputStream output) {
+    return newInstance(output, DEFAULT_BUFFER_SIZE);
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} wrapping the given
+   * {@code OutputStream} with a given buffer size.
+   */
+  public static CodedOutputStreamMicro newInstance(final OutputStream output,
+      final int bufferSize) {
+    return new CodedOutputStreamMicro(output, new byte[bufferSize]);
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} that writes directly to the given
+   * byte array.  If more bytes are written than fit in the array,
+   * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
+   * array is faster than writing to an {@code OutputStream}.
+   */
+  public static CodedOutputStreamMicro newInstance(final byte[] flatArray) {
+    return newInstance(flatArray, 0, flatArray.length);
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} that writes directly to the given
+   * byte array slice.  If more bytes are written than fit in the slice,
+   * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
+   * array is faster than writing to an {@code OutputStream}.
+   */
+  public static CodedOutputStreamMicro newInstance(final byte[] flatArray,
+                                              final int offset,
+                                              final int length) {
+    return new CodedOutputStreamMicro(flatArray, offset, length);
+  }
+
+  // -----------------------------------------------------------------
+
+  /** Write a {@code double} field, including tag, to the stream. */
+  public void writeDouble(final int fieldNumber, final double value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64);
+    writeDoubleNoTag(value);
+  }
+
+  /** Write a {@code float} field, including tag, to the stream. */
+  public void writeFloat(final int fieldNumber, final float value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32);
+    writeFloatNoTag(value);
+  }
+
+  /** Write a {@code uint64} field, including tag, to the stream. */
+  public void writeUInt64(final int fieldNumber, final long value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT);
+    writeUInt64NoTag(value);
+  }
+
+  /** Write an {@code int64} field, including tag, to the stream. */
+  public void writeInt64(final int fieldNumber, final long value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT);
+    writeInt64NoTag(value);
+  }
+
+  /** Write an {@code int32} field, including tag, to the stream. */
+  public void writeInt32(final int fieldNumber, final int value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT);
+    writeInt32NoTag(value);
+  }
+
+  /** Write a {@code fixed64} field, including tag, to the stream. */
+  public void writeFixed64(final int fieldNumber, final long value)
+                           throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64);
+    writeFixed64NoTag(value);
+  }
+
+  /** Write a {@code fixed32} field, including tag, to the stream. */
+  public void writeFixed32(final int fieldNumber, final int value)
+                           throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32);
+    writeFixed32NoTag(value);
+  }
+
+  /** Write a {@code bool} field, including tag, to the stream. */
+  public void writeBool(final int fieldNumber, final boolean value)
+                        throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT);
+    writeBoolNoTag(value);
+  }
+
+  /** Write a {@code string} field, including tag, to the stream. */
+  public void writeString(final int fieldNumber, final String value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED);
+    writeStringNoTag(value);
+  }
+
+  /** Write a {@code group} field, including tag, to the stream. */
+  public void writeGroup(final int fieldNumber, final MessageMicro value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_START_GROUP);
+    writeGroupNoTag(value);
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_END_GROUP);
+  }
+
+  /** Write an embedded message field, including tag, to the stream. */
+  public void writeMessage(final int fieldNumber, final MessageMicro value)
+                           throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED);
+    writeMessageNoTag(value);
+  }
+
+  /** Write a {@code bytes} field, including tag, to the stream. */
+  public void writeBytes(final int fieldNumber, final ByteStringMicro value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED);
+    writeBytesNoTag(value);
+  }
+
+  /** Write a {@code byte} field, including tag, to the stream. */
+  public void writeByteArray(final int fieldNumber, final byte[] value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_LENGTH_DELIMITED);
+    writeByteArrayNoTag(value);
+  }
+
+
+  /** Write a {@code uint32} field, including tag, to the stream. */
+  public void writeUInt32(final int fieldNumber, final int value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT);
+    writeUInt32NoTag(value);
+  }
+
+  /**
+   * Write an enum field, including tag, to the stream.  Caller is responsible
+   * for converting the enum value to its numeric value.
+   */
+  public void writeEnum(final int fieldNumber, final int value)
+                        throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT);
+    writeEnumNoTag(value);
+  }
+
+  /** Write an {@code sfixed32} field, including tag, to the stream. */
+  public void writeSFixed32(final int fieldNumber, final int value)
+                            throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED32);
+    writeSFixed32NoTag(value);
+  }
+
+  /** Write an {@code sfixed64} field, including tag, to the stream. */
+  public void writeSFixed64(final int fieldNumber, final long value)
+                            throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_FIXED64);
+    writeSFixed64NoTag(value);
+  }
+
+  /** Write an {@code sint32} field, including tag, to the stream. */
+  public void writeSInt32(final int fieldNumber, final int value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT);
+    writeSInt32NoTag(value);
+  }
+
+  /** Write an {@code sint64} field, including tag, to the stream. */
+  public void writeSInt64(final int fieldNumber, final long value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatMicro.WIRETYPE_VARINT);
+    writeSInt64NoTag(value);
+  }
+
+  /**
+   * Write a MessageSet extension field to the stream.  For historical reasons,
+   * the wire format differs from normal fields.
+   */
+//  public void writeMessageSetExtension(final int fieldNumber,
+//                                       final MessageMicro value)
+//                                       throws IOException {
+//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
+//    writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
+//    writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
+//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
+//  }
+
+  /**
+   * Write an unparsed MessageSet extension field to the stream.  For
+   * historical reasons, the wire format differs from normal fields.
+   */
+//  public void writeRawMessageSetExtension(final int fieldNumber,
+//                                          final ByteStringMicro value)
+//                                          throws IOException {
+//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
+//    writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
+//    writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
+//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
+//  }
+
+  // -----------------------------------------------------------------
+
+  /** Write a {@code double} field to the stream. */
+  public void writeDoubleNoTag(final double value) throws IOException {
+    writeRawLittleEndian64(Double.doubleToLongBits(value));
+  }
+
+  /** Write a {@code float} field to the stream. */
+  public void writeFloatNoTag(final float value) throws IOException {
+    writeRawLittleEndian32(Float.floatToIntBits(value));
+  }
+
+  /** Write a {@code uint64} field to the stream. */
+  public void writeUInt64NoTag(final long value) throws IOException {
+    writeRawVarint64(value);
+  }
+
+  /** Write an {@code int64} field to the stream. */
+  public void writeInt64NoTag(final long value) throws IOException {
+    writeRawVarint64(value);
+  }
+
+  /** Write an {@code int32} field to the stream. */
+  public void writeInt32NoTag(final int value) throws IOException {
+    if (value >= 0) {
+      writeRawVarint32(value);
+    } else {
+      // Must sign-extend.
+      writeRawVarint64(value);
+    }
+  }
+
+  /** Write a {@code fixed64} field to the stream. */
+  public void writeFixed64NoTag(final long value) throws IOException {
+    writeRawLittleEndian64(value);
+  }
+
+  /** Write a {@code fixed32} field to the stream. */
+  public void writeFixed32NoTag(final int value) throws IOException {
+    writeRawLittleEndian32(value);
+  }
+
+  /** Write a {@code bool} field to the stream. */
+  public void writeBoolNoTag(final boolean value) throws IOException {
+    writeRawByte(value ? 1 : 0);
+  }
+
+  /** Write a {@code string} field to the stream. */
+  public void writeStringNoTag(final String value) throws IOException {
+    // Unfortunately there does not appear to be any way to tell Java to encode
+    // UTF-8 directly into our buffer, so we have to let it create its own byte
+    // array and then copy.
+    final byte[] bytes = value.getBytes("UTF-8");
+    writeRawVarint32(bytes.length);
+    writeRawBytes(bytes);
+  }
+
+  /** Write a {@code group} field to the stream. */
+  public void writeGroupNoTag(final MessageMicro value) throws IOException {
+    value.writeTo(this);
+  }
+
+  /** Write an embedded message field to the stream. */
+  public void writeMessageNoTag(final MessageMicro value) throws IOException {
+    writeRawVarint32(value.getCachedSize());
+    value.writeTo(this);
+  }
+
+  /** Write a {@code bytes} field to the stream. */
+  public void writeBytesNoTag(final ByteStringMicro value) throws IOException {
+    final byte[] bytes = value.toByteArray();
+    writeRawVarint32(bytes.length);
+    writeRawBytes(bytes);
+  }
+
+  /** Write a {@code byte[]} field to the stream. */
+  public void writeByteArrayNoTag(final byte [] value) throws IOException {
+    writeRawVarint32(value.length);
+    writeRawBytes(value);
+  }
+
+  /** Write a {@code uint32} field to the stream. */
+  public void writeUInt32NoTag(final int value) throws IOException {
+    writeRawVarint32(value);
+  }
+
+  /**
+   * Write an enum field to the stream.  Caller is responsible
+   * for converting the enum value to its numeric value.
+   */
+  public void writeEnumNoTag(final int value) throws IOException {
+    writeRawVarint32(value);
+  }
+
+  /** Write an {@code sfixed32} field to the stream. */
+  public void writeSFixed32NoTag(final int value) throws IOException {
+    writeRawLittleEndian32(value);
+  }
+
+  /** Write an {@code sfixed64} field to the stream. */
+  public void writeSFixed64NoTag(final long value) throws IOException {
+    writeRawLittleEndian64(value);
+  }
+
+  /** Write an {@code sint32} field to the stream. */
+  public void writeSInt32NoTag(final int value) throws IOException {
+    writeRawVarint32(encodeZigZag32(value));
+  }
+
+  /** Write an {@code sint64} field to the stream. */
+  public void writeSInt64NoTag(final long value) throws IOException {
+    writeRawVarint64(encodeZigZag64(value));
+  }
+
+  // =================================================================
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code double} field, including tag.
+   */
+  public static int computeDoubleSize(final int fieldNumber,
+                                      final double value) {
+    return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code float} field, including tag.
+   */
+  public static int computeFloatSize(final int fieldNumber, final float value) {
+    return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint64} field, including tag.
+   */
+  public static int computeUInt64Size(final int fieldNumber, final long value) {
+    return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int64} field, including tag.
+   */
+  public static int computeInt64Size(final int fieldNumber, final long value) {
+    return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int32} field, including tag.
+   */
+  public static int computeInt32Size(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed64} field, including tag.
+   */
+  public static int computeFixed64Size(final int fieldNumber,
+                                       final long value) {
+    return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed32} field, including tag.
+   */
+  public static int computeFixed32Size(final int fieldNumber,
+                                       final int value) {
+    return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bool} field, including tag.
+   */
+  public static int computeBoolSize(final int fieldNumber,
+                                    final boolean value) {
+    return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code string} field, including tag.
+   */
+  public static int computeStringSize(final int fieldNumber,
+                                      final String value) {
+    return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code group} field, including tag.
+   */
+  public static int computeGroupSize(final int fieldNumber,
+                                     final MessageMicro value) {
+    return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * embedded message field, including tag.
+   */
+  public static int computeMessageSize(final int fieldNumber,
+                                       final MessageMicro value) {
+    return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field, including tag.
+   */
+  public static int computeBytesSize(final int fieldNumber,
+                                     final ByteStringMicro value) {
+    return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code byte[]} field, including tag.
+   */
+  public static int computeByteArraySize(final int fieldNumber,
+                                     final byte[] value) {
+    return computeTagSize(fieldNumber) + computeByteArraySizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint32} field, including tag.
+   */
+  public static int computeUInt32Size(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * enum field, including tag.  Caller is responsible for converting the
+   * enum value to its numeric value.
+   */
+  public static int computeEnumSize(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed32} field, including tag.
+   */
+  public static int computeSFixed32Size(final int fieldNumber,
+                                        final int value) {
+    return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed64} field, including tag.
+   */
+  public static int computeSFixed64Size(final int fieldNumber,
+                                        final long value) {
+    return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint32} field, including tag.
+   */
+  public static int computeSInt32Size(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint64} field, including tag.
+   */
+  public static int computeSInt64Size(final int fieldNumber, final long value) {
+    return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * MessageSet extension to the stream.  For historical reasons,
+   * the wire format differs from normal fields.
+   */
+//  public static int computeMessageSetExtensionSize(
+//      final int fieldNumber, final MessageMicro value) {
+//    return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
+//           computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
+//           computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
+//  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * unparsed MessageSet extension field to the stream.  For
+   * historical reasons, the wire format differs from normal fields.
+   */
+//  public static int computeRawMessageSetExtensionSize(
+//      final int fieldNumber, final ByteStringMicro value) {
+//    return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
+//           computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
+//           computeBytesSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
+//  }
+
+  // -----------------------------------------------------------------
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code double} field, including tag.
+   */
+  public static int computeDoubleSizeNoTag(final double value) {
+    return LITTLE_ENDIAN_64_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code float} field, including tag.
+   */
+  public static int computeFloatSizeNoTag(final float value) {
+    return LITTLE_ENDIAN_32_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint64} field, including tag.
+   */
+  public static int computeUInt64SizeNoTag(final long value) {
+    return computeRawVarint64Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int64} field, including tag.
+   */
+  public static int computeInt64SizeNoTag(final long value) {
+    return computeRawVarint64Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int32} field, including tag.
+   */
+  public static int computeInt32SizeNoTag(final int value) {
+    if (value >= 0) {
+      return computeRawVarint32Size(value);
+    } else {
+      // Must sign-extend.
+      return 10;
+    }
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed64} field.
+   */
+  public static int computeFixed64SizeNoTag(final long value) {
+    return LITTLE_ENDIAN_64_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed32} field.
+   */
+  public static int computeFixed32SizeNoTag(final int value) {
+    return LITTLE_ENDIAN_32_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bool} field.
+   */
+  public static int computeBoolSizeNoTag(final boolean value) {
+    return 1;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code string} field.
+   */
+  public static int computeStringSizeNoTag(final String value) {
+    try {
+      final byte[] bytes = value.getBytes("UTF-8");
+      return computeRawVarint32Size(bytes.length) +
+             bytes.length;
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 not supported.");
+    }
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code group} field.
+   */
+  public static int computeGroupSizeNoTag(final MessageMicro value) {
+    return value.getSerializedSize();
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an embedded
+   * message field.
+   */
+  public static int computeMessageSizeNoTag(final MessageMicro value) {
+    final int size = value.getSerializedSize();
+    return computeRawVarint32Size(size) + size;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field.
+   */
+  public static int computeBytesSizeNoTag(final ByteStringMicro value) {
+    return computeRawVarint32Size(value.size()) + value.size();
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code byte[]} field.
+   */
+  public static int computeByteArraySizeNoTag(final byte[] value) {
+    return computeRawVarint32Size(value.length) + value.length;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint32} field.
+   */
+  public static int computeUInt32SizeNoTag(final int value) {
+    return computeRawVarint32Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an enum field.
+   * Caller is responsible for converting the enum value to its numeric value.
+   */
+  public static int computeEnumSizeNoTag(final int value) {
+    return computeRawVarint32Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed32} field.
+   */
+  public static int computeSFixed32SizeNoTag(final int value) {
+    return LITTLE_ENDIAN_32_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed64} field.
+   */
+  public static int computeSFixed64SizeNoTag(final long value) {
+    return LITTLE_ENDIAN_64_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint32} field.
+   */
+  public static int computeSInt32SizeNoTag(final int value) {
+    return computeRawVarint32Size(encodeZigZag32(value));
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint64} field.
+   */
+  public static int computeSInt64SizeNoTag(final long value) {
+    return computeRawVarint64Size(encodeZigZag64(value));
+  }
+
+  // =================================================================
+
+  /**
+   * Internal helper that writes the current buffer to the output. The
+   * buffer position is reset to its initial value when this returns.
+   */
+  private void refreshBuffer() throws IOException {
+    if (output == null) {
+      // We're writing to a single buffer.
+      throw new OutOfSpaceException();
+    }
+
+    // Since we have an output stream, this is our buffer
+    // and buffer offset == 0
+    output.write(buffer, 0, position);
+    position = 0;
+  }
+
+  /**
+   * Flushes the stream and forces any buffered bytes to be written.  This
+   * does not flush the underlying OutputStream.
+   */
+  public void flush() throws IOException {
+    if (output != null) {
+      refreshBuffer();
+    }
+  }
+
+  /**
+   * If writing to a flat array, return the space left in the array.
+   * Otherwise, throws {@code UnsupportedOperationException}.
+   */
+  public int spaceLeft() {
+    if (output == null) {
+      return limit - position;
+    } else {
+      throw new UnsupportedOperationException(
+        "spaceLeft() can only be called on CodedOutputStreams that are " +
+        "writing to a flat array.");
+    }
+  }
+
+  /**
+   * Verifies that {@link #spaceLeft()} returns zero.  It's common to create
+   * a byte array that is exactly big enough to hold a message, then write to
+   * it with a {@code CodedOutputStream}.  Calling {@code checkNoSpaceLeft()}
+   * after writing verifies that the message was actually as big as expected,
+   * which can help catch bugs.
+   */
+  public void checkNoSpaceLeft() {
+    if (spaceLeft() != 0) {
+      throw new IllegalStateException(
+        "Did not write as much data as expected.");
+    }
+  }
+
+  /**
+   * If you create a CodedOutputStream around a simple flat array, you must
+   * not attempt to write more bytes than the array has space.  Otherwise,
+   * this exception will be thrown.
+   */
+  public static class OutOfSpaceException extends IOException {
+    private static final long serialVersionUID = -6947486886997889499L;
+
+    OutOfSpaceException() {
+      super("CodedOutputStream was writing to a flat byte array and ran " +
+            "out of space.");
+    }
+  }
+
+  /** Write a single byte. */
+  public void writeRawByte(final byte value) throws IOException {
+    if (position == limit) {
+      refreshBuffer();
+    }
+
+    buffer[position++] = value;
+  }
+
+  /** Write a single byte, represented by an integer value. */
+  public void writeRawByte(final int value) throws IOException {
+    writeRawByte((byte) value);
+  }
+
+  /** Write an array of bytes. */
+  public void writeRawBytes(final byte[] value) throws IOException {
+    writeRawBytes(value, 0, value.length);
+  }
+
+  /** Write part of an array of bytes. */
+  public void writeRawBytes(final byte[] value, int offset, int length)
+                            throws IOException {
+    if (limit - position >= length) {
+      // We have room in the current buffer.
+      System.arraycopy(value, offset, buffer, position, length);
+      position += length;
+    } else {
+      // Write extends past current buffer.  Fill the rest of this buffer and
+      // flush.
+      final int bytesWritten = limit - position;
+      System.arraycopy(value, offset, buffer, position, bytesWritten);
+      offset += bytesWritten;
+      length -= bytesWritten;
+      position = limit;
+      refreshBuffer();
+
+      // Now deal with the rest.
+      // Since we have an output stream, this is our buffer
+      // and buffer offset == 0
+      if (length <= limit) {
+        // Fits in new buffer.
+        System.arraycopy(value, offset, buffer, 0, length);
+        position = length;
+      } else {
+        // Write is very big.  Let's do it all at once.
+        output.write(value, offset, length);
+      }
+    }
+  }
+
+  /** Encode and write a tag. */
+  public void writeTag(final int fieldNumber, final int wireType)
+                       throws IOException {
+    writeRawVarint32(WireFormatMicro.makeTag(fieldNumber, wireType));
+  }
+
+  /** Compute the number of bytes that would be needed to encode a tag. */
+  public static int computeTagSize(final int fieldNumber) {
+    return computeRawVarint32Size(WireFormatMicro.makeTag(fieldNumber, 0));
+  }
+
+  /**
+   * Encode and write a varint.  {@code value} is treated as
+   * unsigned, so it won't be sign-extended if negative.
+   */
+  public void writeRawVarint32(int value) throws IOException {
+    while (true) {
+      if ((value & ~0x7F) == 0) {
+        writeRawByte(value);
+        return;
+      } else {
+        writeRawByte((value & 0x7F) | 0x80);
+        value >>>= 7;
+      }
+    }
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a varint.
+   * {@code value} is treated as unsigned, so it won't be sign-extended if
+   * negative.
+   */
+  public static int computeRawVarint32Size(final int value) {
+    if ((value & (0xffffffff <<  7)) == 0) return 1;
+    if ((value & (0xffffffff << 14)) == 0) return 2;
+    if ((value & (0xffffffff << 21)) == 0) return 3;
+    if ((value & (0xffffffff << 28)) == 0) return 4;
+    return 5;
+  }
+
+  /** Encode and write a varint. */
+  public void writeRawVarint64(long value) throws IOException {
+    while (true) {
+      if ((value & ~0x7FL) == 0) {
+        writeRawByte((int)value);
+        return;
+      } else {
+        writeRawByte(((int)value & 0x7F) | 0x80);
+        value >>>= 7;
+      }
+    }
+  }
+
+  /** Compute the number of bytes that would be needed to encode a varint. */
+  public static int computeRawVarint64Size(final long value) {
+    if ((value & (0xffffffffffffffffL <<  7)) == 0) return 1;
+    if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
+    if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
+    if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
+    if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
+    if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
+    if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
+    if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
+    if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
+    return 10;
+  }
+
+  /** Write a little-endian 32-bit integer. */
+  public void writeRawLittleEndian32(final int value) throws IOException {
+    writeRawByte((value      ) & 0xFF);
+    writeRawByte((value >>  8) & 0xFF);
+    writeRawByte((value >> 16) & 0xFF);
+    writeRawByte((value >> 24) & 0xFF);
+  }
+
+  public static final int LITTLE_ENDIAN_32_SIZE = 4;
+
+  /** Write a little-endian 64-bit integer. */
+  public void writeRawLittleEndian64(final long value) throws IOException {
+    writeRawByte((int)(value      ) & 0xFF);
+    writeRawByte((int)(value >>  8) & 0xFF);
+    writeRawByte((int)(value >> 16) & 0xFF);
+    writeRawByte((int)(value >> 24) & 0xFF);
+    writeRawByte((int)(value >> 32) & 0xFF);
+    writeRawByte((int)(value >> 40) & 0xFF);
+    writeRawByte((int)(value >> 48) & 0xFF);
+    writeRawByte((int)(value >> 56) & 0xFF);
+  }
+
+  public static final int LITTLE_ENDIAN_64_SIZE = 8;
+
+  /**
+   * Encode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n A signed 32-bit integer.
+   * @return An unsigned 32-bit integer, stored in a signed int because
+   *         Java has no explicit unsigned support.
+   */
+  public static int encodeZigZag32(final int n) {
+    // Note:  the right-shift must be arithmetic
+    return (n << 1) ^ (n >> 31);
+  }
+
+  /**
+   * Encode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n A signed 64-bit integer.
+   * @return An unsigned 64-bit integer, stored in a signed int because
+   *         Java has no explicit unsigned support.
+   */
+  public static long encodeZigZag64(final long n) {
+    // Note:  the right-shift must be arithmetic
+    return (n << 1) ^ (n >> 63);
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/micro/InvalidProtocolBufferMicroException.java b/protobuf/java/src/main/java/com/google/protobuf/micro/InvalidProtocolBufferMicroException.java
new file mode 100644
index 0000000..050f99b
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/micro/InvalidProtocolBufferMicroException.java
@@ -0,0 +1,93 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.micro;
+
+import java.io.IOException;
+
+/**
+ * Thrown when a protocol message being parsed is invalid in some way,
+ * e.g. it contains a malformed varint or a negative byte length.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class InvalidProtocolBufferMicroException extends IOException {
+  private static final long serialVersionUID = -1616151763072450476L;
+
+  public InvalidProtocolBufferMicroException(final String description) {
+    super(description);
+  }
+
+  static InvalidProtocolBufferMicroException truncatedMessage() {
+    return new InvalidProtocolBufferMicroException(
+      "While parsing a protocol message, the input ended unexpectedly " +
+      "in the middle of a field.  This could mean either than the " +
+      "input has been truncated or that an embedded message " +
+      "misreported its own length.");
+  }
+
+  static InvalidProtocolBufferMicroException negativeSize() {
+    return new InvalidProtocolBufferMicroException(
+      "CodedInputStream encountered an embedded string or message " +
+      "which claimed to have negative size.");
+  }
+
+  static InvalidProtocolBufferMicroException malformedVarint() {
+    return new InvalidProtocolBufferMicroException(
+      "CodedInputStream encountered a malformed varint.");
+  }
+
+  static InvalidProtocolBufferMicroException invalidTag() {
+    return new InvalidProtocolBufferMicroException(
+      "Protocol message contained an invalid tag (zero).");
+  }
+
+  static InvalidProtocolBufferMicroException invalidEndTag() {
+    return new InvalidProtocolBufferMicroException(
+      "Protocol message end-group tag did not match expected tag.");
+  }
+
+  static InvalidProtocolBufferMicroException invalidWireType() {
+    return new InvalidProtocolBufferMicroException(
+      "Protocol message tag had invalid wire type.");
+  }
+
+  static InvalidProtocolBufferMicroException recursionLimitExceeded() {
+    return new InvalidProtocolBufferMicroException(
+      "Protocol message had too many levels of nesting.  May be malicious.  " +
+      "Use CodedInputStream.setRecursionLimit() to increase the depth limit.");
+  }
+
+  static InvalidProtocolBufferMicroException sizeLimitExceeded() {
+    return new InvalidProtocolBufferMicroException(
+      "Protocol message was too large.  May be malicious.  " +
+      "Use CodedInputStream.setSizeLimit() to increase the size limit.");
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/micro/MessageMicro.java b/protobuf/java/src/main/java/com/google/protobuf/micro/MessageMicro.java
new file mode 100644
index 0000000..0c02793
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/micro/MessageMicro.java
@@ -0,0 +1,136 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.micro;
+
+import com.google.protobuf.micro.CodedOutputStreamMicro;
+import java.io.IOException;
+
+/**
+ * Abstract interface implemented by Protocol Message objects.
+ *
+ * @author wink@google.com Wink Saville
+ */
+public abstract class MessageMicro {
+    /**
+     * Get the number of bytes required to encode this message.
+     * Returns the cached size or calls getSerializedSize which
+     * sets the cached size. This is used internally when serializing
+     * so the size is only computed once. If a member is modified
+     * then this could be stale call getSerializedSize if in doubt.
+     */
+    abstract public int getCachedSize();
+
+    /**
+     * Computes the number of bytes required to encode this message.
+     * The size is cached and the cached result can be retrieved
+     * using getCachedSize().
+     */
+    abstract public int getSerializedSize();
+
+    /**
+     * Serializes the message and writes it to {@code output}.  This does not
+     * flush or close the stream.
+     */
+    abstract public void writeTo(CodedOutputStreamMicro output) throws java.io.IOException;
+
+    /**
+     * Parse {@code input} as a message of this type and merge it with the
+     * message being built.
+     */
+    abstract public MessageMicro mergeFrom(final CodedInputStreamMicro input) throws IOException;
+
+    /**
+     * Serialize to a byte array.
+     * @return byte array with the serialized data.
+     */
+    public byte[] toByteArray() {
+        final byte[] result = new byte[getSerializedSize()];
+        toByteArray(result, 0, result.length);
+        return result;
+    }
+
+    /**
+     * Serialize to a byte array starting at offset through length. The
+     * method getSerializedSize must have been called prior to calling
+     * this method so the proper length is know.  If an attempt to
+     * write more than length bytes OutOfSpaceException will be thrown
+     * and if length bytes are not written then IllegalStateException
+     * is thrown.
+     * @return byte array with the serialized data.
+     */
+    public void toByteArray(byte [] data, int offset, int length) {
+        try {
+            final CodedOutputStreamMicro output = CodedOutputStreamMicro.newInstance(data, offset, length);
+            writeTo(output);
+            output.checkNoSpaceLeft();
+        } catch (IOException e) {
+            throw new RuntimeException("Serializing to a byte array threw an IOException "
+                    + "(should never happen).");
+        }
+    }
+
+    /**
+     * Parse {@code data} as a message of this type and merge it with the
+     * message being built.
+     */
+    public MessageMicro mergeFrom(final byte[] data) throws InvalidProtocolBufferMicroException {
+        return mergeFrom(data, 0, data.length);
+    }
+
+    /**
+     * Parse {@code data} as a message of this type and merge it with the
+     * message being built.
+     */
+    public MessageMicro mergeFrom(final byte[] data, final int off, final int len)
+            throws InvalidProtocolBufferMicroException {
+        try {
+            final CodedInputStreamMicro input = CodedInputStreamMicro.newInstance(data, off, len);
+            mergeFrom(input);
+            input.checkLastTagWas(0);
+            return this;
+        } catch (InvalidProtocolBufferMicroException e) {
+            throw e;
+        } catch (IOException e) {
+            throw new RuntimeException("Reading from a byte array threw an IOException (should "
+                    + "never happen).");
+        }
+    }
+
+    /**
+     * Called by subclasses to parse an unknown field.
+     * @return {@code true} unless the tag is an end-group tag.
+     */
+    protected boolean parseUnknownField(
+        final CodedInputStreamMicro input,
+        final int tag) throws IOException {
+      return input.skipField(tag);
+    }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/micro/WireFormatMicro.java b/protobuf/java/src/main/java/com/google/protobuf/micro/WireFormatMicro.java
new file mode 100644
index 0000000..d8a88bd
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/micro/WireFormatMicro.java
@@ -0,0 +1,87 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.micro;
+
+/**
+ * This class is used internally by the Protocol Buffer library and generated
+ * message implementations.  It is public only because those generated messages
+ * do not reside in the {@code protobuf} package.  Others should not use this
+ * class directly.
+ *
+ * This class contains constants and helper functions useful for dealing with
+ * the Protocol Buffer wire format.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class WireFormatMicro {
+  // Do not allow instantiation.
+  private WireFormatMicro() {}
+
+  static final int WIRETYPE_VARINT           = 0;
+  static final int WIRETYPE_FIXED64          = 1;
+  static final int WIRETYPE_LENGTH_DELIMITED = 2;
+  static final int WIRETYPE_START_GROUP      = 3;
+  static final int WIRETYPE_END_GROUP        = 4;
+  static final int WIRETYPE_FIXED32          = 5;
+
+  static final int TAG_TYPE_BITS = 3;
+  static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;
+
+  /** Given a tag value, determines the wire type (the lower 3 bits). */
+  static int getTagWireType(final int tag) {
+    return tag & TAG_TYPE_MASK;
+  }
+
+  /** Given a tag value, determines the field number (the upper 29 bits). */
+  public static int getTagFieldNumber(final int tag) {
+    return tag >>> TAG_TYPE_BITS;
+  }
+
+  /** Makes a tag value given a field number and wire type. */
+  static int makeTag(final int fieldNumber, final int wireType) {
+    return (fieldNumber << TAG_TYPE_BITS) | wireType;
+  }
+
+  // Field numbers for feilds in MessageSet wire format.
+  static final int MESSAGE_SET_ITEM    = 1;
+  static final int MESSAGE_SET_TYPE_ID = 2;
+  static final int MESSAGE_SET_MESSAGE = 3;
+
+  // Tag numbers.
+  static final int MESSAGE_SET_ITEM_TAG =
+    makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP);
+  static final int MESSAGE_SET_ITEM_END_TAG =
+    makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP);
+  static final int MESSAGE_SET_TYPE_ID_TAG =
+    makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT);
+  static final int MESSAGE_SET_MESSAGE_TAG =
+    makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED);
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java b/protobuf/java/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java
new file mode 100644
index 0000000..844d0a8
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/CodedInputByteBufferNano.java
@@ -0,0 +1,658 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.io.IOException;
+
+/**
+ * Reads and decodes protocol message fields.
+ *
+ * This class contains two kinds of methods:  methods that read specific
+ * protocol message constructs and field types (e.g. {@link #readTag()} and
+ * {@link #readInt32()}) and methods that read low-level values (e.g.
+ * {@link #readRawVarint32()} and {@link #readRawBytes}).  If you are reading
+ * encoded protocol messages, you should use the former methods, but if you are
+ * reading some other format of your own design, use the latter.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class CodedInputByteBufferNano {
+  /**
+   * Create a new CodedInputStream wrapping the given byte array.
+   */
+  public static CodedInputByteBufferNano newInstance(final byte[] buf) {
+    return newInstance(buf, 0, buf.length);
+  }
+
+  /**
+   * Create a new CodedInputStream wrapping the given byte array slice.
+   */
+  public static CodedInputByteBufferNano newInstance(final byte[] buf, final int off,
+                                             final int len) {
+    return new CodedInputByteBufferNano(buf, off, len);
+  }
+
+  // -----------------------------------------------------------------
+
+  /**
+   * Attempt to read a field tag, returning zero if we have reached EOF.
+   * Protocol message parsers use this to read tags, since a protocol message
+   * may legally end wherever a tag occurs, and zero is not a valid tag number.
+   */
+  public int readTag() throws IOException {
+    if (isAtEnd()) {
+      lastTag = 0;
+      return 0;
+    }
+
+    lastTag = readRawVarint32();
+    if (lastTag == 0) {
+      // If we actually read zero, that's not a valid tag.
+      throw InvalidProtocolBufferNanoException.invalidTag();
+    }
+    return lastTag;
+  }
+
+  /**
+   * Verifies that the last call to readTag() returned the given tag value.
+   * This is used to verify that a nested group ended with the correct
+   * end tag.
+   *
+   * @throws InvalidProtocolBufferNanoException {@code value} does not match the
+   *                                        last tag.
+   */
+  public void checkLastTagWas(final int value)
+                              throws InvalidProtocolBufferNanoException {
+    if (lastTag != value) {
+      throw InvalidProtocolBufferNanoException.invalidEndTag();
+    }
+  }
+
+  /**
+   * Reads and discards a single field, given its tag value.
+   *
+   * @return {@code false} if the tag is an endgroup tag, in which case
+   *         nothing is skipped.  Otherwise, returns {@code true}.
+   */
+  public boolean skipField(final int tag) throws IOException {
+    switch (WireFormatNano.getTagWireType(tag)) {
+      case WireFormatNano.WIRETYPE_VARINT:
+        readInt32();
+        return true;
+      case WireFormatNano.WIRETYPE_FIXED64:
+        readRawLittleEndian64();
+        return true;
+      case WireFormatNano.WIRETYPE_LENGTH_DELIMITED:
+        skipRawBytes(readRawVarint32());
+        return true;
+      case WireFormatNano.WIRETYPE_START_GROUP:
+        skipMessage();
+        checkLastTagWas(
+          WireFormatNano.makeTag(WireFormatNano.getTagFieldNumber(tag),
+                             WireFormatNano.WIRETYPE_END_GROUP));
+        return true;
+      case WireFormatNano.WIRETYPE_END_GROUP:
+        return false;
+      case WireFormatNano.WIRETYPE_FIXED32:
+        readRawLittleEndian32();
+        return true;
+      default:
+        throw InvalidProtocolBufferNanoException.invalidWireType();
+    }
+  }
+
+  /**
+   * Reads and discards an entire message.  This will read either until EOF
+   * or until an endgroup tag, whichever comes first.
+   */
+  public void skipMessage() throws IOException {
+    while (true) {
+      final int tag = readTag();
+      if (tag == 0 || !skipField(tag)) {
+        return;
+      }
+    }
+  }
+
+  // -----------------------------------------------------------------
+
+  /** Read a {@code double} field value from the stream. */
+  public double readDouble() throws IOException {
+    return Double.longBitsToDouble(readRawLittleEndian64());
+  }
+
+  /** Read a {@code float} field value from the stream. */
+  public float readFloat() throws IOException {
+    return Float.intBitsToFloat(readRawLittleEndian32());
+  }
+
+  /** Read a {@code uint64} field value from the stream. */
+  public long readUInt64() throws IOException {
+    return readRawVarint64();
+  }
+
+  /** Read an {@code int64} field value from the stream. */
+  public long readInt64() throws IOException {
+    return readRawVarint64();
+  }
+
+  /** Read an {@code int32} field value from the stream. */
+  public int readInt32() throws IOException {
+    return readRawVarint32();
+  }
+
+  /** Read a {@code fixed64} field value from the stream. */
+  public long readFixed64() throws IOException {
+    return readRawLittleEndian64();
+  }
+
+  /** Read a {@code fixed32} field value from the stream. */
+  public int readFixed32() throws IOException {
+    return readRawLittleEndian32();
+  }
+
+  /** Read a {@code bool} field value from the stream. */
+  public boolean readBool() throws IOException {
+    return readRawVarint32() != 0;
+  }
+
+  /** Read a {@code string} field value from the stream. */
+  public String readString() throws IOException {
+    final int size = readRawVarint32();
+    if (size < 0) {
+      throw InvalidProtocolBufferNanoException.negativeSize();
+    }
+    if (size > (bufferSize - bufferPos)) {
+      throw InvalidProtocolBufferNanoException.truncatedMessage();
+    }
+
+    final String result = new String(buffer, bufferPos, size, "UTF-8");
+    bufferPos += size;
+    return result;
+  }
+
+  /** Read a {@code group} field value from the stream. */
+  public void readGroup(final MessageNano msg, final int fieldNumber)
+      throws IOException {
+    if (recursionDepth >= recursionLimit) {
+      throw InvalidProtocolBufferNanoException.recursionLimitExceeded();
+    }
+    ++recursionDepth;
+    msg.mergeFrom(this);
+    checkLastTagWas(
+      WireFormatNano.makeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP));
+    --recursionDepth;
+  }
+
+  public void readMessage(final MessageNano msg)
+      throws IOException {
+    final int length = readRawVarint32();
+    if (recursionDepth >= recursionLimit) {
+      throw InvalidProtocolBufferNanoException.recursionLimitExceeded();
+    }
+    final int oldLimit = pushLimit(length);
+    ++recursionDepth;
+    msg.mergeFrom(this);
+    checkLastTagWas(0);
+    --recursionDepth;
+    popLimit(oldLimit);
+  }
+
+  /** Read a {@code bytes} field value from the stream. */
+  public byte[] readBytes() throws IOException {
+    final int size = readRawVarint32();
+    if (size < 0) {
+      throw InvalidProtocolBufferNanoException.negativeSize();
+    }
+    if (size == 0) {
+      return WireFormatNano.EMPTY_BYTES;
+    }
+    if (size > (bufferSize - bufferPos)) {
+      throw InvalidProtocolBufferNanoException.truncatedMessage();
+    }
+
+    final byte[] result = new byte[size];
+    System.arraycopy(buffer, bufferPos, result, 0, size);
+    bufferPos += size;
+    return result;
+  }
+
+  /** Read a {@code uint32} field value from the stream. */
+  public int readUInt32() throws IOException {
+    return readRawVarint32();
+  }
+
+  /**
+   * Read an enum field value from the stream.  Caller is responsible
+   * for converting the numeric value to an actual enum.
+   */
+  public int readEnum() throws IOException {
+    return readRawVarint32();
+  }
+
+  /** Read an {@code sfixed32} field value from the stream. */
+  public int readSFixed32() throws IOException {
+    return readRawLittleEndian32();
+  }
+
+  /** Read an {@code sfixed64} field value from the stream. */
+  public long readSFixed64() throws IOException {
+    return readRawLittleEndian64();
+  }
+
+  /** Read an {@code sint32} field value from the stream. */
+  public int readSInt32() throws IOException {
+    return decodeZigZag32(readRawVarint32());
+  }
+
+  /** Read an {@code sint64} field value from the stream. */
+  public long readSInt64() throws IOException {
+    return decodeZigZag64(readRawVarint64());
+  }
+
+  // =================================================================
+
+  /**
+   * Read a raw Varint from the stream.  If larger than 32 bits, discard the
+   * upper bits.
+   */
+  public int readRawVarint32() throws IOException {
+    byte tmp = readRawByte();
+    if (tmp >= 0) {
+      return tmp;
+    }
+    int result = tmp & 0x7f;
+    if ((tmp = readRawByte()) >= 0) {
+      result |= tmp << 7;
+    } else {
+      result |= (tmp & 0x7f) << 7;
+      if ((tmp = readRawByte()) >= 0) {
+        result |= tmp << 14;
+      } else {
+        result |= (tmp & 0x7f) << 14;
+        if ((tmp = readRawByte()) >= 0) {
+          result |= tmp << 21;
+        } else {
+          result |= (tmp & 0x7f) << 21;
+          result |= (tmp = readRawByte()) << 28;
+          if (tmp < 0) {
+            // Discard upper 32 bits.
+            for (int i = 0; i < 5; i++) {
+              if (readRawByte() >= 0) {
+                return result;
+              }
+            }
+            throw InvalidProtocolBufferNanoException.malformedVarint();
+          }
+        }
+      }
+    }
+    return result;
+  }
+
+  /** Read a raw Varint from the stream. */
+  public long readRawVarint64() throws IOException {
+    int shift = 0;
+    long result = 0;
+    while (shift < 64) {
+      final byte b = readRawByte();
+      result |= (long)(b & 0x7F) << shift;
+      if ((b & 0x80) == 0) {
+        return result;
+      }
+      shift += 7;
+    }
+    throw InvalidProtocolBufferNanoException.malformedVarint();
+  }
+
+  /** Read a 32-bit little-endian integer from the stream. */
+  public int readRawLittleEndian32() throws IOException {
+    final byte b1 = readRawByte();
+    final byte b2 = readRawByte();
+    final byte b3 = readRawByte();
+    final byte b4 = readRawByte();
+    return ((b1 & 0xff)      ) |
+           ((b2 & 0xff) <<  8) |
+           ((b3 & 0xff) << 16) |
+           ((b4 & 0xff) << 24);
+  }
+
+  /** Read a 64-bit little-endian integer from the stream. */
+  public long readRawLittleEndian64() throws IOException {
+    final byte b1 = readRawByte();
+    final byte b2 = readRawByte();
+    final byte b3 = readRawByte();
+    final byte b4 = readRawByte();
+    final byte b5 = readRawByte();
+    final byte b6 = readRawByte();
+    final byte b7 = readRawByte();
+    final byte b8 = readRawByte();
+    return (((long)b1 & 0xff)      ) |
+           (((long)b2 & 0xff) <<  8) |
+           (((long)b3 & 0xff) << 16) |
+           (((long)b4 & 0xff) << 24) |
+           (((long)b5 & 0xff) << 32) |
+           (((long)b6 & 0xff) << 40) |
+           (((long)b7 & 0xff) << 48) |
+           (((long)b8 & 0xff) << 56);
+  }
+
+  /**
+   * Decode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n An unsigned 32-bit integer, stored in a signed int because
+   *          Java has no explicit unsigned support.
+   * @return A signed 32-bit integer.
+   */
+  public static int decodeZigZag32(final int n) {
+    return (n >>> 1) ^ -(n & 1);
+  }
+
+  /**
+   * Decode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n An unsigned 64-bit integer, stored in a signed int because
+   *          Java has no explicit unsigned support.
+   * @return A signed 64-bit integer.
+   */
+  public static long decodeZigZag64(final long n) {
+    return (n >>> 1) ^ -(n & 1);
+  }
+
+  // -----------------------------------------------------------------
+
+  private final byte[] buffer;
+  private int bufferStart;
+  private int bufferSize;
+  private int bufferSizeAfterLimit;
+  private int bufferPos;
+  private int lastTag;
+
+  /** The absolute position of the end of the current message. */
+  private int currentLimit = Integer.MAX_VALUE;
+
+  /** See setRecursionLimit() */
+  private int recursionDepth;
+  private int recursionLimit = DEFAULT_RECURSION_LIMIT;
+
+  /** See setSizeLimit() */
+  private int sizeLimit = DEFAULT_SIZE_LIMIT;
+
+  private static final int DEFAULT_RECURSION_LIMIT = 64;
+  private static final int DEFAULT_SIZE_LIMIT = 64 << 20;  // 64MB
+
+  private CodedInputByteBufferNano(final byte[] buffer, final int off, final int len) {
+    this.buffer = buffer;
+    bufferStart = off;
+    bufferSize = off + len;
+    bufferPos = off;
+  }
+
+  /**
+   * Set the maximum message recursion depth.  In order to prevent malicious
+   * messages from causing stack overflows, {@code CodedInputStream} limits
+   * how deeply messages may be nested.  The default limit is 64.
+   *
+   * @return the old limit.
+   */
+  public int setRecursionLimit(final int limit) {
+    if (limit < 0) {
+      throw new IllegalArgumentException(
+        "Recursion limit cannot be negative: " + limit);
+    }
+    final int oldLimit = recursionLimit;
+    recursionLimit = limit;
+    return oldLimit;
+  }
+
+  /**
+   * Set the maximum message size.  In order to prevent malicious
+   * messages from exhausting memory or causing integer overflows,
+   * {@code CodedInputStream} limits how large a message may be.
+   * The default limit is 64MB.  You should set this limit as small
+   * as you can without harming your app's functionality.  Note that
+   * size limits only apply when reading from an {@code InputStream}, not
+   * when constructed around a raw byte array.
+   * <p>
+   * If you want to read several messages from a single CodedInputStream, you
+   * could call {@link #resetSizeCounter()} after each one to avoid hitting the
+   * size limit.
+   *
+   * @return the old limit.
+   */
+  public int setSizeLimit(final int limit) {
+    if (limit < 0) {
+      throw new IllegalArgumentException(
+        "Size limit cannot be negative: " + limit);
+    }
+    final int oldLimit = sizeLimit;
+    sizeLimit = limit;
+    return oldLimit;
+  }
+
+  /**
+   * Resets the current size counter to zero (see {@link #setSizeLimit(int)}).
+   */
+  public void resetSizeCounter() {
+  }
+
+  /**
+   * Sets {@code currentLimit} to (current position) + {@code byteLimit}.  This
+   * is called when descending into a length-delimited embedded message.
+   *
+   * @return the old limit.
+   */
+  public int pushLimit(int byteLimit) throws InvalidProtocolBufferNanoException {
+    if (byteLimit < 0) {
+      throw InvalidProtocolBufferNanoException.negativeSize();
+    }
+    byteLimit += bufferPos;
+    final int oldLimit = currentLimit;
+    if (byteLimit > oldLimit) {
+      throw InvalidProtocolBufferNanoException.truncatedMessage();
+    }
+    currentLimit = byteLimit;
+
+    recomputeBufferSizeAfterLimit();
+
+    return oldLimit;
+  }
+
+  private void recomputeBufferSizeAfterLimit() {
+    bufferSize += bufferSizeAfterLimit;
+    final int bufferEnd = bufferSize;
+    if (bufferEnd > currentLimit) {
+      // Limit is in current buffer.
+      bufferSizeAfterLimit = bufferEnd - currentLimit;
+      bufferSize -= bufferSizeAfterLimit;
+    } else {
+      bufferSizeAfterLimit = 0;
+    }
+  }
+
+  /**
+   * Discards the current limit, returning to the previous limit.
+   *
+   * @param oldLimit The old limit, as returned by {@code pushLimit}.
+   */
+  public void popLimit(final int oldLimit) {
+    currentLimit = oldLimit;
+    recomputeBufferSizeAfterLimit();
+  }
+
+  /**
+   * Returns the number of bytes to be read before the current limit.
+   * If no limit is set, returns -1.
+   */
+  public int getBytesUntilLimit() {
+    if (currentLimit == Integer.MAX_VALUE) {
+      return -1;
+    }
+
+    final int currentAbsolutePosition = bufferPos;
+    return currentLimit - currentAbsolutePosition;
+  }
+
+  /**
+   * Returns true if the stream has reached the end of the input.  This is the
+   * case if either the end of the underlying input source has been reached or
+   * if the stream has reached a limit created using {@link #pushLimit(int)}.
+   */
+  public boolean isAtEnd() {
+    return bufferPos == bufferSize;
+  }
+
+  /**
+   * Get current position in buffer relative to beginning offset.
+   */
+  public int getPosition() {
+    return bufferPos - bufferStart;
+  }
+
+  /**
+   * Get current (absolute) position in buffer.
+   */
+  public int getAbsolutePosition() {
+    return bufferPos;
+  }
+
+  /**
+   * Return the raw underlying data in the buffer, directly.
+   */
+  public byte[] getBuffer() {
+    return buffer;
+  }
+
+  /**
+   * Retrieves a subset of data in the buffer. The returned array is not backed by the original
+   * buffer array.
+   *
+   * @param offset the position (relative to the buffer start position) to start at.
+   * @param length the number of bytes to retrieve.
+   */
+  public byte[] getData(int offset, int length) {
+    if (length == 0) {
+      return WireFormatNano.EMPTY_BYTES;
+    }
+    byte[] copy = new byte[length];
+    int start = bufferStart + offset;
+    System.arraycopy(buffer, start, copy, 0, length);
+    return copy;
+  }
+
+  /**
+   * Rewind to previous position. Cannot go forward.
+   */
+  public void rewindToPosition(int position) {
+    if (position > bufferPos - bufferStart) {
+      throw new IllegalArgumentException(
+              "Position " + position + " is beyond current " + (bufferPos - bufferStart));
+    }
+    if (position < 0) {
+      throw new IllegalArgumentException("Bad position " + position);
+    }
+    bufferPos = bufferStart + position;
+  }
+
+  /**
+   * Read one byte from the input.
+   *
+   * @throws InvalidProtocolBufferNanoException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  public byte readRawByte() throws IOException {
+    if (bufferPos == bufferSize) {
+      throw InvalidProtocolBufferNanoException.truncatedMessage();
+    }
+    return buffer[bufferPos++];
+  }
+
+  /**
+   * Read a fixed size of bytes from the input.
+   *
+   * @throws InvalidProtocolBufferNanoException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  public byte[] readRawBytes(final int size) throws IOException {
+    if (size < 0) {
+      throw InvalidProtocolBufferNanoException.negativeSize();
+    }
+
+    if (bufferPos + size > currentLimit) {
+      // Read to the end of the stream anyway.
+      skipRawBytes(currentLimit - bufferPos);
+      // Then fail.
+      throw InvalidProtocolBufferNanoException.truncatedMessage();
+    }
+
+    if (size <= bufferSize - bufferPos) {
+      // We have all the bytes we need already.
+      final byte[] bytes = new byte[size];
+      System.arraycopy(buffer, bufferPos, bytes, 0, size);
+      bufferPos += size;
+      return bytes;
+    } else {
+      throw InvalidProtocolBufferNanoException.truncatedMessage();
+    }
+  }
+
+  /**
+   * Reads and discards {@code size} bytes.
+   *
+   * @throws InvalidProtocolBufferNanoException The end of the stream or the current
+   *                                        limit was reached.
+   */
+  public void skipRawBytes(final int size) throws IOException {
+    if (size < 0) {
+      throw InvalidProtocolBufferNanoException.negativeSize();
+    }
+
+    if (bufferPos + size > currentLimit) {
+      // Read to the end of the stream anyway.
+      skipRawBytes(currentLimit - bufferPos);
+      // Then fail.
+      throw InvalidProtocolBufferNanoException.truncatedMessage();
+    }
+
+    if (size <= bufferSize - bufferPos) {
+      // We have all the bytes we need already.
+      bufferPos += size;
+    } else {
+      throw InvalidProtocolBufferNanoException.truncatedMessage();
+    }
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java b/protobuf/java/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java
new file mode 100644
index 0000000..662f0fa
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/CodedOutputByteBufferNano.java
@@ -0,0 +1,1128 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.io.IOException;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.ReadOnlyBufferException;
+
+/**
+ * Encodes and writes protocol message fields.
+ *
+ * <p>This class contains two kinds of methods:  methods that write specific
+ * protocol message constructs and field types (e.g. {@link #writeTag} and
+ * {@link #writeInt32}) and methods that write low-level values (e.g.
+ * {@link #writeRawVarint32} and {@link #writeRawBytes}).  If you are
+ * writing encoded protocol messages, you should use the former methods, but if
+ * you are writing some other format of your own design, use the latter.
+ *
+ * <p>This class is totally unsynchronized.
+ *
+ * @author kneton@google.com Kenton Varda
+ */
+public final class CodedOutputByteBufferNano {
+  /* max bytes per java UTF-16 char in UTF-8 */
+  private static final int MAX_UTF8_EXPANSION = 3;
+  private final ByteBuffer buffer;
+
+  private CodedOutputByteBufferNano(final byte[] buffer, final int offset,
+                            final int length) {
+    this(ByteBuffer.wrap(buffer, offset, length));
+  }
+
+  private CodedOutputByteBufferNano(final ByteBuffer buffer) {
+    this.buffer = buffer;
+    this.buffer.order(ByteOrder.LITTLE_ENDIAN);
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} that writes directly to the given
+   * byte array.  If more bytes are written than fit in the array,
+   * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
+   * array is faster than writing to an {@code OutputStream}.
+   */
+  public static CodedOutputByteBufferNano newInstance(final byte[] flatArray) {
+    return newInstance(flatArray, 0, flatArray.length);
+  }
+
+  /**
+   * Create a new {@code CodedOutputStream} that writes directly to the given
+   * byte array slice.  If more bytes are written than fit in the slice,
+   * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
+   * array is faster than writing to an {@code OutputStream}.
+   */
+  public static CodedOutputByteBufferNano newInstance(final byte[] flatArray,
+                                              final int offset,
+                                              final int length) {
+    return new CodedOutputByteBufferNano(flatArray, offset, length);
+  }
+
+  // -----------------------------------------------------------------
+
+  /** Write a {@code double} field, including tag, to the stream. */
+  public void writeDouble(final int fieldNumber, final double value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
+    writeDoubleNoTag(value);
+  }
+
+  /** Write a {@code float} field, including tag, to the stream. */
+  public void writeFloat(final int fieldNumber, final float value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
+    writeFloatNoTag(value);
+  }
+
+  /** Write a {@code uint64} field, including tag, to the stream. */
+  public void writeUInt64(final int fieldNumber, final long value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
+    writeUInt64NoTag(value);
+  }
+
+  /** Write an {@code int64} field, including tag, to the stream. */
+  public void writeInt64(final int fieldNumber, final long value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
+    writeInt64NoTag(value);
+  }
+
+  /** Write an {@code int32} field, including tag, to the stream. */
+  public void writeInt32(final int fieldNumber, final int value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
+    writeInt32NoTag(value);
+  }
+
+  /** Write a {@code fixed64} field, including tag, to the stream. */
+  public void writeFixed64(final int fieldNumber, final long value)
+                           throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
+    writeFixed64NoTag(value);
+  }
+
+  /** Write a {@code fixed32} field, including tag, to the stream. */
+  public void writeFixed32(final int fieldNumber, final int value)
+                           throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
+    writeFixed32NoTag(value);
+  }
+
+  /** Write a {@code bool} field, including tag, to the stream. */
+  public void writeBool(final int fieldNumber, final boolean value)
+                        throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
+    writeBoolNoTag(value);
+  }
+
+  /** Write a {@code string} field, including tag, to the stream. */
+  public void writeString(final int fieldNumber, final String value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
+    writeStringNoTag(value);
+  }
+
+  /** Write a {@code group} field, including tag, to the stream. */
+  public void writeGroup(final int fieldNumber, final MessageNano value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_START_GROUP);
+    writeGroupNoTag(value);
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP);
+  }
+
+  /** Write an embedded message field, including tag, to the stream. */
+  public void writeMessage(final int fieldNumber, final MessageNano value)
+                           throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
+    writeMessageNoTag(value);
+  }
+
+  /** Write a {@code bytes} field, including tag, to the stream. */
+  public void writeBytes(final int fieldNumber, final byte[] value)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
+    writeBytesNoTag(value);
+  }
+
+  /** Write a {@code bytes} field, including tag, to the stream. */
+  public void writeBytes(final int fieldNumber, final byte[] value,
+                         final int offset, final int length)
+                         throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
+    writeBytesNoTag(value, offset, length);
+  }
+
+  /** Write a {@code uint32} field, including tag, to the stream. */
+  public void writeUInt32(final int fieldNumber, final int value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
+    writeUInt32NoTag(value);
+  }
+
+  /**
+   * Write an enum field, including tag, to the stream.  Caller is responsible
+   * for converting the enum value to its numeric value.
+   */
+  public void writeEnum(final int fieldNumber, final int value)
+                        throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
+    writeEnumNoTag(value);
+  }
+
+  /** Write an {@code sfixed32} field, including tag, to the stream. */
+  public void writeSFixed32(final int fieldNumber, final int value)
+                            throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED32);
+    writeSFixed32NoTag(value);
+  }
+
+  /** Write an {@code sfixed64} field, including tag, to the stream. */
+  public void writeSFixed64(final int fieldNumber, final long value)
+                            throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_FIXED64);
+    writeSFixed64NoTag(value);
+  }
+
+  /** Write an {@code sint32} field, including tag, to the stream. */
+  public void writeSInt32(final int fieldNumber, final int value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
+    writeSInt32NoTag(value);
+  }
+
+  /** Write an {@code sint64} field, including tag, to the stream. */
+  public void writeSInt64(final int fieldNumber, final long value)
+                          throws IOException {
+    writeTag(fieldNumber, WireFormatNano.WIRETYPE_VARINT);
+    writeSInt64NoTag(value);
+  }
+
+  /**
+   * Write a MessageSet extension field to the stream.  For historical reasons,
+   * the wire format differs from normal fields.
+   */
+//  public void writeMessageSetExtension(final int fieldNumber,
+//                                       final MessageMicro value)
+//                                       throws IOException {
+//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
+//    writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
+//    writeMessage(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
+//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
+//  }
+
+  /**
+   * Write an unparsed MessageSet extension field to the stream.  For
+   * historical reasons, the wire format differs from normal fields.
+   */
+//  public void writeRawMessageSetExtension(final int fieldNumber,
+//                                          final ByteStringMicro value)
+//                                          throws IOException {
+//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_START_GROUP);
+//    writeUInt32(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber);
+//    writeBytes(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
+//    writeTag(WireFormatMicro.MESSAGE_SET_ITEM, WireFormatMicro.WIRETYPE_END_GROUP);
+//  }
+
+  // -----------------------------------------------------------------
+
+  /** Write a {@code double} field to the stream. */
+  public void writeDoubleNoTag(final double value) throws IOException {
+    writeRawLittleEndian64(Double.doubleToLongBits(value));
+  }
+
+  /** Write a {@code float} field to the stream. */
+  public void writeFloatNoTag(final float value) throws IOException {
+    writeRawLittleEndian32(Float.floatToIntBits(value));
+  }
+
+  /** Write a {@code uint64} field to the stream. */
+  public void writeUInt64NoTag(final long value) throws IOException {
+    writeRawVarint64(value);
+  }
+
+  /** Write an {@code int64} field to the stream. */
+  public void writeInt64NoTag(final long value) throws IOException {
+    writeRawVarint64(value);
+  }
+
+  /** Write an {@code int32} field to the stream. */
+  public void writeInt32NoTag(final int value) throws IOException {
+    if (value >= 0) {
+      writeRawVarint32(value);
+    } else {
+      // Must sign-extend.
+      writeRawVarint64(value);
+    }
+  }
+
+  /** Write a {@code fixed64} field to the stream. */
+  public void writeFixed64NoTag(final long value) throws IOException {
+    writeRawLittleEndian64(value);
+  }
+
+  /** Write a {@code fixed32} field to the stream. */
+  public void writeFixed32NoTag(final int value) throws IOException {
+    writeRawLittleEndian32(value);
+  }
+
+  /** Write a {@code bool} field to the stream. */
+  public void writeBoolNoTag(final boolean value) throws IOException {
+    writeRawByte(value ? 1 : 0);
+  }
+
+  /** Write a {@code string} field to the stream. */
+  public void writeStringNoTag(final String value) throws IOException {
+    // UTF-8 byte length of the string is at least its UTF-16 code unit length (value.length()),
+    // and at most 3 times of it. Optimize for the case where we know this length results in a
+    // constant varint length - saves measuring length of the string.
+    try {
+      final int minLengthVarIntSize = computeRawVarint32Size(value.length());
+      final int maxLengthVarIntSize = computeRawVarint32Size(value.length() * MAX_UTF8_EXPANSION);
+      if (minLengthVarIntSize == maxLengthVarIntSize) {
+        int oldPosition = buffer.position();
+        // Buffer.position, when passed a position that is past its limit, throws
+        // IllegalArgumentException, and this class is documented to throw
+        // OutOfSpaceException instead.
+        if (buffer.remaining() < minLengthVarIntSize) {
+          throw new OutOfSpaceException(oldPosition + minLengthVarIntSize, buffer.limit());
+        }
+        buffer.position(oldPosition + minLengthVarIntSize);
+        encode(value, buffer);
+        int newPosition = buffer.position();
+        buffer.position(oldPosition);
+        writeRawVarint32(newPosition - oldPosition - minLengthVarIntSize);
+        buffer.position(newPosition);
+      } else {
+        writeRawVarint32(encodedLength(value));
+        encode(value, buffer);
+      }
+    } catch (BufferOverflowException e) {
+      final OutOfSpaceException outOfSpaceException = new OutOfSpaceException(buffer.position(),
+          buffer.limit());
+      outOfSpaceException.initCause(e);
+      throw outOfSpaceException;
+    }
+  }
+
+  // These UTF-8 handling methods are copied from Guava's Utf8 class.
+  /**
+   * Returns the number of bytes in the UTF-8-encoded form of {@code sequence}. For a string,
+   * this method is equivalent to {@code string.getBytes(UTF_8).length}, but is more efficient in
+   * both time and space.
+   *
+   * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
+   *     surrogates)
+   */
+  private static int encodedLength(CharSequence sequence) {
+    // Warning to maintainers: this implementation is highly optimized.
+    int utf16Length = sequence.length();
+    int utf8Length = utf16Length;
+    int i = 0;
+
+    // This loop optimizes for pure ASCII.
+    while (i < utf16Length && sequence.charAt(i) < 0x80) {
+      i++;
+    }
+
+    // This loop optimizes for chars less than 0x800.
+    for (; i < utf16Length; i++) {
+      char c = sequence.charAt(i);
+      if (c < 0x800) {
+        utf8Length += ((0x7f - c) >>> 31);  // branch free!
+      } else {
+        utf8Length += encodedLengthGeneral(sequence, i);
+        break;
+      }
+    }
+
+    if (utf8Length < utf16Length) {
+      // Necessary and sufficient condition for overflow because of maximum 3x expansion
+      throw new IllegalArgumentException("UTF-8 length does not fit in int: "
+              + (utf8Length + (1L << 32)));
+    }
+    return utf8Length;
+  }
+
+  private static int encodedLengthGeneral(CharSequence sequence, int start) {
+    int utf16Length = sequence.length();
+    int utf8Length = 0;
+    for (int i = start; i < utf16Length; i++) {
+      char c = sequence.charAt(i);
+      if (c < 0x800) {
+        utf8Length += (0x7f - c) >>> 31; // branch free!
+      } else {
+        utf8Length += 2;
+        // jdk7+: if (Character.isSurrogate(c)) {
+        if (Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE) {
+          // Check that we have a well-formed surrogate pair.
+          int cp = Character.codePointAt(sequence, i);
+          if (cp < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+            throw new IllegalArgumentException("Unpaired surrogate at index " + i);
+          }
+          i++;
+        }
+      }
+    }
+    return utf8Length;
+  }
+
+  /**
+   * Encodes {@code sequence} into UTF-8, in {@code byteBuffer}. For a string, this method is
+   * equivalent to {@code buffer.put(string.getBytes(UTF_8))}, but is more efficient in both time
+   * and space. Bytes are written starting at the current position. This method requires paired
+   * surrogates, and therefore does not support chunking.
+   *
+   * <p>To ensure sufficient space in the output buffer, either call {@link #encodedLength} to
+   * compute the exact amount needed, or leave room for {@code 3 * sequence.length()}, which is the
+   * largest possible number of bytes that any input can be encoded to.
+   *
+   * @throws IllegalArgumentException if {@code sequence} contains ill-formed UTF-16 (unpaired
+   *     surrogates)
+   * @throws BufferOverflowException if {@code sequence} encoded in UTF-8 does not fit in
+   *     {@code byteBuffer}'s remaining space.
+   * @throws ReadOnlyBufferException if {@code byteBuffer} is a read-only buffer.
+   */
+  private static void encode(CharSequence sequence, ByteBuffer byteBuffer) {
+    if (byteBuffer.isReadOnly()) {
+      throw new ReadOnlyBufferException();
+    } else if (byteBuffer.hasArray()) {
+      try {
+        int encoded = encode(sequence,
+                byteBuffer.array(),
+                byteBuffer.arrayOffset() + byteBuffer.position(),
+                byteBuffer.remaining());
+        byteBuffer.position(encoded - byteBuffer.arrayOffset());
+      } catch (ArrayIndexOutOfBoundsException e) {
+        BufferOverflowException boe = new BufferOverflowException();
+        boe.initCause(e);
+        throw boe;
+      }
+    } else {
+      encodeDirect(sequence, byteBuffer);
+    }
+  }
+
+  private static void encodeDirect(CharSequence sequence, ByteBuffer byteBuffer) {
+    int utf16Length = sequence.length();
+    for (int i = 0; i < utf16Length; i++) {
+      final char c = sequence.charAt(i);
+      if (c < 0x80) { // ASCII
+        byteBuffer.put((byte) c);
+      } else if (c < 0x800) { // 11 bits, two UTF-8 bytes
+        byteBuffer.put((byte) ((0xF << 6) | (c >>> 6)));
+        byteBuffer.put((byte) (0x80 | (0x3F & c)));
+      } else if (c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) {
+        // Maximium single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
+        byteBuffer.put((byte) ((0xF << 5) | (c >>> 12)));
+        byteBuffer.put((byte) (0x80 | (0x3F & (c >>> 6))));
+        byteBuffer.put((byte) (0x80 | (0x3F & c)));
+      } else {
+        final char low;
+        if (i + 1 == sequence.length()
+                || !Character.isSurrogatePair(c, (low = sequence.charAt(++i)))) {
+          throw new IllegalArgumentException("Unpaired surrogate at index " + (i - 1));
+        }
+        int codePoint = Character.toCodePoint(c, low);
+        byteBuffer.put((byte) ((0xF << 4) | (codePoint >>> 18)));
+        byteBuffer.put((byte) (0x80 | (0x3F & (codePoint >>> 12))));
+        byteBuffer.put((byte) (0x80 | (0x3F & (codePoint >>> 6))));
+        byteBuffer.put((byte) (0x80 | (0x3F & codePoint)));
+      }
+    }
+  }
+
+  private static int encode(CharSequence sequence, byte[] bytes, int offset, int length) {
+    int utf16Length = sequence.length();
+    int j = offset;
+    int i = 0;
+    int limit = offset + length;
+    // Designed to take advantage of
+    // https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
+    for (char c; i < utf16Length && i + j < limit && (c = sequence.charAt(i)) < 0x80; i++) {
+      bytes[j + i] = (byte) c;
+    }
+    if (i == utf16Length) {
+      return j + utf16Length;
+    }
+    j += i;
+    for (char c; i < utf16Length; i++) {
+      c = sequence.charAt(i);
+      if (c < 0x80 && j < limit) {
+        bytes[j++] = (byte) c;
+      } else if (c < 0x800 && j <= limit - 2) { // 11 bits, two UTF-8 bytes
+        bytes[j++] = (byte) ((0xF << 6) | (c >>> 6));
+        bytes[j++] = (byte) (0x80 | (0x3F & c));
+      } else if ((c < Character.MIN_SURROGATE || Character.MAX_SURROGATE < c) && j <= limit - 3) {
+        // Maximum single-char code point is 0xFFFF, 16 bits, three UTF-8 bytes
+        bytes[j++] = (byte) ((0xF << 5) | (c >>> 12));
+        bytes[j++] = (byte) (0x80 | (0x3F & (c >>> 6)));
+        bytes[j++] = (byte) (0x80 | (0x3F & c));
+      } else if (j <= limit - 4) {
+        // Minimum code point represented by a surrogate pair is 0x10000, 17 bits, four UTF-8 bytes
+        final char low;
+        if (i + 1 == sequence.length()
+                || !Character.isSurrogatePair(c, (low = sequence.charAt(++i)))) {
+          throw new IllegalArgumentException("Unpaired surrogate at index " + (i - 1));
+        }
+        int codePoint = Character.toCodePoint(c, low);
+        bytes[j++] = (byte) ((0xF << 4) | (codePoint >>> 18));
+        bytes[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 12)));
+        bytes[j++] = (byte) (0x80 | (0x3F & (codePoint >>> 6)));
+        bytes[j++] = (byte) (0x80 | (0x3F & codePoint));
+      } else {
+        // If we are surrogates and we're not a surrogate pair, always throw an
+        // IllegalArgumentException instead of an ArrayOutOfBoundsException.
+        if ((Character.MIN_SURROGATE <= c && c <= Character.MAX_SURROGATE)
+            && (i + 1 == sequence.length()
+                || !Character.isSurrogatePair(c, sequence.charAt(i + 1)))) {
+          throw new IllegalArgumentException("Unpaired surrogate at index " + i);
+        }
+        throw new ArrayIndexOutOfBoundsException("Failed writing " + c + " at index " + j);
+      }
+    }
+    return j;
+  }
+
+  // End guava UTF-8 methods
+
+  /** Write a {@code group} field to the stream. */
+  public void writeGroupNoTag(final MessageNano value) throws IOException {
+    value.writeTo(this);
+  }
+
+  /** Write an embedded message field to the stream. */
+  public void writeMessageNoTag(final MessageNano value) throws IOException {
+    writeRawVarint32(value.getCachedSize());
+    value.writeTo(this);
+  }
+
+  /** Write a {@code bytes} field to the stream. */
+  public void writeBytesNoTag(final byte[] value) throws IOException {
+    writeRawVarint32(value.length);
+    writeRawBytes(value);
+  }
+
+  /** Write a {@code bytes} field to the stream. */
+  public void writeBytesNoTag(final byte[] value, final int offset, final int length)
+                              throws IOException {
+    writeRawVarint32(length);
+    writeRawBytes(value, offset, length);
+  }
+
+  /** Write a {@code uint32} field to the stream. */
+  public void writeUInt32NoTag(final int value) throws IOException {
+    writeRawVarint32(value);
+  }
+
+  /**
+   * Write an enum field to the stream.  Caller is responsible
+   * for converting the enum value to its numeric value.
+   */
+  public void writeEnumNoTag(final int value) throws IOException {
+    writeRawVarint32(value);
+  }
+
+  /** Write an {@code sfixed32} field to the stream. */
+  public void writeSFixed32NoTag(final int value) throws IOException {
+    writeRawLittleEndian32(value);
+  }
+
+  /** Write an {@code sfixed64} field to the stream. */
+  public void writeSFixed64NoTag(final long value) throws IOException {
+    writeRawLittleEndian64(value);
+  }
+
+  /** Write an {@code sint32} field to the stream. */
+  public void writeSInt32NoTag(final int value) throws IOException {
+    writeRawVarint32(encodeZigZag32(value));
+  }
+
+  /** Write an {@code sint64} field to the stream. */
+  public void writeSInt64NoTag(final long value) throws IOException {
+    writeRawVarint64(encodeZigZag64(value));
+  }
+
+  // =================================================================
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code double} field, including tag.
+   */
+  public static int computeDoubleSize(final int fieldNumber,
+                                      final double value) {
+    return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code float} field, including tag.
+   */
+  public static int computeFloatSize(final int fieldNumber, final float value) {
+    return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint64} field, including tag.
+   */
+  public static int computeUInt64Size(final int fieldNumber, final long value) {
+    return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int64} field, including tag.
+   */
+  public static int computeInt64Size(final int fieldNumber, final long value) {
+    return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int32} field, including tag.
+   */
+  public static int computeInt32Size(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed64} field, including tag.
+   */
+  public static int computeFixed64Size(final int fieldNumber,
+                                       final long value) {
+    return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed32} field, including tag.
+   */
+  public static int computeFixed32Size(final int fieldNumber,
+                                       final int value) {
+    return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bool} field, including tag.
+   */
+  public static int computeBoolSize(final int fieldNumber,
+                                    final boolean value) {
+    return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code string} field, including tag.
+   */
+  public static int computeStringSize(final int fieldNumber,
+                                      final String value) {
+    return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code group} field, including tag.
+   */
+  public static int computeGroupSize(final int fieldNumber,
+                                     final MessageNano value) {
+    return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * embedded message field, including tag.
+   */
+  public static int computeMessageSize(final int fieldNumber,
+                                       final MessageNano value) {
+    return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field, including tag.
+   */
+  public static int computeBytesSize(final int fieldNumber,
+                                     final byte[] value) {
+    return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field of the given length, including tag.
+   */
+  public static int computeBytesSize(final int fieldNumber,
+                                     final int length) {
+    return computeTagSize(fieldNumber) + computeBytesSizeNoTag(length);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint32} field, including tag.
+   */
+  public static int computeUInt32Size(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * enum field, including tag.  Caller is responsible for converting the
+   * enum value to its numeric value.
+   */
+  public static int computeEnumSize(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed32} field, including tag.
+   */
+  public static int computeSFixed32Size(final int fieldNumber,
+                                        final int value) {
+    return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed64} field, including tag.
+   */
+  public static int computeSFixed64Size(final int fieldNumber,
+                                        final long value) {
+    return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint32} field, including tag.
+   */
+  public static int computeSInt32Size(final int fieldNumber, final int value) {
+    return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint64} field, including tag.
+   */
+  public static int computeSInt64Size(final int fieldNumber, final long value) {
+    return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * MessageSet extension to the stream.  For historical reasons,
+   * the wire format differs from normal fields.
+   */
+//  public static int computeMessageSetExtensionSize(
+//      final int fieldNumber, final MessageMicro value) {
+//    return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
+//           computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
+//           computeMessageSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
+//  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * unparsed MessageSet extension field to the stream.  For
+   * historical reasons, the wire format differs from normal fields.
+   */
+//  public static int computeRawMessageSetExtensionSize(
+//      final int fieldNumber, final ByteStringMicro value) {
+//    return computeTagSize(WireFormatMicro.MESSAGE_SET_ITEM) * 2 +
+//           computeUInt32Size(WireFormatMicro.MESSAGE_SET_TYPE_ID, fieldNumber) +
+//           computeBytesSize(WireFormatMicro.MESSAGE_SET_MESSAGE, value);
+//  }
+
+  // -----------------------------------------------------------------
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code double} field, including tag.
+   */
+  public static int computeDoubleSizeNoTag(final double value) {
+    return LITTLE_ENDIAN_64_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code float} field, including tag.
+   */
+  public static int computeFloatSizeNoTag(final float value) {
+    return LITTLE_ENDIAN_32_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint64} field, including tag.
+   */
+  public static int computeUInt64SizeNoTag(final long value) {
+    return computeRawVarint64Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int64} field, including tag.
+   */
+  public static int computeInt64SizeNoTag(final long value) {
+    return computeRawVarint64Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code int32} field, including tag.
+   */
+  public static int computeInt32SizeNoTag(final int value) {
+    if (value >= 0) {
+      return computeRawVarint32Size(value);
+    } else {
+      // Must sign-extend.
+      return 10;
+    }
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed64} field.
+   */
+  public static int computeFixed64SizeNoTag(final long value) {
+    return LITTLE_ENDIAN_64_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code fixed32} field.
+   */
+  public static int computeFixed32SizeNoTag(final int value) {
+    return LITTLE_ENDIAN_32_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bool} field.
+   */
+  public static int computeBoolSizeNoTag(final boolean value) {
+    return 1;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code string} field.
+   */
+  public static int computeStringSizeNoTag(final String value) {
+    final int length = encodedLength(value);
+    return computeRawVarint32Size(length) + length;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code group} field.
+   */
+  public static int computeGroupSizeNoTag(final MessageNano value) {
+    return value.getSerializedSize();
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an embedded
+   * message field.
+   */
+  public static int computeMessageSizeNoTag(final MessageNano value) {
+    final int size = value.getSerializedSize();
+    return computeRawVarint32Size(size) + size;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field.
+   */
+  public static int computeBytesSizeNoTag(final byte[] value) {
+    return computeRawVarint32Size(value.length) + value.length;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code bytes} field of the given length.
+   */
+  public static int computeBytesSizeNoTag(final int length) {
+    return computeRawVarint32Size(length) + length;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a
+   * {@code uint32} field.
+   */
+  public static int computeUInt32SizeNoTag(final int value) {
+    return computeRawVarint32Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an enum field.
+   * Caller is responsible for converting the enum value to its numeric value.
+   */
+  public static int computeEnumSizeNoTag(final int value) {
+    return computeRawVarint32Size(value);
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed32} field.
+   */
+  public static int computeSFixed32SizeNoTag(final int value) {
+    return LITTLE_ENDIAN_32_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sfixed64} field.
+   */
+  public static int computeSFixed64SizeNoTag(final long value) {
+    return LITTLE_ENDIAN_64_SIZE;
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint32} field.
+   */
+  public static int computeSInt32SizeNoTag(final int value) {
+    return computeRawVarint32Size(encodeZigZag32(value));
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode an
+   * {@code sint64} field.
+   */
+  public static int computeSInt64SizeNoTag(final long value) {
+    return computeRawVarint64Size(encodeZigZag64(value));
+  }
+
+  // =================================================================
+
+  /**
+   * If writing to a flat array, return the space left in the array.
+   * Otherwise, throws {@code UnsupportedOperationException}.
+   */
+  public int spaceLeft() {
+    return buffer.remaining();
+  }
+
+  /**
+   * Verifies that {@link #spaceLeft()} returns zero.  It's common to create
+   * a byte array that is exactly big enough to hold a message, then write to
+   * it with a {@code CodedOutputStream}.  Calling {@code checkNoSpaceLeft()}
+   * after writing verifies that the message was actually as big as expected,
+   * which can help catch bugs.
+   */
+  public void checkNoSpaceLeft() {
+    if (spaceLeft() != 0) {
+      throw new IllegalStateException(
+        "Did not write as much data as expected.");
+    }
+  }
+
+  /**
+   * Returns the position within the internal buffer.
+   */
+  public int position() {
+    return buffer.position();
+  }
+
+  /**
+   * Resets the position within the internal buffer to zero.
+   *
+   * @see #position
+   * @see #spaceLeft
+   */
+  public void reset() {
+    buffer.clear();
+  }
+
+  /**
+   * If you create a CodedOutputStream around a simple flat array, you must
+   * not attempt to write more bytes than the array has space.  Otherwise,
+   * this exception will be thrown.
+   */
+  public static class OutOfSpaceException extends IOException {
+    private static final long serialVersionUID = -6947486886997889499L;
+
+    OutOfSpaceException(int position, int limit) {
+      super("CodedOutputStream was writing to a flat byte array and ran " +
+            "out of space (pos " + position + " limit " + limit + ").");
+    }
+  }
+
+  /** Write a single byte. */
+  public void writeRawByte(final byte value) throws IOException {
+    if (!buffer.hasRemaining()) {
+      // We're writing to a single buffer.
+      throw new OutOfSpaceException(buffer.position(), buffer.limit());
+    }
+
+    buffer.put(value);
+  }
+
+  /** Write a single byte, represented by an integer value. */
+  public void writeRawByte(final int value) throws IOException {
+    writeRawByte((byte) value);
+  }
+
+  /** Write an array of bytes. */
+  public void writeRawBytes(final byte[] value) throws IOException {
+    writeRawBytes(value, 0, value.length);
+  }
+
+  /** Write part of an array of bytes. */
+  public void writeRawBytes(final byte[] value, int offset, int length)
+                            throws IOException {
+    if (buffer.remaining() >= length) {
+      buffer.put(value, offset, length);
+    } else {
+      // We're writing to a single buffer.
+      throw new OutOfSpaceException(buffer.position(), buffer.limit());
+    }
+  }
+
+  /** Encode and write a tag. */
+  public void writeTag(final int fieldNumber, final int wireType)
+                       throws IOException {
+    writeRawVarint32(WireFormatNano.makeTag(fieldNumber, wireType));
+  }
+
+  /** Compute the number of bytes that would be needed to encode a tag. */
+  public static int computeTagSize(final int fieldNumber) {
+    return computeRawVarint32Size(WireFormatNano.makeTag(fieldNumber, 0));
+  }
+
+  /**
+   * Encode and write a varint.  {@code value} is treated as
+   * unsigned, so it won't be sign-extended if negative.
+   */
+  public void writeRawVarint32(int value) throws IOException {
+    while (true) {
+      if ((value & ~0x7F) == 0) {
+        writeRawByte(value);
+        return;
+      } else {
+        writeRawByte((value & 0x7F) | 0x80);
+        value >>>= 7;
+      }
+    }
+  }
+
+  /**
+   * Compute the number of bytes that would be needed to encode a varint.
+   * {@code value} is treated as unsigned, so it won't be sign-extended if
+   * negative.
+   */
+  public static int computeRawVarint32Size(final int value) {
+    if ((value & (0xffffffff <<  7)) == 0) return 1;
+    if ((value & (0xffffffff << 14)) == 0) return 2;
+    if ((value & (0xffffffff << 21)) == 0) return 3;
+    if ((value & (0xffffffff << 28)) == 0) return 4;
+    return 5;
+  }
+
+  /** Encode and write a varint. */
+  public void writeRawVarint64(long value) throws IOException {
+    while (true) {
+      if ((value & ~0x7FL) == 0) {
+        writeRawByte((int)value);
+        return;
+      } else {
+        writeRawByte(((int)value & 0x7F) | 0x80);
+        value >>>= 7;
+      }
+    }
+  }
+
+  /** Compute the number of bytes that would be needed to encode a varint. */
+  public static int computeRawVarint64Size(final long value) {
+    if ((value & (0xffffffffffffffffL <<  7)) == 0) return 1;
+    if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
+    if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
+    if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
+    if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
+    if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
+    if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
+    if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
+    if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
+    return 10;
+  }
+
+  /** Write a little-endian 32-bit integer. */
+  public void writeRawLittleEndian32(final int value) throws IOException {
+    if (buffer.remaining() < 4) {
+      throw new OutOfSpaceException(buffer.position(), buffer.limit());
+    }
+    buffer.putInt(value);
+  }
+
+  public static final int LITTLE_ENDIAN_32_SIZE = 4;
+
+  /** Write a little-endian 64-bit integer. */
+  public void writeRawLittleEndian64(final long value) throws IOException {
+    if (buffer.remaining() < 8) {
+      throw new OutOfSpaceException(buffer.position(), buffer.limit());
+    }
+    buffer.putLong(value);
+  }
+
+  public static final int LITTLE_ENDIAN_64_SIZE = 8;
+
+  /**
+   * Encode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n A signed 32-bit integer.
+   * @return An unsigned 32-bit integer, stored in a signed int because
+   *         Java has no explicit unsigned support.
+   */
+  public static int encodeZigZag32(final int n) {
+    // Note:  the right-shift must be arithmetic
+    return (n << 1) ^ (n >> 31);
+  }
+
+  /**
+   * Encode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
+   * into values that can be efficiently encoded with varint.  (Otherwise,
+   * negative values must be sign-extended to 64 bits to be varint encoded,
+   * thus always taking 10 bytes on the wire.)
+   *
+   * @param n A signed 64-bit integer.
+   * @return An unsigned 64-bit integer, stored in a signed int because
+   *         Java has no explicit unsigned support.
+   */
+  public static long encodeZigZag64(final long n) {
+    // Note:  the right-shift must be arithmetic
+    return (n << 1) ^ (n >> 63);
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java b/protobuf/java/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java
new file mode 100644
index 0000000..4fe8dce
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/ExtendableMessageNano.java
@@ -0,0 +1,169 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.io.IOException;
+
+/**
+ * Base class of those Protocol Buffer messages that need to store unknown fields,
+ * such as extensions.
+ */
+public abstract class ExtendableMessageNano<M extends ExtendableMessageNano<M>>
+        extends MessageNano {
+    /**
+     * A container for fields unknown to the message, including extensions. Extension fields can
+     * can be accessed through the {@link #getExtension} and {@link #setExtension} methods.
+     */
+    protected FieldArray unknownFieldData;
+
+    @Override
+    protected int computeSerializedSize() {
+        int size = 0;
+        if (unknownFieldData != null) {
+            for (int i = 0; i < unknownFieldData.size(); i++) {
+                FieldData field = unknownFieldData.dataAt(i);
+                size += field.computeSerializedSize();
+            }
+        }
+        return size;
+    }
+
+    @Override
+    public void writeTo(CodedOutputByteBufferNano output) throws IOException {
+        if (unknownFieldData == null) {
+            return;
+        }
+        for (int i = 0; i < unknownFieldData.size(); i++) {
+            FieldData field = unknownFieldData.dataAt(i);
+            field.writeTo(output);
+        }
+    }
+
+    /**
+     * Checks if there is a value stored for the specified extension in this
+     * message.
+     */
+    public final boolean hasExtension(Extension<M, ?> extension) {
+        if (unknownFieldData == null) {
+            return false;
+        }
+        FieldData field = unknownFieldData.get(WireFormatNano.getTagFieldNumber(extension.tag));
+        return field != null;
+    }
+
+    /**
+     * Gets the value stored in the specified extension of this message.
+     */
+    public final <T> T getExtension(Extension<M, T> extension) {
+        if (unknownFieldData == null) {
+            return null;
+        }
+        FieldData field = unknownFieldData.get(WireFormatNano.getTagFieldNumber(extension.tag));
+        return field == null ? null : field.getValue(extension);
+    }
+
+    /**
+     * Sets the value of the specified extension of this message.
+     */
+    public final <T> M setExtension(Extension<M, T> extension, T value) {
+        int fieldNumber = WireFormatNano.getTagFieldNumber(extension.tag);
+        if (value == null) {
+            if (unknownFieldData != null) {
+                unknownFieldData.remove(fieldNumber);
+                if (unknownFieldData.isEmpty()) {
+                    unknownFieldData = null;
+                }
+            }
+        } else {
+            FieldData field = null;
+            if (unknownFieldData == null) {
+                unknownFieldData = new FieldArray();
+            } else {
+                field = unknownFieldData.get(fieldNumber);
+            }
+            if (field == null) {
+                unknownFieldData.put(fieldNumber, new FieldData(extension, value));
+            } else {
+                field.setValue(extension, value);
+            }
+        }
+
+        @SuppressWarnings("unchecked") // Generated code should guarantee type safety
+        M typedThis = (M) this;
+        return typedThis;
+    }
+
+    /**
+     * Stores the binary data of an unknown field.
+     *
+     * <p>Generated messages will call this for unknown fields if the store_unknown_fields
+     * option is on.
+     *
+     * <p>Note that the tag might be a end-group tag (rather than the start of an unknown field) in
+     * which case we do not want to add an unknown field entry.
+     *
+     * @param input the input buffer.
+     * @param tag the tag of the field.
+
+     * @return {@literal true} unless the tag is an end-group tag.
+     */
+    protected final boolean storeUnknownField(CodedInputByteBufferNano input, int tag)
+            throws IOException {
+        int startPos = input.getPosition();
+        if (!input.skipField(tag)) {
+            return false;  // This wasn't an unknown field, it's an end-group tag.
+        }
+        int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
+        int endPos = input.getPosition();
+        byte[] bytes = input.getData(startPos, endPos - startPos);
+        UnknownFieldData unknownField = new UnknownFieldData(tag, bytes);
+
+        FieldData field = null;
+        if (unknownFieldData == null) {
+            unknownFieldData = new FieldArray();
+        } else {
+            field = unknownFieldData.get(fieldNumber);
+        }
+        if (field == null) {
+            field = new FieldData();
+            unknownFieldData.put(fieldNumber, field);
+        }
+        field.addUnknownField(unknownField);
+        return true;
+    }
+
+    @Override
+    public M clone() throws CloneNotSupportedException {
+        M cloned = (M) super.clone();
+        InternalNano.cloneUnknownFieldData(this, cloned);
+        return cloned;
+    }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/Extension.java b/protobuf/java/src/main/java/com/google/protobuf/nano/Extension.java
new file mode 100644
index 0000000..6e2202e
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/Extension.java
@@ -0,0 +1,741 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents an extension.
+ *
+ * @author bduff@google.com (Brian Duff)
+ * @author maxtroy@google.com (Max Cai)
+ * @param <M> the type of the extendable message this extension is for.
+ * @param <T> the Java type of the extension; see {@link #clazz}.
+ */
+public class Extension<M extends ExtendableMessageNano<M>, T> {
+
+    /*
+     * Because we typically only define message-typed extensions, the Extension class hierarchy is
+     * designed as follows, to allow a big amount of code in this file to be removed by ProGuard:
+     *
+     *            Extension          // ready to use for message/group typed extensions
+     *                Δ
+     *                |
+     *       PrimitiveExtension      // for primitive/enum typed extensions
+     */
+
+    public static final int TYPE_DOUBLE   = 1;
+    public static final int TYPE_FLOAT    = 2;
+    public static final int TYPE_INT64    = 3;
+    public static final int TYPE_UINT64   = 4;
+    public static final int TYPE_INT32    = 5;
+    public static final int TYPE_FIXED64  = 6;
+    public static final int TYPE_FIXED32  = 7;
+    public static final int TYPE_BOOL     = 8;
+    public static final int TYPE_STRING   = 9;
+    public static final int TYPE_GROUP    = 10;
+    public static final int TYPE_MESSAGE  = 11;
+    public static final int TYPE_BYTES    = 12;
+    public static final int TYPE_UINT32   = 13;
+    public static final int TYPE_ENUM     = 14;
+    public static final int TYPE_SFIXED32 = 15;
+    public static final int TYPE_SFIXED64 = 16;
+    public static final int TYPE_SINT32   = 17;
+    public static final int TYPE_SINT64   = 18;
+
+    /**
+     * Creates an {@code Extension} of the given message type and tag number.
+     * Should be used by the generated code only.
+     *
+     * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
+     * @deprecated use {@link #createMessageTyped(int, Class, long)} instead.
+     */
+    @Deprecated
+    public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
+            Extension<M, T> createMessageTyped(int type, Class<T> clazz, int tag) {
+        return new Extension<M, T>(type, clazz, tag, false);
+    }
+
+    // Note: these create...() methods take a long for the tag parameter,
+    // because tags are represented as unsigned ints, and these values exist
+    // in generated code as long values. However, they can fit in 32-bits, so
+    // it's safe to cast them to int without loss of precision.
+
+    /**
+     * Creates an {@code Extension} of the given message type and tag number.
+     * Should be used by the generated code only.
+     *
+     * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
+     */
+    public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
+            Extension<M, T> createMessageTyped(int type, Class<T> clazz, long tag) {
+        return new Extension<M, T>(type, clazz, (int) tag, false);
+    }
+
+    /**
+     * Creates a repeated {@code Extension} of the given message type and tag number.
+     * Should be used by the generated code only.
+     *
+     * @param type {@link #TYPE_MESSAGE} or {@link #TYPE_GROUP}
+     */
+    public static <M extends ExtendableMessageNano<M>, T extends MessageNano>
+            Extension<M, T[]> createRepeatedMessageTyped(int type, Class<T[]> clazz, long tag) {
+        return new Extension<M, T[]>(type, clazz, (int) tag, true);
+    }
+
+    /**
+     * Creates an {@code Extension} of the given primitive type and tag number.
+     * Should be used by the generated code only.
+     *
+     * @param type one of {@code TYPE_*}, except {@link #TYPE_MESSAGE} and {@link #TYPE_GROUP}
+     * @param clazz the boxed Java type of this extension
+     */
+    public static <M extends ExtendableMessageNano<M>, T>
+            Extension<M, T> createPrimitiveTyped(int type, Class<T> clazz, long tag) {
+        return new PrimitiveExtension<M, T>(type, clazz, (int) tag, false, 0, 0);
+    }
+
+    /**
+     * Creates a repeated {@code Extension} of the given primitive type and tag number.
+     * Should be used by the generated code only.
+     *
+     * @param type one of {@code TYPE_*}, except {@link #TYPE_MESSAGE} and {@link #TYPE_GROUP}
+     * @param clazz the Java array type of this extension, with an unboxed component type
+     */
+    public static <M extends ExtendableMessageNano<M>, T>
+            Extension<M, T> createRepeatedPrimitiveTyped(
+                    int type, Class<T> clazz, long tag, long nonPackedTag, long packedTag) {
+        return new PrimitiveExtension<M, T>(type, clazz, (int) tag, true,
+            (int) nonPackedTag, (int) packedTag);
+    }
+
+    /**
+     * Protocol Buffer type of this extension; one of the {@code TYPE_} constants.
+     */
+    protected final int type;
+
+    /**
+     * Java type of this extension. For a singular extension, this is the boxed Java type for the
+     * Protocol Buffer {@link #type}; for a repeated extension, this is an array type whose
+     * component type is the unboxed Java type for {@link #type}. For example, for a singular
+     * {@code int32}/{@link #TYPE_INT32} extension, this equals {@code Integer.class}; for a
+     * repeated {@code int32} extension, this equals {@code int[].class}.
+     */
+    protected final Class<T> clazz;
+
+    /**
+     * Tag number of this extension. The data should be viewed as an unsigned 32-bit value.
+     */
+    public final int tag;
+
+    /**
+     * Whether this extension is repeated.
+     */
+    protected final boolean repeated;
+
+    private Extension(int type, Class<T> clazz, int tag, boolean repeated) {
+        this.type = type;
+        this.clazz = clazz;
+        this.tag = tag;
+        this.repeated = repeated;
+    }
+
+    /**
+     * Returns the value of this extension stored in the given list of unknown fields, or
+     * {@code null} if no unknown fields matches this extension.
+     *
+     * @param unknownFields a list of {@link UnknownFieldData}. All of the elements must have a tag
+     *                      that matches this Extension's tag.
+     *
+     */
+    final T getValueFrom(List<UnknownFieldData> unknownFields) {
+        if (unknownFields == null) {
+            return null;
+        }
+        return repeated ? getRepeatedValueFrom(unknownFields) : getSingularValueFrom(unknownFields);
+    }
+
+    private T getRepeatedValueFrom(List<UnknownFieldData> unknownFields) {
+        // For repeated extensions, read all matching unknown fields in their original order.
+        List<Object> resultList = new ArrayList<Object>();
+        for (int i = 0; i < unknownFields.size(); i++) {
+            UnknownFieldData data = unknownFields.get(i);
+            if (data.bytes.length != 0) {
+                readDataInto(data, resultList);
+            }
+        }
+
+        int resultSize = resultList.size();
+        if (resultSize == 0) {
+            return null;
+        } else {
+            T result = clazz.cast(Array.newInstance(clazz.getComponentType(), resultSize));
+            for (int i = 0; i < resultSize; i++) {
+                Array.set(result, i, resultList.get(i));
+            }
+            return result;
+        }
+    }
+
+    private T getSingularValueFrom(List<UnknownFieldData> unknownFields) {
+        // For singular extensions, get the last piece of data stored under this extension.
+        if (unknownFields.isEmpty()) {
+            return null;
+        }
+        UnknownFieldData lastData = unknownFields.get(unknownFields.size() - 1);
+        return clazz.cast(readData(CodedInputByteBufferNano.newInstance(lastData.bytes)));
+    }
+
+    protected Object readData(CodedInputByteBufferNano input) {
+        // This implementation is for message/group extensions.
+        Class<?> messageType = repeated ? clazz.getComponentType() : clazz;
+        try {
+            switch (type) {
+                case TYPE_GROUP:
+                    MessageNano group = (MessageNano) messageType.newInstance();
+                    input.readGroup(group, WireFormatNano.getTagFieldNumber(tag));
+                    return group;
+                case TYPE_MESSAGE:
+                    MessageNano message = (MessageNano) messageType.newInstance();
+                    input.readMessage(message);
+                    return message;
+                default:
+                    throw new IllegalArgumentException("Unknown type " + type);
+            }
+        } catch (InstantiationException e) {
+            throw new IllegalArgumentException(
+                    "Error creating instance of class " + messageType, e);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(
+                    "Error creating instance of class " + messageType, e);
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Error reading extension field", e);
+        }
+    }
+
+    protected void readDataInto(UnknownFieldData data, List<Object> resultList) {
+        // This implementation is for message/group extensions.
+        resultList.add(readData(CodedInputByteBufferNano.newInstance(data.bytes)));
+    }
+
+    void writeTo(Object value, CodedOutputByteBufferNano output) throws IOException {
+        if (repeated) {
+            writeRepeatedData(value, output);
+        } else {
+            writeSingularData(value, output);
+        }
+    }
+
+    protected void writeSingularData(Object value, CodedOutputByteBufferNano out) {
+        // This implementation is for message/group extensions.
+        try {
+            out.writeRawVarint32(tag);
+            switch (type) {
+                case TYPE_GROUP:
+                    MessageNano groupValue = (MessageNano) value;
+                    int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
+                    out.writeGroupNoTag(groupValue);
+                    // The endgroup tag must be included in the data payload.
+                    out.writeTag(fieldNumber, WireFormatNano.WIRETYPE_END_GROUP);
+                    break;
+                case TYPE_MESSAGE:
+                    MessageNano messageValue = (MessageNano) value;
+                    out.writeMessageNoTag(messageValue);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown type " + type);
+            }
+        } catch (IOException e) {
+            // Should not happen
+            throw new IllegalStateException(e);
+        }
+    }
+
+    protected void writeRepeatedData(Object array, CodedOutputByteBufferNano output) {
+        // This implementation is for non-packed extensions.
+        int arrayLength = Array.getLength(array);
+        for (int i = 0; i < arrayLength; i++) {
+            Object element = Array.get(array, i);
+            if (element != null) {
+                writeSingularData(element, output);
+            }
+        }
+    }
+
+    int computeSerializedSize(Object value) {
+        if (repeated) {
+            return computeRepeatedSerializedSize(value);
+        } else {
+            return computeSingularSerializedSize(value);
+        }
+    }
+
+    protected int computeRepeatedSerializedSize(Object array) {
+        // This implementation is for non-packed extensions.
+        int size = 0;
+        int arrayLength = Array.getLength(array);
+        for (int i = 0; i < arrayLength; i++) {
+            Object element = Array.get(array, i);
+            if (element != null) {
+                size += computeSingularSerializedSize(Array.get(array, i));
+            }
+        }
+        return size;
+    }
+
+    protected int computeSingularSerializedSize(Object value) {
+        // This implementation is for message/group extensions.
+        int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
+        switch (type) {
+            case TYPE_GROUP:
+                MessageNano groupValue = (MessageNano) value;
+                return CodedOutputByteBufferNano.computeGroupSize(fieldNumber, groupValue);
+            case TYPE_MESSAGE:
+                MessageNano messageValue = (MessageNano) value;
+                return CodedOutputByteBufferNano.computeMessageSize(fieldNumber, messageValue);
+            default:
+                throw new IllegalArgumentException("Unknown type " + type);
+        }
+    }
+
+    /**
+     * Represents an extension of a primitive (including enum) type. If there is no primitive
+     * extensions, this subclass will be removable by ProGuard.
+     */
+    private static class PrimitiveExtension<M extends ExtendableMessageNano<M>, T>
+            extends Extension<M, T> {
+
+        /**
+         * Tag of a piece of non-packed data from the wire compatible with this extension.
+         */
+        private final int nonPackedTag;
+
+        /**
+         * Tag of a piece of packed data from the wire compatible with this extension.
+         * 0 if the type of this extension is not packable.
+         */
+        private final int packedTag;
+
+        public PrimitiveExtension(int type, Class<T> clazz, int tag, boolean repeated,
+                int nonPackedTag, int packedTag) {
+            super(type, clazz, tag, repeated);
+            this.nonPackedTag = nonPackedTag;
+            this.packedTag = packedTag;
+        }
+
+        @Override
+        protected Object readData(CodedInputByteBufferNano input) {
+            try {
+                switch (type) {
+                    case TYPE_DOUBLE:
+                        return input.readDouble();
+                    case TYPE_FLOAT:
+                        return input.readFloat();
+                    case TYPE_INT64:
+                        return input.readInt64();
+                    case TYPE_UINT64:
+                        return input.readUInt64();
+                    case TYPE_INT32:
+                        return input.readInt32();
+                    case TYPE_FIXED64:
+                        return input.readFixed64();
+                    case TYPE_FIXED32:
+                        return input.readFixed32();
+                    case TYPE_BOOL:
+                        return input.readBool();
+                    case TYPE_STRING:
+                        return input.readString();
+                    case TYPE_BYTES:
+                        return input.readBytes();
+                    case TYPE_UINT32:
+                        return input.readUInt32();
+                    case TYPE_ENUM:
+                        return input.readEnum();
+                    case TYPE_SFIXED32:
+                        return input.readSFixed32();
+                    case TYPE_SFIXED64:
+                        return input.readSFixed64();
+                    case TYPE_SINT32:
+                        return input.readSInt32();
+                    case TYPE_SINT64:
+                        return input.readSInt64();
+                    default:
+                        throw new IllegalArgumentException("Unknown type " + type);
+                }
+            } catch (IOException e) {
+                throw new IllegalArgumentException("Error reading extension field", e);
+            }
+        }
+
+        @Override
+        protected void readDataInto(UnknownFieldData data, List<Object> resultList) {
+            // This implementation is for primitive typed extensions,
+            // which can read both packed and non-packed data.
+            if (data.tag == nonPackedTag) {
+                resultList.add(readData(CodedInputByteBufferNano.newInstance(data.bytes)));
+            } else {
+                CodedInputByteBufferNano buffer =
+                        CodedInputByteBufferNano.newInstance(data.bytes);
+                try {
+                    buffer.pushLimit(buffer.readRawVarint32()); // length limit
+                } catch (IOException e) {
+                    throw new IllegalArgumentException("Error reading extension field", e);
+                }
+                while (!buffer.isAtEnd()) {
+                    resultList.add(readData(buffer));
+                }
+            }
+        }
+
+        @Override
+        protected final void writeSingularData(Object value, CodedOutputByteBufferNano output) {
+            try {
+                output.writeRawVarint32(tag);
+                switch (type) {
+                    case TYPE_DOUBLE:
+                        Double doubleValue = (Double) value;
+                        output.writeDoubleNoTag(doubleValue);
+                        break;
+                    case TYPE_FLOAT:
+                        Float floatValue = (Float) value;
+                        output.writeFloatNoTag(floatValue);
+                        break;
+                    case TYPE_INT64:
+                        Long int64Value = (Long) value;
+                        output.writeInt64NoTag(int64Value);
+                        break;
+                    case TYPE_UINT64:
+                        Long uint64Value = (Long) value;
+                        output.writeUInt64NoTag(uint64Value);
+                        break;
+                    case TYPE_INT32:
+                        Integer int32Value = (Integer) value;
+                        output.writeInt32NoTag(int32Value);
+                        break;
+                    case TYPE_FIXED64:
+                        Long fixed64Value = (Long) value;
+                        output.writeFixed64NoTag(fixed64Value);
+                        break;
+                    case TYPE_FIXED32:
+                        Integer fixed32Value = (Integer) value;
+                        output.writeFixed32NoTag(fixed32Value);
+                        break;
+                    case TYPE_BOOL:
+                        Boolean boolValue = (Boolean) value;
+                        output.writeBoolNoTag(boolValue);
+                        break;
+                    case TYPE_STRING:
+                        String stringValue = (String) value;
+                        output.writeStringNoTag(stringValue);
+                        break;
+                    case TYPE_BYTES:
+                        byte[] bytesValue = (byte[]) value;
+                        output.writeBytesNoTag(bytesValue);
+                        break;
+                    case TYPE_UINT32:
+                        Integer uint32Value = (Integer) value;
+                        output.writeUInt32NoTag(uint32Value);
+                        break;
+                    case TYPE_ENUM:
+                        Integer enumValue = (Integer) value;
+                        output.writeEnumNoTag(enumValue);
+                        break;
+                    case TYPE_SFIXED32:
+                        Integer sfixed32Value = (Integer) value;
+                        output.writeSFixed32NoTag(sfixed32Value);
+                        break;
+                    case TYPE_SFIXED64:
+                        Long sfixed64Value = (Long) value;
+                        output.writeSFixed64NoTag(sfixed64Value);
+                        break;
+                    case TYPE_SINT32:
+                        Integer sint32Value = (Integer) value;
+                        output.writeSInt32NoTag(sint32Value);
+                        break;
+                    case TYPE_SINT64:
+                        Long sint64Value = (Long) value;
+                        output.writeSInt64NoTag(sint64Value);
+                        break;
+                    default:
+                        throw new IllegalArgumentException("Unknown type " + type);
+                }
+            } catch (IOException e) {
+                // Should not happen
+                throw new IllegalStateException(e);
+            }
+        }
+
+        @Override
+        protected void writeRepeatedData(Object array, CodedOutputByteBufferNano output) {
+            if (tag == nonPackedTag) {
+                // Use base implementation for non-packed data
+                super.writeRepeatedData(array, output);
+            } else if (tag == packedTag) {
+                // Packed. Note that the array element type is guaranteed to be primitive, so there
+                // won't be any null elements, so no null check in this block.
+                int arrayLength = Array.getLength(array);
+                int dataSize = computePackedDataSize(array);
+
+                try {
+                    output.writeRawVarint32(tag);
+                    output.writeRawVarint32(dataSize);
+                    switch (type) {
+                        case TYPE_BOOL:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeBoolNoTag(Array.getBoolean(array, i));
+                            }
+                            break;
+                        case TYPE_FIXED32:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeFixed32NoTag(Array.getInt(array, i));
+                            }
+                            break;
+                        case TYPE_SFIXED32:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeSFixed32NoTag(Array.getInt(array, i));
+                            }
+                            break;
+                        case TYPE_FLOAT:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeFloatNoTag(Array.getFloat(array, i));
+                            }
+                            break;
+                        case TYPE_FIXED64:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeFixed64NoTag(Array.getLong(array, i));
+                            }
+                            break;
+                        case TYPE_SFIXED64:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeSFixed64NoTag(Array.getLong(array, i));
+                            }
+                            break;
+                        case TYPE_DOUBLE:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeDoubleNoTag(Array.getDouble(array, i));
+                            }
+                            break;
+                        case TYPE_INT32:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeInt32NoTag(Array.getInt(array, i));
+                            }
+                            break;
+                        case TYPE_SINT32:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeSInt32NoTag(Array.getInt(array, i));
+                            }
+                            break;
+                        case TYPE_UINT32:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeUInt32NoTag(Array.getInt(array, i));
+                            }
+                            break;
+                        case TYPE_INT64:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeInt64NoTag(Array.getLong(array, i));
+                            }
+                            break;
+                        case TYPE_SINT64:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeSInt64NoTag(Array.getLong(array, i));
+                            }
+                            break;
+                        case TYPE_UINT64:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeUInt64NoTag(Array.getLong(array, i));
+                            }
+                            break;
+                        case TYPE_ENUM:
+                            for (int i = 0; i < arrayLength; i++) {
+                                output.writeEnumNoTag(Array.getInt(array, i));
+                            }
+                            break;
+                        default:
+                            throw new IllegalArgumentException("Unpackable type " + type);
+                    }
+                } catch (IOException e) {
+                    // Should not happen.
+                    throw new IllegalStateException(e);
+                }
+            } else {
+                throw new IllegalArgumentException("Unexpected repeated extension tag " + tag
+                        + ", unequal to both non-packed variant " + nonPackedTag
+                        + " and packed variant " + packedTag);
+            }
+        }
+
+        private int computePackedDataSize(Object array) {
+            int dataSize = 0;
+            int arrayLength = Array.getLength(array);
+            switch (type) {
+                case TYPE_BOOL:
+                    // Bools are stored as int32 but just as 0 or 1, so 1 byte each.
+                    dataSize = arrayLength;
+                    break;
+                case TYPE_FIXED32:
+                case TYPE_SFIXED32:
+                case TYPE_FLOAT:
+                    dataSize = arrayLength * CodedOutputByteBufferNano.LITTLE_ENDIAN_32_SIZE;
+                    break;
+                case TYPE_FIXED64:
+                case TYPE_SFIXED64:
+                case TYPE_DOUBLE:
+                    dataSize = arrayLength * CodedOutputByteBufferNano.LITTLE_ENDIAN_64_SIZE;
+                    break;
+                case TYPE_INT32:
+                    for (int i = 0; i < arrayLength; i++) {
+                        dataSize += CodedOutputByteBufferNano.computeInt32SizeNoTag(
+                                Array.getInt(array, i));
+                    }
+                    break;
+                case TYPE_SINT32:
+                    for (int i = 0; i < arrayLength; i++) {
+                        dataSize += CodedOutputByteBufferNano.computeSInt32SizeNoTag(
+                                Array.getInt(array, i));
+                    }
+                    break;
+                case TYPE_UINT32:
+                    for (int i = 0; i < arrayLength; i++) {
+                        dataSize += CodedOutputByteBufferNano.computeUInt32SizeNoTag(
+                                Array.getInt(array, i));
+                    }
+                    break;
+                case TYPE_INT64:
+                    for (int i = 0; i < arrayLength; i++) {
+                        dataSize += CodedOutputByteBufferNano.computeInt64SizeNoTag(
+                                Array.getLong(array, i));
+                    }
+                    break;
+                case TYPE_SINT64:
+                    for (int i = 0; i < arrayLength; i++) {
+                        dataSize += CodedOutputByteBufferNano.computeSInt64SizeNoTag(
+                                Array.getLong(array, i));
+                    }
+                    break;
+                case TYPE_UINT64:
+                    for (int i = 0; i < arrayLength; i++) {
+                        dataSize += CodedOutputByteBufferNano.computeUInt64SizeNoTag(
+                                Array.getLong(array, i));
+                    }
+                    break;
+                case TYPE_ENUM:
+                    for (int i = 0; i < arrayLength; i++) {
+                        dataSize += CodedOutputByteBufferNano.computeEnumSizeNoTag(
+                                Array.getInt(array, i));
+                    }
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unexpected non-packable type " + type);
+            }
+            return dataSize;
+        }
+
+        @Override
+        protected int computeRepeatedSerializedSize(Object array) {
+            if (tag == nonPackedTag) {
+                // Use base implementation for non-packed data
+                return super.computeRepeatedSerializedSize(array);
+            } else if (tag == packedTag) {
+                // Packed.
+                int dataSize = computePackedDataSize(array);
+                int payloadSize =
+                        dataSize + CodedOutputByteBufferNano.computeRawVarint32Size(dataSize);
+                return payloadSize + CodedOutputByteBufferNano.computeRawVarint32Size(tag);
+            } else {
+                throw new IllegalArgumentException("Unexpected repeated extension tag " + tag
+                        + ", unequal to both non-packed variant " + nonPackedTag
+                        + " and packed variant " + packedTag);
+            }
+        }
+
+        @Override
+        protected final int computeSingularSerializedSize(Object value) {
+            int fieldNumber = WireFormatNano.getTagFieldNumber(tag);
+            switch (type) {
+                case TYPE_DOUBLE:
+                    Double doubleValue = (Double) value;
+                    return CodedOutputByteBufferNano.computeDoubleSize(fieldNumber, doubleValue);
+                case TYPE_FLOAT:
+                    Float floatValue = (Float) value;
+                    return CodedOutputByteBufferNano.computeFloatSize(fieldNumber, floatValue);
+                case TYPE_INT64:
+                    Long int64Value = (Long) value;
+                    return CodedOutputByteBufferNano.computeInt64Size(fieldNumber, int64Value);
+                case TYPE_UINT64:
+                    Long uint64Value = (Long) value;
+                    return CodedOutputByteBufferNano.computeUInt64Size(fieldNumber, uint64Value);
+                case TYPE_INT32:
+                    Integer int32Value = (Integer) value;
+                    return CodedOutputByteBufferNano.computeInt32Size(fieldNumber, int32Value);
+                case TYPE_FIXED64:
+                    Long fixed64Value = (Long) value;
+                    return CodedOutputByteBufferNano.computeFixed64Size(fieldNumber, fixed64Value);
+                case TYPE_FIXED32:
+                    Integer fixed32Value = (Integer) value;
+                    return CodedOutputByteBufferNano.computeFixed32Size(fieldNumber, fixed32Value);
+                case TYPE_BOOL:
+                    Boolean boolValue = (Boolean) value;
+                    return CodedOutputByteBufferNano.computeBoolSize(fieldNumber, boolValue);
+                case TYPE_STRING:
+                    String stringValue = (String) value;
+                    return CodedOutputByteBufferNano.computeStringSize(fieldNumber, stringValue);
+                case TYPE_BYTES:
+                    byte[] bytesValue = (byte[]) value;
+                    return CodedOutputByteBufferNano.computeBytesSize(fieldNumber, bytesValue);
+                case TYPE_UINT32:
+                    Integer uint32Value = (Integer) value;
+                    return CodedOutputByteBufferNano.computeUInt32Size(fieldNumber, uint32Value);
+                case TYPE_ENUM:
+                    Integer enumValue = (Integer) value;
+                    return CodedOutputByteBufferNano.computeEnumSize(fieldNumber, enumValue);
+                case TYPE_SFIXED32:
+                    Integer sfixed32Value = (Integer) value;
+                    return CodedOutputByteBufferNano.computeSFixed32Size(fieldNumber,
+                            sfixed32Value);
+                case TYPE_SFIXED64:
+                    Long sfixed64Value = (Long) value;
+                    return CodedOutputByteBufferNano.computeSFixed64Size(fieldNumber,
+                            sfixed64Value);
+                case TYPE_SINT32:
+                    Integer sint32Value = (Integer) value;
+                    return CodedOutputByteBufferNano.computeSInt32Size(fieldNumber, sint32Value);
+                case TYPE_SINT64:
+                    Long sint64Value = (Long) value;
+                    return CodedOutputByteBufferNano.computeSInt64Size(fieldNumber, sint64Value);
+                default:
+                    throw new IllegalArgumentException("Unknown type " + type);
+            }
+        }
+    }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/FieldArray.java b/protobuf/java/src/main/java/com/google/protobuf/nano/FieldArray.java
new file mode 100644
index 0000000..5e8856d
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/FieldArray.java
@@ -0,0 +1,291 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2014 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+
+/**
+ * A custom version of {@link android.util.SparseArray} with the minimal API
+ * for storing {@link FieldData} objects.
+ *
+ * <p>This class is an internal implementation detail of nano and should not
+ * be called directly by clients.
+ *
+ * Based on {@link android.support.v4.util.SpareArrayCompat}.
+ */
+public final class FieldArray implements Cloneable {
+    private static final FieldData DELETED = new FieldData();
+    private boolean mGarbage = false;
+
+    private int[] mFieldNumbers;
+    private FieldData[] mData;
+    private int mSize;
+
+    /**
+     * Creates a new FieldArray containing no fields.
+     */
+    FieldArray() {
+        this(10);
+    }
+
+    /**
+     * Creates a new FieldArray containing no mappings that will not
+     * require any additional memory allocation to store the specified
+     * number of mappings.
+     */
+    FieldArray(int initialCapacity) {
+        initialCapacity = idealIntArraySize(initialCapacity);
+        mFieldNumbers = new int[initialCapacity];
+        mData = new FieldData[initialCapacity];
+        mSize = 0;
+    }
+
+    /**
+     * Gets the FieldData mapped from the specified fieldNumber, or <code>null</code>
+     * if no such mapping has been made.
+     */
+    FieldData get(int fieldNumber) {
+        int i = binarySearch(fieldNumber);
+
+        if (i < 0 || mData[i] == DELETED) {
+            return null;
+        } else {
+            return mData[i];
+        }
+    }
+
+    /**
+     * Removes the data from the specified fieldNumber, if there was any.
+     */
+    void remove(int fieldNumber) {
+        int i = binarySearch(fieldNumber);
+
+        if (i >= 0 && mData[i] != DELETED) {
+            mData[i] = DELETED;
+            mGarbage = true;
+        }
+    }
+
+    private void gc() {
+        int n = mSize;
+        int o = 0;
+        int[] keys = mFieldNumbers;
+        FieldData[] values = mData;
+
+        for (int i = 0; i < n; i++) {
+            FieldData val = values[i];
+
+            if (val != DELETED) {
+                if (i != o) {
+                    keys[o] = keys[i];
+                    values[o] = val;
+                    values[i] = null;
+                }
+
+                o++;
+            }
+        }
+
+        mGarbage = false;
+        mSize = o;
+    }
+
+    /**
+     * Adds a mapping from the specified fieldNumber to the specified data,
+     * replacing the previous mapping if there was one.
+     */
+    void put(int fieldNumber, FieldData data) {
+        int i = binarySearch(fieldNumber);
+
+        if (i >= 0) {
+            mData[i] = data;
+        } else {
+            i = ~i;
+
+            if (i < mSize && mData[i] == DELETED) {
+                mFieldNumbers[i] = fieldNumber;
+                mData[i] = data;
+                return;
+            }
+
+            if (mGarbage && mSize >= mFieldNumbers.length) {
+                gc();
+
+                // Search again because indices may have changed.
+                i = ~ binarySearch(fieldNumber);
+            }
+
+            if (mSize >= mFieldNumbers.length) {
+                int n = idealIntArraySize(mSize + 1);
+
+                int[] nkeys = new int[n];
+                FieldData[] nvalues = new FieldData[n];
+
+                System.arraycopy(mFieldNumbers, 0, nkeys, 0, mFieldNumbers.length);
+                System.arraycopy(mData, 0, nvalues, 0, mData.length);
+
+                mFieldNumbers = nkeys;
+                mData = nvalues;
+            }
+
+            if (mSize - i != 0) {
+                System.arraycopy(mFieldNumbers, i, mFieldNumbers, i + 1, mSize - i);
+                System.arraycopy(mData, i, mData, i + 1, mSize - i);
+            }
+
+            mFieldNumbers[i] = fieldNumber;
+            mData[i] = data;
+            mSize++;
+        }
+    }
+
+    /**
+     * Returns the number of key-value mappings that this FieldArray
+     * currently stores.
+     */
+    int size() {
+        if (mGarbage) {
+            gc();
+        }
+
+        return mSize;
+    }
+
+    public boolean isEmpty() {
+        return size() == 0;
+    }
+
+    /**
+     * Given an index in the range <code>0...size()-1</code>, returns
+     * the value from the <code>index</code>th key-value mapping that this
+     * FieldArray stores.
+     */
+    FieldData dataAt(int index) {
+        if (mGarbage) {
+            gc();
+        }
+
+        return mData[index];
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (!(o instanceof FieldArray)) {
+            return false;
+        }
+
+        FieldArray other = (FieldArray) o;
+        if (size() != other.size()) {  // size() will call gc() if necessary.
+            return false;
+        }
+        return arrayEquals(mFieldNumbers, other.mFieldNumbers, mSize) &&
+                arrayEquals(mData, other.mData, mSize);
+    }
+
+    @Override
+    public int hashCode() {
+        if (mGarbage) {
+            gc();
+        }
+        int result = 17;
+        for (int i = 0; i < mSize; i++) {
+            result = 31 * result + mFieldNumbers[i];
+            result = 31 * result + mData[i].hashCode();
+        }
+        return result;
+    }
+
+    private int idealIntArraySize(int need) {
+        return idealByteArraySize(need * 4) / 4;
+    }
+
+    private int idealByteArraySize(int need) {
+        for (int i = 4; i < 32; i++)
+            if (need <= (1 << i) - 12)
+                return (1 << i) - 12;
+
+        return need;
+    }
+
+    private int binarySearch(int value) {
+        int lo = 0;
+        int hi = mSize - 1;
+
+        while (lo <= hi) {
+            int mid = (lo + hi) >>> 1;
+            int midVal = mFieldNumbers[mid];
+
+            if (midVal < value) {
+                lo = mid + 1;
+            } else if (midVal > value) {
+                hi = mid - 1;
+            } else {
+                return mid; // value found
+            }
+        }
+        return ~lo; // value not present
+    }
+
+    private boolean arrayEquals(int[] a, int[] b, int size) {
+        for (int i = 0; i < size; i++) {
+            if (a[i] != b[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean arrayEquals(FieldData[] a, FieldData[] b, int size) {
+        for (int i = 0; i < size; i++) {
+            if (!a[i].equals(b[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public final FieldArray clone() {
+        // Trigger GC so we compact and don't copy DELETED elements.
+        int size = size();
+        FieldArray clone = new FieldArray(size);
+        System.arraycopy(mFieldNumbers, 0, clone.mFieldNumbers, 0, size);
+        for (int i = 0; i < size; i++) {
+            if (mData[i] != null) {
+                clone.mData[i] = mData[i].clone();
+            }
+        }
+        clone.mSize = size;
+        return clone;
+    }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/FieldData.java b/protobuf/java/src/main/java/com/google/protobuf/nano/FieldData.java
new file mode 100644
index 0000000..20a5142
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/FieldData.java
@@ -0,0 +1,240 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2014 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Stores unknown fields. These might be extensions or fields that the generated API doesn't
+ * know about yet.
+ */
+class FieldData implements Cloneable {
+    private Extension<?, ?> cachedExtension;
+    private Object value;
+    /** The serialised values for this object. Will be cleared if getValue is called */
+    private List<UnknownFieldData> unknownFieldData;
+
+    <T> FieldData(Extension<?, T> extension, T newValue) {
+        cachedExtension = extension;
+        value = newValue;
+    }
+
+    FieldData() {
+        unknownFieldData = new ArrayList<UnknownFieldData>();
+    }
+
+    void addUnknownField(UnknownFieldData unknownField) {
+        unknownFieldData.add(unknownField);
+    }
+
+    UnknownFieldData getUnknownField(int index) {
+        if (unknownFieldData == null) {
+            return null;
+        }
+        if (index < unknownFieldData.size()) {
+            return unknownFieldData.get(index);
+        }
+        return null;
+    }
+
+    int getUnknownFieldSize() {
+        if (unknownFieldData == null) {
+            return 0;
+        }
+        return unknownFieldData.size();
+    }
+
+    <T> T getValue(Extension<?, T> extension) {
+        if (value != null){
+            if (cachedExtension != extension) {  // Extension objects are singletons.
+                throw new IllegalStateException(
+                        "Tried to getExtension with a differernt Extension.");
+            }
+        } else {
+            cachedExtension = extension;
+            value = extension.getValueFrom(unknownFieldData);
+            unknownFieldData = null;
+        }
+        return (T) value;
+    }
+
+    <T> void setValue(Extension<?, T> extension, T newValue) {
+        cachedExtension = extension;
+        value = newValue;
+        unknownFieldData = null;
+    }
+
+    int computeSerializedSize() {
+        int size = 0;
+        if (value != null) {
+            size = cachedExtension.computeSerializedSize(value);
+        } else {
+            for (UnknownFieldData unknownField : unknownFieldData) {
+                size += unknownField.computeSerializedSize();
+            }
+        }
+        return size;
+    }
+
+    void writeTo(CodedOutputByteBufferNano output) throws IOException {
+        if (value != null) {
+            cachedExtension.writeTo(value, output);
+        } else {
+            for (UnknownFieldData unknownField : unknownFieldData) {
+                unknownField.writeTo(output);
+            }
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (!(o instanceof FieldData)) {
+            return false;
+        }
+
+        FieldData other = (FieldData) o;
+        if (value != null && other.value != null) {
+            // If both objects have deserialized values, compare those.
+            // Since unknown fields are only compared if messages have generated equals methods
+            // we know this will be a meaningful comparison (not identity) for all values.
+            if (cachedExtension != other.cachedExtension) {  // Extension objects are singletons.
+                return false;
+            }
+            if (!cachedExtension.clazz.isArray()) {
+                // Can't test (!cachedExtension.repeated) due to 'bytes' -> 'byte[]'
+                return value.equals(other.value);
+            }
+            if (value instanceof byte[]) {
+                return Arrays.equals((byte[]) value, (byte[]) other.value);
+            } else if (value instanceof int[]) {
+                return Arrays.equals((int[]) value, (int[]) other.value);
+            } else if (value instanceof long[]) {
+                return Arrays.equals((long[]) value, (long[]) other.value);
+            } else if (value instanceof float[]) {
+                return Arrays.equals((float[]) value, (float[]) other.value);
+            } else if (value instanceof double[]) {
+                return Arrays.equals((double[]) value, (double[]) other.value);
+            } else if (value instanceof boolean[]) {
+                return Arrays.equals((boolean[]) value, (boolean[]) other.value);
+            } else {
+                return Arrays.deepEquals((Object[]) value, (Object[]) other.value);
+            }
+        }
+        if (unknownFieldData != null && other.unknownFieldData != null) {
+            // If both objects have byte arrays compare those directly.
+            return unknownFieldData.equals(other.unknownFieldData);
+        }
+        try {
+            // As a last resort, serialize and compare the resulting byte arrays.
+            return Arrays.equals(toByteArray(), other.toByteArray());
+        } catch (IOException e) {
+            // Should not happen.
+            throw new IllegalStateException(e);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 17;
+        try {
+            // The only way to generate a consistent hash is to use the serialized form.
+            result = 31 * result + Arrays.hashCode(toByteArray());
+        } catch (IOException e) {
+            // Should not happen.
+            throw new IllegalStateException(e);
+        }
+        return result;
+    }
+
+    private byte[] toByteArray() throws IOException {
+        byte[] result = new byte[computeSerializedSize()];
+        CodedOutputByteBufferNano output = CodedOutputByteBufferNano.newInstance(result);
+        writeTo(output);
+        return result;
+    }
+
+    @Override
+    public final FieldData clone() {
+        FieldData clone = new FieldData();
+        try {
+            clone.cachedExtension = cachedExtension;
+            if (unknownFieldData == null) {
+                clone.unknownFieldData = null;
+            } else {
+                clone.unknownFieldData.addAll(unknownFieldData);
+            }
+
+            // Whether we need to deep clone value depends on its type. Primitive reference types
+            // (e.g. Integer, Long etc.) are ok, since they're immutable. We need to clone arrays
+            // and messages.
+            if (value == null) {
+                // No cloning required.
+            } else if (value instanceof MessageNano) {
+                clone.value = ((MessageNano) value).clone();
+            } else if (value instanceof byte[]) {
+                clone.value = ((byte[]) value).clone();
+            } else if (value instanceof byte[][]) {
+                byte[][] valueArray = (byte[][]) value;
+                byte[][] cloneArray = new byte[valueArray.length][];
+                clone.value = cloneArray;
+                for (int i = 0; i < valueArray.length; i++) {
+                    cloneArray[i] = valueArray[i].clone();
+                }
+            } else if (value instanceof boolean[]) {
+                clone.value = ((boolean[]) value).clone();
+            } else if (value instanceof int[]) {
+                clone.value = ((int[]) value).clone();
+            } else if (value instanceof long[]) {
+                clone.value = ((long[]) value).clone();
+            } else if (value instanceof float[]) {
+                clone.value = ((float[]) value).clone();
+            } else if (value instanceof double[]) {
+                clone.value = ((double[]) value).clone();
+            } else if (value instanceof MessageNano[]) {
+                MessageNano[] valueArray = (MessageNano[]) value;
+                MessageNano[] cloneArray = new MessageNano[valueArray.length];
+                clone.value = cloneArray;
+                for (int i = 0; i < valueArray.length; i++) {
+                    cloneArray[i] = valueArray[i].clone();
+                }
+            }
+            return clone;
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError(e);
+        }
+    }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/InternalNano.java b/protobuf/java/src/main/java/com/google/protobuf/nano/InternalNano.java
new file mode 100644
index 0000000..c4adfa5
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/InternalNano.java
@@ -0,0 +1,341 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+
+/**
+ * The classes contained within are used internally by the Protocol Buffer
+ * library and generated message implementations. They are public only because
+ * those generated messages do not reside in the {@code protobuf} package.
+ * Others should not use this class directly.
+ *
+ * @author kenton@google.com (Kenton Varda)
+ */
+public final class InternalNano {
+
+  private InternalNano() {}
+
+  /**
+   * An object to provide synchronization when lazily initializing static fields
+   * of {@link MessageNano} subclasses.
+   * <p>
+   * To enable earlier versions of ProGuard to inline short methods from a
+   * generated MessageNano subclass to the call sites, that class must not have
+   * a class initializer, which will be created if there is any static variable
+   * initializers. To lazily initialize the static variables in a thread-safe
+   * manner, the initialization code will synchronize on this object.
+   */
+  public static final Object LAZY_INIT_LOCK = new Object();
+
+  /**
+   * Helper called by generated code to construct default values for string
+   * fields.
+   * <p>
+   * The protocol compiler does not actually contain a UTF-8 decoder -- it
+   * just pushes UTF-8-encoded text around without touching it.  The one place
+   * where this presents a problem is when generating Java string literals.
+   * Unicode characters in the string literal would normally need to be encoded
+   * using a Unicode escape sequence, which would require decoding them.
+   * To get around this, protoc instead embeds the UTF-8 bytes into the
+   * generated code and leaves it to the runtime library to decode them.
+   * <p>
+   * It gets worse, though.  If protoc just generated a byte array, like:
+   *   new byte[] {0x12, 0x34, 0x56, 0x78}
+   * Java actually generates *code* which allocates an array and then fills
+   * in each value.  This is much less efficient than just embedding the bytes
+   * directly into the bytecode.  To get around this, we need another
+   * work-around.  String literals are embedded directly, so protoc actually
+   * generates a string literal corresponding to the bytes.  The easiest way
+   * to do this is to use the ISO-8859-1 character set, which corresponds to
+   * the first 256 characters of the Unicode range.  Protoc can then use
+   * good old CEscape to generate the string.
+   * <p>
+   * So we have a string literal which represents a set of bytes which
+   * represents another string.  This function -- stringDefaultValue --
+   * converts from the generated string to the string we actually want.  The
+   * generated code calls this automatically.
+   */
+  public static String stringDefaultValue(String bytes) {
+    try {
+      return new String(bytes.getBytes("ISO-8859-1"), "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      // This should never happen since all JVMs are required to implement
+      // both of the above character sets.
+      throw new IllegalStateException(
+          "Java VM does not support a standard character set.", e);
+    }
+  }
+
+  /**
+   * Helper called by generated code to construct default values for bytes
+   * fields.
+   * <p>
+   * This is a lot like {@link #stringDefaultValue}, but for bytes fields.
+   * In this case we only need the second of the two hacks -- allowing us to
+   * embed raw bytes as a string literal with ISO-8859-1 encoding.
+   */
+  public static byte[] bytesDefaultValue(String bytes) {
+    try {
+      return bytes.getBytes("ISO-8859-1");
+    } catch (UnsupportedEncodingException e) {
+      // This should never happen since all JVMs are required to implement
+      // ISO-8859-1.
+      throw new IllegalStateException(
+          "Java VM does not support a standard character set.", e);
+    }
+  }
+
+  /**
+   * Helper function to convert a string into UTF-8 while turning the
+   * UnsupportedEncodingException to a RuntimeException.
+   */
+  public static byte[] copyFromUtf8(final String text) {
+    try {
+      return text.getBytes("UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 not supported?");
+    }
+  }
+
+  /**
+   * Checks repeated int field equality; null-value and 0-length fields are
+   * considered equal.
+   */
+  public static boolean equals(int[] field1, int[] field2) {
+    if (field1 == null || field1.length == 0) {
+      return field2 == null || field2.length == 0;
+    } else {
+      return Arrays.equals(field1, field2);
+    }
+  }
+
+  /**
+   * Checks repeated long field equality; null-value and 0-length fields are
+   * considered equal.
+   */
+  public static boolean equals(long[] field1, long[] field2) {
+    if (field1 == null || field1.length == 0) {
+      return field2 == null || field2.length == 0;
+    } else {
+      return Arrays.equals(field1, field2);
+    }
+  }
+
+  /**
+   * Checks repeated float field equality; null-value and 0-length fields are
+   * considered equal.
+   */
+  public static boolean equals(float[] field1, float[] field2) {
+    if (field1 == null || field1.length == 0) {
+      return field2 == null || field2.length == 0;
+    } else {
+      return Arrays.equals(field1, field2);
+    }
+  }
+
+  /**
+   * Checks repeated double field equality; null-value and 0-length fields are
+   * considered equal.
+   */
+  public static boolean equals(double[] field1, double[] field2) {
+    if (field1 == null || field1.length == 0) {
+      return field2 == null || field2.length == 0;
+    } else {
+      return Arrays.equals(field1, field2);
+    }
+  }
+
+  /**
+   * Checks repeated boolean field equality; null-value and 0-length fields are
+   * considered equal.
+   */
+  public static boolean equals(boolean[] field1, boolean[] field2) {
+    if (field1 == null || field1.length == 0) {
+      return field2 == null || field2.length == 0;
+    } else {
+      return Arrays.equals(field1, field2);
+    }
+  }
+
+  /**
+   * Checks repeated bytes field equality. Only non-null elements are tested.
+   * Returns true if the two fields have the same sequence of non-null
+   * elements. Null-value fields and fields of any length with only null
+   * elements are considered equal.
+   */
+  public static boolean equals(byte[][] field1, byte[][] field2) {
+    int index1 = 0;
+    int length1 = field1 == null ? 0 : field1.length;
+    int index2 = 0;
+    int length2 = field2 == null ? 0 : field2.length;
+    while (true) {
+      while (index1 < length1 && field1[index1] == null) {
+        index1++;
+      }
+      while (index2 < length2 && field2[index2] == null) {
+        index2++;
+      }
+      boolean atEndOf1 = index1 >= length1;
+      boolean atEndOf2 = index2 >= length2;
+      if (atEndOf1 && atEndOf2) {
+        // no more non-null elements to test in both arrays
+        return true;
+      } else if (atEndOf1 != atEndOf2) {
+        // one of the arrays have extra non-null elements
+        return false;
+      } else if (!Arrays.equals(field1[index1], field2[index2])) {
+        // element mismatch
+        return false;
+      }
+      index1++;
+      index2++;
+    }
+  }
+
+  /**
+   * Checks repeated string/message field equality. Only non-null elements are
+   * tested. Returns true if the two fields have the same sequence of non-null
+   * elements. Null-value fields and fields of any length with only null
+   * elements are considered equal.
+   */
+  public static boolean equals(Object[] field1, Object[] field2) {
+    int index1 = 0;
+    int length1 = field1 == null ? 0 : field1.length;
+    int index2 = 0;
+    int length2 = field2 == null ? 0 : field2.length;
+    while (true) {
+      while (index1 < length1 && field1[index1] == null) {
+        index1++;
+      }
+      while (index2 < length2 && field2[index2] == null) {
+        index2++;
+      }
+      boolean atEndOf1 = index1 >= length1;
+      boolean atEndOf2 = index2 >= length2;
+      if (atEndOf1 && atEndOf2) {
+        // no more non-null elements to test in both arrays
+        return true;
+      } else if (atEndOf1 != atEndOf2) {
+        // one of the arrays have extra non-null elements
+        return false;
+      } else if (!field1[index1].equals(field2[index2])) {
+        // element mismatch
+        return false;
+      }
+      index1++;
+      index2++;
+    }
+  }
+
+  /**
+   * Computes the hash code of a repeated int field. Null-value and 0-length
+   * fields have the same hash code.
+   */
+  public static int hashCode(int[] field) {
+    return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
+  }
+
+  /**
+   * Computes the hash code of a repeated long field. Null-value and 0-length
+   * fields have the same hash code.
+   */
+  public static int hashCode(long[] field) {
+    return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
+  }
+
+  /**
+   * Computes the hash code of a repeated float field. Null-value and 0-length
+   * fields have the same hash code.
+   */
+  public static int hashCode(float[] field) {
+    return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
+  }
+
+  /**
+   * Computes the hash code of a repeated double field. Null-value and 0-length
+   * fields have the same hash code.
+   */
+  public static int hashCode(double[] field) {
+    return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
+  }
+
+  /**
+   * Computes the hash code of a repeated boolean field. Null-value and 0-length
+   * fields have the same hash code.
+   */
+  public static int hashCode(boolean[] field) {
+    return field == null || field.length == 0 ? 0 : Arrays.hashCode(field);
+  }
+
+  /**
+   * Computes the hash code of a repeated bytes field. Only the sequence of all
+   * non-null elements are used in the computation. Null-value fields and fields
+   * of any length with only null elements have the same hash code.
+   */
+  public static int hashCode(byte[][] field) {
+    int result = 0;
+    for (int i = 0, size = field == null ? 0 : field.length; i < size; i++) {
+      byte[] element = field[i];
+      if (element != null) {
+        result = 31 * result + Arrays.hashCode(element);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Computes the hash code of a repeated string/message field. Only the
+   * sequence of all non-null elements are used in the computation. Null-value
+   * fields and fields of any length with only null elements have the same hash
+   * code.
+   */
+  public static int hashCode(Object[] field) {
+    int result = 0;
+    for (int i = 0, size = field == null ? 0 : field.length; i < size; i++) {
+      Object element = field[i];
+      if (element != null) {
+        result = 31 * result + element.hashCode();
+      }
+    }
+    return result;
+  }
+
+  // This avoids having to make FieldArray public.
+  public static void cloneUnknownFieldData(ExtendableMessageNano original,
+      ExtendableMessageNano cloned) {
+    if (original.unknownFieldData != null) {
+      cloned.unknownFieldData = (FieldArray) original.unknownFieldData.clone();
+    }
+  }
+
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java b/protobuf/java/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java
new file mode 100644
index 0000000..ff0af9d
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/InvalidProtocolBufferNanoException.java
@@ -0,0 +1,93 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.io.IOException;
+
+/**
+ * Thrown when a protocol message being parsed is invalid in some way,
+ * e.g. it contains a malformed varint or a negative byte length.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class InvalidProtocolBufferNanoException extends IOException {
+  private static final long serialVersionUID = -1616151763072450476L;
+
+  public InvalidProtocolBufferNanoException(final String description) {
+    super(description);
+  }
+
+  static InvalidProtocolBufferNanoException truncatedMessage() {
+    return new InvalidProtocolBufferNanoException(
+      "While parsing a protocol message, the input ended unexpectedly " +
+      "in the middle of a field.  This could mean either than the " +
+      "input has been truncated or that an embedded message " +
+      "misreported its own length.");
+  }
+
+  static InvalidProtocolBufferNanoException negativeSize() {
+    return new InvalidProtocolBufferNanoException(
+      "CodedInputStream encountered an embedded string or message " +
+      "which claimed to have negative size.");
+  }
+
+  static InvalidProtocolBufferNanoException malformedVarint() {
+    return new InvalidProtocolBufferNanoException(
+      "CodedInputStream encountered a malformed varint.");
+  }
+
+  static InvalidProtocolBufferNanoException invalidTag() {
+    return new InvalidProtocolBufferNanoException(
+      "Protocol message contained an invalid tag (zero).");
+  }
+
+  static InvalidProtocolBufferNanoException invalidEndTag() {
+    return new InvalidProtocolBufferNanoException(
+      "Protocol message end-group tag did not match expected tag.");
+  }
+
+  static InvalidProtocolBufferNanoException invalidWireType() {
+    return new InvalidProtocolBufferNanoException(
+      "Protocol message tag had invalid wire type.");
+  }
+
+  static InvalidProtocolBufferNanoException recursionLimitExceeded() {
+    return new InvalidProtocolBufferNanoException(
+      "Protocol message had too many levels of nesting.  May be malicious.  " +
+      "Use CodedInputStream.setRecursionLimit() to increase the depth limit.");
+  }
+
+  static InvalidProtocolBufferNanoException sizeLimitExceeded() {
+    return new InvalidProtocolBufferNanoException(
+      "Protocol message was too large.  May be malicious.  " +
+      "Use CodedInputStream.setSizeLimit() to increase the size limit.");
+  }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/MessageNano.java b/protobuf/java/src/main/java/com/google/protobuf/nano/MessageNano.java
new file mode 100644
index 0000000..ea91b21
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/MessageNano.java
@@ -0,0 +1,198 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Abstract interface implemented by Protocol Message objects.
+ *
+ * @author wink@google.com Wink Saville
+ */
+public abstract class MessageNano {
+    protected volatile int cachedSize = -1;
+
+    /**
+     * Get the number of bytes required to encode this message.
+     * Returns the cached size or calls getSerializedSize which
+     * sets the cached size. This is used internally when serializing
+     * so the size is only computed once. If a member is modified
+     * then this could be stale call getSerializedSize if in doubt.
+     */
+    public int getCachedSize() {
+        if (cachedSize < 0) {
+            // getSerializedSize sets cachedSize
+            getSerializedSize();
+        }
+        return cachedSize;
+    }
+
+    /**
+     * Computes the number of bytes required to encode this message.
+     * The size is cached and the cached result can be retrieved
+     * using getCachedSize().
+     */
+    public int getSerializedSize() {
+        int size = computeSerializedSize();
+        cachedSize = size;
+        return size;
+    }
+
+    /**
+     * Computes the number of bytes required to encode this message. This does not update the
+     * cached size.
+     */
+    protected int computeSerializedSize() {
+      // This is overridden if the generated message has serialized fields.
+      return 0;
+    }
+
+    /**
+     * Serializes the message and writes it to {@code output}.
+     *
+     * @param output the output to receive the serialized form.
+     * @throws IOException if an error occurred writing to {@code output}.
+     */
+    public void writeTo(CodedOutputByteBufferNano output) throws IOException {
+        // Does nothing by default. Overridden by subclasses which have data to write.
+    }
+
+    /**
+     * Parse {@code input} as a message of this type and merge it with the
+     * message being built.
+     */
+    public abstract MessageNano mergeFrom(CodedInputByteBufferNano input) throws IOException;
+
+    /**
+     * Serialize to a byte array.
+     * @return byte array with the serialized data.
+     */
+    public static final byte[] toByteArray(MessageNano msg) {
+        final byte[] result = new byte[msg.getSerializedSize()];
+        toByteArray(msg, result, 0, result.length);
+        return result;
+    }
+
+    /**
+     * Serialize to a byte array starting at offset through length. The
+     * method getSerializedSize must have been called prior to calling
+     * this method so the proper length is know.  If an attempt to
+     * write more than length bytes OutOfSpaceException will be thrown
+     * and if length bytes are not written then IllegalStateException
+     * is thrown.
+     */
+    public static final void toByteArray(MessageNano msg, byte[] data, int offset, int length) {
+        try {
+            final CodedOutputByteBufferNano output =
+                CodedOutputByteBufferNano.newInstance(data, offset, length);
+            msg.writeTo(output);
+            output.checkNoSpaceLeft();
+        } catch (IOException e) {
+            throw new RuntimeException("Serializing to a byte array threw an IOException "
+                    + "(should never happen).", e);
+        }
+    }
+
+    /**
+     * Parse {@code data} as a message of this type and merge it with the
+     * message being built.
+     */
+    public static final <T extends MessageNano> T mergeFrom(T msg, final byte[] data)
+        throws InvalidProtocolBufferNanoException {
+        return mergeFrom(msg, data, 0, data.length);
+    }
+
+    /**
+     * Parse {@code data} as a message of this type and merge it with the
+     * message being built.
+     */
+    public static final <T extends MessageNano> T mergeFrom(T msg, final byte[] data,
+            final int off, final int len) throws InvalidProtocolBufferNanoException {
+        try {
+            final CodedInputByteBufferNano input =
+                CodedInputByteBufferNano.newInstance(data, off, len);
+            msg.mergeFrom(input);
+            input.checkLastTagWas(0);
+            return msg;
+        } catch (InvalidProtocolBufferNanoException e) {
+            throw e;
+        } catch (IOException e) {
+            throw new RuntimeException("Reading from a byte array threw an IOException (should "
+                    + "never happen).");
+        }
+    }
+
+    /**
+     * Compares two {@code MessageNano}s and returns true if the message's are the same class and
+     * have serialized form equality (i.e. all of the field values are the same).
+     */
+    public static final boolean messageNanoEquals(MessageNano a, MessageNano b) {
+        if (a == b) {
+            return true;
+        }
+        if (a == null || b == null) {
+            return false;
+        }
+        if (a.getClass() != b.getClass()) {
+          return false;
+        }
+        final int serializedSize = a.getSerializedSize();
+        if (b.getSerializedSize() != serializedSize) {
+            return false;
+        }
+        final byte[] aByteArray = new byte[serializedSize];
+        final byte[] bByteArray = new byte[serializedSize];
+        toByteArray(a, aByteArray, 0, serializedSize);
+        toByteArray(b, bByteArray, 0, serializedSize);
+        return Arrays.equals(aByteArray, bByteArray);
+    }
+
+    /**
+     * Returns a string that is (mostly) compatible with ProtoBuffer's TextFormat. Note that groups
+     * (which are deprecated) are not serialized with the correct field name.
+     *
+     * <p>This is implemented using reflection, so it is not especially fast nor is it guaranteed
+     * to find all fields if you have method removal turned on for proguard.
+     */
+    @Override
+    public String toString() {
+        return MessageNanoPrinter.print(this);
+    }
+
+    /**
+     * Provides support for cloning. This only works if you specify the generate_clone method.
+     */
+    @Override
+    public MessageNano clone() throws CloneNotSupportedException {
+        return (MessageNano) super.clone();
+    }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java b/protobuf/java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
new file mode 100644
index 0000000..a30f2f3
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/MessageNanoPrinter.java
@@ -0,0 +1,261 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * Static helper methods for printing nano protos.
+ *
+ * @author flynn@google.com Andrew Flynn
+ */
+public final class MessageNanoPrinter {
+    // Do not allow instantiation
+    private MessageNanoPrinter() {}
+
+    private static final String INDENT = "  ";
+    private static final int MAX_STRING_LEN = 200;
+
+    /**
+     * Returns an text representation of a MessageNano suitable for debugging. The returned string
+     * is mostly compatible with Protocol Buffer's TextFormat (as provided by non-nano protocol
+     * buffers) -- groups (which are deprecated) are output with an underscore name (e.g. foo_bar
+     * instead of FooBar) and will thus not parse.
+     *
+     * <p>Employs Java reflection on the given object and recursively prints primitive fields,
+     * groups, and messages.</p>
+     */
+    public static <T extends MessageNano> String print(T message) {
+        if (message == null) {
+            return "";
+        }
+
+        StringBuffer buf = new StringBuffer();
+        try {
+            print(null, message, new StringBuffer(), buf);
+        } catch (IllegalAccessException e) {
+            return "Error printing proto: " + e.getMessage();
+        } catch (InvocationTargetException e) {
+            return "Error printing proto: " + e.getMessage();
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Function that will print the given message/field into the StringBuffer.
+     * Meant to be called recursively.
+     *
+     * @param identifier the identifier to use, or {@code null} if this is the root message to
+     *        print.
+     * @param object the value to print. May in fact be a primitive value or byte array and not a
+     *        message.
+     * @param indentBuf the indentation each line should begin with.
+     * @param buf the output buffer.
+     */
+    private static void print(String identifier, Object object,
+            StringBuffer indentBuf, StringBuffer buf) throws IllegalAccessException,
+            InvocationTargetException {
+        if (object == null) {
+            // This can happen if...
+            //   - we're about to print a message, String, or byte[], but it not present;
+            //   - we're about to print a primitive, but "reftype" optional style is enabled, and
+            //     the field is unset.
+            // In both cases the appropriate behavior is to output nothing.
+        } else if (object instanceof MessageNano) {  // Nano proto message
+            int origIndentBufLength = indentBuf.length();
+            if (identifier != null) {
+                buf.append(indentBuf).append(deCamelCaseify(identifier)).append(" <\n");
+                indentBuf.append(INDENT);
+            }
+            Class<?> clazz = object.getClass();
+
+            // Proto fields follow one of two formats:
+            //
+            // 1) Public, non-static variables that do not begin or end with '_'
+            // Find and print these using declared public fields
+            for (Field field : clazz.getFields()) {
+                int modifiers = field.getModifiers();
+                String fieldName = field.getName();
+                if ("cachedSize".equals(fieldName)) {
+                    // TODO(bduff): perhaps cachedSize should have a more obscure name.
+                    continue;
+                }
+
+                if ((modifiers & Modifier.PUBLIC) == Modifier.PUBLIC
+                        && (modifiers & Modifier.STATIC) != Modifier.STATIC
+                        && !fieldName.startsWith("_")
+                        && !fieldName.endsWith("_")) {
+                    Class<?> fieldType = field.getType();
+                    Object value = field.get(object);
+
+                    if (fieldType.isArray()) {
+                        Class<?> arrayType = fieldType.getComponentType();
+
+                        // bytes is special since it's not repeated, but is represented by an array
+                        if (arrayType == byte.class) {
+                            print(fieldName, value, indentBuf, buf);
+                        } else {
+                            int len = value == null ? 0 : Array.getLength(value);
+                            for (int i = 0; i < len; i++) {
+                                Object elem = Array.get(value, i);
+                                print(fieldName, elem, indentBuf, buf);
+                            }
+                        }
+                    } else {
+                        print(fieldName, value, indentBuf, buf);
+                    }
+                }
+            }
+
+            // 2) Fields that are accessed via getter methods (when accessors
+            //    mode is turned on)
+            // Find and print these using getter methods.
+            for (Method method : clazz.getMethods()) {
+                String name = method.getName();
+                // Check for the setter accessor method since getters and hazzers both have
+                // non-proto-field name collisions (hashCode() and getSerializedSize())
+                if (name.startsWith("set")) {
+                    String subfieldName = name.substring(3);
+
+                    Method hazzer = null;
+                    try {
+                        hazzer = clazz.getMethod("has" + subfieldName);
+                    } catch (NoSuchMethodException e) {
+                        continue;
+                    }
+                    // If hazzer does't exist or returns false, no need to continue
+                    if (!(Boolean) hazzer.invoke(object)) {
+                        continue;
+                    }
+
+                    Method getter = null;
+                    try {
+                        getter = clazz.getMethod("get" + subfieldName);
+                    } catch (NoSuchMethodException e) {
+                        continue;
+                    }
+
+                    print(subfieldName, getter.invoke(object), indentBuf, buf);
+                }
+            }
+            if (identifier != null) {
+                indentBuf.setLength(origIndentBufLength);
+                buf.append(indentBuf).append(">\n");
+            }
+        } else {
+            // Non-null primitive value
+            identifier = deCamelCaseify(identifier);
+            buf.append(indentBuf).append(identifier).append(": ");
+            if (object instanceof String) {
+                String stringMessage = sanitizeString((String) object);
+                buf.append("\"").append(stringMessage).append("\"");
+            } else if (object instanceof byte[]) {
+                appendQuotedBytes((byte[]) object, buf);
+            } else {
+                buf.append(object);
+            }
+            buf.append("\n");
+        }
+    }
+
+    /**
+     * Converts an identifier of the format "FieldName" into "field_name".
+     */
+    private static String deCamelCaseify(String identifier) {
+        StringBuffer out = new StringBuffer();
+        for (int i = 0; i < identifier.length(); i++) {
+            char currentChar = identifier.charAt(i);
+            if (i == 0) {
+                out.append(Character.toLowerCase(currentChar));
+            } else if (Character.isUpperCase(currentChar)) {
+                out.append('_').append(Character.toLowerCase(currentChar));
+            } else {
+                out.append(currentChar);
+            }
+        }
+        return out.toString();
+    }
+
+    /**
+     * Shortens and escapes the given string.
+     */
+    private static String sanitizeString(String str) {
+        if (!str.startsWith("http") && str.length() > MAX_STRING_LEN) {
+            // Trim non-URL strings.
+            str = str.substring(0, MAX_STRING_LEN) + "[...]";
+        }
+        return escapeString(str);
+    }
+
+    /**
+     * Escape everything except for low ASCII code points.
+     */
+    private static String escapeString(String str) {
+        int strLen = str.length();
+        StringBuilder b = new StringBuilder(strLen);
+        for (int i = 0; i < strLen; i++) {
+            char original = str.charAt(i);
+            if (original >= ' ' && original <= '~' && original != '"' && original != '\'') {
+                b.append(original);
+            } else {
+                b.append(String.format("\\u%04x", (int) original));
+            }
+        }
+        return b.toString();
+    }
+
+    /**
+     * Appends a quoted byte array to the provided {@code StringBuffer}.
+     */
+    private static void appendQuotedBytes(byte[] bytes, StringBuffer builder) {
+        if (bytes == null) {
+            builder.append("\"\"");
+            return;
+        }
+
+        builder.append('"');
+        for (int i = 0; i < bytes.length; ++i) {
+            int ch = bytes[i] & 0xff;
+            if (ch == '\\' || ch == '"') {
+                builder.append('\\').append((char) ch);
+            } else if (ch >= 32 && ch < 127) {
+                builder.append((char) ch);
+            } else {
+                builder.append(String.format("\\%03o", ch));
+            }
+        }
+        builder.append('"');
+    }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/UnknownFieldData.java b/protobuf/java/src/main/java/com/google/protobuf/nano/UnknownFieldData.java
new file mode 100644
index 0000000..bf34bed
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/UnknownFieldData.java
@@ -0,0 +1,88 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Stores unknown fields. These might be extensions or fields that the generated
+ * API doesn't know about yet.
+ *
+ * @author bduff@google.com (Brian Duff)
+ */
+final class UnknownFieldData {
+
+    final int tag;
+    /**
+     * Important: this should be treated as immutable, even though it's possible
+     * to change the array values.
+     */
+    final byte[] bytes;
+
+    UnknownFieldData(int tag, byte[] bytes) {
+        this.tag = tag;
+        this.bytes = bytes;
+    }
+
+    int computeSerializedSize() {
+        int size = 0;
+        size += CodedOutputByteBufferNano.computeRawVarint32Size(tag);
+        size += bytes.length;
+        return size;
+    }
+
+    void writeTo(CodedOutputByteBufferNano output) throws IOException {
+        output.writeRawVarint32(tag);
+        output.writeRawBytes(bytes);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (!(o instanceof UnknownFieldData)) {
+            return false;
+        }
+
+        UnknownFieldData other = (UnknownFieldData) o;
+        return tag == other.tag && Arrays.equals(bytes, other.bytes);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = 17;
+        result = 31 * result + tag;
+        result = 31 * result + Arrays.hashCode(bytes);
+        return result;
+    }
+}
diff --git a/protobuf/java/src/main/java/com/google/protobuf/nano/WireFormatNano.java b/protobuf/java/src/main/java/com/google/protobuf/nano/WireFormatNano.java
new file mode 100644
index 0000000..a3405e5
--- /dev/null
+++ b/protobuf/java/src/main/java/com/google/protobuf/nano/WireFormatNano.java
@@ -0,0 +1,124 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf.nano;
+
+import java.io.IOException;
+
+/**
+ * This class is used internally by the Protocol Buffer library and generated
+ * message implementations.  It is public only because those generated messages
+ * do not reside in the {@code protobuf} package.  Others should not use this
+ * class directly.
+ *
+ * This class contains constants and helper functions useful for dealing with
+ * the Protocol Buffer wire format.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class WireFormatNano {
+  // Do not allow instantiation.
+  private WireFormatNano() {}
+
+  static final int WIRETYPE_VARINT           = 0;
+  static final int WIRETYPE_FIXED64          = 1;
+  static final int WIRETYPE_LENGTH_DELIMITED = 2;
+  static final int WIRETYPE_START_GROUP      = 3;
+  static final int WIRETYPE_END_GROUP        = 4;
+  static final int WIRETYPE_FIXED32          = 5;
+
+  static final int TAG_TYPE_BITS = 3;
+  static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;
+
+  /** Given a tag value, determines the wire type (the lower 3 bits). */
+  static int getTagWireType(final int tag) {
+    return tag & TAG_TYPE_MASK;
+  }
+
+  /** Given a tag value, determines the field number (the upper 29 bits). */
+  public static int getTagFieldNumber(final int tag) {
+    return tag >>> TAG_TYPE_BITS;
+  }
+
+  /** Makes a tag value given a field number and wire type. */
+  static int makeTag(final int fieldNumber, final int wireType) {
+    return (fieldNumber << TAG_TYPE_BITS) | wireType;
+  }
+
+  public static final int EMPTY_INT_ARRAY[] = {};
+  public static final long EMPTY_LONG_ARRAY[] = {};
+  public static final float EMPTY_FLOAT_ARRAY[] = {};
+  public static final double EMPTY_DOUBLE_ARRAY[] = {};
+  public static final boolean EMPTY_BOOLEAN_ARRAY[] = {};
+  public static final String EMPTY_STRING_ARRAY[] = {};
+  public static final byte[] EMPTY_BYTES_ARRAY[] = {};
+  public static final byte[] EMPTY_BYTES = {};
+
+  /**
+   * Parses an unknown field. This implementation skips the field.
+   *
+   * <p>Generated messages will call this for unknown fields if the store_unknown_fields
+   * option is off.
+   *
+   * @return {@literal true} unless the tag is an end-group tag.
+   */
+  public static boolean parseUnknownField(
+      final CodedInputByteBufferNano input,
+      final int tag) throws IOException {
+    return input.skipField(tag);
+  }
+
+  /**
+   * Computes the array length of a repeated field. We assume that in the common case repeated
+   * fields are contiguously serialized but we still correctly handle interspersed values of a
+   * repeated field (but with extra allocations).
+   *
+   * Rewinds to current input position before returning.
+   *
+   * @param input stream input, pointing to the byte after the first tag
+   * @param tag repeated field tag just read
+   * @return length of array
+   * @throws IOException
+   */
+  public static final int getRepeatedFieldArrayLength(
+      final CodedInputByteBufferNano input,
+      final int tag) throws IOException {
+    int arrayLength = 1;
+    int startPos = input.getPosition();
+    input.skipField(tag);
+    while (input.readTag() == tag) {
+      input.skipField(tag);
+      arrayLength++;
+    }
+    input.rewindToPosition(startPos);
+    return arrayLength;
+  }
+
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/AbstractMessageTest.java b/protobuf/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
new file mode 100644
index 0000000..d964ef5
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/AbstractMessageTest.java
@@ -0,0 +1,527 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestRequiredForeign;
+import protobuf_unittest.UnittestProto.TestUnpackedTypes;
+
+import junit.framework.TestCase;
+
+import java.util.Map;
+
+/**
+ * Unit test for {@link AbstractMessage}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class AbstractMessageTest extends TestCase {
+  /**
+   * Extends AbstractMessage and wraps some other message object.  The methods
+   * of the Message interface which aren't explicitly implemented by
+   * AbstractMessage are forwarded to the wrapped object.  This allows us to
+   * test that AbstractMessage's implementations work even if the wrapped
+   * object does not use them.
+   */
+  private static class AbstractMessageWrapper extends AbstractMessage {
+    private final Message wrappedMessage;
+
+    public AbstractMessageWrapper(Message wrappedMessage) {
+      this.wrappedMessage = wrappedMessage;
+    }
+
+    public Descriptors.Descriptor getDescriptorForType() {
+      return wrappedMessage.getDescriptorForType();
+    }
+    public AbstractMessageWrapper getDefaultInstanceForType() {
+      return new AbstractMessageWrapper(
+        wrappedMessage.getDefaultInstanceForType());
+    }
+    public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
+      return wrappedMessage.getAllFields();
+    }
+    public boolean hasField(Descriptors.FieldDescriptor field) {
+      return wrappedMessage.hasField(field);
+    }
+    public Object getField(Descriptors.FieldDescriptor field) {
+      return wrappedMessage.getField(field);
+    }
+    public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
+      return wrappedMessage.getRepeatedFieldCount(field);
+    }
+    public Object getRepeatedField(
+        Descriptors.FieldDescriptor field, int index) {
+      return wrappedMessage.getRepeatedField(field, index);
+    }
+    public UnknownFieldSet getUnknownFields() {
+      return wrappedMessage.getUnknownFields();
+    }
+    public Builder newBuilderForType() {
+      return new Builder(wrappedMessage.newBuilderForType());
+    }
+    public Builder toBuilder() {
+      return new Builder(wrappedMessage.toBuilder());
+    }
+
+    static class Builder extends AbstractMessage.Builder<Builder> {
+      private final Message.Builder wrappedBuilder;
+
+      public Builder(Message.Builder wrappedBuilder) {
+        this.wrappedBuilder = wrappedBuilder;
+      }
+
+      public AbstractMessageWrapper build() {
+        return new AbstractMessageWrapper(wrappedBuilder.build());
+      }
+      public AbstractMessageWrapper buildPartial() {
+        return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
+      }
+      public Builder clone() {
+        return new Builder(wrappedBuilder.clone());
+      }
+      public boolean isInitialized() {
+        return clone().buildPartial().isInitialized();
+      }
+      public Descriptors.Descriptor getDescriptorForType() {
+        return wrappedBuilder.getDescriptorForType();
+      }
+      public AbstractMessageWrapper getDefaultInstanceForType() {
+        return new AbstractMessageWrapper(
+          wrappedBuilder.getDefaultInstanceForType());
+      }
+      public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
+        return wrappedBuilder.getAllFields();
+      }
+      public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
+        return new Builder(wrappedBuilder.newBuilderForField(field));
+      }
+      public boolean hasField(Descriptors.FieldDescriptor field) {
+        return wrappedBuilder.hasField(field);
+      }
+      public Object getField(Descriptors.FieldDescriptor field) {
+        return wrappedBuilder.getField(field);
+      }
+      public Builder setField(Descriptors.FieldDescriptor field, Object value) {
+        wrappedBuilder.setField(field, value);
+        return this;
+      }
+      public Builder clearField(Descriptors.FieldDescriptor field) {
+        wrappedBuilder.clearField(field);
+        return this;
+      }
+      public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
+        return wrappedBuilder.getRepeatedFieldCount(field);
+      }
+      public Object getRepeatedField(
+          Descriptors.FieldDescriptor field, int index) {
+        return wrappedBuilder.getRepeatedField(field, index);
+      }
+      public Builder setRepeatedField(Descriptors.FieldDescriptor field,
+                                      int index, Object value) {
+        wrappedBuilder.setRepeatedField(field, index, value);
+        return this;
+      }
+      public Builder addRepeatedField(
+          Descriptors.FieldDescriptor field, Object value) {
+        wrappedBuilder.addRepeatedField(field, value);
+        return this;
+      }
+      public UnknownFieldSet getUnknownFields() {
+        return wrappedBuilder.getUnknownFields();
+      }
+      public Builder setUnknownFields(UnknownFieldSet unknownFields) {
+        wrappedBuilder.setUnknownFields(unknownFields);
+        return this;
+      }
+      @Override
+      public Message.Builder getFieldBuilder(FieldDescriptor field) {
+        return wrappedBuilder.getFieldBuilder(field);
+      }
+    }
+    public Parser<? extends Message> getParserForType() {
+      return wrappedMessage.getParserForType();
+    }
+  }
+
+  // =================================================================
+
+  TestUtil.ReflectionTester reflectionTester =
+    new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
+
+  TestUtil.ReflectionTester extensionsReflectionTester =
+    new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
+                                  TestUtil.getExtensionRegistry());
+
+  public void testClear() throws Exception {
+    AbstractMessageWrapper message =
+      new AbstractMessageWrapper.Builder(
+          TestAllTypes.newBuilder(TestUtil.getAllSet()))
+        .clear().build();
+    TestUtil.assertClear((TestAllTypes) message.wrappedMessage);
+  }
+
+  public void testCopy() throws Exception {
+    AbstractMessageWrapper message =
+      new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder())
+        .mergeFrom(TestUtil.getAllSet()).build();
+    TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
+  }
+
+  public void testSerializedSize() throws Exception {
+    TestAllTypes message = TestUtil.getAllSet();
+    Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());
+
+    assertEquals(message.getSerializedSize(),
+                 abstractMessage.getSerializedSize());
+  }
+
+  public void testSerialization() throws Exception {
+    Message abstractMessage = new AbstractMessageWrapper(TestUtil.getAllSet());
+
+    TestUtil.assertAllFieldsSet(
+      TestAllTypes.parseFrom(abstractMessage.toByteString()));
+
+    assertEquals(TestUtil.getAllSet().toByteString(),
+                 abstractMessage.toByteString());
+  }
+
+  public void testParsing() throws Exception {
+    AbstractMessageWrapper.Builder builder =
+      new AbstractMessageWrapper.Builder(TestAllTypes.newBuilder());
+    AbstractMessageWrapper message =
+      builder.mergeFrom(TestUtil.getAllSet().toByteString()).build();
+    TestUtil.assertAllFieldsSet((TestAllTypes) message.wrappedMessage);
+  }
+
+  public void testParsingUninitialized() throws Exception {
+    TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
+    builder.getOptionalMessageBuilder().setDummy2(10);
+    ByteString bytes = builder.buildPartial().toByteString();
+    Message.Builder abstractMessageBuilder =
+        new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder());
+    // mergeFrom() should not throw initialization error.
+    abstractMessageBuilder.mergeFrom(bytes).buildPartial();
+    try {
+      abstractMessageBuilder.mergeFrom(bytes).build();
+      fail();
+    } catch (UninitializedMessageException ex) {
+      // pass
+    }
+
+    // test DynamicMessage directly.
+    Message.Builder dynamicMessageBuilder = DynamicMessage.newBuilder(
+        TestRequiredForeign.getDescriptor());
+    // mergeFrom() should not throw initialization error.
+    dynamicMessageBuilder.mergeFrom(bytes).buildPartial();
+    try {
+      dynamicMessageBuilder.mergeFrom(bytes).build();
+      fail();
+    } catch (UninitializedMessageException ex) {
+      // pass
+    }
+  }
+
+  public void testPackedSerialization() throws Exception {
+    Message abstractMessage =
+        new AbstractMessageWrapper(TestUtil.getPackedSet());
+
+    TestUtil.assertPackedFieldsSet(
+      TestPackedTypes.parseFrom(abstractMessage.toByteString()));
+
+    assertEquals(TestUtil.getPackedSet().toByteString(),
+                 abstractMessage.toByteString());
+  }
+
+  public void testPackedParsing() throws Exception {
+    AbstractMessageWrapper.Builder builder =
+      new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
+    AbstractMessageWrapper message =
+      builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
+    TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
+  }
+
+  public void testUnpackedSerialization() throws Exception {
+    Message abstractMessage =
+      new AbstractMessageWrapper(TestUtil.getUnpackedSet());
+
+    TestUtil.assertUnpackedFieldsSet(
+      TestUnpackedTypes.parseFrom(abstractMessage.toByteString()));
+
+    assertEquals(TestUtil.getUnpackedSet().toByteString(),
+                 abstractMessage.toByteString());
+  }
+
+  public void testParsePackedToUnpacked() throws Exception {
+    AbstractMessageWrapper.Builder builder =
+      new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
+    AbstractMessageWrapper message =
+      builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
+    TestUtil.assertUnpackedFieldsSet(
+      (TestUnpackedTypes) message.wrappedMessage);
+  }
+
+  public void testParseUnpackedToPacked() throws Exception {
+    AbstractMessageWrapper.Builder builder =
+      new AbstractMessageWrapper.Builder(TestPackedTypes.newBuilder());
+    AbstractMessageWrapper message =
+      builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
+    TestUtil.assertPackedFieldsSet((TestPackedTypes) message.wrappedMessage);
+  }
+
+  public void testUnpackedParsing() throws Exception {
+    AbstractMessageWrapper.Builder builder =
+      new AbstractMessageWrapper.Builder(TestUnpackedTypes.newBuilder());
+    AbstractMessageWrapper message =
+      builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
+    TestUtil.assertUnpackedFieldsSet(
+      (TestUnpackedTypes) message.wrappedMessage);
+  }
+
+  public void testOptimizedForSize() throws Exception {
+    // We're mostly only checking that this class was compiled successfully.
+    TestOptimizedForSize message =
+      TestOptimizedForSize.newBuilder().setI(1).build();
+    message = TestOptimizedForSize.parseFrom(message.toByteString());
+    assertEquals(2, message.getSerializedSize());
+  }
+
+  // -----------------------------------------------------------------
+  // Tests for isInitialized().
+
+  private static final TestRequired TEST_REQUIRED_UNINITIALIZED =
+    TestRequired.getDefaultInstance();
+  private static final TestRequired TEST_REQUIRED_INITIALIZED =
+    TestRequired.newBuilder().setA(1).setB(2).setC(3).build();
+
+  public void testIsInitialized() throws Exception {
+    TestRequired.Builder builder = TestRequired.newBuilder();
+    AbstractMessageWrapper.Builder abstractBuilder =
+      new AbstractMessageWrapper.Builder(builder);
+
+    assertFalse(abstractBuilder.isInitialized());
+    assertEquals("a, b, c", abstractBuilder.getInitializationErrorString());
+    builder.setA(1);
+    assertFalse(abstractBuilder.isInitialized());
+    assertEquals("b, c", abstractBuilder.getInitializationErrorString());
+    builder.setB(1);
+    assertFalse(abstractBuilder.isInitialized());
+    assertEquals("c", abstractBuilder.getInitializationErrorString());
+    builder.setC(1);
+    assertTrue(abstractBuilder.isInitialized());
+    assertEquals("", abstractBuilder.getInitializationErrorString());
+  }
+
+  public void testForeignIsInitialized() throws Exception {
+    TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
+    AbstractMessageWrapper.Builder abstractBuilder =
+      new AbstractMessageWrapper.Builder(builder);
+
+    assertTrue(abstractBuilder.isInitialized());
+    assertEquals("", abstractBuilder.getInitializationErrorString());
+
+    builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
+    assertFalse(abstractBuilder.isInitialized());
+    assertEquals(
+        "optional_message.a, optional_message.b, optional_message.c",
+        abstractBuilder.getInitializationErrorString());
+
+    builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
+    assertTrue(abstractBuilder.isInitialized());
+    assertEquals("", abstractBuilder.getInitializationErrorString());
+
+    builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
+    assertFalse(abstractBuilder.isInitialized());
+    assertEquals(
+        "repeated_message[0].a, repeated_message[0].b, repeated_message[0].c",
+        abstractBuilder.getInitializationErrorString());
+
+    builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
+    assertTrue(abstractBuilder.isInitialized());
+    assertEquals("", abstractBuilder.getInitializationErrorString());
+  }
+
+  // -----------------------------------------------------------------
+  // Tests for mergeFrom
+
+  static final TestAllTypes MERGE_SOURCE =
+    TestAllTypes.newBuilder()
+      .setOptionalInt32(1)
+      .setOptionalString("foo")
+      .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
+      .addRepeatedString("bar")
+      .build();
+
+  static final TestAllTypes MERGE_DEST =
+    TestAllTypes.newBuilder()
+      .setOptionalInt64(2)
+      .setOptionalString("baz")
+      .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
+      .addRepeatedString("qux")
+      .build();
+
+  static final String MERGE_RESULT_TEXT =
+      "optional_int32: 1\n" +
+      "optional_int64: 2\n" +
+      "optional_string: \"foo\"\n" +
+      "optional_foreign_message {\n" +
+      "  c: 3\n" +
+      "}\n" +
+      "repeated_string: \"qux\"\n" +
+      "repeated_string: \"bar\"\n";
+
+  public void testMergeFrom() throws Exception {
+    AbstractMessageWrapper result =
+      new AbstractMessageWrapper.Builder(
+        TestAllTypes.newBuilder(MERGE_DEST))
+      .mergeFrom(MERGE_SOURCE).build();
+
+    assertEquals(MERGE_RESULT_TEXT, result.toString());
+  }
+
+  // -----------------------------------------------------------------
+  // Tests for equals and hashCode
+
+  public void testEqualsAndHashCode() throws Exception {
+    TestAllTypes a = TestUtil.getAllSet();
+    TestAllTypes b = TestAllTypes.newBuilder().build();
+    TestAllTypes c = TestAllTypes.newBuilder(b).addRepeatedString("x").build();
+    TestAllTypes d = TestAllTypes.newBuilder(c).addRepeatedString("y").build();
+    TestAllExtensions e = TestUtil.getAllExtensionsSet();
+    TestAllExtensions f = TestAllExtensions.newBuilder(e)
+        .addExtension(UnittestProto.repeatedInt32Extension, 999).build();
+
+    checkEqualsIsConsistent(a);
+    checkEqualsIsConsistent(b);
+    checkEqualsIsConsistent(c);
+    checkEqualsIsConsistent(d);
+    checkEqualsIsConsistent(e);
+    checkEqualsIsConsistent(f);
+
+    checkNotEqual(a, b);
+    checkNotEqual(a, c);
+    checkNotEqual(a, d);
+    checkNotEqual(a, e);
+    checkNotEqual(a, f);
+
+    checkNotEqual(b, c);
+    checkNotEqual(b, d);
+    checkNotEqual(b, e);
+    checkNotEqual(b, f);
+
+    checkNotEqual(c, d);
+    checkNotEqual(c, e);
+    checkNotEqual(c, f);
+
+    checkNotEqual(d, e);
+    checkNotEqual(d, f);
+
+    checkNotEqual(e, f);
+
+    // Deserializing into the TestEmptyMessage such that every field
+    // is an {@link UnknownFieldSet.Field}.
+    UnittestProto.TestEmptyMessage eUnknownFields =
+        UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
+    UnittestProto.TestEmptyMessage fUnknownFields =
+        UnittestProto.TestEmptyMessage.parseFrom(f.toByteArray());
+    checkNotEqual(eUnknownFields, fUnknownFields);
+    checkEqualsIsConsistent(eUnknownFields);
+    checkEqualsIsConsistent(fUnknownFields);
+
+    // Subsequent reconstitutions should be identical
+    UnittestProto.TestEmptyMessage eUnknownFields2 =
+        UnittestProto.TestEmptyMessage.parseFrom(e.toByteArray());
+    checkEqualsIsConsistent(eUnknownFields, eUnknownFields2);
+  }
+
+
+  /**
+   * Asserts that the given proto has symmetric equals and hashCode methods.
+   */
+  private void checkEqualsIsConsistent(Message message) {
+    // Object should be equal to itself.
+    assertEquals(message, message);
+
+    // Object should be equal to a dynamic copy of itself.
+    DynamicMessage dynamic = DynamicMessage.newBuilder(message).build();
+    checkEqualsIsConsistent(message, dynamic);
+  }
+
+  /**
+   * Asserts that the given protos are equal and have the same hash code.
+   */
+  private void checkEqualsIsConsistent(Message message1, Message message2) {
+    assertEquals(message1, message2);
+    assertEquals(message2, message1);
+    assertEquals(message2.hashCode(), message1.hashCode());
+  }
+
+  /**
+   * Asserts that the given protos are not equal and have different hash codes.
+   *
+   * @warning It's valid for non-equal objects to have the same hash code, so
+   *   this test is stricter than it needs to be. However, this should happen
+   *   relatively rarely.
+   */
+  private void checkNotEqual(Message m1, Message m2) {
+    String equalsError = String.format("%s should not be equal to %s", m1, m2);
+    assertFalse(equalsError, m1.equals(m2));
+    assertFalse(equalsError, m2.equals(m1));
+
+    assertFalse(
+        String.format("%s should have a different hash code from %s", m1, m2),
+        m1.hashCode() == m2.hashCode());
+  }
+
+  public void testCheckByteStringIsUtf8OnUtf8() {
+    ByteString byteString = ByteString.copyFromUtf8("some text");
+    AbstractMessageLite.checkByteStringIsUtf8(byteString);
+    // No exception thrown.
+  }
+
+  public void testCheckByteStringIsUtf8OnNonUtf8() {
+    ByteString byteString =
+        ByteString.copyFrom(new byte[]{(byte) 0x80}); // A lone continuation byte.
+    try {
+      AbstractMessageLite.checkByteStringIsUtf8(byteString);
+      fail("Expected AbstractMessageLite.checkByteStringIsUtf8 to throw IllegalArgumentException");
+    } catch (IllegalArgumentException exception) {
+      assertEquals("Byte string is not UTF-8.", exception.getMessage());
+    }
+  }
+
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java b/protobuf/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java
new file mode 100644
index 0000000..2b71cfb
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/BoundedByteStringTest.java
@@ -0,0 +1,68 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * This class tests {@link BoundedByteString}, which extends {@link LiteralByteString},
+ * by inheriting the tests from {@link LiteralByteStringTest}.  The only method which
+ * is strange enough that it needs to be overridden here is {@link #testToString()}.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+public class BoundedByteStringTest extends LiteralByteStringTest {
+
+  @Override
+  protected void setUp() throws Exception {
+    classUnderTest = "BoundedByteString";
+    byte[] sourceBytes = ByteStringTest.getTestBytes(2341, 11337766L);
+    int from = 100;
+    int to = sourceBytes.length - 100;
+    stringUnderTest = ByteString.copyFrom(sourceBytes).substring(from, to);
+    referenceBytes = new byte[to - from];
+    System.arraycopy(sourceBytes, from, referenceBytes, 0, to - from);
+    expectedHashCode = 727575887;
+  }
+
+  @Override
+  public void testToString() throws UnsupportedEncodingException {
+    String testString = "I love unicode \u1234\u5678 characters";
+    LiteralByteString unicode = new LiteralByteString(testString.getBytes(UTF_8));
+    ByteString chopped = unicode.substring(2, unicode.size() - 6);
+    assertEquals(classUnderTest + ".substring() must have the expected type",
+        classUnderTest, getActualClassName(chopped));
+
+    String roundTripString = chopped.toString(UTF_8);
+    assertEquals(classUnderTest + " unicode bytes must match",
+        testString.substring(2, testString.length() - 6), roundTripString);
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/ByteStringTest.java b/protobuf/java/src/test/java/com/google/protobuf/ByteStringTest.java
new file mode 100644
index 0000000..15de17c
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/ByteStringTest.java
@@ -0,0 +1,759 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.ByteString.Output;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Random;
+
+/**
+ * Test methods with implementations in {@link ByteString}, plus do some top-level "integration"
+ * tests.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+public class ByteStringTest extends TestCase {
+
+  private static final String UTF_16 = "UTF-16";
+
+  static byte[] getTestBytes(int size, long seed) {
+    Random random = new Random(seed);
+    byte[] result = new byte[size];
+    random.nextBytes(result);
+    return result;
+  }
+
+  private byte[] getTestBytes(int size) {
+    return getTestBytes(size, 445566L);
+  }
+
+  private byte[] getTestBytes() {
+    return getTestBytes(1000);
+  }
+
+  // Compare the entire left array with a subset of the right array.
+  private boolean isArrayRange(byte[] left, byte[] right, int rightOffset, int length) {
+    boolean stillEqual = (left.length == length);
+    for (int i = 0; (stillEqual && i < length); ++i) {
+      stillEqual = (left[i] == right[rightOffset + i]);
+    }
+    return stillEqual;
+  }
+
+  // Returns true only if the given two arrays have identical contents.
+  private boolean isArray(byte[] left, byte[] right) {
+    return left.length == right.length && isArrayRange(left, right, 0, left.length);
+  }
+
+  public void testSubstring_BeginIndex() {
+    byte[] bytes = getTestBytes();
+    ByteString substring = ByteString.copyFrom(bytes).substring(500);
+    assertTrue("substring must contain the tail of the string",
+        isArrayRange(substring.toByteArray(), bytes, 500, bytes.length - 500));
+  }
+
+  public void testCopyFrom_BytesOffsetSize() {
+    byte[] bytes = getTestBytes();
+    ByteString byteString = ByteString.copyFrom(bytes, 500, 200);
+    assertTrue("copyFrom sub-range must contain the expected bytes",
+        isArrayRange(byteString.toByteArray(), bytes, 500, 200));
+  }
+
+  public void testCopyFrom_Bytes() {
+    byte[] bytes = getTestBytes();
+    ByteString byteString = ByteString.copyFrom(bytes);
+    assertTrue("copyFrom must contain the expected bytes",
+        isArray(byteString.toByteArray(), bytes));
+  }
+
+  public void testCopyFrom_ByteBufferSize() {
+    byte[] bytes = getTestBytes();
+    ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
+    byteBuffer.put(bytes);
+    byteBuffer.position(500);
+    ByteString byteString = ByteString.copyFrom(byteBuffer, 200);
+    assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes",
+        isArrayRange(byteString.toByteArray(), bytes, 500, 200));
+  }
+
+  public void testCopyFrom_ByteBuffer() {
+    byte[] bytes = getTestBytes();
+    ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
+    byteBuffer.put(bytes);
+    byteBuffer.position(500);
+    ByteString byteString = ByteString.copyFrom(byteBuffer);
+    assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes",
+        isArrayRange(byteString.toByteArray(), bytes, 500, bytes.length - 500));
+  }
+
+  public void testCopyFrom_StringEncoding() throws UnsupportedEncodingException {
+    String testString = "I love unicode \u1234\u5678 characters";
+    ByteString byteString = ByteString.copyFrom(testString, UTF_16);
+    byte[] testBytes = testString.getBytes(UTF_16);
+    assertTrue("copyFrom string must respect the charset",
+        isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
+  }
+
+  public void testCopyFrom_Utf8() throws UnsupportedEncodingException {
+    String testString = "I love unicode \u1234\u5678 characters";
+    ByteString byteString = ByteString.copyFromUtf8(testString);
+    byte[] testBytes = testString.getBytes("UTF-8");
+    assertTrue("copyFromUtf8 string must respect the charset",
+        isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
+  }
+
+  public void testCopyFrom_Iterable() {
+    byte[] testBytes = getTestBytes(77777, 113344L);
+    final List<ByteString> pieces = makeConcretePieces(testBytes);
+    // Call copyFrom() on a Collection
+    ByteString byteString = ByteString.copyFrom(pieces);
+    assertTrue("copyFrom a List must contain the expected bytes",
+        isArrayRange(byteString.toByteArray(), testBytes, 0, testBytes.length));
+    // Call copyFrom on an iteration that's not a collection
+    ByteString byteStringAlt = ByteString.copyFrom(new Iterable<ByteString>() {
+      public Iterator<ByteString> iterator() {
+        return pieces.iterator();
+      }
+    });
+    assertEquals("copyFrom from an Iteration must contain the expected bytes",
+        byteString, byteStringAlt);
+  }
+
+  public void testCopyTo_TargetOffset() {
+    byte[] bytes = getTestBytes();
+    ByteString byteString = ByteString.copyFrom(bytes);
+    byte[] target = new byte[bytes.length + 1000];
+    byteString.copyTo(target, 400);
+    assertTrue("copyFrom byteBuffer sub-range must contain the expected bytes",
+        isArrayRange(bytes, target, 400, bytes.length));
+  }
+
+  public void testReadFrom_emptyStream() throws IOException {
+    ByteString byteString =
+        ByteString.readFrom(new ByteArrayInputStream(new byte[0]));
+    assertSame("reading an empty stream must result in the EMPTY constant "
+        + "byte string", ByteString.EMPTY, byteString);
+  }
+
+  public void testReadFrom_smallStream() throws IOException {
+    assertReadFrom(getTestBytes(10));
+  }
+
+  public void testReadFrom_mutating() throws IOException {
+    byte[] capturedArray = null;
+    EvilInputStream eis = new EvilInputStream();
+    ByteString byteString = ByteString.readFrom(eis);
+
+    capturedArray = eis.capturedArray;
+    byte[] originalValue = byteString.toByteArray();
+    for (int x = 0; x < capturedArray.length; ++x) {
+      capturedArray[x] = (byte) 0;
+    }
+
+    byte[] newValue = byteString.toByteArray();
+    assertTrue("copyFrom byteBuffer must not grant access to underlying array",
+        Arrays.equals(originalValue, newValue));
+  }
+
+  // Tests sizes that are near the rope copy-out threshold.
+  public void testReadFrom_mediumStream() throws IOException {
+    assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE - 1));
+    assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE));
+    assertReadFrom(getTestBytes(ByteString.CONCATENATE_BY_COPY_SIZE + 1));
+    assertReadFrom(getTestBytes(200));
+  }
+
+  // Tests sizes that are over multi-segment rope threshold.
+  public void testReadFrom_largeStream() throws IOException {
+    assertReadFrom(getTestBytes(0x100));
+    assertReadFrom(getTestBytes(0x101));
+    assertReadFrom(getTestBytes(0x110));
+    assertReadFrom(getTestBytes(0x1000));
+    assertReadFrom(getTestBytes(0x1001));
+    assertReadFrom(getTestBytes(0x1010));
+    assertReadFrom(getTestBytes(0x10000));
+    assertReadFrom(getTestBytes(0x10001));
+    assertReadFrom(getTestBytes(0x10010));
+  }
+
+  // Tests sizes that are near the read buffer size.
+  public void testReadFrom_byteBoundaries() throws IOException {
+    final int min = ByteString.MIN_READ_FROM_CHUNK_SIZE;
+    final int max = ByteString.MAX_READ_FROM_CHUNK_SIZE;
+
+    assertReadFrom(getTestBytes(min - 1));
+    assertReadFrom(getTestBytes(min));
+    assertReadFrom(getTestBytes(min + 1));
+
+    assertReadFrom(getTestBytes(min * 2 - 1));
+    assertReadFrom(getTestBytes(min * 2));
+    assertReadFrom(getTestBytes(min * 2 + 1));
+
+    assertReadFrom(getTestBytes(min * 4 - 1));
+    assertReadFrom(getTestBytes(min * 4));
+    assertReadFrom(getTestBytes(min * 4 + 1));
+
+    assertReadFrom(getTestBytes(min * 8 - 1));
+    assertReadFrom(getTestBytes(min * 8));
+    assertReadFrom(getTestBytes(min * 8 + 1));
+
+    assertReadFrom(getTestBytes(max - 1));
+    assertReadFrom(getTestBytes(max));
+    assertReadFrom(getTestBytes(max + 1));
+
+    assertReadFrom(getTestBytes(max * 2 - 1));
+    assertReadFrom(getTestBytes(max * 2));
+    assertReadFrom(getTestBytes(max * 2 + 1));
+  }
+
+  // Tests that IOExceptions propagate through ByteString.readFrom().
+  public void testReadFrom_IOExceptions() {
+    try {
+      ByteString.readFrom(new FailStream());
+      fail("readFrom must throw the underlying IOException");
+
+    } catch (IOException e) {
+      assertEquals("readFrom must throw the expected exception",
+                   "synthetic failure", e.getMessage());
+    }
+  }
+
+  // Tests that ByteString.readFrom works with streams that don't
+  // always fill their buffers.
+  public void testReadFrom_reluctantStream() throws IOException {
+    final byte[] data = getTestBytes(0x1000);
+
+    ByteString byteString = ByteString.readFrom(new ReluctantStream(data));
+    assertTrue("readFrom byte stream must contain the expected bytes",
+        isArray(byteString.toByteArray(), data));
+
+    // Same test as above, but with some specific chunk sizes.
+    assertReadFromReluctantStream(data, 100);
+    assertReadFromReluctantStream(data, 248);
+    assertReadFromReluctantStream(data, 249);
+    assertReadFromReluctantStream(data, 250);
+    assertReadFromReluctantStream(data, 251);
+    assertReadFromReluctantStream(data, 0x1000);
+    assertReadFromReluctantStream(data, 0x1001);
+  }
+
+  // Fails unless ByteString.readFrom reads the bytes correctly from a
+  // reluctant stream with the given chunkSize parameter.
+  private void assertReadFromReluctantStream(byte[] bytes, int chunkSize)
+      throws IOException {
+    ByteString b = ByteString.readFrom(new ReluctantStream(bytes), chunkSize);
+    assertTrue("readFrom byte stream must contain the expected bytes",
+        isArray(b.toByteArray(), bytes));
+  }
+
+  // Tests that ByteString.readFrom works with streams that implement
+  // available().
+  public void testReadFrom_available() throws IOException {
+    final byte[] data = getTestBytes(0x1001);
+
+    ByteString byteString = ByteString.readFrom(new AvailableStream(data));
+    assertTrue("readFrom byte stream must contain the expected bytes",
+        isArray(byteString.toByteArray(), data));
+  }
+
+  // Fails unless ByteString.readFrom reads the bytes correctly.
+  private void assertReadFrom(byte[] bytes) throws IOException {
+    ByteString byteString =
+        ByteString.readFrom(new ByteArrayInputStream(bytes));
+    assertTrue("readFrom byte stream must contain the expected bytes",
+        isArray(byteString.toByteArray(), bytes));
+  }
+
+  // A stream that fails when read.
+  private static final class FailStream extends InputStream {
+    @Override public int read() throws IOException {
+      throw new IOException("synthetic failure");
+    }
+  }
+
+  // A stream that simulates blocking by only producing 250 characters
+  // per call to read(byte[]).
+  private static class ReluctantStream extends InputStream {
+    protected final byte[] data;
+    protected int pos = 0;
+
+    public ReluctantStream(byte[] data) {
+      this.data = data;
+    }
+
+    @Override public int read() {
+      if (pos == data.length) {
+        return -1;
+      } else {
+        return data[pos++];
+      }
+    }
+
+    @Override public int read(byte[] buf) {
+      return read(buf, 0, buf.length);
+    }
+
+    @Override public int read(byte[] buf, int offset, int size) {
+      if (pos == data.length) {
+        return -1;
+      }
+      int count = Math.min(Math.min(size, data.length - pos), 250);
+      System.arraycopy(data, pos, buf, offset, count);
+      pos += count;
+      return count;
+    }
+  }
+
+  // Same as above, but also implements available().
+  private static final class AvailableStream extends ReluctantStream {
+    public AvailableStream(byte[] data) {
+      super(data);
+    }
+
+    @Override public int available() {
+      return Math.min(250, data.length - pos);
+    }
+  }
+
+  // A stream which exposes the byte array passed into read(byte[], int, int).
+  private static class EvilInputStream extends InputStream {
+    public byte[] capturedArray = null;
+
+    @Override
+    public int read(byte[] buf, int off, int len) {
+      if (capturedArray != null) {
+        return -1;
+      } else {
+        capturedArray = buf;
+        for (int x = 0; x < len; ++x) {
+          buf[x] = (byte) x;
+        }
+        return len;
+      }
+    }
+
+    @Override
+    public int read() {
+      // Purposefully do nothing.
+      return -1;
+    }
+  }
+  
+  // A stream which exposes the byte array passed into write(byte[], int, int).
+  private static class EvilOutputStream extends OutputStream {
+    public byte[] capturedArray = null;
+
+    @Override
+    public void write(byte[] buf, int off, int len) {
+      if (capturedArray == null) {
+        capturedArray = buf;
+      }
+    }
+
+    @Override
+    public void write(int ignored) {
+      // Purposefully do nothing.
+    }
+  }
+
+  public void testToStringUtf8() throws UnsupportedEncodingException {
+    String testString = "I love unicode \u1234\u5678 characters";
+    byte[] testBytes = testString.getBytes("UTF-8");
+    ByteString byteString = ByteString.copyFrom(testBytes);
+    assertEquals("copyToStringUtf8 must respect the charset",
+        testString, byteString.toStringUtf8());
+  }
+
+  public void testNewOutput_InitialCapacity() throws IOException {
+    byte[] bytes = getTestBytes();
+    ByteString.Output output = ByteString.newOutput(bytes.length + 100);
+    output.write(bytes);
+    ByteString byteString = output.toByteString();
+    assertTrue(
+        "String built from newOutput(int) must contain the expected bytes",
+        isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
+  }
+
+  // Test newOutput() using a variety of buffer sizes and a variety of (fixed)
+  // write sizes
+  public void testNewOutput_ArrayWrite() throws IOException {
+    byte[] bytes = getTestBytes();
+    int length = bytes.length;
+    int[] bufferSizes = {128, 256, length / 2, length - 1, length, length + 1,
+                         2 * length, 3 * length};
+    int[] writeSizes = {1, 4, 5, 7, 23, bytes.length};
+
+    for (int bufferSize : bufferSizes) {
+      for (int writeSize : writeSizes) {
+        // Test writing the entire output writeSize bytes at a time.
+        ByteString.Output output = ByteString.newOutput(bufferSize);
+        for (int i = 0; i < length; i += writeSize) {
+          output.write(bytes, i, Math.min(writeSize, length - i));
+        }
+        ByteString byteString = output.toByteString();
+        assertTrue("String built from newOutput() must contain the expected bytes",
+            isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
+      }
+    }
+  }
+
+  // Test newOutput() using a variety of buffer sizes, but writing all the
+  // characters using write(byte);
+  public void testNewOutput_WriteChar() throws IOException {
+    byte[] bytes = getTestBytes();
+    int length = bytes.length;
+    int[] bufferSizes = {0, 1, 128, 256, length / 2,
+                         length - 1, length, length + 1,
+                         2 * length, 3 * length};
+    for (int bufferSize : bufferSizes) {
+      ByteString.Output output = ByteString.newOutput(bufferSize);
+      for (byte byteValue : bytes) {
+        output.write(byteValue);
+      }
+      ByteString byteString = output.toByteString();
+      assertTrue("String built from newOutput() must contain the expected bytes",
+          isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
+    }
+  }
+
+  // Test newOutput() in which we write the bytes using a variety of methods
+  // and sizes, and in which we repeatedly call toByteString() in the middle.
+  public void testNewOutput_Mixed() throws IOException {
+    Random rng = new Random(1);
+    byte[] bytes = getTestBytes();
+    int length = bytes.length;
+    int[] bufferSizes = {0, 1, 128, 256, length / 2,
+                         length - 1, length, length + 1,
+                         2 * length, 3 * length};
+
+    for (int bufferSize : bufferSizes) {
+      // Test writing the entire output using a mixture of write sizes and
+      // methods;
+      ByteString.Output output = ByteString.newOutput(bufferSize);
+      int position = 0;
+      while (position < bytes.length) {
+        if (rng.nextBoolean()) {
+          int count = 1 + rng.nextInt(bytes.length - position);
+          output.write(bytes, position, count);
+          position += count;
+        } else {
+          output.write(bytes[position]);
+          position++;
+        }
+        assertEquals("size() returns the right value", position, output.size());
+        assertTrue("newOutput() substring must have correct bytes",
+            isArrayRange(output.toByteString().toByteArray(),
+                bytes, 0, position));
+      }
+      ByteString byteString = output.toByteString();
+      assertTrue("String built from newOutput() must contain the expected bytes",
+          isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
+    }
+  }
+  
+  public void testNewOutputEmpty() throws IOException {
+    // Make sure newOutput() correctly builds empty byte strings
+    ByteString byteString = ByteString.newOutput().toByteString();
+    assertEquals(ByteString.EMPTY, byteString);
+  }
+  
+  public void testNewOutput_Mutating() throws IOException {
+    Output os = ByteString.newOutput(5);
+    os.write(new byte[] {1, 2, 3, 4, 5});
+    EvilOutputStream eos = new EvilOutputStream();
+    os.writeTo(eos);
+    byte[] capturedArray = eos.capturedArray;
+    ByteString byteString = os.toByteString();
+    byte[] oldValue = byteString.toByteArray();
+    Arrays.fill(capturedArray, (byte) 0);
+    byte[] newValue = byteString.toByteArray();
+    assertTrue("Output must not provide access to the underlying byte array",
+        Arrays.equals(oldValue, newValue));
+  }
+
+  public void testNewCodedBuilder() throws IOException {
+    byte[] bytes = getTestBytes();
+    ByteString.CodedBuilder builder = ByteString.newCodedBuilder(bytes.length);
+    builder.getCodedOutput().writeRawBytes(bytes);
+    ByteString byteString = builder.build();
+    assertTrue("String built from newCodedBuilder() must contain the expected bytes",
+        isArrayRange(bytes, byteString.toByteArray(), 0, bytes.length));
+  }
+
+  public void testSubstringParity() {
+    byte[] bigBytes = getTestBytes(2048 * 1024, 113344L);
+    int start = 512 * 1024 - 3333;
+    int end   = 512 * 1024 + 7777;
+    ByteString concreteSubstring = ByteString.copyFrom(bigBytes).substring(start, end);
+    boolean ok = true;
+    for (int i = start; ok && i < end; ++i) {
+      ok = (bigBytes[i] == concreteSubstring.byteAt(i - start));
+    }
+    assertTrue("Concrete substring didn't capture the right bytes", ok);
+
+    ByteString literalString = ByteString.copyFrom(bigBytes, start, end - start);
+    assertTrue("Substring must be equal to literal string",
+        concreteSubstring.equals(literalString));
+    assertEquals("Substring must have same hashcode as literal string",
+        literalString.hashCode(), concreteSubstring.hashCode());
+  }
+
+  public void testCompositeSubstring() {
+    byte[] referenceBytes = getTestBytes(77748, 113344L);
+
+    List<ByteString> pieces = makeConcretePieces(referenceBytes);
+    ByteString listString = ByteString.copyFrom(pieces);
+
+    int from = 1000;
+    int to = 40000;
+    ByteString compositeSubstring = listString.substring(from, to);
+    byte[] substringBytes = compositeSubstring.toByteArray();
+    boolean stillEqual = true;
+    for (int i = 0; stillEqual && i < to - from; ++i) {
+      stillEqual = referenceBytes[from + i] == substringBytes[i];
+    }
+    assertTrue("Substring must return correct bytes", stillEqual);
+
+    stillEqual = true;
+    for (int i = 0; stillEqual && i < to - from; ++i) {
+      stillEqual = referenceBytes[from + i] == compositeSubstring.byteAt(i);
+    }
+    assertTrue("Substring must support byteAt() correctly", stillEqual);
+
+    ByteString literalSubstring = ByteString.copyFrom(referenceBytes, from, to - from);
+    assertTrue("Composite substring must equal a literal substring over the same bytes",
+        compositeSubstring.equals(literalSubstring));
+    assertTrue("Literal substring must equal a composite substring over the same bytes",
+        literalSubstring.equals(compositeSubstring));
+
+    assertEquals("We must get the same hashcodes for composite and literal substrings",
+        literalSubstring.hashCode(), compositeSubstring.hashCode());
+
+    assertFalse("We can't be equal to a proper substring",
+        compositeSubstring.equals(literalSubstring.substring(0, literalSubstring.size() - 1)));
+  }
+
+  public void testCopyFromList() {
+    byte[] referenceBytes = getTestBytes(77748, 113344L);
+    ByteString literalString = ByteString.copyFrom(referenceBytes);
+
+    List<ByteString> pieces = makeConcretePieces(referenceBytes);
+    ByteString listString = ByteString.copyFrom(pieces);
+
+    assertTrue("Composite string must be equal to literal string",
+        listString.equals(literalString));
+    assertEquals("Composite string must have same hashcode as literal string",
+        literalString.hashCode(), listString.hashCode());
+  }
+
+  public void testConcat() {
+    byte[] referenceBytes = getTestBytes(77748, 113344L);
+    ByteString literalString = ByteString.copyFrom(referenceBytes);
+
+    List<ByteString> pieces = makeConcretePieces(referenceBytes);
+
+    Iterator<ByteString> iter = pieces.iterator();
+    ByteString concatenatedString = iter.next();
+    while (iter.hasNext()) {
+      concatenatedString = concatenatedString.concat(iter.next());
+    }
+
+    assertTrue("Concatenated string must be equal to literal string",
+        concatenatedString.equals(literalString));
+    assertEquals("Concatenated string must have same hashcode as literal string",
+        literalString.hashCode(), concatenatedString.hashCode());
+  }
+
+  /**
+   * Test the Rope implementation can deal with Empty nodes, even though we
+   * guard against them. See also {@link LiteralByteStringTest#testConcat_empty()}.
+   */
+  public void testConcat_empty() {
+    byte[] referenceBytes = getTestBytes(7748, 113344L);
+    ByteString literalString = ByteString.copyFrom(referenceBytes);
+
+    ByteString duo = RopeByteString.newInstanceForTest(literalString, literalString);
+    ByteString temp = RopeByteString.newInstanceForTest(
+        RopeByteString.newInstanceForTest(literalString, ByteString.EMPTY),
+        RopeByteString.newInstanceForTest(ByteString.EMPTY, literalString));
+    ByteString quintet = RopeByteString.newInstanceForTest(temp, ByteString.EMPTY);
+
+    assertTrue("String with concatenated nulls must equal simple concatenate",
+        duo.equals(quintet));
+    assertEquals("String with concatenated nulls have same hashcode as simple concatenate",
+        duo.hashCode(), quintet.hashCode());
+
+    ByteString.ByteIterator duoIter = duo.iterator();
+    ByteString.ByteIterator quintetIter = quintet.iterator();
+    boolean stillEqual = true;
+    while (stillEqual && quintetIter.hasNext()) {
+      stillEqual = (duoIter.nextByte() == quintetIter.nextByte());
+    }
+    assertTrue("We must get the same characters by iterating", stillEqual);
+    assertFalse("Iterator must be exhausted", duoIter.hasNext());
+    try {
+      duoIter.nextByte();
+      fail("Should have thrown an exception.");
+    } catch (NoSuchElementException e) {
+      // This is success
+    }
+    try {
+      quintetIter.nextByte();
+      fail("Should have thrown an exception.");
+    } catch (NoSuchElementException e) {
+      // This is success
+    }
+
+    // Test that even if we force empty strings in as rope leaves in this
+    // configuration, we always get a (possibly Bounded) LiteralByteString
+    // for a length 1 substring.
+    //
+    // It is possible, using the testing factory method to create deeply nested
+    // trees of empty leaves, to make a string that will fail this test.
+    for (int i = 1; i < duo.size(); ++i) {
+      assertTrue("Substrings of size() < 2 must not be RopeByteStrings",
+          duo.substring(i - 1, i) instanceof LiteralByteString);
+    }
+    for (int i = 1; i < quintet.size(); ++i) {
+      assertTrue("Substrings of size() < 2 must not be RopeByteStrings",
+          quintet.substring(i - 1, i) instanceof LiteralByteString);
+    }
+  }
+
+  public void testStartsWith() {
+    byte[] bytes = getTestBytes(1000, 1234L);
+    ByteString string = ByteString.copyFrom(bytes);
+    ByteString prefix = ByteString.copyFrom(bytes, 0, 500);
+    ByteString suffix = ByteString.copyFrom(bytes, 400, 600);
+    assertTrue(string.startsWith(ByteString.EMPTY));
+    assertTrue(string.startsWith(string));
+    assertTrue(string.startsWith(prefix));
+    assertFalse(string.startsWith(suffix));
+    assertFalse(prefix.startsWith(suffix));
+    assertFalse(suffix.startsWith(prefix));
+    assertFalse(ByteString.EMPTY.startsWith(prefix));
+    assertTrue(ByteString.EMPTY.startsWith(ByteString.EMPTY));
+  }
+
+  public void testEndsWith() {
+    byte[] bytes = getTestBytes(1000, 1234L);
+    ByteString string = ByteString.copyFrom(bytes);
+    ByteString prefix = ByteString.copyFrom(bytes, 0, 500);
+    ByteString suffix = ByteString.copyFrom(bytes, 400, 600);
+    assertTrue(string.endsWith(ByteString.EMPTY));
+    assertTrue(string.endsWith(string));
+    assertTrue(string.endsWith(suffix));
+    assertFalse(string.endsWith(prefix));
+    assertFalse(suffix.endsWith(prefix));
+    assertFalse(prefix.endsWith(suffix));
+    assertFalse(ByteString.EMPTY.endsWith(suffix));
+    assertTrue(ByteString.EMPTY.endsWith(ByteString.EMPTY));
+  }
+
+  static List<ByteString> makeConcretePieces(byte[] referenceBytes) {
+    List<ByteString> pieces = new ArrayList<ByteString>();
+    // Starting length should be small enough that we'll do some concatenating by
+    // copying if we just concatenate all these pieces together.
+    for (int start = 0, length = 16; start < referenceBytes.length; start += length) {
+      length = (length << 1) - 1;
+      if (start + length > referenceBytes.length) {
+        length = referenceBytes.length - start;
+      }
+      pieces.add(ByteString.copyFrom(referenceBytes, start, length));
+    }
+    return pieces;
+  }
+  
+  private byte[] substringUsingWriteTo(
+      ByteString data, int offset, int length) throws IOException {
+    ByteArrayOutputStream output = new ByteArrayOutputStream();
+    data.writeTo(output, offset, length);
+    return output.toByteArray();
+  }
+  
+  public void testWriteToOutputStream() throws Exception {
+    // Choose a size large enough so when two ByteStrings are concatenated they
+    // won't be merged into one byte array due to some optimizations.
+    final int dataSize = ByteString.CONCATENATE_BY_COPY_SIZE + 1;
+    byte[] data1 = new byte[dataSize];
+    for (int i = 0; i < data1.length; i++) {
+      data1[i] = (byte) 1;
+    }
+    data1[1] = (byte) 11;
+    // Test LiteralByteString.writeTo(OutputStream,int,int)
+    LiteralByteString left = new LiteralByteString(data1);
+    byte[] result = substringUsingWriteTo(left, 1, 1);
+    assertEquals(1, result.length);
+    assertEquals((byte) 11, result[0]);
+    
+    byte[] data2 = new byte[dataSize];
+    for (int i = 0; i < data1.length; i++) {
+      data2[i] = (byte) 2;
+    }
+    LiteralByteString right = new LiteralByteString(data2);
+    // Concatenate two ByteStrings to create a RopeByteString.
+    ByteString root = left.concat(right);
+    // Make sure we are actually testing a RopeByteString with a simple tree
+    // structure.
+    assertEquals(1, root.getTreeDepth());
+    // Write parts of the left node.
+    result = substringUsingWriteTo(root, 0, dataSize);
+    assertEquals(dataSize, result.length);
+    assertEquals((byte) 1, result[0]);
+    assertEquals((byte) 1, result[dataSize - 1]);
+    // Write parts of the right node.
+    result = substringUsingWriteTo(root, dataSize, dataSize);
+    assertEquals(dataSize, result.length);
+    assertEquals((byte) 2, result[0]);
+    assertEquals((byte) 2, result[dataSize - 1]);
+    // Write a segment of bytes that runs across both nodes.
+    result = substringUsingWriteTo(root, dataSize / 2, dataSize);
+    assertEquals(dataSize, result.length);
+    assertEquals((byte) 1, result[0]);
+    assertEquals((byte) 1, result[dataSize - dataSize / 2 - 1]);
+    assertEquals((byte) 2, result[dataSize - dataSize / 2]);
+    assertEquals((byte) 2, result[dataSize - 1]);
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/CheckUtf8Test.java b/protobuf/java/src/test/java/com/google/protobuf/CheckUtf8Test.java
new file mode 100644
index 0000000..6470e9c
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/CheckUtf8Test.java
@@ -0,0 +1,141 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import proto2_test_check_utf8.TestCheckUtf8.BytesWrapper;
+import proto2_test_check_utf8.TestCheckUtf8.StringWrapper;
+import proto2_test_check_utf8_size.TestCheckUtf8Size.BytesWrapperSize;
+import proto2_test_check_utf8_size.TestCheckUtf8Size.StringWrapperSize;
+import junit.framework.TestCase;
+
+/**
+ * Test that protos generated with file option java_string_check_utf8 do in
+ * fact perform appropriate UTF-8 checks.
+ *
+ * @author jbaum@google.com (Jacob Butcher)
+ */
+public class CheckUtf8Test extends TestCase {
+
+  private static final String UTF8_BYTE_STRING_TEXT = "some text";
+  private static final ByteString UTF8_BYTE_STRING =
+      ByteString.copyFromUtf8(UTF8_BYTE_STRING_TEXT);
+  private static final ByteString NON_UTF8_BYTE_STRING =
+      ByteString.copyFrom(new byte[]{(byte) 0x80}); // A lone continuation byte.
+
+  public void testBuildRequiredStringWithGoodUtf8() throws Exception {
+    assertEquals(UTF8_BYTE_STRING_TEXT,
+                 StringWrapper.newBuilder().setReqBytes(UTF8_BYTE_STRING).getReq());
+  }
+
+  public void testParseRequiredStringWithGoodUtf8() throws Exception {
+    ByteString serialized =
+        BytesWrapper.newBuilder().setReq(UTF8_BYTE_STRING).build().toByteString();
+    assertEquals(UTF8_BYTE_STRING_TEXT,
+                 StringWrapper.PARSER.parseFrom(serialized).getReq());
+  }
+
+  public void testBuildRequiredStringWithBadUtf8() throws Exception {
+    try {
+      StringWrapper.newBuilder().setReqBytes(NON_UTF8_BYTE_STRING);
+      fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+    } catch (IllegalArgumentException exception) {
+      assertEquals("Byte string is not UTF-8.", exception.getMessage());
+    }
+  }
+
+  public void testBuildOptionalStringWithBadUtf8() throws Exception {
+    try {
+      StringWrapper.newBuilder().setOptBytes(NON_UTF8_BYTE_STRING);
+      fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+    } catch (IllegalArgumentException exception) {
+      assertEquals("Byte string is not UTF-8.", exception.getMessage());
+    }
+  }
+
+  public void testBuildRepeatedStringWithBadUtf8() throws Exception {
+    try {
+      StringWrapper.newBuilder().addRepBytes(NON_UTF8_BYTE_STRING);
+      fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+    } catch (IllegalArgumentException exception) {
+      assertEquals("Byte string is not UTF-8.", exception.getMessage());
+    }
+  }
+
+  public void testParseRequiredStringWithBadUtf8() throws Exception {
+    ByteString serialized =
+        BytesWrapper.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteString();
+    try {
+      StringWrapper.PARSER.parseFrom(serialized);
+      fail("Expected InvalidProtocolBufferException for non UTF-8 byte string.");
+    } catch (InvalidProtocolBufferException exception) {
+      assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
+    }
+  }
+
+  public void testBuildRequiredStringWithBadUtf8Size() throws Exception {
+    try {
+      StringWrapperSize.newBuilder().setReqBytes(NON_UTF8_BYTE_STRING);
+      fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+    } catch (IllegalArgumentException exception) {
+      assertEquals("Byte string is not UTF-8.", exception.getMessage());
+    }
+  }
+
+  public void testBuildOptionalStringWithBadUtf8Size() throws Exception {
+    try {
+      StringWrapperSize.newBuilder().setOptBytes(NON_UTF8_BYTE_STRING);
+      fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+    } catch (IllegalArgumentException exception) {
+      assertEquals("Byte string is not UTF-8.", exception.getMessage());
+    }
+  }
+
+  public void testBuildRepeatedStringWithBadUtf8Size() throws Exception {
+    try {
+      StringWrapperSize.newBuilder().addRepBytes(NON_UTF8_BYTE_STRING);
+      fail("Expected IllegalArgumentException for non UTF-8 byte string.");
+    } catch (IllegalArgumentException exception) {
+      assertEquals("Byte string is not UTF-8.", exception.getMessage());
+    }
+  }
+
+  public void testParseRequiredStringWithBadUtf8Size() throws Exception {
+    ByteString serialized =
+        BytesWrapperSize.newBuilder().setReq(NON_UTF8_BYTE_STRING).build().toByteString();
+    try {
+      StringWrapperSize.PARSER.parseFrom(serialized);
+      fail("Expected InvalidProtocolBufferException for non UTF-8 byte string.");
+    } catch (InvalidProtocolBufferException exception) {
+      assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
+    }
+  }
+
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java b/protobuf/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java
new file mode 100644
index 0000000..3f656e2
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/CodedInputStreamTest.java
@@ -0,0 +1,769 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.BoolMessage;
+import protobuf_unittest.UnittestProto.Int32Message;
+import protobuf_unittest.UnittestProto.Int64Message;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestRecursiveMessage;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+/**
+ * Unit test for {@link CodedInputStream}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class CodedInputStreamTest extends TestCase {
+  /**
+   * Helper to construct a byte array from a bunch of bytes.  The inputs are
+   * actually ints so that I can use hex notation and not get stupid errors
+   * about precision.
+   */
+  private byte[] bytes(int... bytesAsInts) {
+    byte[] bytes = new byte[bytesAsInts.length];
+    for (int i = 0; i < bytesAsInts.length; i++) {
+      bytes[i] = (byte) bytesAsInts[i];
+    }
+    return bytes;
+  }
+
+  /**
+   * An InputStream which limits the number of bytes it reads at a time.
+   * We use this to make sure that CodedInputStream doesn't screw up when
+   * reading in small blocks.
+   */
+  private static final class SmallBlockInputStream extends FilterInputStream {
+    private final int blockSize;
+
+    public SmallBlockInputStream(byte[] data, int blockSize) {
+      this(new ByteArrayInputStream(data), blockSize);
+    }
+
+    public SmallBlockInputStream(InputStream in, int blockSize) {
+      super(in);
+      this.blockSize = blockSize;
+    }
+
+    public int read(byte[] b) throws IOException {
+      return super.read(b, 0, Math.min(b.length, blockSize));
+    }
+
+    public int read(byte[] b, int off, int len) throws IOException {
+      return super.read(b, off, Math.min(len, blockSize));
+    }
+  }
+
+  private void assertDataConsumed(byte[] data, CodedInputStream input)
+      throws IOException {
+    assertEquals(data.length, input.getTotalBytesRead());
+    assertTrue(input.isAtEnd());
+  }
+
+  /**
+   * Parses the given bytes using readRawVarint32() and readRawVarint64() and
+   * checks that the result matches the given value.
+   */
+  private void assertReadVarint(byte[] data, long value) throws Exception {
+    CodedInputStream input = CodedInputStream.newInstance(data);
+    assertEquals((int) value, input.readRawVarint32());
+    assertDataConsumed(data, input);
+
+    input = CodedInputStream.newInstance(data);
+    assertEquals(value, input.readRawVarint64());
+    assertDataConsumed(data, input);
+
+    input = CodedInputStream.newInstance(data);
+    assertEquals(value, input.readRawVarint64SlowPath());
+    assertDataConsumed(data, input);
+
+    input = CodedInputStream.newInstance(data);
+    assertTrue(input.skipField(WireFormat.WIRETYPE_VARINT));
+    assertDataConsumed(data, input);
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+      input = CodedInputStream.newInstance(
+        new SmallBlockInputStream(data, blockSize));
+      assertEquals((int) value, input.readRawVarint32());
+      assertDataConsumed(data, input);
+
+      input = CodedInputStream.newInstance(
+        new SmallBlockInputStream(data, blockSize));
+      assertEquals(value, input.readRawVarint64());
+      assertDataConsumed(data, input);
+
+      input = CodedInputStream.newInstance(
+        new SmallBlockInputStream(data, blockSize));
+      assertEquals(value, input.readRawVarint64SlowPath());
+      assertDataConsumed(data, input);
+
+      input = CodedInputStream.newInstance(
+        new SmallBlockInputStream(data, blockSize));
+      assertTrue(input.skipField(WireFormat.WIRETYPE_VARINT));
+      assertDataConsumed(data, input);
+    }
+
+    // Try reading direct from an InputStream.  We want to verify that it
+    // doesn't read past the end of the input, so we copy to a new, bigger
+    // array first.
+    byte[] longerData = new byte[data.length + 1];
+    System.arraycopy(data, 0, longerData, 0, data.length);
+    InputStream rawInput = new ByteArrayInputStream(longerData);
+    assertEquals((int) value, CodedInputStream.readRawVarint32(rawInput));
+    assertEquals(1, rawInput.available());
+  }
+
+  /**
+   * Parses the given bytes using readRawVarint32() and readRawVarint64() and
+   * expects them to fail with an InvalidProtocolBufferException whose
+   * description matches the given one.
+   */
+  private void assertReadVarintFailure(
+      InvalidProtocolBufferException expected, byte[] data)
+      throws Exception {
+    CodedInputStream input = CodedInputStream.newInstance(data);
+    try {
+      input.readRawVarint32();
+      fail("Should have thrown an exception.");
+    } catch (InvalidProtocolBufferException e) {
+      assertEquals(expected.getMessage(), e.getMessage());
+    }
+
+    input = CodedInputStream.newInstance(data);
+    try {
+      input.readRawVarint64();
+      fail("Should have thrown an exception.");
+    } catch (InvalidProtocolBufferException e) {
+      assertEquals(expected.getMessage(), e.getMessage());
+    }
+
+    input = CodedInputStream.newInstance(data);
+    try {
+      input.readRawVarint64SlowPath();
+      fail("Should have thrown an exception.");
+    } catch (InvalidProtocolBufferException e) {
+      assertEquals(expected.getMessage(), e.getMessage());
+    }
+
+    // Make sure we get the same error when reading direct from an InputStream.
+    try {
+      CodedInputStream.readRawVarint32(new ByteArrayInputStream(data));
+      fail("Should have thrown an exception.");
+    } catch (InvalidProtocolBufferException e) {
+      assertEquals(expected.getMessage(), e.getMessage());
+    }
+  }
+
+  /** Tests readRawVarint32() and readRawVarint64(). */
+  public void testReadVarint() throws Exception {
+    assertReadVarint(bytes(0x00), 0);
+    assertReadVarint(bytes(0x01), 1);
+    assertReadVarint(bytes(0x7f), 127);
+    // 14882
+    assertReadVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
+    // 2961488830
+    assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
+      (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+      (0x0bL << 28));
+
+    // 64-bit
+    // 7256456126
+    assertReadVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
+      (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+      (0x1bL << 28));
+    // 41256202580718336
+    assertReadVarint(
+      bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
+      (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+      (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
+    // 11964378330978735131
+    assertReadVarint(
+      bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
+      (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+      (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
+      (0x05L << 49) | (0x26L << 56) | (0x01L << 63));
+
+    // Failures
+    assertReadVarintFailure(
+      InvalidProtocolBufferException.malformedVarint(),
+      bytes(0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+            0x00));
+    assertReadVarintFailure(
+      InvalidProtocolBufferException.truncatedMessage(),
+      bytes(0x80));
+  }
+
+  /**
+   * Parses the given bytes using readRawLittleEndian32() and checks
+   * that the result matches the given value.
+   */
+  private void assertReadLittleEndian32(byte[] data, int value)
+                                        throws Exception {
+    CodedInputStream input = CodedInputStream.newInstance(data);
+    assertEquals(value, input.readRawLittleEndian32());
+    assertTrue(input.isAtEnd());
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+      input = CodedInputStream.newInstance(
+        new SmallBlockInputStream(data, blockSize));
+      assertEquals(value, input.readRawLittleEndian32());
+      assertTrue(input.isAtEnd());
+    }
+  }
+
+  /**
+   * Parses the given bytes using readRawLittleEndian64() and checks
+   * that the result matches the given value.
+   */
+  private void assertReadLittleEndian64(byte[] data, long value)
+                                        throws Exception {
+    CodedInputStream input = CodedInputStream.newInstance(data);
+    assertEquals(value, input.readRawLittleEndian64());
+    assertTrue(input.isAtEnd());
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+      input = CodedInputStream.newInstance(
+        new SmallBlockInputStream(data, blockSize));
+      assertEquals(value, input.readRawLittleEndian64());
+      assertTrue(input.isAtEnd());
+    }
+  }
+
+  /** Tests readRawLittleEndian32() and readRawLittleEndian64(). */
+  public void testReadLittleEndian() throws Exception {
+    assertReadLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
+    assertReadLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
+
+    assertReadLittleEndian64(
+      bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
+      0x123456789abcdef0L);
+    assertReadLittleEndian64(
+      bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a),
+      0x9abcdef012345678L);
+  }
+
+  /** Test decodeZigZag32() and decodeZigZag64(). */
+  public void testDecodeZigZag() throws Exception {
+    assertEquals( 0, CodedInputStream.decodeZigZag32(0));
+    assertEquals(-1, CodedInputStream.decodeZigZag32(1));
+    assertEquals( 1, CodedInputStream.decodeZigZag32(2));
+    assertEquals(-2, CodedInputStream.decodeZigZag32(3));
+    assertEquals(0x3FFFFFFF, CodedInputStream.decodeZigZag32(0x7FFFFFFE));
+    assertEquals(0xC0000000, CodedInputStream.decodeZigZag32(0x7FFFFFFF));
+    assertEquals(0x7FFFFFFF, CodedInputStream.decodeZigZag32(0xFFFFFFFE));
+    assertEquals(0x80000000, CodedInputStream.decodeZigZag32(0xFFFFFFFF));
+
+    assertEquals( 0, CodedInputStream.decodeZigZag64(0));
+    assertEquals(-1, CodedInputStream.decodeZigZag64(1));
+    assertEquals( 1, CodedInputStream.decodeZigZag64(2));
+    assertEquals(-2, CodedInputStream.decodeZigZag64(3));
+    assertEquals(0x000000003FFFFFFFL,
+                 CodedInputStream.decodeZigZag64(0x000000007FFFFFFEL));
+    assertEquals(0xFFFFFFFFC0000000L,
+                 CodedInputStream.decodeZigZag64(0x000000007FFFFFFFL));
+    assertEquals(0x000000007FFFFFFFL,
+                 CodedInputStream.decodeZigZag64(0x00000000FFFFFFFEL));
+    assertEquals(0xFFFFFFFF80000000L,
+                 CodedInputStream.decodeZigZag64(0x00000000FFFFFFFFL));
+    assertEquals(0x7FFFFFFFFFFFFFFFL,
+                 CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFEL));
+    assertEquals(0x8000000000000000L,
+                 CodedInputStream.decodeZigZag64(0xFFFFFFFFFFFFFFFFL));
+  }
+
+  /** Tests reading and parsing a whole message with every field type. */
+  public void testReadWholeMessage() throws Exception {
+    TestAllTypes message = TestUtil.getAllSet();
+
+    byte[] rawBytes = message.toByteArray();
+    assertEquals(rawBytes.length, message.getSerializedSize());
+
+    TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+    TestUtil.assertAllFieldsSet(message2);
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
+      message2 = TestAllTypes.parseFrom(
+        new SmallBlockInputStream(rawBytes, blockSize));
+      TestUtil.assertAllFieldsSet(message2);
+    }
+  }
+
+  /** Tests skipField(). */
+  public void testSkipWholeMessage() throws Exception {
+    TestAllTypes message = TestUtil.getAllSet();
+    byte[] rawBytes = message.toByteArray();
+
+    // Create two parallel inputs.  Parse one as unknown fields while using
+    // skipField() to skip each field on the other.  Expect the same tags.
+    CodedInputStream input1 = CodedInputStream.newInstance(rawBytes);
+    CodedInputStream input2 = CodedInputStream.newInstance(rawBytes);
+    UnknownFieldSet.Builder unknownFields = UnknownFieldSet.newBuilder();
+
+    while (true) {
+      int tag = input1.readTag();
+      assertEquals(tag, input2.readTag());
+      if (tag == 0) {
+        break;
+      }
+      unknownFields.mergeFieldFrom(tag, input1);
+      input2.skipField(tag);
+    }
+  }
+
+
+  /**
+   * Test that a bug in skipRawBytes() has been fixed:  if the skip skips
+   * exactly up to a limit, this should not break things.
+   */
+  public void testSkipRawBytesBug() throws Exception {
+    byte[] rawBytes = new byte[] { 1, 2 };
+    CodedInputStream input = CodedInputStream.newInstance(rawBytes);
+
+    int limit = input.pushLimit(1);
+    input.skipRawBytes(1);
+    input.popLimit(limit);
+    assertEquals(2, input.readRawByte());
+  }
+
+  /**
+   * Test that a bug in skipRawBytes() has been fixed:  if the skip skips
+   * past the end of a buffer with a limit that has been set past the end of
+   * that buffer, this should not break things.
+   */
+  public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception {
+    byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 };
+    CodedInputStream input = CodedInputStream.newInstance(
+        new SmallBlockInputStream(rawBytes, 3));
+
+    int limit = input.pushLimit(4);
+    // In order to expose the bug we need to read at least one byte to prime the
+    // buffer inside the CodedInputStream.
+    assertEquals(1, input.readRawByte());
+    // Skip to the end of the limit.
+    input.skipRawBytes(3);
+    assertTrue(input.isAtEnd());
+    input.popLimit(limit);
+    assertEquals(5, input.readRawByte());
+  }
+
+  public void testReadHugeBlob() throws Exception {
+    // Allocate and initialize a 1MB blob.
+    byte[] blob = new byte[1 << 20];
+    for (int i = 0; i < blob.length; i++) {
+      blob[i] = (byte) i;
+    }
+
+    // Make a message containing it.
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestUtil.setAllFields(builder);
+    builder.setOptionalBytes(ByteString.copyFrom(blob));
+    TestAllTypes message = builder.build();
+
+    // Serialize and parse it.  Make sure to parse from an InputStream, not
+    // directly from a ByteString, so that CodedInputStream uses buffered
+    // reading.
+    TestAllTypes message2 =
+      TestAllTypes.parseFrom(message.toByteString().newInput());
+
+    assertEquals(message.getOptionalBytes(), message2.getOptionalBytes());
+
+    // Make sure all the other fields were parsed correctly.
+    TestAllTypes message3 = TestAllTypes.newBuilder(message2)
+      .setOptionalBytes(TestUtil.getAllSet().getOptionalBytes())
+      .build();
+    TestUtil.assertAllFieldsSet(message3);
+  }
+
+  public void testReadMaliciouslyLargeBlob() throws Exception {
+    ByteString.Output rawOutput = ByteString.newOutput();
+    CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+
+    int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+    output.writeRawVarint32(tag);
+    output.writeRawVarint32(0x7FFFFFFF);
+    output.writeRawBytes(new byte[32]);  // Pad with a few random bytes.
+    output.flush();
+
+    CodedInputStream input = rawOutput.toByteString().newCodedInput();
+    assertEquals(tag, input.readTag());
+
+    try {
+      input.readBytes();
+      fail("Should have thrown an exception!");
+    } catch (InvalidProtocolBufferException e) {
+      // success.
+    }
+  }
+
+  private TestRecursiveMessage makeRecursiveMessage(int depth) {
+    if (depth == 0) {
+      return TestRecursiveMessage.newBuilder().setI(5).build();
+    } else {
+      return TestRecursiveMessage.newBuilder()
+        .setA(makeRecursiveMessage(depth - 1)).build();
+    }
+  }
+
+  private void assertMessageDepth(TestRecursiveMessage message, int depth) {
+    if (depth == 0) {
+      assertFalse(message.hasA());
+      assertEquals(5, message.getI());
+    } else {
+      assertTrue(message.hasA());
+      assertMessageDepth(message.getA(), depth - 1);
+    }
+  }
+
+  public void testMaliciousRecursion() throws Exception {
+    ByteString data64 = makeRecursiveMessage(64).toByteString();
+    ByteString data65 = makeRecursiveMessage(65).toByteString();
+
+    assertMessageDepth(TestRecursiveMessage.parseFrom(data64), 64);
+
+    try {
+      TestRecursiveMessage.parseFrom(data65);
+      fail("Should have thrown an exception!");
+    } catch (InvalidProtocolBufferException e) {
+      // success.
+    }
+
+    CodedInputStream input = data64.newCodedInput();
+    input.setRecursionLimit(8);
+    try {
+      TestRecursiveMessage.parseFrom(input);
+      fail("Should have thrown an exception!");
+    } catch (InvalidProtocolBufferException e) {
+      // success.
+    }
+  }
+
+  private void checkSizeLimitExceeded(InvalidProtocolBufferException e) {
+      assertEquals(
+          InvalidProtocolBufferException.sizeLimitExceeded().getMessage(),
+          e.getMessage());
+  }
+
+  public void testSizeLimit() throws Exception {
+    CodedInputStream input = CodedInputStream.newInstance(
+        new SmallBlockInputStream(
+            TestUtil.getAllSet().toByteString().newInput(), 16));
+    input.setSizeLimit(16);
+
+    try {
+      TestAllTypes.parseFrom(input);
+      fail("Should have thrown an exception!");
+    } catch (InvalidProtocolBufferException expected) {
+      checkSizeLimitExceeded(expected);
+    }
+  }
+
+  public void testResetSizeCounter() throws Exception {
+    CodedInputStream input = CodedInputStream.newInstance(
+        new SmallBlockInputStream(new byte[256], 8));
+    input.setSizeLimit(16);
+    input.readRawBytes(16);
+    assertEquals(16, input.getTotalBytesRead());
+
+    try {
+      input.readRawByte();
+      fail("Should have thrown an exception!");
+    } catch (InvalidProtocolBufferException expected) {
+      checkSizeLimitExceeded(expected);
+    }
+
+    input.resetSizeCounter();
+    assertEquals(0, input.getTotalBytesRead());
+    input.readRawByte();  // No exception thrown.
+    input.resetSizeCounter();
+    assertEquals(0, input.getTotalBytesRead());
+    input.readRawBytes(16);
+    assertEquals(16, input.getTotalBytesRead());
+    input.resetSizeCounter();
+
+    try {
+      input.readRawBytes(17);  // Hits limit again.
+      fail("Should have thrown an exception!");
+    } catch (InvalidProtocolBufferException expected) {
+      checkSizeLimitExceeded(expected);
+    }
+  }
+
+  public void testSizeLimitMultipleMessages() throws Exception {
+    byte[] bytes = new byte[256];
+    for (int i = 0; i < bytes.length; i++) {
+      bytes[i] = (byte) i;
+    }
+    CodedInputStream input = CodedInputStream.newInstance(
+        new SmallBlockInputStream(bytes, 7));
+    input.setSizeLimit(16);
+    for (int i = 0; i < 256 / 16; i++) {
+      byte[] message = input.readRawBytes(16);
+      for (int j = 0; j < message.length; j++) {
+        assertEquals(i * 16 + j, message[j] & 0xff);
+      }
+      assertEquals(16, input.getTotalBytesRead());
+      input.resetSizeCounter();
+      assertEquals(0, input.getTotalBytesRead());
+    }
+  }
+
+  /**
+   * Tests that if we readString invalid UTF-8 bytes, no exception
+   * is thrown.  Instead, the invalid bytes are replaced with the Unicode
+   * "replacement character" U+FFFD.
+   */
+  public void testReadStringInvalidUtf8() throws Exception {
+    ByteString.Output rawOutput = ByteString.newOutput();
+    CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+
+    int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+    output.writeRawVarint32(tag);
+    output.writeRawVarint32(1);
+    output.writeRawBytes(new byte[] { (byte) 0x80 });
+    output.flush();
+
+    CodedInputStream input = rawOutput.toByteString().newCodedInput();
+    assertEquals(tag, input.readTag());
+    String text = input.readString();
+    assertEquals(0xfffd, text.charAt(0));
+  }
+
+  /**
+   * Tests that if we readStringRequireUtf8 invalid UTF-8 bytes, an
+   * InvalidProtocolBufferException is thrown.
+   */
+  public void testReadStringRequireUtf8InvalidUtf8() throws Exception {
+    ByteString.Output rawOutput = ByteString.newOutput();
+    CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+
+    int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
+    output.writeRawVarint32(tag);
+    output.writeRawVarint32(1);
+    output.writeRawBytes(new byte[] { (byte) 0x80 });
+    output.flush();
+
+    CodedInputStream input = rawOutput.toByteString().newCodedInput();
+    assertEquals(tag, input.readTag());
+    try {
+      input.readStringRequireUtf8();
+      fail("Expected invalid UTF-8 exception.");
+    } catch (InvalidProtocolBufferException exception) {
+      assertEquals("Protocol message had invalid UTF-8.", exception.getMessage());
+    }
+  }
+
+  public void testReadFromSlice() throws Exception {
+    byte[] bytes = bytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+    CodedInputStream in = CodedInputStream.newInstance(bytes, 3, 5);
+    assertEquals(0, in.getTotalBytesRead());
+    for (int i = 3; i < 8; i++) {
+      assertEquals(i, in.readRawByte());
+      assertEquals(i - 2, in.getTotalBytesRead());
+    }
+    // eof
+    assertEquals(0, in.readTag());
+    assertEquals(5, in.getTotalBytesRead());
+  }
+
+  public void testInvalidTag() throws Exception {
+    // Any tag number which corresponds to field number zero is invalid and
+    // should throw InvalidProtocolBufferException.
+    for (int i = 0; i < 8; i++) {
+      try {
+        CodedInputStream.newInstance(bytes(i)).readTag();
+        fail("Should have thrown an exception.");
+      } catch (InvalidProtocolBufferException e) {
+        assertEquals(InvalidProtocolBufferException.invalidTag().getMessage(),
+                     e.getMessage());
+      }
+    }
+  }
+
+  public void testReadByteArray() throws Exception {
+    ByteString.Output rawOutput = ByteString.newOutput();
+    CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+    // Zero-sized bytes field.
+    output.writeRawVarint32(0);
+    // One one-byte bytes field
+    output.writeRawVarint32(1);
+    output.writeRawBytes(new byte[] { (byte) 23 });
+    // Another one-byte bytes field
+    output.writeRawVarint32(1);
+    output.writeRawBytes(new byte[] { (byte) 45 });
+    // A bytes field large enough that won't fit into the 4K buffer.
+    final int bytesLength = 16 * 1024;
+    byte[] bytes = new byte[bytesLength];
+    bytes[0] = (byte) 67;
+    bytes[bytesLength - 1] = (byte) 89;
+    output.writeRawVarint32(bytesLength);
+    output.writeRawBytes(bytes);
+
+    output.flush();
+    CodedInputStream inputStream = rawOutput.toByteString().newCodedInput();
+
+    byte[] result = inputStream.readByteArray();
+    assertEquals(0, result.length);
+    result = inputStream.readByteArray();
+    assertEquals(1, result.length);
+    assertEquals((byte) 23, result[0]);
+    result = inputStream.readByteArray();
+    assertEquals(1, result.length);
+    assertEquals((byte) 45, result[0]);
+    result = inputStream.readByteArray();
+    assertEquals(bytesLength, result.length);
+    assertEquals((byte) 67, result[0]);
+    assertEquals((byte) 89, result[bytesLength - 1]);
+  }
+
+  public void testReadByteBuffer() throws Exception {
+    ByteString.Output rawOutput = ByteString.newOutput();
+    CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+    // Zero-sized bytes field.
+    output.writeRawVarint32(0);
+    // One one-byte bytes field
+    output.writeRawVarint32(1);
+    output.writeRawBytes(new byte[]{(byte) 23});
+    // Another one-byte bytes field
+    output.writeRawVarint32(1);
+    output.writeRawBytes(new byte[]{(byte) 45});
+    // A bytes field large enough that won't fit into the 4K buffer.
+    final int bytesLength = 16 * 1024;
+    byte[] bytes = new byte[bytesLength];
+    bytes[0] = (byte) 67;
+    bytes[bytesLength - 1] = (byte) 89;
+    output.writeRawVarint32(bytesLength);
+    output.writeRawBytes(bytes);
+
+    output.flush();
+    CodedInputStream inputStream = rawOutput.toByteString().newCodedInput();
+
+    ByteBuffer result = inputStream.readByteBuffer();
+    assertEquals(0, result.capacity());
+    result = inputStream.readByteBuffer();
+    assertEquals(1, result.capacity());
+    assertEquals((byte) 23, result.get());
+    result = inputStream.readByteBuffer();
+    assertEquals(1, result.capacity());
+    assertEquals((byte) 45, result.get());
+    result = inputStream.readByteBuffer();
+    assertEquals(bytesLength, result.capacity());
+    assertEquals((byte) 67, result.get());
+    result.position(bytesLength - 1);
+    assertEquals((byte) 89, result.get());
+  }
+
+  public void testReadByteBufferAliasing() throws Exception {
+    ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
+    CodedOutputStream output = CodedOutputStream.newInstance(byteArrayStream);
+    // Zero-sized bytes field.
+    output.writeRawVarint32(0);
+    // One one-byte bytes field
+    output.writeRawVarint32(1);
+    output.writeRawBytes(new byte[]{(byte) 23});
+    // Another one-byte bytes field
+    output.writeRawVarint32(1);
+    output.writeRawBytes(new byte[]{(byte) 45});
+    // A bytes field large enough that won't fit into the 4K buffer.
+    final int bytesLength = 16 * 1024;
+    byte[] bytes = new byte[bytesLength];
+    bytes[0] = (byte) 67;
+    bytes[bytesLength - 1] = (byte) 89;
+    output.writeRawVarint32(bytesLength);
+    output.writeRawBytes(bytes);
+    output.flush();
+    byte[] data = byteArrayStream.toByteArray();
+
+    // Without aliasing
+    CodedInputStream inputStream = CodedInputStream.newInstance(data);
+    ByteBuffer result = inputStream.readByteBuffer();
+    assertEquals(0, result.capacity());
+    result = inputStream.readByteBuffer();
+    assertTrue(result.array() != data);
+    assertEquals(1, result.capacity());
+    assertEquals((byte) 23, result.get());
+    result = inputStream.readByteBuffer();
+    assertTrue(result.array() != data);
+    assertEquals(1, result.capacity());
+    assertEquals((byte) 45, result.get());
+    result = inputStream.readByteBuffer();
+    assertTrue(result.array() != data);
+    assertEquals(bytesLength, result.capacity());
+    assertEquals((byte) 67, result.get());
+    result.position(bytesLength - 1);
+    assertEquals((byte) 89, result.get());
+
+    // Enable aliasing
+    inputStream = CodedInputStream.newInstance(data);
+    inputStream.enableAliasing(true);
+    result = inputStream.readByteBuffer();
+    assertEquals(0, result.capacity());
+    result = inputStream.readByteBuffer();
+    assertTrue(result.array() == data);
+    assertEquals(1, result.capacity());
+    assertEquals((byte) 23, result.get());
+    result = inputStream.readByteBuffer();
+    assertTrue(result.array() == data);
+    assertEquals(1, result.capacity());
+    assertEquals((byte) 45, result.get());
+    result = inputStream.readByteBuffer();
+    assertTrue(result.array() == data);
+    assertEquals(bytesLength, result.capacity());
+    assertEquals((byte) 67, result.get());
+    result.position(bytesLength - 1);
+    assertEquals((byte) 89, result.get());
+  }
+
+  public void testCompatibleTypes() throws Exception {
+    long data = 0x100000000L;
+    Int64Message message = Int64Message.newBuilder().setData(data).build();
+    ByteString serialized = message.toByteString();
+
+    // Test int64(long) is compatible with bool(boolean)
+    BoolMessage msg2 = BoolMessage.parseFrom(serialized);
+    assertTrue(msg2.getData());
+
+    // Test int64(long) is compatible with int32(int)
+    Int32Message msg3 = Int32Message.parseFrom(serialized);
+    assertEquals((int) data, msg3.getData());
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/protobuf/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
new file mode 100644
index 0000000..0785cc9
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/CodedOutputStreamTest.java
@@ -0,0 +1,401 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.SparseEnumMessage;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestSparseEnum;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Unit test for {@link CodedOutputStream}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class CodedOutputStreamTest extends TestCase {
+  /**
+   * Helper to construct a byte array from a bunch of bytes.  The inputs are
+   * actually ints so that I can use hex notation and not get stupid errors
+   * about precision.
+   */
+  private byte[] bytes(int... bytesAsInts) {
+    byte[] bytes = new byte[bytesAsInts.length];
+    for (int i = 0; i < bytesAsInts.length; i++) {
+      bytes[i] = (byte) bytesAsInts[i];
+    }
+    return bytes;
+  }
+
+  /** Arrays.asList() does not work with arrays of primitives.  :( */
+  private List<Byte> toList(byte[] bytes) {
+    List<Byte> result = new ArrayList<Byte>();
+    for (byte b : bytes) {
+      result.add(b);
+    }
+    return result;
+  }
+
+  private void assertEqualBytes(byte[] a, byte[] b) {
+    assertEquals(toList(a), toList(b));
+  }
+
+  /**
+   * Writes the given value using writeRawVarint32() and writeRawVarint64() and
+   * checks that the result matches the given bytes.
+   */
+  private void assertWriteVarint(byte[] data, long value) throws Exception {
+    // Only do 32-bit write if the value fits in 32 bits.
+    if ((value >>> 32) == 0) {
+      ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+      CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+      output.writeRawVarint32((int) value);
+      output.flush();
+      assertEqualBytes(data, rawOutput.toByteArray());
+
+      // Also try computing size.
+      assertEquals(data.length,
+                   CodedOutputStream.computeRawVarint32Size((int) value));
+    }
+
+    {
+      ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+      CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+      output.writeRawVarint64(value);
+      output.flush();
+      assertEqualBytes(data, rawOutput.toByteArray());
+
+      // Also try computing size.
+      assertEquals(data.length,
+                   CodedOutputStream.computeRawVarint64Size(value));
+    }
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+      // Only do 32-bit write if the value fits in 32 bits.
+      if ((value >>> 32) == 0) {
+        ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+        CodedOutputStream output =
+          CodedOutputStream.newInstance(rawOutput, blockSize);
+        output.writeRawVarint32((int) value);
+        output.flush();
+        assertEqualBytes(data, rawOutput.toByteArray());
+      }
+
+      {
+        ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+        CodedOutputStream output =
+          CodedOutputStream.newInstance(rawOutput, blockSize);
+        output.writeRawVarint64(value);
+        output.flush();
+        assertEqualBytes(data, rawOutput.toByteArray());
+      }
+    }
+  }
+
+  /** Tests writeRawVarint32() and writeRawVarint64(). */
+  public void testWriteVarint() throws Exception {
+    assertWriteVarint(bytes(0x00), 0);
+    assertWriteVarint(bytes(0x01), 1);
+    assertWriteVarint(bytes(0x7f), 127);
+    // 14882
+    assertWriteVarint(bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7));
+    // 2961488830
+    assertWriteVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b),
+      (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+      (0x0bL << 28));
+
+    // 64-bit
+    // 7256456126
+    assertWriteVarint(bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b),
+      (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
+      (0x1bL << 28));
+    // 41256202580718336
+    assertWriteVarint(
+      bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49),
+      (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
+      (0x43L << 28) | (0x49L << 35) | (0x24L << 42) | (0x49L << 49));
+    // 11964378330978735131
+    assertWriteVarint(
+      bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01),
+      (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
+      (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
+      (0x05L << 49) | (0x26L << 56) | (0x01L << 63));
+  }
+
+  /**
+   * Parses the given bytes using writeRawLittleEndian32() and checks
+   * that the result matches the given value.
+   */
+  private void assertWriteLittleEndian32(byte[] data, int value)
+                                         throws Exception {
+    ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+    CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+    output.writeRawLittleEndian32(value);
+    output.flush();
+    assertEqualBytes(data, rawOutput.toByteArray());
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+      rawOutput = new ByteArrayOutputStream();
+      output = CodedOutputStream.newInstance(rawOutput, blockSize);
+      output.writeRawLittleEndian32(value);
+      output.flush();
+      assertEqualBytes(data, rawOutput.toByteArray());
+    }
+  }
+
+  /**
+   * Parses the given bytes using writeRawLittleEndian64() and checks
+   * that the result matches the given value.
+   */
+  private void assertWriteLittleEndian64(byte[] data, long value)
+                                         throws Exception {
+    ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+    CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
+    output.writeRawLittleEndian64(value);
+    output.flush();
+    assertEqualBytes(data, rawOutput.toByteArray());
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize <= 16; blockSize *= 2) {
+      rawOutput = new ByteArrayOutputStream();
+      output = CodedOutputStream.newInstance(rawOutput, blockSize);
+      output.writeRawLittleEndian64(value);
+      output.flush();
+      assertEqualBytes(data, rawOutput.toByteArray());
+    }
+  }
+
+  /** Tests writeRawLittleEndian32() and writeRawLittleEndian64(). */
+  public void testWriteLittleEndian() throws Exception {
+    assertWriteLittleEndian32(bytes(0x78, 0x56, 0x34, 0x12), 0x12345678);
+    assertWriteLittleEndian32(bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0);
+
+    assertWriteLittleEndian64(
+      bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12),
+      0x123456789abcdef0L);
+    assertWriteLittleEndian64(
+      bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a),
+      0x9abcdef012345678L);
+  }
+
+  /** Test encodeZigZag32() and encodeZigZag64(). */
+  public void testEncodeZigZag() throws Exception {
+    assertEquals(0, CodedOutputStream.encodeZigZag32( 0));
+    assertEquals(1, CodedOutputStream.encodeZigZag32(-1));
+    assertEquals(2, CodedOutputStream.encodeZigZag32( 1));
+    assertEquals(3, CodedOutputStream.encodeZigZag32(-2));
+    assertEquals(0x7FFFFFFE, CodedOutputStream.encodeZigZag32(0x3FFFFFFF));
+    assertEquals(0x7FFFFFFF, CodedOutputStream.encodeZigZag32(0xC0000000));
+    assertEquals(0xFFFFFFFE, CodedOutputStream.encodeZigZag32(0x7FFFFFFF));
+    assertEquals(0xFFFFFFFF, CodedOutputStream.encodeZigZag32(0x80000000));
+
+    assertEquals(0, CodedOutputStream.encodeZigZag64( 0));
+    assertEquals(1, CodedOutputStream.encodeZigZag64(-1));
+    assertEquals(2, CodedOutputStream.encodeZigZag64( 1));
+    assertEquals(3, CodedOutputStream.encodeZigZag64(-2));
+    assertEquals(0x000000007FFFFFFEL,
+                 CodedOutputStream.encodeZigZag64(0x000000003FFFFFFFL));
+    assertEquals(0x000000007FFFFFFFL,
+                 CodedOutputStream.encodeZigZag64(0xFFFFFFFFC0000000L));
+    assertEquals(0x00000000FFFFFFFEL,
+                 CodedOutputStream.encodeZigZag64(0x000000007FFFFFFFL));
+    assertEquals(0x00000000FFFFFFFFL,
+                 CodedOutputStream.encodeZigZag64(0xFFFFFFFF80000000L));
+    assertEquals(0xFFFFFFFFFFFFFFFEL,
+                 CodedOutputStream.encodeZigZag64(0x7FFFFFFFFFFFFFFFL));
+    assertEquals(0xFFFFFFFFFFFFFFFFL,
+                 CodedOutputStream.encodeZigZag64(0x8000000000000000L));
+
+    // Some easier-to-verify round-trip tests.  The inputs (other than 0, 1, -1)
+    // were chosen semi-randomly via keyboard bashing.
+    assertEquals(0,
+      CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(0)));
+    assertEquals(1,
+      CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(1)));
+    assertEquals(-1,
+      CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-1)));
+    assertEquals(14927,
+      CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(14927)));
+    assertEquals(-3612,
+      CodedOutputStream.encodeZigZag32(CodedInputStream.decodeZigZag32(-3612)));
+
+    assertEquals(0,
+      CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(0)));
+    assertEquals(1,
+      CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(1)));
+    assertEquals(-1,
+      CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-1)));
+    assertEquals(14927,
+      CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(14927)));
+    assertEquals(-3612,
+      CodedOutputStream.encodeZigZag64(CodedInputStream.decodeZigZag64(-3612)));
+
+    assertEquals(856912304801416L,
+      CodedOutputStream.encodeZigZag64(
+        CodedInputStream.decodeZigZag64(
+          856912304801416L)));
+    assertEquals(-75123905439571256L,
+      CodedOutputStream.encodeZigZag64(
+        CodedInputStream.decodeZigZag64(
+          -75123905439571256L)));
+  }
+
+  /** Tests writing a whole message with every field type. */
+  public void testWriteWholeMessage() throws Exception {
+    TestAllTypes message = TestUtil.getAllSet();
+
+    byte[] rawBytes = message.toByteArray();
+    assertEqualBytes(TestUtil.getGoldenMessage().toByteArray(), rawBytes);
+
+    // Try different block sizes.
+    for (int blockSize = 1; blockSize < 256; blockSize *= 2) {
+      ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
+      CodedOutputStream output =
+        CodedOutputStream.newInstance(rawOutput, blockSize);
+      message.writeTo(output);
+      output.flush();
+      assertEqualBytes(rawBytes, rawOutput.toByteArray());
+    }
+  }
+
+  /** Tests writing a whole message with every packed field type. Ensures the
+   * wire format of packed fields is compatible with C++. */
+  public void testWriteWholePackedFieldsMessage() throws Exception {
+    TestPackedTypes message = TestUtil.getPackedSet();
+
+    byte[] rawBytes = message.toByteArray();
+    assertEqualBytes(TestUtil.getGoldenPackedFieldsMessage().toByteArray(),
+                     rawBytes);
+  }
+
+  /** Test writing a message containing a negative enum value. This used to
+   * fail because the size was not properly computed as a sign-extended varint.
+   */
+  public void testWriteMessageWithNegativeEnumValue() throws Exception {
+    SparseEnumMessage message = SparseEnumMessage.newBuilder()
+        .setSparseEnum(TestSparseEnum.SPARSE_E) .build();
+    assertTrue(message.getSparseEnum().getNumber() < 0);
+    byte[] rawBytes = message.toByteArray();
+    SparseEnumMessage message2 = SparseEnumMessage.parseFrom(rawBytes);
+    assertEquals(TestSparseEnum.SPARSE_E, message2.getSparseEnum());
+  }
+
+  /** Test getTotalBytesWritten() */
+  public void testGetTotalBytesWritten() throws Exception {
+    final int BUFFER_SIZE = 4 * 1024;
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(BUFFER_SIZE);
+    CodedOutputStream codedStream = CodedOutputStream.newInstance(outputStream);
+    byte[] value = "abcde".getBytes("UTF-8");
+    for (int i = 0; i < 1024; ++i) {
+      codedStream.writeRawBytes(value, 0, value.length);
+    }
+    // Make sure we have written more bytes than the buffer could hold. This is
+    // to make the test complete.
+    assertTrue(codedStream.getTotalBytesWritten() > BUFFER_SIZE);
+    assertEquals(value.length * 1024, codedStream.getTotalBytesWritten());
+  }
+  
+  public void testWriteToByteBuffer() throws Exception {
+    final int bufferSize = 16 * 1024;
+    ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
+    CodedOutputStream codedStream = CodedOutputStream.newInstance(buffer);
+    // Write raw bytes into the ByteBuffer.
+    final int length1 = 5000;
+    for (int i = 0; i < length1; i++) {
+      codedStream.writeRawByte((byte) 1);
+    }
+    final int length2 = 8 * 1024;
+    byte[] data = new byte[length2];
+    for (int i = 0; i < length2; i++) {
+      data[i] = (byte) 2;
+    }
+    codedStream.writeRawBytes(data);
+    final int length3 = bufferSize - length1 - length2;
+    for (int i = 0; i < length3; i++) {
+      codedStream.writeRawByte((byte) 3);
+    }
+    codedStream.flush();
+    
+    // Check that data is correctly written to the ByteBuffer.
+    assertEquals(0, buffer.remaining());
+    buffer.flip();
+    for (int i = 0; i < length1; i++) {
+      assertEquals((byte) 1, buffer.get());
+    }
+    for (int i = 0; i < length2; i++) {
+      assertEquals((byte) 2, buffer.get());
+    }
+    for (int i = 0; i < length3; i++) {
+      assertEquals((byte) 3, buffer.get());
+    }
+  }
+  
+  public void testWriteByteBuffer() throws Exception {
+    byte[] value = "abcde".getBytes("UTF-8");
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    CodedOutputStream codedStream = CodedOutputStream.newInstance(outputStream);
+    ByteBuffer byteBuffer = ByteBuffer.wrap(value, 0, 1);
+    // This will actually write 5 bytes into the CodedOutputStream as the
+    // ByteBuffer's capacity() is 5.
+    codedStream.writeRawBytes(byteBuffer);
+    // The above call shouldn't affect the ByteBuffer's state.
+    assertEquals(0, byteBuffer.position());
+    assertEquals(1, byteBuffer.limit());
+    
+    // The correct way to write part of an array using ByteBuffer.
+    codedStream.writeRawBytes(ByteBuffer.wrap(value, 2, 1).slice());
+    
+    codedStream.flush();
+    byte[] result = outputStream.toByteArray();
+    assertEquals(6, result.length);
+    for (int i = 0; i < 5; i++) {
+      assertEquals(value[i], result[i]);
+    }
+    assertEquals(value[2], result[5]);
+  }
+
+  public void testWriteByteArrayWithOffsets() throws Exception {
+    byte[] fullArray = bytes(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88);
+    byte[] destination = new byte[4];
+    CodedOutputStream codedStream = CodedOutputStream.newInstance(destination);
+    codedStream.writeByteArrayNoTag(fullArray, 2, 2);
+    assertEqualBytes(bytes(0x02, 0x33, 0x44, 0x00), destination);
+    assertEquals(3, codedStream.getTotalBytesWritten());
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java b/protobuf/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
new file mode 100644
index 0000000..e7905f7
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/DeprecatedFieldTest.java
@@ -0,0 +1,80 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestDeprecatedFields;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Method;
+/**
+ * Test field deprecation
+ * 
+ * @author birdo@google.com (Roberto Scaramuzzi)
+ */
+public class DeprecatedFieldTest extends TestCase {
+  private String[] deprecatedGetterNames = {
+      "hasDeprecatedInt32",
+      "getDeprecatedInt32"};
+  
+  private String[] deprecatedBuilderGetterNames = {
+      "hasDeprecatedInt32",
+      "getDeprecatedInt32",
+      "clearDeprecatedInt32"};
+  
+  private String[] deprecatedBuilderSetterNames = {
+      "setDeprecatedInt32"}; 
+  
+  public void testDeprecatedField() throws Exception {
+    Class<?> deprecatedFields = TestDeprecatedFields.class;
+    Class<?> deprecatedFieldsBuilder = TestDeprecatedFields.Builder.class;
+    for (String name : deprecatedGetterNames) {
+      Method method = deprecatedFields.getMethod(name);
+      assertTrue("Method " + name + " should be deprecated",
+          isDeprecated(method));
+    }
+    for (String name : deprecatedBuilderGetterNames) {
+      Method method = deprecatedFieldsBuilder.getMethod(name);
+      assertTrue("Method " + name + " should be deprecated",
+          isDeprecated(method));
+    }
+    for (String name : deprecatedBuilderSetterNames) {
+      Method method = deprecatedFieldsBuilder.getMethod(name, int.class);
+      assertTrue("Method " + name + " should be deprecated",
+          isDeprecated(method));
+    }
+  }
+  
+  private boolean isDeprecated(AnnotatedElement annotated) {
+    return annotated.isAnnotationPresent(Deprecated.class);
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/DescriptorsTest.java b/protobuf/java/src/test/java/com/google/protobuf/DescriptorsTest.java
new file mode 100644
index 0000000..0092771
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/DescriptorsTest.java
@@ -0,0 +1,735 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.DescriptorProtos.DescriptorProto;
+import com.google.protobuf.DescriptorProtos.EnumDescriptorProto;
+import com.google.protobuf.DescriptorProtos.EnumValueDescriptorProto;
+import com.google.protobuf.DescriptorProtos.FieldDescriptorProto;
+import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
+import com.google.protobuf.Descriptors.DescriptorValidationException;
+import com.google.protobuf.Descriptors.FileDescriptor;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.OneofDescriptor;
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.ServiceDescriptor;
+import com.google.protobuf.Descriptors.MethodDescriptor;
+
+import com.google.protobuf.test.UnittestImport;
+import com.google.protobuf.test.UnittestImport.ImportEnum;
+import com.google.protobuf.test.UnittestImport.ImportMessage;
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
+import protobuf_unittest.UnittestProto.TestMultipleExtensionRanges;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestService;
+import protobuf_unittest.UnittestCustomOptions;
+
+import protobuf_unittest.TestCustomOptions;
+
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Unit test for {@link Descriptors}.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class DescriptorsTest extends TestCase {
+
+  // Regression test for bug where referencing a FieldDescriptor.Type value
+  // before a FieldDescriptorProto.Type value would yield a
+  // ExceptionInInitializerError.
+  @SuppressWarnings("unused")
+  private static final Object STATIC_INIT_TEST = FieldDescriptor.Type.BOOL;
+
+  public void testFieldTypeEnumMapping() throws Exception {
+    assertEquals(FieldDescriptor.Type.values().length,
+        FieldDescriptorProto.Type.values().length);
+    for (FieldDescriptor.Type type : FieldDescriptor.Type.values()) {
+      FieldDescriptorProto.Type protoType = type.toProto();
+      assertEquals("TYPE_" + type.name(), protoType.name());
+      assertEquals(type, FieldDescriptor.Type.valueOf(protoType));
+    }
+  }
+
+  public void testFileDescriptor() throws Exception {
+    FileDescriptor file = UnittestProto.getDescriptor();
+
+    assertEquals("google/protobuf/unittest.proto", file.getName());
+    assertEquals("protobuf_unittest", file.getPackage());
+
+    assertEquals("UnittestProto", file.getOptions().getJavaOuterClassname());
+    assertEquals("google/protobuf/unittest.proto",
+                 file.toProto().getName());
+
+    assertEquals(Arrays.asList(UnittestImport.getDescriptor()),
+                 file.getDependencies());
+
+    Descriptor messageType = TestAllTypes.getDescriptor();
+    assertEquals(messageType, file.getMessageTypes().get(0));
+    assertEquals(messageType, file.findMessageTypeByName("TestAllTypes"));
+    assertNull(file.findMessageTypeByName("NoSuchType"));
+    assertNull(file.findMessageTypeByName("protobuf_unittest.TestAllTypes"));
+    for (int i = 0; i < file.getMessageTypes().size(); i++) {
+      assertEquals(i, file.getMessageTypes().get(i).getIndex());
+    }
+
+    EnumDescriptor enumType = ForeignEnum.getDescriptor();
+    assertEquals(enumType, file.getEnumTypes().get(0));
+    assertEquals(enumType, file.findEnumTypeByName("ForeignEnum"));
+    assertNull(file.findEnumTypeByName("NoSuchType"));
+    assertNull(file.findEnumTypeByName("protobuf_unittest.ForeignEnum"));
+    assertEquals(Arrays.asList(ImportEnum.getDescriptor()),
+                 UnittestImport.getDescriptor().getEnumTypes());
+    for (int i = 0; i < file.getEnumTypes().size(); i++) {
+      assertEquals(i, file.getEnumTypes().get(i).getIndex());
+    }
+
+    ServiceDescriptor service = TestService.getDescriptor();
+    assertEquals(service, file.getServices().get(0));
+    assertEquals(service, file.findServiceByName("TestService"));
+    assertNull(file.findServiceByName("NoSuchType"));
+    assertNull(file.findServiceByName("protobuf_unittest.TestService"));
+    assertEquals(Collections.emptyList(),
+                 UnittestImport.getDescriptor().getServices());
+    for (int i = 0; i < file.getServices().size(); i++) {
+      assertEquals(i, file.getServices().get(i).getIndex());
+    }
+
+    FieldDescriptor extension =
+      UnittestProto.optionalInt32Extension.getDescriptor();
+    assertEquals(extension, file.getExtensions().get(0));
+    assertEquals(extension,
+                 file.findExtensionByName("optional_int32_extension"));
+    assertNull(file.findExtensionByName("no_such_ext"));
+    assertNull(file.findExtensionByName(
+      "protobuf_unittest.optional_int32_extension"));
+    assertEquals(Collections.emptyList(),
+                 UnittestImport.getDescriptor().getExtensions());
+    for (int i = 0; i < file.getExtensions().size(); i++) {
+      assertEquals(i, file.getExtensions().get(i).getIndex());
+    }
+  }
+
+  public void testDescriptor() throws Exception {
+    Descriptor messageType = TestAllTypes.getDescriptor();
+    Descriptor nestedType = TestAllTypes.NestedMessage.getDescriptor();
+
+    assertEquals("TestAllTypes", messageType.getName());
+    assertEquals("protobuf_unittest.TestAllTypes", messageType.getFullName());
+    assertEquals(UnittestProto.getDescriptor(), messageType.getFile());
+    assertNull(messageType.getContainingType());
+    assertEquals(DescriptorProtos.MessageOptions.getDefaultInstance(),
+                 messageType.getOptions());
+    assertEquals("TestAllTypes", messageType.toProto().getName());
+
+    assertEquals("NestedMessage", nestedType.getName());
+    assertEquals("protobuf_unittest.TestAllTypes.NestedMessage",
+                 nestedType.getFullName());
+    assertEquals(UnittestProto.getDescriptor(), nestedType.getFile());
+    assertEquals(messageType, nestedType.getContainingType());
+
+    FieldDescriptor field = messageType.getFields().get(0);
+    assertEquals("optional_int32", field.getName());
+    assertEquals(field, messageType.findFieldByName("optional_int32"));
+    assertNull(messageType.findFieldByName("no_such_field"));
+    assertEquals(field, messageType.findFieldByNumber(1));
+    assertNull(messageType.findFieldByNumber(571283));
+    for (int i = 0; i < messageType.getFields().size(); i++) {
+      assertEquals(i, messageType.getFields().get(i).getIndex());
+    }
+
+    assertEquals(nestedType, messageType.getNestedTypes().get(0));
+    assertEquals(nestedType, messageType.findNestedTypeByName("NestedMessage"));
+    assertNull(messageType.findNestedTypeByName("NoSuchType"));
+    for (int i = 0; i < messageType.getNestedTypes().size(); i++) {
+      assertEquals(i, messageType.getNestedTypes().get(i).getIndex());
+    }
+
+    EnumDescriptor enumType = TestAllTypes.NestedEnum.getDescriptor();
+    assertEquals(enumType, messageType.getEnumTypes().get(0));
+    assertEquals(enumType, messageType.findEnumTypeByName("NestedEnum"));
+    assertNull(messageType.findEnumTypeByName("NoSuchType"));
+    for (int i = 0; i < messageType.getEnumTypes().size(); i++) {
+      assertEquals(i, messageType.getEnumTypes().get(i).getIndex());
+    }
+  }
+
+  public void testFieldDescriptor() throws Exception {
+    Descriptor messageType = TestAllTypes.getDescriptor();
+    FieldDescriptor primitiveField =
+      messageType.findFieldByName("optional_int32");
+    FieldDescriptor enumField =
+      messageType.findFieldByName("optional_nested_enum");
+    FieldDescriptor messageField =
+      messageType.findFieldByName("optional_foreign_message");
+    FieldDescriptor cordField =
+      messageType.findFieldByName("optional_cord");
+    FieldDescriptor extension =
+      UnittestProto.optionalInt32Extension.getDescriptor();
+    FieldDescriptor nestedExtension = TestRequired.single.getDescriptor();
+
+    assertEquals("optional_int32", primitiveField.getName());
+    assertEquals("protobuf_unittest.TestAllTypes.optional_int32",
+                 primitiveField.getFullName());
+    assertEquals(1, primitiveField.getNumber());
+    assertEquals(messageType, primitiveField.getContainingType());
+    assertEquals(UnittestProto.getDescriptor(), primitiveField.getFile());
+    assertEquals(FieldDescriptor.Type.INT32, primitiveField.getType());
+    assertEquals(FieldDescriptor.JavaType.INT, primitiveField.getJavaType());
+    assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(),
+                 primitiveField.getOptions());
+    assertFalse(primitiveField.isExtension());
+    assertEquals("optional_int32", primitiveField.toProto().getName());
+
+    assertEquals("optional_nested_enum", enumField.getName());
+    assertEquals(FieldDescriptor.Type.ENUM, enumField.getType());
+    assertEquals(FieldDescriptor.JavaType.ENUM, enumField.getJavaType());
+    assertEquals(TestAllTypes.NestedEnum.getDescriptor(),
+                 enumField.getEnumType());
+
+    assertEquals("optional_foreign_message", messageField.getName());
+    assertEquals(FieldDescriptor.Type.MESSAGE, messageField.getType());
+    assertEquals(FieldDescriptor.JavaType.MESSAGE, messageField.getJavaType());
+    assertEquals(ForeignMessage.getDescriptor(), messageField.getMessageType());
+
+    assertEquals("optional_cord", cordField.getName());
+    assertEquals(FieldDescriptor.Type.STRING, cordField.getType());
+    assertEquals(FieldDescriptor.JavaType.STRING, cordField.getJavaType());
+    assertEquals(DescriptorProtos.FieldOptions.CType.CORD,
+                 cordField.getOptions().getCtype());
+
+    assertEquals("optional_int32_extension", extension.getName());
+    assertEquals("protobuf_unittest.optional_int32_extension",
+                 extension.getFullName());
+    assertEquals(1, extension.getNumber());
+    assertEquals(TestAllExtensions.getDescriptor(),
+                 extension.getContainingType());
+    assertEquals(UnittestProto.getDescriptor(), extension.getFile());
+    assertEquals(FieldDescriptor.Type.INT32, extension.getType());
+    assertEquals(FieldDescriptor.JavaType.INT, extension.getJavaType());
+    assertEquals(DescriptorProtos.FieldOptions.getDefaultInstance(),
+                 extension.getOptions());
+    assertTrue(extension.isExtension());
+    assertEquals(null, extension.getExtensionScope());
+    assertEquals("optional_int32_extension", extension.toProto().getName());
+
+    assertEquals("single", nestedExtension.getName());
+    assertEquals("protobuf_unittest.TestRequired.single",
+                 nestedExtension.getFullName());
+    assertEquals(TestRequired.getDescriptor(),
+                 nestedExtension.getExtensionScope());
+  }
+
+  public void testFieldDescriptorLabel() throws Exception {
+    FieldDescriptor requiredField =
+      TestRequired.getDescriptor().findFieldByName("a");
+    FieldDescriptor optionalField =
+      TestAllTypes.getDescriptor().findFieldByName("optional_int32");
+    FieldDescriptor repeatedField =
+      TestAllTypes.getDescriptor().findFieldByName("repeated_int32");
+
+    assertTrue(requiredField.isRequired());
+    assertFalse(requiredField.isRepeated());
+    assertFalse(optionalField.isRequired());
+    assertFalse(optionalField.isRepeated());
+    assertFalse(repeatedField.isRequired());
+    assertTrue(repeatedField.isRepeated());
+  }
+
+  public void testFieldDescriptorDefault() throws Exception {
+    Descriptor d = TestAllTypes.getDescriptor();
+    assertFalse(d.findFieldByName("optional_int32").hasDefaultValue());
+    assertEquals(0, d.findFieldByName("optional_int32").getDefaultValue());
+    assertTrue(d.findFieldByName("default_int32").hasDefaultValue());
+    assertEquals(41, d.findFieldByName("default_int32").getDefaultValue());
+
+    d = TestExtremeDefaultValues.getDescriptor();
+    assertEquals(
+      ByteString.copyFrom(
+        "\0\001\007\b\f\n\r\t\013\\\'\"\u00fe".getBytes("ISO-8859-1")),
+      d.findFieldByName("escaped_bytes").getDefaultValue());
+    assertEquals(-1, d.findFieldByName("large_uint32").getDefaultValue());
+    assertEquals(-1L, d.findFieldByName("large_uint64").getDefaultValue());
+  }
+
+  public void testEnumDescriptor() throws Exception {
+    EnumDescriptor enumType = ForeignEnum.getDescriptor();
+    EnumDescriptor nestedType = TestAllTypes.NestedEnum.getDescriptor();
+
+    assertEquals("ForeignEnum", enumType.getName());
+    assertEquals("protobuf_unittest.ForeignEnum", enumType.getFullName());
+    assertEquals(UnittestProto.getDescriptor(), enumType.getFile());
+    assertNull(enumType.getContainingType());
+    assertEquals(DescriptorProtos.EnumOptions.getDefaultInstance(),
+                 enumType.getOptions());
+
+    assertEquals("NestedEnum", nestedType.getName());
+    assertEquals("protobuf_unittest.TestAllTypes.NestedEnum",
+                 nestedType.getFullName());
+    assertEquals(UnittestProto.getDescriptor(), nestedType.getFile());
+    assertEquals(TestAllTypes.getDescriptor(), nestedType.getContainingType());
+
+    EnumValueDescriptor value = ForeignEnum.FOREIGN_FOO.getValueDescriptor();
+    assertEquals(value, enumType.getValues().get(0));
+    assertEquals("FOREIGN_FOO", value.getName());
+    assertEquals("FOREIGN_FOO", value.toString());
+    assertEquals(4, value.getNumber());
+    assertEquals(value, enumType.findValueByName("FOREIGN_FOO"));
+    assertEquals(value, enumType.findValueByNumber(4));
+    assertNull(enumType.findValueByName("NO_SUCH_VALUE"));
+    for (int i = 0; i < enumType.getValues().size(); i++) {
+      assertEquals(i, enumType.getValues().get(i).getIndex());
+    }
+  }
+
+  public void testServiceDescriptor() throws Exception {
+    ServiceDescriptor service = TestService.getDescriptor();
+
+    assertEquals("TestService", service.getName());
+    assertEquals("protobuf_unittest.TestService", service.getFullName());
+    assertEquals(UnittestProto.getDescriptor(), service.getFile());
+
+
+    MethodDescriptor fooMethod = service.getMethods().get(0);
+    assertEquals("Foo", fooMethod.getName());
+    assertEquals(UnittestProto.FooRequest.getDescriptor(),
+                 fooMethod.getInputType());
+    assertEquals(UnittestProto.FooResponse.getDescriptor(),
+                 fooMethod.getOutputType());
+    assertEquals(fooMethod, service.findMethodByName("Foo"));
+
+    MethodDescriptor barMethod = service.getMethods().get(1);
+    assertEquals("Bar", barMethod.getName());
+    assertEquals(UnittestProto.BarRequest.getDescriptor(),
+                 barMethod.getInputType());
+    assertEquals(UnittestProto.BarResponse.getDescriptor(),
+                 barMethod.getOutputType());
+    assertEquals(barMethod, service.findMethodByName("Bar"));
+
+    assertNull(service.findMethodByName("NoSuchMethod"));
+
+    for (int i = 0; i < service.getMethods().size(); i++) {
+      assertEquals(i, service.getMethods().get(i).getIndex());
+    }
+  }
+
+
+  public void testCustomOptions() throws Exception {
+    // Get the descriptor indirectly from a dependent proto class. This is to
+    // ensure that when a proto class is loaded, custom options defined in its
+    // dependencies are also properly initialized.
+    Descriptor descriptor =
+        TestCustomOptions.TestMessageWithCustomOptionsContainer.getDescriptor()
+        .findFieldByName("field").getMessageType();
+
+    assertTrue(
+      descriptor.getOptions().hasExtension(UnittestCustomOptions.messageOpt1));
+    assertEquals(Integer.valueOf(-56),
+      descriptor.getOptions().getExtension(UnittestCustomOptions.messageOpt1));
+
+    FieldDescriptor field = descriptor.findFieldByName("field1");
+    assertNotNull(field);
+
+    assertTrue(
+      field.getOptions().hasExtension(UnittestCustomOptions.fieldOpt1));
+    assertEquals(Long.valueOf(8765432109L),
+      field.getOptions().getExtension(UnittestCustomOptions.fieldOpt1));
+
+    EnumDescriptor enumType =
+      UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor();
+
+    assertTrue(
+      enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1));
+    assertEquals(Integer.valueOf(-789),
+      enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1));
+
+    ServiceDescriptor service =
+      UnittestCustomOptions.TestServiceWithCustomOptions.getDescriptor();
+
+    assertTrue(
+      service.getOptions().hasExtension(UnittestCustomOptions.serviceOpt1));
+    assertEquals(Long.valueOf(-9876543210L),
+      service.getOptions().getExtension(UnittestCustomOptions.serviceOpt1));
+
+    MethodDescriptor method = service.findMethodByName("Foo");
+    assertNotNull(method);
+
+    assertTrue(
+      method.getOptions().hasExtension(UnittestCustomOptions.methodOpt1));
+    assertEquals(UnittestCustomOptions.MethodOpt1.METHODOPT1_VAL2,
+      method.getOptions().getExtension(UnittestCustomOptions.methodOpt1));
+  }
+
+  /**
+   * Test that the FieldDescriptor.Type enum is the same as the
+   * WireFormat.FieldType enum.
+   */
+  public void testFieldTypeTablesMatch() throws Exception {
+    FieldDescriptor.Type[] values1 = FieldDescriptor.Type.values();
+    WireFormat.FieldType[] values2 = WireFormat.FieldType.values();
+
+    assertEquals(values1.length, values2.length);
+
+    for (int i = 0; i < values1.length; i++) {
+      assertEquals(values1[i].toString(), values2[i].toString());
+    }
+  }
+
+  /**
+   * Test that the FieldDescriptor.JavaType enum is the same as the
+   * WireFormat.JavaType enum.
+   */
+  public void testJavaTypeTablesMatch() throws Exception {
+    FieldDescriptor.JavaType[] values1 = FieldDescriptor.JavaType.values();
+    WireFormat.JavaType[] values2 = WireFormat.JavaType.values();
+
+    assertEquals(values1.length, values2.length);
+
+    for (int i = 0; i < values1.length; i++) {
+      assertEquals(values1[i].toString(), values2[i].toString());
+    }
+  }
+
+  public void testEnormousDescriptor() throws Exception {
+    // The descriptor for this file is larger than 64k, yet it did not cause
+    // a compiler error due to an over-long string literal.
+    assertTrue(
+        UnittestEnormousDescriptor.getDescriptor()
+          .toProto().getSerializedSize() > 65536);
+  }
+
+  /**
+   * Tests that the DescriptorValidationException works as intended.
+   */
+  public void testDescriptorValidatorException() throws Exception {
+    FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder()
+      .setName("foo.proto")
+      .addMessageType(DescriptorProto.newBuilder()
+      .setName("Foo")
+        .addField(FieldDescriptorProto.newBuilder()
+          .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+          .setType(FieldDescriptorProto.Type.TYPE_INT32)
+          .setName("foo")
+          .setNumber(1)
+          .setDefaultValue("invalid")
+          .build())
+        .build())
+      .build();
+    try {
+      Descriptors.FileDescriptor.buildFrom(fileDescriptorProto,
+          new FileDescriptor[0]);
+      fail("DescriptorValidationException expected");
+    } catch (DescriptorValidationException e) {
+      // Expected; check that the error message contains some useful hints
+      assertTrue(e.getMessage().indexOf("foo") != -1);
+      assertTrue(e.getMessage().indexOf("Foo") != -1);
+      assertTrue(e.getMessage().indexOf("invalid") != -1);
+      assertTrue(e.getCause() instanceof NumberFormatException);
+      assertTrue(e.getCause().getMessage().indexOf("invalid") != -1);
+    }
+  }
+
+  /**
+   * Tests the translate/crosslink for an example where a message field's name
+   * and type name are the same.
+   */
+  public void testDescriptorComplexCrosslink() throws Exception {
+    FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder()
+      .setName("foo.proto")
+      .addMessageType(DescriptorProto.newBuilder()
+        .setName("Foo")
+        .addField(FieldDescriptorProto.newBuilder()
+          .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+          .setType(FieldDescriptorProto.Type.TYPE_INT32)
+          .setName("foo")
+          .setNumber(1)
+          .build())
+        .build())
+      .addMessageType(DescriptorProto.newBuilder()
+        .setName("Bar")
+        .addField(FieldDescriptorProto.newBuilder()
+          .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+          .setTypeName("Foo")
+          .setName("Foo")
+          .setNumber(1)
+          .build())
+        .build())
+      .build();
+    // translate and crosslink
+    FileDescriptor file =
+      Descriptors.FileDescriptor.buildFrom(fileDescriptorProto, 
+          new FileDescriptor[0]);
+    // verify resulting descriptors
+    assertNotNull(file);
+    List<Descriptor> msglist = file.getMessageTypes();
+    assertNotNull(msglist);
+    assertTrue(msglist.size() == 2);
+    boolean barFound = false;
+    for (Descriptor desc : msglist) {
+      if (desc.getName().equals("Bar")) {
+        barFound = true;
+        assertNotNull(desc.getFields());
+        List<FieldDescriptor> fieldlist = desc.getFields();
+        assertNotNull(fieldlist);
+        assertTrue(fieldlist.size() == 1);
+        assertTrue(fieldlist.get(0).getType() == FieldDescriptor.Type.MESSAGE);
+        assertTrue(fieldlist.get(0).getMessageType().getName().equals("Foo"));
+      }
+    }
+    assertTrue(barFound);
+  }
+  
+  public void testDependencyOrder() throws Exception {
+    FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+        .setName("foo.proto").build();
+    FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
+        .setName("bar.proto")
+        .addDependency("foo.proto")
+        .build();
+    FileDescriptorProto bazProto = FileDescriptorProto.newBuilder()
+        .setName("baz.proto")
+        .addDependency("foo.proto")
+        .addDependency("bar.proto")
+        .addPublicDependency(0)
+        .addPublicDependency(1)
+        .build();
+    FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom(fooProto,
+        new FileDescriptor[0]);
+    FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(barProto,
+        new FileDescriptor[] {fooFile});
+    
+    // Items in the FileDescriptor array can be in any order. 
+    Descriptors.FileDescriptor.buildFrom(bazProto,
+        new FileDescriptor[] {fooFile, barFile});
+    Descriptors.FileDescriptor.buildFrom(bazProto,
+        new FileDescriptor[] {barFile, fooFile});
+  }
+  
+  public void testInvalidPublicDependency() throws Exception {
+    FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+        .setName("foo.proto").build();
+    FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
+        .setName("boo.proto")
+        .addDependency("foo.proto")
+        .addPublicDependency(1)  // Error, should be 0.
+        .build();
+    FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom(fooProto,
+        new FileDescriptor[0]);
+    try {
+      Descriptors.FileDescriptor.buildFrom(barProto,
+          new FileDescriptor[] {fooFile});
+      fail("DescriptorValidationException expected");
+    } catch (DescriptorValidationException e) {
+      assertTrue(
+          e.getMessage().indexOf("Invalid public dependency index.") != -1);
+    }
+  }
+
+  public void testHiddenDependency() throws Exception {
+    FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
+        .setName("bar.proto")
+        .addMessageType(DescriptorProto.newBuilder().setName("Bar"))
+        .build();
+    FileDescriptorProto forwardProto = FileDescriptorProto.newBuilder()
+        .setName("forward.proto")
+        .addDependency("bar.proto")
+        .build();
+    FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+        .setName("foo.proto")
+        .addDependency("forward.proto")
+        .addMessageType(DescriptorProto.newBuilder()
+            .setName("Foo")
+            .addField(FieldDescriptorProto.newBuilder()
+                .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+                .setTypeName("Bar")
+                .setName("bar")
+                .setNumber(1)))
+        .build();
+    FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(
+        barProto, new FileDescriptor[0]);
+    FileDescriptor forwardFile = Descriptors.FileDescriptor.buildFrom(
+        forwardProto, new FileDescriptor[] {barFile});
+
+    try {
+      Descriptors.FileDescriptor.buildFrom(
+          fooProto, new FileDescriptor[] {forwardFile});
+      fail("DescriptorValidationException expected");
+    } catch (DescriptorValidationException e) {
+      assertTrue(e.getMessage().indexOf("Bar") != -1);
+      assertTrue(e.getMessage().indexOf("is not defined") != -1);
+    }
+  }
+
+  public void testPublicDependency() throws Exception {
+    FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
+        .setName("bar.proto")
+        .addMessageType(DescriptorProto.newBuilder().setName("Bar"))
+        .build();
+    FileDescriptorProto forwardProto = FileDescriptorProto.newBuilder()
+        .setName("forward.proto")
+        .addDependency("bar.proto")
+        .addPublicDependency(0)
+        .build();
+    FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+        .setName("foo.proto")
+        .addDependency("forward.proto")
+        .addMessageType(DescriptorProto.newBuilder()
+            .setName("Foo")
+            .addField(FieldDescriptorProto.newBuilder()
+                .setLabel(FieldDescriptorProto.Label.LABEL_OPTIONAL)
+                .setTypeName("Bar")
+                .setName("bar")
+                .setNumber(1)))
+        .build();
+    FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(
+        barProto, new FileDescriptor[0]);
+    FileDescriptor forwardFile = Descriptors.FileDescriptor.buildFrom(
+        forwardProto, new FileDescriptor[]{barFile});
+    Descriptors.FileDescriptor.buildFrom(
+        fooProto, new FileDescriptor[] {forwardFile});
+  }
+  
+  /**
+   * Tests the translate/crosslink for an example with a more complex namespace
+   * referencing.
+   */
+  public void testComplexNamespacePublicDependency() throws Exception {
+    FileDescriptorProto fooProto = FileDescriptorProto.newBuilder()
+        .setName("bar.proto")
+        .setPackage("a.b.c.d.bar.shared")
+        .addEnumType(EnumDescriptorProto.newBuilder()
+            .setName("MyEnum")
+            .addValue(EnumValueDescriptorProto.newBuilder()
+                .setName("BLAH")
+                .setNumber(1)))
+        .build();
+    FileDescriptorProto barProto = FileDescriptorProto.newBuilder()
+        .setName("foo.proto")
+        .addDependency("bar.proto")
+        .setPackage("a.b.c.d.foo.shared")
+        .addMessageType(DescriptorProto.newBuilder()
+            .setName("MyMessage")
+            .addField(FieldDescriptorProto.newBuilder()
+                .setLabel(FieldDescriptorProto.Label.LABEL_REPEATED)
+                .setTypeName("bar.shared.MyEnum")
+                .setName("MyField")
+                .setNumber(1)))
+        .build();
+    // translate and crosslink
+    FileDescriptor fooFile = Descriptors.FileDescriptor.buildFrom(
+        fooProto, new FileDescriptor[0]);
+    FileDescriptor barFile = Descriptors.FileDescriptor.buildFrom(
+        barProto, new FileDescriptor[]{fooFile});
+    // verify resulting descriptors
+    assertNotNull(barFile);
+    List<Descriptor> msglist = barFile.getMessageTypes();
+    assertNotNull(msglist);
+    assertTrue(msglist.size() == 1);
+    Descriptor desc = msglist.get(0);
+    if (desc.getName().equals("MyMessage")) {
+      assertNotNull(desc.getFields());
+      List<FieldDescriptor> fieldlist = desc.getFields();
+      assertNotNull(fieldlist);
+      assertTrue(fieldlist.size() == 1);
+      FieldDescriptor field = fieldlist.get(0);
+      assertTrue(field.getType() == FieldDescriptor.Type.ENUM);
+      assertTrue(field.getEnumType().getName().equals("MyEnum"));
+      assertTrue(field.getEnumType().getFile().getName().equals("bar.proto"));
+      assertTrue(field.getEnumType().getFile().getPackage().equals(
+          "a.b.c.d.bar.shared"));
+    }   
+  }
+
+  public void testOneofDescriptor() throws Exception {
+    Descriptor messageType = TestAllTypes.getDescriptor();
+    FieldDescriptor field =
+        messageType.findFieldByName("oneof_nested_message");
+    OneofDescriptor oneofDescriptor = field.getContainingOneof();
+    assertNotNull(oneofDescriptor);
+    assertSame(oneofDescriptor, messageType.getOneofs().get(0));
+    assertEquals("oneof_field", oneofDescriptor.getName());
+
+    assertEquals(4, oneofDescriptor.getFieldCount());
+    assertSame(oneofDescriptor.getField(1), field);
+  }
+
+  public void testMessageDescriptorExtensions() throws Exception {
+    assertFalse(TestAllTypes.getDescriptor().isExtendable());
+    assertTrue(TestAllExtensions.getDescriptor().isExtendable());
+    assertTrue(TestMultipleExtensionRanges.getDescriptor().isExtendable());
+
+    assertFalse(TestAllTypes.getDescriptor().isExtensionNumber(3));
+    assertTrue(TestAllExtensions.getDescriptor().isExtensionNumber(3));
+    assertTrue(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(42));
+    assertFalse(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(43));
+    assertFalse(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(4142));
+    assertTrue(TestMultipleExtensionRanges.getDescriptor().isExtensionNumber(4143));
+  }
+
+  public void testPackedEnumField() throws Exception {
+    FileDescriptorProto fileDescriptorProto = FileDescriptorProto.newBuilder()
+        .setName("foo.proto")
+        .addEnumType(EnumDescriptorProto.newBuilder()
+          .setName("Enum")
+          .addValue(EnumValueDescriptorProto.newBuilder()
+            .setName("FOO")
+            .setNumber(1)
+            .build())
+          .build())
+        .addMessageType(DescriptorProto.newBuilder()
+          .setName("Message")
+          .addField(FieldDescriptorProto.newBuilder()
+            .setName("foo")
+            .setTypeName("Enum")
+            .setNumber(1)
+            .setLabel(FieldDescriptorProto.Label.LABEL_REPEATED)
+            .setOptions(DescriptorProtos.FieldOptions.newBuilder()
+              .setPacked(true)
+              .build())
+            .build())
+          .build())
+        .build();
+    Descriptors.FileDescriptor.buildFrom(
+        fileDescriptorProto, new FileDescriptor[0]);
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/DynamicMessageTest.java b/protobuf/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
new file mode 100644
index 0000000..55144e7
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/DynamicMessageTest.java
@@ -0,0 +1,326 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.Descriptors.OneofDescriptor;
+
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestEmptyMessage;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+
+import junit.framework.TestCase;
+import java.util.Arrays;
+
+/**
+ * Unit test for {@link DynamicMessage}.  See also {@link MessageTest}, which
+ * tests some {@link DynamicMessage} functionality.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class DynamicMessageTest extends TestCase {
+  TestUtil.ReflectionTester reflectionTester =
+    new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
+
+  TestUtil.ReflectionTester extensionsReflectionTester =
+    new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
+                                  TestUtil.getExtensionRegistry());
+  TestUtil.ReflectionTester packedReflectionTester =
+    new TestUtil.ReflectionTester(TestPackedTypes.getDescriptor(), null);
+
+  public void testDynamicMessageAccessors() throws Exception {
+    Message.Builder builder =
+      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    reflectionTester.setAllFieldsViaReflection(builder);
+    Message message = builder.build();
+    reflectionTester.assertAllFieldsSetViaReflection(message);
+  }
+
+  public void testSettersAfterBuild() throws Exception {
+    Message.Builder builder =
+      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    Message firstMessage = builder.build();
+    // double build()
+    builder.build();
+    // clear() after build()
+    builder.clear();
+    // setters after build()
+    reflectionTester.setAllFieldsViaReflection(builder);
+    Message message = builder.build();
+    reflectionTester.assertAllFieldsSetViaReflection(message);
+    // repeated setters after build()
+    reflectionTester.modifyRepeatedFieldsViaReflection(builder);
+    message = builder.build();
+    reflectionTester.assertRepeatedFieldsModifiedViaReflection(message);
+    // firstMessage shouldn't have been modified.
+    reflectionTester.assertClearViaReflection(firstMessage);
+  }
+
+  public void testUnknownFields() throws Exception {
+    Message.Builder builder =
+        DynamicMessage.newBuilder(TestEmptyMessage.getDescriptor());
+    builder.setUnknownFields(UnknownFieldSet.newBuilder()
+        .addField(1, UnknownFieldSet.Field.newBuilder().addVarint(1).build())
+        .addField(2, UnknownFieldSet.Field.newBuilder().addFixed32(1).build())
+        .build());
+    Message message = builder.build();
+    assertEquals(2, message.getUnknownFields().asMap().size());
+    // clone() with unknown fields
+    Message.Builder newBuilder = builder.clone();
+    assertEquals(2, newBuilder.getUnknownFields().asMap().size());
+    // clear() with unknown fields
+    newBuilder.clear();
+    assertTrue(newBuilder.getUnknownFields().asMap().isEmpty());
+    // serialize/parse with unknown fields
+    newBuilder.mergeFrom(message.toByteString());
+    assertEquals(2, newBuilder.getUnknownFields().asMap().size());
+  }
+
+  public void testDynamicMessageSettersRejectNull() throws Exception {
+    Message.Builder builder =
+      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    reflectionTester.assertReflectionSettersRejectNull(builder);
+  }
+
+  public void testDynamicMessageExtensionAccessors() throws Exception {
+    // We don't need to extensively test DynamicMessage's handling of
+    // extensions because, frankly, it doesn't do anything special with them.
+    // It treats them just like any other fields.
+    Message.Builder builder =
+      DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
+    extensionsReflectionTester.setAllFieldsViaReflection(builder);
+    Message message = builder.build();
+    extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
+  }
+
+  public void testDynamicMessageExtensionSettersRejectNull() throws Exception {
+    Message.Builder builder =
+      DynamicMessage.newBuilder(TestAllExtensions.getDescriptor());
+    extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
+  }
+
+  public void testDynamicMessageRepeatedSetters() throws Exception {
+    Message.Builder builder =
+      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    reflectionTester.setAllFieldsViaReflection(builder);
+    reflectionTester.modifyRepeatedFieldsViaReflection(builder);
+    Message message = builder.build();
+    reflectionTester.assertRepeatedFieldsModifiedViaReflection(message);
+  }
+
+  public void testDynamicMessageRepeatedSettersRejectNull() throws Exception {
+    Message.Builder builder =
+      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
+  }
+
+  public void testDynamicMessageDefaults() throws Exception {
+    reflectionTester.assertClearViaReflection(
+      DynamicMessage.getDefaultInstance(TestAllTypes.getDescriptor()));
+    reflectionTester.assertClearViaReflection(
+      DynamicMessage.newBuilder(TestAllTypes.getDescriptor()).build());
+  }
+
+  public void testDynamicMessageSerializedSize() throws Exception {
+    TestAllTypes message = TestUtil.getAllSet();
+
+    Message.Builder dynamicBuilder =
+      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    reflectionTester.setAllFieldsViaReflection(dynamicBuilder);
+    Message dynamicMessage = dynamicBuilder.build();
+
+    assertEquals(message.getSerializedSize(),
+                 dynamicMessage.getSerializedSize());
+  }
+
+  public void testDynamicMessageSerialization() throws Exception {
+    Message.Builder builder =
+      DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    reflectionTester.setAllFieldsViaReflection(builder);
+    Message message = builder.build();
+
+    ByteString rawBytes = message.toByteString();
+    TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+    TestUtil.assertAllFieldsSet(message2);
+
+    // In fact, the serialized forms should be exactly the same, byte-for-byte.
+    assertEquals(TestUtil.getAllSet().toByteString(), rawBytes);
+  }
+
+  public void testDynamicMessageParsing() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestUtil.setAllFields(builder);
+    TestAllTypes message = builder.build();
+
+    ByteString rawBytes = message.toByteString();
+
+    Message message2 =
+      DynamicMessage.parseFrom(TestAllTypes.getDescriptor(), rawBytes);
+    reflectionTester.assertAllFieldsSetViaReflection(message2);
+
+    // Test Parser interface.
+    Message message3 = message2.getParserForType().parseFrom(rawBytes);
+    reflectionTester.assertAllFieldsSetViaReflection(message3);
+  }
+
+  public void testDynamicMessageExtensionParsing() throws Exception {
+    ByteString rawBytes = TestUtil.getAllExtensionsSet().toByteString();
+    Message message = DynamicMessage.parseFrom(
+        TestAllExtensions.getDescriptor(), rawBytes,
+        TestUtil.getExtensionRegistry());
+    extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
+
+    // Test Parser interface.
+    Message message2 = message.getParserForType().parseFrom(
+        rawBytes, TestUtil.getExtensionRegistry());
+    extensionsReflectionTester.assertAllFieldsSetViaReflection(message2);
+  }
+
+  public void testDynamicMessagePackedSerialization() throws Exception {
+    Message.Builder builder =
+        DynamicMessage.newBuilder(TestPackedTypes.getDescriptor());
+    packedReflectionTester.setPackedFieldsViaReflection(builder);
+    Message message = builder.build();
+
+    ByteString rawBytes = message.toByteString();
+    TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
+
+    TestUtil.assertPackedFieldsSet(message2);
+
+    // In fact, the serialized forms should be exactly the same, byte-for-byte.
+    assertEquals(TestUtil.getPackedSet().toByteString(), rawBytes);
+  }
+
+  public void testDynamicMessagePackedParsing() throws Exception {
+    TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+    TestUtil.setPackedFields(builder);
+    TestPackedTypes message = builder.build();
+
+    ByteString rawBytes = message.toByteString();
+
+    Message message2 =
+      DynamicMessage.parseFrom(TestPackedTypes.getDescriptor(), rawBytes);
+    packedReflectionTester.assertPackedFieldsSetViaReflection(message2);
+
+    // Test Parser interface.
+    Message message3 = message2.getParserForType().parseFrom(rawBytes);
+    packedReflectionTester.assertPackedFieldsSetViaReflection(message3);
+  }
+
+  public void testDynamicMessageCopy() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestUtil.setAllFields(builder);
+    TestAllTypes message = builder.build();
+
+    DynamicMessage copy = DynamicMessage.newBuilder(message).build();
+    reflectionTester.assertAllFieldsSetViaReflection(copy);
+
+    // Test oneof behavior
+    FieldDescriptor bytesField =
+        TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");
+    FieldDescriptor uint32Field =
+        TestAllTypes.getDescriptor().findFieldByName("oneof_uint32");
+    assertTrue(copy.hasField(bytesField));
+    assertFalse(copy.hasField(uint32Field));
+    DynamicMessage copy2 =
+        DynamicMessage.newBuilder(message).setField(uint32Field, 123).build();
+    assertFalse(copy2.hasField(bytesField));
+    assertTrue(copy2.hasField(uint32Field));
+    assertEquals(123, copy2.getField(uint32Field));
+  }
+
+  public void testToBuilder() throws Exception {
+    DynamicMessage.Builder builder =
+        DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    reflectionTester.setAllFieldsViaReflection(builder);
+    int unknownFieldNum = 9;
+    long unknownFieldVal = 90;
+    builder.setUnknownFields(UnknownFieldSet.newBuilder()
+        .addField(unknownFieldNum,
+            UnknownFieldSet.Field.newBuilder()
+                .addVarint(unknownFieldVal).build())
+        .build());
+    DynamicMessage message = builder.build();
+
+    DynamicMessage derived = message.toBuilder().build();
+    reflectionTester.assertAllFieldsSetViaReflection(derived);
+    assertEquals(Arrays.asList(unknownFieldVal),
+        derived.getUnknownFields().getField(unknownFieldNum).getVarintList());
+  }
+
+  public void testDynamicOneofMessage() throws Exception {
+    DynamicMessage.Builder builder =
+        DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    OneofDescriptor oneof = TestAllTypes.getDescriptor().getOneofs().get(0);
+    assertFalse(builder.hasOneof(oneof));
+    assertSame(null, builder.getOneofFieldDescriptor(oneof));
+
+    reflectionTester.setAllFieldsViaReflection(builder);
+    assertTrue(builder.hasOneof(oneof));
+    FieldDescriptor field = oneof.getField(3);
+    assertSame(field, builder.getOneofFieldDescriptor(oneof));
+
+    DynamicMessage message = builder.buildPartial();
+    assertTrue(message.hasOneof(oneof));
+
+    DynamicMessage.Builder mergedBuilder =
+        DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    FieldDescriptor mergedField = oneof.getField(0);
+    mergedBuilder.setField(mergedField, 123);
+    assertTrue(mergedBuilder.hasField(mergedField));
+    mergedBuilder.mergeFrom(message);
+    assertTrue(mergedBuilder.hasField(field));
+    assertFalse(mergedBuilder.hasField(mergedField));
+
+    builder.clearOneof(oneof);
+    assertSame(null, builder.getOneofFieldDescriptor(oneof));
+    message = builder.build();
+    assertSame(null, message.getOneofFieldDescriptor(oneof));
+  }
+
+  // Regression test for a bug that makes setField() not work for repeated
+  // enum fields.
+  public void testSettersForRepeatedEnumField() throws Exception {
+    DynamicMessage.Builder builder =
+        DynamicMessage.newBuilder(TestAllTypes.getDescriptor());
+    FieldDescriptor repeatedEnumField =
+        TestAllTypes.getDescriptor().findFieldByName(
+            "repeated_nested_enum");
+    EnumDescriptor enumDescriptor = TestAllTypes.NestedEnum.getDescriptor();
+    builder.setField(repeatedEnumField, enumDescriptor.getValues());
+    DynamicMessage message = builder.build();
+    assertEquals(
+        enumDescriptor.getValues(), message.getField(repeatedEnumField));
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java b/protobuf/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
new file mode 100644
index 0000000..a92ba37
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/ForceFieldBuildersPreRun.java
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+/**
+ * A prerun for a test suite that allows running the full protocol buffer
+ * tests in a mode that disables the optimization for not using
+ * {@link RepeatedFieldBuilder} and {@link SingleFieldBuilder} until they are
+ * requested. This allows us to run all the tests through both code paths
+ * and ensures that both code paths produce identical results.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class ForceFieldBuildersPreRun implements Runnable {
+
+  //@Override (Java 1.6 override semantics, but we must support 1.5)
+  public void run() {
+    GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/protobuf/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
new file mode 100644
index 0000000..0b3482c
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -0,0 +1,1515 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.test.UnittestImport;
+import protobuf_unittest.EnumWithNoOuter;
+import protobuf_unittest.MessageWithNoOuter;
+import protobuf_unittest.MultipleFilesTestProto;
+import protobuf_unittest.NestedExtension.MyNestedExtension;
+import protobuf_unittest.NestedExtensionLite.MyNestedExtensionLite;
+import protobuf_unittest.NonNestedExtension;
+import protobuf_unittest.NonNestedExtension.MessageToBeExtended;
+import protobuf_unittest.NonNestedExtension.MyNonNestedExtension;
+import protobuf_unittest.NonNestedExtensionLite;
+import protobuf_unittest.NonNestedExtensionLite.MessageLiteToBeExtended;
+import protobuf_unittest.NonNestedExtensionLite.MyNonNestedExtensionLite;
+import protobuf_unittest.OuterClassNameTest2OuterClass;
+import protobuf_unittest.OuterClassNameTest3OuterClass;
+import protobuf_unittest.OuterClassNameTestOuterClass;
+import protobuf_unittest.ServiceWithNoOuter;
+import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
+import protobuf_unittest.UnittestOptimizeFor.TestOptionalOptimizedForSize;
+import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.ForeignMessageOrBuilder;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
+import protobuf_unittest.UnittestProto.TestOneof2;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestUnpackedTypes;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Unit test for generated messages and generated code.  See also
+ * {@link MessageTest}, which tests some generated message functionality.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class GeneratedMessageTest extends TestCase {
+  TestUtil.ReflectionTester reflectionTester =
+    new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
+
+  public void testDefaultInstance() throws Exception {
+    assertSame(TestAllTypes.getDefaultInstance(),
+               TestAllTypes.getDefaultInstance().getDefaultInstanceForType());
+    assertSame(TestAllTypes.getDefaultInstance(),
+               TestAllTypes.newBuilder().getDefaultInstanceForType());
+  }
+
+  public void testMessageOrBuilder() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestUtil.setAllFields(builder);
+    TestAllTypes message = builder.build();
+    TestUtil.assertAllFieldsSet(message);
+  }
+
+  public void testUsingBuilderMultipleTimes() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    // primitive field scalar and repeated
+    builder.setOptionalSfixed64(100);
+    builder.addRepeatedInt32(100);
+    // enum field scalar and repeated
+    builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+    builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+    // proto field scalar and repeated
+    builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(1));
+    builder.addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(1));
+
+    TestAllTypes value1 = builder.build();
+
+    assertEquals(100, value1.getOptionalSfixed64());
+    assertEquals(100, value1.getRepeatedInt32(0));
+    assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+        value1.getOptionalImportEnum());
+    assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+        value1.getRepeatedImportEnum(0));
+    assertEquals(1, value1.getOptionalForeignMessage().getC());
+    assertEquals(1, value1.getRepeatedForeignMessage(0).getC());
+
+    // Make sure that builder didn't update previously created values
+    builder.setOptionalSfixed64(200);
+    builder.setRepeatedInt32(0, 200);
+    builder.setOptionalImportEnum(UnittestImport.ImportEnum.IMPORT_FOO);
+    builder.setRepeatedImportEnum(0, UnittestImport.ImportEnum.IMPORT_FOO);
+    builder.setOptionalForeignMessage(ForeignMessage.newBuilder().setC(2));
+    builder.setRepeatedForeignMessage(0, ForeignMessage.newBuilder().setC(2));
+
+    TestAllTypes value2 = builder.build();
+
+    // Make sure value1 didn't change.
+    assertEquals(100, value1.getOptionalSfixed64());
+    assertEquals(100, value1.getRepeatedInt32(0));
+    assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+        value1.getOptionalImportEnum());
+    assertEquals(UnittestImport.ImportEnum.IMPORT_BAR,
+        value1.getRepeatedImportEnum(0));
+    assertEquals(1, value1.getOptionalForeignMessage().getC());
+    assertEquals(1, value1.getRepeatedForeignMessage(0).getC());
+
+    // Make sure value2 is correct
+    assertEquals(200, value2.getOptionalSfixed64());
+    assertEquals(200, value2.getRepeatedInt32(0));
+    assertEquals(UnittestImport.ImportEnum.IMPORT_FOO,
+        value2.getOptionalImportEnum());
+    assertEquals(UnittestImport.ImportEnum.IMPORT_FOO,
+        value2.getRepeatedImportEnum(0));
+    assertEquals(2, value2.getOptionalForeignMessage().getC());
+    assertEquals(2, value2.getRepeatedForeignMessage(0).getC());
+  }
+
+  public void testProtosShareRepeatedArraysIfDidntChange() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    builder.addRepeatedInt32(100);
+    builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+    builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance());
+
+    TestAllTypes value1 = builder.build();
+    TestAllTypes value2 = value1.toBuilder().build();
+
+    assertSame(value1.getRepeatedInt32List(), value2.getRepeatedInt32List());
+    assertSame(value1.getRepeatedImportEnumList(),
+        value2.getRepeatedImportEnumList());
+    assertSame(value1.getRepeatedForeignMessageList(),
+        value2.getRepeatedForeignMessageList());
+  }
+
+  public void testRepeatedArraysAreImmutable() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    builder.addRepeatedInt32(100);
+    builder.addRepeatedImportEnum(UnittestImport.ImportEnum.IMPORT_BAR);
+    builder.addRepeatedForeignMessage(ForeignMessage.getDefaultInstance());
+    assertIsUnmodifiable(builder.getRepeatedInt32List());
+    assertIsUnmodifiable(builder.getRepeatedImportEnumList());
+    assertIsUnmodifiable(builder.getRepeatedForeignMessageList());
+    assertIsUnmodifiable(builder.getRepeatedFloatList());
+
+
+    TestAllTypes value = builder.build();
+    assertIsUnmodifiable(value.getRepeatedInt32List());
+    assertIsUnmodifiable(value.getRepeatedImportEnumList());
+    assertIsUnmodifiable(value.getRepeatedForeignMessageList());
+    assertIsUnmodifiable(value.getRepeatedFloatList());
+  }
+
+  public void testParsedMessagesAreImmutable() throws Exception {
+    TestAllTypes value = TestAllTypes.PARSER.parseFrom(
+        TestUtil.getAllSet().toByteString());
+    assertIsUnmodifiable(value.getRepeatedInt32List());
+    assertIsUnmodifiable(value.getRepeatedInt64List());
+    assertIsUnmodifiable(value.getRepeatedUint32List());
+    assertIsUnmodifiable(value.getRepeatedUint64List());
+    assertIsUnmodifiable(value.getRepeatedSint32List());
+    assertIsUnmodifiable(value.getRepeatedSint64List());
+    assertIsUnmodifiable(value.getRepeatedFixed32List());
+    assertIsUnmodifiable(value.getRepeatedFixed64List());
+    assertIsUnmodifiable(value.getRepeatedSfixed32List());
+    assertIsUnmodifiable(value.getRepeatedSfixed64List());
+    assertIsUnmodifiable(value.getRepeatedFloatList());
+    assertIsUnmodifiable(value.getRepeatedDoubleList());
+    assertIsUnmodifiable(value.getRepeatedBoolList());
+    assertIsUnmodifiable(value.getRepeatedStringList());
+    assertIsUnmodifiable(value.getRepeatedBytesList());
+    assertIsUnmodifiable(value.getRepeatedGroupList());
+    assertIsUnmodifiable(value.getRepeatedNestedMessageList());
+    assertIsUnmodifiable(value.getRepeatedForeignMessageList());
+    assertIsUnmodifiable(value.getRepeatedImportMessageList());
+    assertIsUnmodifiable(value.getRepeatedNestedEnumList());
+    assertIsUnmodifiable(value.getRepeatedForeignEnumList());
+    assertIsUnmodifiable(value.getRepeatedImportEnumList());
+  }
+
+  private void assertIsUnmodifiable(List<?> list) {
+    if (list == Collections.emptyList()) {
+      // OKAY -- Need to check this b/c EmptyList allows you to call clear.
+    } else {
+      try {
+        list.clear();
+        fail("List wasn't immutable");
+      } catch (UnsupportedOperationException e) {
+        // good
+      }
+    }
+  }
+
+  public void testSettersRejectNull() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    try {
+      builder.setOptionalString(null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.setOptionalBytes(null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.setOptionalNestedMessage((TestAllTypes.NestedMessage) null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.setOptionalNestedMessage(
+          (TestAllTypes.NestedMessage.Builder) null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.setOptionalNestedEnum(null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.addRepeatedString(null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.addRepeatedBytes(null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.addRepeatedNestedMessage((TestAllTypes.NestedMessage) null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.addRepeatedNestedMessage(
+          (TestAllTypes.NestedMessage.Builder) null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.addRepeatedNestedEnum(null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+  }
+
+  public void testRepeatedSetters() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestUtil.setAllFields(builder);
+    TestUtil.modifyRepeatedFields(builder);
+    TestAllTypes message = builder.build();
+    TestUtil.assertRepeatedFieldsModified(message);
+  }
+
+  public void testRepeatedSettersRejectNull() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+    builder.addRepeatedString("one");
+    builder.addRepeatedString("two");
+    try {
+      builder.setRepeatedString(1, null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+
+    builder.addRepeatedBytes(TestUtil.toBytes("one"));
+    builder.addRepeatedBytes(TestUtil.toBytes("two"));
+    try {
+      builder.setRepeatedBytes(1, null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+
+    builder.addRepeatedNestedMessage(
+      TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+    builder.addRepeatedNestedMessage(
+      TestAllTypes.NestedMessage.newBuilder().setBb(456).build());
+    try {
+      builder.setRepeatedNestedMessage(1, (TestAllTypes.NestedMessage) null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.setRepeatedNestedMessage(
+          1, (TestAllTypes.NestedMessage.Builder) null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+
+    builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.FOO);
+    builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
+    try {
+      builder.setRepeatedNestedEnum(1, null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+  }
+
+  public void testRepeatedAppend() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+    builder.addAllRepeatedInt32(Arrays.asList(1, 2, 3, 4));
+    builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ));
+
+    ForeignMessage foreignMessage =
+        ForeignMessage.newBuilder().setC(12).build();
+    builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage));
+
+    TestAllTypes message = builder.build();
+    assertEquals(message.getRepeatedInt32List(), Arrays.asList(1, 2, 3, 4));
+    assertEquals(message.getRepeatedForeignEnumList(),
+        Arrays.asList(ForeignEnum.FOREIGN_BAZ));
+    assertEquals(1, message.getRepeatedForeignMessageCount());
+    assertEquals(12, message.getRepeatedForeignMessage(0).getC());
+  }
+
+  public void testRepeatedAppendRejectsNull() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+    ForeignMessage foreignMessage =
+        ForeignMessage.newBuilder().setC(12).build();
+    try {
+      builder.addAllRepeatedForeignMessage(
+          Arrays.asList(foreignMessage, (ForeignMessage) null));
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+
+    try {
+      builder.addAllRepeatedForeignEnum(
+          Arrays.asList(ForeignEnum.FOREIGN_BAZ, null));
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+
+    try {
+      builder.addAllRepeatedString(Arrays.asList("one", null));
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+
+    try {
+      builder.addAllRepeatedBytes(Arrays.asList(TestUtil.toBytes("one"), null));
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+  }
+  
+  public void testRepeatedAppendIterateOnlyOnce() throws Exception {
+    // Create a Iterable that can only be iterated once.
+    Iterable<String> stringIterable = new Iterable<String>() {
+      private boolean called = false;
+      @Override
+      public Iterator<String> iterator() {
+        if (called) {
+          throw new IllegalStateException();
+        }
+        called = true;
+        return Arrays.asList("one", "two", "three").iterator();
+      }
+    };
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    builder.addAllRepeatedString(stringIterable);
+    assertEquals(3, builder.getRepeatedStringCount());
+    assertEquals("one", builder.getRepeatedString(0));
+    assertEquals("two", builder.getRepeatedString(1));
+    assertEquals("three", builder.getRepeatedString(2));
+
+    try {
+      builder.addAllRepeatedString(stringIterable);
+      fail("Exception was not thrown");
+    } catch (IllegalStateException e) {
+      // We expect this exception.
+    }
+  }
+
+  public void testMergeFromOtherRejectsNull() throws Exception {
+    try {
+      TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+      builder.mergeFrom((TestAllTypes) null);
+      fail("Exception was not thrown");
+    } catch (NullPointerException e) {
+      // We expect this exception.
+    }
+  }
+
+  public void testSettingForeignMessageUsingBuilder() throws Exception {
+    TestAllTypes message = TestAllTypes.newBuilder()
+        // Pass builder for foreign message instance.
+        .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(123))
+        .build();
+    TestAllTypes expectedMessage = TestAllTypes.newBuilder()
+        // Create expected version passing foreign message instance explicitly.
+        .setOptionalForeignMessage(
+            ForeignMessage.newBuilder().setC(123).build())
+        .build();
+    // TODO(ngd): Upgrade to using real #equals method once implemented
+    assertEquals(expectedMessage.toString(), message.toString());
+  }
+
+  public void testSettingRepeatedForeignMessageUsingBuilder() throws Exception {
+    TestAllTypes message = TestAllTypes.newBuilder()
+        // Pass builder for foreign message instance.
+        .addRepeatedForeignMessage(ForeignMessage.newBuilder().setC(456))
+        .build();
+    TestAllTypes expectedMessage = TestAllTypes.newBuilder()
+        // Create expected version passing foreign message instance explicitly.
+        .addRepeatedForeignMessage(
+            ForeignMessage.newBuilder().setC(456).build())
+        .build();
+    assertEquals(expectedMessage.toString(), message.toString());
+  }
+
+  public void testDefaults() throws Exception {
+    TestUtil.assertClear(TestAllTypes.getDefaultInstance());
+    TestUtil.assertClear(TestAllTypes.newBuilder().build());
+
+    TestExtremeDefaultValues message =
+        TestExtremeDefaultValues.getDefaultInstance();
+    assertEquals("\u1234", message.getUtf8String());
+    assertEquals(Double.POSITIVE_INFINITY, message.getInfDouble());
+    assertEquals(Double.NEGATIVE_INFINITY, message.getNegInfDouble());
+    assertTrue(Double.isNaN(message.getNanDouble()));
+    assertEquals(Float.POSITIVE_INFINITY, message.getInfFloat());
+    assertEquals(Float.NEGATIVE_INFINITY, message.getNegInfFloat());
+    assertTrue(Float.isNaN(message.getNanFloat()));
+    assertEquals("? ? ?? ?? ??? ??/ ??-", message.getCppTrigraph());
+  }
+
+  public void testClear() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestUtil.assertClear(builder);
+    TestUtil.setAllFields(builder);
+    builder.clear();
+    TestUtil.assertClear(builder);
+  }
+
+  public void testReflectionGetters() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestUtil.setAllFields(builder);
+    reflectionTester.assertAllFieldsSetViaReflection(builder);
+
+    TestAllTypes message = builder.build();
+    reflectionTester.assertAllFieldsSetViaReflection(message);
+  }
+
+  public void testReflectionSetters() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    reflectionTester.setAllFieldsViaReflection(builder);
+    TestUtil.assertAllFieldsSet(builder);
+
+    TestAllTypes message = builder.build();
+    TestUtil.assertAllFieldsSet(message);
+  }
+
+  public void testReflectionSettersRejectNull() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    reflectionTester.assertReflectionSettersRejectNull(builder);
+  }
+
+  public void testReflectionRepeatedSetters() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    reflectionTester.setAllFieldsViaReflection(builder);
+    reflectionTester.modifyRepeatedFieldsViaReflection(builder);
+    TestUtil.assertRepeatedFieldsModified(builder);
+
+    TestAllTypes message = builder.build();
+    TestUtil.assertRepeatedFieldsModified(message);
+  }
+
+  public void testReflectionRepeatedSettersRejectNull() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    reflectionTester.assertReflectionRepeatedSettersRejectNull(builder);
+  }
+
+  public void testReflectionDefaults() throws Exception {
+    reflectionTester.assertClearViaReflection(
+      TestAllTypes.getDefaultInstance());
+    reflectionTester.assertClearViaReflection(
+      TestAllTypes.newBuilder().build());
+  }
+
+  public void testReflectionGetOneof() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    reflectionTester.setAllFieldsViaReflection(builder);
+    Descriptors.OneofDescriptor oneof =
+        TestAllTypes.getDescriptor().getOneofs().get(0);
+    Descriptors.FieldDescriptor field =
+        TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");
+    assertSame(field, builder.getOneofFieldDescriptor(oneof));
+
+    TestAllTypes message = builder.build();
+    assertSame(field, message.getOneofFieldDescriptor(oneof));
+  }
+
+  public void testReflectionClearOneof() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    reflectionTester.setAllFieldsViaReflection(builder);
+    Descriptors.OneofDescriptor oneof =
+        TestAllTypes.getDescriptor().getOneofs().get(0);
+    Descriptors.FieldDescriptor field =
+        TestAllTypes.getDescriptor().findFieldByName("oneof_bytes");
+
+    assertTrue(builder.hasOneof(oneof));
+    assertTrue(builder.hasField(field));
+    builder.clearOneof(oneof);
+    assertFalse(builder.hasOneof(oneof));
+    assertFalse(builder.hasField(field));
+  }
+
+  public void testEnumInterface() throws Exception {
+    assertTrue(TestAllTypes.getDefaultInstance().getDefaultNestedEnum()
+        instanceof ProtocolMessageEnum);
+  }
+
+  public void testEnumMap() throws Exception {
+    Internal.EnumLiteMap<ForeignEnum> map = ForeignEnum.internalGetValueMap();
+
+    for (ForeignEnum value : ForeignEnum.values()) {
+      assertEquals(value, map.findValueByNumber(value.getNumber()));
+    }
+
+    assertTrue(map.findValueByNumber(12345) == null);
+  }
+
+  public void testParsePackedToUnpacked() throws Exception {
+    TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder();
+    TestUnpackedTypes message =
+      builder.mergeFrom(TestUtil.getPackedSet().toByteString()).build();
+    TestUtil.assertUnpackedFieldsSet(message);
+  }
+
+  public void testParseUnpackedToPacked() throws Exception {
+    TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+    TestPackedTypes message =
+      builder.mergeFrom(TestUtil.getUnpackedSet().toByteString()).build();
+    TestUtil.assertPackedFieldsSet(message);
+  }
+
+  // =================================================================
+  // Extensions.
+
+  TestUtil.ReflectionTester extensionsReflectionTester =
+    new TestUtil.ReflectionTester(TestAllExtensions.getDescriptor(),
+                                  TestUtil.getExtensionRegistry());
+
+  public void testExtensionMessageOrBuilder() throws Exception {
+    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+    TestUtil.setAllExtensions(builder);
+    TestAllExtensions message = builder.build();
+    TestUtil.assertAllExtensionsSet(message);
+  }
+
+  public void testExtensionRepeatedSetters() throws Exception {
+    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+    TestUtil.setAllExtensions(builder);
+    TestUtil.modifyRepeatedExtensions(builder);
+    TestAllExtensions message = builder.build();
+    TestUtil.assertRepeatedExtensionsModified(message);
+  }
+
+  public void testExtensionDefaults() throws Exception {
+    TestUtil.assertExtensionsClear(TestAllExtensions.getDefaultInstance());
+    TestUtil.assertExtensionsClear(TestAllExtensions.newBuilder().build());
+  }
+
+  public void testExtensionReflectionGetters() throws Exception {
+    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+    TestUtil.setAllExtensions(builder);
+    extensionsReflectionTester.assertAllFieldsSetViaReflection(builder);
+
+    TestAllExtensions message = builder.build();
+    extensionsReflectionTester.assertAllFieldsSetViaReflection(message);
+  }
+
+  public void testExtensionReflectionSetters() throws Exception {
+    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+    extensionsReflectionTester.setAllFieldsViaReflection(builder);
+    TestUtil.assertAllExtensionsSet(builder);
+
+    TestAllExtensions message = builder.build();
+    TestUtil.assertAllExtensionsSet(message);
+  }
+
+  public void testExtensionReflectionSettersRejectNull() throws Exception {
+    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+    extensionsReflectionTester.assertReflectionSettersRejectNull(builder);
+  }
+
+  public void testExtensionReflectionRepeatedSetters() throws Exception {
+    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+    extensionsReflectionTester.setAllFieldsViaReflection(builder);
+    extensionsReflectionTester.modifyRepeatedFieldsViaReflection(builder);
+    TestUtil.assertRepeatedExtensionsModified(builder);
+
+    TestAllExtensions message = builder.build();
+    TestUtil.assertRepeatedExtensionsModified(message);
+  }
+
+  public void testExtensionReflectionRepeatedSettersRejectNull()
+      throws Exception {
+    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+    extensionsReflectionTester.assertReflectionRepeatedSettersRejectNull(
+        builder);
+  }
+
+  public void testExtensionReflectionDefaults() throws Exception {
+    extensionsReflectionTester.assertClearViaReflection(
+      TestAllExtensions.getDefaultInstance());
+    extensionsReflectionTester.assertClearViaReflection(
+      TestAllExtensions.newBuilder().build());
+  }
+
+  public void testClearExtension() throws Exception {
+    // clearExtension() is not actually used in TestUtil, so try it manually.
+    assertFalse(
+      TestAllExtensions.newBuilder()
+        .setExtension(UnittestProto.optionalInt32Extension, 1)
+        .clearExtension(UnittestProto.optionalInt32Extension)
+        .hasExtension(UnittestProto.optionalInt32Extension));
+    assertEquals(0,
+      TestAllExtensions.newBuilder()
+        .addExtension(UnittestProto.repeatedInt32Extension, 1)
+        .clearExtension(UnittestProto.repeatedInt32Extension)
+        .getExtensionCount(UnittestProto.repeatedInt32Extension));
+  }
+
+  public void testExtensionCopy() throws Exception {
+    TestAllExtensions original = TestUtil.getAllExtensionsSet();
+    TestAllExtensions copy = TestAllExtensions.newBuilder(original).build();
+    TestUtil.assertAllExtensionsSet(copy);
+  }
+
+  public void testExtensionMergeFrom() throws Exception {
+    TestAllExtensions original =
+      TestAllExtensions.newBuilder()
+        .setExtension(UnittestProto.optionalInt32Extension, 1).build();
+    TestAllExtensions merged =
+        TestAllExtensions.newBuilder().mergeFrom(original).build();
+    assertTrue(merged.hasExtension(UnittestProto.optionalInt32Extension));
+    assertEquals(
+        1, (int) merged.getExtension(UnittestProto.optionalInt32Extension));
+  }
+
+  // =================================================================
+  // Lite Extensions.
+
+  // We test lite extensions directly because they have a separate
+  // implementation from full extensions.  In contrast, we do not test
+  // lite fields directly since they are implemented exactly the same as
+  // regular fields.
+
+  public void testLiteExtensionMessageOrBuilder() throws Exception {
+    TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
+    TestUtil.setAllExtensions(builder);
+    TestUtil.assertAllExtensionsSet(builder);
+
+    TestAllExtensionsLite message = builder.build();
+    TestUtil.assertAllExtensionsSet(message);
+  }
+
+  public void testLiteExtensionRepeatedSetters() throws Exception {
+    TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
+    TestUtil.setAllExtensions(builder);
+    TestUtil.modifyRepeatedExtensions(builder);
+    TestUtil.assertRepeatedExtensionsModified(builder);
+
+    TestAllExtensionsLite message = builder.build();
+    TestUtil.assertRepeatedExtensionsModified(message);
+  }
+
+  public void testLiteExtensionDefaults() throws Exception {
+    TestUtil.assertExtensionsClear(TestAllExtensionsLite.getDefaultInstance());
+    TestUtil.assertExtensionsClear(TestAllExtensionsLite.newBuilder().build());
+  }
+
+  public void testClearLiteExtension() throws Exception {
+    // clearExtension() is not actually used in TestUtil, so try it manually.
+    assertFalse(
+      TestAllExtensionsLite.newBuilder()
+        .setExtension(UnittestLite.optionalInt32ExtensionLite, 1)
+        .clearExtension(UnittestLite.optionalInt32ExtensionLite)
+        .hasExtension(UnittestLite.optionalInt32ExtensionLite));
+    assertEquals(0,
+      TestAllExtensionsLite.newBuilder()
+        .addExtension(UnittestLite.repeatedInt32ExtensionLite, 1)
+        .clearExtension(UnittestLite.repeatedInt32ExtensionLite)
+        .getExtensionCount(UnittestLite.repeatedInt32ExtensionLite));
+  }
+
+  public void testLiteExtensionCopy() throws Exception {
+    TestAllExtensionsLite original = TestUtil.getAllLiteExtensionsSet();
+    TestAllExtensionsLite copy =
+        TestAllExtensionsLite.newBuilder(original).build();
+    TestUtil.assertAllExtensionsSet(copy);
+  }
+
+  public void testLiteExtensionMergeFrom() throws Exception {
+    TestAllExtensionsLite original =
+      TestAllExtensionsLite.newBuilder()
+        .setExtension(UnittestLite.optionalInt32ExtensionLite, 1).build();
+    TestAllExtensionsLite merged =
+        TestAllExtensionsLite.newBuilder().mergeFrom(original).build();
+    assertTrue(merged.hasExtension(UnittestLite.optionalInt32ExtensionLite));
+    assertEquals(
+        1, (int) merged.getExtension(UnittestLite.optionalInt32ExtensionLite));
+  }
+
+  // =================================================================
+  // multiple_files_test
+
+  // Test that custom options of an file level enum are properly initialized.
+  // This test needs to be put before any other access to MultipleFilesTestProto
+  // or messages defined in multiple_files_test.proto because the class loading
+  // order affects initialization process of custom options.
+  public void testEnumValueOptionsInMultipleFilesMode() throws Exception {
+    assertEquals(12345, EnumWithNoOuter.FOO.getValueDescriptor().getOptions()
+        .getExtension(MultipleFilesTestProto.enumValueOption).intValue());
+  }
+
+  public void testMultipleFilesOption() throws Exception {
+    // We mostly just want to check that things compile.
+    MessageWithNoOuter message =
+      MessageWithNoOuter.newBuilder()
+        .setNested(MessageWithNoOuter.NestedMessage.newBuilder().setI(1))
+        .addForeign(TestAllTypes.newBuilder().setOptionalInt32(1))
+        .setNestedEnum(MessageWithNoOuter.NestedEnum.BAZ)
+        .setForeignEnum(EnumWithNoOuter.BAR)
+        .build();
+    assertEquals(message, MessageWithNoOuter.parseFrom(message.toByteString()));
+
+    assertEquals(MultipleFilesTestProto.getDescriptor(),
+                 MessageWithNoOuter.getDescriptor().getFile());
+
+    Descriptors.FieldDescriptor field =
+      MessageWithNoOuter.getDescriptor().findFieldByName("foreign_enum");
+    assertEquals(EnumWithNoOuter.BAR.getValueDescriptor(),
+                 message.getField(field));
+
+    assertEquals(MultipleFilesTestProto.getDescriptor(),
+                 ServiceWithNoOuter.getDescriptor().getFile());
+
+    assertFalse(
+      TestAllExtensions.getDefaultInstance().hasExtension(
+        MultipleFilesTestProto.extensionWithOuter));
+  }
+
+  public void testOptionalFieldWithRequiredSubfieldsOptimizedForSize()
+    throws Exception {
+    TestOptionalOptimizedForSize message =
+        TestOptionalOptimizedForSize.getDefaultInstance();
+    assertTrue(message.isInitialized());
+
+    message = TestOptionalOptimizedForSize.newBuilder().setO(
+        TestRequiredOptimizedForSize.newBuilder().buildPartial()
+        ).buildPartial();
+    assertFalse(message.isInitialized());
+
+    message = TestOptionalOptimizedForSize.newBuilder().setO(
+        TestRequiredOptimizedForSize.newBuilder().setX(5).buildPartial()
+        ).buildPartial();
+    assertTrue(message.isInitialized());
+  }
+
+  public void testUninitializedExtensionInOptimizedForSize()
+      throws Exception {
+    TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder();
+    builder.setExtension(TestOptimizedForSize.testExtension2,
+        TestRequiredOptimizedForSize.newBuilder().buildPartial());
+    assertFalse(builder.isInitialized());
+    assertFalse(builder.buildPartial().isInitialized());
+
+    builder = TestOptimizedForSize.newBuilder();
+    builder.setExtension(TestOptimizedForSize.testExtension2,
+        TestRequiredOptimizedForSize.newBuilder().setX(10).buildPartial());
+    assertTrue(builder.isInitialized());
+    assertTrue(builder.buildPartial().isInitialized());
+  }
+
+  public void testToBuilder() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestUtil.setAllFields(builder);
+    TestAllTypes message = builder.build();
+    TestUtil.assertAllFieldsSet(message);
+    TestUtil.assertAllFieldsSet(message.toBuilder().build());
+  }
+
+  public void testFieldConstantValues() throws Exception {
+    assertEquals(TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1);
+    assertEquals(TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 1);
+    assertEquals(TestAllTypes.OPTIONALGROUP_FIELD_NUMBER, 16);
+    assertEquals(TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER, 18);
+    assertEquals(TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER, 21);
+    assertEquals(TestAllTypes.REPEATED_INT32_FIELD_NUMBER, 31);
+    assertEquals(TestAllTypes.REPEATEDGROUP_FIELD_NUMBER, 46);
+    assertEquals(TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER, 48);
+    assertEquals(TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER, 51);
+  }
+
+  public void testExtensionConstantValues() throws Exception {
+    assertEquals(UnittestProto.TestRequired.SINGLE_FIELD_NUMBER, 1000);
+    assertEquals(UnittestProto.TestRequired.MULTI_FIELD_NUMBER, 1001);
+    assertEquals(UnittestProto.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER, 1);
+    assertEquals(UnittestProto.OPTIONALGROUP_EXTENSION_FIELD_NUMBER, 16);
+    assertEquals(
+      UnittestProto.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 18);
+    assertEquals(UnittestProto.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 21);
+    assertEquals(UnittestProto.REPEATED_INT32_EXTENSION_FIELD_NUMBER, 31);
+    assertEquals(UnittestProto.REPEATEDGROUP_EXTENSION_FIELD_NUMBER, 46);
+    assertEquals(
+      UnittestProto.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48);
+    assertEquals(UnittestProto.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER, 51);
+  }
+
+  public void testRecursiveMessageDefaultInstance() throws Exception {
+    UnittestProto.TestRecursiveMessage message =
+        UnittestProto.TestRecursiveMessage.getDefaultInstance();
+    assertTrue(message != null);
+    assertNotNull(message.getA());
+    assertTrue(message.getA() == message);
+  }
+
+  public void testSerialize() throws Exception {
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestUtil.setAllFields(builder);
+    TestAllTypes expected = builder.build();
+    ObjectOutputStream out = new ObjectOutputStream(baos);
+    try {
+      out.writeObject(expected);
+    } finally {
+      out.close();
+    }
+    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+    ObjectInputStream in = new ObjectInputStream(bais);
+    TestAllTypes actual = (TestAllTypes) in.readObject();
+    assertEquals(expected, actual);
+  }
+
+  public void testSerializePartial() throws Exception {
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestAllTypes expected = builder.buildPartial();
+    ObjectOutputStream out = new ObjectOutputStream(baos);
+    try {
+      out.writeObject(expected);
+    } finally {
+      out.close();
+    }
+    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+    ObjectInputStream in = new ObjectInputStream(bais);
+    TestAllTypes actual = (TestAllTypes) in.readObject();
+    assertEquals(expected, actual);
+  }
+
+  public void testEnumValues() {
+     assertEquals(
+         TestAllTypes.NestedEnum.BAR.getNumber(),
+         TestAllTypes.NestedEnum.BAR_VALUE);
+    assertEquals(
+        TestAllTypes.NestedEnum.BAZ.getNumber(),
+        TestAllTypes.NestedEnum.BAZ_VALUE);
+    assertEquals(
+        TestAllTypes.NestedEnum.FOO.getNumber(),
+        TestAllTypes.NestedEnum.FOO_VALUE);
+  }
+
+  public void testNonNestedExtensionInitialization() {
+    assertTrue(NonNestedExtension.nonNestedExtension
+               .getMessageDefaultInstance() instanceof MyNonNestedExtension);
+    assertEquals("nonNestedExtension",
+                 NonNestedExtension.nonNestedExtension.getDescriptor().getName());
+  }
+
+  public void testNestedExtensionInitialization() {
+    assertTrue(MyNestedExtension.recursiveExtension.getMessageDefaultInstance()
+               instanceof MessageToBeExtended);
+    assertEquals("recursiveExtension",
+                 MyNestedExtension.recursiveExtension.getDescriptor().getName());
+  }
+
+  public void testNonNestedExtensionLiteInitialization() {
+    assertTrue(NonNestedExtensionLite.nonNestedExtensionLite
+               .getMessageDefaultInstance() instanceof MyNonNestedExtensionLite);
+  }
+
+  public void testNestedExtensionLiteInitialization() {
+    assertTrue(MyNestedExtensionLite.recursiveExtensionLite
+               .getMessageDefaultInstance() instanceof MessageLiteToBeExtended);
+  }
+
+  public void testInvalidations() throws Exception {
+    GeneratedMessage.enableAlwaysUseFieldBuildersForTesting();
+    TestAllTypes.NestedMessage nestedMessage1 =
+        TestAllTypes.NestedMessage.newBuilder().build();
+    TestAllTypes.NestedMessage nestedMessage2 =
+        TestAllTypes.NestedMessage.newBuilder().build();
+
+    // Set all three flavors (enum, primitive, message and singular/repeated)
+    // and verify no invalidations fired
+    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+
+    TestAllTypes.Builder builder = (TestAllTypes.Builder)
+        ((GeneratedMessage) TestAllTypes.getDefaultInstance()).
+            newBuilderForType(mockParent);
+    builder.setOptionalInt32(1);
+    builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
+    builder.setOptionalNestedMessage(nestedMessage1);
+    builder.addRepeatedInt32(1);
+    builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAR);
+    builder.addRepeatedNestedMessage(nestedMessage1);
+    assertEquals(0, mockParent.getInvalidationCount());
+
+    // Now tell it we want changes and make sure it's only fired once
+    // And do this for each flavor
+
+    // primitive single
+    builder.buildPartial();
+    builder.setOptionalInt32(2);
+    builder.setOptionalInt32(3);
+    assertEquals(1, mockParent.getInvalidationCount());
+
+    // enum single
+    builder.buildPartial();
+    builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ);
+    builder.setOptionalNestedEnum(TestAllTypes.NestedEnum.BAR);
+    assertEquals(2, mockParent.getInvalidationCount());
+
+    // message single
+    builder.buildPartial();
+    builder.setOptionalNestedMessage(nestedMessage2);
+    builder.setOptionalNestedMessage(nestedMessage1);
+    assertEquals(3, mockParent.getInvalidationCount());
+
+    // primitive repeated
+    builder.buildPartial();
+    builder.addRepeatedInt32(2);
+    builder.addRepeatedInt32(3);
+    assertEquals(4, mockParent.getInvalidationCount());
+
+    // enum repeated
+    builder.buildPartial();
+    builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
+    builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
+    assertEquals(5, mockParent.getInvalidationCount());
+
+    // message repeated
+    builder.buildPartial();
+    builder.addRepeatedNestedMessage(nestedMessage2);
+    builder.addRepeatedNestedMessage(nestedMessage1);
+    assertEquals(6, mockParent.getInvalidationCount());
+
+  }
+
+  public void testInvalidations_Extensions() throws Exception {
+    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+
+    TestAllExtensions.Builder builder = (TestAllExtensions.Builder)
+        ((GeneratedMessage) TestAllExtensions.getDefaultInstance()).
+            newBuilderForType(mockParent);
+
+    builder.addExtension(UnittestProto.repeatedInt32Extension, 1);
+    builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 2);
+    builder.clearExtension(UnittestProto.repeatedInt32Extension);
+    assertEquals(0, mockParent.getInvalidationCount());
+
+    // Now tell it we want changes and make sure it's only fired once
+    builder.buildPartial();
+    builder.addExtension(UnittestProto.repeatedInt32Extension, 2);
+    builder.addExtension(UnittestProto.repeatedInt32Extension, 3);
+    assertEquals(1, mockParent.getInvalidationCount());
+
+    builder.buildPartial();
+    builder.setExtension(UnittestProto.repeatedInt32Extension, 0, 4);
+    builder.setExtension(UnittestProto.repeatedInt32Extension, 1, 5);
+    assertEquals(2, mockParent.getInvalidationCount());
+
+    builder.buildPartial();
+    builder.clearExtension(UnittestProto.repeatedInt32Extension);
+    builder.clearExtension(UnittestProto.repeatedInt32Extension);
+    assertEquals(3, mockParent.getInvalidationCount());
+  }
+
+  public void testBaseMessageOrBuilder() {
+    // Mostly just makes sure the base interface exists and has some methods.
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestAllTypes message = builder.buildPartial();
+    TestAllTypesOrBuilder builderAsInterface = (TestAllTypesOrBuilder) builder;
+    TestAllTypesOrBuilder messageAsInterface = (TestAllTypesOrBuilder) message;
+
+    assertEquals(
+        messageAsInterface.getDefaultBool(),
+        messageAsInterface.getDefaultBool());
+    assertEquals(
+        messageAsInterface.getOptionalDouble(),
+        messageAsInterface.getOptionalDouble());
+  }
+
+  public void testMessageOrBuilderGetters() {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+
+    // single fields
+    assertSame(ForeignMessage.getDefaultInstance(),
+        builder.getOptionalForeignMessageOrBuilder());
+    ForeignMessage.Builder subBuilder =
+        builder.getOptionalForeignMessageBuilder();
+    assertSame(subBuilder, builder.getOptionalForeignMessageOrBuilder());
+
+    // repeated fields
+    ForeignMessage m0 = ForeignMessage.newBuilder().buildPartial();
+    ForeignMessage m1 = ForeignMessage.newBuilder().buildPartial();
+    ForeignMessage m2 = ForeignMessage.newBuilder().buildPartial();
+    builder.addRepeatedForeignMessage(m0);
+    builder.addRepeatedForeignMessage(m1);
+    builder.addRepeatedForeignMessage(m2);
+    assertSame(m0, builder.getRepeatedForeignMessageOrBuilder(0));
+    assertSame(m1, builder.getRepeatedForeignMessageOrBuilder(1));
+    assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2));
+    ForeignMessage.Builder b0 = builder.getRepeatedForeignMessageBuilder(0);
+    ForeignMessage.Builder b1 = builder.getRepeatedForeignMessageBuilder(1);
+    assertSame(b0, builder.getRepeatedForeignMessageOrBuilder(0));
+    assertSame(b1, builder.getRepeatedForeignMessageOrBuilder(1));
+    assertSame(m2, builder.getRepeatedForeignMessageOrBuilder(2));
+
+    List<? extends ForeignMessageOrBuilder> messageOrBuilderList =
+        builder.getRepeatedForeignMessageOrBuilderList();
+    assertSame(b0, messageOrBuilderList.get(0));
+    assertSame(b1, messageOrBuilderList.get(1));
+    assertSame(m2, messageOrBuilderList.get(2));
+  }
+
+  public void testGetFieldBuilder() {
+    Descriptor descriptor = TestAllTypes.getDescriptor();
+
+    FieldDescriptor fieldDescriptor =
+        descriptor.findFieldByName("optional_nested_message");
+    FieldDescriptor foreignFieldDescriptor =
+        descriptor.findFieldByName("optional_foreign_message");
+    FieldDescriptor importFieldDescriptor =
+        descriptor.findFieldByName("optional_import_message");
+
+    // Mutate the message with new field builder
+    // Mutate nested message
+    TestAllTypes.Builder builder1 = TestAllTypes.newBuilder();
+    Message.Builder fieldBuilder1 = builder1.newBuilderForField(fieldDescriptor)
+        .mergeFrom((Message) builder1.getField(fieldDescriptor));
+    FieldDescriptor subFieldDescriptor1 =
+        fieldBuilder1.getDescriptorForType().findFieldByName("bb");
+    fieldBuilder1.setField(subFieldDescriptor1, 1);
+    builder1.setField(fieldDescriptor, fieldBuilder1.build());
+
+    // Mutate foreign message
+    Message.Builder foreignFieldBuilder1 = builder1.newBuilderForField(
+        foreignFieldDescriptor)
+        .mergeFrom((Message) builder1.getField(foreignFieldDescriptor));
+    FieldDescriptor subForeignFieldDescriptor1 =
+        foreignFieldBuilder1.getDescriptorForType().findFieldByName("c");
+    foreignFieldBuilder1.setField(subForeignFieldDescriptor1, 2);
+    builder1.setField(foreignFieldDescriptor, foreignFieldBuilder1.build());
+
+    // Mutate import message
+    Message.Builder importFieldBuilder1 = builder1.newBuilderForField(
+        importFieldDescriptor)
+        .mergeFrom((Message) builder1.getField(importFieldDescriptor));
+    FieldDescriptor subImportFieldDescriptor1 =
+        importFieldBuilder1.getDescriptorForType().findFieldByName("d");
+    importFieldBuilder1.setField(subImportFieldDescriptor1, 3);
+    builder1.setField(importFieldDescriptor, importFieldBuilder1.build());
+
+    Message newMessage1 = builder1.build();
+
+    // Mutate the message with existing field builder
+    // Mutate nested message
+    TestAllTypes.Builder builder2 = TestAllTypes.newBuilder();
+    Message.Builder fieldBuilder2 = builder2.getFieldBuilder(fieldDescriptor);
+    FieldDescriptor subFieldDescriptor2 =
+        fieldBuilder2.getDescriptorForType().findFieldByName("bb");
+    fieldBuilder2.setField(subFieldDescriptor2, 1);
+    builder2.setField(fieldDescriptor, fieldBuilder2.build());
+
+    // Mutate foreign message
+    Message.Builder foreignFieldBuilder2 = builder2.newBuilderForField(
+        foreignFieldDescriptor)
+        .mergeFrom((Message) builder2.getField(foreignFieldDescriptor));
+    FieldDescriptor subForeignFieldDescriptor2 =
+        foreignFieldBuilder2.getDescriptorForType().findFieldByName("c");
+    foreignFieldBuilder2.setField(subForeignFieldDescriptor2, 2);
+    builder2.setField(foreignFieldDescriptor, foreignFieldBuilder2.build());
+
+    // Mutate import message
+    Message.Builder importFieldBuilder2 = builder2.newBuilderForField(
+        importFieldDescriptor)
+        .mergeFrom((Message) builder2.getField(importFieldDescriptor));
+    FieldDescriptor subImportFieldDescriptor2 =
+        importFieldBuilder2.getDescriptorForType().findFieldByName("d");
+    importFieldBuilder2.setField(subImportFieldDescriptor2, 3);
+    builder2.setField(importFieldDescriptor, importFieldBuilder2.build());
+
+    Message newMessage2 = builder2.build();
+
+    // These two messages should be equal.
+    assertEquals(newMessage1, newMessage2);
+  }
+
+  public void testGetFieldBuilderWithInitializedValue() {
+    Descriptor descriptor = TestAllTypes.getDescriptor();
+    FieldDescriptor fieldDescriptor =
+        descriptor.findFieldByName("optional_nested_message");
+
+    // Before setting field, builder is initialized by default value. 
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    NestedMessage.Builder fieldBuilder =
+        (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor);
+    assertEquals(0, fieldBuilder.getBb());
+
+    // Setting field value with new field builder instance.
+    builder = TestAllTypes.newBuilder();
+    NestedMessage.Builder newFieldBuilder =
+        builder.getOptionalNestedMessageBuilder();
+    newFieldBuilder.setBb(2);
+    // Then get the field builder instance by getFieldBuilder().
+    fieldBuilder =
+        (NestedMessage.Builder) builder.getFieldBuilder(fieldDescriptor);
+    // It should contain new value.
+    assertEquals(2, fieldBuilder.getBb());
+    // These two builder should be equal.
+    assertSame(fieldBuilder, newFieldBuilder);
+  }
+
+  public void testGetFieldBuilderNotSupportedException() {
+    Descriptor descriptor = TestAllTypes.getDescriptor();
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    try {
+      builder.getFieldBuilder(descriptor.findFieldByName("optional_int32"));
+      fail("Exception was not thrown");
+    } catch (UnsupportedOperationException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.getFieldBuilder(
+          descriptor.findFieldByName("optional_nested_enum"));
+      fail("Exception was not thrown");
+    } catch (UnsupportedOperationException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.getFieldBuilder(descriptor.findFieldByName("repeated_int32"));
+      fail("Exception was not thrown");
+    } catch (UnsupportedOperationException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.getFieldBuilder(
+          descriptor.findFieldByName("repeated_nested_enum"));
+      fail("Exception was not thrown");
+    } catch (UnsupportedOperationException e) {
+      // We expect this exception.
+    }
+    try {
+      builder.getFieldBuilder(
+          descriptor.findFieldByName("repeated_nested_message"));
+      fail("Exception was not thrown");
+    } catch (UnsupportedOperationException e) {
+      // We expect this exception.
+    }
+  }
+
+  // Test that when the default outer class name conflicts with another type
+  // defined in the proto the compiler will append a suffix to avoid the
+  // conflict.
+  public void testConflictingOuterClassName() {
+    // We just need to make sure we can refer to the outer class with the
+    // expected name. There is nothing else to test.
+    OuterClassNameTestOuterClass.OuterClassNameTest message =
+        OuterClassNameTestOuterClass.OuterClassNameTest.newBuilder().build();
+    assertTrue(message.getDescriptorForType() ==
+        OuterClassNameTestOuterClass.OuterClassNameTest.getDescriptor());
+
+    OuterClassNameTest2OuterClass.TestMessage2.NestedMessage.OuterClassNameTest2
+        message2 = OuterClassNameTest2OuterClass.TestMessage2.NestedMessage
+            .OuterClassNameTest2.newBuilder().build();
+    assertEquals(0, message2.getSerializedSize());
+
+    OuterClassNameTest3OuterClass.TestMessage3.NestedMessage.OuterClassNameTest3
+        enumValue = OuterClassNameTest3OuterClass.TestMessage3.NestedMessage
+            .OuterClassNameTest3.DUMMY_VALUE;
+    assertEquals(1, enumValue.getNumber());
+  }
+
+  // =================================================================
+  // oneof generated code test
+  public void testOneofEnumCase() throws Exception {
+    TestOneof2 message = TestOneof2.newBuilder()
+        .setFooInt(123).setFooString("foo").setFooCord("bar").build();
+    TestUtil.assertAtMostOneFieldSetOneof(message);
+  }
+
+  public void testClearOneof() throws Exception {
+    TestOneof2.Builder builder = TestOneof2.newBuilder().setFooInt(123);
+    assertEquals(TestOneof2.FooCase.FOO_INT, builder.getFooCase());
+    builder.clearFoo();
+    assertEquals(TestOneof2.FooCase.FOO_NOT_SET, builder.getFooCase());
+  }
+
+  public void testSetOneofClearsOthers() throws Exception {
+    TestOneof2.Builder builder = TestOneof2.newBuilder();
+    TestOneof2 message =
+        builder.setFooInt(123).setFooString("foo").buildPartial();
+    assertTrue(message.hasFooString());
+    TestUtil.assertAtMostOneFieldSetOneof(message);
+
+    message = builder.setFooCord("bar").buildPartial();
+    assertTrue(message.hasFooCord());
+    TestUtil.assertAtMostOneFieldSetOneof(message);
+
+    message = builder.setFooStringPiece("baz").buildPartial();
+    assertTrue(message.hasFooStringPiece());
+    TestUtil.assertAtMostOneFieldSetOneof(message);
+
+    message = builder.setFooBytes(TestUtil.toBytes("qux")).buildPartial();
+    assertTrue(message.hasFooBytes());
+    TestUtil.assertAtMostOneFieldSetOneof(message);
+
+    message = builder.setFooEnum(TestOneof2.NestedEnum.FOO).buildPartial();
+    assertTrue(message.hasFooEnum());
+    TestUtil.assertAtMostOneFieldSetOneof(message);
+
+    message = builder.setFooMessage(
+        TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).buildPartial();
+    assertTrue(message.hasFooMessage());
+    TestUtil.assertAtMostOneFieldSetOneof(message);
+
+    message = builder.setFooInt(123).buildPartial();
+    assertTrue(message.hasFooInt());
+    TestUtil.assertAtMostOneFieldSetOneof(message);
+  }
+
+  public void testOneofTypes() throws Exception {
+    // Primitive
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      assertEquals(builder.getFooInt(), 0);
+      assertFalse(builder.hasFooInt());
+      assertTrue(builder.setFooInt(123).hasFooInt());
+      assertEquals(builder.getFooInt(), 123);
+      TestOneof2 message = builder.buildPartial();
+      assertTrue(message.hasFooInt());
+      assertEquals(message.getFooInt(), 123);
+
+      assertFalse(builder.clearFooInt().hasFooInt());
+      TestOneof2 message2 = builder.build();
+      assertFalse(message2.hasFooInt());
+      assertEquals(message2.getFooInt(), 0);
+    }
+
+    // Enum
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      assertEquals(builder.getFooEnum(), TestOneof2.NestedEnum.FOO);
+      assertTrue(builder.setFooEnum(TestOneof2.NestedEnum.BAR).hasFooEnum());
+      assertEquals(builder.getFooEnum(), TestOneof2.NestedEnum.BAR);
+      TestOneof2 message = builder.buildPartial();
+      assertTrue(message.hasFooEnum());
+      assertEquals(message.getFooEnum(), TestOneof2.NestedEnum.BAR);
+
+      assertFalse(builder.clearFooEnum().hasFooEnum());
+      TestOneof2 message2 = builder.build();
+      assertFalse(message2.hasFooEnum());
+      assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.FOO);
+    }
+
+    // String
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      assertEquals(builder.getFooString(), "");
+      builder.setFooString("foo");
+      assertTrue(builder.hasFooString());
+      assertEquals(builder.getFooString(), "foo");
+      TestOneof2 message = builder.buildPartial();
+      assertTrue(message.hasFooString());
+      assertEquals(message.getFooString(), "foo");
+      assertEquals(message.getFooStringBytes(), TestUtil.toBytes("foo"));
+
+      assertFalse(builder.clearFooString().hasFooString());
+      TestOneof2 message2 = builder.buildPartial();
+      assertFalse(message2.hasFooString());
+      assertEquals(message2.getFooString(), "");
+      assertEquals(message2.getFooStringBytes(), TestUtil.toBytes(""));
+
+      // Get method should not change the oneof value.
+      builder.setFooInt(123);
+      assertEquals(builder.getFooString(), "");
+      assertEquals(builder.getFooStringBytes(), TestUtil.toBytes(""));
+      assertEquals(123, builder.getFooInt());
+
+      message = builder.build();
+      assertEquals(message.getFooString(), "");
+      assertEquals(message.getFooStringBytes(), TestUtil.toBytes(""));
+      assertEquals(123, message.getFooInt());
+    }
+
+    // Cord
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      assertEquals(builder.getFooCord(), "");
+      builder.setFooCord("foo");
+      assertTrue(builder.hasFooCord());
+      assertEquals(builder.getFooCord(), "foo");
+      TestOneof2 message = builder.buildPartial();
+      assertTrue(message.hasFooCord());
+      assertEquals(message.getFooCord(), "foo");
+      assertEquals(message.getFooCordBytes(), TestUtil.toBytes("foo"));
+
+      assertFalse(builder.clearFooCord().hasFooCord());
+      TestOneof2 message2 = builder.build();
+      assertFalse(message2.hasFooCord());
+      assertEquals(message2.getFooCord(), "");
+      assertEquals(message2.getFooCordBytes(), TestUtil.toBytes(""));
+    }
+
+    // StringPiece
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      assertEquals(builder.getFooStringPiece(), "");
+      builder.setFooStringPiece("foo");
+      assertTrue(builder.hasFooStringPiece());
+      assertEquals(builder.getFooStringPiece(), "foo");
+      TestOneof2 message = builder.buildPartial();
+      assertTrue(message.hasFooStringPiece());
+      assertEquals(message.getFooStringPiece(), "foo");
+      assertEquals(message.getFooStringPieceBytes(), TestUtil.toBytes("foo"));
+
+      assertFalse(builder.clearFooStringPiece().hasFooStringPiece());
+      TestOneof2 message2 = builder.build();
+      assertFalse(message2.hasFooStringPiece());
+      assertEquals(message2.getFooStringPiece(), "");
+      assertEquals(message2.getFooStringPieceBytes(), TestUtil.toBytes(""));
+    }
+
+    // Message
+    {
+      // set
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      assertEquals(builder.getFooMessage().getQuxInt(), 0);
+      builder.setFooMessage(
+          TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build());
+      assertTrue(builder.hasFooMessage());
+      assertEquals(builder.getFooMessage().getQuxInt(), 234);
+      TestOneof2 message = builder.buildPartial();
+      assertTrue(message.hasFooMessage());
+      assertEquals(message.getFooMessage().getQuxInt(), 234);
+
+      // clear
+      assertFalse(builder.clearFooMessage().hasFooString());
+      message = builder.build();
+      assertFalse(message.hasFooMessage());
+      assertEquals(message.getFooMessage().getQuxInt(), 0);
+
+      // nested builder
+      builder = TestOneof2.newBuilder();
+      assertSame(builder.getFooMessageOrBuilder(),
+          TestOneof2.NestedMessage.getDefaultInstance());
+      assertFalse(builder.hasFooMessage());
+      builder.getFooMessageBuilder().setQuxInt(123);
+      assertTrue(builder.hasFooMessage());
+      assertEquals(builder.getFooMessage().getQuxInt(), 123);
+      message = builder.build();
+      assertTrue(message.hasFooMessage());
+      assertEquals(message.getFooMessage().getQuxInt(), 123);
+    }
+
+    // LazyMessage is tested in LazyMessageLiteTest.java
+  }
+
+  public void testOneofMerge() throws Exception {
+    // Primitive Type
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      TestOneof2 message = builder.setFooInt(123).build();
+      TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
+      assertTrue(message2.hasFooInt());
+      assertEquals(message2.getFooInt(), 123);
+    }
+
+    // String
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      TestOneof2 message = builder.setFooString("foo").build();
+      TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
+      assertTrue(message2.hasFooString());
+      assertEquals(message2.getFooString(), "foo");
+    }
+
+    // Enum
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build();
+      TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
+      assertTrue(message2.hasFooEnum());
+      assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.BAR);
+    }
+
+    // Message
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      TestOneof2 message = builder.setFooMessage(
+          TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).build();
+      TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
+      assertTrue(message2.hasFooMessage());
+      assertEquals(message2.getFooMessage().getQuxInt(), 234);
+    }
+  }
+
+  public void testOneofSerialization() throws Exception {
+    // Primitive Type
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      TestOneof2 message = builder.setFooInt(123).build();
+      ByteString serialized = message.toByteString();
+      TestOneof2 message2 = TestOneof2.parseFrom(serialized);
+      assertTrue(message2.hasFooInt());
+      assertEquals(message2.getFooInt(), 123);
+    }
+
+    // String
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      TestOneof2 message = builder.setFooString("foo").build();
+      ByteString serialized = message.toByteString();
+      TestOneof2 message2 = TestOneof2.parseFrom(serialized);
+      assertTrue(message2.hasFooString());
+      assertEquals(message2.getFooString(), "foo");
+    }
+
+    // Enum
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build();
+      ByteString serialized = message.toByteString();
+      TestOneof2 message2 = TestOneof2.parseFrom(serialized);
+      assertTrue(message2.hasFooEnum());
+      assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.BAR);
+    }
+
+    // Message
+    {
+      TestOneof2.Builder builder = TestOneof2.newBuilder();
+      TestOneof2 message = builder.setFooMessage(
+          TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).build();
+      ByteString serialized = message.toByteString();
+      TestOneof2 message2 = TestOneof2.parseFrom(serialized);
+      assertTrue(message2.hasFooMessage());
+      assertEquals(message2.getFooMessage().getQuxInt(), 234);
+    }
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java b/protobuf/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java
new file mode 100644
index 0000000..89b6451
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/IsValidUtf8Test.java
@@ -0,0 +1,180 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.IsValidUtf8TestUtil.Shard;
+
+import junit.framework.TestCase;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Tests cases for {@link ByteString#isValidUtf8()}. This includes three
+ * brute force tests that actually test every permutation of one byte, two byte,
+ * and three byte sequences to ensure that the method produces the right result
+ * for every possible byte encoding where "right" means it's consistent with
+ * java's UTF-8 string encoding/decoding such that the method returns true for
+ * any sequence that will round trip when converted to a String and then back to
+ * bytes and will return false for any sequence that will not round trip.
+ * See also {@link IsValidUtf8FourByteTest}. It also includes some
+ * other more targeted tests.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ * @author martinrb@google.com (Martin Buchholz)
+ */
+public class IsValidUtf8Test extends TestCase {
+
+  /**
+   * Tests that round tripping of all two byte permutations work.
+   */
+  public void testIsValidUtf8_1Byte() throws UnsupportedEncodingException {
+    IsValidUtf8TestUtil.testBytes(1,
+        IsValidUtf8TestUtil.EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT);
+  }
+
+  /**
+   * Tests that round tripping of all two byte permutations work.
+   */
+  public void testIsValidUtf8_2Bytes() throws UnsupportedEncodingException {
+    IsValidUtf8TestUtil.testBytes(2,
+        IsValidUtf8TestUtil.EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT);
+  }
+
+  /**
+   * Tests that round tripping of all three byte permutations work.
+   */
+  public void testIsValidUtf8_3Bytes() throws UnsupportedEncodingException {
+    IsValidUtf8TestUtil.testBytes(3,
+        IsValidUtf8TestUtil.EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT);
+  }
+
+  /**
+   * Tests that round tripping of a sample of four byte permutations work.
+   * All permutations are prohibitively expensive to test for automated runs;
+   * {@link IsValidUtf8FourByteTest} is used for full coverage. This method
+   * tests specific four-byte cases.
+   */
+  public void testIsValidUtf8_4BytesSamples()
+      throws UnsupportedEncodingException {
+    // Valid 4 byte.
+    assertValidUtf8(0xF0, 0xA4, 0xAD, 0xA2);
+
+    // Bad trailing bytes
+    assertInvalidUtf8(0xF0, 0xA4, 0xAD, 0x7F);
+    assertInvalidUtf8(0xF0, 0xA4, 0xAD, 0xC0);
+
+    // Special cases for byte2
+    assertInvalidUtf8(0xF0, 0x8F, 0xAD, 0xA2);
+    assertInvalidUtf8(0xF4, 0x90, 0xAD, 0xA2);
+  }
+
+  /**
+   * Tests some hard-coded test cases.
+   */
+  public void testSomeSequences() {
+    // Empty
+    assertTrue(asBytes("").isValidUtf8());
+
+    // One-byte characters, including control characters
+    assertTrue(asBytes("\u0000abc\u007f").isValidUtf8());
+
+    // Two-byte characters
+    assertTrue(asBytes("\u00a2\u00a2").isValidUtf8());
+
+    // Three-byte characters
+    assertTrue(asBytes("\u020ac\u020ac").isValidUtf8());
+
+    // Four-byte characters
+    assertTrue(asBytes("\u024B62\u024B62").isValidUtf8());
+
+    // Mixed string
+    assertTrue(
+        asBytes("a\u020ac\u00a2b\\u024B62u020acc\u00a2de\u024B62")
+        .isValidUtf8());
+
+    // Not a valid string
+    assertInvalidUtf8(-1, 0, -1, 0);
+  }
+
+  private byte[] toByteArray(int... bytes) {
+    byte[] realBytes = new byte[bytes.length];
+    for (int i = 0; i < bytes.length; i++) {
+      realBytes[i] = (byte) bytes[i];
+    }
+    return realBytes;
+  }
+
+  private ByteString toByteString(int... bytes) {
+    return ByteString.copyFrom(toByteArray(bytes));
+  }
+
+  private void assertValidUtf8(int[] bytes, boolean not) {
+    byte[] realBytes = toByteArray(bytes);
+    assertTrue(not ^ Utf8.isValidUtf8(realBytes));
+    assertTrue(not ^ Utf8.isValidUtf8(realBytes, 0, bytes.length));
+    ByteString lit = ByteString.copyFrom(realBytes);
+    ByteString sub = lit.substring(0, bytes.length);
+    assertTrue(not ^ lit.isValidUtf8());
+    assertTrue(not ^ sub.isValidUtf8());
+    ByteString[] ropes = {
+      RopeByteString.newInstanceForTest(ByteString.EMPTY, lit),
+      RopeByteString.newInstanceForTest(ByteString.EMPTY, sub),
+      RopeByteString.newInstanceForTest(lit, ByteString.EMPTY),
+      RopeByteString.newInstanceForTest(sub, ByteString.EMPTY),
+      RopeByteString.newInstanceForTest(sub, lit)
+    };
+    for (ByteString rope : ropes) {
+      assertTrue(not ^ rope.isValidUtf8());
+    }
+  }
+
+  private void assertValidUtf8(int... bytes) {
+    assertValidUtf8(bytes, false);
+  }
+
+  private void assertInvalidUtf8(int... bytes) {
+    assertValidUtf8(bytes, true);
+  }
+
+  private static ByteString asBytes(String s) {
+    return ByteString.copyFromUtf8(s);
+  }
+
+  public void testShardsHaveExpectedRoundTrippables() {
+    // A sanity check.
+    int actual = 0;
+    for (Shard shard : IsValidUtf8TestUtil.FOUR_BYTE_SHARDS) {
+      actual += shard.expected;
+    }
+    assertEquals(IsValidUtf8TestUtil.EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT,
+        actual);
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java b/protobuf/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java
new file mode 100644
index 0000000..f41595e
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/IsValidUtf8TestUtil.java
@@ -0,0 +1,421 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import static junit.framework.Assert.*;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.logging.Logger;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.Charset;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CoderResult;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+
+/**
+ * Shared testing code for {@link IsValidUtf8Test} and
+ * {@link IsValidUtf8FourByteTest}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ * @author martinrb@google.com (Martin Buchholz)
+ */
+class IsValidUtf8TestUtil {
+  private static Logger logger = Logger.getLogger(
+      IsValidUtf8TestUtil.class.getName());
+
+  // 128 - [chars 0x0000 to 0x007f]
+  static long ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x007f - 0x0000 + 1;
+
+  // 128
+  static long EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT =
+      ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS;
+
+  // 1920 [chars 0x0080 to 0x07FF]
+  static long TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x07FF - 0x0080 + 1;
+
+  // 18,304
+  static long EXPECTED_TWO_BYTE_ROUNDTRIPPABLE_COUNT =
+      // Both bytes are one byte characters
+      (long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 2) +
+      // The possible number of two byte characters
+      TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS;
+
+  // 2048
+  static long THREE_BYTE_SURROGATES = 2 * 1024;
+
+  // 61,440 [chars 0x0800 to 0xFFFF, minus surrogates]
+  static long THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS =
+      0xFFFF - 0x0800 + 1 - THREE_BYTE_SURROGATES;
+
+  // 2,650,112
+  static long EXPECTED_THREE_BYTE_ROUNDTRIPPABLE_COUNT =
+      // All one byte characters
+      (long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 3) +
+      // One two byte character and a one byte character
+      2 * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS *
+          ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS +
+       // Three byte characters
+      THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS;
+
+  // 1,048,576 [chars 0x10000L to 0x10FFFF]
+  static long FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS = 0x10FFFF - 0x10000L + 1;
+
+  // 289,571,839
+  static long EXPECTED_FOUR_BYTE_ROUNDTRIPPABLE_COUNT =
+      // All one byte characters
+      (long) Math.pow(EXPECTED_ONE_BYTE_ROUNDTRIPPABLE_COUNT, 4) +
+      // One and three byte characters
+      2 * THREE_BYTE_ROUNDTRIPPABLE_CHARACTERS *
+          ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS +
+      // Two two byte characters
+      TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS +
+      // Permutations of one and two byte characters
+      3 * TWO_BYTE_ROUNDTRIPPABLE_CHARACTERS *
+          ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS *
+          ONE_BYTE_ROUNDTRIPPABLE_CHARACTERS +
+      // Four byte characters
+      FOUR_BYTE_ROUNDTRIPPABLE_CHARACTERS;
+
+  static class Shard {
+    final long index;
+    final long start;
+    final long lim;
+    final long expected;
+
+
+    public Shard(long index, long start, long lim, long expected) {
+      assertTrue(start < lim);
+      this.index = index;
+      this.start = start;
+      this.lim = lim;
+      this.expected = expected;
+    }
+  }
+
+  static final long[] FOUR_BYTE_SHARDS_EXPECTED_ROUNTRIPPABLES =
+      generateFourByteShardsExpectedRunnables();
+
+  private static long[] generateFourByteShardsExpectedRunnables() {
+    long[] expected = new long[128];
+
+    // 0-63 are all 5300224
+    for (int i = 0; i <= 63; i++) {
+      expected[i] = 5300224;
+    }
+
+    // 97-111 are all 2342912
+    for (int i = 97; i <= 111; i++) {
+     expected[i] = 2342912;
+    }
+
+    // 113-117 are all 1048576
+    for (int i = 113; i <= 117; i++) {
+      expected[i] = 1048576;
+    }
+
+    // One offs
+    expected[112] = 786432;
+    expected[118] = 786432;
+    expected[119] = 1048576;
+    expected[120] = 458752;
+    expected[121] = 524288;
+    expected[122] = 65536;
+
+    // Anything not assigned was the default 0.
+    return expected;
+  }
+
+  static final List<Shard> FOUR_BYTE_SHARDS = generateFourByteShards(
+      128, FOUR_BYTE_SHARDS_EXPECTED_ROUNTRIPPABLES);
+
+
+  private static List<Shard> generateFourByteShards(
+      int numShards, long[] expected) {
+    assertEquals(numShards, expected.length);
+    List<Shard> shards = new ArrayList<Shard>(numShards);
+    long LIM = 1L << 32;
+    long increment = LIM / numShards;
+    assertTrue(LIM % numShards == 0);
+    for (int i = 0; i < numShards; i++) {
+      shards.add(new Shard(i,
+          increment * i,
+          increment * (i + 1),
+          expected[i]));
+    }
+    return shards;
+  }
+
+  /**
+   * Helper to run the loop to test all the permutations for the number of bytes
+   * specified.
+   *
+   * @param numBytes the number of bytes in the byte array
+   * @param expectedCount the expected number of roundtrippable permutations
+   */
+  static void testBytes(int numBytes, long expectedCount)
+      throws UnsupportedEncodingException {
+    testBytes(numBytes, expectedCount, 0, -1);
+  }
+
+  /**
+   * Helper to run the loop to test all the permutations for the number of bytes
+   * specified. This overload is useful for debugging to get the loop to start
+   * at a certain character.
+   *
+   * @param numBytes the number of bytes in the byte array
+   * @param expectedCount the expected number of roundtrippable permutations
+   * @param start the starting bytes encoded as a long as big-endian
+   * @param lim the limit of bytes to process encoded as a long as big-endian,
+   *     or -1 to mean the max limit for numBytes
+   */
+  static void testBytes(int numBytes, long expectedCount, long start, long lim)
+      throws UnsupportedEncodingException {
+    Random rnd = new Random();
+    byte[] bytes = new byte[numBytes];
+
+    if (lim == -1) {
+      lim = 1L << (numBytes * 8);
+    }
+    long count = 0;
+    long countRoundTripped = 0;
+    for (long byteChar = start; byteChar < lim; byteChar++) {
+      long tmpByteChar = byteChar;
+      for (int i = 0; i < numBytes; i++) {
+        bytes[bytes.length - i - 1] = (byte) tmpByteChar;
+        tmpByteChar = tmpByteChar >> 8;
+      }
+      ByteString bs = ByteString.copyFrom(bytes);
+      boolean isRoundTrippable = bs.isValidUtf8();
+      String s = new String(bytes, "UTF-8");
+      byte[] bytesReencoded = s.getBytes("UTF-8");
+      boolean bytesEqual = Arrays.equals(bytes, bytesReencoded);
+
+      if (bytesEqual != isRoundTrippable) {
+        outputFailure(byteChar, bytes, bytesReencoded);
+      }
+
+      // Check agreement with static Utf8 methods.
+      assertEquals(isRoundTrippable, Utf8.isValidUtf8(bytes));
+      assertEquals(isRoundTrippable, Utf8.isValidUtf8(bytes, 0, numBytes));
+
+      // Test partial sequences.
+      // Partition numBytes into three segments (not necessarily non-empty).
+      int i = rnd.nextInt(numBytes);
+      int j = rnd.nextInt(numBytes);
+      if (j < i) {
+        int tmp = i; i = j; j = tmp;
+      }
+      int state1 = Utf8.partialIsValidUtf8(Utf8.COMPLETE, bytes, 0, i);
+      int state2 = Utf8.partialIsValidUtf8(state1, bytes, i, j);
+      int state3 = Utf8.partialIsValidUtf8(state2, bytes, j, numBytes);
+      if (isRoundTrippable != (state3 == Utf8.COMPLETE)) {
+        System.out.printf("state=%04x %04x %04x i=%d j=%d%n",
+                          state1, state2, state3, i, j);
+        outputFailure(byteChar, bytes, bytesReencoded);
+      }
+      assertEquals(isRoundTrippable, (state3 == Utf8.COMPLETE));
+
+      // Test ropes built out of small partial sequences
+      ByteString rope = RopeByteString.newInstanceForTest(
+          bs.substring(0, i),
+          RopeByteString.newInstanceForTest(
+              bs.substring(i, j),
+              bs.substring(j, numBytes)));
+      assertSame(RopeByteString.class, rope.getClass());
+
+      ByteString[] byteStrings = { bs, bs.substring(0, numBytes), rope };
+      for (ByteString x : byteStrings) {
+        assertEquals(isRoundTrippable,
+                     x.isValidUtf8());
+        assertEquals(state3,
+                     x.partialIsValidUtf8(Utf8.COMPLETE, 0, numBytes));
+
+        assertEquals(state1,
+                     x.partialIsValidUtf8(Utf8.COMPLETE, 0, i));
+        assertEquals(state1,
+                     x.substring(0, i).partialIsValidUtf8(Utf8.COMPLETE, 0, i));
+        assertEquals(state2,
+                     x.partialIsValidUtf8(state1, i, j - i));
+        assertEquals(state2,
+                     x.substring(i, j).partialIsValidUtf8(state1, 0, j - i));
+        assertEquals(state3,
+                     x.partialIsValidUtf8(state2, j, numBytes - j));
+        assertEquals(state3,
+                     x.substring(j, numBytes)
+                     .partialIsValidUtf8(state2, 0, numBytes - j));
+      }
+
+      // ByteString reduplication should not affect its UTF-8 validity.
+      ByteString ropeADope =
+          RopeByteString.newInstanceForTest(bs, bs.substring(0, numBytes));
+      assertEquals(isRoundTrippable, ropeADope.isValidUtf8());
+
+      if (isRoundTrippable) {
+        countRoundTripped++;
+      }
+      count++;
+      if (byteChar != 0 && byteChar % 1000000L == 0) {
+        logger.info("Processed " + (byteChar / 1000000L) +
+            " million characters");
+      }
+    }
+    logger.info("Round tripped " + countRoundTripped + " of " + count);
+    assertEquals(expectedCount, countRoundTripped);
+  }
+
+  /**
+   * Variation of {@link #testBytes} that does less allocation using the
+   * low-level encoders/decoders directly. Checked in because it's useful for
+   * debugging when trying to process bytes faster, but since it doesn't use the
+   * actual String class, it's possible for incompatibilities to develop
+   * (although unlikely).
+   *
+   * @param numBytes the number of bytes in the byte array
+   * @param expectedCount the expected number of roundtrippable permutations
+   * @param start the starting bytes encoded as a long as big-endian
+   * @param lim the limit of bytes to process encoded as a long as big-endian,
+   *     or -1 to mean the max limit for numBytes
+   */
+  void testBytesUsingByteBuffers(
+      int numBytes, long expectedCount, long start, long lim)
+      throws UnsupportedEncodingException {
+    CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder()
+        .onMalformedInput(CodingErrorAction.REPLACE)
+        .onUnmappableCharacter(CodingErrorAction.REPLACE);
+    CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder()
+        .onMalformedInput(CodingErrorAction.REPLACE)
+        .onUnmappableCharacter(CodingErrorAction.REPLACE);
+    byte[] bytes = new byte[numBytes];
+    int maxChars = (int) (decoder.maxCharsPerByte() * numBytes) + 1;
+    char[] charsDecoded =
+        new char[(int) (decoder.maxCharsPerByte() * numBytes) + 1];
+    int maxBytes = (int) (encoder.maxBytesPerChar() * maxChars) + 1;
+    byte[] bytesReencoded = new byte[maxBytes];
+
+    ByteBuffer bb = ByteBuffer.wrap(bytes);
+    CharBuffer cb = CharBuffer.wrap(charsDecoded);
+    ByteBuffer bbReencoded = ByteBuffer.wrap(bytesReencoded);
+    if (lim == -1) {
+      lim = 1L << (numBytes * 8);
+    }
+    long count = 0;
+    long countRoundTripped = 0;
+    for (long byteChar = start; byteChar < lim; byteChar++) {
+      bb.rewind();
+      bb.limit(bytes.length);
+      cb.rewind();
+      cb.limit(charsDecoded.length);
+      bbReencoded.rewind();
+      bbReencoded.limit(bytesReencoded.length);
+      encoder.reset();
+      decoder.reset();
+      long tmpByteChar = byteChar;
+      for (int i = 0; i < bytes.length; i++) {
+        bytes[bytes.length - i - 1] = (byte) tmpByteChar;
+        tmpByteChar = tmpByteChar >> 8;
+      }
+      boolean isRoundTrippable = ByteString.copyFrom(bytes).isValidUtf8();
+      CoderResult result = decoder.decode(bb, cb, true);
+      assertFalse(result.isError());
+      result = decoder.flush(cb);
+      assertFalse(result.isError());
+
+      int charLen = cb.position();
+      cb.rewind();
+      cb.limit(charLen);
+      result = encoder.encode(cb, bbReencoded, true);
+      assertFalse(result.isError());
+      result = encoder.flush(bbReencoded);
+      assertFalse(result.isError());
+
+      boolean bytesEqual = true;
+      int bytesLen = bbReencoded.position();
+      if (bytesLen != numBytes) {
+        bytesEqual = false;
+      } else {
+        for (int i = 0; i < numBytes; i++) {
+          if (bytes[i] != bytesReencoded[i]) {
+            bytesEqual = false;
+            break;
+          }
+        }
+      }
+      if (bytesEqual != isRoundTrippable) {
+        outputFailure(byteChar, bytes, bytesReencoded, bytesLen);
+      }
+
+      count++;
+      if (isRoundTrippable) {
+        countRoundTripped++;
+      }
+      if (byteChar != 0 && byteChar % 1000000 == 0) {
+        logger.info("Processed " + (byteChar / 1000000) +
+            " million characters");
+      }
+    }
+    logger.info("Round tripped " + countRoundTripped + " of " + count);
+    assertEquals(expectedCount, countRoundTripped);
+  }
+
+  private static void outputFailure(long byteChar, byte[] bytes, byte[] after) {
+    outputFailure(byteChar, bytes, after, after.length);
+  }
+
+  private static void outputFailure(long byteChar, byte[] bytes, byte[] after,
+      int len) {
+    fail("Failure: (" + Long.toHexString(byteChar) + ") " +
+        toHexString(bytes) + " => " + toHexString(after, len));
+  }
+
+  private static String toHexString(byte[] b) {
+    return toHexString(b, b.length);
+  }
+
+  private static String toHexString(byte[] b, int len) {
+    StringBuilder s = new StringBuilder();
+    s.append("\"");
+    for (int i = 0; i < len; i++) {
+      if (i > 0) {
+        s.append(" ");
+      }
+      s.append(String.format("%02x", b[i] & 0xFF));
+    }
+    s.append("\"");
+    return s.toString();
+  }
+
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java b/protobuf/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
new file mode 100644
index 0000000..e67c6d2
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/LazyFieldLiteTest.java
@@ -0,0 +1,134 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+
+/**
+ * Unit test for {@link LazyFieldLite}.
+ *
+ * @author xiangl@google.com (Xiang Li)
+ */
+public class LazyFieldLiteTest extends TestCase {
+
+  public void testGetValue() {
+    MessageLite message = TestUtil.getAllSet();
+    LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+    assertEquals(message, lazyField.getValue(TestAllTypes.getDefaultInstance()));
+    changeValue(lazyField);
+    assertNotEqual(message, lazyField.getValue(TestAllTypes.getDefaultInstance()));
+  }
+
+  public void testGetValueEx() throws Exception {
+    TestAllExtensions message = TestUtil.getAllExtensionsSet();
+    LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+    assertEquals(message, lazyField.getValue(TestAllExtensions.getDefaultInstance()));
+    changeValue(lazyField);
+    assertNotEqual(message, lazyField.getValue(TestAllExtensions.getDefaultInstance()));
+  }
+
+  public void testSetValue() {
+    MessageLite message = TestUtil.getAllSet();
+    LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+    changeValue(lazyField);
+    assertNotEqual(message, lazyField.getValue(TestAllTypes.getDefaultInstance()));
+    message = lazyField.getValue(TestAllTypes.getDefaultInstance());
+    changeValue(lazyField);
+    assertEquals(message, lazyField.getValue(TestAllTypes.getDefaultInstance()));
+  }
+
+  public void testSetValueEx() throws Exception {
+    TestAllExtensions message = TestUtil.getAllExtensionsSet();
+    LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+    changeValue(lazyField);
+    assertNotEqual(message, lazyField.getValue(TestAllExtensions.getDefaultInstance()));
+    MessageLite value = lazyField.getValue(TestAllExtensions.getDefaultInstance());
+    changeValue(lazyField);
+    assertEquals(value, lazyField.getValue(TestAllExtensions.getDefaultInstance()));
+  }
+
+  public void testGetSerializedSize() {
+    MessageLite message = TestUtil.getAllSet();
+    LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+    assertEquals(message.getSerializedSize(), lazyField.getSerializedSize());
+    changeValue(lazyField);
+    assertNotEqual(message.getSerializedSize(), lazyField.getSerializedSize());
+  }
+
+  public void testGetSerializedSizeEx() throws Exception {
+    TestAllExtensions message = TestUtil.getAllExtensionsSet();
+    LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+    assertEquals(message.getSerializedSize(), lazyField.getSerializedSize());
+    changeValue(lazyField);
+    assertNotEqual(message.getSerializedSize(), lazyField.getSerializedSize());
+  }
+
+  public void testGetByteString() {
+    MessageLite message = TestUtil.getAllSet();
+    LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+    assertEquals(message.toByteString(), lazyField.toByteString());
+    changeValue(lazyField);
+    assertNotEqual(message.toByteString(), lazyField.toByteString());
+  }
+
+  public void testGetByteStringEx() throws Exception {
+    TestAllExtensions message = TestUtil.getAllExtensionsSet();
+    LazyFieldLite lazyField = createLazyFieldLiteFromMessage(message);
+    assertEquals(message.toByteString(), lazyField.toByteString());
+    changeValue(lazyField);
+    assertNotEqual(message.toByteString(), lazyField.toByteString());
+  }
+
+
+  // Help methods.
+
+  private LazyFieldLite createLazyFieldLiteFromMessage(MessageLite message) {
+    ByteString bytes = message.toByteString();
+    return new LazyFieldLite(TestUtil.getExtensionRegistry(), bytes);
+  }
+
+  private void changeValue(LazyFieldLite lazyField) {
+    TestAllTypes.Builder builder = TestUtil.getAllSet().toBuilder();
+    builder.addRepeatedBool(true);
+    MessageLite newMessage = builder.build();
+    lazyField.setValue(newMessage);
+  }
+
+  private void assertNotEqual(Object unexpected, Object actual) {
+    assertFalse(unexpected == actual
+        || (unexpected != null && unexpected.equals(actual)));
+  }
+
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/LazyFieldTest.java b/protobuf/java/src/test/java/com/google/protobuf/LazyFieldTest.java
new file mode 100644
index 0000000..2b90006
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/LazyFieldTest.java
@@ -0,0 +1,121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+
+import java.io.IOException;
+import junit.framework.TestCase;
+
+/**
+ * Unit test for {@link LazyField}.
+ *
+ * @author xiangl@google.com (Xiang Li)
+ */
+public class LazyFieldTest extends TestCase {
+  public void testHashCode() {
+    MessageLite message = TestUtil.getAllSet();
+    LazyField lazyField =
+        createLazyFieldFromMessage(message);
+    assertEquals(message.hashCode(), lazyField.hashCode());
+    lazyField.getValue();
+    assertEquals(message.hashCode(), lazyField.hashCode());
+    changeValue(lazyField);
+    // make sure two messages have different hash code
+    assertNotEqual(message.hashCode(), lazyField.hashCode());
+  }
+
+  public void testHashCodeEx() throws Exception {
+    TestAllExtensions message = TestUtil.getAllExtensionsSet();
+    LazyField lazyField = createLazyFieldFromMessage(message);
+    assertEquals(message.hashCode(), lazyField.hashCode());
+    lazyField.getValue();
+    assertEquals(message.hashCode(), lazyField.hashCode());
+    changeValue(lazyField);
+    // make sure two messages have different hash code
+    assertNotEqual(message.hashCode(), lazyField.hashCode());
+  }
+
+  public void testGetValue() {
+    MessageLite message = TestUtil.getAllSet();
+    LazyField lazyField = createLazyFieldFromMessage(message);
+    assertEquals(message, lazyField.getValue());
+    changeValue(lazyField);
+    assertNotEqual(message, lazyField.getValue());
+  }
+
+  public void testGetValueEx() throws Exception {
+    TestAllExtensions message = TestUtil.getAllExtensionsSet();
+    LazyField lazyField = createLazyFieldFromMessage(message);
+    assertEquals(message, lazyField.getValue());
+    changeValue(lazyField);
+    assertNotEqual(message, lazyField.getValue());
+  }
+
+  public void testEqualsObject() {
+    MessageLite message = TestUtil.getAllSet();
+    LazyField lazyField = createLazyFieldFromMessage(message);
+    assertTrue(lazyField.equals(message));
+    changeValue(lazyField);
+    assertFalse(lazyField.equals(message));
+    assertFalse(message.equals(lazyField.getValue()));
+  }
+
+  public void testEqualsObjectEx() throws Exception {
+    TestAllExtensions message = TestUtil.getAllExtensionsSet();
+    LazyField lazyField = createLazyFieldFromMessage(message);
+    assertTrue(lazyField.equals(message));
+    changeValue(lazyField);
+    assertFalse(lazyField.equals(message));
+    assertFalse(message.equals(lazyField.getValue()));
+  }
+
+  // Help methods.
+
+  private LazyField createLazyFieldFromMessage(MessageLite message) {
+    ByteString bytes = message.toByteString();
+    return new LazyField(message.getDefaultInstanceForType(),
+        TestUtil.getExtensionRegistry(), bytes);
+  }
+
+  private void changeValue(LazyField lazyField) {
+    TestAllTypes.Builder builder = TestUtil.getAllSet().toBuilder();
+    builder.addRepeatedBool(true);
+    MessageLite newMessage = builder.build();
+    lazyField.setValue(newMessage);
+  }
+
+  private void assertNotEqual(Object unexpected, Object actual) {
+    assertFalse(unexpected == actual
+        || (unexpected != null && unexpected.equals(actual)));
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java b/protobuf/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
new file mode 100644
index 0000000..00e3a84
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/LazyMessageLiteTest.java
@@ -0,0 +1,319 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.LazyFieldsLite.LazyInnerMessageLite;
+import protobuf_unittest.LazyFieldsLite.LazyMessageLite;
+import protobuf_unittest.LazyFieldsLite.LazyNestedInnerMessageLite;
+
+import junit.framework.TestCase;
+
+import org.easymock.classextension.EasyMock;
+
+import java.util.ArrayList;
+
+/**
+ * Unit test for messages with lazy fields.
+ *
+ * @author niwasaki@google.com (Naoki Iwasaki)
+ */
+public class LazyMessageLiteTest extends TestCase {
+
+  private Parser<LazyInnerMessageLite> originalLazyInnerMessageLiteParser;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    originalLazyInnerMessageLiteParser = LazyInnerMessageLite.PARSER;
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    LazyInnerMessageLite.PARSER = originalLazyInnerMessageLiteParser;
+
+    super.tearDown();
+  }
+
+  public void testSetValues() {
+    LazyNestedInnerMessageLite nested = LazyNestedInnerMessageLite.newBuilder()
+        .setNum(3)
+        .build();
+    LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder()
+        .setNum(2)
+        .setNested(nested)
+        .build();
+    LazyMessageLite outer = LazyMessageLite.newBuilder()
+        .setNum(1)
+        .setInner(inner)
+        .setOneofNum(123)
+        .setOneofInner(inner)
+        .build();
+
+    assertEquals(1, outer.getNum());
+    assertEquals(421, outer.getNumWithDefault());
+
+    assertEquals(2, outer.getInner().getNum());
+    assertEquals(42, outer.getInner().getNumWithDefault());
+
+    assertEquals(3, outer.getInner().getNested().getNum());
+    assertEquals(4, outer.getInner().getNested().getNumWithDefault());
+
+    assertFalse(outer.hasOneofNum());
+    assertTrue(outer.hasOneofInner());
+
+    assertEquals(2, outer.getOneofInner().getNum());
+    assertEquals(42, outer.getOneofInner().getNumWithDefault());
+    assertEquals(3, outer.getOneofInner().getNested().getNum());
+    assertEquals(4, outer.getOneofInner().getNested().getNumWithDefault());
+  }
+
+  public void testSetRepeatedValues() {
+    LazyMessageLite outer = LazyMessageLite.newBuilder()
+        .setNum(1)
+        .addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(119))
+        .addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(122))
+        .build();
+
+    assertEquals(1, outer.getNum());
+    assertEquals(2, outer.getRepeatedInnerCount());
+    assertEquals(119, outer.getRepeatedInner(0).getNum());
+    assertEquals(122, outer.getRepeatedInner(1).getNum());
+  }
+
+  public void testAddAll() {
+    ArrayList<LazyInnerMessageLite> inners = new ArrayList<LazyInnerMessageLite>();
+    int count = 4;
+    for (int i = 0; i < count; i++) {
+      LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder()
+          .setNum(i)
+          .build();
+      inners.add(inner);
+    }
+
+    LazyMessageLite outer = LazyMessageLite.newBuilder()
+        .addAllRepeatedInner(inners)
+        .build();
+    assertEquals(count, outer.getRepeatedInnerCount());
+    for (int i = 0; i < count; i++) {
+      assertEquals(i, outer.getRepeatedInner(i).getNum());
+    }
+  }
+
+  public void testGetDefaultValues() {
+    LazyMessageLite outer = LazyMessageLite.newBuilder()
+        .build();
+
+    assertEquals(0, outer.getNum());
+    assertEquals(421, outer.getNumWithDefault());
+
+    assertEquals(0, outer.getInner().getNum());
+    assertEquals(42, outer.getInner().getNumWithDefault());
+
+    assertEquals(0, outer.getInner().getNested().getNum());
+    assertEquals(4, outer.getInner().getNested().getNumWithDefault());
+
+    assertEquals(0, outer.getOneofNum());
+
+    assertEquals(0, outer.getOneofInner().getNum());
+    assertEquals(42, outer.getOneofInner().getNumWithDefault());
+    assertEquals(0, outer.getOneofInner().getNested().getNum());
+    assertEquals(4, outer.getOneofInner().getNested().getNumWithDefault());
+  }
+
+  public void testClearValues() {
+    LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder()
+        .setNum(115)
+        .build();
+
+    LazyMessageLite.Builder outerBuilder = LazyMessageLite.newBuilder();
+
+    assertEquals(0, outerBuilder.build().getNum());
+
+
+    // Set/Clear num
+    outerBuilder.setNum(100);
+
+    assertEquals(100, outerBuilder.build().getNum());
+    assertEquals(421, outerBuilder.build().getNumWithDefault());
+    assertFalse(outerBuilder.build().hasInner());
+
+    outerBuilder.clearNum();
+
+    assertEquals(0, outerBuilder.build().getNum());
+    assertEquals(421, outerBuilder.build().getNumWithDefault());
+    assertFalse(outerBuilder.build().hasInner());
+
+
+    // Set/Clear all
+    outerBuilder.setNum(100)
+        .setInner(inner)
+        .addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(119))
+        .addRepeatedInner(LazyInnerMessageLite.newBuilder().setNum(122))
+        .setOneofInner(LazyInnerMessageLite.newBuilder().setNum(123));
+
+    LazyMessageLite outer = outerBuilder.build();
+    assertEquals(100, outer.getNum());
+    assertEquals(421, outer.getNumWithDefault());
+    assertTrue(outer.hasInner());
+    assertEquals(115, outer.getInner().getNum());
+    assertEquals(2, outer.getRepeatedInnerCount());
+    assertEquals(119, outer.getRepeatedInner(0).getNum());
+    assertEquals(122, outer.getRepeatedInner(1).getNum());
+    assertTrue(outer.hasOneofInner());
+    assertEquals(123, outer.getOneofInner().getNum());
+
+    outerBuilder.clear();
+
+    outer = outerBuilder.build();
+
+    assertEquals(0, outer.getNum());
+    assertEquals(421, outer.getNumWithDefault());
+    assertFalse(outer.hasInner());
+    assertEquals(0, outer.getRepeatedInnerCount());
+    assertFalse(outer.hasOneofInner());
+    assertEquals(0, outer.getOneofInner().getNum());
+  }
+
+  public void testMergeValues() {
+    LazyMessageLite outerBase = LazyMessageLite.newBuilder()
+        .setNumWithDefault(122)
+        .build();
+
+    LazyInnerMessageLite innerMerging = LazyInnerMessageLite.newBuilder()
+        .setNum(115)
+        .build();
+    LazyMessageLite outerMerging = LazyMessageLite.newBuilder()
+        .setNum(119)
+        .setInner(innerMerging)
+        .setOneofInner(innerMerging)
+        .build();
+
+    LazyMessageLite merged = LazyMessageLite
+        .newBuilder(outerBase)
+        .mergeFrom(outerMerging)
+        .build();
+    assertEquals(119, merged.getNum());
+    assertEquals(122, merged.getNumWithDefault());
+    assertEquals(115, merged.getInner().getNum());
+    assertEquals(42, merged.getInner().getNumWithDefault());
+    assertEquals(115, merged.getOneofInner().getNum());
+    assertEquals(42, merged.getOneofInner().getNumWithDefault());
+  }
+
+  public void testMergeDefaultValues() {
+    LazyInnerMessageLite innerBase = LazyInnerMessageLite.newBuilder()
+        .setNum(115)
+        .build();
+    LazyMessageLite outerBase = LazyMessageLite.newBuilder()
+        .setNum(119)
+        .setNumWithDefault(122)
+        .setInner(innerBase)
+        .setOneofInner(innerBase)
+        .build();
+
+    LazyMessageLite outerMerging = LazyMessageLite.newBuilder()
+        .build();
+
+    LazyMessageLite merged = LazyMessageLite
+        .newBuilder(outerBase)
+        .mergeFrom(outerMerging)
+        .build();
+    // Merging default-instance shouldn't overwrite values in the base message.
+    assertEquals(119, merged.getNum());
+    assertEquals(122, merged.getNumWithDefault());
+    assertEquals(115, merged.getInner().getNum());
+    assertEquals(42, merged.getInner().getNumWithDefault());
+    assertEquals(115, merged.getOneofInner().getNum());
+    assertEquals(42, merged.getOneofInner().getNumWithDefault());
+  }
+
+  public void testSerialize() throws InvalidProtocolBufferException {
+    LazyNestedInnerMessageLite nested = LazyNestedInnerMessageLite.newBuilder()
+        .setNum(3)
+        .build();
+    LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder()
+        .setNum(2)
+        .setNested(nested)
+        .build();
+    LazyMessageLite outer = LazyMessageLite.newBuilder()
+        .setNum(1)
+        .setInner(inner)
+        .setOneofInner(inner)
+        .build();
+
+    ByteString bytes = outer.toByteString();
+    assertEquals(bytes.size(), outer.getSerializedSize());
+
+    LazyMessageLite deserialized = LazyMessageLite.parseFrom(bytes);
+
+    assertEquals(1, deserialized.getNum());
+    assertEquals(421,  deserialized.getNumWithDefault());
+
+    assertEquals(2,  deserialized.getInner().getNum());
+    assertEquals(42,  deserialized.getInner().getNumWithDefault());
+
+    assertEquals(3,  deserialized.getInner().getNested().getNum());
+    assertEquals(4,  deserialized.getInner().getNested().getNumWithDefault());
+
+    assertEquals(2,  deserialized.getOneofInner().getNum());
+    assertEquals(42,  deserialized.getOneofInner().getNumWithDefault());
+    assertEquals(3,  deserialized.getOneofInner().getNested().getNum());
+    assertEquals(4,  deserialized.getOneofInner().getNested().getNumWithDefault());
+
+    assertEquals(bytes, deserialized.toByteString());
+  }
+
+  public void testLaziness() throws InvalidProtocolBufferException {
+    LazyInnerMessageLite inner = LazyInnerMessageLite.newBuilder()
+        .setNum(2)
+        .build();
+    LazyMessageLite outer = LazyMessageLite.newBuilder()
+        .setNum(1)
+        .setInner(inner)
+        .setOneofInner(inner)
+        .build();
+    ByteString bytes = outer.toByteString();
+
+
+    // The parser for inner / oneofInner message shouldn't be used if
+    // getInner / getOneofInner is not called.
+    LazyInnerMessageLite.PARSER = EasyMock.createStrictMock(Parser.class);
+
+    EasyMock.replay(LazyInnerMessageLite.PARSER);
+
+    LazyMessageLite deserialized = LazyMessageLite.parseFrom(bytes);
+    assertEquals(1, deserialized.getNum());
+    assertEquals(421,  deserialized.getNumWithDefault());
+
+    EasyMock.verify(LazyInnerMessageLite.PARSER);
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java b/protobuf/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
new file mode 100644
index 0000000..f3012b9
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/LazyStringArrayListTest.java
@@ -0,0 +1,174 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link LazyStringArrayList}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class LazyStringArrayListTest extends TestCase {
+
+  private static String STRING_A = "A";
+  private static String STRING_B = "B";
+  private static String STRING_C = "C";
+
+  private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A");
+  private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B");
+  private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C");
+
+  public void testJustStrings() {
+    LazyStringArrayList list = new LazyStringArrayList();
+    list.add(STRING_A);
+    list.add(STRING_B);
+    list.add(STRING_C);
+
+    assertEquals(3, list.size());
+    assertSame(STRING_A, list.get(0));
+    assertSame(STRING_B, list.get(1));
+    assertSame(STRING_C, list.get(2));
+
+    list.set(1, STRING_C);
+    assertSame(STRING_C, list.get(1));
+
+    list.remove(1);
+    assertSame(STRING_A, list.get(0));
+    assertSame(STRING_C, list.get(1));
+
+    List<ByteString> byteStringList = list.asByteStringList();
+    assertEquals(BYTE_STRING_A, byteStringList.get(0));
+    assertEquals(BYTE_STRING_C, byteStringList.get(1));
+
+    // Underlying list should be transformed.
+    assertSame(byteStringList.get(0), list.getByteString(0));
+    assertSame(byteStringList.get(1), list.getByteString(1));
+  }
+
+  public void testJustByteString() {
+    LazyStringArrayList list = new LazyStringArrayList();
+    list.add(BYTE_STRING_A);
+    list.add(BYTE_STRING_B);
+    list.add(BYTE_STRING_C);
+
+    assertEquals(3, list.size());
+    assertSame(BYTE_STRING_A, list.getByteString(0));
+    assertSame(BYTE_STRING_B, list.getByteString(1));
+    assertSame(BYTE_STRING_C, list.getByteString(2));
+
+    list.remove(1);
+    assertSame(BYTE_STRING_A, list.getByteString(0));
+    assertSame(BYTE_STRING_C, list.getByteString(1));
+
+    List<ByteString> byteStringList = list.asByteStringList();
+    assertSame(BYTE_STRING_A, byteStringList.get(0));
+    assertSame(BYTE_STRING_C, byteStringList.get(1));
+  }
+
+  public void testConversionBackAndForth() {
+    LazyStringArrayList list = new LazyStringArrayList();
+    list.add(STRING_A);
+    list.add(BYTE_STRING_B);
+    list.add(BYTE_STRING_C);
+
+    // String a should be the same because it was originally a string
+    assertSame(STRING_A, list.get(0));
+
+    // String b and c should be different because the string has to be computed
+    // from the ByteString
+    String bPrime = list.get(1);
+    assertNotSame(STRING_B, bPrime);
+    assertEquals(STRING_B, bPrime);
+    String cPrime = list.get(2);
+    assertNotSame(STRING_C, cPrime);
+    assertEquals(STRING_C, cPrime);
+
+    // String c and c should stay the same once cached.
+    assertSame(bPrime, list.get(1));
+    assertSame(cPrime, list.get(2));
+
+    // ByteString needs to be computed from string for both a and b
+    ByteString aPrimeByteString = list.getByteString(0);
+    assertEquals(BYTE_STRING_A, aPrimeByteString);
+    ByteString bPrimeByteString = list.getByteString(1);
+    assertNotSame(BYTE_STRING_B, bPrimeByteString);
+    assertEquals(BYTE_STRING_B, list.getByteString(1));
+
+    // Once cached, ByteString should stay cached.
+    assertSame(aPrimeByteString, list.getByteString(0));
+    assertSame(bPrimeByteString, list.getByteString(1));
+  }
+
+  public void testCopyConstructorCopiesByReference() {
+    LazyStringArrayList list1 = new LazyStringArrayList();
+    list1.add(STRING_A);
+    list1.add(BYTE_STRING_B);
+    list1.add(BYTE_STRING_C);
+
+    LazyStringArrayList list2 = new LazyStringArrayList(list1);
+    assertEquals(3, list2.size());
+    assertSame(STRING_A, list2.get(0));
+    assertSame(BYTE_STRING_B, list2.getByteString(1));
+    assertSame(BYTE_STRING_C, list2.getByteString(2));
+  }
+
+  public void testListCopyConstructor() {
+    List<String> list1 = new ArrayList<String>();
+    list1.add(STRING_A);
+    list1.add(STRING_B);
+    list1.add(STRING_C);
+
+    LazyStringArrayList list2 = new LazyStringArrayList(list1);
+    assertEquals(3, list2.size());
+    assertSame(STRING_A, list2.get(0));
+    assertSame(STRING_B, list2.get(1));
+    assertSame(STRING_C, list2.get(2));
+  }
+
+  public void testAddAllCopiesByReferenceIfPossible() {
+    LazyStringArrayList list1 = new LazyStringArrayList();
+    list1.add(STRING_A);
+    list1.add(BYTE_STRING_B);
+    list1.add(BYTE_STRING_C);
+
+    LazyStringArrayList list2 = new LazyStringArrayList();
+    list2.addAll(list1);
+
+    assertEquals(3, list2.size());
+    assertSame(STRING_A, list2.get(0));
+    assertSame(BYTE_STRING_B, list2.getByteString(1));
+    assertSame(BYTE_STRING_C, list2.getByteString(2));
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java b/protobuf/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
new file mode 100644
index 0000000..acd1800
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java
@@ -0,0 +1,143 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+
+import protobuf_unittest.UnittestProto;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+
+/**
+ * Tests to make sure the lazy conversion of UTF8-encoded byte arrays to
+ * strings works correctly.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class LazyStringEndToEndTest extends TestCase {
+
+  private static ByteString TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8 =
+      ByteString.copyFrom(new byte[] {
+          114, 4, -1, 0, -1, 0, -30, 2, 4, -1,
+          0, -1, 0, -30, 2, 4, -1, 0, -1, 0, });
+
+  private ByteString encodedTestAllTypes;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    this.encodedTestAllTypes = UnittestProto.TestAllTypes.newBuilder()
+        .setOptionalString("foo")
+        .addRepeatedString("bar")
+        .addRepeatedString("baz")
+        .build()
+        .toByteString();
+  }
+
+  /**
+   * Tests that an invalid UTF8 string will roundtrip through a parse
+   * and serialization.
+   */
+  public void testParseAndSerialize() throws InvalidProtocolBufferException {
+    UnittestProto.TestAllTypes tV2 = UnittestProto.TestAllTypes.parseFrom(
+        TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8);
+    ByteString bytes = tV2.toByteString();
+    assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes);
+
+    tV2.getOptionalString();
+    bytes = tV2.toByteString();
+    assertEquals(TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8, bytes);
+  }
+
+  public void testParseAndWrite() throws IOException {
+    UnittestProto.TestAllTypes tV2 = UnittestProto.TestAllTypes.parseFrom(
+        TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8);
+    byte[] sink = new byte[TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8.size()];
+    CodedOutputStream outputStream = CodedOutputStream.newInstance(sink);
+    tV2.writeTo(outputStream);
+    outputStream.flush();
+    assertEquals(
+        TEST_ALL_TYPES_SERIALIZED_WITH_ILLEGAL_UTF8,
+        ByteString.copyFrom(sink));
+  }
+
+  public void testCaching() {
+    String a = "a";
+    String b = "b";
+    String c = "c";
+    UnittestProto.TestAllTypes proto = UnittestProto.TestAllTypes.newBuilder()
+        .setOptionalString(a)
+        .addRepeatedString(b)
+        .addRepeatedString(c)
+        .build();
+
+    // String should be the one we passed it.
+    assertSame(a, proto.getOptionalString());
+    assertSame(b, proto.getRepeatedString(0));
+    assertSame(c, proto.getRepeatedString(1));
+
+
+    // There's no way to directly observe that the ByteString is cached
+    // correctly on serialization, but we can observe that it had to recompute
+    // the string after serialization.
+    proto.toByteString();
+    String aPrime = proto.getOptionalString();
+    assertNotSame(a, aPrime);
+    assertEquals(a, aPrime);
+    String bPrime = proto.getRepeatedString(0);
+    assertNotSame(b, bPrime);
+    assertEquals(b, bPrime);
+    String cPrime = proto.getRepeatedString(1);
+    assertNotSame(c, cPrime);
+    assertEquals(c, cPrime);
+
+    // And now the string should stay cached.
+    assertSame(aPrime, proto.getOptionalString());
+    assertSame(bPrime, proto.getRepeatedString(0));
+    assertSame(cPrime, proto.getRepeatedString(1));
+  }
+
+  public void testNoStringCachingIfOnlyBytesAccessed() throws Exception {
+    UnittestProto.TestAllTypes proto =
+        UnittestProto.TestAllTypes.parseFrom(encodedTestAllTypes);
+    ByteString optional = proto.getOptionalStringBytes();
+    assertSame(optional, proto.getOptionalStringBytes());
+    assertSame(optional, proto.toBuilder().getOptionalStringBytes());
+
+    ByteString repeated0 = proto.getRepeatedStringBytes(0);
+    ByteString repeated1 = proto.getRepeatedStringBytes(1);
+    assertSame(repeated0, proto.getRepeatedStringBytes(0));
+    assertSame(repeated1, proto.getRepeatedStringBytes(1));
+    assertSame(repeated0, proto.toBuilder().getRepeatedStringBytes(0));
+    assertSame(repeated1, proto.toBuilder().getRepeatedStringBytes(1));
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java b/protobuf/java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java
new file mode 100644
index 0000000..94f4fcf
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java
@@ -0,0 +1,85 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Bar;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime;
+import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
+
+import junit.framework.TestCase;
+
+/**
+ * Test generate equal and hash methods for the lite runtime.
+ *
+ * @author pbogle@google.com Phil Bogle
+ */
+public class LiteEqualsAndHashTest extends TestCase {
+
+  public void testEquals() throws Exception {
+    // Since the generated equals and hashCode methods for lite messages are a
+    // mostly complete subset of those for regular messages, we can mostly assume
+    // that the generated methods are already thoroughly tested by the regular tests.
+
+    // This test mostly just verifies is that a proto with
+    // optimize_for = LITE_RUNTIME and java_generates_equals_and_hash_compiles
+    // correctly when linked only against the lite library.
+
+    // We do however do some basic testing to make sure that equals is actually
+    // overriden to test for value equality rather than simple object equality.
+
+    // Check that two identical objs are equal.
+    Foo foo1a = Foo.newBuilder()
+        .setValue(1)
+        .addBar(Bar.newBuilder().setName("foo1"))
+        .build();
+    Foo foo1b = Foo.newBuilder()
+        .setValue(1)
+        .addBar(Bar.newBuilder().setName("foo1"))
+        .build();
+    Foo foo2 = Foo.newBuilder()
+        .setValue(1)
+        .addBar(Bar.newBuilder().setName("foo2"))
+        .build();
+
+    // Check that equals is doing value rather than object equality.
+    assertEquals(foo1a, foo1b);
+    assertEquals(foo1a.hashCode(), foo1b.hashCode());
+
+    // Check that a diffeent object is not equal.
+    assertFalse(foo1a.equals(foo2));
+
+    // Check that two objects which have different types but the same field values are not
+    // considered to be equal.
+    Bar bar = Bar.newBuilder().setName("bar").build();
+    BarPrime barPrime = BarPrime.newBuilder().setName("bar").build();
+    assertFalse(bar.equals(barPrime));
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/LiteTest.java b/protobuf/java/src/test/java/com/google/protobuf/LiteTest.java
new file mode 100644
index 0000000..8bb30ad
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/LiteTest.java
@@ -0,0 +1,148 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.UnittestLite;
+import com.google.protobuf.UnittestLite.TestAllTypesLite;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.UnittestLite.TestNestedExtensionLite;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ * Test lite runtime.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class LiteTest extends TestCase {
+  public void setUp() throws Exception {
+    // Test that nested extensions are initialized correctly even if the outer
+    // class has not been accessed directly.  This was once a bug with lite
+    // messages.
+    //
+    // We put this in setUp() rather than in its own test method because we
+    // need to make sure it runs before any actual tests.
+    assertTrue(TestNestedExtensionLite.nestedExtension != null);
+  }
+
+  public void testLite() throws Exception {
+    // Since lite messages are a subset of regular messages, we can mostly
+    // assume that the functionality of lite messages is already thoroughly
+    // tested by the regular tests.  All this test really verifies is that
+    // a proto with optimize_for = LITE_RUNTIME compiles correctly when
+    // linked only against the lite library.  That is all tested at compile
+    // time, leaving not much to do in this method.  Let's just do some random
+    // stuff to make sure the lite message is actually here and usable.
+
+    TestAllTypesLite message =
+      TestAllTypesLite.newBuilder()
+                      .setOptionalInt32(123)
+                      .addRepeatedString("hello")
+                      .setOptionalNestedMessage(
+                          TestAllTypesLite.NestedMessage.newBuilder().setBb(7))
+                      .build();
+
+    ByteString data = message.toByteString();
+
+    TestAllTypesLite message2 = TestAllTypesLite.parseFrom(data);
+
+    assertEquals(123, message2.getOptionalInt32());
+    assertEquals(1, message2.getRepeatedStringCount());
+    assertEquals("hello", message2.getRepeatedString(0));
+    assertEquals(7, message2.getOptionalNestedMessage().getBb());
+  }
+
+  public void testLiteExtensions() throws Exception {
+    // TODO(kenton):  Unlike other features of the lite library, extensions are
+    //   implemented completely differently from the regular library.  We
+    //   should probably test them more thoroughly.
+
+    TestAllExtensionsLite message =
+      TestAllExtensionsLite.newBuilder()
+        .setExtension(UnittestLite.optionalInt32ExtensionLite, 123)
+        .addExtension(UnittestLite.repeatedStringExtensionLite, "hello")
+        .setExtension(UnittestLite.optionalNestedEnumExtensionLite,
+            TestAllTypesLite.NestedEnum.BAZ)
+        .setExtension(UnittestLite.optionalNestedMessageExtensionLite,
+            TestAllTypesLite.NestedMessage.newBuilder().setBb(7).build())
+        .build();
+
+    // Test copying a message, since coping extensions actually does use a
+    // different code path between lite and regular libraries, and as of this
+    // writing, parsing hasn't been implemented yet.
+    TestAllExtensionsLite message2 = message.toBuilder().build();
+
+    assertEquals(123, (int) message2.getExtension(
+        UnittestLite.optionalInt32ExtensionLite));
+    assertEquals(1, message2.getExtensionCount(
+        UnittestLite.repeatedStringExtensionLite));
+    assertEquals(1, message2.getExtension(
+        UnittestLite.repeatedStringExtensionLite).size());
+    assertEquals("hello", message2.getExtension(
+        UnittestLite.repeatedStringExtensionLite, 0));
+    assertEquals(TestAllTypesLite.NestedEnum.BAZ, message2.getExtension(
+        UnittestLite.optionalNestedEnumExtensionLite));
+    assertEquals(7, message2.getExtension(
+        UnittestLite.optionalNestedMessageExtensionLite).getBb());
+  }
+
+  public void testSerialize() throws Exception {
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    TestAllTypesLite expected =
+      TestAllTypesLite.newBuilder()
+                      .setOptionalInt32(123)
+                      .addRepeatedString("hello")
+                      .setOptionalNestedMessage(
+                          TestAllTypesLite.NestedMessage.newBuilder().setBb(7))
+                      .build();
+    ObjectOutputStream out = new ObjectOutputStream(baos);
+    try {
+      out.writeObject(expected);
+    } finally {
+      out.close();
+    }
+    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+    ObjectInputStream in = new ObjectInputStream(bais);
+    TestAllTypesLite actual = (TestAllTypesLite) in.readObject();
+    assertEquals(expected.getOptionalInt32(), actual.getOptionalInt32());
+    assertEquals(expected.getRepeatedStringCount(),
+        actual.getRepeatedStringCount());
+    assertEquals(expected.getRepeatedString(0),
+        actual.getRepeatedString(0));
+    assertEquals(expected.getOptionalNestedMessage().getBb(),
+        actual.getOptionalNestedMessage().getBb());
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java b/protobuf/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java
new file mode 100644
index 0000000..475f7ff
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/LiteralByteStringTest.java
@@ -0,0 +1,396 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Test {@link LiteralByteString} by setting up a reference string in {@link #setUp()}.
+ * This class is designed to be extended for testing extensions of {@link LiteralByteString}
+ * such as {@link BoundedByteString}, see {@link BoundedByteStringTest}.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+public class LiteralByteStringTest extends TestCase {
+  protected static final String UTF_8 = "UTF-8";
+
+  protected String classUnderTest;
+  protected byte[] referenceBytes;
+  protected ByteString stringUnderTest;
+  protected int expectedHashCode;
+
+  @Override
+  protected void setUp() throws Exception {
+    classUnderTest = "LiteralByteString";
+    referenceBytes = ByteStringTest.getTestBytes(1234, 11337766L);
+    stringUnderTest = ByteString.copyFrom(referenceBytes);
+    expectedHashCode = 331161852;
+  }
+
+  public void testExpectedType() {
+    String actualClassName = getActualClassName(stringUnderTest);
+    assertEquals(classUnderTest + " should match type exactly", classUnderTest, actualClassName);
+  }
+
+  protected String getActualClassName(Object object) {
+    String actualClassName = object.getClass().getName();
+    actualClassName = actualClassName.substring(actualClassName.lastIndexOf('.') + 1);
+    return actualClassName;
+  }
+
+  public void testByteAt() {
+    boolean stillEqual = true;
+    for (int i = 0; stillEqual && i < referenceBytes.length; ++i) {
+      stillEqual = (referenceBytes[i] == stringUnderTest.byteAt(i));
+    }
+    assertTrue(classUnderTest + " must capture the right bytes", stillEqual);
+  }
+
+  public void testByteIterator() {
+    boolean stillEqual = true;
+    ByteString.ByteIterator iter = stringUnderTest.iterator();
+    for (int i = 0; stillEqual && i < referenceBytes.length; ++i) {
+      stillEqual = (iter.hasNext() && referenceBytes[i] == iter.nextByte());
+    }
+    assertTrue(classUnderTest + " must capture the right bytes", stillEqual);
+    assertFalse(classUnderTest + " must have exhausted the itertor", iter.hasNext());
+
+    try {
+      iter.nextByte();
+      fail("Should have thrown an exception.");
+    } catch (NoSuchElementException e) {
+      // This is success
+    }
+  }
+
+  public void testByteIterable() {
+    boolean stillEqual = true;
+    int j = 0;
+    for (byte quantum : stringUnderTest) {
+      stillEqual = (referenceBytes[j] == quantum);
+      ++j;
+    }
+    assertTrue(classUnderTest + " must capture the right bytes as Bytes", stillEqual);
+    assertEquals(classUnderTest + " iterable character count", referenceBytes.length, j);
+  }
+
+  public void testSize() {
+    assertEquals(classUnderTest + " must have the expected size", referenceBytes.length,
+        stringUnderTest.size());
+  }
+
+  public void testGetTreeDepth() {
+    assertEquals(classUnderTest + " must have depth 0", 0, stringUnderTest.getTreeDepth());
+  }
+
+  public void testIsBalanced() {
+    assertTrue(classUnderTest + " is technically balanced", stringUnderTest.isBalanced());
+  }
+
+  public void testCopyTo_ByteArrayOffsetLength() {
+    int destinationOffset = 50;
+    int length = 100;
+    byte[] destination = new byte[destinationOffset + length];
+    int sourceOffset = 213;
+    stringUnderTest.copyTo(destination, sourceOffset, destinationOffset, length);
+    boolean stillEqual = true;
+    for (int i = 0; stillEqual && i < length; ++i) {
+      stillEqual = referenceBytes[i + sourceOffset] == destination[i + destinationOffset];
+    }
+    assertTrue(classUnderTest + ".copyTo(4 arg) must give the expected bytes", stillEqual);
+  }
+
+  public void testCopyTo_ByteArrayOffsetLengthErrors() {
+    int destinationOffset = 50;
+    int length = 100;
+    byte[] destination = new byte[destinationOffset + length];
+
+    try {
+      // Copy one too many bytes
+      stringUnderTest.copyTo(destination, stringUnderTest.size() + 1 - length,
+          destinationOffset, length);
+      fail("Should have thrown an exception when copying too many bytes of a "
+          + classUnderTest);
+    } catch (IndexOutOfBoundsException expected) {
+      // This is success
+    }
+
+    try {
+      // Copy with illegal negative sourceOffset
+      stringUnderTest.copyTo(destination, -1, destinationOffset, length);
+      fail("Should have thrown an exception when given a negative sourceOffset in "
+          + classUnderTest);
+    } catch (IndexOutOfBoundsException expected) {
+      // This is success
+    }
+
+    try {
+      // Copy with illegal negative destinationOffset
+      stringUnderTest.copyTo(destination, 0, -1, length);
+      fail("Should have thrown an exception when given a negative destinationOffset in "
+          + classUnderTest);
+    } catch (IndexOutOfBoundsException expected) {
+      // This is success
+    }
+
+    try {
+      // Copy with illegal negative size
+      stringUnderTest.copyTo(destination, 0, 0, -1);
+      fail("Should have thrown an exception when given a negative size in "
+          + classUnderTest);
+    } catch (IndexOutOfBoundsException expected) {
+      // This is success
+    }
+
+    try {
+      // Copy with illegal too-large sourceOffset
+      stringUnderTest.copyTo(destination, 2 * stringUnderTest.size(), 0, length);
+      fail("Should have thrown an exception when the destinationOffset is too large in "
+          + classUnderTest);
+    } catch (IndexOutOfBoundsException expected) {
+      // This is success
+    }
+
+    try {
+      // Copy with illegal too-large destinationOffset
+      stringUnderTest.copyTo(destination, 0, 2 * destination.length, length);
+      fail("Should have thrown an exception when the destinationOffset is too large in "
+          + classUnderTest);
+    } catch (IndexOutOfBoundsException expected) {
+      // This is success
+    }
+  }
+
+  public void testCopyTo_ByteBuffer() {
+    ByteBuffer myBuffer = ByteBuffer.allocate(referenceBytes.length);
+    stringUnderTest.copyTo(myBuffer);
+    assertTrue(classUnderTest + ".copyTo(ByteBuffer) must give back the same bytes",
+        Arrays.equals(referenceBytes, myBuffer.array()));
+  }
+
+  public void testAsReadOnlyByteBuffer() {
+    ByteBuffer byteBuffer = stringUnderTest.asReadOnlyByteBuffer();
+    byte[] roundTripBytes = new byte[referenceBytes.length];
+    assertTrue(byteBuffer.remaining() == referenceBytes.length);
+    assertTrue(byteBuffer.isReadOnly());
+    byteBuffer.get(roundTripBytes);
+    assertTrue(classUnderTest + ".asReadOnlyByteBuffer() must give back the same bytes",
+        Arrays.equals(referenceBytes, roundTripBytes));
+  }
+
+  public void testAsReadOnlyByteBufferList() {
+    List<ByteBuffer> byteBuffers = stringUnderTest.asReadOnlyByteBufferList();
+    int bytesSeen = 0;
+    byte[] roundTripBytes = new byte[referenceBytes.length];
+    for (ByteBuffer byteBuffer : byteBuffers) {
+      int thisLength = byteBuffer.remaining();
+      assertTrue(byteBuffer.isReadOnly());
+      assertTrue(bytesSeen + thisLength <= referenceBytes.length);
+      byteBuffer.get(roundTripBytes, bytesSeen, thisLength);
+      bytesSeen += thisLength;
+    }
+    assertTrue(bytesSeen == referenceBytes.length);
+    assertTrue(classUnderTest + ".asReadOnlyByteBufferTest() must give back the same bytes",
+        Arrays.equals(referenceBytes, roundTripBytes));
+  }
+
+  public void testToByteArray() {
+    byte[] roundTripBytes = stringUnderTest.toByteArray();
+    assertTrue(classUnderTest + ".toByteArray() must give back the same bytes",
+        Arrays.equals(referenceBytes, roundTripBytes));
+  }
+
+  public void testWriteTo() throws IOException {
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    stringUnderTest.writeTo(bos);
+    byte[] roundTripBytes = bos.toByteArray();
+    assertTrue(classUnderTest + ".writeTo() must give back the same bytes",
+        Arrays.equals(referenceBytes, roundTripBytes));
+  }
+  
+  public void testWriteTo_mutating() throws IOException {
+    OutputStream os = new OutputStream() {
+      @Override
+      public void write(byte[] b, int off, int len) {
+        for (int x = 0; x < len; ++x) {
+          b[off + x] = (byte) 0;
+        }
+      }
+
+      @Override
+      public void write(int b) {
+        // Purposefully left blank.
+      }
+    };
+
+    stringUnderTest.writeTo(os);
+    byte[] newBytes = stringUnderTest.toByteArray();
+    assertTrue(classUnderTest + ".writeTo() must not grant access to underlying array",
+        Arrays.equals(referenceBytes, newBytes));
+  }
+
+  public void testNewOutput() throws IOException {
+    ByteArrayOutputStream bos = new ByteArrayOutputStream();
+    ByteString.Output output = ByteString.newOutput();
+    stringUnderTest.writeTo(output);
+    assertEquals("Output Size returns correct result",
+        output.size(), stringUnderTest.size());
+    output.writeTo(bos);
+    assertTrue("Output.writeTo() must give back the same bytes",
+        Arrays.equals(referenceBytes, bos.toByteArray()));
+
+    // write the output stream to itself! This should cause it to double
+    output.writeTo(output);
+    assertEquals("Writing an output stream to itself is successful",
+        stringUnderTest.concat(stringUnderTest), output.toByteString());
+
+    output.reset();
+    assertEquals("Output.reset() resets the output", 0, output.size());
+    assertEquals("Output.reset() resets the output",
+        ByteString.EMPTY, output.toByteString());
+    
+  }
+
+  public void testToString() throws UnsupportedEncodingException {
+    String testString = "I love unicode \u1234\u5678 characters";
+    LiteralByteString unicode = new LiteralByteString(testString.getBytes(UTF_8));
+    String roundTripString = unicode.toString(UTF_8);
+    assertEquals(classUnderTest + " unicode must match", testString, roundTripString);
+  }
+
+  public void testEquals() {
+    assertEquals(classUnderTest + " must not equal null", false, stringUnderTest.equals(null));
+    assertEquals(classUnderTest + " must equal self", stringUnderTest, stringUnderTest);
+    assertFalse(classUnderTest + " must not equal the empty string",
+        stringUnderTest.equals(ByteString.EMPTY));
+    assertEquals(classUnderTest + " empty strings must be equal",
+        new LiteralByteString(new byte[]{}), stringUnderTest.substring(55, 55));
+    assertEquals(classUnderTest + " must equal another string with the same value",
+        stringUnderTest, new LiteralByteString(referenceBytes));
+
+    byte[] mungedBytes = new byte[referenceBytes.length];
+    System.arraycopy(referenceBytes, 0, mungedBytes, 0, referenceBytes.length);
+    mungedBytes[mungedBytes.length - 5] ^= 0xFF;
+    assertFalse(classUnderTest + " must not equal every string with the same length",
+        stringUnderTest.equals(new LiteralByteString(mungedBytes)));
+  }
+
+  public void testHashCode() {
+    int hash = stringUnderTest.hashCode();
+    assertEquals(classUnderTest + " must have expected hashCode", expectedHashCode, hash);
+  }
+
+  public void testPeekCachedHashCode() {
+    assertEquals(classUnderTest + ".peekCachedHashCode() should return zero at first", 0,
+        stringUnderTest.peekCachedHashCode());
+    stringUnderTest.hashCode();
+    assertEquals(classUnderTest + ".peekCachedHashCode should return zero at first",
+        expectedHashCode, stringUnderTest.peekCachedHashCode());
+  }
+
+  public void testPartialHash() {
+    // partialHash() is more strenuously tested elsewhere by testing hashes of substrings.
+    // This test would fail if the expected hash were 1.  It's not.
+    int hash = stringUnderTest.partialHash(stringUnderTest.size(), 0, stringUnderTest.size());
+    assertEquals(classUnderTest + ".partialHash() must yield expected hashCode",
+        expectedHashCode, hash);
+  }
+
+  public void testNewInput() throws IOException {
+    InputStream input = stringUnderTest.newInput();
+    assertEquals("InputStream.available() returns correct value",
+        stringUnderTest.size(), input.available());
+    boolean stillEqual = true;
+    for (byte referenceByte : referenceBytes) {
+      int expectedInt = (referenceByte & 0xFF);
+      stillEqual = (expectedInt == input.read());
+    }
+    assertEquals("InputStream.available() returns correct value",
+        0, input.available());
+    assertTrue(classUnderTest + " must give the same bytes from the InputStream", stillEqual);
+    assertEquals(classUnderTest + " InputStream must now be exhausted", -1, input.read());
+  }
+
+  public void testNewInput_skip() throws IOException {
+    InputStream input = stringUnderTest.newInput();
+    int stringSize = stringUnderTest.size();
+    int nearEndIndex = stringSize * 2 / 3;
+    long skipped1 = input.skip(nearEndIndex);
+    assertEquals("InputStream.skip()", skipped1, nearEndIndex);
+    assertEquals("InputStream.available()",
+        stringSize - skipped1, input.available());
+    assertTrue("InputStream.mark() is available", input.markSupported());
+    input.mark(0);
+    assertEquals("InputStream.skip(), read()",
+        stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read());
+    assertEquals("InputStream.available()",
+                 stringSize - skipped1 - 1, input.available());
+    long skipped2 = input.skip(stringSize);
+    assertEquals("InputStream.skip() incomplete",
+        skipped2, stringSize - skipped1 - 1);
+    assertEquals("InputStream.skip(), no more input", 0, input.available());
+    assertEquals("InputStream.skip(), no more input", -1, input.read());
+    input.reset();
+    assertEquals("InputStream.reset() succeded",
+                 stringSize - skipped1, input.available());
+    assertEquals("InputStream.reset(), read()",
+        stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read());
+  }
+
+  public void testNewCodedInput() throws IOException {
+    CodedInputStream cis = stringUnderTest.newCodedInput();
+    byte[] roundTripBytes = cis.readRawBytes(referenceBytes.length);
+    assertTrue(classUnderTest + " must give the same bytes back from the CodedInputStream",
+        Arrays.equals(referenceBytes, roundTripBytes));
+    assertTrue(classUnderTest + " CodedInputStream must now be exhausted", cis.isAtEnd());
+  }
+
+  /**
+   * Make sure we keep things simple when concatenating with empty. See also
+   * {@link ByteStringTest#testConcat_empty()}.
+   */
+  public void testConcat_empty() {
+    assertSame(classUnderTest + " concatenated with empty must give " + classUnderTest,
+        stringUnderTest.concat(ByteString.EMPTY), stringUnderTest);
+    assertSame("empty concatenated with " + classUnderTest + " must give " + classUnderTest,
+        ByteString.EMPTY.concat(stringUnderTest), stringUnderTest);
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/MessageTest.java b/protobuf/java/src/test/java/com/google/protobuf/MessageTest.java
new file mode 100644
index 0000000..abcd3a1
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/MessageTest.java
@@ -0,0 +1,353 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto.TestRequiredForeign;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+
+/**
+ * Misc. unit tests for message operations that apply to both generated
+ * and dynamic messages.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class MessageTest extends TestCase {
+  // =================================================================
+  // Message-merging tests.
+
+  static final TestAllTypes MERGE_SOURCE =
+    TestAllTypes.newBuilder()
+      .setOptionalInt32(1)
+      .setOptionalString("foo")
+      .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
+      .addRepeatedString("bar")
+      .build();
+
+  static final TestAllTypes MERGE_DEST =
+    TestAllTypes.newBuilder()
+      .setOptionalInt64(2)
+      .setOptionalString("baz")
+      .setOptionalForeignMessage(ForeignMessage.newBuilder().setC(3).build())
+      .addRepeatedString("qux")
+      .build();
+
+  static final String MERGE_RESULT_TEXT =
+      "optional_int32: 1\n" +
+      "optional_int64: 2\n" +
+      "optional_string: \"foo\"\n" +
+      "optional_foreign_message {\n" +
+      "  c: 3\n" +
+      "}\n" +
+      "repeated_string: \"qux\"\n" +
+      "repeated_string: \"bar\"\n";
+
+  public void testMergeFrom() throws Exception {
+    TestAllTypes result =
+      TestAllTypes.newBuilder(MERGE_DEST)
+        .mergeFrom(MERGE_SOURCE).build();
+
+    assertEquals(MERGE_RESULT_TEXT, result.toString());
+  }
+
+  /**
+   * Test merging a DynamicMessage into a GeneratedMessage.  As long as they
+   * have the same descriptor, this should work, but it is an entirely different
+   * code path.
+   */
+  public void testMergeFromDynamic() throws Exception {
+    TestAllTypes result =
+      TestAllTypes.newBuilder(MERGE_DEST)
+        .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
+        .build();
+
+    assertEquals(MERGE_RESULT_TEXT, result.toString());
+  }
+
+  /** Test merging two DynamicMessages. */
+  public void testDynamicMergeFrom() throws Exception {
+    DynamicMessage result =
+      DynamicMessage.newBuilder(MERGE_DEST)
+        .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
+        .build();
+
+    assertEquals(MERGE_RESULT_TEXT, result.toString());
+  }
+
+  // =================================================================
+  // Required-field-related tests.
+
+  private static final TestRequired TEST_REQUIRED_UNINITIALIZED =
+    TestRequired.getDefaultInstance();
+  private static final TestRequired TEST_REQUIRED_INITIALIZED =
+    TestRequired.newBuilder().setA(1).setB(2).setC(3).build();
+
+  public void testRequired() throws Exception {
+    TestRequired.Builder builder = TestRequired.newBuilder();
+
+    assertFalse(builder.isInitialized());
+    builder.setA(1);
+    assertFalse(builder.isInitialized());
+    builder.setB(1);
+    assertFalse(builder.isInitialized());
+    builder.setC(1);
+    assertTrue(builder.isInitialized());
+  }
+
+  public void testRequiredForeign() throws Exception {
+    TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
+
+    assertTrue(builder.isInitialized());
+
+    builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
+    assertFalse(builder.isInitialized());
+
+    builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
+    assertTrue(builder.isInitialized());
+
+    builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
+    assertFalse(builder.isInitialized());
+
+    builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
+    assertTrue(builder.isInitialized());
+  }
+
+  public void testRequiredExtension() throws Exception {
+    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+
+    assertTrue(builder.isInitialized());
+
+    builder.setExtension(TestRequired.single, TEST_REQUIRED_UNINITIALIZED);
+    assertFalse(builder.isInitialized());
+
+    builder.setExtension(TestRequired.single, TEST_REQUIRED_INITIALIZED);
+    assertTrue(builder.isInitialized());
+
+    builder.addExtension(TestRequired.multi, TEST_REQUIRED_UNINITIALIZED);
+    assertFalse(builder.isInitialized());
+
+    builder.setExtension(TestRequired.multi, 0, TEST_REQUIRED_INITIALIZED);
+    assertTrue(builder.isInitialized());
+  }
+
+  public void testRequiredDynamic() throws Exception {
+    Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
+    DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
+
+    assertFalse(builder.isInitialized());
+    builder.setField(descriptor.findFieldByName("a"), 1);
+    assertFalse(builder.isInitialized());
+    builder.setField(descriptor.findFieldByName("b"), 1);
+    assertFalse(builder.isInitialized());
+    builder.setField(descriptor.findFieldByName("c"), 1);
+    assertTrue(builder.isInitialized());
+  }
+
+  public void testRequiredDynamicForeign() throws Exception {
+    Descriptors.Descriptor descriptor = TestRequiredForeign.getDescriptor();
+    DynamicMessage.Builder builder = DynamicMessage.newBuilder(descriptor);
+
+    assertTrue(builder.isInitialized());
+
+    builder.setField(descriptor.findFieldByName("optional_message"),
+                     TEST_REQUIRED_UNINITIALIZED);
+    assertFalse(builder.isInitialized());
+
+    builder.setField(descriptor.findFieldByName("optional_message"),
+                     TEST_REQUIRED_INITIALIZED);
+    assertTrue(builder.isInitialized());
+
+    builder.addRepeatedField(descriptor.findFieldByName("repeated_message"),
+                             TEST_REQUIRED_UNINITIALIZED);
+    assertFalse(builder.isInitialized());
+
+    builder.setRepeatedField(descriptor.findFieldByName("repeated_message"), 0,
+                             TEST_REQUIRED_INITIALIZED);
+    assertTrue(builder.isInitialized());
+  }
+
+  public void testUninitializedException() throws Exception {
+    try {
+      TestRequired.newBuilder().build();
+      fail("Should have thrown an exception.");
+    } catch (UninitializedMessageException e) {
+      assertEquals("Message missing required fields: a, b, c", e.getMessage());
+    }
+  }
+
+  public void testBuildPartial() throws Exception {
+    // We're mostly testing that no exception is thrown.
+    TestRequired message = TestRequired.newBuilder().buildPartial();
+    assertFalse(message.isInitialized());
+  }
+
+  public void testNestedUninitializedException() throws Exception {
+    try {
+      TestRequiredForeign.newBuilder()
+        .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
+        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+        .build();
+      fail("Should have thrown an exception.");
+    } catch (UninitializedMessageException e) {
+      assertEquals(
+        "Message missing required fields: " +
+        "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",
+        e.getMessage());
+    }
+  }
+
+  public void testBuildNestedPartial() throws Exception {
+    // We're mostly testing that no exception is thrown.
+    TestRequiredForeign message =
+      TestRequiredForeign.newBuilder()
+        .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
+        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+        .buildPartial();
+    assertFalse(message.isInitialized());
+  }
+
+  public void testParseUnititialized() throws Exception {
+    try {
+      TestRequired.parseFrom(ByteString.EMPTY);
+      fail("Should have thrown an exception.");
+    } catch (InvalidProtocolBufferException e) {
+      assertEquals("Message missing required fields: a, b, c", e.getMessage());
+    }
+  }
+
+  public void testParseNestedUnititialized() throws Exception {
+    ByteString data =
+      TestRequiredForeign.newBuilder()
+        .setOptionalMessage(TEST_REQUIRED_UNINITIALIZED)
+        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+        .addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED)
+        .buildPartial().toByteString();
+
+    try {
+      TestRequiredForeign.parseFrom(data);
+      fail("Should have thrown an exception.");
+    } catch (InvalidProtocolBufferException e) {
+      assertEquals(
+        "Message missing required fields: " +
+        "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",
+        e.getMessage());
+    }
+  }
+
+  public void testDynamicUninitializedException() throws Exception {
+    try {
+      DynamicMessage.newBuilder(TestRequired.getDescriptor()).build();
+      fail("Should have thrown an exception.");
+    } catch (UninitializedMessageException e) {
+      assertEquals("Message missing required fields: a, b, c", e.getMessage());
+    }
+  }
+
+  public void testDynamicBuildPartial() throws Exception {
+    // We're mostly testing that no exception is thrown.
+    DynamicMessage message =
+      DynamicMessage.newBuilder(TestRequired.getDescriptor())
+        .buildPartial();
+    assertFalse(message.isInitialized());
+  }
+
+  public void testDynamicParseUnititialized() throws Exception {
+    try {
+      Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
+      DynamicMessage.parseFrom(descriptor, ByteString.EMPTY);
+      fail("Should have thrown an exception.");
+    } catch (InvalidProtocolBufferException e) {
+      assertEquals("Message missing required fields: a, b, c", e.getMessage());
+    }
+  }
+  
+  /** Test reading unset repeated message from DynamicMessage. */
+  public void testDynamicRepeatedMessageNull() throws Exception {
+    Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
+    DynamicMessage result =
+      DynamicMessage.newBuilder(TestAllTypes.getDescriptor())
+        .mergeFrom(DynamicMessage.newBuilder(MERGE_SOURCE).build())
+        .build();
+
+    assertTrue(result.getField(result.getDescriptorForType()
+        .findFieldByName("repeated_foreign_message")) instanceof List<?>);
+    assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
+        .findFieldByName("repeated_foreign_message")), 0);
+  }
+  
+  /** Test reading repeated message from DynamicMessage. */
+  public void testDynamicRepeatedMessageNotNull() throws Exception {
+
+    TestAllTypes REPEATED_NESTED =
+      TestAllTypes.newBuilder()
+        .setOptionalInt32(1)
+        .setOptionalString("foo")
+        .setOptionalForeignMessage(ForeignMessage.getDefaultInstance())
+        .addRepeatedString("bar")
+        .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance())
+        .addRepeatedForeignMessage(ForeignMessage.getDefaultInstance())
+        .build();
+    Descriptors.Descriptor descriptor = TestRequired.getDescriptor();
+    DynamicMessage result =
+      DynamicMessage.newBuilder(TestAllTypes.getDescriptor())
+        .mergeFrom(DynamicMessage.newBuilder(REPEATED_NESTED).build())
+        .build();
+
+    assertTrue(result.getField(result.getDescriptorForType()
+        .findFieldByName("repeated_foreign_message")) instanceof List<?>);
+    assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
+        .findFieldByName("repeated_foreign_message")), 2);
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/MicroTest.java b/protobuf/java/src/test/java/com/google/protobuf/MicroTest.java
new file mode 100644
index 0000000..1e43f07
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/MicroTest.java
@@ -0,0 +1,2273 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf;
+
+import com.google.protobuf.micro.ByteStringMicro;
+import com.google.protobuf.micro.CodedInputStreamMicro;
+import com.google.protobuf.micro.FileScopeEnumRefMicro;
+import com.google.protobuf.micro.MessageScopeEnumRefMicro;
+import com.google.protobuf.micro.MicroOuterClass;
+import com.google.protobuf.micro.MicroOuterClass.TestAllTypesMicro;
+import com.google.protobuf.micro.MultipleImportingNonMultipleMicro1;
+import com.google.protobuf.micro.MultipleImportingNonMultipleMicro2;
+import com.google.protobuf.micro.MultipleNameClashMicro;
+import com.google.protobuf.micro.UnittestImportMicro;
+import com.google.protobuf.micro.UnittestMultipleMicro;
+import com.google.protobuf.micro.UnittestRecursiveMicro.RecursiveMessageMicro;
+import com.google.protobuf.micro.UnittestSimpleMicro.SimpleMessageMicro;
+import com.google.protobuf.micro.UnittestSingleMicro.SingleMessageMicro;
+import com.google.protobuf.micro.UnittestStringutf8Micro.StringUtf8;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Test micro runtime.
+ *
+ * @author wink@google.com Wink Saville
+ */
+public class MicroTest extends TestCase {
+  public void setUp() throws Exception {
+  }
+
+  public void testSimpleMessageMicro() throws Exception {
+    SimpleMessageMicro msg = new SimpleMessageMicro();
+    assertFalse(msg.hasD());
+    assertEquals(123, msg.getD());
+    assertFalse(msg.hasNestedMsg());
+    assertEquals(null, msg.getNestedMsg());
+    assertFalse(msg.hasDefaultNestedEnum());
+    assertEquals(SimpleMessageMicro.BAZ, msg.getDefaultNestedEnum());
+
+    msg.setD(456);
+    assertTrue(msg.hasD());
+    assertEquals(456, msg.getD());
+    msg.clearD()
+       .setD(456);
+    assertTrue(msg.hasD());
+
+    SimpleMessageMicro.NestedMessage nestedMsg = new SimpleMessageMicro.NestedMessage()
+      .setBb(2);
+    assertTrue(nestedMsg.hasBb());
+    assertEquals(2, nestedMsg.getBb());
+    msg.setNestedMsg(nestedMsg);
+    assertTrue(msg.hasNestedMsg());
+    assertEquals(2, msg.getNestedMsg().getBb());
+
+    msg.setDefaultNestedEnum(SimpleMessageMicro.BAR);
+    assertTrue(msg.hasDefaultNestedEnum());
+    assertEquals(SimpleMessageMicro.BAR, msg.getDefaultNestedEnum());
+
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    SimpleMessageMicro newMsg = SimpleMessageMicro.parseFrom(result);
+    assertTrue(newMsg.hasD());
+    assertTrue(newMsg.hasNestedMsg());
+    assertTrue(newMsg.hasDefaultNestedEnum());
+    assertEquals(456, newMsg.getD());
+    assertEquals(2, msg.getNestedMsg().getBb());
+    assertEquals(SimpleMessageMicro.BAR, msg.getDefaultNestedEnum());
+  }
+
+  public void testRecursiveMessageMicro() throws Exception {
+    RecursiveMessageMicro msg = new RecursiveMessageMicro();
+    assertFalse(msg.hasId());
+    assertFalse(msg.hasNestedMessage());
+    assertFalse(msg.hasOptionalRecursiveMessageMicro());
+    assertEquals(0, msg.getRepeatedRecursiveMessageMicroCount());
+
+    RecursiveMessageMicro msg1 = new RecursiveMessageMicro();
+    msg1.setId(1);
+    assertEquals(1, msg1.getId());
+    RecursiveMessageMicro msg2 = new RecursiveMessageMicro();
+    msg2.setId(2);
+    RecursiveMessageMicro msg3 = new RecursiveMessageMicro();
+    msg3.setId(3);
+
+    RecursiveMessageMicro.NestedMessage nestedMsg = new RecursiveMessageMicro.NestedMessage();
+    nestedMsg.setA(msg1);
+    assertEquals(1, nestedMsg.getA().getId());
+
+    msg.setId(0);
+    msg.setNestedMessage(nestedMsg);
+    msg.setOptionalRecursiveMessageMicro(msg2);
+    msg.addRepeatedRecursiveMessageMicro(msg3);
+
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 16);
+    assertEquals(result.length, msgSerializedSize);
+
+    RecursiveMessageMicro newMsg = RecursiveMessageMicro.parseFrom(result);
+    assertTrue(newMsg.hasId());
+    assertTrue(newMsg.hasNestedMessage());
+    assertTrue(newMsg.hasOptionalRecursiveMessageMicro());
+    assertEquals(1, newMsg.getRepeatedRecursiveMessageMicroCount());
+
+    assertEquals(0, newMsg.getId());
+    assertEquals(1, newMsg.getNestedMessage().getA().getId());
+    assertEquals(2, newMsg.getOptionalRecursiveMessageMicro().getId());
+    assertEquals(3, newMsg.getRepeatedRecursiveMessageMicro(0).getId());
+  }
+
+  public void testMicroRequiredInt32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasId());
+    assertFalse(msg.isInitialized());
+    msg.setId(123);
+    assertTrue(msg.hasId());
+    assertTrue(msg.isInitialized());
+    assertEquals(123, msg.getId());
+    msg.clearId();
+    assertFalse(msg.hasId());
+    assertFalse(msg.isInitialized());
+    msg.clearId()
+       .setId(456);
+    assertTrue(msg.hasId());
+    msg.clear();
+    assertFalse(msg.hasId());
+    assertFalse(msg.isInitialized());
+
+    msg.setId(123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasId());
+    assertTrue(newMsg.isInitialized());
+    assertEquals(123, newMsg.getId());
+  }
+
+  public void testMicroOptionalInt32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalInt32());
+    msg.setOptionalInt32(123);
+    assertTrue(msg.hasOptionalInt32());
+    assertEquals(123, msg.getOptionalInt32());
+    msg.clearOptionalInt32();
+    assertFalse(msg.hasOptionalInt32());
+    msg.clearOptionalInt32()
+       .setOptionalInt32(456);
+    assertTrue(msg.hasOptionalInt32());
+    msg.clear();
+    assertFalse(msg.hasOptionalInt32());
+
+    msg.setOptionalInt32(123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 2);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalInt32());
+    assertEquals(123, newMsg.getOptionalInt32());
+  }
+
+  public void testMicroOptionalInt64() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalInt64());
+    msg.setOptionalInt64(123);
+    assertTrue(msg.hasOptionalInt64());
+    assertEquals(123, msg.getOptionalInt64());
+    msg.clearOptionalInt64();
+    assertFalse(msg.hasOptionalInt64());
+    msg.clearOptionalInt64()
+       .setOptionalInt64(456);
+    assertTrue(msg.hasOptionalInt64());
+    msg.clear();
+    assertFalse(msg.hasOptionalInt64());
+
+    msg.setOptionalInt64(123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 2);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalInt64());
+    assertEquals(123, newMsg.getOptionalInt64());
+  }
+
+  public void testMicroOptionalUint32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalUint32());
+    msg.setOptionalUint32(123);
+    assertTrue(msg.hasOptionalUint32());
+    assertEquals(123, msg.getOptionalUint32());
+    msg.clearOptionalUint32();
+    assertFalse(msg.hasOptionalUint32());
+    msg.clearOptionalUint32()
+       .setOptionalUint32(456);
+    assertTrue(msg.hasOptionalUint32());
+    msg.clear();
+    assertFalse(msg.hasOptionalUint32());
+
+    msg.setOptionalUint32(123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 2);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalUint32());
+    assertEquals(123, newMsg.getOptionalUint32());
+  }
+
+  public void testMicroOptionalUint64() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalUint64());
+    msg.setOptionalUint64(123);
+    assertTrue(msg.hasOptionalUint64());
+    assertEquals(123, msg.getOptionalUint64());
+    msg.clearOptionalUint64();
+    assertFalse(msg.hasOptionalUint64());
+    msg.clearOptionalUint64()
+       .setOptionalUint64(456);
+    assertTrue(msg.hasOptionalUint64());
+    msg.clear();
+    assertFalse(msg.hasOptionalUint64());
+
+    msg.setOptionalUint64(123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 2);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalUint64());
+    assertEquals(123, newMsg.getOptionalUint64());
+  }
+
+  public void testMicroOptionalSint32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalSint32());
+    msg.setOptionalSint32(123);
+    assertTrue(msg.hasOptionalSint32());
+    assertEquals(123, msg.getOptionalSint32());
+    msg.clearOptionalSint32();
+    assertFalse(msg.hasOptionalSint32());
+    msg.clearOptionalSint32()
+       .setOptionalSint32(456);
+    assertTrue(msg.hasOptionalSint32());
+    msg.clear();
+    assertFalse(msg.hasOptionalSint32());
+
+    msg.setOptionalSint32(-123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalSint32());
+    assertEquals(-123, newMsg.getOptionalSint32());
+  }
+
+  public void testMicroOptionalSint64() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalSint64());
+    msg.setOptionalSint64(123);
+    assertTrue(msg.hasOptionalSint64());
+    assertEquals(123, msg.getOptionalSint64());
+    msg.clearOptionalSint64();
+    assertFalse(msg.hasOptionalSint64());
+    msg.clearOptionalSint64()
+       .setOptionalSint64(456);
+    assertTrue(msg.hasOptionalSint64());
+    msg.clear();
+    assertFalse(msg.hasOptionalSint64());
+
+    msg.setOptionalSint64(-123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalSint64());
+    assertEquals(-123, newMsg.getOptionalSint64());
+  }
+
+  public void testMicroOptionalFixed32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalFixed32());
+    msg.setOptionalFixed32(123);
+    assertTrue(msg.hasOptionalFixed32());
+    assertEquals(123, msg.getOptionalFixed32());
+    msg.clearOptionalFixed32();
+    assertFalse(msg.hasOptionalFixed32());
+    msg.clearOptionalFixed32()
+       .setOptionalFixed32(456);
+    assertTrue(msg.hasOptionalFixed32());
+    msg.clear();
+    assertFalse(msg.hasOptionalFixed32());
+
+    msg.setOptionalFixed32(123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalFixed32());
+    assertEquals(123, newMsg.getOptionalFixed32());
+  }
+
+  public void testMicroOptionalFixed64() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalFixed64());
+    msg.setOptionalFixed64(123);
+    assertTrue(msg.hasOptionalFixed64());
+    assertEquals(123, msg.getOptionalFixed64());
+    msg.clearOptionalFixed64();
+    assertFalse(msg.hasOptionalFixed64());
+    msg.clearOptionalFixed64()
+       .setOptionalFixed64(456);
+    assertTrue(msg.hasOptionalFixed64());
+    msg.clear();
+    assertFalse(msg.hasOptionalFixed64());
+
+    msg.setOptionalFixed64(123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalFixed64());
+    assertEquals(123, newMsg.getOptionalFixed64());
+  }
+  public void testMicroOptionalSfixed32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalSfixed32());
+    msg.setOptionalSfixed32(123);
+    assertTrue(msg.hasOptionalSfixed32());
+    assertEquals(123, msg.getOptionalSfixed32());
+    msg.clearOptionalSfixed32();
+    assertFalse(msg.hasOptionalSfixed32());
+    msg.clearOptionalSfixed32()
+       .setOptionalSfixed32(456);
+    assertTrue(msg.hasOptionalSfixed32());
+    msg.clear();
+    assertFalse(msg.hasOptionalSfixed32());
+
+    msg.setOptionalSfixed32(123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalSfixed32());
+    assertEquals(123, newMsg.getOptionalSfixed32());
+  }
+
+  public void testMicroOptionalSfixed64() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalSfixed64());
+    msg.setOptionalSfixed64(123);
+    assertTrue(msg.hasOptionalSfixed64());
+    assertEquals(123, msg.getOptionalSfixed64());
+    msg.clearOptionalSfixed64();
+    assertFalse(msg.hasOptionalSfixed64());
+    msg.clearOptionalSfixed64()
+       .setOptionalSfixed64(456);
+    assertTrue(msg.hasOptionalSfixed64());
+    msg.clear();
+    assertFalse(msg.hasOptionalSfixed64());
+
+    msg.setOptionalSfixed64(-123);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalSfixed64());
+    assertEquals(-123, newMsg.getOptionalSfixed64());
+  }
+
+  public void testMicroOptionalFloat() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalFloat());
+    msg.setOptionalFloat(123f);
+    assertTrue(msg.hasOptionalFloat());
+    assertTrue(123.0f == msg.getOptionalFloat());
+    msg.clearOptionalFloat();
+    assertFalse(msg.hasOptionalFloat());
+    msg.clearOptionalFloat()
+       .setOptionalFloat(456.0f);
+    assertTrue(msg.hasOptionalFloat());
+    msg.clear();
+    assertFalse(msg.hasOptionalFloat());
+
+    msg.setOptionalFloat(-123.456f);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalFloat());
+    assertTrue(-123.456f == newMsg.getOptionalFloat());
+  }
+
+  public void testMicroOptionalDouble() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalDouble());
+    msg.setOptionalDouble(123);
+    assertTrue(msg.hasOptionalDouble());
+    assertTrue(123.0 == msg.getOptionalDouble());
+    msg.clearOptionalDouble();
+    assertFalse(msg.hasOptionalDouble());
+    msg.clearOptionalDouble()
+       .setOptionalDouble(456.0);
+    assertTrue(msg.hasOptionalDouble());
+    msg.clear();
+    assertFalse(msg.hasOptionalDouble());
+
+    msg.setOptionalDouble(-123.456);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalDouble());
+    assertTrue(-123.456 == newMsg.getOptionalDouble());
+  }
+
+  public void testMicroOptionalBool() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalBool());
+    msg.setOptionalBool(true);
+    assertTrue(msg.hasOptionalBool());
+    assertEquals(true, msg.getOptionalBool());
+    msg.clearOptionalBool();
+    assertFalse(msg.hasOptionalBool());
+    msg.clearOptionalBool()
+       .setOptionalBool(true);
+    assertTrue(msg.hasOptionalBool());
+    msg.clear();
+    assertFalse(msg.hasOptionalBool());
+
+    msg.setOptionalBool(false);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 2);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalBool());
+    assertEquals(false, newMsg.getOptionalBool());
+  }
+
+  public void testMicroOptionalString() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalString());
+    msg.setOptionalString("hello");
+    assertTrue(msg.hasOptionalString());
+    assertEquals("hello", msg.getOptionalString());
+    msg.clearOptionalString();
+    assertFalse(msg.hasOptionalString());
+    msg.clearOptionalString()
+       .setOptionalString("hello");
+    assertTrue(msg.hasOptionalString());
+    msg.clear();
+    assertFalse(msg.hasOptionalString());
+
+    msg.setOptionalString("bye");
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalString());
+    assertEquals("bye", newMsg.getOptionalString());
+  }
+
+  public void testMicroOptionalBytes() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalBytes());
+    msg.setOptionalBytes(ByteStringMicro.copyFromUtf8("hello"));
+    assertTrue(msg.hasOptionalBytes());
+    assertEquals("hello", msg.getOptionalBytes().toStringUtf8());
+    msg.clearOptionalBytes();
+    assertFalse(msg.hasOptionalBytes());
+    msg.clearOptionalBytes()
+       .setOptionalBytes(ByteStringMicro.copyFromUtf8("hello"));
+    assertTrue(msg.hasOptionalBytes());
+    msg.clear();
+    assertFalse(msg.hasOptionalBytes());
+
+    msg.setOptionalBytes(ByteStringMicro.copyFromUtf8("bye"));
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalBytes());
+    assertEquals("bye", newMsg.getOptionalBytes().toStringUtf8());
+  }
+
+  public void testMicroOptionalGroup() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    TestAllTypesMicro.OptionalGroup grp = new TestAllTypesMicro.OptionalGroup();
+    grp.setA(1);
+    assertFalse(msg.hasOptionalGroup());
+    msg.setOptionalGroup(grp);
+    assertTrue(msg.hasOptionalGroup());
+    assertEquals(1, msg.getOptionalGroup().getA());
+    msg.clearOptionalGroup();
+    assertFalse(msg.hasOptionalGroup());
+    msg.clearOptionalGroup()
+       .setOptionalGroup(new TestAllTypesMicro.OptionalGroup().setA(2));
+    assertTrue(msg.hasOptionalGroup());
+    msg.clear();
+    assertFalse(msg.hasOptionalGroup());
+
+    msg.setOptionalGroup(grp);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalGroup());
+    assertEquals(1, newMsg.getOptionalGroup().getA());
+  }
+
+  public void testMicroOptionalNestedMessage() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    TestAllTypesMicro.NestedMessage nestedMsg = new TestAllTypesMicro.NestedMessage();
+    nestedMsg.setBb(1);
+    assertFalse(msg.hasOptionalNestedMessage());
+    msg.setOptionalNestedMessage(nestedMsg);
+    assertTrue(msg.hasOptionalNestedMessage());
+    assertEquals(1, msg.getOptionalNestedMessage().getBb());
+    msg.clearOptionalNestedMessage();
+    assertFalse(msg.hasOptionalNestedMessage());
+    msg.clearOptionalNestedMessage()
+       .setOptionalNestedMessage(new TestAllTypesMicro.NestedMessage().setBb(2));
+    assertTrue(msg.hasOptionalNestedMessage());
+    msg.clear();
+    assertFalse(msg.hasOptionalNestedMessage());
+
+    msg.setOptionalNestedMessage(nestedMsg);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalNestedMessage());
+    assertEquals(1, newMsg.getOptionalNestedMessage().getBb());
+  }
+
+  public void testMicroOptionalForeignMessage() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    MicroOuterClass.ForeignMessageMicro foreignMsg =
+        new MicroOuterClass.ForeignMessageMicro();
+    assertFalse(foreignMsg.hasC());
+    foreignMsg.setC(1);
+    assertTrue(foreignMsg.hasC());
+    assertFalse(msg.hasOptionalForeignMessage());
+    msg.setOptionalForeignMessage(foreignMsg);
+    assertTrue(msg.hasOptionalForeignMessage());
+    assertEquals(1, msg.getOptionalForeignMessage().getC());
+    msg.clearOptionalForeignMessage();
+    assertFalse(msg.hasOptionalForeignMessage());
+    msg.clearOptionalForeignMessage()
+       .setOptionalForeignMessage(new MicroOuterClass.ForeignMessageMicro().setC(2));
+    assertTrue(msg.hasOptionalForeignMessage());
+    msg.clear();
+    assertFalse(msg.hasOptionalForeignMessage());
+
+    msg.setOptionalForeignMessage(foreignMsg);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalForeignMessage());
+    assertEquals(1, newMsg.getOptionalForeignMessage().getC());
+  }
+
+  public void testMicroOptionalImportMessage() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    UnittestImportMicro.ImportMessageMicro importMsg =
+        new UnittestImportMicro.ImportMessageMicro();
+    assertFalse(importMsg.hasD());
+    importMsg.setD(1);
+    assertTrue(importMsg.hasD());
+    assertFalse(msg.hasOptionalImportMessage());
+    msg.setOptionalImportMessage(importMsg);
+    assertTrue(msg.hasOptionalImportMessage());
+    assertEquals(1, msg.getOptionalImportMessage().getD());
+    msg.clearOptionalImportMessage();
+    assertFalse(msg.hasOptionalImportMessage());
+    msg.clearOptionalImportMessage()
+       .setOptionalImportMessage(new UnittestImportMicro.ImportMessageMicro().setD(2));
+    assertTrue(msg.hasOptionalImportMessage());
+    msg.clear();
+    assertFalse(msg.hasOptionalImportMessage());
+
+    msg.setOptionalImportMessage(importMsg);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalImportMessage());
+    assertEquals(1, newMsg.getOptionalImportMessage().getD());
+  }
+
+  public void testMicroOptionalNestedEnum() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    msg.setOptionalNestedEnum(TestAllTypesMicro.BAR);
+    assertTrue(msg.hasOptionalNestedEnum());
+    assertEquals(TestAllTypesMicro.BAR, msg.getOptionalNestedEnum());
+    msg.clearOptionalNestedEnum();
+    assertFalse(msg.hasOptionalNestedEnum());
+    msg.clearOptionalNestedEnum()
+       .setOptionalNestedEnum(TestAllTypesMicro.BAZ);
+    assertTrue(msg.hasOptionalNestedEnum());
+    msg.clear();
+    assertFalse(msg.hasOptionalNestedEnum());
+
+    msg.setOptionalNestedEnum(TestAllTypesMicro.BAR);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalNestedEnum());
+    assertEquals(TestAllTypesMicro.BAR, newMsg.getOptionalNestedEnum());
+  }
+
+  public void testMicroOptionalForeignEnum() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    msg.setOptionalForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR);
+    assertTrue(msg.hasOptionalForeignEnum());
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR,
+        msg.getOptionalForeignEnum());
+    msg.clearOptionalForeignEnum();
+    assertFalse(msg.hasOptionalForeignEnum());
+    msg.clearOptionalForeignEnum()
+       .setOptionalForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAZ);
+    assertTrue(msg.hasOptionalForeignEnum());
+    msg.clear();
+    assertFalse(msg.hasOptionalForeignEnum());
+
+    msg.setOptionalForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalForeignEnum());
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR,
+        newMsg.getOptionalForeignEnum());
+  }
+
+  public void testMicroOptionalImportEnum() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    msg.setOptionalImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR);
+    assertTrue(msg.hasOptionalImportEnum());
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR,
+        msg.getOptionalImportEnum());
+    msg.clearOptionalImportEnum();
+    assertFalse(msg.hasOptionalImportEnum());
+    msg.clearOptionalImportEnum()
+       .setOptionalImportEnum(UnittestImportMicro.IMPORT_MICRO_BAZ);
+    assertTrue(msg.hasOptionalImportEnum());
+    msg.clear();
+    assertFalse(msg.hasOptionalImportEnum());
+
+    msg.setOptionalImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalImportEnum());
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR,
+        newMsg.getOptionalImportEnum());
+  }
+
+  public void testMicroOptionalStringPiece() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalStringPiece());
+    msg.setOptionalStringPiece("hello");
+    assertTrue(msg.hasOptionalStringPiece());
+    assertEquals("hello", msg.getOptionalStringPiece());
+    msg.clearOptionalStringPiece();
+    assertFalse(msg.hasOptionalStringPiece());
+    msg.clearOptionalStringPiece()
+       .setOptionalStringPiece("hello");
+    assertTrue(msg.hasOptionalStringPiece());
+    msg.clear();
+    assertFalse(msg.hasOptionalStringPiece());
+
+    msg.setOptionalStringPiece("bye");
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalStringPiece());
+    assertEquals("bye", newMsg.getOptionalStringPiece());
+  }
+
+  public void testMicroOptionalCord() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasOptionalCord());
+    msg.setOptionalCord("hello");
+    assertTrue(msg.hasOptionalCord());
+    assertEquals("hello", msg.getOptionalCord());
+    msg.clearOptionalCord();
+    assertFalse(msg.hasOptionalCord());
+    msg.clearOptionalCord()
+      .setOptionalCord("hello");
+    assertTrue(msg.hasOptionalCord());
+    msg.clear();
+    assertFalse(msg.hasOptionalCord());
+
+    msg.setOptionalCord("bye");
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertTrue(newMsg.hasOptionalCord());
+    assertEquals("bye", newMsg.getOptionalCord());
+  }
+
+  public void testMicroRepeatedInt32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedInt32Count());
+    msg.addRepeatedInt32(123);
+    assertEquals(1, msg.getRepeatedInt32Count());
+    assertEquals(123, msg.getRepeatedInt32(0));
+    msg.addRepeatedInt32(456);
+    assertEquals(2, msg.getRepeatedInt32Count());
+    assertEquals(123, msg.getRepeatedInt32(0));
+    assertEquals(456, msg.getRepeatedInt32(1));
+    msg.setRepeatedInt32(0, 789);
+    assertEquals(2, msg.getRepeatedInt32Count());
+    assertEquals(789, msg.getRepeatedInt32(0));
+    assertEquals(456, msg.getRepeatedInt32(1));
+    msg.clearRepeatedInt32();
+    assertEquals(0, msg.getRepeatedInt32Count());
+    msg.clearRepeatedInt32()
+       .addRepeatedInt32(456);
+    assertEquals(1, msg.getRepeatedInt32Count());
+    assertEquals(456, msg.getRepeatedInt32(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedInt32Count());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedInt32(123);
+    assertEquals(1, msg.getRepeatedInt32Count());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedInt32Count());
+    assertEquals(123, newMsg.getRepeatedInt32(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedInt32(123)
+       .addRepeatedInt32(456);
+    assertEquals(2, msg.getRepeatedInt32Count());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedInt32Count());
+    assertEquals(123, newMsg.getRepeatedInt32(0));
+    assertEquals(456, newMsg.getRepeatedInt32(1));
+  }
+
+  public void testMicroRepeatedInt64() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedInt64Count());
+    msg.addRepeatedInt64(123);
+    assertEquals(1, msg.getRepeatedInt64Count());
+    assertEquals(123, msg.getRepeatedInt64(0));
+    msg.addRepeatedInt64(456);
+    assertEquals(2, msg.getRepeatedInt64Count());
+    assertEquals(123, msg.getRepeatedInt64(0));
+    assertEquals(456, msg.getRepeatedInt64(1));
+    msg.setRepeatedInt64(0, 789);
+    assertEquals(2, msg.getRepeatedInt64Count());
+    assertEquals(789, msg.getRepeatedInt64(0));
+    assertEquals(456, msg.getRepeatedInt64(1));
+    msg.clearRepeatedInt64();
+    assertEquals(0, msg.getRepeatedInt64Count());
+    msg.clearRepeatedInt64()
+       .addRepeatedInt64(456);
+    assertEquals(1, msg.getRepeatedInt64Count());
+    assertEquals(456, msg.getRepeatedInt64(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedInt64Count());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedInt64(123);
+    assertEquals(1, msg.getRepeatedInt64Count());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedInt64Count());
+    assertEquals(123, newMsg.getRepeatedInt64(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedInt64(123)
+       .addRepeatedInt64(456);
+    assertEquals(2, msg.getRepeatedInt64Count());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedInt64Count());
+    assertEquals(123, newMsg.getRepeatedInt64(0));
+    assertEquals(456, newMsg.getRepeatedInt64(1));
+  }
+
+  public void testMicroRepeatedUint32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedUint32Count());
+    msg.addRepeatedUint32(123);
+    assertEquals(1, msg.getRepeatedUint32Count());
+    assertEquals(123, msg.getRepeatedUint32(0));
+    msg.addRepeatedUint32(456);
+    assertEquals(2, msg.getRepeatedUint32Count());
+    assertEquals(123, msg.getRepeatedUint32(0));
+    assertEquals(456, msg.getRepeatedUint32(1));
+    msg.setRepeatedUint32(0, 789);
+    assertEquals(2, msg.getRepeatedUint32Count());
+    assertEquals(789, msg.getRepeatedUint32(0));
+    assertEquals(456, msg.getRepeatedUint32(1));
+    msg.clearRepeatedUint32();
+    assertEquals(0, msg.getRepeatedUint32Count());
+    msg.clearRepeatedUint32()
+       .addRepeatedUint32(456);
+    assertEquals(1, msg.getRepeatedUint32Count());
+    assertEquals(456, msg.getRepeatedUint32(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedUint32Count());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedUint32(123);
+    assertEquals(1, msg.getRepeatedUint32Count());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedUint32Count());
+    assertEquals(123, newMsg.getRepeatedUint32(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedUint32(123)
+       .addRepeatedUint32(456);
+    assertEquals(2, msg.getRepeatedUint32Count());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedUint32Count());
+    assertEquals(123, newMsg.getRepeatedUint32(0));
+    assertEquals(456, newMsg.getRepeatedUint32(1));
+  }
+
+  public void testMicroRepeatedUint64() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedUint64Count());
+    msg.addRepeatedUint64(123);
+    assertEquals(1, msg.getRepeatedUint64Count());
+    assertEquals(123, msg.getRepeatedUint64(0));
+    msg.addRepeatedUint64(456);
+    assertEquals(2, msg.getRepeatedUint64Count());
+    assertEquals(123, msg.getRepeatedUint64(0));
+    assertEquals(456, msg.getRepeatedUint64(1));
+    msg.setRepeatedUint64(0, 789);
+    assertEquals(2, msg.getRepeatedUint64Count());
+    assertEquals(789, msg.getRepeatedUint64(0));
+    assertEquals(456, msg.getRepeatedUint64(1));
+    msg.clearRepeatedUint64();
+    assertEquals(0, msg.getRepeatedUint64Count());
+    msg.clearRepeatedUint64()
+       .addRepeatedUint64(456);
+    assertEquals(1, msg.getRepeatedUint64Count());
+    assertEquals(456, msg.getRepeatedUint64(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedUint64Count());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedUint64(123);
+    assertEquals(1, msg.getRepeatedUint64Count());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedUint64Count());
+    assertEquals(123, newMsg.getRepeatedUint64(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedUint64(123)
+       .addRepeatedUint64(456);
+    assertEquals(2, msg.getRepeatedUint64Count());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedUint64Count());
+    assertEquals(123, newMsg.getRepeatedUint64(0));
+    assertEquals(456, newMsg.getRepeatedUint64(1));
+  }
+
+  public void testMicroRepeatedSint32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedSint32Count());
+    msg.addRepeatedSint32(123);
+    assertEquals(1, msg.getRepeatedSint32Count());
+    assertEquals(123, msg.getRepeatedSint32(0));
+    msg.addRepeatedSint32(456);
+    assertEquals(2, msg.getRepeatedSint32Count());
+    assertEquals(123, msg.getRepeatedSint32(0));
+    assertEquals(456, msg.getRepeatedSint32(1));
+    msg.setRepeatedSint32(0, 789);
+    assertEquals(2, msg.getRepeatedSint32Count());
+    assertEquals(789, msg.getRepeatedSint32(0));
+    assertEquals(456, msg.getRepeatedSint32(1));
+    msg.clearRepeatedSint32();
+    assertEquals(0, msg.getRepeatedSint32Count());
+    msg.clearRepeatedSint32()
+       .addRepeatedSint32(456);
+    assertEquals(1, msg.getRepeatedSint32Count());
+    assertEquals(456, msg.getRepeatedSint32(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedSint32Count());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedSint32(123);
+    assertEquals(1, msg.getRepeatedSint32Count());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 4);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedSint32Count());
+    assertEquals(123, newMsg.getRepeatedSint32(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedSint32(123)
+       .addRepeatedSint32(456);
+    assertEquals(2, msg.getRepeatedSint32Count());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedSint32Count());
+    assertEquals(123, newMsg.getRepeatedSint32(0));
+    assertEquals(456, newMsg.getRepeatedSint32(1));
+  }
+
+  public void testMicroRepeatedSint64() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedSint64Count());
+    msg.addRepeatedSint64(123);
+    assertEquals(1, msg.getRepeatedSint64Count());
+    assertEquals(123, msg.getRepeatedSint64(0));
+    msg.addRepeatedSint64(456);
+    assertEquals(2, msg.getRepeatedSint64Count());
+    assertEquals(123, msg.getRepeatedSint64(0));
+    assertEquals(456, msg.getRepeatedSint64(1));
+    msg.setRepeatedSint64(0, 789);
+    assertEquals(2, msg.getRepeatedSint64Count());
+    assertEquals(789, msg.getRepeatedSint64(0));
+    assertEquals(456, msg.getRepeatedSint64(1));
+    msg.clearRepeatedSint64();
+    assertEquals(0, msg.getRepeatedSint64Count());
+    msg.clearRepeatedSint64()
+       .addRepeatedSint64(456);
+    assertEquals(1, msg.getRepeatedSint64Count());
+    assertEquals(456, msg.getRepeatedSint64(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedSint64Count());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedSint64(123);
+    assertEquals(1, msg.getRepeatedSint64Count());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 4);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedSint64Count());
+    assertEquals(123, newMsg.getRepeatedSint64(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedSint64(123)
+       .addRepeatedSint64(456);
+    assertEquals(2, msg.getRepeatedSint64Count());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedSint64Count());
+    assertEquals(123, newMsg.getRepeatedSint64(0));
+    assertEquals(456, newMsg.getRepeatedSint64(1));
+  }
+
+  public void testMicroRepeatedFixed32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedFixed32Count());
+    msg.addRepeatedFixed32(123);
+    assertEquals(1, msg.getRepeatedFixed32Count());
+    assertEquals(123, msg.getRepeatedFixed32(0));
+    msg.addRepeatedFixed32(456);
+    assertEquals(2, msg.getRepeatedFixed32Count());
+    assertEquals(123, msg.getRepeatedFixed32(0));
+    assertEquals(456, msg.getRepeatedFixed32(1));
+    msg.setRepeatedFixed32(0, 789);
+    assertEquals(2, msg.getRepeatedFixed32Count());
+    assertEquals(789, msg.getRepeatedFixed32(0));
+    assertEquals(456, msg.getRepeatedFixed32(1));
+    msg.clearRepeatedFixed32();
+    assertEquals(0, msg.getRepeatedFixed32Count());
+    msg.clearRepeatedFixed32()
+       .addRepeatedFixed32(456);
+    assertEquals(1, msg.getRepeatedFixed32Count());
+    assertEquals(456, msg.getRepeatedFixed32(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedFixed32Count());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedFixed32(123);
+    assertEquals(1, msg.getRepeatedFixed32Count());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedFixed32Count());
+    assertEquals(123, newMsg.getRepeatedFixed32(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedFixed32(123)
+       .addRepeatedFixed32(456);
+    assertEquals(2, msg.getRepeatedFixed32Count());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 12);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedFixed32Count());
+    assertEquals(123, newMsg.getRepeatedFixed32(0));
+    assertEquals(456, newMsg.getRepeatedFixed32(1));
+  }
+
+  public void testMicroRepeatedFixed64() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedFixed64Count());
+    msg.addRepeatedFixed64(123);
+    assertEquals(1, msg.getRepeatedFixed64Count());
+    assertEquals(123, msg.getRepeatedFixed64(0));
+    msg.addRepeatedFixed64(456);
+    assertEquals(2, msg.getRepeatedFixed64Count());
+    assertEquals(123, msg.getRepeatedFixed64(0));
+    assertEquals(456, msg.getRepeatedFixed64(1));
+    msg.setRepeatedFixed64(0, 789);
+    assertEquals(2, msg.getRepeatedFixed64Count());
+    assertEquals(789, msg.getRepeatedFixed64(0));
+    assertEquals(456, msg.getRepeatedFixed64(1));
+    msg.clearRepeatedFixed64();
+    assertEquals(0, msg.getRepeatedFixed64Count());
+    msg.clearRepeatedFixed64()
+       .addRepeatedFixed64(456);
+    assertEquals(1, msg.getRepeatedFixed64Count());
+    assertEquals(456, msg.getRepeatedFixed64(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedFixed64Count());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedFixed64(123);
+    assertEquals(1, msg.getRepeatedFixed64Count());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedFixed64Count());
+    assertEquals(123, newMsg.getRepeatedFixed64(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedFixed64(123)
+       .addRepeatedFixed64(456);
+    assertEquals(2, msg.getRepeatedFixed64Count());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 20);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedFixed64Count());
+    assertEquals(123, newMsg.getRepeatedFixed64(0));
+    assertEquals(456, newMsg.getRepeatedFixed64(1));
+  }
+
+  public void testMicroRepeatedSfixed32() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedSfixed32Count());
+    msg.addRepeatedSfixed32(123);
+    assertEquals(1, msg.getRepeatedSfixed32Count());
+    assertEquals(123, msg.getRepeatedSfixed32(0));
+    msg.addRepeatedSfixed32(456);
+    assertEquals(2, msg.getRepeatedSfixed32Count());
+    assertEquals(123, msg.getRepeatedSfixed32(0));
+    assertEquals(456, msg.getRepeatedSfixed32(1));
+    msg.setRepeatedSfixed32(0, 789);
+    assertEquals(2, msg.getRepeatedSfixed32Count());
+    assertEquals(789, msg.getRepeatedSfixed32(0));
+    assertEquals(456, msg.getRepeatedSfixed32(1));
+    msg.clearRepeatedSfixed32();
+    assertEquals(0, msg.getRepeatedSfixed32Count());
+    msg.clearRepeatedSfixed32()
+       .addRepeatedSfixed32(456);
+    assertEquals(1, msg.getRepeatedSfixed32Count());
+    assertEquals(456, msg.getRepeatedSfixed32(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedSfixed32Count());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedSfixed32(123);
+    assertEquals(1, msg.getRepeatedSfixed32Count());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedSfixed32Count());
+    assertEquals(123, newMsg.getRepeatedSfixed32(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedSfixed32(123)
+       .addRepeatedSfixed32(456);
+    assertEquals(2, msg.getRepeatedSfixed32Count());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 12);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedSfixed32Count());
+    assertEquals(123, newMsg.getRepeatedSfixed32(0));
+    assertEquals(456, newMsg.getRepeatedSfixed32(1));
+  }
+
+  public void testMicroRepeatedSfixed64() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedSfixed64Count());
+    msg.addRepeatedSfixed64(123);
+    assertEquals(1, msg.getRepeatedSfixed64Count());
+    assertEquals(123, msg.getRepeatedSfixed64(0));
+    msg.addRepeatedSfixed64(456);
+    assertEquals(2, msg.getRepeatedSfixed64Count());
+    assertEquals(123, msg.getRepeatedSfixed64(0));
+    assertEquals(456, msg.getRepeatedSfixed64(1));
+    msg.setRepeatedSfixed64(0, 789);
+    assertEquals(2, msg.getRepeatedSfixed64Count());
+    assertEquals(789, msg.getRepeatedSfixed64(0));
+    assertEquals(456, msg.getRepeatedSfixed64(1));
+    msg.clearRepeatedSfixed64();
+    assertEquals(0, msg.getRepeatedSfixed64Count());
+    msg.clearRepeatedSfixed64()
+       .addRepeatedSfixed64(456);
+    assertEquals(1, msg.getRepeatedSfixed64Count());
+    assertEquals(456, msg.getRepeatedSfixed64(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedSfixed64Count());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedSfixed64(123);
+    assertEquals(1, msg.getRepeatedSfixed64Count());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedSfixed64Count());
+    assertEquals(123, newMsg.getRepeatedSfixed64(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedSfixed64(123)
+       .addRepeatedSfixed64(456);
+    assertEquals(2, msg.getRepeatedSfixed64Count());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 20);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedSfixed64Count());
+    assertEquals(123, newMsg.getRepeatedSfixed64(0));
+    assertEquals(456, newMsg.getRepeatedSfixed64(1));
+  }
+
+  public void testMicroRepeatedFloat() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedFloatCount());
+    msg.addRepeatedFloat(123f);
+    assertEquals(1, msg.getRepeatedFloatCount());
+    assertTrue(123f == msg.getRepeatedFloat(0));
+    msg.addRepeatedFloat(456f);
+    assertEquals(2, msg.getRepeatedFloatCount());
+    assertTrue(123f == msg.getRepeatedFloat(0));
+    assertTrue(456f == msg.getRepeatedFloat(1));
+    msg.setRepeatedFloat(0, 789f);
+    assertEquals(2, msg.getRepeatedFloatCount());
+    assertTrue(789f == msg.getRepeatedFloat(0));
+    assertTrue(456f == msg.getRepeatedFloat(1));
+    msg.clearRepeatedFloat();
+    assertEquals(0, msg.getRepeatedFloatCount());
+    msg.clearRepeatedFloat()
+       .addRepeatedFloat(456f);
+    assertEquals(1, msg.getRepeatedFloatCount());
+    assertTrue(456f == msg.getRepeatedFloat(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedFloatCount());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedFloat(123f);
+    assertEquals(1, msg.getRepeatedFloatCount());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedFloatCount());
+    assertTrue(123f == newMsg.getRepeatedFloat(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedFloat(123f)
+       .addRepeatedFloat(456f);
+    assertEquals(2, msg.getRepeatedFloatCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 12);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedFloatCount());
+    assertTrue(123f == newMsg.getRepeatedFloat(0));
+    assertTrue(456f == newMsg.getRepeatedFloat(1));
+  }
+
+  public void testMicroRepeatedDouble() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedDoubleCount());
+    msg.addRepeatedDouble(123.0);
+    assertEquals(1, msg.getRepeatedDoubleCount());
+    assertTrue(123.0 == msg.getRepeatedDouble(0));
+    msg.addRepeatedDouble(456.0);
+    assertEquals(2, msg.getRepeatedDoubleCount());
+    assertTrue(123.0 == msg.getRepeatedDouble(0));
+    assertTrue(456.0 == msg.getRepeatedDouble(1));
+    msg.setRepeatedDouble(0, 789.0);
+    assertEquals(2, msg.getRepeatedDoubleCount());
+    assertTrue(789.0 == msg.getRepeatedDouble(0));
+    assertTrue(456.0 == msg.getRepeatedDouble(1));
+    msg.clearRepeatedDouble();
+    assertEquals(0, msg.getRepeatedDoubleCount());
+    msg.clearRepeatedDouble()
+       .addRepeatedDouble(456.0);
+    assertEquals(1, msg.getRepeatedDoubleCount());
+    assertTrue(456.0 == msg.getRepeatedDouble(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedDoubleCount());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedDouble(123.0);
+    assertEquals(1, msg.getRepeatedDoubleCount());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedDoubleCount());
+    assertTrue(123.0 == newMsg.getRepeatedDouble(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedDouble(123.0)
+       .addRepeatedDouble(456.0);
+    assertEquals(2, msg.getRepeatedDoubleCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 20);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedDoubleCount());
+    assertTrue(123.0 == newMsg.getRepeatedDouble(0));
+    assertTrue(456.0 == newMsg.getRepeatedDouble(1));
+  }
+
+  public void testMicroRepeatedBool() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedBoolCount());
+    msg.addRepeatedBool(true);
+    assertEquals(1, msg.getRepeatedBoolCount());
+    assertEquals(true, msg.getRepeatedBool(0));
+    msg.addRepeatedBool(false);
+    assertEquals(2, msg.getRepeatedBoolCount());
+    assertEquals(true, msg.getRepeatedBool(0));
+    assertEquals(false, msg.getRepeatedBool(1));
+    msg.setRepeatedBool(0, false);
+    assertEquals(2, msg.getRepeatedBoolCount());
+    assertEquals(false, msg.getRepeatedBool(0));
+    assertEquals(false, msg.getRepeatedBool(1));
+    msg.clearRepeatedBool();
+    assertEquals(0, msg.getRepeatedBoolCount());
+    msg.clearRepeatedBool()
+       .addRepeatedBool(true);
+    assertEquals(1, msg.getRepeatedBoolCount());
+    assertEquals(true, msg.getRepeatedBool(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedBoolCount());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedBool(false);
+    assertEquals(1, msg.getRepeatedBoolCount());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedBoolCount());
+    assertEquals(false, newMsg.getRepeatedBool(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedBool(true)
+       .addRepeatedBool(false);
+    assertEquals(2, msg.getRepeatedBoolCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedBoolCount());
+    assertEquals(true, newMsg.getRepeatedBool(0));
+    assertEquals(false, newMsg.getRepeatedBool(1));
+  }
+
+  public void testMicroRepeatedString() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedStringCount());
+    msg.addRepeatedString("hello");
+    assertEquals(1, msg.getRepeatedStringCount());
+    assertEquals("hello", msg.getRepeatedString(0));
+    msg.addRepeatedString("bye");
+    assertEquals(2, msg.getRepeatedStringCount());
+    assertEquals("hello", msg.getRepeatedString(0));
+    assertEquals("bye", msg.getRepeatedString(1));
+    msg.setRepeatedString(0, "boo");
+    assertEquals(2, msg.getRepeatedStringCount());
+    assertEquals("boo", msg.getRepeatedString(0));
+    assertEquals("bye", msg.getRepeatedString(1));
+    msg.clearRepeatedString();
+    assertEquals(0, msg.getRepeatedStringCount());
+    msg.clearRepeatedString()
+       .addRepeatedString("hello");
+    assertEquals(1, msg.getRepeatedStringCount());
+    assertEquals("hello", msg.getRepeatedString(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedStringCount());
+
+    // Test 1 entry and an empty string
+    msg.clear()
+       .addRepeatedString("");
+    assertEquals(1, msg.getRepeatedStringCount());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedStringCount());
+    assertEquals("", newMsg.getRepeatedString(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedString("hello")
+       .addRepeatedString("world");
+    assertEquals(2, msg.getRepeatedStringCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 16);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedStringCount());
+    assertEquals("hello", newMsg.getRepeatedString(0));
+    assertEquals("world", newMsg.getRepeatedString(1));
+  }
+
+  public void testMicroRepeatedBytes() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedBytesCount());
+    msg.addRepeatedBytes(ByteStringMicro.copyFromUtf8("hello"));
+    assertEquals(1, msg.getRepeatedBytesCount());
+    assertEquals("hello", msg.getRepeatedBytes(0).toStringUtf8());
+    msg.addRepeatedBytes(ByteStringMicro.copyFromUtf8("bye"));
+    assertEquals(2, msg.getRepeatedBytesCount());
+    assertEquals("hello", msg.getRepeatedBytes(0).toStringUtf8());
+    assertEquals("bye", msg.getRepeatedBytes(1).toStringUtf8());
+    msg.setRepeatedBytes(0, ByteStringMicro.copyFromUtf8("boo"));
+    assertEquals(2, msg.getRepeatedBytesCount());
+    assertEquals("boo", msg.getRepeatedBytes(0).toStringUtf8());
+    assertEquals("bye", msg.getRepeatedBytes(1).toStringUtf8());
+    msg.clearRepeatedBytes();
+    assertEquals(0, msg.getRepeatedBytesCount());
+    msg.clearRepeatedBytes()
+       .addRepeatedBytes(ByteStringMicro.copyFromUtf8("hello"));
+    assertEquals(1, msg.getRepeatedBytesCount());
+    assertEquals("hello", msg.getRepeatedBytes(0).toStringUtf8());
+    msg.clear();
+    assertEquals(0, msg.getRepeatedBytesCount());
+
+    // Test 1 entry and an empty byte array can be serialized
+    msg.clear()
+       .addRepeatedBytes(ByteStringMicro.copyFromUtf8(""));
+    assertEquals(1, msg.getRepeatedBytesCount());
+    assertEquals("", msg.getRepeatedBytes(0).toStringUtf8());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedBytesCount());
+    assertEquals("", newMsg.getRepeatedBytes(0).toStringUtf8());
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedBytes(ByteStringMicro.copyFromUtf8("hello"))
+       .addRepeatedBytes(ByteStringMicro.copyFromUtf8("world"));
+    assertEquals(2, msg.getRepeatedBytesCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 16);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedBytesCount());
+    assertEquals("hello", newMsg.getRepeatedBytes(0).toStringUtf8());
+    assertEquals("world", newMsg.getRepeatedBytes(1).toStringUtf8());
+  }
+
+  public void testMicroRepeatedGroup() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    TestAllTypesMicro.RepeatedGroup group0 =
+      new TestAllTypesMicro.RepeatedGroup().setA(0);
+    TestAllTypesMicro.RepeatedGroup group1 =
+      new TestAllTypesMicro.RepeatedGroup().setA(1);
+    TestAllTypesMicro.RepeatedGroup group2 =
+      new TestAllTypesMicro.RepeatedGroup().setA(2);
+
+    msg.addRepeatedGroup(group0);
+    assertEquals(1, msg.getRepeatedGroupCount());
+    assertEquals(0, msg.getRepeatedGroup(0).getA());
+    msg.addRepeatedGroup(group1);
+    assertEquals(2, msg.getRepeatedGroupCount());
+    assertEquals(0, msg.getRepeatedGroup(0).getA());
+    assertEquals(1, msg.getRepeatedGroup(1).getA());
+    msg.setRepeatedGroup(0, group2);
+    assertEquals(2, msg.getRepeatedGroupCount());
+    assertEquals(2, msg.getRepeatedGroup(0).getA());
+    assertEquals(1, msg.getRepeatedGroup(1).getA());
+    msg.clearRepeatedGroup();
+    assertEquals(0, msg.getRepeatedGroupCount());
+    msg.clearRepeatedGroup()
+       .addRepeatedGroup(group1);
+    assertEquals(1, msg.getRepeatedGroupCount());
+    assertEquals(1, msg.getRepeatedGroup(0).getA());
+    msg.clear();
+    assertEquals(0, msg.getRepeatedGroupCount());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedGroup(group0);
+    assertEquals(1, msg.getRepeatedGroupCount());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedGroupCount());
+    assertEquals(0, newMsg.getRepeatedGroup(0).getA());
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedGroup(group0)
+       .addRepeatedGroup(group1);
+    assertEquals(2, msg.getRepeatedGroupCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 14);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedGroupCount());
+    assertEquals(0, newMsg.getRepeatedGroup(0).getA());
+    assertEquals(1, newMsg.getRepeatedGroup(1).getA());
+  }
+
+
+  public void testMicroRepeatedNestedMessage() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    TestAllTypesMicro.NestedMessage nestedMsg0 =
+      new TestAllTypesMicro.NestedMessage().setBb(0);
+    TestAllTypesMicro.NestedMessage nestedMsg1 =
+      new TestAllTypesMicro.NestedMessage().setBb(1);
+    TestAllTypesMicro.NestedMessage nestedMsg2 =
+      new TestAllTypesMicro.NestedMessage().setBb(2);
+
+    msg.addRepeatedNestedMessage(nestedMsg0);
+    assertEquals(1, msg.getRepeatedNestedMessageCount());
+    assertEquals(0, msg.getRepeatedNestedMessage(0).getBb());
+    msg.addRepeatedNestedMessage(nestedMsg1);
+    assertEquals(2, msg.getRepeatedNestedMessageCount());
+    assertEquals(0, msg.getRepeatedNestedMessage(0).getBb());
+    assertEquals(1, msg.getRepeatedNestedMessage(1).getBb());
+    msg.setRepeatedNestedMessage(0, nestedMsg2);
+    assertEquals(2, msg.getRepeatedNestedMessageCount());
+    assertEquals(2, msg.getRepeatedNestedMessage(0).getBb());
+    assertEquals(1, msg.getRepeatedNestedMessage(1).getBb());
+    msg.clearRepeatedNestedMessage();
+    assertEquals(0, msg.getRepeatedNestedMessageCount());
+    msg.clearRepeatedNestedMessage()
+       .addRepeatedNestedMessage(nestedMsg1);
+    assertEquals(1, msg.getRepeatedNestedMessageCount());
+    assertEquals(1, msg.getRepeatedNestedMessage(0).getBb());
+    msg.clear();
+    assertEquals(0, msg.getRepeatedNestedMessageCount());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedNestedMessage(nestedMsg0);
+    assertEquals(1, msg.getRepeatedNestedMessageCount());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedNestedMessageCount());
+    assertEquals(0, newMsg.getRepeatedNestedMessage(0).getBb());
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedNestedMessage(nestedMsg0)
+       .addRepeatedNestedMessage(nestedMsg1);
+    assertEquals(2, msg.getRepeatedNestedMessageCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedNestedMessageCount());
+    assertEquals(0, newMsg.getRepeatedNestedMessage(0).getBb());
+    assertEquals(1, newMsg.getRepeatedNestedMessage(1).getBb());
+  }
+
+  public void testMicroRepeatedForeignMessage() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    MicroOuterClass.ForeignMessageMicro foreignMsg0 =
+      new MicroOuterClass.ForeignMessageMicro().setC(0);
+    MicroOuterClass.ForeignMessageMicro foreignMsg1 =
+      new MicroOuterClass.ForeignMessageMicro().setC(1);
+    MicroOuterClass.ForeignMessageMicro foreignMsg2 =
+      new MicroOuterClass.ForeignMessageMicro().setC(2);
+
+    msg.addRepeatedForeignMessage(foreignMsg0);
+    assertEquals(1, msg.getRepeatedForeignMessageCount());
+    assertEquals(0, msg.getRepeatedForeignMessage(0).getC());
+    msg.addRepeatedForeignMessage(foreignMsg1);
+    assertEquals(2, msg.getRepeatedForeignMessageCount());
+    assertEquals(0, msg.getRepeatedForeignMessage(0).getC());
+    assertEquals(1, msg.getRepeatedForeignMessage(1).getC());
+    msg.setRepeatedForeignMessage(0, foreignMsg2);
+    assertEquals(2, msg.getRepeatedForeignMessageCount());
+    assertEquals(2, msg.getRepeatedForeignMessage(0).getC());
+    assertEquals(1, msg.getRepeatedForeignMessage(1).getC());
+    msg.clearRepeatedForeignMessage();
+    assertEquals(0, msg.getRepeatedForeignMessageCount());
+    msg.clearRepeatedForeignMessage()
+       .addRepeatedForeignMessage(foreignMsg1);
+    assertEquals(1, msg.getRepeatedForeignMessageCount());
+    assertEquals(1, msg.getRepeatedForeignMessage(0).getC());
+    msg.clear();
+    assertEquals(0, msg.getRepeatedForeignMessageCount());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedForeignMessage(foreignMsg0);
+    assertEquals(1, msg.getRepeatedForeignMessageCount());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedForeignMessageCount());
+    assertEquals(0, newMsg.getRepeatedForeignMessage(0).getC());
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedForeignMessage(foreignMsg0)
+       .addRepeatedForeignMessage(foreignMsg1);
+    assertEquals(2, msg.getRepeatedForeignMessageCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedForeignMessageCount());
+    assertEquals(0, newMsg.getRepeatedForeignMessage(0).getC());
+    assertEquals(1, newMsg.getRepeatedForeignMessage(1).getC());
+  }
+
+  public void testMicroRepeatedImportMessage() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    UnittestImportMicro.ImportMessageMicro importMsg0 =
+      new UnittestImportMicro.ImportMessageMicro().setD(0);
+    UnittestImportMicro.ImportMessageMicro importMsg1 =
+      new UnittestImportMicro.ImportMessageMicro().setD(1);
+    UnittestImportMicro.ImportMessageMicro importMsg2 =
+      new UnittestImportMicro.ImportMessageMicro().setD(2);
+
+    msg.addRepeatedImportMessage(importMsg0);
+    assertEquals(1, msg.getRepeatedImportMessageCount());
+    assertEquals(0, msg.getRepeatedImportMessage(0).getD());
+    msg.addRepeatedImportMessage(importMsg1);
+    assertEquals(2, msg.getRepeatedImportMessageCount());
+    assertEquals(0, msg.getRepeatedImportMessage(0).getD());
+    assertEquals(1, msg.getRepeatedImportMessage(1).getD());
+    msg.setRepeatedImportMessage(0, importMsg2);
+    assertEquals(2, msg.getRepeatedImportMessageCount());
+    assertEquals(2, msg.getRepeatedImportMessage(0).getD());
+    assertEquals(1, msg.getRepeatedImportMessage(1).getD());
+    msg.clearRepeatedImportMessage();
+    assertEquals(0, msg.getRepeatedImportMessageCount());
+    msg.clearRepeatedImportMessage()
+       .addRepeatedImportMessage(importMsg1);
+    assertEquals(1, msg.getRepeatedImportMessageCount());
+    assertEquals(1, msg.getRepeatedImportMessage(0).getD());
+    msg.clear();
+    assertEquals(0, msg.getRepeatedImportMessageCount());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedImportMessage(importMsg0);
+    assertEquals(1, msg.getRepeatedImportMessageCount());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedImportMessageCount());
+    assertEquals(0, newMsg.getRepeatedImportMessage(0).getD());
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedImportMessage(importMsg0)
+       .addRepeatedImportMessage(importMsg1);
+    assertEquals(2, msg.getRepeatedImportMessageCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedImportMessageCount());
+    assertEquals(0, newMsg.getRepeatedImportMessage(0).getD());
+    assertEquals(1, newMsg.getRepeatedImportMessage(1).getD());
+  }
+
+  public void testMicroRepeatedNestedEnum() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    msg.addRepeatedNestedEnum(TestAllTypesMicro.FOO);
+    assertEquals(1, msg.getRepeatedNestedEnumCount());
+    assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0));
+    msg.addRepeatedNestedEnum(TestAllTypesMicro.BAR);
+    assertEquals(2, msg.getRepeatedNestedEnumCount());
+    assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0));
+    assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(1));
+    msg.setRepeatedNestedEnum(0, TestAllTypesMicro.BAZ);
+    assertEquals(2, msg.getRepeatedNestedEnumCount());
+    assertEquals(TestAllTypesMicro.BAZ, msg.getRepeatedNestedEnum(0));
+    assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(1));
+    msg.clearRepeatedNestedEnum();
+    assertEquals(0, msg.getRepeatedNestedEnumCount());
+    msg.clearRepeatedNestedEnum()
+       .addRepeatedNestedEnum(TestAllTypesMicro.BAR);
+    assertEquals(1, msg.getRepeatedNestedEnumCount());
+    assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedNestedEnumCount());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedNestedEnum(TestAllTypesMicro.FOO);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedNestedEnumCount());
+    assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedNestedEnum(TestAllTypesMicro.FOO)
+       .addRepeatedNestedEnum(TestAllTypesMicro.BAR);
+    assertEquals(2, msg.getRepeatedNestedEnumCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedNestedEnumCount());
+    assertEquals(TestAllTypesMicro.FOO, msg.getRepeatedNestedEnum(0));
+    assertEquals(TestAllTypesMicro.BAR, msg.getRepeatedNestedEnum(1));
+  }
+
+  public void testMicroRepeatedForeignEnum() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    msg.addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_FOO);
+    assertEquals(1, msg.getRepeatedForeignEnumCount());
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0));
+    msg.addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR);
+    assertEquals(2, msg.getRepeatedForeignEnumCount());
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0));
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(1));
+    msg.setRepeatedForeignEnum(0, MicroOuterClass.FOREIGN_MICRO_BAZ);
+    assertEquals(2, msg.getRepeatedForeignEnumCount());
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_BAZ, msg.getRepeatedForeignEnum(0));
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(1));
+    msg.clearRepeatedForeignEnum();
+    assertEquals(0, msg.getRepeatedForeignEnumCount());
+    msg.clearRepeatedForeignEnum()
+       .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR);
+    assertEquals(1, msg.getRepeatedForeignEnumCount());
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedForeignEnumCount());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_FOO);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedForeignEnumCount());
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_FOO)
+       .addRepeatedForeignEnum(MicroOuterClass.FOREIGN_MICRO_BAR);
+    assertEquals(2, msg.getRepeatedForeignEnumCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedForeignEnumCount());
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_FOO, msg.getRepeatedForeignEnum(0));
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getRepeatedForeignEnum(1));
+  }
+
+  public void testMicroRepeatedImportEnum() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    msg.addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_FOO);
+    assertEquals(1, msg.getRepeatedImportEnumCount());
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0));
+    msg.addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR);
+    assertEquals(2, msg.getRepeatedImportEnumCount());
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0));
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(1));
+    msg.setRepeatedImportEnum(0, UnittestImportMicro.IMPORT_MICRO_BAZ);
+    assertEquals(2, msg.getRepeatedImportEnumCount());
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_BAZ, msg.getRepeatedImportEnum(0));
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(1));
+    msg.clearRepeatedImportEnum();
+    assertEquals(0, msg.getRepeatedImportEnumCount());
+    msg.clearRepeatedImportEnum()
+       .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR);
+    assertEquals(1, msg.getRepeatedImportEnumCount());
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedImportEnumCount());
+
+    // Test 1 entry
+    msg.clear()
+       .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_FOO);
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedImportEnumCount());
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_FOO)
+       .addRepeatedImportEnum(UnittestImportMicro.IMPORT_MICRO_BAR);
+    assertEquals(2, msg.getRepeatedImportEnumCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedImportEnumCount());
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_FOO, msg.getRepeatedImportEnum(0));
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getRepeatedImportEnum(1));
+  }
+
+  public void testMicroRepeatedStringPiece() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedStringPieceCount());
+    msg.addRepeatedStringPiece("hello");
+    assertEquals(1, msg.getRepeatedStringPieceCount());
+    assertEquals("hello", msg.getRepeatedStringPiece(0));
+    msg.addRepeatedStringPiece("bye");
+    assertEquals(2, msg.getRepeatedStringPieceCount());
+    assertEquals("hello", msg.getRepeatedStringPiece(0));
+    assertEquals("bye", msg.getRepeatedStringPiece(1));
+    msg.setRepeatedStringPiece(0, "boo");
+    assertEquals(2, msg.getRepeatedStringPieceCount());
+    assertEquals("boo", msg.getRepeatedStringPiece(0));
+    assertEquals("bye", msg.getRepeatedStringPiece(1));
+    msg.clearRepeatedStringPiece();
+    assertEquals(0, msg.getRepeatedStringPieceCount());
+    msg.clearRepeatedStringPiece()
+       .addRepeatedStringPiece("hello");
+    assertEquals(1, msg.getRepeatedStringPieceCount());
+    assertEquals("hello", msg.getRepeatedStringPiece(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedStringPieceCount());
+
+    // Test 1 entry and an empty string
+    msg.clear()
+       .addRepeatedStringPiece("");
+    assertEquals(1, msg.getRepeatedStringPieceCount());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedStringPieceCount());
+    assertEquals("", newMsg.getRepeatedStringPiece(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedStringPiece("hello")
+       .addRepeatedStringPiece("world");
+    assertEquals(2, msg.getRepeatedStringPieceCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 16);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedStringPieceCount());
+    assertEquals("hello", newMsg.getRepeatedStringPiece(0));
+    assertEquals("world", newMsg.getRepeatedStringPiece(1));
+  }
+
+  public void testMicroRepeatedCord() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertEquals(0, msg.getRepeatedCordCount());
+    msg.addRepeatedCord("hello");
+    assertEquals(1, msg.getRepeatedCordCount());
+    assertEquals("hello", msg.getRepeatedCord(0));
+    msg.addRepeatedCord("bye");
+    assertEquals(2, msg.getRepeatedCordCount());
+    assertEquals("hello", msg.getRepeatedCord(0));
+    assertEquals("bye", msg.getRepeatedCord(1));
+    msg.setRepeatedCord(0, "boo");
+    assertEquals(2, msg.getRepeatedCordCount());
+    assertEquals("boo", msg.getRepeatedCord(0));
+    assertEquals("bye", msg.getRepeatedCord(1));
+    msg.clearRepeatedCord();
+    assertEquals(0, msg.getRepeatedCordCount());
+    msg.clearRepeatedCord()
+       .addRepeatedCord("hello");
+    assertEquals(1, msg.getRepeatedCordCount());
+    assertEquals("hello", msg.getRepeatedCord(0));
+    msg.clear();
+    assertEquals(0, msg.getRepeatedCordCount());
+
+    // Test 1 entry and an empty string
+    msg.clear()
+       .addRepeatedCord("");
+    assertEquals(1, msg.getRepeatedCordCount());
+    byte [] result = msg.toByteArray();
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesMicro newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(1, newMsg.getRepeatedCordCount());
+    assertEquals("", newMsg.getRepeatedCord(0));
+
+    // Test 2 entries
+    msg.clear()
+       .addRepeatedCord("hello")
+       .addRepeatedCord("world");
+    assertEquals(2, msg.getRepeatedCordCount());
+    result = msg.toByteArray();
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 16);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesMicro.parseFrom(result);
+    assertEquals(2, newMsg.getRepeatedCordCount());
+    assertEquals("hello", newMsg.getRepeatedCord(0));
+    assertEquals("world", newMsg.getRepeatedCord(1));
+  }
+
+  /**
+   * Tests that code generation correctly wraps a single message into its outer
+   * class. The class {@code SingleMessageMicro} is imported from the outer
+   * class {@code UnittestSingleMicro}, whose name is implicit. Any error would
+   * cause this method to fail compilation.
+   */
+  public void testMicroSingle() throws Exception {
+    SingleMessageMicro msg = new SingleMessageMicro();
+  }
+
+  /**
+   * Tests that code generation correctly skips generating the outer class if
+   * unnecessary, letting a file-scope entity have the same name. The class
+   * {@code MultipleNameClashMicro} shares the same name with the file's outer
+   * class defined explicitly, but the file contains no other entities and has
+   * java_multiple_files set. Any error would cause this method to fail
+   * compilation.
+   */
+  public void testMicroMultipleNameClash() throws Exception {
+    MultipleNameClashMicro msg = new MultipleNameClashMicro();
+    msg.setField(0);
+  }
+
+  /**
+   * Tests that code generation correctly handles enums in different scopes in
+   * a source file with the option java_multiple_files set to true. Any error
+   * would cause this method to fail compilation.
+   */
+  public void testMicroMultipleEnumScoping() throws Exception {
+    FileScopeEnumRefMicro msg1 = new FileScopeEnumRefMicro();
+    msg1.setEnumField(UnittestMultipleMicro.ONE);
+    MessageScopeEnumRefMicro msg2 = new MessageScopeEnumRefMicro();
+    msg2.setEnumField(MessageScopeEnumRefMicro.TWO);
+  }
+
+  /**
+   * Tests that code generation with mixed values of the java_multiple_files
+   * options between the main source file and the imported source files would
+   * generate correct references. Any error would cause this method to fail
+   * compilation.
+   */
+  public void testMicroMultipleImportingNonMultiple() throws Exception {
+    UnittestImportMicro.ImportMessageMicro importMsg =
+        new UnittestImportMicro.ImportMessageMicro();
+    MultipleImportingNonMultipleMicro1 micro1 = new MultipleImportingNonMultipleMicro1();
+    micro1.setField(importMsg);
+    MultipleImportingNonMultipleMicro2 micro2 = new MultipleImportingNonMultipleMicro2();
+    micro2.setMicro1(micro1);
+  }
+
+  public void testMicroDefaults() throws Exception {
+    TestAllTypesMicro msg = new TestAllTypesMicro();
+    assertFalse(msg.hasDefaultInt32());
+    assertEquals(41, msg.getDefaultInt32());
+    assertFalse(msg.hasDefaultInt64());
+    assertEquals(42, msg.getDefaultInt64());
+    assertFalse(msg.hasDefaultUint32());
+    assertEquals(43, msg.getDefaultUint32());
+    assertFalse(msg.hasDefaultUint64());
+    assertEquals(44, msg.getDefaultUint64());
+    assertFalse(msg.hasDefaultSint32());
+    assertEquals(-45, msg.getDefaultSint32());
+    assertFalse(msg.hasDefaultSint64());
+    assertEquals(46, msg.getDefaultSint64());
+    assertFalse(msg.hasDefaultFixed32());
+    assertEquals(47, msg.getDefaultFixed32());
+    assertFalse(msg.hasDefaultFixed64());
+    assertEquals(48, msg.getDefaultFixed64());
+    assertFalse(msg.hasDefaultSfixed32());
+    assertEquals(49, msg.getDefaultSfixed32());
+    assertFalse(msg.hasDefaultSfixed64());
+    assertEquals(-50, msg.getDefaultSfixed64());
+    assertFalse(msg.hasDefaultFloat());
+    assertTrue(51.5f == msg.getDefaultFloat());
+    assertFalse(msg.hasDefaultDouble());
+    assertTrue(52.0e3 == msg.getDefaultDouble());
+    assertFalse(msg.hasDefaultBool());
+    assertEquals(true, msg.getDefaultBool());
+    assertFalse(msg.hasDefaultString());
+    assertEquals("hello", msg.getDefaultString());
+    assertFalse(msg.hasDefaultBytes());
+    assertEquals("world", msg.getDefaultBytes().toStringUtf8());
+    assertFalse(msg.hasDefaultNestedEnum());
+    assertEquals(TestAllTypesMicro.BAR, msg.getDefaultNestedEnum());
+    assertFalse(msg.hasDefaultForeignEnum());
+    assertEquals(MicroOuterClass.FOREIGN_MICRO_BAR, msg.getDefaultForeignEnum());
+    assertFalse(msg.hasDefaultImportEnum());
+    assertEquals(UnittestImportMicro.IMPORT_MICRO_BAR, msg.getDefaultImportEnum());
+    assertFalse(msg.hasDefaultFloatInf());
+    assertEquals(Float.POSITIVE_INFINITY, msg.getDefaultFloatInf());
+    assertFalse(msg.hasDefaultFloatNegInf());
+    assertEquals(Float.NEGATIVE_INFINITY, msg.getDefaultFloatNegInf());
+    assertFalse(msg.hasDefaultFloatNan());
+    assertEquals(Float.NaN, msg.getDefaultFloatNan());
+    assertFalse(msg.hasDefaultDoubleInf());
+    assertEquals(Double.POSITIVE_INFINITY, msg.getDefaultDoubleInf());
+    assertFalse(msg.hasDefaultDoubleNegInf());
+    assertEquals(Double.NEGATIVE_INFINITY, msg.getDefaultDoubleNegInf());
+    assertFalse(msg.hasDefaultDoubleNan());
+    assertEquals(Double.NaN, msg.getDefaultDoubleNan());
+  }
+
+  /**
+   * Test that a bug in skipRawBytes() has been fixed:  if the skip skips
+   * exactly up to a limit, this should not break things.
+   */
+  public void testSkipRawBytesBug() throws Exception {
+    byte[] rawBytes = new byte[] { 1, 2 };
+    CodedInputStreamMicro input = CodedInputStreamMicro.newInstance(rawBytes);
+
+    int limit = input.pushLimit(1);
+    input.skipRawBytes(1);
+    input.popLimit(limit);
+    assertEquals(2, input.readRawByte());
+  }
+
+  /**
+   * Test that a bug in skipRawBytes() has been fixed:  if the skip skips
+   * past the end of a buffer with a limit that has been set past the end of
+   * that buffer, this should not break things.
+   */
+  public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception {
+    byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 };
+    CodedInputStreamMicro input = CodedInputStreamMicro.newInstance(
+        new SmallBlockInputStream(rawBytes, 3));
+
+    int limit = input.pushLimit(4);
+    // In order to expose the bug we need to read at least one byte to prime the
+    // buffer inside the CodedInputStream.
+    assertEquals(1, input.readRawByte());
+    // Skip to the end of the limit.
+    input.skipRawBytes(3);
+    assertTrue(input.isAtEnd());
+    input.popLimit(limit);
+    assertEquals(5, input.readRawByte());
+  }
+
+  /**
+   * An InputStream which limits the number of bytes it reads at a time.
+   * We use this to make sure that CodedInputStream doesn't screw up when
+   * reading in small blocks.
+   */
+  private static final class SmallBlockInputStream extends FilterInputStream {
+    private final int blockSize;
+
+    public SmallBlockInputStream(byte[] data, int blockSize) {
+      this(new ByteArrayInputStream(data), blockSize);
+    }
+
+    public SmallBlockInputStream(InputStream in, int blockSize) {
+      super(in);
+      this.blockSize = blockSize;
+    }
+
+    public int read(byte[] b) throws IOException {
+      return super.read(b, 0, Math.min(b.length, blockSize));
+    }
+
+    public int read(byte[] b, int off, int len) throws IOException {
+      return super.read(b, off, Math.min(len, blockSize));
+    }
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/NanoTest.java b/protobuf/java/src/test/java/com/google/protobuf/NanoTest.java
new file mode 100644
index 0000000..42b1793
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/NanoTest.java
@@ -0,0 +1,3962 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package com.google.protobuf;
+
+import com.google.protobuf.nano.BytesOffsetLengthTestNanoOuterClass.BytesOffsetLengthTestNano;
+import com.google.protobuf.nano.CodedInputByteBufferNano;
+import com.google.protobuf.nano.CodedOutputByteBufferNano;
+import com.google.protobuf.nano.EnumClassNanoMultiple;
+import com.google.protobuf.nano.EnumClassNanos;
+import com.google.protobuf.nano.EnumValidity;
+import com.google.protobuf.nano.EnumValidityAccessors;
+import com.google.protobuf.nano.FileScopeEnumMultiple;
+import com.google.protobuf.nano.FileScopeEnumRefNano;
+import com.google.protobuf.nano.InternalNano;
+import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
+import com.google.protobuf.nano.MessageNano;
+import com.google.protobuf.nano.MessageScopeEnumRefNano;
+import com.google.protobuf.nano.MultipleImportingNonMultipleNano1;
+import com.google.protobuf.nano.MultipleImportingNonMultipleNano2;
+import com.google.protobuf.nano.MultipleNameClashNano;
+import com.google.protobuf.nano.NanoAccessorsOuterClass.TestNanoAccessors;
+import com.google.protobuf.nano.NanoHasOuterClass.TestAllTypesNanoHas;
+import com.google.protobuf.nano.NanoOuterClass;
+import com.google.protobuf.nano.NanoOuterClass.TestAllTypesNano;
+import com.google.protobuf.nano.NanoReferenceTypes;
+import com.google.protobuf.nano.NanoReferenceTypesCompat;
+import com.google.protobuf.nano.NanoRepeatedPackables;
+import com.google.protobuf.nano.PackedExtensions;
+import com.google.protobuf.nano.RepeatedExtensions;
+import com.google.protobuf.nano.SingularExtensions;
+import com.google.protobuf.nano.TestRepeatedMergeNano;
+import com.google.protobuf.nano.UnittestMultipleNano;
+import com.google.protobuf.nano.UnittestRecursiveNano.RecursiveMessageNano;
+import com.google.protobuf.nano.UnittestSimpleNano.SimpleMessageNano;
+import com.google.protobuf.nano.UnittestSingleNano.SingleMessageNano;
+import com.google.protobuf.nano.UnknownEnumValuesNanoOuterClass.StandardVersion;
+import com.google.protobuf.nano.UnknownEnumValuesNanoOuterClass.VersionWithoutVal3;
+import com.google.protobuf.nano.testext.Extensions;
+import com.google.protobuf.nano.testext.Extensions.AnotherMessage;
+import com.google.protobuf.nano.testext.Extensions.MessageWithGroup;
+import com.google.protobuf.nano.testimport.UnittestImportNano;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+/**
+ * Test nano runtime.
+ *
+ * @author ulas@google.com Ulas Kirazci
+ */
+public class NanoTest extends TestCase {
+  @Override
+  public void setUp() throws Exception {
+  }
+
+  public void testSimpleMessageNano() throws Exception {
+    SimpleMessageNano msg = new SimpleMessageNano();
+    assertEquals(123, msg.d);
+    assertEquals(null, msg.nestedMsg);
+    assertEquals(SimpleMessageNano.BAZ, msg.defaultNestedEnum);
+
+    msg.d = 456;
+    assertEquals(456, msg.d);
+
+    SimpleMessageNano.NestedMessage nestedMsg = new SimpleMessageNano.NestedMessage();
+    nestedMsg.bb = 2;
+    assertEquals(2, nestedMsg.bb);
+    msg.nestedMsg = nestedMsg;
+    assertEquals(2, msg.nestedMsg.bb);
+
+    msg.defaultNestedEnum = SimpleMessageNano.BAR;
+    assertEquals(SimpleMessageNano.BAR, msg.defaultNestedEnum);
+
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    SimpleMessageNano newMsg = SimpleMessageNano.parseFrom(result);
+    assertEquals(456, newMsg.d);
+    assertEquals(2, msg.nestedMsg.bb);
+    assertEquals(SimpleMessageNano.BAR, msg.defaultNestedEnum);
+
+    msg.nestedMsg = null;
+    assertTrue(msgSerializedSize != msg.getSerializedSize());
+
+    msg.clear();
+    assertEquals(0, msg.getSerializedSize());
+  }
+
+  public void testRecursiveMessageNano() throws Exception {
+    RecursiveMessageNano msg = new RecursiveMessageNano();
+    assertTrue(msg.repeatedRecursiveMessageNano.length == 0);
+
+    RecursiveMessageNano msg1 = new RecursiveMessageNano();
+    msg1.id = 1;
+    assertEquals(1, msg1.id);
+    RecursiveMessageNano msg2 = new RecursiveMessageNano();
+    msg2.id = 2;
+    RecursiveMessageNano msg3 = new RecursiveMessageNano();
+    msg3.id = 3;
+
+    RecursiveMessageNano.NestedMessage nestedMsg = new RecursiveMessageNano.NestedMessage();
+    nestedMsg.a = msg1;
+    assertEquals(1, nestedMsg.a.id);
+
+    msg.id = 0;
+    msg.nestedMessage = nestedMsg;
+    msg.optionalRecursiveMessageNano = msg2;
+    msg.repeatedRecursiveMessageNano = new RecursiveMessageNano[] { msg3 };
+
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 16);
+    assertEquals(result.length, msgSerializedSize);
+
+    RecursiveMessageNano newMsg = RecursiveMessageNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedRecursiveMessageNano.length);
+
+    assertEquals(0, newMsg.id);
+    assertEquals(1, newMsg.nestedMessage.a.id);
+    assertEquals(2, newMsg.optionalRecursiveMessageNano.id);
+    assertEquals(3, newMsg.repeatedRecursiveMessageNano[0].id);
+  }
+
+  public void testMessageNoFields() {
+    SingleMessageNano msg = new SingleMessageNano();
+    assertEquals(0, msg.getSerializedSize());
+    assertEquals(0, MessageNano.toByteArray(msg).length);
+  }
+
+  public void testNanoRequiredInt32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.id = 123;
+    assertEquals(123, msg.id);
+    msg.clear().id = 456;
+    assertEquals(456, msg.id);
+    msg.clear();
+
+    msg.id = 123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 3);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(123, newMsg.id);
+  }
+
+  public void testNanoOptionalInt32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalInt32 = 123;
+    assertEquals(123, msg.optionalInt32);
+    msg.clear()
+       .optionalInt32 = 456;
+    assertEquals(456, msg.optionalInt32);
+    msg.clear();
+
+    msg.optionalInt32 = 123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(123, newMsg.optionalInt32);
+  }
+
+  public void testNanoOptionalInt64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalInt64 = 123;
+    assertEquals(123, msg.optionalInt64);
+    msg.clear()
+       .optionalInt64 = 456;
+    assertEquals(456, msg.optionalInt64);
+    msg.clear();
+    assertEquals(0, msg.optionalInt64);
+
+    msg.optionalInt64 = 123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(123, newMsg.optionalInt64);
+  }
+
+  public void testNanoOptionalUint32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalUint32 = 123;
+    assertEquals(123, msg.optionalUint32);
+    msg.clear()
+       .optionalUint32 = 456;
+    assertEquals(456, msg.optionalUint32);
+    msg.clear();
+    assertEquals(0, msg.optionalUint32);
+
+    msg.optionalUint32 = 123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(123, newMsg.optionalUint32);
+  }
+
+  public void testNanoOptionalUint64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalUint64 = 123;
+    assertEquals(123, msg.optionalUint64);
+    msg.clear()
+       .optionalUint64 = 456;
+    assertEquals(456, msg.optionalUint64);
+    msg.clear();
+    assertEquals(0, msg.optionalUint64);
+
+    msg.optionalUint64 = 123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(123, newMsg.optionalUint64);
+  }
+
+  public void testNanoOptionalSint32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalSint32 = 123;
+    assertEquals(123, msg.optionalSint32);
+    msg.clear()
+       .optionalSint32 = 456;
+    assertEquals(456, msg.optionalSint32);
+    msg.clear();
+    assertEquals(0, msg.optionalSint32);
+
+    msg.optionalSint32 = -123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(-123, newMsg.optionalSint32);
+  }
+
+  public void testNanoOptionalSint64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalSint64 = 123;
+    assertEquals(123, msg.optionalSint64);
+    msg.clear()
+       .optionalSint64 = 456;
+    assertEquals(456, msg.optionalSint64);
+    msg.clear();
+    assertEquals(0, msg.optionalSint64);
+
+    msg.optionalSint64 = -123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(-123, newMsg.optionalSint64);
+  }
+
+  public void testNanoOptionalFixed32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalFixed32 = 123;
+    assertEquals(123, msg.optionalFixed32);
+    msg.clear()
+       .optionalFixed32 = 456;
+    assertEquals(456, msg.optionalFixed32);
+    msg.clear();
+    assertEquals(0, msg.optionalFixed32);
+
+    msg.optionalFixed32 = 123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(123, newMsg.optionalFixed32);
+  }
+
+  public void testNanoOptionalFixed64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalFixed64 = 123;
+    assertEquals(123, msg.optionalFixed64);
+    msg.clear()
+       .optionalFixed64 = 456;
+    assertEquals(456, msg.optionalFixed64);
+    msg.clear();
+    assertEquals(0, msg.optionalFixed64);
+
+    msg.optionalFixed64 = 123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 12);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(123, newMsg.optionalFixed64);
+  }
+
+  public void testNanoOptionalSfixed32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalSfixed32 = 123;
+    assertEquals(123, msg.optionalSfixed32);
+    msg.clear()
+       .optionalSfixed32 = 456;
+    assertEquals(456, msg.optionalSfixed32);
+    msg.clear();
+    assertEquals(0, msg.optionalSfixed32);
+
+    msg.optionalSfixed32 = 123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(123, newMsg.optionalSfixed32);
+  }
+
+  public void testNanoOptionalSfixed64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalSfixed64 = 123;
+    assertEquals(123, msg.optionalSfixed64);
+    msg.clear()
+       .optionalSfixed64 = 456;
+    assertEquals(456, msg.optionalSfixed64);
+    msg.clear();
+    assertEquals(0, msg.optionalSfixed64);
+
+    msg.optionalSfixed64 = -123;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 12);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(-123, newMsg.optionalSfixed64);
+  }
+
+  public void testNanoOptionalFloat() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalFloat = 123f;
+    assertTrue(123.0f == msg.optionalFloat);
+    msg.clear()
+       .optionalFloat = 456.0f;
+    assertTrue(456.0f == msg.optionalFloat);
+    msg.clear();
+    assertTrue(0.0f == msg.optionalFloat);
+
+    msg.optionalFloat = -123.456f;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(-123.456f == newMsg.optionalFloat);
+  }
+
+  public void testNanoOptionalDouble() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalDouble = 123;
+    assertTrue(123.0 == msg.optionalDouble);
+    msg.clear()
+       .optionalDouble = 456.0;
+    assertTrue(456.0 == msg.optionalDouble);
+    msg.clear();
+    assertTrue(0.0 == msg.optionalDouble);
+
+    msg.optionalDouble = -123.456;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 12);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(-123.456 == newMsg.optionalDouble);
+  }
+
+  public void testNanoOptionalBool() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalBool = true;
+    assertTrue(msg.optionalBool);
+    msg.clear()
+       .optionalBool = true;
+    assertTrue(msg.optionalBool);
+    msg.clear();
+    assertFalse(msg.optionalBool);
+
+    msg.optionalBool = true;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 5);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(newMsg.optionalBool);
+  }
+
+  public void testNanoOptionalString() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalString = "hello";
+    assertEquals("hello", msg.optionalString);
+    msg.clear();
+    assertTrue(msg.optionalString.isEmpty());
+    msg.clear()
+       .optionalString = "hello2";
+    assertEquals("hello2", msg.optionalString);
+    msg.clear();
+    assertTrue(msg.optionalString.isEmpty());
+
+    msg.optionalString = "bye";
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(newMsg.optionalString != null);
+    assertEquals("bye", newMsg.optionalString);
+  }
+
+  public void testNanoOptionalBytes() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertFalse(msg.optionalBytes.length > 0);
+    msg.optionalBytes = InternalNano.copyFromUtf8("hello");
+    assertTrue(msg.optionalBytes.length > 0);
+    assertEquals("hello", new String(msg.optionalBytes, "UTF-8"));
+    msg.clear();
+    assertFalse(msg.optionalBytes.length > 0);
+    msg.clear()
+       .optionalBytes = InternalNano.copyFromUtf8("hello");
+    assertTrue(msg.optionalBytes.length > 0);
+    msg.clear();
+    assertFalse(msg.optionalBytes.length > 0);
+
+    msg.optionalBytes = InternalNano.copyFromUtf8("bye");
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(newMsg.optionalBytes.length > 0);
+    assertEquals("bye", new String(newMsg.optionalBytes, "UTF-8"));
+  }
+
+  public void testNanoOptionalGroup() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    TestAllTypesNano.OptionalGroup grp = new TestAllTypesNano.OptionalGroup();
+    grp.a = 1;
+    assertFalse(msg.optionalGroup != null);
+    msg.optionalGroup = grp;
+    assertTrue(msg.optionalGroup != null);
+    assertEquals(1, msg.optionalGroup.a);
+    msg.clear();
+    assertFalse(msg.optionalGroup != null);
+    msg.clear()
+       .optionalGroup = new TestAllTypesNano.OptionalGroup();
+    msg.optionalGroup.a = 2;
+    assertTrue(msg.optionalGroup != null);
+    msg.clear();
+    assertFalse(msg.optionalGroup != null);
+
+    msg.optionalGroup = grp;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(newMsg.optionalGroup != null);
+    assertEquals(1, newMsg.optionalGroup.a);
+  }
+
+  public void testNanoOptionalGroupWithUnknownFieldsEnabled() throws Exception {
+    MessageWithGroup msg = new MessageWithGroup();
+    MessageWithGroup.Group grp = new MessageWithGroup.Group();
+    grp.a = 1;
+    msg.group = grp;
+    byte [] serialized = MessageNano.toByteArray(msg);
+
+    MessageWithGroup parsed = MessageWithGroup.parseFrom(serialized);
+    assertEquals(1, parsed.group.a);
+
+    byte [] serialized2 = MessageNano.toByteArray(parsed);
+    assertEquals(serialized.length, serialized2.length);
+    MessageWithGroup parsed2 = MessageWithGroup.parseFrom(serialized2);
+    assertEquals(1, parsed2.group.a);
+  }
+
+  public void testNanoOptionalNestedMessage() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    TestAllTypesNano.NestedMessage nestedMsg = new TestAllTypesNano.NestedMessage();
+    nestedMsg.bb = 1;
+    assertFalse(msg.optionalNestedMessage != null);
+    msg.optionalNestedMessage = nestedMsg;
+    assertTrue(msg.optionalNestedMessage != null);
+    assertEquals(1, msg.optionalNestedMessage.bb);
+    msg.clear();
+    assertFalse(msg.optionalNestedMessage != null);
+    msg.clear()
+       .optionalNestedMessage = new TestAllTypesNano.NestedMessage();
+    msg.optionalNestedMessage.bb = 2;
+    assertTrue(msg.optionalNestedMessage != null);
+    msg.clear();
+    assertFalse(msg.optionalNestedMessage != null);
+
+    msg.optionalNestedMessage = nestedMsg;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(newMsg.optionalNestedMessage != null);
+    assertEquals(1, newMsg.optionalNestedMessage.bb);
+  }
+
+  public void testNanoOptionalForeignMessage() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    NanoOuterClass.ForeignMessageNano nestedMsg = new NanoOuterClass.ForeignMessageNano();
+    nestedMsg.c = 1;
+    assertFalse(msg.optionalForeignMessage != null);
+    msg.optionalForeignMessage = nestedMsg;
+    assertTrue(msg.optionalForeignMessage != null);
+    assertEquals(1, msg.optionalForeignMessage.c);
+    msg.clear();
+    assertFalse(msg.optionalForeignMessage != null);
+    msg.clear()
+       .optionalForeignMessage = new NanoOuterClass.ForeignMessageNano();
+    msg.optionalForeignMessage.c = 2;
+    assertTrue(msg.optionalForeignMessage != null);
+    msg.clear();
+    assertFalse(msg.optionalForeignMessage != null);
+
+    msg.optionalForeignMessage = nestedMsg;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(newMsg.optionalForeignMessage != null);
+    assertEquals(1, newMsg.optionalForeignMessage.c);
+  }
+
+  public void testNanoOptionalImportMessage() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    UnittestImportNano.ImportMessageNano nestedMsg = new UnittestImportNano.ImportMessageNano();
+    nestedMsg.d = 1;
+    assertFalse(msg.optionalImportMessage != null);
+    msg.optionalImportMessage = nestedMsg;
+    assertTrue(msg.optionalImportMessage != null);
+    assertEquals(1, msg.optionalImportMessage.d);
+    msg.clear();
+    assertFalse(msg.optionalImportMessage != null);
+    msg.clear()
+       .optionalImportMessage = new UnittestImportNano.ImportMessageNano();
+    msg.optionalImportMessage.d = 2;
+    assertTrue(msg.optionalImportMessage != null);
+    msg.clear();
+    assertFalse(msg.optionalImportMessage != null);
+
+    msg.optionalImportMessage = nestedMsg;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(newMsg.optionalImportMessage != null);
+    assertEquals(1, newMsg.optionalImportMessage.d);
+  }
+
+  public void testNanoOptionalNestedEnum() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalNestedEnum = TestAllTypesNano.BAR;
+    assertEquals(TestAllTypesNano.BAR, msg.optionalNestedEnum);
+    msg.clear()
+       .optionalNestedEnum = TestAllTypesNano.BAZ;
+    assertEquals(TestAllTypesNano.BAZ, msg.optionalNestedEnum);
+    msg.clear();
+    assertEquals(TestAllTypesNano.FOO, msg.optionalNestedEnum);
+
+    msg.optionalNestedEnum = TestAllTypesNano.BAR;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(TestAllTypesNano.BAR, newMsg.optionalNestedEnum);
+  }
+
+  public void testNanoOptionalForeignEnum() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalForeignEnum = NanoOuterClass.FOREIGN_NANO_BAR;
+    assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.optionalForeignEnum);
+    msg.clear()
+       .optionalForeignEnum = NanoOuterClass.FOREIGN_NANO_BAZ;
+    assertEquals(NanoOuterClass.FOREIGN_NANO_BAZ, msg.optionalForeignEnum);
+    msg.clear();
+    assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.optionalForeignEnum);
+
+    msg.optionalForeignEnum = NanoOuterClass.FOREIGN_NANO_BAR;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, newMsg.optionalForeignEnum);
+  }
+
+  public void testNanoOptionalImportEnum() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalImportEnum = UnittestImportNano.IMPORT_NANO_BAR;
+    assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.optionalImportEnum);
+    msg.clear()
+       .optionalImportEnum = UnittestImportNano.IMPORT_NANO_BAZ;
+    assertEquals(UnittestImportNano.IMPORT_NANO_BAZ, msg.optionalImportEnum);
+    msg.clear();
+    assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.optionalImportEnum);
+
+    msg.optionalImportEnum = UnittestImportNano.IMPORT_NANO_BAR;
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(UnittestImportNano.IMPORT_NANO_BAR, newMsg.optionalImportEnum);
+  }
+
+  public void testNanoOptionalStringPiece() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalStringPiece = "hello";
+    assertEquals("hello", msg.optionalStringPiece);
+    msg.clear();
+    assertTrue(msg.optionalStringPiece.isEmpty());
+    msg.clear()
+       .optionalStringPiece = "hello2";
+    assertEquals("hello2", msg.optionalStringPiece);
+    msg.clear();
+    assertTrue(msg.optionalStringPiece.isEmpty());
+
+    msg.optionalStringPiece = "bye";
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(newMsg.optionalStringPiece != null);
+    assertEquals("bye", newMsg.optionalStringPiece);
+  }
+
+  public void testNanoOptionalCord() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalCord = "hello";
+    assertEquals("hello", msg.optionalCord);
+    msg.clear();
+    assertTrue(msg.optionalCord.isEmpty());
+    msg.clear()
+       .optionalCord = "hello2";
+    assertEquals("hello2", msg.optionalCord);
+    msg.clear();
+    assertTrue(msg.optionalCord.isEmpty());
+
+    msg.optionalCord = "bye";
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertTrue(newMsg.optionalCord != null);
+    assertEquals("bye", newMsg.optionalCord);
+  }
+
+  public void testNanoRepeatedInt32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedInt32.length);
+    msg.repeatedInt32 = new int[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedInt32[1]);
+    assertEquals(456, msg.repeatedInt32[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedInt32.length);
+    msg.clear()
+       .repeatedInt32 = new int[] { 456 };
+    assertEquals(1, msg.repeatedInt32.length);
+    assertEquals(456, msg.repeatedInt32[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedInt32.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedInt32 = new int[] { 123 };
+    assertEquals(1, msg.repeatedInt32.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedInt32.length);
+    assertEquals(123, newMsg.repeatedInt32[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedInt32 = new int[] { 123, 456 };
+    assertEquals(2, msg.repeatedInt32.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedInt32.length);
+    assertEquals(123, newMsg.repeatedInt32[0]);
+    assertEquals(456, newMsg.repeatedInt32[1]);
+  }
+
+  public void testNanoRepeatedInt64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedInt64.length);
+    msg.repeatedInt64 = new long[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedInt64[1]);
+    assertEquals(456, msg.repeatedInt64[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedInt64.length);
+    msg.clear()
+       .repeatedInt64 = new long[] { 456 };
+    assertEquals(1, msg.repeatedInt64.length);
+    assertEquals(456, msg.repeatedInt64[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedInt64.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedInt64 = new long[] { 123 };
+    assertEquals(1, msg.repeatedInt64.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedInt64.length);
+    assertEquals(123, newMsg.repeatedInt64[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedInt64 = new long[] { 123, 456 };
+    assertEquals(2, msg.repeatedInt64.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedInt64.length);
+    assertEquals(123, newMsg.repeatedInt64[0]);
+    assertEquals(456, newMsg.repeatedInt64[1]);
+  }
+
+  public void testNanoRepeatedUint32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedUint32.length);
+    msg.repeatedUint32 = new int[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedUint32[1]);
+    assertEquals(456, msg.repeatedUint32[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedUint32.length);
+    msg.clear()
+       .repeatedUint32 = new int[] { 456 };
+    assertEquals(1, msg.repeatedUint32.length);
+    assertEquals(456, msg.repeatedUint32[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedUint32.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedUint32 = new int[] { 123 };
+    assertEquals(1, msg.repeatedUint32.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedUint32.length);
+    assertEquals(123, newMsg.repeatedUint32[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedUint32 = new int[] { 123, 456 };
+    assertEquals(2, msg.repeatedUint32.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedUint32.length);
+    assertEquals(123, newMsg.repeatedUint32[0]);
+    assertEquals(456, newMsg.repeatedUint32[1]);
+  }
+
+  public void testNanoRepeatedUint64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedUint64.length);
+    msg.repeatedUint64 = new long[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedUint64[1]);
+    assertEquals(456, msg.repeatedUint64[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedUint64.length);
+    msg.clear()
+       .repeatedUint64 = new long[] { 456 };
+    assertEquals(1, msg.repeatedUint64.length);
+    assertEquals(456, msg.repeatedUint64[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedUint64.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedUint64 = new long[] { 123 };
+    assertEquals(1, msg.repeatedUint64.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedUint64.length);
+    assertEquals(123, newMsg.repeatedUint64[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedUint64 = new long[] { 123, 456 };
+    assertEquals(2, msg.repeatedUint64.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedUint64.length);
+    assertEquals(123, newMsg.repeatedUint64[0]);
+    assertEquals(456, newMsg.repeatedUint64[1]);
+  }
+
+  public void testNanoRepeatedSint32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedSint32.length);
+    msg.repeatedSint32 = new int[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedSint32[1]);
+    assertEquals(456, msg.repeatedSint32[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedSint32.length);
+    msg.clear()
+       .repeatedSint32 = new int[] { 456 };
+    assertEquals(1, msg.repeatedSint32.length);
+    assertEquals(456, msg.repeatedSint32[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedSint32.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedSint32 = new int[] { 123 };
+    assertEquals(1, msg.repeatedSint32.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedSint32.length);
+    assertEquals(123, newMsg.repeatedSint32[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedSint32 = new int[] { 123, 456 };
+    assertEquals(2, msg.repeatedSint32.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 11);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedSint32.length);
+    assertEquals(123, newMsg.repeatedSint32[0]);
+    assertEquals(456, newMsg.repeatedSint32[1]);
+  }
+
+  public void testNanoRepeatedSint64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedSint64.length);
+    msg.repeatedSint64 = new long[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedSint64[1]);
+    assertEquals(456, msg.repeatedSint64[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedSint64.length);
+    msg.clear()
+       .repeatedSint64 = new long[] { 456 };
+    assertEquals(1, msg.repeatedSint64.length);
+    assertEquals(456, msg.repeatedSint64[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedSint64.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedSint64 = new long[] { 123 };
+    assertEquals(1, msg.repeatedSint64.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedSint64.length);
+    assertEquals(123, newMsg.repeatedSint64[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedSint64 = new long[] { 123, 456 };
+    assertEquals(2, msg.repeatedSint64.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 11);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedSint64.length);
+    assertEquals(123, newMsg.repeatedSint64[0]);
+    assertEquals(456, newMsg.repeatedSint64[1]);
+  }
+
+  public void testNanoRepeatedFixed32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedFixed32.length);
+    msg.repeatedFixed32 = new int[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedFixed32[1]);
+    assertEquals(456, msg.repeatedFixed32[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedFixed32.length);
+    msg.clear()
+       .repeatedFixed32 = new int[] { 456 };
+    assertEquals(1, msg.repeatedFixed32.length);
+    assertEquals(456, msg.repeatedFixed32[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedFixed32.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedFixed32 = new int[] { 123 };
+    assertEquals(1, msg.repeatedFixed32.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedFixed32.length);
+    assertEquals(123, newMsg.repeatedFixed32[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedFixed32 = new int[] { 123, 456 };
+    assertEquals(2, msg.repeatedFixed32.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 15);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedFixed32.length);
+    assertEquals(123, newMsg.repeatedFixed32[0]);
+    assertEquals(456, newMsg.repeatedFixed32[1]);
+  }
+
+  public void testNanoRepeatedFixed64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedFixed64.length);
+    msg.repeatedFixed64 = new long[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedFixed64[1]);
+    assertEquals(456, msg.repeatedFixed64[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedFixed64.length);
+    msg.clear()
+       .repeatedFixed64 = new long[] { 456 };
+    assertEquals(1, msg.repeatedFixed64.length);
+    assertEquals(456, msg.repeatedFixed64[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedFixed64.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedFixed64 = new long[] { 123 };
+    assertEquals(1, msg.repeatedFixed64.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 13);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedFixed64.length);
+    assertEquals(123, newMsg.repeatedFixed64[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedFixed64 = new long[] { 123, 456 };
+    assertEquals(2, msg.repeatedFixed64.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 23);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedFixed64.length);
+    assertEquals(123, newMsg.repeatedFixed64[0]);
+    assertEquals(456, newMsg.repeatedFixed64[1]);
+  }
+
+  public void testNanoRepeatedSfixed32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedSfixed32.length);
+    msg.repeatedSfixed32 = new int[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedSfixed32[1]);
+    assertEquals(456, msg.repeatedSfixed32[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedSfixed32.length);
+    msg.clear()
+       .repeatedSfixed32 = new int[] { 456 };
+    assertEquals(1, msg.repeatedSfixed32.length);
+    assertEquals(456, msg.repeatedSfixed32[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedSfixed32.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedSfixed32 = new int[] { 123 };
+    assertEquals(1, msg.repeatedSfixed32.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedSfixed32.length);
+    assertEquals(123, newMsg.repeatedSfixed32[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedSfixed32 = new int[] { 123, 456 };
+    assertEquals(2, msg.repeatedSfixed32.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 15);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedSfixed32.length);
+    assertEquals(123, newMsg.repeatedSfixed32[0]);
+    assertEquals(456, newMsg.repeatedSfixed32[1]);
+  }
+
+  public void testNanoRepeatedSfixed64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedSfixed64.length);
+    msg.repeatedSfixed64 = new long[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedSfixed64[1]);
+    assertEquals(456, msg.repeatedSfixed64[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedSfixed64.length);
+    msg.clear()
+       .repeatedSfixed64 = new long[] { 456 };
+    assertEquals(1, msg.repeatedSfixed64.length);
+    assertEquals(456, msg.repeatedSfixed64[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedSfixed64.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedSfixed64 = new long[] { 123 };
+    assertEquals(1, msg.repeatedSfixed64.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 13);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedSfixed64.length);
+    assertEquals(123, newMsg.repeatedSfixed64[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedSfixed64 = new long[] { 123, 456 };
+    assertEquals(2, msg.repeatedSfixed64.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 23);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedSfixed64.length);
+    assertEquals(123, newMsg.repeatedSfixed64[0]);
+    assertEquals(456, newMsg.repeatedSfixed64[1]);
+  }
+
+  public void testNanoRepeatedFloat() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedFloat.length);
+    msg.repeatedFloat = new float[] { 123f, 789f, 456f };
+    assertEquals(789f, msg.repeatedFloat[1]);
+    assertEquals(456f, msg.repeatedFloat[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedFloat.length);
+    msg.clear()
+       .repeatedFloat = new float[] { 456f };
+    assertEquals(1, msg.repeatedFloat.length);
+    assertEquals(456f, msg.repeatedFloat[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedFloat.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedFloat = new float[] { 123f };
+    assertEquals(1, msg.repeatedFloat.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedFloat.length);
+    assertEquals(123f, newMsg.repeatedFloat[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedFloat = new float[] { 123f, 456f };
+    assertEquals(2, msg.repeatedFloat.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 15);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedFloat.length);
+    assertEquals(123f, newMsg.repeatedFloat[0]);
+    assertEquals(456f, newMsg.repeatedFloat[1]);
+  }
+
+  public void testNanoRepeatedDouble() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedDouble.length);
+    msg.repeatedDouble = new double[] { 123.0, 789.0, 456.0 };
+    assertEquals(789.0, msg.repeatedDouble[1]);
+    assertEquals(456.0, msg.repeatedDouble[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedDouble.length);
+    msg.clear()
+       .repeatedDouble = new double[] { 456.0 };
+    assertEquals(1, msg.repeatedDouble.length);
+    assertEquals(456.0, msg.repeatedDouble[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedDouble.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedDouble = new double[] { 123.0 };
+    assertEquals(1, msg.repeatedDouble.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 13);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedDouble.length);
+    assertEquals(123.0, newMsg.repeatedDouble[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedDouble = new double[] { 123.0, 456.0 };
+    assertEquals(2, msg.repeatedDouble.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 23);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedDouble.length);
+    assertEquals(123.0, newMsg.repeatedDouble[0]);
+    assertEquals(456.0, newMsg.repeatedDouble[1]);
+  }
+
+  public void testNanoRepeatedBool() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedBool.length);
+    msg.repeatedBool = new boolean[] { false, true, false };
+    assertTrue(msg.repeatedBool[1]);
+    assertFalse(msg.repeatedBool[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedBool.length);
+    msg.clear()
+       .repeatedBool = new boolean[] { true };
+    assertEquals(1, msg.repeatedBool.length);
+    assertTrue(msg.repeatedBool[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedBool.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedBool = new boolean[] { false };
+    assertEquals(1, msg.repeatedBool.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedBool.length);
+    assertFalse(newMsg.repeatedBool[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedBool = new boolean[] { true, false };
+    assertEquals(2, msg.repeatedBool.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedBool.length);
+    assertTrue(newMsg.repeatedBool[0]);
+    assertFalse(newMsg.repeatedBool[1]);
+  }
+
+  public void testNanoRepeatedString() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedString.length);
+    msg.repeatedString = new String[] { "hello", "bye", "boo" };
+    assertEquals("bye", msg.repeatedString[1]);
+    assertEquals("boo", msg.repeatedString[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedString.length);
+    msg.clear()
+       .repeatedString = new String[] { "boo" };
+    assertEquals(1, msg.repeatedString.length);
+    assertEquals("boo", msg.repeatedString[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedString.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedString = new String[] { "" };
+    assertEquals(1, msg.repeatedString.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedString.length);
+    assertTrue(newMsg.repeatedString[0].isEmpty());
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedString = new String[] { "hello", "world" };
+    assertEquals(2, msg.repeatedString.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 19);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedString.length);
+    assertEquals("hello", newMsg.repeatedString[0]);
+    assertEquals("world", newMsg.repeatedString[1]);
+  }
+
+  public void testNanoRepeatedBytes() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedBytes.length);
+    msg.repeatedBytes = new byte[][] {
+        InternalNano.copyFromUtf8("hello"),
+        InternalNano.copyFromUtf8("bye"),
+        InternalNano.copyFromUtf8("boo")
+    };
+    assertEquals("bye", new String(msg.repeatedBytes[1], "UTF-8"));
+    assertEquals("boo", new String(msg.repeatedBytes[2], "UTF-8"));
+    msg.clear();
+    assertEquals(0, msg.repeatedBytes.length);
+    msg.clear()
+       .repeatedBytes = new byte[][] { InternalNano.copyFromUtf8("boo") };
+    assertEquals(1, msg.repeatedBytes.length);
+    assertEquals("boo", new String(msg.repeatedBytes[0], "UTF-8"));
+    msg.clear();
+    assertEquals(0, msg.repeatedBytes.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedBytes = new byte[][] { InternalNano.copyFromUtf8("") };
+    assertEquals(1, msg.repeatedBytes.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedBytes.length);
+    assertTrue(newMsg.repeatedBytes[0].length == 0);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedBytes = new byte[][] {
+      InternalNano.copyFromUtf8("hello"),
+      InternalNano.copyFromUtf8("world")
+    };
+    assertEquals(2, msg.repeatedBytes.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 19);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedBytes.length);
+    assertEquals("hello", new String(newMsg.repeatedBytes[0], "UTF-8"));
+    assertEquals("world", new String(newMsg.repeatedBytes[1], "UTF-8"));
+  }
+
+  public void testNanoRepeatedGroup() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    TestAllTypesNano.RepeatedGroup group0 =
+      new TestAllTypesNano.RepeatedGroup();
+    group0.a = 0;
+    TestAllTypesNano.RepeatedGroup group1 =
+      new TestAllTypesNano.RepeatedGroup();
+    group1.a = 1;
+    TestAllTypesNano.RepeatedGroup group2 =
+      new TestAllTypesNano.RepeatedGroup();
+    group2.a = 2;
+
+    msg.repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group0, group1, group2 };
+    assertEquals(3, msg.repeatedGroup.length);
+    assertEquals(0, msg.repeatedGroup[0].a);
+    assertEquals(1, msg.repeatedGroup[1].a);
+    assertEquals(2, msg.repeatedGroup[2].a);
+    msg.clear();
+    assertEquals(0, msg.repeatedGroup.length);
+    msg.clear()
+       .repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group1 };
+    assertEquals(1, msg.repeatedGroup.length);
+    assertEquals(1, msg.repeatedGroup[0].a);
+    msg.clear();
+    assertEquals(0, msg.repeatedGroup.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group0 };
+    assertEquals(1, msg.repeatedGroup.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedGroup.length);
+    assertEquals(0, newMsg.repeatedGroup[0].a);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedGroup = new TestAllTypesNano.RepeatedGroup[] { group0, group1 };
+    assertEquals(2, msg.repeatedGroup.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 14);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedGroup.length);
+    assertEquals(0, newMsg.repeatedGroup[0].a);
+    assertEquals(1, newMsg.repeatedGroup[1].a);
+  }
+
+  public void testNanoRepeatedNestedMessage() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    TestAllTypesNano.NestedMessage nestedMsg0 =
+      new TestAllTypesNano.NestedMessage();
+    nestedMsg0.bb = 0;
+    TestAllTypesNano.NestedMessage nestedMsg1 =
+      new TestAllTypesNano.NestedMessage();
+    nestedMsg1.bb = 1;
+    TestAllTypesNano.NestedMessage nestedMsg2 =
+      new TestAllTypesNano.NestedMessage();
+    nestedMsg2.bb = 2;
+
+    msg.repeatedNestedMessage =
+        new TestAllTypesNano.NestedMessage[] { nestedMsg0, nestedMsg1, nestedMsg2 };
+    assertEquals(3, msg.repeatedNestedMessage.length);
+    assertEquals(0, msg.repeatedNestedMessage[0].bb);
+    assertEquals(1, msg.repeatedNestedMessage[1].bb);
+    assertEquals(2, msg.repeatedNestedMessage[2].bb);
+    msg.clear();
+    assertEquals(0, msg.repeatedNestedMessage.length);
+    msg.clear()
+       .repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg1 };
+    assertEquals(1, msg.repeatedNestedMessage.length);
+    assertEquals(1, msg.repeatedNestedMessage[0].bb);
+    msg.clear();
+    assertEquals(0, msg.repeatedNestedMessage.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg0 };
+    assertEquals(1, msg.repeatedNestedMessage.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedNestedMessage.length);
+    assertEquals(0, newMsg.repeatedNestedMessage[0].bb);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg0, nestedMsg1 };
+    assertEquals(2, msg.repeatedNestedMessage.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 11);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedNestedMessage.length);
+    assertEquals(0, newMsg.repeatedNestedMessage[0].bb);
+    assertEquals(1, newMsg.repeatedNestedMessage[1].bb);
+  }
+
+  public void testNanoRepeatedForeignMessage() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    NanoOuterClass.ForeignMessageNano foreignMsg0 =
+      new NanoOuterClass.ForeignMessageNano();
+    foreignMsg0.c = 0;
+    NanoOuterClass.ForeignMessageNano foreignMsg1 =
+      new NanoOuterClass.ForeignMessageNano();
+    foreignMsg1.c = 1;
+    NanoOuterClass.ForeignMessageNano foreignMsg2 =
+      new NanoOuterClass.ForeignMessageNano();
+    foreignMsg2.c = 2;
+
+    msg.repeatedForeignMessage =
+        new NanoOuterClass.ForeignMessageNano[] { foreignMsg0, foreignMsg1, foreignMsg2 };
+    assertEquals(3, msg.repeatedForeignMessage.length);
+    assertEquals(0, msg.repeatedForeignMessage[0].c);
+    assertEquals(1, msg.repeatedForeignMessage[1].c);
+    assertEquals(2, msg.repeatedForeignMessage[2].c);
+    msg.clear();
+    assertEquals(0, msg.repeatedForeignMessage.length);
+    msg.clear()
+       .repeatedForeignMessage = new NanoOuterClass.ForeignMessageNano[] { foreignMsg1 };
+    assertEquals(1, msg.repeatedForeignMessage.length);
+    assertEquals(1, msg.repeatedForeignMessage[0].c);
+    msg.clear();
+    assertEquals(0, msg.repeatedForeignMessage.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedForeignMessage = new NanoOuterClass.ForeignMessageNano[] { foreignMsg0 };
+    assertEquals(1, msg.repeatedForeignMessage.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedForeignMessage.length);
+    assertEquals(0, newMsg.repeatedForeignMessage[0].c);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedForeignMessage = new NanoOuterClass.ForeignMessageNano[] { foreignMsg0, foreignMsg1 };
+    assertEquals(2, msg.repeatedForeignMessage.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 11);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedForeignMessage.length);
+    assertEquals(0, newMsg.repeatedForeignMessage[0].c);
+    assertEquals(1, newMsg.repeatedForeignMessage[1].c);
+  }
+
+  public void testNanoRepeatedImportMessage() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    UnittestImportNano.ImportMessageNano foreignMsg0 =
+      new UnittestImportNano.ImportMessageNano();
+    foreignMsg0.d = 0;
+    UnittestImportNano.ImportMessageNano foreignMsg1 =
+      new UnittestImportNano.ImportMessageNano();
+    foreignMsg1.d = 1;
+    UnittestImportNano.ImportMessageNano foreignMsg2 =
+      new UnittestImportNano.ImportMessageNano();
+    foreignMsg2.d = 2;
+
+    msg.repeatedImportMessage =
+        new UnittestImportNano.ImportMessageNano[] { foreignMsg0, foreignMsg1, foreignMsg2 };
+    assertEquals(3, msg.repeatedImportMessage.length);
+    assertEquals(0, msg.repeatedImportMessage[0].d);
+    assertEquals(1, msg.repeatedImportMessage[1].d);
+    assertEquals(2, msg.repeatedImportMessage[2].d);
+    msg.clear();
+    assertEquals(0, msg.repeatedImportMessage.length);
+    msg.clear()
+       .repeatedImportMessage = new UnittestImportNano.ImportMessageNano[] { foreignMsg1 };
+    assertEquals(1, msg.repeatedImportMessage.length);
+    assertEquals(1, msg.repeatedImportMessage[0].d);
+    msg.clear();
+    assertEquals(0, msg.repeatedImportMessage.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedImportMessage = new UnittestImportNano.ImportMessageNano[] { foreignMsg0 };
+    assertEquals(1, msg.repeatedImportMessage.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedImportMessage.length);
+    assertEquals(0, newMsg.repeatedImportMessage[0].d);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedImportMessage = new UnittestImportNano.ImportMessageNano[] { foreignMsg0, foreignMsg1 };
+    assertEquals(2, msg.repeatedImportMessage.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 11);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedImportMessage.length);
+    assertEquals(0, newMsg.repeatedImportMessage[0].d);
+    assertEquals(1, newMsg.repeatedImportMessage[1].d);
+  }
+
+  public void testNanoRepeatedNestedEnum() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.repeatedNestedEnum = new int[] {
+        TestAllTypesNano.FOO,
+        TestAllTypesNano.BAR,
+        TestAllTypesNano.BAZ
+    };
+    assertEquals(3, msg.repeatedNestedEnum.length);
+    assertEquals(TestAllTypesNano.FOO, msg.repeatedNestedEnum[0]);
+    assertEquals(TestAllTypesNano.BAR, msg.repeatedNestedEnum[1]);
+    assertEquals(TestAllTypesNano.BAZ, msg.repeatedNestedEnum[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedNestedEnum.length);
+    msg.clear()
+       .repeatedNestedEnum = new int[] { TestAllTypesNano.BAR };
+    assertEquals(1, msg.repeatedNestedEnum.length);
+    assertEquals(TestAllTypesNano.BAR, msg.repeatedNestedEnum[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedNestedEnum.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedNestedEnum = new int[] { TestAllTypesNano.FOO };
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedNestedEnum.length);
+    assertEquals(TestAllTypesNano.FOO, msg.repeatedNestedEnum[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedNestedEnum = new int[] { TestAllTypesNano.FOO, TestAllTypesNano.BAR };
+    assertEquals(2, msg.repeatedNestedEnum.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedNestedEnum.length);
+    assertEquals(TestAllTypesNano.FOO, msg.repeatedNestedEnum[0]);
+    assertEquals(TestAllTypesNano.BAR, msg.repeatedNestedEnum[1]);
+  }
+
+  public void testNanoRepeatedForeignEnum() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.repeatedForeignEnum = new int[] {
+        NanoOuterClass.FOREIGN_NANO_FOO,
+        NanoOuterClass.FOREIGN_NANO_BAR,
+        NanoOuterClass.FOREIGN_NANO_BAZ
+    };
+    assertEquals(3, msg.repeatedForeignEnum.length);
+    assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.repeatedForeignEnum[0]);
+    assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.repeatedForeignEnum[1]);
+    assertEquals(NanoOuterClass.FOREIGN_NANO_BAZ, msg.repeatedForeignEnum[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedForeignEnum.length);
+    msg.clear()
+       .repeatedForeignEnum = new int[] { NanoOuterClass.FOREIGN_NANO_BAR };
+    assertEquals(1, msg.repeatedForeignEnum.length);
+    assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.repeatedForeignEnum[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedForeignEnum.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedForeignEnum = new int[] { NanoOuterClass.FOREIGN_NANO_FOO };
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedForeignEnum.length);
+    assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.repeatedForeignEnum[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedForeignEnum = new int[] {
+      NanoOuterClass.FOREIGN_NANO_FOO,
+      NanoOuterClass.FOREIGN_NANO_BAR
+    };
+    assertEquals(2, msg.repeatedForeignEnum.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedForeignEnum.length);
+    assertEquals(NanoOuterClass.FOREIGN_NANO_FOO, msg.repeatedForeignEnum[0]);
+    assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.repeatedForeignEnum[1]);
+  }
+
+  public void testNanoRepeatedImportEnum() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.repeatedImportEnum = new int[] {
+        UnittestImportNano.IMPORT_NANO_FOO,
+        UnittestImportNano.IMPORT_NANO_BAR,
+        UnittestImportNano.IMPORT_NANO_BAZ
+    };
+    assertEquals(3, msg.repeatedImportEnum.length);
+    assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.repeatedImportEnum[0]);
+    assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.repeatedImportEnum[1]);
+    assertEquals(UnittestImportNano.IMPORT_NANO_BAZ, msg.repeatedImportEnum[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedImportEnum.length);
+    msg.clear()
+       .repeatedImportEnum = new int[] { UnittestImportNano.IMPORT_NANO_BAR };
+    assertEquals(1, msg.repeatedImportEnum.length);
+    assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.repeatedImportEnum[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedImportEnum.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedImportEnum = new int[] { UnittestImportNano.IMPORT_NANO_FOO };
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedImportEnum.length);
+    assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.repeatedImportEnum[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedImportEnum = new int[] {
+      UnittestImportNano.IMPORT_NANO_FOO,
+      UnittestImportNano.IMPORT_NANO_BAR
+    };
+    assertEquals(2, msg.repeatedImportEnum.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedImportEnum.length);
+    assertEquals(UnittestImportNano.IMPORT_NANO_FOO, msg.repeatedImportEnum[0]);
+    assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.repeatedImportEnum[1]);
+  }
+
+  public void testNanoRepeatedStringPiece() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedStringPiece.length);
+    msg.repeatedStringPiece = new String[] { "hello", "bye", "boo" };
+    assertEquals("bye", msg.repeatedStringPiece[1]);
+    assertEquals("boo", msg.repeatedStringPiece[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedStringPiece.length);
+    msg.clear()
+       .repeatedStringPiece = new String[] { "boo" };
+    assertEquals(1, msg.repeatedStringPiece.length);
+    assertEquals("boo", msg.repeatedStringPiece[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedStringPiece.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedStringPiece = new String[] { "" };
+    assertEquals(1, msg.repeatedStringPiece.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedStringPiece.length);
+    assertTrue(newMsg.repeatedStringPiece[0].isEmpty());
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedStringPiece = new String[] { "hello", "world" };
+    assertEquals(2, msg.repeatedStringPiece.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 19);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedStringPiece.length);
+    assertEquals("hello", newMsg.repeatedStringPiece[0]);
+    assertEquals("world", newMsg.repeatedStringPiece[1]);
+  }
+
+  public void testNanoRepeatedCord() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedCord.length);
+    msg.repeatedCord = new String[] { "hello", "bye", "boo" };
+    assertEquals("bye", msg.repeatedCord[1]);
+    assertEquals("boo", msg.repeatedCord[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedCord.length);
+    msg.clear()
+       .repeatedCord = new String[] { "boo" };
+    assertEquals(1, msg.repeatedCord.length);
+    assertEquals("boo", msg.repeatedCord[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedCord.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedCord = new String[] { "" };
+    assertEquals(1, msg.repeatedCord.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 6);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedCord.length);
+    assertTrue(newMsg.repeatedCord[0].isEmpty());
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedCord = new String[] { "hello", "world" };
+    assertEquals(2, msg.repeatedCord.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 19);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedCord.length);
+    assertEquals("hello", newMsg.repeatedCord[0]);
+    assertEquals("world", newMsg.repeatedCord[1]);
+  }
+
+  public void testNanoRepeatedPackedInt32() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedPackedInt32.length);
+    msg.repeatedPackedInt32 = new int[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedPackedInt32[1]);
+    assertEquals(456, msg.repeatedPackedInt32[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedPackedInt32.length);
+    msg.clear()
+       .repeatedPackedInt32 = new int[] { 456 };
+    assertEquals(1, msg.repeatedPackedInt32.length);
+    assertEquals(456, msg.repeatedPackedInt32[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedPackedInt32.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedPackedInt32 = new int[] { 123 };
+    assertEquals(1, msg.repeatedPackedInt32.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedPackedInt32.length);
+    assertEquals(123, newMsg.repeatedPackedInt32[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedPackedInt32 = new int[] { 123, 456 };
+    assertEquals(2, msg.repeatedPackedInt32.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 9);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedPackedInt32.length);
+    assertEquals(123, newMsg.repeatedPackedInt32[0]);
+    assertEquals(456, newMsg.repeatedPackedInt32[1]);
+  }
+
+  public void testNanoRepeatedPackedSfixed64() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    assertEquals(0, msg.repeatedPackedSfixed64.length);
+    msg.repeatedPackedSfixed64 = new long[] { 123, 789, 456 };
+    assertEquals(789, msg.repeatedPackedSfixed64[1]);
+    assertEquals(456, msg.repeatedPackedSfixed64[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedPackedSfixed64.length);
+    msg.clear()
+       .repeatedPackedSfixed64 = new long[] { 456 };
+    assertEquals(1, msg.repeatedPackedSfixed64.length);
+    assertEquals(456, msg.repeatedPackedSfixed64[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedPackedSfixed64.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedPackedSfixed64 = new long[] { 123 };
+    assertEquals(1, msg.repeatedPackedSfixed64.length);
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 14);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedPackedSfixed64.length);
+    assertEquals(123, newMsg.repeatedPackedSfixed64[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedPackedSfixed64 = new long[] { 123, 456 };
+    assertEquals(2, msg.repeatedPackedSfixed64.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 22);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedPackedSfixed64.length);
+    assertEquals(123, newMsg.repeatedPackedSfixed64[0]);
+    assertEquals(456, newMsg.repeatedPackedSfixed64[1]);
+  }
+
+  public void testNanoRepeatedPackedNestedEnum() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.repeatedPackedNestedEnum = new int[] {
+        TestAllTypesNano.FOO,
+        TestAllTypesNano.BAR,
+        TestAllTypesNano.BAZ
+    };
+    assertEquals(3, msg.repeatedPackedNestedEnum.length);
+    assertEquals(TestAllTypesNano.FOO, msg.repeatedPackedNestedEnum[0]);
+    assertEquals(TestAllTypesNano.BAR, msg.repeatedPackedNestedEnum[1]);
+    assertEquals(TestAllTypesNano.BAZ, msg.repeatedPackedNestedEnum[2]);
+    msg.clear();
+    assertEquals(0, msg.repeatedPackedNestedEnum.length);
+    msg.clear()
+       .repeatedPackedNestedEnum = new int[] { TestAllTypesNano.BAR };
+    assertEquals(1, msg.repeatedPackedNestedEnum.length);
+    assertEquals(TestAllTypesNano.BAR, msg.repeatedPackedNestedEnum[0]);
+    msg.clear();
+    assertEquals(0, msg.repeatedPackedNestedEnum.length);
+
+    // Test 1 entry
+    msg.clear()
+       .repeatedPackedNestedEnum = new int[] { TestAllTypesNano.FOO };
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 7);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(1, newMsg.repeatedPackedNestedEnum.length);
+    assertEquals(TestAllTypesNano.FOO, msg.repeatedPackedNestedEnum[0]);
+
+    // Test 2 entries
+    msg.clear()
+       .repeatedPackedNestedEnum = new int[] { TestAllTypesNano.FOO, TestAllTypesNano.BAR };
+    assertEquals(2, msg.repeatedPackedNestedEnum.length);
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 8);
+    assertEquals(result.length, msgSerializedSize);
+
+    newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(2, newMsg.repeatedPackedNestedEnum.length);
+    assertEquals(TestAllTypesNano.FOO, msg.repeatedPackedNestedEnum[0]);
+    assertEquals(TestAllTypesNano.BAR, msg.repeatedPackedNestedEnum[1]);
+  }
+
+  public void testNanoRepeatedPackedSerializedSize() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.repeatedPackedInt32 = new int[] { 123, 789, 456 };
+    int msgSerializedSize = msg.getSerializedSize();
+    byte [] result = MessageNano.toByteArray(msg);
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 11);
+    assertEquals(result.length, msgSerializedSize);
+    TestAllTypesNano msg2 = new TestAllTypesNano();
+    msg2.repeatedPackedInt32 = new int[] { 123, 789, 456 };
+    byte [] result2 = new byte[msgSerializedSize];
+    MessageNano.toByteArray(msg2, result2, 0, msgSerializedSize);
+
+    // Check equal size and content.
+    assertEquals(msgSerializedSize, msg2.getSerializedSize());
+    assertTrue(Arrays.equals(result, result2));
+  }
+
+  public void testNanoRepeatedInt32ReMerge() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.repeatedInt32 = new int[] { 234 };
+    byte [] result1 = MessageNano.toByteArray(msg);
+
+    msg.clear().optionalInt32 = 789;
+    byte [] result2 = MessageNano.toByteArray(msg);
+
+    msg.clear().repeatedInt32 = new int[] { 123, 456 };
+    byte [] result3 = MessageNano.toByteArray(msg);
+
+    // Concatenate the three serializations and read as one message.
+    byte [] result = new byte[result1.length + result2.length + result3.length];
+    System.arraycopy(result1, 0, result, 0, result1.length);
+    System.arraycopy(result2, 0, result, result1.length, result2.length);
+    System.arraycopy(result3, 0, result, result1.length + result2.length, result3.length);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(789, newMsg.optionalInt32);
+    assertEquals(3, newMsg.repeatedInt32.length);
+    assertEquals(234, newMsg.repeatedInt32[0]);
+    assertEquals(123, newMsg.repeatedInt32[1]);
+    assertEquals(456, newMsg.repeatedInt32[2]);
+  }
+
+  public void testNanoRepeatedNestedEnumReMerge() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.repeatedNestedEnum = new int[] { TestAllTypesNano.FOO };
+    byte [] result1 = MessageNano.toByteArray(msg);
+
+    msg.clear().optionalInt32 = 789;
+    byte [] result2 = MessageNano.toByteArray(msg);
+
+    msg.clear().repeatedNestedEnum = new int[] { TestAllTypesNano.BAR, TestAllTypesNano.FOO };
+    byte [] result3 = MessageNano.toByteArray(msg);
+
+    // Concatenate the three serializations and read as one message.
+    byte [] result = new byte[result1.length + result2.length + result3.length];
+    System.arraycopy(result1, 0, result, 0, result1.length);
+    System.arraycopy(result2, 0, result, result1.length, result2.length);
+    System.arraycopy(result3, 0, result, result1.length + result2.length, result3.length);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(789, newMsg.optionalInt32);
+    assertEquals(3, newMsg.repeatedNestedEnum.length);
+    assertEquals(TestAllTypesNano.FOO, newMsg.repeatedNestedEnum[0]);
+    assertEquals(TestAllTypesNano.BAR, newMsg.repeatedNestedEnum[1]);
+    assertEquals(TestAllTypesNano.FOO, newMsg.repeatedNestedEnum[2]);
+  }
+
+  public void testNanoRepeatedNestedMessageReMerge() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    TestAllTypesNano.NestedMessage nestedMsg0 =
+      new TestAllTypesNano.NestedMessage();
+    nestedMsg0.bb = 0;
+    TestAllTypesNano.NestedMessage nestedMsg1 =
+      new TestAllTypesNano.NestedMessage();
+    nestedMsg1.bb = 1;
+    TestAllTypesNano.NestedMessage nestedMsg2 =
+      new TestAllTypesNano.NestedMessage();
+    nestedMsg2.bb = 2;
+
+    msg.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] { nestedMsg0 };
+    byte [] result1 = MessageNano.toByteArray(msg);
+
+    msg.clear().optionalInt32 = 789;
+    byte [] result2 = MessageNano.toByteArray(msg);
+
+    msg.clear().repeatedNestedMessage =
+        new TestAllTypesNano.NestedMessage[] { nestedMsg1, nestedMsg2 };
+    byte [] result3 = MessageNano.toByteArray(msg);
+
+    // Concatenate the three serializations and read as one message.
+    byte [] result = new byte[result1.length + result2.length + result3.length];
+    System.arraycopy(result1, 0, result, 0, result1.length);
+    System.arraycopy(result2, 0, result, result1.length, result2.length);
+    System.arraycopy(result3, 0, result, result1.length + result2.length, result3.length);
+
+    TestAllTypesNano newMsg = TestAllTypesNano.parseFrom(result);
+    assertEquals(789, newMsg.optionalInt32);
+    assertEquals(3, newMsg.repeatedNestedMessage.length);
+    assertEquals(nestedMsg0.bb, newMsg.repeatedNestedMessage[0].bb);
+    assertEquals(nestedMsg1.bb, newMsg.repeatedNestedMessage[1].bb);
+    assertEquals(nestedMsg2.bb, newMsg.repeatedNestedMessage[2].bb);
+  }
+
+  /**
+   * Tests that invalid enum values from the wire are not accepted.
+   */
+  public void testNanoEnumValidity() throws Exception {
+    final int invalid = 120;
+    final int alsoInvalid = 121;
+
+    EnumValidity.M m = new EnumValidity.M();
+    // Sanity check & baseline of the assertions for the first case below.
+    assertEquals(EnumValidity.E.default_, m.optionalE);
+    assertEquals(EnumValidity.E.BAZ, m.defaultE);
+
+    m.optionalE = invalid;
+    m.defaultE = invalid;
+    // E contains all valid values
+    m.repeatedE = new int[] {EnumValidity.E.FOO, EnumValidity.E.BAR};
+    m.packedE = new int[] {EnumValidity.E.FOO, EnumValidity.E.BAZ};
+    // E2 contains some invalid values
+    m.repeatedE2 = new int[] {invalid, EnumValidity.E.BAR, alsoInvalid};
+    m.packedE2 = new int[] {EnumValidity.E.FOO, invalid, alsoInvalid};
+    // E3 contains all invalid values
+    m.repeatedE3 = new int[] {invalid, invalid};
+    m.packedE3 = new int[] {alsoInvalid, alsoInvalid};
+    byte[] serialized = MessageNano.toByteArray(m);
+    // Sanity check that we do have all data in the byte array.
+    assertEquals(31, serialized.length);
+
+    // Test 1: tests that invalid values aren't included in the deserialized message.
+    EnumValidity.M deserialized = MessageNano.mergeFrom(new EnumValidity.M(), serialized);
+    assertEquals(EnumValidity.E.default_, deserialized.optionalE);
+    assertEquals(EnumValidity.E.BAZ, deserialized.defaultE);
+    assertTrue(Arrays.equals(
+        new int[] {EnumValidity.E.FOO, EnumValidity.E.BAR}, deserialized.repeatedE));
+    assertTrue(Arrays.equals(
+        new int[] {EnumValidity.E.FOO, EnumValidity.E.BAZ}, deserialized.packedE));
+    assertTrue(Arrays.equals(
+        new int[] {EnumValidity.E.BAR}, deserialized.repeatedE2));
+    assertTrue(Arrays.equals(
+        new int[] {EnumValidity.E.FOO}, deserialized.packedE2));
+    assertEquals(0, deserialized.repeatedE3.length);
+    assertEquals(0, deserialized.packedE3.length);
+
+    // Test 2: tests that invalid values do not override previous values in the field, including
+    // arrays, including pre-existing invalid values.
+    deserialized.optionalE = EnumValidity.E.BAR;
+    deserialized.defaultE = alsoInvalid;
+    deserialized.repeatedE = new int[] {EnumValidity.E.BAZ};
+    deserialized.packedE = new int[] {EnumValidity.E.BAZ, alsoInvalid};
+    deserialized.repeatedE2 = new int[] {invalid, alsoInvalid};
+    deserialized.packedE2 = null;
+    deserialized.repeatedE3 = null;
+    deserialized.packedE3 = new int[0];
+    MessageNano.mergeFrom(deserialized, serialized);
+    assertEquals(EnumValidity.E.BAR, deserialized.optionalE);
+    assertEquals(alsoInvalid, deserialized.defaultE);
+    assertTrue(Arrays.equals(
+        new int[] {EnumValidity.E.BAZ, /* + */ EnumValidity.E.FOO, EnumValidity.E.BAR},
+        deserialized.repeatedE));
+    assertTrue(Arrays.equals(
+        new int[] {EnumValidity.E.BAZ, alsoInvalid, /* + */ EnumValidity.E.FOO, EnumValidity.E.BAZ},
+        deserialized.packedE));
+    assertTrue(Arrays.equals(
+        new int[] {invalid, alsoInvalid, /* + */ EnumValidity.E.BAR},
+        deserialized.repeatedE2));
+    assertTrue(Arrays.equals(
+        new int[] {/* <null> + */ EnumValidity.E.FOO},
+        deserialized.packedE2));
+    assertNull(deserialized.repeatedE3); // null + all invalid == null
+    assertEquals(0, deserialized.packedE3.length); // empty + all invalid == empty
+
+    // Test 3: reading by alternative forms
+    EnumValidity.Alt alt = MessageNano.mergeFrom(new EnumValidity.Alt(), serialized);
+    assertEquals(EnumValidity.E.BAR, // last valid value in m.repeatedE2
+        alt.repeatedE2AsOptional);
+    assertTrue(Arrays.equals(new int[] {EnumValidity.E.FOO}, alt.packedE2AsNonPacked));
+    assertEquals(0, alt.nonPackedE3AsPacked.length);
+  }
+
+  /**
+   * Tests the same as {@link #testNanoEnumValidity()} with accessor style. Repeated fields are
+   * not re-tested here because they are not affected by the accessor style.
+   */
+  public void testNanoEnumValidityAccessors() throws Exception {
+    final int invalid = 120;
+    final int alsoInvalid = 121;
+
+    EnumValidityAccessors.M m = new EnumValidityAccessors.M();
+    // Sanity check & baseline of the assertions for the first case below.
+    assertEquals(EnumValidityAccessors.default_, m.getOptionalE());
+    assertEquals(EnumValidityAccessors.BAZ, m.getDefaultE());
+
+    m.setOptionalE(invalid);
+    m.setDefaultE(invalid);
+    // Set repeatedE2 for Alt.repeatedE2AsOptional
+    m.repeatedE2 = new int[] {invalid, EnumValidityAccessors.BAR, alsoInvalid};
+    byte[] serialized = MessageNano.toByteArray(m);
+    // Sanity check that we do have all data in the byte array.
+    assertEquals(10, serialized.length);
+
+    // Test 1: tests that invalid values aren't included in the deserialized message.
+    EnumValidityAccessors.M deserialized =
+        MessageNano.mergeFrom(new EnumValidityAccessors.M(), serialized);
+    assertEquals(EnumValidityAccessors.default_, deserialized.getOptionalE());
+    assertEquals(EnumValidityAccessors.BAZ, deserialized.getDefaultE());
+
+    // Test 2: tests that invalid values do not override previous values in the field, including
+    // pre-existing invalid values.
+    deserialized.setOptionalE(EnumValidityAccessors.BAR);
+    deserialized.setDefaultE(alsoInvalid);
+    MessageNano.mergeFrom(deserialized, serialized);
+    assertEquals(EnumValidityAccessors.BAR, deserialized.getOptionalE());
+    assertEquals(alsoInvalid, deserialized.getDefaultE());
+
+    // Test 3: reading by alternative forms
+    EnumValidityAccessors.Alt alt =
+        MessageNano.mergeFrom(new EnumValidityAccessors.Alt(), serialized);
+    assertEquals(EnumValidityAccessors.BAR, // last valid value in m.repeatedE2
+        alt.getRepeatedE2AsOptional());
+  }
+
+  /**
+   * Tests that code generation correctly wraps a single message into its outer
+   * class. The class {@code SingleMessageNano} is imported from the outer
+   * class {@code UnittestSingleNano}, whose name is implicit. Any error would
+   * cause this method to fail compilation.
+   */
+  public void testNanoSingle() throws Exception {
+    SingleMessageNano msg = new SingleMessageNano();
+    assertNotNull(msg);
+  }
+
+  /**
+   * Tests that code generation correctly skips generating the outer class if
+   * unnecessary, letting a file-scope entity have the same name. The class
+   * {@code MultipleNameClashNano} shares the same name with the file's outer
+   * class defined explicitly, but the file contains no other entities and has
+   * java_multiple_files set. Any error would cause this method to fail
+   * compilation.
+   */
+  public void testNanoMultipleNameClash() throws Exception {
+    MultipleNameClashNano msg = new MultipleNameClashNano();
+    msg.field = 0;
+  }
+
+  /**
+   * Tests that code generation correctly handles enums in different scopes in
+   * a source file with the option java_multiple_files set to true. Any error
+   * would cause this method to fail compilation.
+   */
+  public void testNanoMultipleEnumScoping() throws Exception {
+    FileScopeEnumRefNano msg1 = new FileScopeEnumRefNano();
+    msg1.enumField = UnittestMultipleNano.ONE;
+    MessageScopeEnumRefNano msg2 = new MessageScopeEnumRefNano();
+    msg2.enumField = MessageScopeEnumRefNano.TWO;
+  }
+
+  /**
+   * Tests that code generation with mixed values of the java_multiple_files
+   * options between the main source file and the imported source files would
+   * generate correct references. Any error would cause this method to fail
+   * compilation.
+   */
+  public void testNanoMultipleImportingNonMultiple() throws Exception {
+    UnittestImportNano.ImportMessageNano importMsg = new UnittestImportNano.ImportMessageNano();
+    MultipleImportingNonMultipleNano1 nano1 = new MultipleImportingNonMultipleNano1();
+    nano1.field = importMsg;
+    MultipleImportingNonMultipleNano2 nano2 = new MultipleImportingNonMultipleNano2();
+    nano2.nano1 = nano1;
+  }
+
+  public void testNanoDefaults() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    for (int i = 0; i < 2; i++) {
+      assertEquals(41, msg.defaultInt32);
+      assertEquals(42, msg.defaultInt64);
+      assertEquals(43, msg.defaultUint32);
+      assertEquals(44, msg.defaultUint64);
+      assertEquals(-45, msg.defaultSint32);
+      assertEquals(46, msg.defaultSint64);
+      assertEquals(47, msg.defaultFixed32);
+      assertEquals(48, msg.defaultFixed64);
+      assertEquals(49, msg.defaultSfixed32);
+      assertEquals(-50, msg.defaultSfixed64);
+      assertTrue(51.5f == msg.defaultFloat);
+      assertTrue(52.0e3 == msg.defaultDouble);
+      assertEquals(true, msg.defaultBool);
+      assertEquals("hello", msg.defaultString);
+      assertEquals("world", new String(msg.defaultBytes, "UTF-8"));
+      assertEquals("dünya", msg.defaultStringNonascii);
+      assertEquals("dünyab", new String(msg.defaultBytesNonascii, "UTF-8"));
+      assertEquals(TestAllTypesNano.BAR, msg.defaultNestedEnum);
+      assertEquals(NanoOuterClass.FOREIGN_NANO_BAR, msg.defaultForeignEnum);
+      assertEquals(UnittestImportNano.IMPORT_NANO_BAR, msg.defaultImportEnum);
+      assertEquals(Float.POSITIVE_INFINITY, msg.defaultFloatInf);
+      assertEquals(Float.NEGATIVE_INFINITY, msg.defaultFloatNegInf);
+      assertEquals(Float.NaN, msg.defaultFloatNan);
+      assertEquals(Double.POSITIVE_INFINITY, msg.defaultDoubleInf);
+      assertEquals(Double.NEGATIVE_INFINITY, msg.defaultDoubleNegInf);
+      assertEquals(Double.NaN, msg.defaultDoubleNan);
+
+      // Default values are not output, except for required fields.
+      byte [] result = MessageNano.toByteArray(msg);
+      int msgSerializedSize = msg.getSerializedSize();
+      //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+      assertTrue(msgSerializedSize == 3);
+      assertEquals(result.length, msgSerializedSize);
+      msg.clear();
+    }
+  }
+
+  public void testDifferentStringLengthsNano() throws Exception {
+    // Test string serialization roundtrip using strings of the following lengths,
+    // with ASCII and Unicode characters requiring different UTF-8 byte counts per
+    // char, hence causing the length delimiter varint to sometimes require more
+    // bytes for the Unicode strings than the ASCII string of the same length.
+    int[] lengths = new int[] {
+            0,
+            1,
+            (1 << 4) - 1,  // 1 byte for ASCII and Unicode
+            (1 << 7) - 1,  // 1 byte for ASCII, 2 bytes for Unicode
+            (1 << 11) - 1, // 2 bytes for ASCII and Unicode
+            (1 << 14) - 1, // 2 bytes for ASCII, 3 bytes for Unicode
+            (1 << 17) - 1, // 3 bytes for ASCII and Unicode
+    };
+    for (int i : lengths) {
+      testEncodingOfString('q', i);      // 1 byte per char
+      testEncodingOfString('\u07FF', i); // 2 bytes per char
+      testEncodingOfString('\u0981', i); // 3 bytes per char
+    }
+  }
+
+  /** Regression test for https://github.com/google/protobuf/issues/292 */
+  public void testCorrectExceptionThrowWhenEncodingStringsWithoutEnoughSpace() throws Exception {
+    String testCase = "Foooooooo";
+    assertEquals(CodedOutputByteBufferNano.computeRawVarint32Size(testCase.length()),
+            CodedOutputByteBufferNano.computeRawVarint32Size(testCase.length() * 3));
+    assertEquals(11, CodedOutputByteBufferNano.computeStringSize(1, testCase));
+    // Tag is one byte, varint describing string length is 1 byte, string length is 9 bytes.
+    // An array of size 1 will cause a failure when trying to write the varint.
+    for (int i = 0; i < 11; i++) {
+      CodedOutputByteBufferNano bufferNano = CodedOutputByteBufferNano.newInstance(new byte[i]);
+      try {
+        bufferNano.writeString(1, testCase);
+        fail("Should have thrown an out of space exception");
+      } catch (CodedOutputByteBufferNano.OutOfSpaceException expected) {}
+    }
+  }
+
+  private void testEncodingOfString(char c, int length) throws InvalidProtocolBufferNanoException {
+    TestAllTypesNano testAllTypesNano = new TestAllTypesNano();
+    final String fullString = fullString(c, length);
+    testAllTypesNano.optionalString = fullString;
+    final TestAllTypesNano resultNano = new TestAllTypesNano();
+    MessageNano.mergeFrom(resultNano, MessageNano.toByteArray(testAllTypesNano));
+    assertEquals(fullString, resultNano.optionalString);
+  }
+
+  private String fullString(char c, int length) {
+    char[] result = new char[length];
+    Arrays.fill(result, c);
+    return new String(result);
+  }
+
+  public void testNanoWithHasParseFrom() throws Exception {
+    TestAllTypesNanoHas msg = null;
+    // Test false on creation, after clear and upon empty parse.
+    for (int i = 0; i < 3; i++) {
+      if (i == 0) {
+        msg = new TestAllTypesNanoHas();
+      } else if (i == 1) {
+        msg.clear();
+      } else if (i == 2) {
+        msg = TestAllTypesNanoHas.parseFrom(new byte[0]);
+      }
+      assertFalse(msg.hasOptionalInt32);
+      assertFalse(msg.hasOptionalString);
+      assertFalse(msg.hasOptionalBytes);
+      assertFalse(msg.hasOptionalNestedEnum);
+      assertFalse(msg.hasDefaultInt32);
+      assertFalse(msg.hasDefaultString);
+      assertFalse(msg.hasDefaultBytes);
+      assertFalse(msg.hasDefaultFloatNan);
+      assertFalse(msg.hasDefaultNestedEnum);
+      assertFalse(msg.hasId);
+      assertFalse(msg.hasRequiredEnum);
+      msg.optionalInt32 = 123;
+      msg.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
+      msg.optionalNestedMessage.bb = 2;
+      msg.optionalNestedEnum = TestAllTypesNano.BAZ;
+    }
+
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 10);
+    assertEquals(result.length, msgSerializedSize);
+
+    // Has fields true upon parse.
+    TestAllTypesNanoHas newMsg = TestAllTypesNanoHas.parseFrom(result);
+    assertEquals(123, newMsg.optionalInt32);
+    assertTrue(newMsg.hasOptionalInt32);
+    assertEquals(2, newMsg.optionalNestedMessage.bb);
+    assertTrue(newMsg.optionalNestedMessage.hasBb);
+    assertEquals(TestAllTypesNanoHas.BAZ, newMsg.optionalNestedEnum);
+    assertTrue(newMsg.hasOptionalNestedEnum);
+  }
+
+  public void testNanoWithHasSerialize() throws Exception {
+    TestAllTypesNanoHas msg = new TestAllTypesNanoHas();
+    msg.hasOptionalInt32 = true;
+    msg.hasOptionalString = true;
+    msg.hasOptionalBytes = true;
+    msg.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
+    msg.optionalNestedMessage.hasBb = true;
+    msg.hasOptionalNestedEnum = true;
+    msg.hasDefaultInt32 = true;
+    msg.hasDefaultString = true;
+    msg.hasDefaultBytes = true;
+    msg.hasDefaultFloatNan = true;
+    msg.hasDefaultNestedEnum = true;
+    msg.hasId = true;
+    msg.hasRequiredEnum = true;
+
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    assertEquals(result.length, msgSerializedSize);
+
+    // Now deserialize and find that all fields are set and equal to their defaults.
+    TestAllTypesNanoHas newMsg = TestAllTypesNanoHas.parseFrom(result);
+    assertTrue(newMsg.hasOptionalInt32);
+    assertTrue(newMsg.hasOptionalString);
+    assertTrue(newMsg.hasOptionalBytes);
+    assertTrue(newMsg.optionalNestedMessage.hasBb);
+    assertTrue(newMsg.hasOptionalNestedEnum);
+    assertTrue(newMsg.hasDefaultInt32);
+    assertTrue(newMsg.hasDefaultString);
+    assertTrue(newMsg.hasDefaultBytes);
+    assertTrue(newMsg.hasDefaultFloatNan);
+    assertTrue(newMsg.hasDefaultNestedEnum);
+    assertTrue(newMsg.hasId);
+    assertTrue(newMsg.hasRequiredEnum);
+    assertEquals(0, newMsg.optionalInt32);
+    assertEquals(0, newMsg.optionalString.length());
+    assertEquals(0, newMsg.optionalBytes.length);
+    assertEquals(0, newMsg.optionalNestedMessage.bb);
+    assertEquals(TestAllTypesNanoHas.FOO, newMsg.optionalNestedEnum);
+    assertEquals(41, newMsg.defaultInt32);
+    assertEquals("hello", newMsg.defaultString);
+    assertEquals("world", new String(newMsg.defaultBytes, "UTF-8"));
+    assertEquals(TestAllTypesNanoHas.BAR, newMsg.defaultNestedEnum);
+    assertEquals(Float.NaN, newMsg.defaultFloatNan);
+    assertEquals(0, newMsg.id);
+    assertEquals(TestAllTypesNanoHas.FOO, newMsg.requiredEnum);
+  }
+
+  public void testNanoWithAccessorsBasic() throws Exception {
+    TestNanoAccessors msg = new TestNanoAccessors();
+
+    // Makes sure required, repeated, and message fields are still public
+    msg.id = 3;
+    msg.repeatedBytes = new byte[2][3];
+    msg.optionalNestedMessage = null;
+
+    // Test accessors
+    assertEquals(0, msg.getOptionalInt32());
+    assertFalse(msg.hasOptionalInt32());
+    msg.setOptionalInt32(135);
+    assertEquals(135, msg.getOptionalInt32());
+    assertTrue(msg.hasOptionalInt32());
+    msg.clearOptionalInt32();
+    assertFalse(msg.hasOptionalInt32());
+    msg.setOptionalInt32(0); // default value
+    assertTrue(msg.hasOptionalInt32());
+
+    // Test NPE
+    try {
+      msg.setOptionalBytes(null);
+      fail();
+    } catch (NullPointerException expected) {}
+    try {
+      msg.setOptionalString(null);
+      fail();
+    } catch (NullPointerException expected) {}
+
+    // Test has bit on bytes field with defaults and clear() re-clones the default array
+    assertFalse(msg.hasDefaultBytes());
+    byte[] defaultBytes = msg.getDefaultBytes();
+    msg.setDefaultBytes(defaultBytes);
+    assertTrue(msg.hasDefaultBytes());
+    msg.clearDefaultBytes();
+    assertFalse(msg.hasDefaultBytes());
+    defaultBytes[0]++; // modify original array
+    assertFalse(Arrays.equals(defaultBytes, msg.getDefaultBytes()));
+
+    // Test has bits that require additional bit fields
+    assertFalse(msg.hasBitFieldCheck());
+    msg.setBitFieldCheck(0);
+    assertTrue(msg.hasBitFieldCheck());
+    assertFalse(msg.hasBeforeBitFieldCheck()); // checks bit field does not leak
+    assertFalse(msg.hasAfterBitFieldCheck());
+
+    // Test clear() clears has bits
+    msg.setOptionalString("hi");
+    msg.setDefaultString("there");
+    msg.clear();
+    assertFalse(msg.hasOptionalString());
+    assertFalse(msg.hasDefaultString());
+    assertFalse(msg.hasBitFieldCheck());
+
+    // Test set() and clear() returns itself (compiles = success)
+    msg.clear()
+        .setOptionalInt32(3)
+        .clearDefaultBytes()
+        .setOptionalString("4");
+  }
+
+  public void testNanoWithAccessorsParseFrom() throws Exception {
+    TestNanoAccessors msg = null;
+    // Test false on creation, after clear and upon empty parse.
+    for (int i = 0; i < 3; i++) {
+      if (i == 0) {
+        msg = new TestNanoAccessors();
+      } else if (i == 1) {
+        msg.clear();
+      } else if (i == 2) {
+        msg = TestNanoAccessors.parseFrom(new byte[0]);
+      }
+      assertFalse(msg.hasOptionalInt32());
+      assertFalse(msg.hasOptionalString());
+      assertFalse(msg.hasOptionalBytes());
+      assertFalse(msg.hasOptionalNestedEnum());
+      assertFalse(msg.hasDefaultInt32());
+      assertFalse(msg.hasDefaultString());
+      assertFalse(msg.hasDefaultBytes());
+      assertFalse(msg.hasDefaultFloatNan());
+      assertFalse(msg.hasDefaultNestedEnum());
+      msg.optionalNestedMessage = new TestNanoAccessors.NestedMessage();
+      msg.optionalNestedMessage.setBb(2);
+      msg.setOptionalNestedEnum(TestNanoAccessors.BAZ);
+      msg.setDefaultInt32(msg.getDefaultInt32());
+    }
+
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    //System.out.printf("mss=%d result.length=%d\n", msgSerializedSize, result.length);
+    assertTrue(msgSerializedSize == 14);
+    assertEquals(result.length, msgSerializedSize);
+
+    // Has fields true upon parse.
+    TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(result);
+    assertEquals(2, newMsg.optionalNestedMessage.getBb());
+    assertTrue(newMsg.optionalNestedMessage.hasBb());
+    assertEquals(TestNanoAccessors.BAZ, newMsg.getOptionalNestedEnum());
+    assertTrue(newMsg.hasOptionalNestedEnum());
+
+    // Has field true on fields with explicit default values from wire.
+    assertTrue(newMsg.hasDefaultInt32());
+    assertEquals(41, newMsg.getDefaultInt32());
+  }
+
+  public void testNanoWithAccessorsPublicFieldTypes() throws Exception {
+    TestNanoAccessors msg = new TestNanoAccessors();
+    assertNull(msg.optionalNestedMessage);
+    assertEquals(0, msg.id);
+    assertEquals(0, msg.repeatedNestedEnum.length);
+
+    TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(MessageNano.toByteArray(msg));
+    assertNull(newMsg.optionalNestedMessage);
+    assertEquals(0, newMsg.id);
+    assertEquals(0, newMsg.repeatedNestedEnum.length);
+
+    TestNanoAccessors.NestedMessage nestedMessage = new TestNanoAccessors.NestedMessage();
+    nestedMessage.setBb(5);
+    newMsg.optionalNestedMessage = nestedMessage;
+    newMsg.id = -1;
+    newMsg.repeatedNestedEnum = new int[] { TestAllTypesNano.FOO };
+
+    TestNanoAccessors newMsg2 = TestNanoAccessors.parseFrom(MessageNano.toByteArray(newMsg));
+    assertEquals(nestedMessage.getBb(), newMsg2.optionalNestedMessage.getBb());
+    assertEquals(-1, newMsg2.id);
+    assertEquals(TestAllTypesNano.FOO, newMsg2.repeatedNestedEnum[0]);
+
+    newMsg2.optionalNestedMessage = null;
+    newMsg2.id = 0;
+    newMsg2.repeatedNestedEnum = null;
+
+    TestNanoAccessors newMsg3 = TestNanoAccessors.parseFrom(MessageNano.toByteArray(newMsg2));
+    assertNull(newMsg3.optionalNestedMessage);
+    assertEquals(0, newMsg3.id);
+    assertEquals(0, newMsg3.repeatedNestedEnum.length);
+  }
+
+  public void testNanoWithAccessorsSerialize() throws Exception {
+    TestNanoAccessors msg = new TestNanoAccessors();
+    msg.setOptionalInt32(msg.getOptionalInt32());
+    msg.setOptionalString(msg.getOptionalString());
+    msg.setOptionalBytes(msg.getOptionalBytes());
+    TestNanoAccessors.NestedMessage nestedMessage = new TestNanoAccessors.NestedMessage();
+    nestedMessage.setBb(nestedMessage.getBb());
+    msg.optionalNestedMessage = nestedMessage;
+    msg.setOptionalNestedEnum(msg.getOptionalNestedEnum());
+    msg.setDefaultInt32(msg.getDefaultInt32());
+    msg.setDefaultString(msg.getDefaultString());
+    msg.setDefaultBytes(msg.getDefaultBytes());
+    msg.setDefaultFloatNan(msg.getDefaultFloatNan());
+    msg.setDefaultNestedEnum(msg.getDefaultNestedEnum());
+
+    byte [] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    assertEquals(result.length, msgSerializedSize);
+
+    // Now deserialize and find that all fields are set and equal to their defaults.
+    TestNanoAccessors newMsg = TestNanoAccessors.parseFrom(result);
+    assertTrue(newMsg.hasOptionalInt32());
+    assertTrue(newMsg.hasOptionalString());
+    assertTrue(newMsg.hasOptionalBytes());
+    assertTrue(newMsg.optionalNestedMessage.hasBb());
+    assertTrue(newMsg.hasOptionalNestedEnum());
+    assertTrue(newMsg.hasDefaultInt32());
+    assertTrue(newMsg.hasDefaultString());
+    assertTrue(newMsg.hasDefaultBytes());
+    assertTrue(newMsg.hasDefaultFloatNan());
+    assertTrue(newMsg.hasDefaultNestedEnum());
+    assertEquals(0, newMsg.getOptionalInt32());
+    assertEquals(0, newMsg.getOptionalString().length());
+    assertEquals(0, newMsg.getOptionalBytes().length);
+    assertEquals(0, newMsg.optionalNestedMessage.getBb());
+    assertEquals(TestNanoAccessors.FOO, newMsg.getOptionalNestedEnum());
+    assertEquals(41, newMsg.getDefaultInt32());
+    assertEquals("hello", newMsg.getDefaultString());
+    assertEquals("world", new String(newMsg.getDefaultBytes(), "UTF-8"));
+    assertEquals(TestNanoAccessors.BAR, newMsg.getDefaultNestedEnum());
+    assertEquals(Float.NaN, newMsg.getDefaultFloatNan());
+    assertEquals(0, newMsg.id);
+  }
+
+  public void testNanoJavaEnumStyle() throws Exception {
+    EnumClassNanos.EnumClassNano msg = new EnumClassNanos.EnumClassNano();
+    assertEquals(EnumClassNanos.FileScopeEnum.ONE, msg.one);
+    assertEquals(EnumClassNanos.EnumClassNano.MessageScopeEnum.TWO, msg.two);
+
+    EnumClassNanoMultiple msg2 = new EnumClassNanoMultiple();
+    assertEquals(FileScopeEnumMultiple.THREE, msg2.three);
+    assertEquals(EnumClassNanoMultiple.MessageScopeEnumMultiple.FOUR, msg2.four);
+  }
+
+  /**
+   * Tests that fields with a default value of NaN are not serialized when
+   * set to NaN. This is a special case as NaN != NaN, so normal equality
+   * checks don't work.
+   */
+  public void testNanoNotANumberDefaults() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.defaultDoubleNan = 0;
+    msg.defaultFloatNan = 0;
+    byte[] result = MessageNano.toByteArray(msg);
+    int msgSerializedSize = msg.getSerializedSize();
+    assertTrue(result.length == msgSerializedSize);
+    assertTrue(msgSerializedSize > 3);
+
+    msg.defaultDoubleNan = Double.NaN;
+    msg.defaultFloatNan = Float.NaN;
+    result = MessageNano.toByteArray(msg);
+    msgSerializedSize = msg.getSerializedSize();
+    assertEquals(3, result.length);
+    assertEquals(3, msgSerializedSize);
+  }
+
+  /**
+   * Test that a bug in skipRawBytes() has been fixed:  if the skip skips
+   * exactly up to a limit, this should not break things.
+   */
+  public void testSkipRawBytesBug() throws Exception {
+    byte[] rawBytes = new byte[] { 1, 2 };
+    CodedInputByteBufferNano input = CodedInputByteBufferNano.newInstance(rawBytes);
+
+    int limit = input.pushLimit(1);
+    input.skipRawBytes(1);
+    input.popLimit(limit);
+    assertEquals(2, input.readRawByte());
+  }
+
+  /**
+   * Test that a bug in skipRawBytes() has been fixed:  if the skip skips
+   * past the end of a buffer with a limit that has been set past the end of
+   * that buffer, this should not break things.
+   */
+  public void testSkipRawBytesPastEndOfBufferWithLimit() throws Exception {
+    byte[] rawBytes = new byte[] { 1, 2, 3, 4, 5 };
+    CodedInputByteBufferNano input = CodedInputByteBufferNano.newInstance(rawBytes);
+
+    int limit = input.pushLimit(4);
+    // In order to expose the bug we need to read at least one byte to prime the
+    // buffer inside the CodedInputStream.
+    assertEquals(1, input.readRawByte());
+    // Skip to the end of the limit.
+    input.skipRawBytes(3);
+    assertTrue(input.isAtEnd());
+    input.popLimit(limit);
+    assertEquals(5, input.readRawByte());
+  }
+
+  // Test a smattering of various proto types for printing
+  public void testMessageNanoPrinter() {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.optionalInt32 = 14;
+    msg.optionalFloat = 42.3f;
+    msg.optionalString = "String \"with' both quotes";
+    msg.optionalBytes = new byte[] {'"', '\0', 1, 8};
+    msg.optionalGroup = new TestAllTypesNano.OptionalGroup();
+    msg.optionalGroup.a = 15;
+    msg.repeatedInt64 = new long[2];
+    msg.repeatedInt64[0] = 1L;
+    msg.repeatedInt64[1] = -1L;
+    msg.repeatedBytes = new byte[2][];
+    msg.repeatedBytes[1] = new byte[] {'h', 'e', 'l', 'l', 'o'};
+    msg.repeatedGroup = new TestAllTypesNano.RepeatedGroup[2];
+    msg.repeatedGroup[0] = new TestAllTypesNano.RepeatedGroup();
+    msg.repeatedGroup[0].a = -27;
+    msg.repeatedGroup[1] = new TestAllTypesNano.RepeatedGroup();
+    msg.repeatedGroup[1].a = -72;
+    msg.optionalNestedMessage = new TestAllTypesNano.NestedMessage();
+    msg.optionalNestedMessage.bb = 7;
+    msg.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[2];
+    msg.repeatedNestedMessage[0] = new TestAllTypesNano.NestedMessage();
+    msg.repeatedNestedMessage[0].bb = 77;
+    msg.repeatedNestedMessage[1] = new TestAllTypesNano.NestedMessage();
+    msg.repeatedNestedMessage[1].bb = 88;
+    msg.optionalNestedEnum = TestAllTypesNano.BAZ;
+    msg.repeatedNestedEnum = new int[2];
+    msg.repeatedNestedEnum[0] = TestAllTypesNano.BAR;
+    msg.repeatedNestedEnum[1] = TestAllTypesNano.FOO;
+    msg.repeatedStringPiece = new String[] {null, "world"};
+
+    String protoPrint = msg.toString();
+    assertTrue(protoPrint.contains("optional_int32: 14"));
+    assertTrue(protoPrint.contains("optional_float: 42.3"));
+    assertTrue(protoPrint.contains("optional_double: 0.0"));
+    assertTrue(protoPrint.contains("optional_string: \"String \\u0022with\\u0027 both quotes\""));
+    assertTrue(protoPrint.contains("optional_bytes: \"\\\"\\000\\001\\010\""));
+    assertTrue(protoPrint.contains("optional_group <\n  a: 15\n>"));
+
+    assertTrue(protoPrint.contains("repeated_int64: 1\nrepeated_int64: -1"));
+    assertFalse(protoPrint.contains("repeated_bytes: \"\"")); // null should be dropped
+    assertTrue(protoPrint.contains("repeated_bytes: \"hello\""));
+    assertTrue(protoPrint.contains("repeated_group <\n  a: -27\n>\n"
+            + "repeated_group <\n  a: -72\n>"));
+    assertTrue(protoPrint.contains("optional_nested_message <\n  bb: 7\n>"));
+    assertTrue(protoPrint.contains("repeated_nested_message <\n  bb: 77\n>\n"
+            + "repeated_nested_message <\n  bb: 88\n>"));
+    assertTrue(protoPrint.contains("optional_nested_enum: 3"));
+    assertTrue(protoPrint.contains("repeated_nested_enum: 2\nrepeated_nested_enum: 1"));
+    assertTrue(protoPrint.contains("default_int32: 41"));
+    assertTrue(protoPrint.contains("default_string: \"hello\""));
+    assertFalse(protoPrint.contains("repeated_string_piece: \"\""));  // null should be dropped
+    assertTrue(protoPrint.contains("repeated_string_piece: \"world\""));
+  }
+
+  public void testMessageNanoPrinterAccessors() throws Exception {
+    TestNanoAccessors msg = new TestNanoAccessors();
+    msg.setOptionalInt32(13);
+    msg.setOptionalString("foo");
+    msg.setOptionalBytes(new byte[] {'"', '\0', 1, 8});
+    msg.optionalNestedMessage = new TestNanoAccessors.NestedMessage();
+    msg.optionalNestedMessage.setBb(7);
+    msg.setOptionalNestedEnum(TestNanoAccessors.BAZ);
+    msg.repeatedInt32 = new int[] { 1, -1 };
+    msg.repeatedString = new String[] { "Hello", "world" };
+    msg.repeatedBytes = new byte[2][];
+    msg.repeatedBytes[1] = new byte[] {'h', 'e', 'l', 'l', 'o'};
+    msg.repeatedNestedMessage = new TestNanoAccessors.NestedMessage[2];
+    msg.repeatedNestedMessage[0] = new TestNanoAccessors.NestedMessage();
+    msg.repeatedNestedMessage[0].setBb(5);
+    msg.repeatedNestedMessage[1] = new TestNanoAccessors.NestedMessage();
+    msg.repeatedNestedMessage[1].setBb(6);
+    msg.repeatedNestedEnum = new int[] { TestNanoAccessors.FOO, TestNanoAccessors.BAR };
+    msg.id = 33;
+
+    String protoPrint = msg.toString();
+    assertTrue(protoPrint.contains("optional_int32: 13"));
+    assertTrue(protoPrint.contains("optional_string: \"foo\""));
+    assertTrue(protoPrint.contains("optional_bytes: \"\\\"\\000\\001\\010\""));
+    assertTrue(protoPrint.contains("optional_nested_message <\n  bb: 7\n>"));
+    assertTrue(protoPrint.contains("optional_nested_enum: 3"));
+    assertTrue(protoPrint.contains("repeated_int32: 1\nrepeated_int32: -1"));
+    assertTrue(protoPrint.contains("repeated_string: \"Hello\"\nrepeated_string: \"world\""));
+    assertFalse(protoPrint.contains("repeated_bytes: \"\"")); // null should be dropped
+    assertTrue(protoPrint.contains("repeated_bytes: \"hello\""));
+    assertTrue(protoPrint.contains("repeated_nested_message <\n  bb: 5\n>\n"
+            + "repeated_nested_message <\n  bb: 6\n>"));
+    assertTrue(protoPrint.contains("repeated_nested_enum: 1\nrepeated_nested_enum: 2"));
+    assertTrue(protoPrint.contains("id: 33"));
+  }
+
+  public void testExtensions() throws Exception {
+    Extensions.ExtendableMessage message = new Extensions.ExtendableMessage();
+    message.field = 5;
+    int[] int32s = {1, 2};
+    int[] uint32s = {3, 4};
+    int[] sint32s = {-5, -6};
+    long[] int64s = {7, 8};
+    long[] uint64s = {9, 10};
+    long[] sint64s = {-11, -12};
+    int[] fixed32s = {13, 14};
+    int[] sfixed32s = {-15, -16};
+    long[] fixed64s = {17, 18};
+    long[] sfixed64s = {-19, -20};
+    boolean[] bools = {true, false};
+    float[] floats = {2.1f, 2.2f};
+    double[] doubles = {2.3, 2.4};
+    int[] enums = {Extensions.SECOND_VALUE, Extensions.FIRST_VALUE};
+    String[] strings = {"vijfentwintig", "twenty-six"};
+    byte[][] bytess = {{2, 7}, {2, 8}};
+    AnotherMessage another1 = new AnotherMessage();
+    another1.string = "er shi jiu";
+    another1.value = false;
+    AnotherMessage another2 = new AnotherMessage();
+    another2.string = "trente";
+    another2.value = true;
+    AnotherMessage[] messages = {another1, another2};
+    RepeatedExtensions.RepeatedGroup group1 = new RepeatedExtensions.RepeatedGroup();
+    group1.a = 31;
+    RepeatedExtensions.RepeatedGroup group2 = new RepeatedExtensions.RepeatedGroup();
+    group2.a = 32;
+    RepeatedExtensions.RepeatedGroup[] groups = {group1, group2};
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedInt32));
+    message.setExtension(RepeatedExtensions.repeatedInt32, int32s);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedInt32));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedUint32));
+    message.setExtension(RepeatedExtensions.repeatedUint32, uint32s);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedUint32));
+    message.setExtension(RepeatedExtensions.repeatedSint32, sint32s);
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedInt64));
+    message.setExtension(RepeatedExtensions.repeatedInt64, int64s);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedInt64));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedUint64));
+    message.setExtension(RepeatedExtensions.repeatedUint64, uint64s);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedUint64));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedSint64));
+    message.setExtension(RepeatedExtensions.repeatedSint64, sint64s);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedSint64));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedFixed32));
+    message.setExtension(RepeatedExtensions.repeatedFixed32, fixed32s);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedFixed32));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedSfixed32));
+    message.setExtension(RepeatedExtensions.repeatedSfixed32, sfixed32s);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedSfixed32));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedFixed64));
+    message.setExtension(RepeatedExtensions.repeatedFixed64, fixed64s);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedFixed64));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedSfixed64));
+    message.setExtension(RepeatedExtensions.repeatedSfixed64, sfixed64s);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedSfixed64));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedBool));
+    message.setExtension(RepeatedExtensions.repeatedBool, bools);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedBool));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedFloat));
+    message.setExtension(RepeatedExtensions.repeatedFloat, floats);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedFloat));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedDouble));
+    message.setExtension(RepeatedExtensions.repeatedDouble, doubles);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedDouble));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedEnum));
+    message.setExtension(RepeatedExtensions.repeatedEnum, enums);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedEnum));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedString));
+    message.setExtension(RepeatedExtensions.repeatedString, strings);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedString));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedBytes));
+    message.setExtension(RepeatedExtensions.repeatedBytes, bytess);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedBytes));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedMessage));
+    message.setExtension(RepeatedExtensions.repeatedMessage, messages);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedMessage));
+    assertFalse(message.hasExtension(RepeatedExtensions.repeatedGroup));
+    message.setExtension(RepeatedExtensions.repeatedGroup, groups);
+    assertTrue(message.hasExtension(RepeatedExtensions.repeatedGroup));
+
+    byte[] data = MessageNano.toByteArray(message);
+    message = Extensions.ExtendableMessage.parseFrom(data);
+    assertEquals(5, message.field);
+
+    // Test reading back using SingularExtensions: the retrieved value should equal the last
+    // in each array.
+    assertEquals(int32s[1], (int) message.getExtension(SingularExtensions.someInt32));
+    assertEquals(uint32s[1], (int) message.getExtension(SingularExtensions.someUint32));
+    assertEquals(sint32s[1], (int) message.getExtension(SingularExtensions.someSint32));
+    assertEquals(int64s[1], (long) message.getExtension(SingularExtensions.someInt64));
+    assertEquals(uint64s[1], (long) message.getExtension(SingularExtensions.someUint64));
+    assertEquals(sint64s[1], (long) message.getExtension(SingularExtensions.someSint64));
+    assertEquals(fixed32s[1], (int) message.getExtension(SingularExtensions.someFixed32));
+    assertEquals(sfixed32s[1], (int) message.getExtension(SingularExtensions.someSfixed32));
+    assertEquals(fixed64s[1], (long) message.getExtension(SingularExtensions.someFixed64));
+    assertEquals(sfixed64s[1], (long) message.getExtension(SingularExtensions.someSfixed64));
+    assertEquals(bools[1], (boolean) message.getExtension(SingularExtensions.someBool));
+    assertEquals(floats[1], (float) message.getExtension(SingularExtensions.someFloat));
+    assertEquals(doubles[1], (double) message.getExtension(SingularExtensions.someDouble));
+    assertEquals(enums[1], (int) message.getExtension(SingularExtensions.someEnum));
+    assertEquals(strings[1], message.getExtension(SingularExtensions.someString));
+    assertTrue(Arrays.equals(bytess[1], message.getExtension(SingularExtensions.someBytes)));
+    AnotherMessage deserializedMessage = message.getExtension(SingularExtensions.someMessage);
+    assertEquals(another2.string, deserializedMessage.string);
+    assertEquals(another2.value, deserializedMessage.value);
+    assertEquals(group2.a, message.getExtension(SingularExtensions.someGroup).a);
+
+    // Test reading back using RepeatedExtensions: the arrays should be equal.
+    message = Extensions.ExtendableMessage.parseFrom(data);
+    assertEquals(5, message.field);
+    assertTrue(Arrays.equals(int32s, message.getExtension(RepeatedExtensions.repeatedInt32)));
+    assertTrue(Arrays.equals(uint32s, message.getExtension(RepeatedExtensions.repeatedUint32)));
+    assertTrue(Arrays.equals(sint32s, message.getExtension(RepeatedExtensions.repeatedSint32)));
+    assertTrue(Arrays.equals(int64s, message.getExtension(RepeatedExtensions.repeatedInt64)));
+    assertTrue(Arrays.equals(uint64s, message.getExtension(RepeatedExtensions.repeatedUint64)));
+    assertTrue(Arrays.equals(sint64s, message.getExtension(RepeatedExtensions.repeatedSint64)));
+    assertTrue(Arrays.equals(fixed32s, message.getExtension(RepeatedExtensions.repeatedFixed32)));
+    assertTrue(Arrays.equals(sfixed32s, message.getExtension(RepeatedExtensions.repeatedSfixed32)));
+    assertTrue(Arrays.equals(fixed64s, message.getExtension(RepeatedExtensions.repeatedFixed64)));
+    assertTrue(Arrays.equals(sfixed64s, message.getExtension(RepeatedExtensions.repeatedSfixed64)));
+    assertTrue(Arrays.equals(bools, message.getExtension(RepeatedExtensions.repeatedBool)));
+    assertTrue(Arrays.equals(floats, message.getExtension(RepeatedExtensions.repeatedFloat)));
+    assertTrue(Arrays.equals(doubles, message.getExtension(RepeatedExtensions.repeatedDouble)));
+    assertTrue(Arrays.equals(enums, message.getExtension(RepeatedExtensions.repeatedEnum)));
+    assertTrue(Arrays.equals(strings, message.getExtension(RepeatedExtensions.repeatedString)));
+    byte[][] deserializedRepeatedBytes = message.getExtension(RepeatedExtensions.repeatedBytes);
+    assertEquals(2, deserializedRepeatedBytes.length);
+    assertTrue(Arrays.equals(bytess[0], deserializedRepeatedBytes[0]));
+    assertTrue(Arrays.equals(bytess[1], deserializedRepeatedBytes[1]));
+    AnotherMessage[] deserializedRepeatedMessage =
+        message.getExtension(RepeatedExtensions.repeatedMessage);
+    assertEquals(2, deserializedRepeatedMessage.length);
+    assertEquals(another1.string, deserializedRepeatedMessage[0].string);
+    assertEquals(another1.value, deserializedRepeatedMessage[0].value);
+    assertEquals(another2.string, deserializedRepeatedMessage[1].string);
+    assertEquals(another2.value, deserializedRepeatedMessage[1].value);
+    RepeatedExtensions.RepeatedGroup[] deserializedRepeatedGroup =
+        message.getExtension(RepeatedExtensions.repeatedGroup);
+    assertEquals(2, deserializedRepeatedGroup.length);
+    assertEquals(group1.a, deserializedRepeatedGroup[0].a);
+    assertEquals(group2.a, deserializedRepeatedGroup[1].a);
+
+    message = Extensions.ExtendableMessage.parseFrom(data);
+    assertEquals(5, message.field);
+    // Test hasExtension using PackedExtensions.
+    assertTrue(message.hasExtension(PackedExtensions.packedInt32));
+    assertTrue(message.hasExtension(PackedExtensions.packedUint32));
+    assertTrue(message.hasExtension(PackedExtensions.packedSint32));
+    assertTrue(message.hasExtension(PackedExtensions.packedInt64));
+    assertTrue(message.hasExtension(PackedExtensions.packedUint64));
+    assertTrue(message.hasExtension(PackedExtensions.packedSint64));
+    assertTrue(message.hasExtension(PackedExtensions.packedFixed32));
+    assertTrue(message.hasExtension(PackedExtensions.packedSfixed32));
+    assertTrue(message.hasExtension(PackedExtensions.packedFixed64));
+    assertTrue(message.hasExtension(PackedExtensions.packedSfixed64));
+    assertTrue(message.hasExtension(PackedExtensions.packedBool));
+    assertTrue(message.hasExtension(PackedExtensions.packedFloat));
+    assertTrue(message.hasExtension(PackedExtensions.packedDouble));
+    assertTrue(message.hasExtension(PackedExtensions.packedEnum));
+
+    // Test reading back using PackedExtensions: the arrays should be equal, even the fields
+    // are non-packed.
+    assertTrue(Arrays.equals(int32s, message.getExtension(PackedExtensions.packedInt32)));
+    assertTrue(Arrays.equals(uint32s, message.getExtension(PackedExtensions.packedUint32)));
+    assertTrue(Arrays.equals(sint32s, message.getExtension(PackedExtensions.packedSint32)));
+    assertTrue(Arrays.equals(int64s, message.getExtension(PackedExtensions.packedInt64)));
+    assertTrue(Arrays.equals(uint64s, message.getExtension(PackedExtensions.packedUint64)));
+    assertTrue(Arrays.equals(sint64s, message.getExtension(PackedExtensions.packedSint64)));
+    assertTrue(Arrays.equals(fixed32s, message.getExtension(PackedExtensions.packedFixed32)));
+    assertTrue(Arrays.equals(sfixed32s, message.getExtension(PackedExtensions.packedSfixed32)));
+    assertTrue(Arrays.equals(fixed64s, message.getExtension(PackedExtensions.packedFixed64)));
+    assertTrue(Arrays.equals(sfixed64s, message.getExtension(PackedExtensions.packedSfixed64)));
+    assertTrue(Arrays.equals(bools, message.getExtension(PackedExtensions.packedBool)));
+    assertTrue(Arrays.equals(floats, message.getExtension(PackedExtensions.packedFloat)));
+    assertTrue(Arrays.equals(doubles, message.getExtension(PackedExtensions.packedDouble)));
+    assertTrue(Arrays.equals(enums, message.getExtension(PackedExtensions.packedEnum)));
+
+    // Now set the packable extension values using PackedExtensions so they're serialized packed.
+    message.setExtension(PackedExtensions.packedInt32, int32s);
+    message.setExtension(PackedExtensions.packedUint32, uint32s);
+    message.setExtension(PackedExtensions.packedSint32, sint32s);
+    message.setExtension(PackedExtensions.packedInt64, int64s);
+    message.setExtension(PackedExtensions.packedUint64, uint64s);
+    message.setExtension(PackedExtensions.packedSint64, sint64s);
+    message.setExtension(PackedExtensions.packedFixed32, fixed32s);
+    message.setExtension(PackedExtensions.packedSfixed32, sfixed32s);
+    message.setExtension(PackedExtensions.packedFixed64, fixed64s);
+    message.setExtension(PackedExtensions.packedSfixed64, sfixed64s);
+    message.setExtension(PackedExtensions.packedBool, bools);
+    message.setExtension(PackedExtensions.packedFloat, floats);
+    message.setExtension(PackedExtensions.packedDouble, doubles);
+    message.setExtension(PackedExtensions.packedEnum, enums);
+
+    // And read back using non-packed RepeatedExtensions.
+    byte[] data2 = MessageNano.toByteArray(message);
+    message = MessageNano.mergeFrom(new Extensions.ExtendableMessage(), data2);
+    assertTrue(Arrays.equals(int32s, message.getExtension(RepeatedExtensions.repeatedInt32)));
+    assertTrue(Arrays.equals(uint32s, message.getExtension(RepeatedExtensions.repeatedUint32)));
+    assertTrue(Arrays.equals(sint32s, message.getExtension(RepeatedExtensions.repeatedSint32)));
+    assertTrue(Arrays.equals(int64s, message.getExtension(RepeatedExtensions.repeatedInt64)));
+    assertTrue(Arrays.equals(uint64s, message.getExtension(RepeatedExtensions.repeatedUint64)));
+    assertTrue(Arrays.equals(sint64s, message.getExtension(RepeatedExtensions.repeatedSint64)));
+    assertTrue(Arrays.equals(fixed32s, message.getExtension(RepeatedExtensions.repeatedFixed32)));
+    assertTrue(Arrays.equals(sfixed32s, message.getExtension(RepeatedExtensions.repeatedSfixed32)));
+    assertTrue(Arrays.equals(fixed64s, message.getExtension(RepeatedExtensions.repeatedFixed64)));
+    assertTrue(Arrays.equals(sfixed64s, message.getExtension(RepeatedExtensions.repeatedSfixed64)));
+    assertTrue(Arrays.equals(bools, message.getExtension(RepeatedExtensions.repeatedBool)));
+    assertTrue(Arrays.equals(floats, message.getExtension(RepeatedExtensions.repeatedFloat)));
+    assertTrue(Arrays.equals(doubles, message.getExtension(RepeatedExtensions.repeatedDouble)));
+    assertTrue(Arrays.equals(enums, message.getExtension(RepeatedExtensions.repeatedEnum)));
+
+    // Clone the message and ensure it's still equal.
+    Extensions.ExtendableMessage clone = message.clone();
+    assertEquals(clone, message);
+  }
+
+  public void testNullExtensions() throws Exception {
+    // Check that clearing the extension on an empty message is a no-op.
+    Extensions.ExtendableMessage message = new Extensions.ExtendableMessage();
+    assertFalse(message.hasExtension(SingularExtensions.someMessage));
+    message.setExtension(SingularExtensions.someMessage, null);
+    assertFalse(message.hasExtension(SingularExtensions.someMessage));
+    assertEquals(0, MessageNano.toByteArray(message).length);
+
+    // Check that the message is empty after setting and clearing an extension.
+    AnotherMessage another = new AnotherMessage();
+    assertFalse(message.hasExtension(SingularExtensions.someMessage));
+    message.setExtension(SingularExtensions.someMessage, another);
+    assertTrue(message.hasExtension(SingularExtensions.someMessage));
+    assertTrue(MessageNano.toByteArray(message).length > 0);
+    message.setExtension(SingularExtensions.someMessage, null);
+    assertFalse(message.hasExtension(SingularExtensions.someMessage));
+    assertEquals(0, MessageNano.toByteArray(message).length);
+  }
+
+  public void testExtensionsMutation() {
+    Extensions.ExtendableMessage extendableMessage = new Extensions.ExtendableMessage();
+    extendableMessage.setExtension(SingularExtensions.someMessage,
+        new Extensions.AnotherMessage());
+
+    extendableMessage.getExtension(SingularExtensions.someMessage).string = "not empty";
+
+    assertEquals("not empty",
+        extendableMessage.getExtension(SingularExtensions.someMessage).string);
+  }
+
+  public void testExtensionsMutation_Equals() throws InvalidProtocolBufferNanoException {
+    Extensions.ExtendableMessage extendableMessage = new Extensions.ExtendableMessage();
+    extendableMessage.field = 5;
+    int int32 = 42;
+    int[] uint32s = {3, 4};
+    int[] sint32s = {-5, -6};
+    long[] int64s = {7, 8};
+    long[] uint64s = {9, 10};
+    long[] sint64s = {-11, -12};
+    int[] fixed32s = {13, 14};
+    int[] sfixed32s = {-15, -16};
+    long[] fixed64s = {17, 18};
+    long[] sfixed64s = {-19, -20};
+    boolean[] bools = {true, false};
+    float[] floats = {2.1f, 2.2f};
+    double[] doubles = {2.3, 2.4};
+    int[] enums = {Extensions.SECOND_VALUE, Extensions.FIRST_VALUE};
+    String[] strings = {"vijfentwintig", "twenty-six"};
+    byte[][] bytess = {{2, 7}, {2, 8}};
+    AnotherMessage another1 = new AnotherMessage();
+    another1.string = "er shi jiu";
+    another1.value = false;
+    AnotherMessage another2 = new AnotherMessage();
+    another2.string = "trente";
+    another2.value = true;
+    AnotherMessage[] messages = {another1, another2};
+    RepeatedExtensions.RepeatedGroup group1 = new RepeatedExtensions.RepeatedGroup();
+    group1.a = 31;
+    RepeatedExtensions.RepeatedGroup group2 = new RepeatedExtensions.RepeatedGroup();
+    group2.a = 32;
+    RepeatedExtensions.RepeatedGroup[] groups = {group1, group2};
+    extendableMessage.setExtension(SingularExtensions.someInt32, int32);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedUint32, uint32s);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedSint32, sint32s);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedInt64, int64s);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedUint64, uint64s);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedSint64, sint64s);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedFixed32, fixed32s);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedSfixed32, sfixed32s);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedFixed64, fixed64s);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedSfixed64, sfixed64s);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedBool, bools);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedFloat, floats);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedDouble, doubles);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedEnum, enums);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedString, strings);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedBytes, bytess);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedMessage, messages);
+    extendableMessage.setExtension(RepeatedExtensions.repeatedGroup, groups);
+
+    byte[] data = MessageNano.toByteArray(extendableMessage);
+
+    extendableMessage = Extensions.ExtendableMessage.parseFrom(data);
+    Extensions.ExtendableMessage messageCopy = Extensions.ExtendableMessage.parseFrom(data);
+
+    // Without deserialising.
+    assertEquals(extendableMessage, messageCopy);
+    assertEquals(extendableMessage.hashCode(), messageCopy.hashCode());
+
+    // Only one deserialized.
+    extendableMessage.getExtension(SingularExtensions.someInt32);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedUint32);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedSint32);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedInt64);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedUint64);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedSint64);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedFixed32);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedSfixed32);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedFixed64);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedSfixed64);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedBool);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedFloat);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedDouble);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedEnum);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedString);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedBytes);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedMessage);
+    extendableMessage.getExtension(RepeatedExtensions.repeatedGroup);
+    assertEquals(extendableMessage, messageCopy);
+    assertEquals(extendableMessage.hashCode(), messageCopy.hashCode());
+
+    // Both deserialized.
+    messageCopy.getExtension(SingularExtensions.someInt32);
+    messageCopy.getExtension(RepeatedExtensions.repeatedUint32);
+    messageCopy.getExtension(RepeatedExtensions.repeatedSint32);
+    messageCopy.getExtension(RepeatedExtensions.repeatedInt64);
+    messageCopy.getExtension(RepeatedExtensions.repeatedUint64);
+    messageCopy.getExtension(RepeatedExtensions.repeatedSint64);
+    messageCopy.getExtension(RepeatedExtensions.repeatedFixed32);
+    messageCopy.getExtension(RepeatedExtensions.repeatedSfixed32);
+    messageCopy.getExtension(RepeatedExtensions.repeatedFixed64);
+    messageCopy.getExtension(RepeatedExtensions.repeatedSfixed64);
+    messageCopy.getExtension(RepeatedExtensions.repeatedBool);
+    messageCopy.getExtension(RepeatedExtensions.repeatedFloat);
+    messageCopy.getExtension(RepeatedExtensions.repeatedDouble);
+    messageCopy.getExtension(RepeatedExtensions.repeatedEnum);
+    messageCopy.getExtension(RepeatedExtensions.repeatedString);
+    messageCopy.getExtension(RepeatedExtensions.repeatedBytes);
+    messageCopy.getExtension(RepeatedExtensions.repeatedMessage);
+    messageCopy.getExtension(RepeatedExtensions.repeatedGroup);
+    assertEquals(extendableMessage, messageCopy);
+    assertEquals(extendableMessage.hashCode(), messageCopy.hashCode());
+
+    // Change one, make sure they are still different.
+    messageCopy.getExtension(RepeatedExtensions.repeatedMessage)[0].string = "not empty";
+    assertFalse(extendableMessage.equals(messageCopy));
+
+    // Even if the extension hasn't been deserialized.
+    extendableMessage = Extensions.ExtendableMessage.parseFrom(data);
+    assertFalse(extendableMessage.equals(messageCopy));
+  }
+
+  public void testExtensionsCaching() {
+    Extensions.ExtendableMessage extendableMessage = new Extensions.ExtendableMessage();
+    extendableMessage.setExtension(SingularExtensions.someMessage,
+        new Extensions.AnotherMessage());
+    assertSame("Consecutive calls to getExtensions should return the same object",
+        extendableMessage.getExtension(SingularExtensions.someMessage),
+        extendableMessage.getExtension(SingularExtensions.someMessage));
+  }
+
+  public void testUnknownFields() throws Exception {
+    // Check that we roundtrip (serialize and deserialize) unrecognized fields.
+    AnotherMessage message = new AnotherMessage();
+    message.string = "Hello World";
+    message.value = false;
+
+    byte[] bytes = MessageNano.toByteArray(message);
+    int extraFieldSize = CodedOutputStream.computeStringSize(1001, "This is an unknown field");
+    byte[] newBytes = new byte[bytes.length + extraFieldSize];
+    System.arraycopy(bytes, 0, newBytes, 0, bytes.length);
+    CodedOutputStream.newInstance(newBytes, bytes.length, extraFieldSize).writeString(1001,
+        "This is an unknown field");
+
+    // Deserialize with an unknown field.
+    AnotherMessage deserialized = AnotherMessage.parseFrom(newBytes);
+    byte[] serialized = MessageNano.toByteArray(deserialized);
+
+    assertEquals(newBytes.length, serialized.length);
+
+    // Clear, and make sure it clears everything.
+    deserialized.clear();
+    assertEquals(0, MessageNano.toByteArray(deserialized).length);
+  }
+
+  public void testMergeFrom() throws Exception {
+    SimpleMessageNano message = new SimpleMessageNano();
+    message.d = 123;
+    byte[] bytes = MessageNano.toByteArray(message);
+
+    SimpleMessageNano newMessage = MessageNano.mergeFrom(new SimpleMessageNano(), bytes);
+    assertEquals(message.d, newMessage.d);
+  }
+
+  public void testJavaKeyword() throws Exception {
+    TestAllTypesNano msg = new TestAllTypesNano();
+    msg.synchronized_ = 123;
+    assertEquals(123, msg.synchronized_);
+  }
+
+  public void testReferenceTypesForPrimitives() throws Exception {
+    NanoReferenceTypes.TestAllTypesNano message = new NanoReferenceTypes.TestAllTypesNano();
+
+    // Base check - when nothing is set, we serialize nothing.
+    assertHasWireData(message, false);
+
+    message.defaultBool = true;
+    assertHasWireData(message, true);
+
+    message.defaultBool = false;
+    assertHasWireData(message, true);
+
+    message.defaultBool = null;
+    assertHasWireData(message, false);
+
+    message.defaultInt32 = 5;
+    assertHasWireData(message, true);
+
+    message.defaultInt32 = null;
+    assertHasWireData(message, false);
+
+    message.defaultInt64 = 123456L;
+    assertHasWireData(message, true);
+
+    message.defaultInt64 = null;
+    assertHasWireData(message, false);
+
+    message.defaultFloat = 1f;
+    assertHasWireData(message, true);
+
+    message.defaultFloat = null;
+    assertHasWireData(message, false);
+
+    message.defaultDouble = 2.1;
+    assertHasWireData(message, true);
+
+    message.defaultDouble = null;
+    assertHasWireData(message, false);
+
+    message.defaultString = "hello";
+    assertHasWireData(message, true);
+
+    message.defaultString = null;
+    assertHasWireData(message, false);
+
+    message.defaultBytes = new byte[] { 1, 2, 3 };
+    assertHasWireData(message, true);
+
+    message.defaultBytes = null;
+    assertHasWireData(message, false);
+  }
+
+  public void testHashCodeEquals() throws Exception {
+    // Complete equality:
+    TestAllTypesNano a = createMessageForHashCodeEqualsTest();
+    TestAllTypesNano aEquivalent = createMessageForHashCodeEqualsTest();
+
+    assertTrue(MessageNano.messageNanoEquals(a, aEquivalent));
+    assertFalse(MessageNano.messageNanoEquals(a, new TestAllTypesNano()));
+
+    // Null and empty array for repeated fields equality:
+    TestAllTypesNano b = createMessageForHashCodeEqualsTest();
+    b.repeatedBool = null;
+    b.repeatedFloat = new float[0];
+    TestAllTypesNano bEquivalent = createMessageForHashCodeEqualsTest();
+    bEquivalent.repeatedBool = new boolean[0];
+    bEquivalent.repeatedFloat = null;
+
+    // Ref-element-type repeated fields use non-null subsequence equality:
+    TestAllTypesNano c = createMessageForHashCodeEqualsTest();
+    c.repeatedString = null;
+    c.repeatedStringPiece = new String[] {null, "one", null, "two"};
+    c.repeatedBytes = new byte[][] {{3, 4}, null};
+    TestAllTypesNano cEquivalent = createMessageForHashCodeEqualsTest();
+    cEquivalent.repeatedString = new String[3];
+    cEquivalent.repeatedStringPiece = new String[] {"one", "two", null};
+    cEquivalent.repeatedBytes = new byte[][] {{3, 4}};
+
+    // Complete equality for messages with has fields:
+    TestAllTypesNanoHas d = createMessageWithHasForHashCodeEqualsTest();
+    TestAllTypesNanoHas dEquivalent = createMessageWithHasForHashCodeEqualsTest();
+
+    // If has-fields exist, fields with the same default values but
+    // different has-field values are different.
+    TestAllTypesNanoHas e = createMessageWithHasForHashCodeEqualsTest();
+    e.optionalInt32++; // make different from d
+    e.hasDefaultString = false;
+    TestAllTypesNanoHas eDifferent = createMessageWithHasForHashCodeEqualsTest();
+    eDifferent.optionalInt32 = e.optionalInt32;
+    eDifferent.hasDefaultString = true;
+
+    // Complete equality for messages with accessors:
+    TestNanoAccessors f = createMessageWithAccessorsForHashCodeEqualsTest();
+    TestNanoAccessors fEquivalent = createMessageWithAccessorsForHashCodeEqualsTest();
+
+    // If using accessors, explicitly setting a field to its default value
+    // should make the message different.
+    TestNanoAccessors g = createMessageWithAccessorsForHashCodeEqualsTest();
+    g.setOptionalInt32(g.getOptionalInt32() + 1); // make different from f
+    g.clearDefaultString();
+    TestNanoAccessors gDifferent = createMessageWithAccessorsForHashCodeEqualsTest();
+    gDifferent.setOptionalInt32(g.getOptionalInt32());
+    gDifferent.setDefaultString(g.getDefaultString());
+
+    // Complete equality for reference typed messages:
+    NanoReferenceTypes.TestAllTypesNano h = createRefTypedMessageForHashCodeEqualsTest();
+    NanoReferenceTypes.TestAllTypesNano hEquivalent = createRefTypedMessageForHashCodeEqualsTest();
+
+    // Inequality of null and default value for reference typed messages:
+    NanoReferenceTypes.TestAllTypesNano i = createRefTypedMessageForHashCodeEqualsTest();
+    i.optionalInt32 = 1; // make different from h
+    i.optionalFloat = null;
+    NanoReferenceTypes.TestAllTypesNano iDifferent = createRefTypedMessageForHashCodeEqualsTest();
+    iDifferent.optionalInt32 = i.optionalInt32;
+    iDifferent.optionalFloat = 0.0f;
+
+    HashMap<MessageNano, String> hashMap = new HashMap<MessageNano, String>();
+    hashMap.put(a, "a");
+    hashMap.put(b, "b");
+    hashMap.put(c, "c");
+    hashMap.put(d, "d");
+    hashMap.put(e, "e");
+    hashMap.put(f, "f");
+    hashMap.put(g, "g");
+    hashMap.put(h, "h");
+    hashMap.put(i, "i");
+
+    assertEquals(9, hashMap.size()); // a-i should be different from each other.
+
+    assertEquals("a", hashMap.get(a));
+    assertEquals("a", hashMap.get(aEquivalent));
+
+    assertEquals("b", hashMap.get(b));
+    assertEquals("b", hashMap.get(bEquivalent));
+
+    assertEquals("c", hashMap.get(c));
+    assertEquals("c", hashMap.get(cEquivalent));
+
+    assertEquals("d", hashMap.get(d));
+    assertEquals("d", hashMap.get(dEquivalent));
+
+    assertEquals("e", hashMap.get(e));
+    assertNull(hashMap.get(eDifferent));
+
+    assertEquals("f", hashMap.get(f));
+    assertEquals("f", hashMap.get(fEquivalent));
+
+    assertEquals("g", hashMap.get(g));
+    assertNull(hashMap.get(gDifferent));
+
+    assertEquals("h", hashMap.get(h));
+    assertEquals("h", hashMap.get(hEquivalent));
+
+    assertEquals("i", hashMap.get(i));
+    assertNull(hashMap.get(iDifferent));
+  }
+
+  private TestAllTypesNano createMessageForHashCodeEqualsTest() {
+    TestAllTypesNano message = new TestAllTypesNano();
+    message.optionalInt32 = 5;
+    message.optionalInt64 = 777;
+    message.optionalFloat = 1.0f;
+    message.optionalDouble = 2.0;
+    message.optionalBool = true;
+    message.optionalString = "Hello";
+    message.optionalBytes = new byte[] { 1, 2, 3 };
+    message.optionalNestedMessage = new TestAllTypesNano.NestedMessage();
+    message.optionalNestedMessage.bb = 27;
+    message.optionalNestedEnum = TestAllTypesNano.BAR;
+    message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
+    message.repeatedInt64 = new long[] { 27L, 28L, 29L };
+    message.repeatedFloat = new float[] { 5.0f, 6.0f };
+    message.repeatedDouble = new double[] { 99.1, 22.5 };
+    message.repeatedBool = new boolean[] { true, false, true };
+    message.repeatedString = new String[] { "One", "Two" };
+    message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
+    message.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {
+      message.optionalNestedMessage,
+      message.optionalNestedMessage
+    };
+    message.repeatedNestedEnum = new int[] {
+      TestAllTypesNano.BAR,
+      TestAllTypesNano.BAZ
+    };
+    return message;
+  }
+
+  private TestAllTypesNanoHas createMessageWithHasForHashCodeEqualsTest() {
+    TestAllTypesNanoHas message = new TestAllTypesNanoHas();
+    message.optionalInt32 = 5;
+    message.optionalString = "Hello";
+    message.optionalBytes = new byte[] { 1, 2, 3 };
+    message.optionalNestedMessage = new TestAllTypesNanoHas.NestedMessage();
+    message.optionalNestedMessage.bb = 27;
+    message.optionalNestedEnum = TestAllTypesNano.BAR;
+    message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
+    message.repeatedString = new String[] { "One", "Two" };
+    message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
+    message.repeatedNestedMessage = new TestAllTypesNanoHas.NestedMessage[] {
+      message.optionalNestedMessage,
+      message.optionalNestedMessage
+    };
+    message.repeatedNestedEnum = new int[] {
+      TestAllTypesNano.BAR,
+      TestAllTypesNano.BAZ
+    };
+    return message;
+  }
+
+  private TestNanoAccessors createMessageWithAccessorsForHashCodeEqualsTest() {
+    TestNanoAccessors message = new TestNanoAccessors()
+        .setOptionalInt32(5)
+        .setOptionalString("Hello")
+        .setOptionalBytes(new byte[] {1, 2, 3})
+        .setOptionalNestedEnum(TestNanoAccessors.BAR);
+    message.optionalNestedMessage = new TestNanoAccessors.NestedMessage().setBb(27);
+    message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
+    message.repeatedString = new String[] { "One", "Two" };
+    message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
+    message.repeatedNestedMessage = new TestNanoAccessors.NestedMessage[] {
+      message.optionalNestedMessage,
+      message.optionalNestedMessage
+    };
+    message.repeatedNestedEnum = new int[] {
+      TestAllTypesNano.BAR,
+      TestAllTypesNano.BAZ
+    };
+    return message;
+  }
+
+  private NanoReferenceTypes.TestAllTypesNano createRefTypedMessageForHashCodeEqualsTest() {
+    NanoReferenceTypes.TestAllTypesNano message = new NanoReferenceTypes.TestAllTypesNano();
+    message.optionalInt32 = 5;
+    message.optionalInt64 = 777L;
+    message.optionalFloat = 1.0f;
+    message.optionalDouble = 2.0;
+    message.optionalBool = true;
+    message.optionalString = "Hello";
+    message.optionalBytes = new byte[] { 1, 2, 3 };
+    message.optionalNestedMessage =
+        new NanoReferenceTypes.TestAllTypesNano.NestedMessage();
+    message.optionalNestedMessage.foo = 27;
+    message.optionalNestedEnum = NanoReferenceTypes.TestAllTypesNano.BAR;
+    message.repeatedInt32 = new int[] { 5, 6, 7, 8 };
+    message.repeatedInt64 = new long[] { 27L, 28L, 29L };
+    message.repeatedFloat = new float[] { 5.0f, 6.0f };
+    message.repeatedDouble = new double[] { 99.1, 22.5 };
+    message.repeatedBool = new boolean[] { true, false, true };
+    message.repeatedString = new String[] { "One", "Two" };
+    message.repeatedBytes = new byte[][] { { 2, 7 }, { 2, 7 } };
+    message.repeatedNestedMessage =
+        new NanoReferenceTypes.TestAllTypesNano.NestedMessage[] {
+          message.optionalNestedMessage,
+          message.optionalNestedMessage
+        };
+    message.repeatedNestedEnum = new int[] {
+      NanoReferenceTypes.TestAllTypesNano.BAR,
+      NanoReferenceTypes.TestAllTypesNano.BAZ
+    };
+    return message;
+  }
+
+  public void testEqualsWithSpecialFloatingPointValues() throws Exception {
+    // Checks that the nano implementation complies with Object.equals() when treating
+    // floating point numbers, i.e. NaN == NaN and +0.0 != -0.0.
+    // This test assumes that the generated equals() implementations are symmetric, so
+    // there will only be one direction for each equality check.
+
+    TestAllTypesNano m1 = new TestAllTypesNano();
+    m1.optionalFloat = Float.NaN;
+    m1.optionalDouble = Double.NaN;
+    TestAllTypesNano m2 = new TestAllTypesNano();
+    m2.optionalFloat = Float.NaN;
+    m2.optionalDouble = Double.NaN;
+    assertTrue(m1.equals(m2));
+    assertTrue(m1.equals(
+        MessageNano.mergeFrom(new TestAllTypesNano(), MessageNano.toByteArray(m1))));
+
+    m1.optionalFloat = +0f;
+    m2.optionalFloat = -0f;
+    assertFalse(m1.equals(m2));
+
+    m1.optionalFloat = -0f;
+    m1.optionalDouble = +0d;
+    m2.optionalDouble = -0d;
+    assertFalse(m1.equals(m2));
+
+    m1.optionalDouble = -0d;
+    assertTrue(m1.equals(m2));
+    assertFalse(m1.equals(new TestAllTypesNano())); // -0 does not equals() the default +0
+    assertTrue(m1.equals(
+        MessageNano.mergeFrom(new TestAllTypesNano(), MessageNano.toByteArray(m1))));
+
+    // -------
+
+    TestAllTypesNanoHas m3 = new TestAllTypesNanoHas();
+    m3.optionalFloat = Float.NaN;
+    m3.hasOptionalFloat = true;
+    m3.optionalDouble = Double.NaN;
+    m3.hasOptionalDouble = true;
+    TestAllTypesNanoHas m4 = new TestAllTypesNanoHas();
+    m4.optionalFloat = Float.NaN;
+    m4.hasOptionalFloat = true;
+    m4.optionalDouble = Double.NaN;
+    m4.hasOptionalDouble = true;
+    assertTrue(m3.equals(m4));
+    assertTrue(m3.equals(
+        MessageNano.mergeFrom(new TestAllTypesNanoHas(), MessageNano.toByteArray(m3))));
+
+    m3.optionalFloat = +0f;
+    m4.optionalFloat = -0f;
+    assertFalse(m3.equals(m4));
+
+    m3.optionalFloat = -0f;
+    m3.optionalDouble = +0d;
+    m4.optionalDouble = -0d;
+    assertFalse(m3.equals(m4));
+
+    m3.optionalDouble = -0d;
+    m3.hasOptionalFloat = false;  // -0 does not equals() the default +0,
+    m3.hasOptionalDouble = false; // so these incorrect 'has' flags should be disregarded.
+    assertTrue(m3.equals(m4));    // note: m4 has the 'has' flags set.
+    assertFalse(m3.equals(new TestAllTypesNanoHas())); // note: the new message has +0 defaults
+    assertTrue(m3.equals(
+        MessageNano.mergeFrom(new TestAllTypesNanoHas(), MessageNano.toByteArray(m3))));
+                                  // note: the deserialized message has the 'has' flags set.
+
+    // -------
+
+    TestNanoAccessors m5 = new TestNanoAccessors();
+    m5.setOptionalFloat(Float.NaN);
+    m5.setOptionalDouble(Double.NaN);
+    TestNanoAccessors m6 = new TestNanoAccessors();
+    m6.setOptionalFloat(Float.NaN);
+    m6.setOptionalDouble(Double.NaN);
+    assertTrue(m5.equals(m6));
+    assertTrue(m5.equals(
+        MessageNano.mergeFrom(new TestNanoAccessors(), MessageNano.toByteArray(m6))));
+
+    m5.setOptionalFloat(+0f);
+    m6.setOptionalFloat(-0f);
+    assertFalse(m5.equals(m6));
+
+    m5.setOptionalFloat(-0f);
+    m5.setOptionalDouble(+0d);
+    m6.setOptionalDouble(-0d);
+    assertFalse(m5.equals(m6));
+
+    m5.setOptionalDouble(-0d);
+    assertTrue(m5.equals(m6));
+    assertFalse(m5.equals(new TestNanoAccessors()));
+    assertTrue(m5.equals(
+        MessageNano.mergeFrom(new TestNanoAccessors(), MessageNano.toByteArray(m6))));
+
+    // -------
+
+    NanoReferenceTypes.TestAllTypesNano m7 = new NanoReferenceTypes.TestAllTypesNano();
+    m7.optionalFloat = Float.NaN;
+    m7.optionalDouble = Double.NaN;
+    NanoReferenceTypes.TestAllTypesNano m8 = new NanoReferenceTypes.TestAllTypesNano();
+    m8.optionalFloat = Float.NaN;
+    m8.optionalDouble = Double.NaN;
+    assertTrue(m7.equals(m8));
+    assertTrue(m7.equals(MessageNano.mergeFrom(
+        new NanoReferenceTypes.TestAllTypesNano(), MessageNano.toByteArray(m7))));
+
+    m7.optionalFloat = +0f;
+    m8.optionalFloat = -0f;
+    assertFalse(m7.equals(m8));
+
+    m7.optionalFloat = -0f;
+    m7.optionalDouble = +0d;
+    m8.optionalDouble = -0d;
+    assertFalse(m7.equals(m8));
+
+    m7.optionalDouble = -0d;
+    assertTrue(m7.equals(m8));
+    assertFalse(m7.equals(new NanoReferenceTypes.TestAllTypesNano()));
+    assertTrue(m7.equals(MessageNano.mergeFrom(
+        new NanoReferenceTypes.TestAllTypesNano(), MessageNano.toByteArray(m7))));
+  }
+
+  public void testNullRepeatedFields() throws Exception {
+    // Check that serialization after explicitly setting a repeated field
+    // to null doesn't NPE.
+    TestAllTypesNano message = new TestAllTypesNano();
+    message.repeatedInt32 = null;
+    MessageNano.toByteArray(message);  // should not NPE
+    message.toString(); // should not NPE
+
+    message.repeatedNestedEnum = null;
+    MessageNano.toByteArray(message);  // should not NPE
+    message.toString(); // should not NPE
+
+    message.repeatedBytes = null;
+    MessageNano.toByteArray(message); // should not NPE
+    message.toString(); // should not NPE
+
+    message.repeatedNestedMessage = null;
+    MessageNano.toByteArray(message); // should not NPE
+    message.toString(); // should not NPE
+
+    message.repeatedPackedInt32 = null;
+    MessageNano.toByteArray(message); // should not NPE
+    message.toString(); // should not NPE
+
+    message.repeatedPackedNestedEnum = null;
+    MessageNano.toByteArray(message); // should not NPE
+    message.toString(); // should not NPE
+
+    // Create a second message to merge into message.
+    TestAllTypesNano secondMessage = new TestAllTypesNano();
+    secondMessage.repeatedInt32 = new int[] {1, 2, 3};
+    secondMessage.repeatedNestedEnum = new int[] {
+      TestAllTypesNano.FOO, TestAllTypesNano.BAR
+    };
+    secondMessage.repeatedBytes = new byte[][] {{1, 2}, {3, 4}};
+    TestAllTypesNano.NestedMessage nested =
+        new TestAllTypesNano.NestedMessage();
+    nested.bb = 55;
+    secondMessage.repeatedNestedMessage =
+        new TestAllTypesNano.NestedMessage[] {nested};
+    secondMessage.repeatedPackedInt32 = new int[] {1, 2, 3};
+    secondMessage.repeatedPackedNestedEnum = new int[] {
+        TestAllTypesNano.FOO, TestAllTypesNano.BAR
+      };
+
+    // Should not NPE
+    message.mergeFrom(CodedInputByteBufferNano.newInstance(
+        MessageNano.toByteArray(secondMessage)));
+    assertEquals(3, message.repeatedInt32.length);
+    assertEquals(3, message.repeatedInt32[2]);
+    assertEquals(2, message.repeatedNestedEnum.length);
+    assertEquals(TestAllTypesNano.FOO, message.repeatedNestedEnum[0]);
+    assertEquals(2, message.repeatedBytes.length);
+    assertEquals(4, message.repeatedBytes[1][1]);
+    assertEquals(1, message.repeatedNestedMessage.length);
+    assertEquals(55, message.repeatedNestedMessage[0].bb);
+    assertEquals(3, message.repeatedPackedInt32.length);
+    assertEquals(2, message.repeatedPackedInt32[1]);
+    assertEquals(2, message.repeatedPackedNestedEnum.length);
+    assertEquals(TestAllTypesNano.BAR, message.repeatedPackedNestedEnum[1]);
+  }
+
+  public void testNullRepeatedFieldElements() throws Exception {
+    // Check that serialization with null array elements doesn't NPE.
+    String string1 = "1";
+    String string2 = "2";
+    byte[] bytes1 = {3, 4};
+    byte[] bytes2 = {5, 6};
+    TestAllTypesNano.NestedMessage msg1 = new TestAllTypesNano.NestedMessage();
+    msg1.bb = 7;
+    TestAllTypesNano.NestedMessage msg2 = new TestAllTypesNano.NestedMessage();
+    msg2.bb = 8;
+
+    TestAllTypesNano message = new TestAllTypesNano();
+    message.repeatedString = new String[] {null, string1, string2};
+    message.repeatedBytes = new byte[][] {bytes1, null, bytes2};
+    message.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {msg1, msg2, null};
+    message.repeatedGroup = new TestAllTypesNano.RepeatedGroup[] {null, null, null};
+
+    byte[] serialized = MessageNano.toByteArray(message); // should not NPE
+    TestAllTypesNano deserialized = MessageNano.mergeFrom(new TestAllTypesNano(), serialized);
+    assertEquals(2, deserialized.repeatedString.length);
+    assertEquals(string1, deserialized.repeatedString[0]);
+    assertEquals(string2, deserialized.repeatedString[1]);
+    assertEquals(2, deserialized.repeatedBytes.length);
+    assertTrue(Arrays.equals(bytes1, deserialized.repeatedBytes[0]));
+    assertTrue(Arrays.equals(bytes2, deserialized.repeatedBytes[1]));
+    assertEquals(2, deserialized.repeatedNestedMessage.length);
+    assertEquals(msg1.bb, deserialized.repeatedNestedMessage[0].bb);
+    assertEquals(msg2.bb, deserialized.repeatedNestedMessage[1].bb);
+    assertEquals(0, deserialized.repeatedGroup.length);
+  }
+
+  public void testRepeatedMerge() throws Exception {
+    // Check that merging repeated fields cause the arrays to expand with
+    // new data.
+    TestAllTypesNano first = new TestAllTypesNano();
+    first.repeatedInt32 = new int[] {1, 2, 3};
+    TestAllTypesNano second = new TestAllTypesNano();
+    second.repeatedInt32 = new int[] {4, 5};
+    MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
+    assertEquals(5, first.repeatedInt32.length);
+    assertEquals(1, first.repeatedInt32[0]);
+    assertEquals(4, first.repeatedInt32[3]);
+
+    first = new TestAllTypesNano();
+    first.repeatedNestedEnum = new int[] {TestAllTypesNano.BAR};
+    second = new TestAllTypesNano();
+    second.repeatedNestedEnum = new int[] {TestAllTypesNano.FOO};
+    MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
+    assertEquals(2, first.repeatedNestedEnum.length);
+    assertEquals(TestAllTypesNano.BAR, first.repeatedNestedEnum[0]);
+    assertEquals(TestAllTypesNano.FOO, first.repeatedNestedEnum[1]);
+
+    first = new TestAllTypesNano();
+    first.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {
+      new TestAllTypesNano.NestedMessage()
+    };
+    first.repeatedNestedMessage[0].bb = 3;
+    second = new TestAllTypesNano();
+    second.repeatedNestedMessage = new TestAllTypesNano.NestedMessage[] {
+      new TestAllTypesNano.NestedMessage()
+    };
+    second.repeatedNestedMessage[0].bb = 5;
+    MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
+    assertEquals(2, first.repeatedNestedMessage.length);
+    assertEquals(3, first.repeatedNestedMessage[0].bb);
+    assertEquals(5, first.repeatedNestedMessage[1].bb);
+
+    first = new TestAllTypesNano();
+    first.repeatedPackedSfixed64 = new long[] {-1, -2, -3};
+    second = new TestAllTypesNano();
+    second.repeatedPackedSfixed64 = new long[] {-4, -5};
+    MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
+    assertEquals(5, first.repeatedPackedSfixed64.length);
+    assertEquals(-1, first.repeatedPackedSfixed64[0]);
+    assertEquals(-4, first.repeatedPackedSfixed64[3]);
+
+    first = new TestAllTypesNano();
+    first.repeatedPackedNestedEnum = new int[] {TestAllTypesNano.BAR};
+    second = new TestAllTypesNano();
+    second.repeatedPackedNestedEnum = new int[] {TestAllTypesNano.FOO};
+    MessageNano.mergeFrom(first, MessageNano.toByteArray(second));
+    assertEquals(2, first.repeatedPackedNestedEnum.length);
+    assertEquals(TestAllTypesNano.BAR, first.repeatedPackedNestedEnum[0]);
+    assertEquals(TestAllTypesNano.FOO, first.repeatedPackedNestedEnum[1]);
+
+    // Now test repeated merging in a nested scope
+    TestRepeatedMergeNano firstContainer = new TestRepeatedMergeNano();
+    firstContainer.contained = new TestAllTypesNano();
+    firstContainer.contained.repeatedInt32 = new int[] {10, 20};
+    TestRepeatedMergeNano secondContainer = new TestRepeatedMergeNano();
+    secondContainer.contained = new TestAllTypesNano();
+    secondContainer.contained.repeatedInt32 = new int[] {30};
+    MessageNano.mergeFrom(firstContainer, MessageNano.toByteArray(secondContainer));
+    assertEquals(3, firstContainer.contained.repeatedInt32.length);
+    assertEquals(20, firstContainer.contained.repeatedInt32[1]);
+    assertEquals(30, firstContainer.contained.repeatedInt32[2]);
+  }
+
+  public void testRepeatedPackables() throws Exception {
+    // Check that repeated fields with packable types can accept both packed and unpacked
+    // serialized forms.
+    NanoRepeatedPackables.NonPacked nonPacked = new NanoRepeatedPackables.NonPacked();
+    // Exaggerates the first values of varint-typed arrays. This is to test that the parsing code
+    // of packed fields handles non-packed data correctly. If the code incorrectly thinks it is
+    // reading from a packed tag, it will read the first value as the byte length of the field,
+    // and the large number will cause the input to go out of bounds, thus capturing the error.
+    nonPacked.int32S = new int[] {1000, 2, 3};
+    nonPacked.int64S = new long[] {4000, 5, 6};
+    nonPacked.uint32S = new int[] {7000, 8, 9};
+    nonPacked.uint64S = new long[] {10000, 11, 12};
+    nonPacked.sint32S = new int[] {13000, 14, 15};
+    nonPacked.sint64S = new long[] {16000, 17, 18};
+    nonPacked.fixed32S = new int[] {19, 20, 21};
+    nonPacked.fixed64S = new long[] {22, 23, 24};
+    nonPacked.sfixed32S = new int[] {25, 26, 27};
+    nonPacked.sfixed64S = new long[] {28, 29, 30};
+    nonPacked.floats = new float[] {31, 32, 33};
+    nonPacked.doubles = new double[] {34, 35, 36};
+    nonPacked.bools = new boolean[] {false, true};
+    nonPacked.enums = new int[] {
+      NanoRepeatedPackables.Enum.OPTION_ONE,
+      NanoRepeatedPackables.Enum.OPTION_TWO,
+    };
+    nonPacked.noise = 13579;
+
+    byte[] nonPackedSerialized = MessageNano.toByteArray(nonPacked);
+
+    NanoRepeatedPackables.Packed packed =
+        MessageNano.mergeFrom(new NanoRepeatedPackables.Packed(), nonPackedSerialized);
+    assertRepeatedPackablesEqual(nonPacked, packed);
+
+    byte[] packedSerialized = MessageNano.toByteArray(packed);
+    // Just a cautious check that the two serialized forms are different,
+    // to make sure the remaining of this test is useful:
+    assertFalse(Arrays.equals(nonPackedSerialized, packedSerialized));
+
+    nonPacked = MessageNano.mergeFrom(new NanoRepeatedPackables.NonPacked(), packedSerialized);
+    assertRepeatedPackablesEqual(nonPacked, packed);
+
+    // Test mixed serialized form.
+    byte[] mixedSerialized = new byte[nonPackedSerialized.length + packedSerialized.length];
+    System.arraycopy(nonPackedSerialized, 0, mixedSerialized, 0, nonPackedSerialized.length);
+    System.arraycopy(packedSerialized, 0,
+        mixedSerialized, nonPackedSerialized.length, packedSerialized.length);
+
+    nonPacked = MessageNano.mergeFrom(new NanoRepeatedPackables.NonPacked(), mixedSerialized);
+    packed = MessageNano.mergeFrom(new NanoRepeatedPackables.Packed(), mixedSerialized);
+    assertRepeatedPackablesEqual(nonPacked, packed);
+    assertTrue(Arrays.equals(new int[] {1000, 2, 3, 1000, 2, 3}, nonPacked.int32S));
+    assertTrue(Arrays.equals(new int[] {13000, 14, 15, 13000, 14, 15}, nonPacked.sint32S));
+    assertTrue(Arrays.equals(new int[] {25, 26, 27, 25, 26, 27}, nonPacked.sfixed32S));
+    assertTrue(Arrays.equals(new boolean[] {false, true, false, true}, nonPacked.bools));
+  }
+
+  public void testRepeatedFieldInitializedInReftypesCompatMode() {
+    NanoReferenceTypesCompat.TestAllTypesNano proto = new NanoReferenceTypesCompat.TestAllTypesNano();
+    assertNotNull(proto.repeatedString);
+  }
+
+  private void assertRepeatedPackablesEqual(
+      NanoRepeatedPackables.NonPacked nonPacked, NanoRepeatedPackables.Packed packed) {
+    // Not using MessageNano.equals() -- that belongs to a separate test.
+    assertTrue(Arrays.equals(nonPacked.int32S, packed.int32S));
+    assertTrue(Arrays.equals(nonPacked.int64S, packed.int64S));
+    assertTrue(Arrays.equals(nonPacked.uint32S, packed.uint32S));
+    assertTrue(Arrays.equals(nonPacked.uint64S, packed.uint64S));
+    assertTrue(Arrays.equals(nonPacked.sint32S, packed.sint32S));
+    assertTrue(Arrays.equals(nonPacked.sint64S, packed.sint64S));
+    assertTrue(Arrays.equals(nonPacked.fixed32S, packed.fixed32S));
+    assertTrue(Arrays.equals(nonPacked.fixed64S, packed.fixed64S));
+    assertTrue(Arrays.equals(nonPacked.sfixed32S, packed.sfixed32S));
+    assertTrue(Arrays.equals(nonPacked.sfixed64S, packed.sfixed64S));
+    assertTrue(Arrays.equals(nonPacked.floats, packed.floats));
+    assertTrue(Arrays.equals(nonPacked.doubles, packed.doubles));
+    assertTrue(Arrays.equals(nonPacked.bools, packed.bools));
+    assertTrue(Arrays.equals(nonPacked.enums, packed.enums));
+  }
+
+  public void testClone() throws Exception {
+    // A simple message.
+    AnotherMessage anotherMessage = new AnotherMessage();
+    anotherMessage.string = "Hello";
+    anotherMessage.value = true;
+    anotherMessage.integers = new int[] { 1, 2, 3 };
+
+    AnotherMessage clone = anotherMessage.clone();
+    assertEquals(clone, anotherMessage);
+
+    // Verify it was a deep clone - changes to the clone shouldn't affect the
+    // original.
+    clone.integers[1] = 100;
+    assertFalse(clone.equals(anotherMessage));
+  }
+
+  public void testBytesOffsetLength() throws Exception {
+    BytesOffsetLengthTestNano msg = new BytesOffsetLengthTestNano();
+    msg.fooBuffer = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+    msg.fooOffset = 2;
+    msg.fooLength = 3;
+    msg.barBuffer = msg.fooBuffer;
+    msg.barOffset = 7;
+    msg.barLength = 1;
+
+    byte[] bytes = MessageNano.toByteArray(msg);
+    // Two tags + two lengths + the arrays
+    assertEquals("Unexpected size of encoded proto", 8, bytes.length);
+
+    msg = BytesOffsetLengthTestNano.parseFrom(bytes);
+    byte[] foo = new byte[msg.fooLength];
+    System.arraycopy(msg.fooBuffer, msg.fooOffset, foo, 0, msg.fooLength);
+    assertTrue("foo was not deserialized correctly", Arrays.equals(new byte[] { 2, 3, 4 }, foo));
+    byte[] bar = new byte[msg.barLength];
+    System.arraycopy(msg.barBuffer, msg.barOffset, bar, 0, msg.barLength);
+    assertTrue("bar was not deserialized correctly", Arrays.equals(new byte[] { 7 }, bar));
+  }
+
+  public void testUnknownOptionalEnumValue() throws Exception {
+    StandardVersion standardMsg = new StandardVersion();
+    standardMsg.optionalField = StandardVersion.VAL_3;
+    byte[] standardMsgBytes = MessageNano.toByteArray(standardMsg);
+
+    // When parsing and reading, the unknown value appears as UNKNOWN.
+    VersionWithoutVal3 withoutVal3Msg = new VersionWithoutVal3();
+    MessageNano.mergeFrom(withoutVal3Msg, standardMsgBytes);
+    assertEquals(VersionWithoutVal3.UNKNOWN, withoutVal3Msg.optionalField);
+
+    // When serializing and reparsing as the standard version, the old, unknown value wins out (even
+    // if a new one is set).
+    withoutVal3Msg.optionalField = VersionWithoutVal3.VAL_2;
+    byte[] withoutVal3MsgBytes = MessageNano.toByteArray(withoutVal3Msg);
+    StandardVersion standardMsgFromWithoutVal3Msg = new StandardVersion();
+    MessageNano.mergeFrom(standardMsgFromWithoutVal3Msg, withoutVal3MsgBytes);
+    assertEquals(StandardVersion.VAL_3, standardMsgFromWithoutVal3Msg.optionalField);
+  }
+
+  public void testUnknownRepeatedEnumValue() throws Exception {
+    StandardVersion standardMsg = new StandardVersion();
+    standardMsg.repeatedField = new int[] { StandardVersion.VAL_3, StandardVersion.VAL_2 };
+    byte[] standardMsgBytes = MessageNano.toByteArray(standardMsg);
+
+    // When parsing and reading, the unknown value is stripped out.
+    VersionWithoutVal3 withoutVal3Msg = new VersionWithoutVal3();
+    MessageNano.mergeFrom(withoutVal3Msg, standardMsgBytes);
+    assertTrue(Arrays.equals(new int[] { VersionWithoutVal3.VAL_2 }, withoutVal3Msg.repeatedField));
+
+    // When serializing and reparsing as the standard version, the old, unknown value reappears, but
+    // at the end of all entries (including any newly added ones).
+    withoutVal3Msg.repeatedField = new int[] { VersionWithoutVal3.VAL_2, VersionWithoutVal3.VAL_1 };
+    byte[] withoutVal3MsgBytes = MessageNano.toByteArray(withoutVal3Msg);
+    StandardVersion standardMsgFromWithoutVal3Msg = new StandardVersion();
+    MessageNano.mergeFrom(standardMsgFromWithoutVal3Msg, withoutVal3MsgBytes);
+    assertTrue(Arrays.equals(
+            new int[] { StandardVersion.VAL_2, StandardVersion.VAL_1, StandardVersion.VAL_3 },
+            standardMsgFromWithoutVal3Msg.repeatedField));
+  }
+
+  public void testUnknownRepeatedPackedEnumValue() throws Exception {
+    StandardVersion standardMsg = new StandardVersion();
+    standardMsg.packedField = new int[] { StandardVersion.VAL_3, StandardVersion.VAL_2 };
+    byte[] standardMsgBytes = MessageNano.toByteArray(standardMsg);
+
+    // When parsing and reading, the unknown value is stripped out.
+    VersionWithoutVal3 withoutVal3Msg = new VersionWithoutVal3();
+    MessageNano.mergeFrom(withoutVal3Msg, standardMsgBytes);
+    assertTrue(Arrays.equals(new int[] { VersionWithoutVal3.VAL_2 }, withoutVal3Msg.packedField));
+
+    // When serializing and reparsing as the standard version, the old, unknown value reappears, but
+    // at the end of all entries (including any newly added ones).
+    withoutVal3Msg.packedField = new int[] { VersionWithoutVal3.VAL_2, VersionWithoutVal3.VAL_1 };
+    byte[] withoutVal3MsgBytes = MessageNano.toByteArray(withoutVal3Msg);
+    StandardVersion standardMsgFromWithoutVal3Msg = new StandardVersion();
+    MessageNano.mergeFrom(standardMsgFromWithoutVal3Msg, withoutVal3MsgBytes);
+    assertTrue(Arrays.equals(
+            new int[] { StandardVersion.VAL_2, StandardVersion.VAL_1, StandardVersion.VAL_3 },
+            standardMsgFromWithoutVal3Msg.packedField));
+  }
+
+  private void assertHasWireData(MessageNano message, boolean expected) {
+    byte[] bytes = MessageNano.toByteArray(message);
+    int wireLength = bytes.length;
+    if (expected) {
+      assertFalse(wireLength == 0);
+    } else {
+      if (wireLength != 0) {
+        fail("Expected no wire data for message \n" + message
+            + "\nBut got:\n"
+            + hexDump(bytes));
+      }
+    }
+  }
+
+  private static String hexDump(byte[] bytes) {
+    StringBuilder sb = new StringBuilder();
+    for (byte b : bytes) {
+      sb.append(String.format("%02x ", b));
+    }
+    return sb.toString();
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/NestedBuildersTest.java b/protobuf/java/src/test/java/com/google/protobuf/NestedBuildersTest.java
new file mode 100644
index 0000000..2365312
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/NestedBuildersTest.java
@@ -0,0 +1,185 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.Vehicle;
+import protobuf_unittest.Wheel;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Test cases that exercise end-to-end use cases involving
+ * {@link SingleFieldBuilder} and {@link RepeatedFieldBuilder}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class NestedBuildersTest extends TestCase {
+
+  public void testMessagesAndBuilders() {
+    Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+    vehicleBuilder.addWheelBuilder()
+        .setRadius(4)
+        .setWidth(1);
+    vehicleBuilder.addWheelBuilder()
+        .setRadius(4)
+        .setWidth(2);
+    vehicleBuilder.addWheelBuilder()
+        .setRadius(4)
+        .setWidth(3);
+    vehicleBuilder.addWheelBuilder()
+        .setRadius(4)
+        .setWidth(4);
+    vehicleBuilder.getEngineBuilder()
+        .setLiters(10);
+
+    Vehicle vehicle = vehicleBuilder.build();
+    assertEquals(4, vehicle.getWheelCount());
+    for (int i = 0; i < 4; i++) {
+      Wheel wheel = vehicle.getWheel(i);
+      assertEquals(4, wheel.getRadius());
+      assertEquals(i + 1, wheel.getWidth());
+    }
+    assertEquals(10, vehicle.getEngine().getLiters());
+
+    for (int i = 0; i < 4; i++) {
+      vehicleBuilder.getWheelBuilder(i)
+          .setRadius(5)
+          .setWidth(i + 10);
+    }
+    vehicleBuilder.getEngineBuilder().setLiters(20);
+
+    vehicle = vehicleBuilder.build();
+    for (int i = 0; i < 4; i++) {
+      Wheel wheel = vehicle.getWheel(i);
+      assertEquals(5, wheel.getRadius());
+      assertEquals(i + 10, wheel.getWidth());
+    }
+    assertEquals(20, vehicle.getEngine().getLiters());
+    assertTrue(vehicle.hasEngine());
+  }
+
+  public void testMessagesAreCached() {
+    Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+    vehicleBuilder.addWheelBuilder()
+        .setRadius(1)
+        .setWidth(2);
+    vehicleBuilder.addWheelBuilder()
+        .setRadius(3)
+        .setWidth(4);
+    vehicleBuilder.addWheelBuilder()
+        .setRadius(5)
+        .setWidth(6);
+    vehicleBuilder.addWheelBuilder()
+        .setRadius(7)
+        .setWidth(8);
+
+    // Make sure messages are cached.
+    List<Wheel> wheels = new ArrayList<Wheel>(vehicleBuilder.getWheelList());
+    for (int i = 0; i < wheels.size(); i++) {
+      assertSame(wheels.get(i), vehicleBuilder.getWheel(i));
+    }
+
+    // Now get builders and check they didn't change.
+    for (int i = 0; i < wheels.size(); i++) {
+      vehicleBuilder.getWheel(i);
+    }
+    for (int i = 0; i < wheels.size(); i++) {
+      assertSame(wheels.get(i), vehicleBuilder.getWheel(i));
+    }
+
+    // Change just one
+    vehicleBuilder.getWheelBuilder(3)
+        .setRadius(20).setWidth(20);
+
+    // Now get wheels and check that only that one changed
+    for (int i = 0; i < wheels.size(); i++) {
+      if (i < 3) {
+        assertSame(wheels.get(i), vehicleBuilder.getWheel(i));
+      } else {
+        assertNotSame(wheels.get(i), vehicleBuilder.getWheel(i));
+      }
+    }
+  }
+
+  public void testRemove_WithNestedBuilders() {
+    Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+    vehicleBuilder.addWheelBuilder()
+        .setRadius(1)
+        .setWidth(1);
+    vehicleBuilder.addWheelBuilder()
+        .setRadius(2)
+        .setWidth(2);
+    vehicleBuilder.removeWheel(0);
+
+    assertEquals(1, vehicleBuilder.getWheelCount());
+    assertEquals(2, vehicleBuilder.getWheel(0).getRadius());
+  }
+
+  public void testRemove_WithNestedMessages() {
+    Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+    vehicleBuilder.addWheel(Wheel.newBuilder()
+        .setRadius(1)
+        .setWidth(1));
+    vehicleBuilder.addWheel(Wheel.newBuilder()
+        .setRadius(2)
+        .setWidth(2));
+    vehicleBuilder.removeWheel(0);
+
+    assertEquals(1, vehicleBuilder.getWheelCount());
+    assertEquals(2, vehicleBuilder.getWheel(0).getRadius());
+  }
+
+  public void testMerge() {
+    Vehicle vehicle1 = Vehicle.newBuilder()
+        .addWheel(Wheel.newBuilder().setRadius(1).build())
+        .addWheel(Wheel.newBuilder().setRadius(2).build())
+        .build();
+
+    Vehicle vehicle2 = Vehicle.newBuilder()
+        .mergeFrom(vehicle1)
+        .build();
+    // List should be the same -- no allocation
+    assertSame(vehicle1.getWheelList(), vehicle2.getWheelList());
+
+    Vehicle vehicle3 = vehicle1.toBuilder().build();
+    assertSame(vehicle1.getWheelList(), vehicle3.getWheelList());
+  }
+
+  public void testGettingBuilderMarksFieldAsHaving() {
+    Vehicle.Builder vehicleBuilder = Vehicle.newBuilder();
+    vehicleBuilder.getEngineBuilder();
+    Vehicle vehicle = vehicleBuilder.buildPartial();
+    assertTrue(vehicle.hasEngine());
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/ParserTest.java b/protobuf/java/src/test/java/com/google/protobuf/ParserTest.java
new file mode 100644
index 0000000..b11d8cb
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/ParserTest.java
@@ -0,0 +1,381 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.UnittestLite.TestAllTypesLite;
+import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+import com.google.protobuf.UnittestLite.TestParsingMergeLite;
+import protobuf_unittest.UnittestOptimizeFor.TestOptimizedForSize;
+import protobuf_unittest.UnittestOptimizeFor.TestRequiredOptimizedForSize;
+import protobuf_unittest.UnittestOptimizeFor;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestEmptyMessage;
+import protobuf_unittest.UnittestProto.TestParsingMerge;
+import protobuf_unittest.UnittestProto.TestRequired;
+import protobuf_unittest.UnittestProto;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Unit test for {@link Parser}.
+ *
+ * @author liujisi@google.com (Pherl Liu)
+ */
+public class ParserTest extends TestCase {
+  public void testGeneratedMessageParserSingleton() throws Exception {
+    for (int i = 0; i < 10; i++) {
+      assertEquals(TestAllTypes.PARSER,
+                   TestUtil.getAllSet().getParserForType());
+    }
+  }
+
+  private void assertRoundTripEquals(MessageLite message,
+                                     ExtensionRegistryLite registry)
+      throws Exception {
+    final byte[] data = message.toByteArray();
+    final int offset = 20;
+    final int length = data.length;
+    final int padding = 30;
+    Parser<? extends MessageLite> parser = message.getParserForType();
+    assertMessageEquals(message, parser.parseFrom(data, registry));
+    assertMessageEquals(message, parser.parseFrom(
+        generatePaddingArray(data, offset, padding),
+        offset, length, registry));
+    assertMessageEquals(message, parser.parseFrom(
+        message.toByteString(), registry));
+    assertMessageEquals(message, parser.parseFrom(
+        new ByteArrayInputStream(data), registry));
+    assertMessageEquals(message, parser.parseFrom(
+        CodedInputStream.newInstance(data), registry));
+  }
+
+  @SuppressWarnings("unchecked")
+  private void assertRoundTripEquals(MessageLite message) throws Exception {
+    final byte[] data = message.toByteArray();
+    final int offset = 20;
+    final int length = data.length;
+    final int padding = 30;
+
+    Parser<MessageLite> parser =
+        (Parser<MessageLite>) message.getParserForType();
+    assertMessageEquals(message, parser.parseFrom(data));
+    assertMessageEquals(message, parser.parseFrom(
+        generatePaddingArray(data, offset, padding),
+        offset, length));
+    assertMessageEquals(message, parser.parseFrom(message.toByteString()));
+    assertMessageEquals(message, parser.parseFrom(
+        new ByteArrayInputStream(data)));
+    assertMessageEquals(message, parser.parseFrom(
+        CodedInputStream.newInstance(data)));
+  }
+
+  private void assertMessageEquals(
+      MessageLite expected, MessageLite actual)
+      throws Exception {
+    if (expected instanceof Message) {
+      assertEquals(expected, actual);
+    } else {
+      assertEquals(expected.toByteString(), actual.toByteString());
+    }
+  }
+
+  private byte[] generatePaddingArray(byte[] data, int offset, int padding) {
+    byte[] result = new byte[offset + data.length + padding];
+    System.arraycopy(data, 0, result, offset, data.length);
+    return result;
+  }
+
+  public void testNormalMessage() throws Exception {
+    assertRoundTripEquals(TestUtil.getAllSet());
+  }
+
+
+  public void testParsePartial() throws Exception {
+    assertParsePartial(TestRequired.PARSER,
+        TestRequired.newBuilder().setA(1).buildPartial());
+  }
+
+  private <T extends MessageLite> void assertParsePartial(
+      Parser<T> parser, T partialMessage) throws Exception {
+    final String errorString =
+        "Should throw exceptions when the parsed message isn't initialized.";
+
+    // parsePartialFrom should pass.
+    byte[] data = partialMessage.toByteArray();
+    assertEquals(partialMessage, parser.parsePartialFrom(data));
+    assertEquals(partialMessage, parser.parsePartialFrom(
+        partialMessage.toByteString()));
+    assertEquals(partialMessage, parser.parsePartialFrom(
+        new ByteArrayInputStream(data)));
+    assertEquals(partialMessage, parser.parsePartialFrom(
+        CodedInputStream.newInstance(data)));
+
+    // parseFrom(ByteArray)
+    try {
+      parser.parseFrom(partialMessage.toByteArray());
+      fail(errorString);
+    } catch (InvalidProtocolBufferException e) {
+      // pass.
+    }
+
+    // parseFrom(ByteString)
+    try {
+      parser.parseFrom(partialMessage.toByteString());
+      fail(errorString);
+    } catch (InvalidProtocolBufferException e) {
+      // pass.
+    }
+
+    // parseFrom(InputStream)
+    try {
+      parser.parseFrom(new ByteArrayInputStream(partialMessage.toByteArray()));
+      fail(errorString);
+    } catch (IOException e) {
+      // pass.
+    }
+
+    // parseFrom(CodedInputStream)
+    try {
+      parser.parseFrom(CodedInputStream.newInstance(
+          partialMessage.toByteArray()));
+      fail(errorString);
+    } catch (IOException e) {
+      // pass.
+    }
+  }
+
+  public void testParseExtensions() throws Exception {
+    assertRoundTripEquals(TestUtil.getAllExtensionsSet(),
+                          TestUtil.getExtensionRegistry());
+    assertRoundTripEquals(TestUtil.getAllLiteExtensionsSet(),
+                          TestUtil.getExtensionRegistryLite());
+  }
+
+  public void testParsePacked() throws Exception {
+    assertRoundTripEquals(TestUtil.getPackedSet());
+    assertRoundTripEquals(TestUtil.getPackedExtensionsSet(),
+                          TestUtil.getExtensionRegistry());
+    assertRoundTripEquals(TestUtil.getLitePackedExtensionsSet(),
+                          TestUtil.getExtensionRegistryLite());
+  }
+
+  public void testParseDelimitedTo() throws Exception {
+    // Write normal Message.
+    TestAllTypes normalMessage = TestUtil.getAllSet();
+    ByteArrayOutputStream output = new ByteArrayOutputStream();
+    normalMessage.writeDelimitedTo(output);
+
+    // Write MessageLite with packed extension fields.
+    TestPackedExtensionsLite packedMessage =
+        TestUtil.getLitePackedExtensionsSet();
+    packedMessage.writeDelimitedTo(output);
+
+    InputStream input = new ByteArrayInputStream(output.toByteArray());
+    assertMessageEquals(
+        normalMessage,
+        normalMessage.getParserForType().parseDelimitedFrom(input));
+    assertMessageEquals(
+        packedMessage,
+        packedMessage.getParserForType().parseDelimitedFrom(
+            input, TestUtil.getExtensionRegistryLite()));
+  }
+
+  public void testParseUnknownFields() throws Exception {
+    // All fields will be treated as unknown fields in emptyMessage.
+    TestEmptyMessage emptyMessage = TestEmptyMessage.PARSER.parseFrom(
+        TestUtil.getAllSet().toByteString());
+    assertEquals(
+        TestUtil.getAllSet().toByteString(),
+        emptyMessage.toByteString());
+  }
+
+
+  public void testOptimizeForSize() throws Exception {
+    TestOptimizedForSize.Builder builder = TestOptimizedForSize.newBuilder();
+    builder.setI(12).setMsg(ForeignMessage.newBuilder().setC(34).build());
+    builder.setExtension(TestOptimizedForSize.testExtension, 56);
+    builder.setExtension(TestOptimizedForSize.testExtension2,
+        TestRequiredOptimizedForSize.newBuilder().setX(78).build());
+
+    TestOptimizedForSize message = builder.build();
+    ExtensionRegistry registry = ExtensionRegistry.newInstance();
+    UnittestOptimizeFor.registerAllExtensions(registry);
+
+    assertRoundTripEquals(message, registry);
+  }
+
+  /** Helper method for {@link #testParsingMerge()}.*/
+  private void assertMessageMerged(TestAllTypes allTypes)
+      throws Exception {
+    assertEquals(3, allTypes.getOptionalInt32());
+    assertEquals(2, allTypes.getOptionalInt64());
+    assertEquals("hello", allTypes.getOptionalString());
+  }
+
+  /** Helper method for {@link #testParsingMergeLite()}.*/
+  private void assertMessageMerged(TestAllTypesLite allTypes)
+      throws Exception {
+    assertEquals(3, allTypes.getOptionalInt32());
+    assertEquals(2, allTypes.getOptionalInt64());
+    assertEquals("hello", allTypes.getOptionalString());
+  }
+
+  public void testParsingMerge() throws Exception {
+    // Build messages.
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TestAllTypes msg1 = builder.setOptionalInt32(1).build();
+    builder.clear();
+    TestAllTypes msg2 = builder.setOptionalInt64(2).build();
+    builder.clear();
+    TestAllTypes msg3 = builder.setOptionalInt32(3)
+        .setOptionalString("hello").build();
+
+    // Build groups.
+    TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG1 =
+        TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
+        .setField1(msg1).build();
+    TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG2 =
+        TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
+        .setField1(msg2).build();
+    TestParsingMerge.RepeatedFieldsGenerator.Group1 optionalG3 =
+        TestParsingMerge.RepeatedFieldsGenerator.Group1.newBuilder()
+        .setField1(msg3).build();
+    TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG1 =
+        TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
+        .setField1(msg1).build();
+    TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG2 =
+        TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
+        .setField1(msg2).build();
+    TestParsingMerge.RepeatedFieldsGenerator.Group2 repeatedG3 =
+        TestParsingMerge.RepeatedFieldsGenerator.Group2.newBuilder()
+        .setField1(msg3).build();
+
+    // Assign and serialize RepeatedFieldsGenerator.
+    ByteString data = TestParsingMerge.RepeatedFieldsGenerator.newBuilder()
+        .addField1(msg1).addField1(msg2).addField1(msg3)
+        .addField2(msg1).addField2(msg2).addField2(msg3)
+        .addField3(msg1).addField3(msg2).addField3(msg3)
+        .addGroup1(optionalG1).addGroup1(optionalG2).addGroup1(optionalG3)
+        .addGroup2(repeatedG1).addGroup2(repeatedG2).addGroup2(repeatedG3)
+        .addExt1(msg1).addExt1(msg2).addExt1(msg3)
+        .addExt2(msg1).addExt2(msg2).addExt2(msg3)
+        .build().toByteString();
+
+    // Parse TestParsingMerge.
+    ExtensionRegistry registry = ExtensionRegistry.newInstance();
+    UnittestProto.registerAllExtensions(registry);
+    TestParsingMerge parsingMerge =
+        TestParsingMerge.PARSER.parseFrom(data, registry);
+
+    // Required and optional fields should be merged.
+    assertMessageMerged(parsingMerge.getRequiredAllTypes());
+    assertMessageMerged(parsingMerge.getOptionalAllTypes());
+    assertMessageMerged(
+        parsingMerge.getOptionalGroup().getOptionalGroupAllTypes());
+    assertMessageMerged(parsingMerge.getExtension(
+        TestParsingMerge.optionalExt));
+
+    // Repeated fields should not be merged.
+    assertEquals(3, parsingMerge.getRepeatedAllTypesCount());
+    assertEquals(3, parsingMerge.getRepeatedGroupCount());
+    assertEquals(3, parsingMerge.getExtensionCount(
+        TestParsingMerge.repeatedExt));
+  }
+
+  public void testParsingMergeLite() throws Exception {
+    // Build messages.
+    TestAllTypesLite.Builder builder =
+        TestAllTypesLite.newBuilder();
+    TestAllTypesLite msg1 = builder.setOptionalInt32(1).build();
+    builder.clear();
+    TestAllTypesLite msg2 = builder.setOptionalInt64(2).build();
+    builder.clear();
+    TestAllTypesLite msg3 = builder.setOptionalInt32(3)
+        .setOptionalString("hello").build();
+
+    // Build groups.
+    TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG1 =
+        TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()
+        .setField1(msg1).build();
+    TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG2 =
+        TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()
+        .setField1(msg2).build();
+    TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG3 =
+        TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder()
+        .setField1(msg3).build();
+    TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG1 =
+        TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()
+        .setField1(msg1).build();
+    TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG2 =
+        TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()
+        .setField1(msg2).build();
+    TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG3 =
+        TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder()
+        .setField1(msg3).build();
+
+    // Assign and serialize RepeatedFieldsGenerator.
+    ByteString data = TestParsingMergeLite.RepeatedFieldsGenerator.newBuilder()
+        .addField1(msg1).addField1(msg2).addField1(msg3)
+        .addField2(msg1).addField2(msg2).addField2(msg3)
+        .addField3(msg1).addField3(msg2).addField3(msg3)
+        .addGroup1(optionalG1).addGroup1(optionalG2).addGroup1(optionalG3)
+        .addGroup2(repeatedG1).addGroup2(repeatedG2).addGroup2(repeatedG3)
+        .addExt1(msg1).addExt1(msg2).addExt1(msg3)
+        .addExt2(msg1).addExt2(msg2).addExt2(msg3)
+        .build().toByteString();
+
+    // Parse TestParsingMergeLite.
+    ExtensionRegistry registry = ExtensionRegistry.newInstance();
+    UnittestLite.registerAllExtensions(registry);
+    TestParsingMergeLite parsingMerge =
+        TestParsingMergeLite.PARSER.parseFrom(data, registry);
+
+    // Required and optional fields should be merged.
+    assertMessageMerged(parsingMerge.getRequiredAllTypes());
+    assertMessageMerged(parsingMerge.getOptionalAllTypes());
+    assertMessageMerged(
+        parsingMerge.getOptionalGroup().getOptionalGroupAllTypes());
+    assertMessageMerged(parsingMerge.getExtension(
+        TestParsingMergeLite.optionalExt));
+
+    // Repeated fields should not be merged.
+    assertEquals(3, parsingMerge.getRepeatedAllTypesCount());
+    assertEquals(3, parsingMerge.getRepeatedGroupCount());
+    assertEquals(3, parsingMerge.getExtensionCount(
+        TestParsingMergeLite.repeatedExt));
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java b/protobuf/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java
new file mode 100644
index 0000000..49d5232
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/RepeatedFieldBuilderTest.java
@@ -0,0 +1,190 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+
+import junit.framework.TestCase;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Tests for {@link RepeatedFieldBuilder}. This tests basic functionality.
+ * More extensive testing is provided via other tests that exercise the
+ * builder.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class RepeatedFieldBuilderTest extends TestCase {
+
+  public void testBasicUse() {
+    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+    RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+        TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+    builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+    builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+    assertEquals(0, builder.getMessage(0).getOptionalInt32());
+    assertEquals(1, builder.getMessage(1).getOptionalInt32());
+
+    List<TestAllTypes> list = builder.build();
+    assertEquals(2, list.size());
+    assertEquals(0, list.get(0).getOptionalInt32());
+    assertEquals(1, list.get(1).getOptionalInt32());
+    assertIsUnmodifiable(list);
+
+    // Make sure it doesn't change.
+    List<TestAllTypes> list2 = builder.build();
+    assertSame(list, list2);
+    assertEquals(0, mockParent.getInvalidationCount());
+  }
+
+  public void testGoingBackAndForth() {
+    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+    RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+        TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+    builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+    builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+    assertEquals(0, builder.getMessage(0).getOptionalInt32());
+    assertEquals(1, builder.getMessage(1).getOptionalInt32());
+
+    // Convert to list
+    List<TestAllTypes> list = builder.build();
+    assertEquals(2, list.size());
+    assertEquals(0, list.get(0).getOptionalInt32());
+    assertEquals(1, list.get(1).getOptionalInt32());
+    assertIsUnmodifiable(list);
+
+    // Update 0th item
+    assertEquals(0, mockParent.getInvalidationCount());
+    builder.getBuilder(0).setOptionalString("foo");
+    assertEquals(1, mockParent.getInvalidationCount());
+    list = builder.build();
+    assertEquals(2, list.size());
+    assertEquals(0, list.get(0).getOptionalInt32());
+      assertEquals("foo", list.get(0).getOptionalString());
+    assertEquals(1, list.get(1).getOptionalInt32());
+    assertIsUnmodifiable(list);
+    assertEquals(1, mockParent.getInvalidationCount());
+  }
+
+  public void testVariousMethods() {
+    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+    RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+        TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+    builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+    builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(2).build());
+    builder.addBuilder(0, TestAllTypes.getDefaultInstance())
+        .setOptionalInt32(0);
+    builder.addBuilder(TestAllTypes.getDefaultInstance()).setOptionalInt32(3);
+
+    assertEquals(0, builder.getMessage(0).getOptionalInt32());
+    assertEquals(1, builder.getMessage(1).getOptionalInt32());
+    assertEquals(2, builder.getMessage(2).getOptionalInt32());
+    assertEquals(3, builder.getMessage(3).getOptionalInt32());
+
+    assertEquals(0, mockParent.getInvalidationCount());
+    List<TestAllTypes> messages = builder.build();
+    assertEquals(4, messages.size());
+    assertSame(messages, builder.build()); // expect same list
+
+    // Remove a message.
+    builder.remove(2);
+    assertEquals(1, mockParent.getInvalidationCount());
+    assertEquals(3, builder.getCount());
+    assertEquals(0, builder.getMessage(0).getOptionalInt32());
+    assertEquals(1, builder.getMessage(1).getOptionalInt32());
+    assertEquals(3, builder.getMessage(2).getOptionalInt32());
+
+    // Remove a builder.
+    builder.remove(0);
+    assertEquals(1, mockParent.getInvalidationCount());
+    assertEquals(2, builder.getCount());
+    assertEquals(1, builder.getMessage(0).getOptionalInt32());
+    assertEquals(3, builder.getMessage(1).getOptionalInt32());
+
+    // Test clear.
+    builder.clear();
+    assertEquals(1, mockParent.getInvalidationCount());
+    assertEquals(0, builder.getCount());
+    assertTrue(builder.isEmpty());
+  }
+
+  public void testLists() {
+    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+    RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+        TestAllTypesOrBuilder> builder = newRepeatedFieldBuilder(mockParent);
+    builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(1).build());
+    builder.addMessage(0,
+        TestAllTypes.newBuilder().setOptionalInt32(0).build());
+    assertEquals(0, builder.getMessage(0).getOptionalInt32());
+    assertEquals(1, builder.getMessage(1).getOptionalInt32());
+
+    // Use list of builders.
+    List<TestAllTypes.Builder> builders = builder.getBuilderList();
+    assertEquals(0, builders.get(0).getOptionalInt32());
+    assertEquals(1, builders.get(1).getOptionalInt32());
+    builders.get(0).setOptionalInt32(10);
+    builders.get(1).setOptionalInt32(11);
+
+    // Use list of protos
+    List<TestAllTypes> protos = builder.getMessageList();
+    assertEquals(10, protos.get(0).getOptionalInt32());
+    assertEquals(11, protos.get(1).getOptionalInt32());
+
+    // Add an item to the builders and verify it's updated in both
+    builder.addMessage(TestAllTypes.newBuilder().setOptionalInt32(12).build());
+    assertEquals(3, builders.size());
+    assertEquals(3, protos.size());
+  }
+
+  private void assertIsUnmodifiable(List<?> list) {
+    if (list == Collections.emptyList()) {
+      // OKAY -- Need to check this b/c EmptyList allows you to call clear.
+    } else {
+      try {
+        list.clear();
+        fail("List wasn't immutable");
+      } catch (UnsupportedOperationException e) {
+        // good
+      }
+    }
+  }
+
+  private RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+      TestAllTypesOrBuilder>
+      newRepeatedFieldBuilder(GeneratedMessage.BuilderParent parent) {
+    return new RepeatedFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+        TestAllTypesOrBuilder>(Collections.<TestAllTypes>emptyList(), false,
+        parent, false);
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java b/protobuf/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java
new file mode 100644
index 0000000..212f8d6
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java
@@ -0,0 +1,97 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+
+/**
+ * This class tests {@link RopeByteString#substring(int, int)} by inheriting the tests from
+ * {@link LiteralByteStringTest}.  Only a couple of methods are overridden.  
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+public class RopeByteStringSubstringTest extends LiteralByteStringTest {
+
+  @Override
+  protected void setUp() throws Exception {
+    classUnderTest = "RopeByteString";
+    byte[] sourceBytes = ByteStringTest.getTestBytes(22341, 22337766L);
+    Iterator<ByteString> iter = ByteStringTest.makeConcretePieces(sourceBytes).iterator();
+    ByteString sourceString = iter.next();
+    while (iter.hasNext()) {
+      sourceString = sourceString.concat(iter.next());
+    }
+
+    int from = 1130;
+    int to = sourceBytes.length - 5555;
+    stringUnderTest = sourceString.substring(from, to);
+    referenceBytes = new byte[to - from];
+    System.arraycopy(sourceBytes, from, referenceBytes, 0, to - from);
+    expectedHashCode = -1259260680;
+  }
+
+  @Override
+  public void testGetTreeDepth() {
+    assertEquals(classUnderTest + " must have the expected tree depth",
+        3, stringUnderTest.getTreeDepth());
+  }
+
+  @Override
+  public void testToString() throws UnsupportedEncodingException {
+    String sourceString = "I love unicode \u1234\u5678 characters";
+    ByteString sourceByteString = ByteString.copyFromUtf8(sourceString);
+    int copies = 250;
+
+    // By building the RopeByteString by concatenating, this is actually a fairly strenuous test.
+    StringBuilder builder = new StringBuilder(copies * sourceString.length());
+    ByteString unicode = ByteString.EMPTY;
+    for (int i = 0; i < copies; ++i) {
+      builder.append(sourceString);
+      unicode = RopeByteString.concatenate(unicode, sourceByteString);
+    }
+    String testString = builder.toString();
+
+    // Do the substring part
+    testString = testString.substring(2, testString.length() - 6);
+    unicode = unicode.substring(2, unicode.size() - 6);
+
+    assertEquals(classUnderTest + " from string must have the expected type",
+        classUnderTest, getActualClassName(unicode));
+    String roundTripString = unicode.toString(UTF_8);
+    assertEquals(classUnderTest + " unicode bytes must match",
+        testString, roundTripString);
+    ByteString flatString = ByteString.copyFromUtf8(testString);
+    assertEquals(classUnderTest + " string must equal the flat string", flatString, unicode);
+    assertEquals(classUnderTest + " string must must have same hashCode as the flat string",
+        flatString.hashCode(), unicode.hashCode());
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/RopeByteStringTest.java b/protobuf/java/src/test/java/com/google/protobuf/RopeByteStringTest.java
new file mode 100644
index 0000000..9676f52
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/RopeByteStringTest.java
@@ -0,0 +1,115 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+import java.util.Iterator;
+
+/**
+ * This class tests {@link RopeByteString} by inheriting the tests from
+ * {@link LiteralByteStringTest}.  Only a couple of methods are overridden.
+ * 
+ * <p>A full test of the result of {@link RopeByteString#substring(int, int)} is found in the
+ * separate class {@link RopeByteStringSubstringTest}.
+ *
+ * @author carlanton@google.com (Carl Haverl)
+ */
+public class RopeByteStringTest extends LiteralByteStringTest {
+
+  @Override
+  protected void setUp() throws Exception {
+    classUnderTest = "RopeByteString";
+    referenceBytes = ByteStringTest.getTestBytes(22341, 22337766L);
+    Iterator<ByteString> iter = ByteStringTest.makeConcretePieces(referenceBytes).iterator();
+    stringUnderTest = iter.next();
+    while (iter.hasNext()) {
+      stringUnderTest = stringUnderTest.concat(iter.next());
+    }
+    expectedHashCode = -1214197238;
+  }
+
+  @Override
+  public void testGetTreeDepth() {
+    assertEquals(classUnderTest + " must have the expected tree depth",
+        4, stringUnderTest.getTreeDepth());
+  }
+
+  public void testBalance() {
+    int numberOfPieces = 10000;
+    int pieceSize = 64;
+    byte[] testBytes = ByteStringTest.getTestBytes(numberOfPieces * pieceSize, 113377L);
+
+    // Build up a big ByteString from smaller pieces to force a rebalance
+    ByteString concatenated = ByteString.EMPTY;
+    for (int i = 0; i < numberOfPieces; ++i) {
+      concatenated = concatenated.concat(ByteString.copyFrom(testBytes, i * pieceSize, pieceSize));
+    }
+
+    assertEquals(classUnderTest + " from string must have the expected type",
+        classUnderTest, getActualClassName(concatenated));
+    assertTrue(classUnderTest + " underlying bytes must match after balancing",
+        Arrays.equals(testBytes, concatenated.toByteArray()));
+    ByteString testString = ByteString.copyFrom(testBytes);
+    assertTrue(classUnderTest + " balanced string must equal flat string",
+        concatenated.equals(testString));
+    assertTrue(classUnderTest + " flat string must equal balanced string",
+        testString.equals(concatenated));
+    assertEquals(classUnderTest + " balanced string must have same hash code as flat string",
+        testString.hashCode(), concatenated.hashCode());
+  }
+
+  @Override
+  public void testToString() throws UnsupportedEncodingException {
+    String sourceString = "I love unicode \u1234\u5678 characters";
+    ByteString sourceByteString = ByteString.copyFromUtf8(sourceString);
+    int copies = 250;
+
+    // By building the RopeByteString by concatenating, this is actually a fairly strenuous test.
+    StringBuilder builder = new StringBuilder(copies * sourceString.length());
+    ByteString unicode = ByteString.EMPTY;
+    for (int i = 0; i < copies; ++i) {
+      builder.append(sourceString);
+      unicode = RopeByteString.concatenate(unicode, sourceByteString);
+    }
+    String testString = builder.toString();
+
+    assertEquals(classUnderTest + " from string must have the expected type",
+        classUnderTest, getActualClassName(unicode));
+    String roundTripString = unicode.toString(UTF_8);
+    assertEquals(classUnderTest + " unicode bytes must match",
+        testString, roundTripString);
+    ByteString flatString = ByteString.copyFromUtf8(testString);
+    assertEquals(classUnderTest + " string must equal the flat string", flatString, unicode);
+    assertEquals(classUnderTest + " string must must have same hashCode as the flat string",
+        flatString.hashCode(), unicode.hashCode());
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/ServiceTest.java b/protobuf/java/src/test/java/com/google/protobuf/ServiceTest.java
new file mode 100644
index 0000000..ff980d6
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/ServiceTest.java
@@ -0,0 +1,320 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.FileDescriptor;
+import com.google.protobuf.Descriptors.MethodDescriptor;
+import google.protobuf.no_generic_services_test.UnittestNoGenericServices;
+import protobuf_unittest.MessageWithNoOuter;
+import protobuf_unittest.ServiceWithNoOuter;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestService;
+import protobuf_unittest.UnittestProto.FooRequest;
+import protobuf_unittest.UnittestProto.FooResponse;
+import protobuf_unittest.UnittestProto.BarRequest;
+import protobuf_unittest.UnittestProto.BarResponse;
+
+import org.easymock.classextension.EasyMock;
+import org.easymock.classextension.IMocksControl;
+import org.easymock.IArgumentMatcher;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests services and stubs.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public class ServiceTest extends TestCase {
+  private IMocksControl control;
+  private RpcController mockController;
+
+  private final Descriptors.MethodDescriptor fooDescriptor =
+    TestService.getDescriptor().getMethods().get(0);
+  private final Descriptors.MethodDescriptor barDescriptor =
+    TestService.getDescriptor().getMethods().get(1);
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    control = EasyMock.createStrictControl();
+    mockController = control.createMock(RpcController.class);
+  }
+
+  // =================================================================
+
+  /** Tests Service.callMethod(). */
+  public void testCallMethod() throws Exception {
+    FooRequest fooRequest = FooRequest.newBuilder().build();
+    BarRequest barRequest = BarRequest.newBuilder().build();
+    MockCallback<Message> fooCallback = new MockCallback<Message>();
+    MockCallback<Message> barCallback = new MockCallback<Message>();
+    TestService mockService = control.createMock(TestService.class);
+
+    mockService.foo(EasyMock.same(mockController), EasyMock.same(fooRequest),
+                    this.<FooResponse>wrapsCallback(fooCallback));
+    mockService.bar(EasyMock.same(mockController), EasyMock.same(barRequest),
+                    this.<BarResponse>wrapsCallback(barCallback));
+    control.replay();
+
+    mockService.callMethod(fooDescriptor, mockController,
+                           fooRequest, fooCallback);
+    mockService.callMethod(barDescriptor, mockController,
+                           barRequest, barCallback);
+    control.verify();
+  }
+
+  /** Tests Service.get{Request,Response}Prototype(). */
+  public void testGetPrototype() throws Exception {
+    TestService mockService = control.createMock(TestService.class);
+
+    assertSame(mockService.getRequestPrototype(fooDescriptor),
+               FooRequest.getDefaultInstance());
+    assertSame(mockService.getResponsePrototype(fooDescriptor),
+               FooResponse.getDefaultInstance());
+    assertSame(mockService.getRequestPrototype(barDescriptor),
+               BarRequest.getDefaultInstance());
+    assertSame(mockService.getResponsePrototype(barDescriptor),
+               BarResponse.getDefaultInstance());
+  }
+
+  /** Tests generated stubs. */
+  public void testStub() throws Exception {
+    FooRequest fooRequest = FooRequest.newBuilder().build();
+    BarRequest barRequest = BarRequest.newBuilder().build();
+    MockCallback<FooResponse> fooCallback = new MockCallback<FooResponse>();
+    MockCallback<BarResponse> barCallback = new MockCallback<BarResponse>();
+    RpcChannel mockChannel = control.createMock(RpcChannel.class);
+    TestService stub = TestService.newStub(mockChannel);
+
+    mockChannel.callMethod(
+      EasyMock.same(fooDescriptor),
+      EasyMock.same(mockController),
+      EasyMock.same(fooRequest),
+      EasyMock.same(FooResponse.getDefaultInstance()),
+      this.<Message>wrapsCallback(fooCallback));
+    mockChannel.callMethod(
+      EasyMock.same(barDescriptor),
+      EasyMock.same(mockController),
+      EasyMock.same(barRequest),
+      EasyMock.same(BarResponse.getDefaultInstance()),
+      this.<Message>wrapsCallback(barCallback));
+    control.replay();
+
+    stub.foo(mockController, fooRequest, fooCallback);
+    stub.bar(mockController, barRequest, barCallback);
+    control.verify();
+  }
+
+  /** Tests generated blocking stubs. */
+  public void testBlockingStub() throws Exception {
+    FooRequest fooRequest = FooRequest.newBuilder().build();
+    BarRequest barRequest = BarRequest.newBuilder().build();
+    BlockingRpcChannel mockChannel =
+        control.createMock(BlockingRpcChannel.class);
+    TestService.BlockingInterface stub =
+        TestService.newBlockingStub(mockChannel);
+
+    FooResponse fooResponse = FooResponse.newBuilder().build();
+    BarResponse barResponse = BarResponse.newBuilder().build();
+
+    EasyMock.expect(mockChannel.callBlockingMethod(
+      EasyMock.same(fooDescriptor),
+      EasyMock.same(mockController),
+      EasyMock.same(fooRequest),
+      EasyMock.same(FooResponse.getDefaultInstance()))).andReturn(fooResponse);
+    EasyMock.expect(mockChannel.callBlockingMethod(
+      EasyMock.same(barDescriptor),
+      EasyMock.same(mockController),
+      EasyMock.same(barRequest),
+      EasyMock.same(BarResponse.getDefaultInstance()))).andReturn(barResponse);
+    control.replay();
+
+    assertSame(fooResponse, stub.foo(mockController, fooRequest));
+    assertSame(barResponse, stub.bar(mockController, barRequest));
+    control.verify();
+  }
+
+  public void testNewReflectiveService() {
+    ServiceWithNoOuter.Interface impl =
+        control.createMock(ServiceWithNoOuter.Interface.class);
+    RpcController controller = control.createMock(RpcController.class);
+    Service service = ServiceWithNoOuter.newReflectiveService(impl);
+
+    MethodDescriptor fooMethod =
+        ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
+    MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance();
+    RpcCallback<Message> callback = new RpcCallback<Message>() {
+      public void run(Message parameter) {
+        // No reason this should be run.
+        fail();
+      }
+    };
+    RpcCallback<TestAllTypes> specializedCallback =
+        RpcUtil.specializeCallback(callback);
+
+    impl.foo(EasyMock.same(controller), EasyMock.same(request),
+        EasyMock.same(specializedCallback));
+    EasyMock.expectLastCall();
+
+    control.replay();
+
+    service.callMethod(fooMethod, controller, request, callback);
+
+    control.verify();
+  }
+
+  public void testNewReflectiveBlockingService() throws ServiceException {
+    ServiceWithNoOuter.BlockingInterface impl =
+        control.createMock(ServiceWithNoOuter.BlockingInterface.class);
+    RpcController controller = control.createMock(RpcController.class);
+    BlockingService service =
+        ServiceWithNoOuter.newReflectiveBlockingService(impl);
+
+    MethodDescriptor fooMethod =
+        ServiceWithNoOuter.getDescriptor().findMethodByName("Foo");
+    MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance();
+
+    TestAllTypes expectedResponse = TestAllTypes.getDefaultInstance();
+    EasyMock.expect(impl.foo(EasyMock.same(controller), EasyMock.same(request)))
+        .andReturn(expectedResponse);
+
+    control.replay();
+
+    Message response =
+        service.callBlockingMethod(fooMethod, controller, request);
+    assertEquals(expectedResponse, response);
+
+    control.verify();
+  }
+
+  public void testNoGenericServices() throws Exception {
+    // Non-services should be usable.
+    UnittestNoGenericServices.TestMessage message =
+      UnittestNoGenericServices.TestMessage.newBuilder()
+        .setA(123)
+        .setExtension(UnittestNoGenericServices.testExtension, 456)
+        .build();
+    assertEquals(123, message.getA());
+    assertEquals(1, UnittestNoGenericServices.TestEnum.FOO.getNumber());
+
+    // Build a list of the class names nested in UnittestNoGenericServices.
+    String outerName = "google.protobuf.no_generic_services_test." +
+                       "UnittestNoGenericServices";
+    Class<?> outerClass = Class.forName(outerName);
+
+    Set<String> innerClassNames = new HashSet<String>();
+    for (Class<?> innerClass : outerClass.getClasses()) {
+      String fullName = innerClass.getName();
+      // Figure out the unqualified name of the inner class.
+      // Note:  Surprisingly, the full name of an inner class will be separated
+      //   from the outer class name by a '$' rather than a '.'.  This is not
+      //   mentioned in the documentation for java.lang.Class.  I don't want to
+      //   make assumptions, so I'm just going to accept any character as the
+      //   separator.
+      assertTrue(fullName.startsWith(outerName));
+
+      if (!Service.class.isAssignableFrom(innerClass) &&
+          !Message.class.isAssignableFrom(innerClass) &&
+          !ProtocolMessageEnum.class.isAssignableFrom(innerClass)) {
+        // Ignore any classes not generated by the base code generator.
+        continue;
+      }
+
+      innerClassNames.add(fullName.substring(outerName.length() + 1));
+    }
+
+    // No service class should have been generated.
+    assertTrue(innerClassNames.contains("TestMessage"));
+    assertTrue(innerClassNames.contains("TestEnum"));
+    assertFalse(innerClassNames.contains("TestService"));
+
+    // But descriptors are there.
+    FileDescriptor file = UnittestNoGenericServices.getDescriptor();
+    assertEquals(1, file.getServices().size());
+    assertEquals("TestService", file.getServices().get(0).getName());
+    assertEquals(1, file.getServices().get(0).getMethods().size());
+    assertEquals("Foo",
+        file.getServices().get(0).getMethods().get(0).getName());
+  }
+
+  // =================================================================
+
+  /**
+   * wrapsCallback() is an EasyMock argument predicate.  wrapsCallback(c)
+   * matches a callback if calling that callback causes c to be called.
+   * In other words, c wraps the given callback.
+   */
+  private <Type extends Message> RpcCallback<Type> wrapsCallback(
+      MockCallback<?> callback) {
+    EasyMock.reportMatcher(new WrapsCallback(callback));
+    return null;
+  }
+
+  /** The parameter to wrapsCallback() must be a MockCallback. */
+  private static class MockCallback<Type extends Message>
+      implements RpcCallback<Type> {
+    private boolean called = false;
+
+    public boolean isCalled() { return called; }
+
+    public void reset() { called = false; }
+    public void run(Type message) { called = true; }
+  }
+
+  /** Implementation of the wrapsCallback() argument matcher. */
+  private static class WrapsCallback implements IArgumentMatcher {
+    private MockCallback<?> callback;
+
+    public WrapsCallback(MockCallback<?> callback) {
+      this.callback = callback;
+    }
+
+    @SuppressWarnings("unchecked")
+    public boolean matches(Object actual) {
+      if (!(actual instanceof RpcCallback)) {
+        return false;
+      }
+      RpcCallback actualCallback = (RpcCallback)actual;
+
+      callback.reset();
+      actualCallback.run(null);
+      return callback.isCalled();
+    }
+
+    public void appendTo(StringBuffer buffer) {
+      buffer.append("wrapsCallback(mockCallback)");
+    }
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java b/protobuf/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java
new file mode 100644
index 0000000..58b8000
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/SingleFieldBuilderTest.java
@@ -0,0 +1,155 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link SingleFieldBuilder}. This tests basic functionality.
+ * More extensive testing is provided via other tests that exercise the
+ * builder.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class SingleFieldBuilderTest extends TestCase {
+
+  public void testBasicUseAndInvalidations() {
+    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+    SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+        TestAllTypesOrBuilder> builder =
+        new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+            TestAllTypesOrBuilder>(
+            TestAllTypes.getDefaultInstance(),
+            mockParent,
+            false);
+    assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+    assertEquals(TestAllTypes.getDefaultInstance(),
+        builder.getBuilder().buildPartial());
+    assertEquals(0, mockParent.getInvalidationCount());
+
+    builder.getBuilder().setOptionalInt32(10);
+    assertEquals(0, mockParent.getInvalidationCount());
+    TestAllTypes message = builder.build();
+    assertEquals(10, message.getOptionalInt32());
+
+    // Test that we receive invalidations now that build has been called.
+    assertEquals(0, mockParent.getInvalidationCount());
+    builder.getBuilder().setOptionalInt32(20);
+    assertEquals(1, mockParent.getInvalidationCount());
+
+    // Test that we don't keep getting invalidations on every change
+    builder.getBuilder().setOptionalInt32(30);
+    assertEquals(1, mockParent.getInvalidationCount());
+
+  }
+
+  public void testSetMessage() {
+    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+    SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+        TestAllTypesOrBuilder> builder =
+        new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+            TestAllTypesOrBuilder>(
+            TestAllTypes.getDefaultInstance(),
+            mockParent,
+            false);
+    builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+    assertEquals(0, builder.getMessage().getOptionalInt32());
+
+    // Update message using the builder
+    builder.getBuilder().setOptionalInt32(1);
+    assertEquals(0, mockParent.getInvalidationCount());
+    assertEquals(1, builder.getBuilder().getOptionalInt32());
+    assertEquals(1, builder.getMessage().getOptionalInt32());
+    builder.build();
+    builder.getBuilder().setOptionalInt32(2);
+    assertEquals(2, builder.getBuilder().getOptionalInt32());
+    assertEquals(2, builder.getMessage().getOptionalInt32());
+
+    // Make sure message stays cached
+    assertSame(builder.getMessage(), builder.getMessage());
+  }
+
+  public void testClear() {
+    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+    SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+        TestAllTypesOrBuilder> builder =
+        new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+            TestAllTypesOrBuilder>(
+            TestAllTypes.getDefaultInstance(),
+            mockParent,
+            false);
+    builder.setMessage(TestAllTypes.newBuilder().setOptionalInt32(0).build());
+    assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+    builder.clear();
+    assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+
+    builder.getBuilder().setOptionalInt32(1);
+    assertNotSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+    builder.clear();
+    assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+  }
+
+  public void testMerge() {
+    TestUtil.MockBuilderParent mockParent = new TestUtil.MockBuilderParent();
+    SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+        TestAllTypesOrBuilder> builder =
+        new SingleFieldBuilder<TestAllTypes, TestAllTypes.Builder,
+            TestAllTypesOrBuilder>(
+            TestAllTypes.getDefaultInstance(),
+            mockParent,
+            false);
+
+    // Merge into default field.
+    builder.mergeFrom(TestAllTypes.getDefaultInstance());
+    assertSame(TestAllTypes.getDefaultInstance(), builder.getMessage());
+
+    // Merge into non-default field on existing builder.
+    builder.getBuilder().setOptionalInt32(2);
+    builder.mergeFrom(TestAllTypes.newBuilder()
+        .setOptionalDouble(4.0)
+        .buildPartial());
+    assertEquals(2, builder.getMessage().getOptionalInt32());
+    assertEquals(4.0, builder.getMessage().getOptionalDouble());
+
+    // Merge into non-default field on existing message
+    builder.setMessage(TestAllTypes.newBuilder()
+        .setOptionalInt32(10)
+        .buildPartial());
+    builder.mergeFrom(TestAllTypes.newBuilder()
+        .setOptionalDouble(5.0)
+        .buildPartial());
+    assertEquals(10, builder.getMessage().getOptionalInt32());
+    assertEquals(5.0, builder.getMessage().getOptionalDouble());
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java b/protobuf/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java
new file mode 100644
index 0000000..366086d
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/SmallSortedMapTest.java
@@ -0,0 +1,420 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * @author darick@google.com Darick Tong
+ */
+public class SmallSortedMapTest extends TestCase {
+  // java.util.AbstractMap.SimpleEntry is private in JDK 1.5. We re-implement it
+  // here for JDK 1.5 users.
+  private static class SimpleEntry<K, V> implements Map.Entry<K, V> {
+    private final K key;
+    private V value;
+
+    SimpleEntry(K key, V value) {
+      this.key = key;
+      this.value = value;
+    }
+
+    public K getKey() {
+      return key;
+    }
+
+    public V getValue() {
+      return value;
+    }
+
+    public V setValue(V value) {
+      V oldValue = this.value;
+      this.value = value;
+      return oldValue;
+    }
+
+    private static boolean eq(Object o1, Object o2) {
+      return o1 == null ? o2 == null : o1.equals(o2);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (!(o instanceof Map.Entry))
+        return false;
+      Map.Entry e = (Map.Entry) o;
+      return eq(key, e.getKey()) && eq(value, e.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+      return ((key == null) ? 0 : key.hashCode()) ^
+          ((value == null) ? 0 : value.hashCode());
+    }
+  }
+
+  public void testPutAndGetArrayEntriesOnly() {
+    runPutAndGetTest(3);
+  }
+
+  public void testPutAndGetOverflowEntries() {
+    runPutAndGetTest(6);
+  }
+
+  private void runPutAndGetTest(int numElements) {
+    // Test with even and odd arraySize
+    SmallSortedMap<Integer, Integer> map1 =
+        SmallSortedMap.newInstanceForTest(3);
+    SmallSortedMap<Integer, Integer> map2 =
+        SmallSortedMap.newInstanceForTest(4);
+    SmallSortedMap<Integer, Integer> map3 =
+        SmallSortedMap.newInstanceForTest(3);
+    SmallSortedMap<Integer, Integer> map4 =
+        SmallSortedMap.newInstanceForTest(4);
+
+    // Test with puts in ascending order.
+    for (int i = 0; i < numElements; i++) {
+      assertNull(map1.put(i, i + 1));
+      assertNull(map2.put(i, i + 1));
+    }
+    // Test with puts in descending order.
+    for (int i = numElements - 1; i >= 0; i--) {
+      assertNull(map3.put(i, i + 1));
+      assertNull(map4.put(i, i + 1));
+    }
+
+    assertEquals(Math.min(3, numElements), map1.getNumArrayEntries());
+    assertEquals(Math.min(4, numElements), map2.getNumArrayEntries());
+    assertEquals(Math.min(3, numElements), map3.getNumArrayEntries());
+    assertEquals(Math.min(4, numElements), map4.getNumArrayEntries());
+
+    List<SmallSortedMap<Integer, Integer>> allMaps =
+        new ArrayList<SmallSortedMap<Integer, Integer>>();
+    allMaps.add(map1);
+    allMaps.add(map2);
+    allMaps.add(map3);
+    allMaps.add(map4);
+
+    for (SmallSortedMap<Integer, Integer> map : allMaps) {
+      assertEquals(numElements, map.size());
+      for (int i = 0; i < numElements; i++) {
+        assertEquals(new Integer(i + 1), map.get(i));
+      }
+    }
+
+    assertEquals(map1, map2);
+    assertEquals(map2, map3);
+    assertEquals(map3, map4);
+  }
+
+  public void testReplacingPut() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+      assertNull(map.remove(i + 1));
+    }
+    for (int i = 0; i < 6; i++) {
+      assertEquals(new Integer(i + 1), map.put(i, i + 2));
+    }
+  }
+
+  public void testRemove() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+      assertNull(map.remove(i + 1));
+    }
+
+    assertEquals(3, map.getNumArrayEntries());
+    assertEquals(3, map.getNumOverflowEntries());
+    assertEquals(6,  map.size());
+    assertEquals(makeSortedKeySet(0, 1, 2, 3, 4, 5), map.keySet());
+
+    assertEquals(new Integer(2), map.remove(1));
+    assertEquals(3, map.getNumArrayEntries());
+    assertEquals(2, map.getNumOverflowEntries());
+    assertEquals(5,  map.size());
+    assertEquals(makeSortedKeySet(0, 2, 3, 4, 5), map.keySet());
+
+    assertEquals(new Integer(5), map.remove(4));
+    assertEquals(3, map.getNumArrayEntries());
+    assertEquals(1, map.getNumOverflowEntries());
+    assertEquals(4,  map.size());
+    assertEquals(makeSortedKeySet(0, 2, 3, 5), map.keySet());
+
+    assertEquals(new Integer(4), map.remove(3));
+    assertEquals(3, map.getNumArrayEntries());
+    assertEquals(0, map.getNumOverflowEntries());
+    assertEquals(3, map.size());
+    assertEquals(makeSortedKeySet(0, 2, 5), map.keySet());
+
+    assertNull(map.remove(3));
+    assertEquals(3, map.getNumArrayEntries());
+    assertEquals(0, map.getNumOverflowEntries());
+    assertEquals(3, map.size());
+
+    assertEquals(new Integer(1), map.remove(0));
+    assertEquals(2, map.getNumArrayEntries());
+    assertEquals(0, map.getNumOverflowEntries());
+    assertEquals(2, map.size());
+  }
+
+  public void testClear() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+    }
+    map.clear();
+    assertEquals(0, map.getNumArrayEntries());
+    assertEquals(0, map.getNumOverflowEntries());
+    assertEquals(0, map.size());
+  }
+
+  public void testGetArrayEntryAndOverflowEntries() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+    }
+    assertEquals(3, map.getNumArrayEntries());
+    for (int i = 0; i < 3; i++) {
+      Map.Entry<Integer, Integer> entry = map.getArrayEntryAt(i);
+      assertEquals(new Integer(i), entry.getKey());
+      assertEquals(new Integer(i + 1), entry.getValue());
+    }
+    Iterator<Map.Entry<Integer, Integer>> it =
+        map.getOverflowEntries().iterator();
+    for (int i = 3; i < 6; i++) {
+      assertTrue(it.hasNext());
+      Map.Entry<Integer, Integer> entry = it.next();
+      assertEquals(new Integer(i), entry.getKey());
+      assertEquals(new Integer(i + 1), entry.getValue());
+    }
+    assertFalse(it.hasNext());
+  }
+
+  public void testEntrySetContains() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+    }
+    Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+    for (int i = 0; i < 6; i++) {
+      assertTrue(
+          entrySet.contains(new SimpleEntry<Integer, Integer>(i, i + 1)));
+      assertFalse(
+          entrySet.contains(new SimpleEntry<Integer, Integer>(i, i)));
+    }
+  }
+
+  public void testEntrySetAdd() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+    for (int i = 0; i < 6; i++) {
+      Map.Entry<Integer, Integer> entry =
+          new SimpleEntry<Integer, Integer>(i, i + 1);
+      assertTrue(entrySet.add(entry));
+      assertFalse(entrySet.add(entry));
+    }
+    for (int i = 0; i < 6; i++) {
+      assertEquals(new Integer(i + 1), map.get(i));
+    }
+    assertEquals(3, map.getNumArrayEntries());
+    assertEquals(3, map.getNumOverflowEntries());
+    assertEquals(6, map.size());
+  }
+
+  public void testEntrySetRemove() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+    }
+    for (int i = 0; i < 6; i++) {
+      Map.Entry<Integer, Integer> entry =
+          new SimpleEntry<Integer, Integer>(i, i + 1);
+      assertTrue(entrySet.remove(entry));
+      assertFalse(entrySet.remove(entry));
+    }
+    assertTrue(map.isEmpty());
+    assertEquals(0, map.getNumArrayEntries());
+    assertEquals(0, map.getNumOverflowEntries());
+    assertEquals(0, map.size());
+  }
+
+  public void testEntrySetClear() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+    }
+    map.entrySet().clear();
+    assertTrue(map.isEmpty());
+    assertEquals(0, map.getNumArrayEntries());
+    assertEquals(0, map.getNumOverflowEntries());
+    assertEquals(0, map.size());
+  }
+
+  public void testEntrySetIteratorNext() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+    }
+    Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
+    for (int i = 0; i < 6; i++) {
+      assertTrue(it.hasNext());
+      Map.Entry<Integer, Integer> entry = it.next();
+      assertEquals(new Integer(i), entry.getKey());
+      assertEquals(new Integer(i + 1), entry.getValue());
+    }
+    assertFalse(it.hasNext());
+  }
+
+  public void testEntrySetIteratorRemove() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+    }
+    Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
+    for (int i = 0; i < 6; i++) {
+      assertTrue(map.containsKey(i));
+      it.next();
+      it.remove();
+      assertFalse(map.containsKey(i));
+      assertEquals(6 - i - 1, map.size());
+    }
+  }
+
+  public void testMapEntryModification() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+    }
+    Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
+    for (int i = 0; i < 6; i++) {
+      Map.Entry<Integer, Integer> entry = it.next();
+      entry.setValue(i + 23);
+    }
+    for (int i = 0; i < 6; i++) {
+      assertEquals(new Integer(i + 23), map.get(i));
+    }
+  }
+
+  public void testMakeImmutable() {
+    SmallSortedMap<Integer, Integer> map = SmallSortedMap.newInstanceForTest(3);
+    for (int i = 0; i < 6; i++) {
+      assertNull(map.put(i, i + 1));
+    }
+    map.makeImmutable();
+    assertEquals(new Integer(1), map.get(0));
+    assertEquals(6, map.size());
+
+    try {
+      map.put(23, 23);
+      fail("Expected UnsupportedOperationException");
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    Map<Integer, Integer> other = new HashMap<Integer, Integer>();
+    other.put(23, 23);
+    try {
+      map.putAll(other);
+      fail("Expected UnsupportedOperationException");
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    try {
+      map.remove(0);
+      fail("Expected UnsupportedOperationException");
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    try {
+      map.clear();
+      fail("Expected UnsupportedOperationException");
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    Set<Map.Entry<Integer, Integer>> entrySet = map.entrySet();
+    try {
+      entrySet.clear();
+      fail("Expected UnsupportedOperationException");
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    Iterator<Map.Entry<Integer, Integer>> it = entrySet.iterator();
+    while (it.hasNext()) {
+      Map.Entry<Integer, Integer> entry = it.next();
+      try {
+        entry.setValue(0);
+        fail("Expected UnsupportedOperationException");
+      } catch (UnsupportedOperationException expected) {
+      }
+      try {
+        it.remove();
+        fail("Expected UnsupportedOperationException");
+      } catch (UnsupportedOperationException expected) {
+      }
+    }
+
+    Set<Integer> keySet = map.keySet();
+    try {
+      keySet.clear();
+      fail("Expected UnsupportedOperationException");
+    } catch (UnsupportedOperationException expected) {
+    }
+
+    Iterator<Integer> keys = keySet.iterator();
+    while (keys.hasNext()) {
+      Integer key = keys.next();
+      try {
+        keySet.remove(key);
+        fail("Expected UnsupportedOperationException");
+      } catch (UnsupportedOperationException expected) {
+      }
+      try {
+        keys.remove();
+        fail("Expected UnsupportedOperationException");
+      } catch (UnsupportedOperationException expected) {
+      }
+    }
+  }
+
+  private Set<Integer> makeSortedKeySet(Integer... keys) {
+    return new TreeSet<Integer>(Arrays.<Integer>asList(keys));
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java b/protobuf/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java
new file mode 100644
index 0000000..614ac7f
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/TestBadIdentifiers.java
@@ -0,0 +1,96 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests that proto2 api generation doesn't cause compile errors when
+ * compiling protocol buffers that have names that would otherwise conflict
+ * if not fully qualified (like @Deprecated and @Override).
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class TestBadIdentifiers extends TestCase {
+
+  public void testCompilation() {
+    // If this compiles, it means the generation was correct.
+    TestBadIdentifiersProto.Deprecated.newBuilder();
+    TestBadIdentifiersProto.Override.newBuilder();
+  }
+
+  public void testGetDescriptor() {
+    Descriptors.FileDescriptor fileDescriptor =
+        TestBadIdentifiersProto.getDescriptor();
+    String descriptorField = TestBadIdentifiersProto.Descriptor
+        .getDefaultInstance().getDescriptor();
+    Descriptors.Descriptor protoDescriptor = TestBadIdentifiersProto.Descriptor
+        .getDefaultInstance().getDescriptorForType();
+    String nestedDescriptorField = TestBadIdentifiersProto.Descriptor
+        .NestedDescriptor.getDefaultInstance().getDescriptor();
+    Descriptors.Descriptor nestedProtoDescriptor = TestBadIdentifiersProto
+        .Descriptor.NestedDescriptor.getDefaultInstance()
+        .getDescriptorForType();
+  }
+
+  public void testConflictingFieldNames() throws Exception {
+    TestBadIdentifiersProto.TestConflictingFieldNames message =
+        TestBadIdentifiersProto.TestConflictingFieldNames.getDefaultInstance();
+    // Make sure generated accessors are properly named.
+    assertEquals(0, message.getInt32Field1Count());
+    assertEquals(0, message.getEnumField2Count());
+    assertEquals(0, message.getStringField3Count());
+    assertEquals(0, message.getBytesField4Count());
+    assertEquals(0, message.getMessageField5Count());
+
+    assertEquals(0, message.getInt32FieldCount11());
+    assertEquals(1, message.getEnumFieldCount12().getNumber());
+    assertEquals("", message.getStringFieldCount13());
+    assertEquals(ByteString.EMPTY, message.getBytesFieldCount14());
+    assertEquals(0, message.getMessageFieldCount15().getSerializedSize());
+
+    assertEquals(0, message.getInt32Field21Count());
+    assertEquals(0, message.getEnumField22Count());
+    assertEquals(0, message.getStringField23Count());
+    assertEquals(0, message.getBytesField24Count());
+    assertEquals(0, message.getMessageField25Count());
+
+    assertEquals(0, message.getInt32Field1List().size());
+    assertEquals(0, message.getInt32FieldList31());
+
+    assertEquals(0, message.getInt64FieldCount());
+    assertEquals(0L, message.getExtension(
+        TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldCount).longValue());
+    assertEquals(0L, message.getExtension(
+        TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldList).longValue());
+
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/TestUtil.java b/protobuf/java/src/test/java/com/google/protobuf/TestUtil.java
new file mode 100644
index 0000000..135a117
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/TestUtil.java
@@ -0,0 +1,4124 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto;
+import com.google.protobuf.UnittestLite;
+
+// The static imports are to avoid 100+ char lines.  The following is roughly equivalent to
+// import static protobuf_unittest.UnittestProto.*;
+import static protobuf_unittest.UnittestProto.defaultInt32Extension;
+import static protobuf_unittest.UnittestProto.defaultInt64Extension;
+import static protobuf_unittest.UnittestProto.defaultUint32Extension;
+import static protobuf_unittest.UnittestProto.defaultUint64Extension;
+import static protobuf_unittest.UnittestProto.defaultSint32Extension;
+import static protobuf_unittest.UnittestProto.defaultSint64Extension;
+import static protobuf_unittest.UnittestProto.defaultFixed32Extension;
+import static protobuf_unittest.UnittestProto.defaultFixed64Extension;
+import static protobuf_unittest.UnittestProto.defaultSfixed32Extension;
+import static protobuf_unittest.UnittestProto.defaultSfixed64Extension;
+import static protobuf_unittest.UnittestProto.defaultFloatExtension;
+import static protobuf_unittest.UnittestProto.defaultDoubleExtension;
+import static protobuf_unittest.UnittestProto.defaultBoolExtension;
+import static protobuf_unittest.UnittestProto.defaultStringExtension;
+import static protobuf_unittest.UnittestProto.defaultBytesExtension;
+import static protobuf_unittest.UnittestProto.defaultNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultImportEnumExtension;
+import static protobuf_unittest.UnittestProto.defaultStringPieceExtension;
+import static protobuf_unittest.UnittestProto.defaultCordExtension;
+
+import static protobuf_unittest.UnittestProto.oneofUint32Extension;
+import static protobuf_unittest.UnittestProto.oneofNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.oneofStringExtension;
+import static protobuf_unittest.UnittestProto.oneofBytesExtension;
+
+import static protobuf_unittest.UnittestProto.optionalInt32Extension;
+import static protobuf_unittest.UnittestProto.optionalInt64Extension;
+import static protobuf_unittest.UnittestProto.optionalUint32Extension;
+import static protobuf_unittest.UnittestProto.optionalUint64Extension;
+import static protobuf_unittest.UnittestProto.optionalSint32Extension;
+import static protobuf_unittest.UnittestProto.optionalSint64Extension;
+import static protobuf_unittest.UnittestProto.optionalFixed32Extension;
+import static protobuf_unittest.UnittestProto.optionalFixed64Extension;
+import static protobuf_unittest.UnittestProto.optionalSfixed32Extension;
+import static protobuf_unittest.UnittestProto.optionalSfixed64Extension;
+import static protobuf_unittest.UnittestProto.optionalFloatExtension;
+import static protobuf_unittest.UnittestProto.optionalDoubleExtension;
+import static protobuf_unittest.UnittestProto.optionalBoolExtension;
+import static protobuf_unittest.UnittestProto.optionalStringExtension;
+import static protobuf_unittest.UnittestProto.optionalBytesExtension;
+import static protobuf_unittest.UnittestProto.optionalGroupExtension;
+import static protobuf_unittest.UnittestProto.optionalCordExtension;
+import static protobuf_unittest.UnittestProto.optionalForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalForeignMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalImportEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalImportMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.optionalNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalPublicImportMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalLazyMessageExtension;
+import static protobuf_unittest.UnittestProto.optionalStringPieceExtension;
+
+import static protobuf_unittest.UnittestProto.repeatedInt32Extension;
+import static protobuf_unittest.UnittestProto.repeatedInt64Extension;
+import static protobuf_unittest.UnittestProto.repeatedUint32Extension;
+import static protobuf_unittest.UnittestProto.repeatedUint64Extension;
+import static protobuf_unittest.UnittestProto.repeatedSint32Extension;
+import static protobuf_unittest.UnittestProto.repeatedSint64Extension;
+import static protobuf_unittest.UnittestProto.repeatedFixed32Extension;
+import static protobuf_unittest.UnittestProto.repeatedFixed64Extension;
+import static protobuf_unittest.UnittestProto.repeatedSfixed32Extension;
+import static protobuf_unittest.UnittestProto.repeatedSfixed64Extension;
+import static protobuf_unittest.UnittestProto.repeatedFloatExtension;
+import static protobuf_unittest.UnittestProto.repeatedDoubleExtension;
+import static protobuf_unittest.UnittestProto.repeatedBoolExtension;
+import static protobuf_unittest.UnittestProto.repeatedStringExtension;
+import static protobuf_unittest.UnittestProto.repeatedBytesExtension;
+import static protobuf_unittest.UnittestProto.repeatedGroupExtension;
+import static protobuf_unittest.UnittestProto.repeatedNestedMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedForeignMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedImportMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedLazyMessageExtension;
+import static protobuf_unittest.UnittestProto.repeatedNestedEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedForeignEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedImportEnumExtension;
+import static protobuf_unittest.UnittestProto.repeatedStringPieceExtension;
+import static protobuf_unittest.UnittestProto.repeatedCordExtension;
+
+import static protobuf_unittest.UnittestProto.OptionalGroup_extension;
+import static protobuf_unittest.UnittestProto.RepeatedGroup_extension;
+
+import static protobuf_unittest.UnittestProto.packedInt32Extension;
+import static protobuf_unittest.UnittestProto.packedInt64Extension;
+import static protobuf_unittest.UnittestProto.packedUint32Extension;
+import static protobuf_unittest.UnittestProto.packedUint64Extension;
+import static protobuf_unittest.UnittestProto.packedSint32Extension;
+import static protobuf_unittest.UnittestProto.packedSint64Extension;
+import static protobuf_unittest.UnittestProto.packedFixed32Extension;
+import static protobuf_unittest.UnittestProto.packedFixed64Extension;
+import static protobuf_unittest.UnittestProto.packedSfixed32Extension;
+import static protobuf_unittest.UnittestProto.packedSfixed64Extension;
+import static protobuf_unittest.UnittestProto.packedFloatExtension;
+import static protobuf_unittest.UnittestProto.packedDoubleExtension;
+import static protobuf_unittest.UnittestProto.packedBoolExtension;
+import static protobuf_unittest.UnittestProto.packedEnumExtension;
+
+import static com.google.protobuf.UnittestLite.defaultInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultStringExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.defaultCordExtensionLite;
+
+import static com.google.protobuf.UnittestLite.oneofUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofStringExtensionLite;
+import static com.google.protobuf.UnittestLite.oneofBytesExtensionLite;
+
+import static com.google.protobuf.UnittestLite.optionalInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalStringExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalGroupExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalForeignMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalPublicImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalLazyMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.optionalCordExtensionLite;
+
+import static com.google.protobuf.UnittestLite.repeatedInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedStringExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedBytesExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedGroupExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedNestedMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedForeignMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedImportMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedLazyMessageExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedNestedEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedForeignEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedImportEnumExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedStringPieceExtensionLite;
+import static com.google.protobuf.UnittestLite.repeatedCordExtensionLite;
+
+import static com.google.protobuf.UnittestLite.OptionalGroup_extension_lite;
+import static com.google.protobuf.UnittestLite.RepeatedGroup_extension_lite;
+
+import static com.google.protobuf.UnittestLite.packedInt32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedInt64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedUint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedUint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSint32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSint64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSfixed32ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedSfixed64ExtensionLite;
+import static com.google.protobuf.UnittestLite.packedFloatExtensionLite;
+import static com.google.protobuf.UnittestLite.packedDoubleExtensionLite;
+import static com.google.protobuf.UnittestLite.packedBoolExtensionLite;
+import static com.google.protobuf.UnittestLite.packedEnumExtensionLite;
+
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllExtensionsOrBuilder;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypesOrBuilder;
+import protobuf_unittest.UnittestProto.TestOneof2;
+import protobuf_unittest.UnittestProto.TestPackedExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestProto.TestUnpackedTypes;
+import protobuf_unittest.UnittestProto.ForeignMessage;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import com.google.protobuf.test.UnittestImport.ImportEnum;
+import com.google.protobuf.test.UnittestImport.ImportMessage;
+import com.google.protobuf.test.UnittestImportPublic.PublicImportMessage;
+
+import com.google.protobuf.UnittestLite.TestAllTypesLite;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLiteOrBuilder;
+import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+import com.google.protobuf.UnittestLite.ForeignMessageLite;
+import com.google.protobuf.UnittestLite.ForeignEnumLite;
+import com.google.protobuf.UnittestImportLite.ImportEnumLite;
+import com.google.protobuf.UnittestImportLite.ImportMessageLite;
+import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
+
+import junit.framework.Assert;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/**
+ * Contains methods for setting all fields of {@code TestAllTypes} to
+ * some values as well as checking that all the fields are set to those values.
+ * These are useful for testing various protocol message features, e.g.
+ * set all fields of a message, serialize it, parse it, and check that all
+ * fields are set.
+ *
+ * <p>This code is not to be used outside of {@code com.google.protobuf} and
+ * subpackages.
+ *
+ * @author kenton@google.com Kenton Varda
+ */
+public final class TestUtil {
+  private TestUtil() {}
+
+  /** Helper to convert a String to ByteString. */
+  static ByteString toBytes(String str) {
+    try {
+      return ByteString.copyFrom(str.getBytes("UTF-8"));
+    } catch(java.io.UnsupportedEncodingException e) {
+      throw new RuntimeException("UTF-8 not supported.", e);
+    }
+  }
+
+  /**
+   * Get a {@code TestAllTypes} with all fields set as they would be by
+   * {@link #setAllFields(TestAllTypes.Builder)}.
+   */
+  public static TestAllTypes getAllSet() {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    setAllFields(builder);
+    return builder.build();
+  }
+
+  /**
+   * Get a {@code TestAllTypes.Builder} with all fields set as they would be by
+   * {@link #setAllFields(TestAllTypes.Builder)}.
+   */
+  public static TestAllTypes.Builder getAllSetBuilder() {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    setAllFields(builder);
+    return builder;
+  }
+
+  /**
+   * Get a {@code TestAllExtensions} with all fields set as they would be by
+   * {@link #setAllExtensions(TestAllExtensions.Builder)}.
+   */
+  public static TestAllExtensions getAllExtensionsSet() {
+    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+    setAllExtensions(builder);
+    return builder.build();
+  }
+
+  public static TestAllExtensionsLite getAllLiteExtensionsSet() {
+    TestAllExtensionsLite.Builder builder = TestAllExtensionsLite.newBuilder();
+    setAllExtensions(builder);
+    return builder.build();
+  }
+
+  public static TestPackedTypes getPackedSet() {
+    TestPackedTypes.Builder builder = TestPackedTypes.newBuilder();
+    setPackedFields(builder);
+    return builder.build();
+  }
+
+  public static TestUnpackedTypes getUnpackedSet() {
+    TestUnpackedTypes.Builder builder = TestUnpackedTypes.newBuilder();
+    setUnpackedFields(builder);
+    return builder.build();
+  }
+
+  public static TestPackedExtensions getPackedExtensionsSet() {
+    TestPackedExtensions.Builder builder = TestPackedExtensions.newBuilder();
+    setPackedExtensions(builder);
+    return builder.build();
+  }
+
+  public static TestPackedExtensionsLite getLitePackedExtensionsSet() {
+    TestPackedExtensionsLite.Builder builder =
+        TestPackedExtensionsLite.newBuilder();
+    setPackedExtensions(builder);
+    return builder.build();
+  }
+
+  /**
+   * Set every field of {@code message} to the values expected by
+   * {@code assertAllFieldsSet()}.
+   */
+  public static void setAllFields(TestAllTypes.Builder message) {
+    message.setOptionalInt32   (101);
+    message.setOptionalInt64   (102);
+    message.setOptionalUint32  (103);
+    message.setOptionalUint64  (104);
+    message.setOptionalSint32  (105);
+    message.setOptionalSint64  (106);
+    message.setOptionalFixed32 (107);
+    message.setOptionalFixed64 (108);
+    message.setOptionalSfixed32(109);
+    message.setOptionalSfixed64(110);
+    message.setOptionalFloat   (111);
+    message.setOptionalDouble  (112);
+    message.setOptionalBool    (true);
+    message.setOptionalString  ("115");
+    message.setOptionalBytes   (toBytes("116"));
+
+    message.setOptionalGroup(
+      TestAllTypes.OptionalGroup.newBuilder().setA(117).build());
+    message.setOptionalNestedMessage(
+      TestAllTypes.NestedMessage.newBuilder().setBb(118).build());
+    message.setOptionalForeignMessage(
+      ForeignMessage.newBuilder().setC(119).build());
+    message.setOptionalImportMessage(
+      ImportMessage.newBuilder().setD(120).build());
+    message.setOptionalPublicImportMessage(
+      PublicImportMessage.newBuilder().setE(126).build());
+    message.setOptionalLazyMessage(
+      TestAllTypes.NestedMessage.newBuilder().setBb(127).build());
+
+    message.setOptionalNestedEnum (TestAllTypes.NestedEnum.BAZ);
+    message.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAZ);
+    message.setOptionalImportEnum (ImportEnum.IMPORT_BAZ);
+
+    message.setOptionalStringPiece("124");
+    message.setOptionalCord("125");
+
+    // -----------------------------------------------------------------
+
+    message.addRepeatedInt32   (201);
+    message.addRepeatedInt64   (202);
+    message.addRepeatedUint32  (203);
+    message.addRepeatedUint64  (204);
+    message.addRepeatedSint32  (205);
+    message.addRepeatedSint64  (206);
+    message.addRepeatedFixed32 (207);
+    message.addRepeatedFixed64 (208);
+    message.addRepeatedSfixed32(209);
+    message.addRepeatedSfixed64(210);
+    message.addRepeatedFloat   (211);
+    message.addRepeatedDouble  (212);
+    message.addRepeatedBool    (true);
+    message.addRepeatedString  ("215");
+    message.addRepeatedBytes   (toBytes("216"));
+
+    message.addRepeatedGroup(
+      TestAllTypes.RepeatedGroup.newBuilder().setA(217).build());
+    message.addRepeatedNestedMessage(
+      TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+    message.addRepeatedForeignMessage(
+      ForeignMessage.newBuilder().setC(219).build());
+    message.addRepeatedImportMessage(
+      ImportMessage.newBuilder().setD(220).build());
+    message.addRepeatedLazyMessage(
+      TestAllTypes.NestedMessage.newBuilder().setBb(227).build());
+
+    message.addRepeatedNestedEnum (TestAllTypes.NestedEnum.BAR);
+    message.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR);
+    message.addRepeatedImportEnum (ImportEnum.IMPORT_BAR);
+
+    message.addRepeatedStringPiece("224");
+    message.addRepeatedCord("225");
+
+    // Add a second one of each field.
+    message.addRepeatedInt32   (301);
+    message.addRepeatedInt64   (302);
+    message.addRepeatedUint32  (303);
+    message.addRepeatedUint64  (304);
+    message.addRepeatedSint32  (305);
+    message.addRepeatedSint64  (306);
+    message.addRepeatedFixed32 (307);
+    message.addRepeatedFixed64 (308);
+    message.addRepeatedSfixed32(309);
+    message.addRepeatedSfixed64(310);
+    message.addRepeatedFloat   (311);
+    message.addRepeatedDouble  (312);
+    message.addRepeatedBool    (false);
+    message.addRepeatedString  ("315");
+    message.addRepeatedBytes   (toBytes("316"));
+
+    message.addRepeatedGroup(
+      TestAllTypes.RepeatedGroup.newBuilder().setA(317).build());
+    message.addRepeatedNestedMessage(
+      TestAllTypes.NestedMessage.newBuilder().setBb(318).build());
+    message.addRepeatedForeignMessage(
+      ForeignMessage.newBuilder().setC(319).build());
+    message.addRepeatedImportMessage(
+      ImportMessage.newBuilder().setD(320).build());
+    message.addRepeatedLazyMessage(
+      TestAllTypes.NestedMessage.newBuilder().setBb(327).build());
+
+    message.addRepeatedNestedEnum (TestAllTypes.NestedEnum.BAZ);
+    message.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAZ);
+    message.addRepeatedImportEnum (ImportEnum.IMPORT_BAZ);
+
+    message.addRepeatedStringPiece("324");
+    message.addRepeatedCord("325");
+
+    // -----------------------------------------------------------------
+
+    message.setDefaultInt32   (401);
+    message.setDefaultInt64   (402);
+    message.setDefaultUint32  (403);
+    message.setDefaultUint64  (404);
+    message.setDefaultSint32  (405);
+    message.setDefaultSint64  (406);
+    message.setDefaultFixed32 (407);
+    message.setDefaultFixed64 (408);
+    message.setDefaultSfixed32(409);
+    message.setDefaultSfixed64(410);
+    message.setDefaultFloat   (411);
+    message.setDefaultDouble  (412);
+    message.setDefaultBool    (false);
+    message.setDefaultString  ("415");
+    message.setDefaultBytes   (toBytes("416"));
+
+    message.setDefaultNestedEnum (TestAllTypes.NestedEnum.FOO);
+    message.setDefaultForeignEnum(ForeignEnum.FOREIGN_FOO);
+    message.setDefaultImportEnum (ImportEnum.IMPORT_FOO);
+
+    message.setDefaultStringPiece("424");
+    message.setDefaultCord("425");
+
+    message.setOneofUint32(601);
+    message.setOneofNestedMessage(
+      TestAllTypes.NestedMessage.newBuilder().setBb(602).build());
+    message.setOneofString("603");
+    message.setOneofBytes(toBytes("604"));
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Modify the repeated fields of {@code message} to contain the values
+   * expected by {@code assertRepeatedFieldsModified()}.
+   */
+  public static void modifyRepeatedFields(TestAllTypes.Builder message) {
+    message.setRepeatedInt32   (1, 501);
+    message.setRepeatedInt64   (1, 502);
+    message.setRepeatedUint32  (1, 503);
+    message.setRepeatedUint64  (1, 504);
+    message.setRepeatedSint32  (1, 505);
+    message.setRepeatedSint64  (1, 506);
+    message.setRepeatedFixed32 (1, 507);
+    message.setRepeatedFixed64 (1, 508);
+    message.setRepeatedSfixed32(1, 509);
+    message.setRepeatedSfixed64(1, 510);
+    message.setRepeatedFloat   (1, 511);
+    message.setRepeatedDouble  (1, 512);
+    message.setRepeatedBool    (1, true);
+    message.setRepeatedString  (1, "515");
+    message.setRepeatedBytes   (1, toBytes("516"));
+
+    message.setRepeatedGroup(1,
+      TestAllTypes.RepeatedGroup.newBuilder().setA(517).build());
+    message.setRepeatedNestedMessage(1,
+      TestAllTypes.NestedMessage.newBuilder().setBb(518).build());
+    message.setRepeatedForeignMessage(1,
+      ForeignMessage.newBuilder().setC(519).build());
+    message.setRepeatedImportMessage(1,
+      ImportMessage.newBuilder().setD(520).build());
+    message.setRepeatedLazyMessage(1,
+      TestAllTypes.NestedMessage.newBuilder().setBb(527).build());
+
+    message.setRepeatedNestedEnum (1, TestAllTypes.NestedEnum.FOO);
+    message.setRepeatedForeignEnum(1, ForeignEnum.FOREIGN_FOO);
+    message.setRepeatedImportEnum (1, ImportEnum.IMPORT_FOO);
+
+    message.setRepeatedStringPiece(1, "524");
+    message.setRepeatedCord(1, "525");
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all fields of
+   * {@code message} are set to the values assigned by {@code setAllFields}.
+   */
+  public static void assertAllFieldsSet(TestAllTypesOrBuilder message) {
+    Assert.assertTrue(message.hasOptionalInt32   ());
+    Assert.assertTrue(message.hasOptionalInt64   ());
+    Assert.assertTrue(message.hasOptionalUint32  ());
+    Assert.assertTrue(message.hasOptionalUint64  ());
+    Assert.assertTrue(message.hasOptionalSint32  ());
+    Assert.assertTrue(message.hasOptionalSint64  ());
+    Assert.assertTrue(message.hasOptionalFixed32 ());
+    Assert.assertTrue(message.hasOptionalFixed64 ());
+    Assert.assertTrue(message.hasOptionalSfixed32());
+    Assert.assertTrue(message.hasOptionalSfixed64());
+    Assert.assertTrue(message.hasOptionalFloat   ());
+    Assert.assertTrue(message.hasOptionalDouble  ());
+    Assert.assertTrue(message.hasOptionalBool    ());
+    Assert.assertTrue(message.hasOptionalString  ());
+    Assert.assertTrue(message.hasOptionalBytes   ());
+
+    Assert.assertTrue(message.hasOptionalGroup         ());
+    Assert.assertTrue(message.hasOptionalNestedMessage ());
+    Assert.assertTrue(message.hasOptionalForeignMessage());
+    Assert.assertTrue(message.hasOptionalImportMessage ());
+
+    Assert.assertTrue(message.getOptionalGroup         ().hasA());
+    Assert.assertTrue(message.getOptionalNestedMessage ().hasBb());
+    Assert.assertTrue(message.getOptionalForeignMessage().hasC());
+    Assert.assertTrue(message.getOptionalImportMessage ().hasD());
+
+    Assert.assertTrue(message.hasOptionalNestedEnum ());
+    Assert.assertTrue(message.hasOptionalForeignEnum());
+    Assert.assertTrue(message.hasOptionalImportEnum ());
+
+    Assert.assertTrue(message.hasOptionalStringPiece());
+    Assert.assertTrue(message.hasOptionalCord());
+
+    Assert.assertEquals(101  , message.getOptionalInt32   ());
+    Assert.assertEquals(102  , message.getOptionalInt64   ());
+    Assert.assertEquals(103  , message.getOptionalUint32  ());
+    Assert.assertEquals(104  , message.getOptionalUint64  ());
+    Assert.assertEquals(105  , message.getOptionalSint32  ());
+    Assert.assertEquals(106  , message.getOptionalSint64  ());
+    Assert.assertEquals(107  , message.getOptionalFixed32 ());
+    Assert.assertEquals(108  , message.getOptionalFixed64 ());
+    Assert.assertEquals(109  , message.getOptionalSfixed32());
+    Assert.assertEquals(110  , message.getOptionalSfixed64());
+    Assert.assertEquals(111  , message.getOptionalFloat   (), 0.0);
+    Assert.assertEquals(112  , message.getOptionalDouble  (), 0.0);
+    Assert.assertEquals(true , message.getOptionalBool    ());
+    Assert.assertEquals("115", message.getOptionalString  ());
+    Assert.assertEquals(toBytes("116"), message.getOptionalBytes());
+
+    Assert.assertEquals(117, message.getOptionalGroup              ().getA());
+    Assert.assertEquals(118, message.getOptionalNestedMessage      ().getBb());
+    Assert.assertEquals(119, message.getOptionalForeignMessage     ().getC());
+    Assert.assertEquals(120, message.getOptionalImportMessage      ().getD());
+    Assert.assertEquals(126, message.getOptionalPublicImportMessage().getE());
+    Assert.assertEquals(127, message.getOptionalLazyMessage        ().getBb());
+
+    Assert.assertEquals(TestAllTypes.NestedEnum.BAZ, message.getOptionalNestedEnum());
+    Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getOptionalForeignEnum());
+    Assert.assertEquals(ImportEnum.IMPORT_BAZ, message.getOptionalImportEnum());
+
+    Assert.assertEquals("124", message.getOptionalStringPiece());
+    Assert.assertEquals("125", message.getOptionalCord());
+
+    // -----------------------------------------------------------------
+
+    Assert.assertEquals(2, message.getRepeatedInt32Count   ());
+    Assert.assertEquals(2, message.getRepeatedInt64Count   ());
+    Assert.assertEquals(2, message.getRepeatedUint32Count  ());
+    Assert.assertEquals(2, message.getRepeatedUint64Count  ());
+    Assert.assertEquals(2, message.getRepeatedSint32Count  ());
+    Assert.assertEquals(2, message.getRepeatedSint64Count  ());
+    Assert.assertEquals(2, message.getRepeatedFixed32Count ());
+    Assert.assertEquals(2, message.getRepeatedFixed64Count ());
+    Assert.assertEquals(2, message.getRepeatedSfixed32Count());
+    Assert.assertEquals(2, message.getRepeatedSfixed64Count());
+    Assert.assertEquals(2, message.getRepeatedFloatCount   ());
+    Assert.assertEquals(2, message.getRepeatedDoubleCount  ());
+    Assert.assertEquals(2, message.getRepeatedBoolCount    ());
+    Assert.assertEquals(2, message.getRepeatedStringCount  ());
+    Assert.assertEquals(2, message.getRepeatedBytesCount   ());
+
+    Assert.assertEquals(2, message.getRepeatedGroupCount         ());
+    Assert.assertEquals(2, message.getRepeatedNestedMessageCount ());
+    Assert.assertEquals(2, message.getRepeatedForeignMessageCount());
+    Assert.assertEquals(2, message.getRepeatedImportMessageCount ());
+    Assert.assertEquals(2, message.getRepeatedLazyMessageCount   ());
+    Assert.assertEquals(2, message.getRepeatedNestedEnumCount    ());
+    Assert.assertEquals(2, message.getRepeatedForeignEnumCount   ());
+    Assert.assertEquals(2, message.getRepeatedImportEnumCount    ());
+
+    Assert.assertEquals(2, message.getRepeatedStringPieceCount());
+    Assert.assertEquals(2, message.getRepeatedCordCount());
+
+    Assert.assertEquals(201  , message.getRepeatedInt32   (0));
+    Assert.assertEquals(202  , message.getRepeatedInt64   (0));
+    Assert.assertEquals(203  , message.getRepeatedUint32  (0));
+    Assert.assertEquals(204  , message.getRepeatedUint64  (0));
+    Assert.assertEquals(205  , message.getRepeatedSint32  (0));
+    Assert.assertEquals(206  , message.getRepeatedSint64  (0));
+    Assert.assertEquals(207  , message.getRepeatedFixed32 (0));
+    Assert.assertEquals(208  , message.getRepeatedFixed64 (0));
+    Assert.assertEquals(209  , message.getRepeatedSfixed32(0));
+    Assert.assertEquals(210  , message.getRepeatedSfixed64(0));
+    Assert.assertEquals(211  , message.getRepeatedFloat   (0), 0.0);
+    Assert.assertEquals(212  , message.getRepeatedDouble  (0), 0.0);
+    Assert.assertEquals(true , message.getRepeatedBool    (0));
+    Assert.assertEquals("215", message.getRepeatedString  (0));
+    Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0));
+
+    Assert.assertEquals(217, message.getRepeatedGroup         (0).getA());
+    Assert.assertEquals(218, message.getRepeatedNestedMessage (0).getBb());
+    Assert.assertEquals(219, message.getRepeatedForeignMessage(0).getC());
+    Assert.assertEquals(220, message.getRepeatedImportMessage (0).getD());
+    Assert.assertEquals(227, message.getRepeatedLazyMessage   (0).getBb());
+
+    Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnum (0));
+    Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnum(0));
+    Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnum(0));
+
+    Assert.assertEquals("224", message.getRepeatedStringPiece(0));
+    Assert.assertEquals("225", message.getRepeatedCord(0));
+
+    Assert.assertEquals(301  , message.getRepeatedInt32   (1));
+    Assert.assertEquals(302  , message.getRepeatedInt64   (1));
+    Assert.assertEquals(303  , message.getRepeatedUint32  (1));
+    Assert.assertEquals(304  , message.getRepeatedUint64  (1));
+    Assert.assertEquals(305  , message.getRepeatedSint32  (1));
+    Assert.assertEquals(306  , message.getRepeatedSint64  (1));
+    Assert.assertEquals(307  , message.getRepeatedFixed32 (1));
+    Assert.assertEquals(308  , message.getRepeatedFixed64 (1));
+    Assert.assertEquals(309  , message.getRepeatedSfixed32(1));
+    Assert.assertEquals(310  , message.getRepeatedSfixed64(1));
+    Assert.assertEquals(311  , message.getRepeatedFloat   (1), 0.0);
+    Assert.assertEquals(312  , message.getRepeatedDouble  (1), 0.0);
+    Assert.assertEquals(false, message.getRepeatedBool    (1));
+    Assert.assertEquals("315", message.getRepeatedString  (1));
+    Assert.assertEquals(toBytes("316"), message.getRepeatedBytes(1));
+
+    Assert.assertEquals(317, message.getRepeatedGroup         (1).getA());
+    Assert.assertEquals(318, message.getRepeatedNestedMessage (1).getBb());
+    Assert.assertEquals(319, message.getRepeatedForeignMessage(1).getC());
+    Assert.assertEquals(320, message.getRepeatedImportMessage (1).getD());
+    Assert.assertEquals(327, message.getRepeatedLazyMessage   (1).getBb());
+
+    Assert.assertEquals(TestAllTypes.NestedEnum.BAZ, message.getRepeatedNestedEnum (1));
+    Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getRepeatedForeignEnum(1));
+    Assert.assertEquals(ImportEnum.IMPORT_BAZ, message.getRepeatedImportEnum(1));
+
+    Assert.assertEquals("324", message.getRepeatedStringPiece(1));
+    Assert.assertEquals("325", message.getRepeatedCord(1));
+
+    // -----------------------------------------------------------------
+
+    Assert.assertTrue(message.hasDefaultInt32   ());
+    Assert.assertTrue(message.hasDefaultInt64   ());
+    Assert.assertTrue(message.hasDefaultUint32  ());
+    Assert.assertTrue(message.hasDefaultUint64  ());
+    Assert.assertTrue(message.hasDefaultSint32  ());
+    Assert.assertTrue(message.hasDefaultSint64  ());
+    Assert.assertTrue(message.hasDefaultFixed32 ());
+    Assert.assertTrue(message.hasDefaultFixed64 ());
+    Assert.assertTrue(message.hasDefaultSfixed32());
+    Assert.assertTrue(message.hasDefaultSfixed64());
+    Assert.assertTrue(message.hasDefaultFloat   ());
+    Assert.assertTrue(message.hasDefaultDouble  ());
+    Assert.assertTrue(message.hasDefaultBool    ());
+    Assert.assertTrue(message.hasDefaultString  ());
+    Assert.assertTrue(message.hasDefaultBytes   ());
+
+    Assert.assertTrue(message.hasDefaultNestedEnum ());
+    Assert.assertTrue(message.hasDefaultForeignEnum());
+    Assert.assertTrue(message.hasDefaultImportEnum ());
+
+    Assert.assertTrue(message.hasDefaultStringPiece());
+    Assert.assertTrue(message.hasDefaultCord());
+
+    Assert.assertEquals(401  , message.getDefaultInt32   ());
+    Assert.assertEquals(402  , message.getDefaultInt64   ());
+    Assert.assertEquals(403  , message.getDefaultUint32  ());
+    Assert.assertEquals(404  , message.getDefaultUint64  ());
+    Assert.assertEquals(405  , message.getDefaultSint32  ());
+    Assert.assertEquals(406  , message.getDefaultSint64  ());
+    Assert.assertEquals(407  , message.getDefaultFixed32 ());
+    Assert.assertEquals(408  , message.getDefaultFixed64 ());
+    Assert.assertEquals(409  , message.getDefaultSfixed32());
+    Assert.assertEquals(410  , message.getDefaultSfixed64());
+    Assert.assertEquals(411  , message.getDefaultFloat   (), 0.0);
+    Assert.assertEquals(412  , message.getDefaultDouble  (), 0.0);
+    Assert.assertEquals(false, message.getDefaultBool    ());
+    Assert.assertEquals("415", message.getDefaultString  ());
+    Assert.assertEquals(toBytes("416"), message.getDefaultBytes());
+
+    Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getDefaultNestedEnum ());
+    Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getDefaultForeignEnum());
+    Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getDefaultImportEnum());
+
+    Assert.assertEquals("424", message.getDefaultStringPiece());
+    Assert.assertEquals("425", message.getDefaultCord());
+
+    Assert.assertFalse(message.hasOneofUint32());
+    Assert.assertFalse(message.hasOneofNestedMessage());
+    Assert.assertFalse(message.hasOneofString());
+    Assert.assertTrue(message.hasOneofBytes());
+
+    Assert.assertEquals(toBytes("604"), message.getOneofBytes());
+  }
+
+  // -------------------------------------------------------------------
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all fields of
+   * {@code message} are cleared, and that getting the fields returns their
+   * default values.
+   */
+  public static void assertClear(TestAllTypesOrBuilder message) {
+    // hasBlah() should initially be false for all optional fields.
+    Assert.assertFalse(message.hasOptionalInt32   ());
+    Assert.assertFalse(message.hasOptionalInt64   ());
+    Assert.assertFalse(message.hasOptionalUint32  ());
+    Assert.assertFalse(message.hasOptionalUint64  ());
+    Assert.assertFalse(message.hasOptionalSint32  ());
+    Assert.assertFalse(message.hasOptionalSint64  ());
+    Assert.assertFalse(message.hasOptionalFixed32 ());
+    Assert.assertFalse(message.hasOptionalFixed64 ());
+    Assert.assertFalse(message.hasOptionalSfixed32());
+    Assert.assertFalse(message.hasOptionalSfixed64());
+    Assert.assertFalse(message.hasOptionalFloat   ());
+    Assert.assertFalse(message.hasOptionalDouble  ());
+    Assert.assertFalse(message.hasOptionalBool    ());
+    Assert.assertFalse(message.hasOptionalString  ());
+    Assert.assertFalse(message.hasOptionalBytes   ());
+
+    Assert.assertFalse(message.hasOptionalGroup         ());
+    Assert.assertFalse(message.hasOptionalNestedMessage ());
+    Assert.assertFalse(message.hasOptionalForeignMessage());
+    Assert.assertFalse(message.hasOptionalImportMessage ());
+
+    Assert.assertFalse(message.hasOptionalNestedEnum ());
+    Assert.assertFalse(message.hasOptionalForeignEnum());
+    Assert.assertFalse(message.hasOptionalImportEnum ());
+
+    Assert.assertFalse(message.hasOptionalStringPiece());
+    Assert.assertFalse(message.hasOptionalCord());
+
+    // Optional fields without defaults are set to zero or something like it.
+    Assert.assertEquals(0    , message.getOptionalInt32   ());
+    Assert.assertEquals(0    , message.getOptionalInt64   ());
+    Assert.assertEquals(0    , message.getOptionalUint32  ());
+    Assert.assertEquals(0    , message.getOptionalUint64  ());
+    Assert.assertEquals(0    , message.getOptionalSint32  ());
+    Assert.assertEquals(0    , message.getOptionalSint64  ());
+    Assert.assertEquals(0    , message.getOptionalFixed32 ());
+    Assert.assertEquals(0    , message.getOptionalFixed64 ());
+    Assert.assertEquals(0    , message.getOptionalSfixed32());
+    Assert.assertEquals(0    , message.getOptionalSfixed64());
+    Assert.assertEquals(0    , message.getOptionalFloat   (), 0.0);
+    Assert.assertEquals(0    , message.getOptionalDouble  (), 0.0);
+    Assert.assertEquals(false, message.getOptionalBool    ());
+    Assert.assertEquals(""   , message.getOptionalString  ());
+    Assert.assertEquals(ByteString.EMPTY, message.getOptionalBytes());
+
+    // Embedded messages should also be clear.
+    Assert.assertFalse(message.getOptionalGroup              ().hasA());
+    Assert.assertFalse(message.getOptionalNestedMessage      ().hasBb());
+    Assert.assertFalse(message.getOptionalForeignMessage     ().hasC());
+    Assert.assertFalse(message.getOptionalImportMessage      ().hasD());
+    Assert.assertFalse(message.getOptionalPublicImportMessage().hasE());
+    Assert.assertFalse(message.getOptionalLazyMessage        ().hasBb());
+
+    Assert.assertEquals(0, message.getOptionalGroup              ().getA());
+    Assert.assertEquals(0, message.getOptionalNestedMessage      ().getBb());
+    Assert.assertEquals(0, message.getOptionalForeignMessage     ().getC());
+    Assert.assertEquals(0, message.getOptionalImportMessage      ().getD());
+    Assert.assertEquals(0, message.getOptionalPublicImportMessage().getE());
+    Assert.assertEquals(0, message.getOptionalLazyMessage        ().getBb());
+
+    // Enums without defaults are set to the first value in the enum.
+    Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getOptionalNestedEnum ());
+    Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getOptionalForeignEnum());
+    Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getOptionalImportEnum());
+
+    Assert.assertEquals("", message.getOptionalStringPiece());
+    Assert.assertEquals("", message.getOptionalCord());
+
+    // Repeated fields are empty.
+    Assert.assertEquals(0, message.getRepeatedInt32Count   ());
+    Assert.assertEquals(0, message.getRepeatedInt64Count   ());
+    Assert.assertEquals(0, message.getRepeatedUint32Count  ());
+    Assert.assertEquals(0, message.getRepeatedUint64Count  ());
+    Assert.assertEquals(0, message.getRepeatedSint32Count  ());
+    Assert.assertEquals(0, message.getRepeatedSint64Count  ());
+    Assert.assertEquals(0, message.getRepeatedFixed32Count ());
+    Assert.assertEquals(0, message.getRepeatedFixed64Count ());
+    Assert.assertEquals(0, message.getRepeatedSfixed32Count());
+    Assert.assertEquals(0, message.getRepeatedSfixed64Count());
+    Assert.assertEquals(0, message.getRepeatedFloatCount   ());
+    Assert.assertEquals(0, message.getRepeatedDoubleCount  ());
+    Assert.assertEquals(0, message.getRepeatedBoolCount    ());
+    Assert.assertEquals(0, message.getRepeatedStringCount  ());
+    Assert.assertEquals(0, message.getRepeatedBytesCount   ());
+
+    Assert.assertEquals(0, message.getRepeatedGroupCount         ());
+    Assert.assertEquals(0, message.getRepeatedNestedMessageCount ());
+    Assert.assertEquals(0, message.getRepeatedForeignMessageCount());
+    Assert.assertEquals(0, message.getRepeatedImportMessageCount ());
+    Assert.assertEquals(0, message.getRepeatedLazyMessageCount   ());
+    Assert.assertEquals(0, message.getRepeatedNestedEnumCount    ());
+    Assert.assertEquals(0, message.getRepeatedForeignEnumCount   ());
+    Assert.assertEquals(0, message.getRepeatedImportEnumCount    ());
+
+    Assert.assertEquals(0, message.getRepeatedStringPieceCount());
+    Assert.assertEquals(0, message.getRepeatedCordCount());
+
+    // hasBlah() should also be false for all default fields.
+    Assert.assertFalse(message.hasDefaultInt32   ());
+    Assert.assertFalse(message.hasDefaultInt64   ());
+    Assert.assertFalse(message.hasDefaultUint32  ());
+    Assert.assertFalse(message.hasDefaultUint64  ());
+    Assert.assertFalse(message.hasDefaultSint32  ());
+    Assert.assertFalse(message.hasDefaultSint64  ());
+    Assert.assertFalse(message.hasDefaultFixed32 ());
+    Assert.assertFalse(message.hasDefaultFixed64 ());
+    Assert.assertFalse(message.hasDefaultSfixed32());
+    Assert.assertFalse(message.hasDefaultSfixed64());
+    Assert.assertFalse(message.hasDefaultFloat   ());
+    Assert.assertFalse(message.hasDefaultDouble  ());
+    Assert.assertFalse(message.hasDefaultBool    ());
+    Assert.assertFalse(message.hasDefaultString  ());
+    Assert.assertFalse(message.hasDefaultBytes   ());
+
+    Assert.assertFalse(message.hasDefaultNestedEnum ());
+    Assert.assertFalse(message.hasDefaultForeignEnum());
+    Assert.assertFalse(message.hasDefaultImportEnum ());
+
+    Assert.assertFalse(message.hasDefaultStringPiece());
+    Assert.assertFalse(message.hasDefaultCord());
+
+    // Fields with defaults have their default values (duh).
+    Assert.assertEquals( 41    , message.getDefaultInt32   ());
+    Assert.assertEquals( 42    , message.getDefaultInt64   ());
+    Assert.assertEquals( 43    , message.getDefaultUint32  ());
+    Assert.assertEquals( 44    , message.getDefaultUint64  ());
+    Assert.assertEquals(-45    , message.getDefaultSint32  ());
+    Assert.assertEquals( 46    , message.getDefaultSint64  ());
+    Assert.assertEquals( 47    , message.getDefaultFixed32 ());
+    Assert.assertEquals( 48    , message.getDefaultFixed64 ());
+    Assert.assertEquals( 49    , message.getDefaultSfixed32());
+    Assert.assertEquals(-50    , message.getDefaultSfixed64());
+    Assert.assertEquals( 51.5  , message.getDefaultFloat   (), 0.0);
+    Assert.assertEquals( 52e3  , message.getDefaultDouble  (), 0.0);
+    Assert.assertEquals(true   , message.getDefaultBool    ());
+    Assert.assertEquals("hello", message.getDefaultString  ());
+    Assert.assertEquals(toBytes("world"), message.getDefaultBytes());
+
+    Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getDefaultNestedEnum ());
+    Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getDefaultForeignEnum());
+    Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getDefaultImportEnum());
+
+    Assert.assertEquals("abc", message.getDefaultStringPiece());
+    Assert.assertEquals("123", message.getDefaultCord());
+
+    Assert.assertFalse(message.hasOneofUint32());
+    Assert.assertFalse(message.hasOneofNestedMessage());
+    Assert.assertFalse(message.hasOneofString());
+    Assert.assertFalse(message.hasOneofBytes());
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all fields of
+   * {@code message} are set to the values assigned by {@code setAllFields}
+   * followed by {@code modifyRepeatedFields}.
+   */
+  public static void assertRepeatedFieldsModified(
+      TestAllTypesOrBuilder 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.assertEquals(2, message.getRepeatedInt32Count   ());
+    Assert.assertEquals(2, message.getRepeatedInt64Count   ());
+    Assert.assertEquals(2, message.getRepeatedUint32Count  ());
+    Assert.assertEquals(2, message.getRepeatedUint64Count  ());
+    Assert.assertEquals(2, message.getRepeatedSint32Count  ());
+    Assert.assertEquals(2, message.getRepeatedSint64Count  ());
+    Assert.assertEquals(2, message.getRepeatedFixed32Count ());
+    Assert.assertEquals(2, message.getRepeatedFixed64Count ());
+    Assert.assertEquals(2, message.getRepeatedSfixed32Count());
+    Assert.assertEquals(2, message.getRepeatedSfixed64Count());
+    Assert.assertEquals(2, message.getRepeatedFloatCount   ());
+    Assert.assertEquals(2, message.getRepeatedDoubleCount  ());
+    Assert.assertEquals(2, message.getRepeatedBoolCount    ());
+    Assert.assertEquals(2, message.getRepeatedStringCount  ());
+    Assert.assertEquals(2, message.getRepeatedBytesCount   ());
+
+    Assert.assertEquals(2, message.getRepeatedGroupCount         ());
+    Assert.assertEquals(2, message.getRepeatedNestedMessageCount ());
+    Assert.assertEquals(2, message.getRepeatedForeignMessageCount());
+    Assert.assertEquals(2, message.getRepeatedImportMessageCount ());
+    Assert.assertEquals(2, message.getRepeatedLazyMessageCount   ());
+    Assert.assertEquals(2, message.getRepeatedNestedEnumCount    ());
+    Assert.assertEquals(2, message.getRepeatedForeignEnumCount   ());
+    Assert.assertEquals(2, message.getRepeatedImportEnumCount    ());
+
+    Assert.assertEquals(2, message.getRepeatedStringPieceCount());
+    Assert.assertEquals(2, message.getRepeatedCordCount());
+
+    Assert.assertEquals(201  , message.getRepeatedInt32   (0));
+    Assert.assertEquals(202L , message.getRepeatedInt64   (0));
+    Assert.assertEquals(203  , message.getRepeatedUint32  (0));
+    Assert.assertEquals(204L , message.getRepeatedUint64  (0));
+    Assert.assertEquals(205  , message.getRepeatedSint32  (0));
+    Assert.assertEquals(206L , message.getRepeatedSint64  (0));
+    Assert.assertEquals(207  , message.getRepeatedFixed32 (0));
+    Assert.assertEquals(208L , message.getRepeatedFixed64 (0));
+    Assert.assertEquals(209  , message.getRepeatedSfixed32(0));
+    Assert.assertEquals(210L , message.getRepeatedSfixed64(0));
+    Assert.assertEquals(211F , message.getRepeatedFloat   (0));
+    Assert.assertEquals(212D , message.getRepeatedDouble  (0));
+    Assert.assertEquals(true , message.getRepeatedBool    (0));
+    Assert.assertEquals("215", message.getRepeatedString  (0));
+    Assert.assertEquals(toBytes("216"), message.getRepeatedBytes(0));
+
+    Assert.assertEquals(217, message.getRepeatedGroup         (0).getA());
+    Assert.assertEquals(218, message.getRepeatedNestedMessage (0).getBb());
+    Assert.assertEquals(219, message.getRepeatedForeignMessage(0).getC());
+    Assert.assertEquals(220, message.getRepeatedImportMessage (0).getD());
+    Assert.assertEquals(227, message.getRepeatedLazyMessage   (0).getBb());
+
+    Assert.assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnum (0));
+    Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnum(0));
+    Assert.assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnum(0));
+
+    Assert.assertEquals("224", message.getRepeatedStringPiece(0));
+    Assert.assertEquals("225", message.getRepeatedCord(0));
+
+    // Actually verify the second (modified) elements now.
+    Assert.assertEquals(501  , message.getRepeatedInt32   (1));
+    Assert.assertEquals(502L , message.getRepeatedInt64   (1));
+    Assert.assertEquals(503  , message.getRepeatedUint32  (1));
+    Assert.assertEquals(504L , message.getRepeatedUint64  (1));
+    Assert.assertEquals(505  , message.getRepeatedSint32  (1));
+    Assert.assertEquals(506L , message.getRepeatedSint64  (1));
+    Assert.assertEquals(507  , message.getRepeatedFixed32 (1));
+    Assert.assertEquals(508L , message.getRepeatedFixed64 (1));
+    Assert.assertEquals(509  , message.getRepeatedSfixed32(1));
+    Assert.assertEquals(510L , message.getRepeatedSfixed64(1));
+    Assert.assertEquals(511F , message.getRepeatedFloat   (1));
+    Assert.assertEquals(512D , message.getRepeatedDouble  (1));
+    Assert.assertEquals(true , message.getRepeatedBool    (1));
+    Assert.assertEquals("515", message.getRepeatedString  (1));
+    Assert.assertEquals(toBytes("516"), message.getRepeatedBytes(1));
+
+    Assert.assertEquals(517, message.getRepeatedGroup         (1).getA());
+    Assert.assertEquals(518, message.getRepeatedNestedMessage (1).getBb());
+    Assert.assertEquals(519, message.getRepeatedForeignMessage(1).getC());
+    Assert.assertEquals(520, message.getRepeatedImportMessage (1).getD());
+    Assert.assertEquals(527, message.getRepeatedLazyMessage   (1).getBb());
+
+    Assert.assertEquals(TestAllTypes.NestedEnum.FOO, message.getRepeatedNestedEnum (1));
+    Assert.assertEquals(ForeignEnum.FOREIGN_FOO, message.getRepeatedForeignEnum(1));
+    Assert.assertEquals(ImportEnum.IMPORT_FOO, message.getRepeatedImportEnum(1));
+
+    Assert.assertEquals("524", message.getRepeatedStringPiece(1));
+    Assert.assertEquals("525", message.getRepeatedCord(1));
+  }
+
+  /**
+   * Set every field of {@code message} to a unique value.
+   */
+  public static void setPackedFields(TestPackedTypes.Builder message) {
+    message.addPackedInt32   (601);
+    message.addPackedInt64   (602);
+    message.addPackedUint32  (603);
+    message.addPackedUint64  (604);
+    message.addPackedSint32  (605);
+    message.addPackedSint64  (606);
+    message.addPackedFixed32 (607);
+    message.addPackedFixed64 (608);
+    message.addPackedSfixed32(609);
+    message.addPackedSfixed64(610);
+    message.addPackedFloat   (611);
+    message.addPackedDouble  (612);
+    message.addPackedBool    (true);
+    message.addPackedEnum    (ForeignEnum.FOREIGN_BAR);
+    // Add a second one of each field.
+    message.addPackedInt32   (701);
+    message.addPackedInt64   (702);
+    message.addPackedUint32  (703);
+    message.addPackedUint64  (704);
+    message.addPackedSint32  (705);
+    message.addPackedSint64  (706);
+    message.addPackedFixed32 (707);
+    message.addPackedFixed64 (708);
+    message.addPackedSfixed32(709);
+    message.addPackedSfixed64(710);
+    message.addPackedFloat   (711);
+    message.addPackedDouble  (712);
+    message.addPackedBool    (false);
+    message.addPackedEnum    (ForeignEnum.FOREIGN_BAZ);
+  }
+
+  /**
+   * Set every field of {@code message} to a unique value. Must correspond with
+   * the values applied by {@code setPackedFields}.
+   */
+  public static void setUnpackedFields(TestUnpackedTypes.Builder message) {
+    message.addUnpackedInt32   (601);
+    message.addUnpackedInt64   (602);
+    message.addUnpackedUint32  (603);
+    message.addUnpackedUint64  (604);
+    message.addUnpackedSint32  (605);
+    message.addUnpackedSint64  (606);
+    message.addUnpackedFixed32 (607);
+    message.addUnpackedFixed64 (608);
+    message.addUnpackedSfixed32(609);
+    message.addUnpackedSfixed64(610);
+    message.addUnpackedFloat   (611);
+    message.addUnpackedDouble  (612);
+    message.addUnpackedBool    (true);
+    message.addUnpackedEnum    (ForeignEnum.FOREIGN_BAR);
+    // Add a second one of each field.
+    message.addUnpackedInt32   (701);
+    message.addUnpackedInt64   (702);
+    message.addUnpackedUint32  (703);
+    message.addUnpackedUint64  (704);
+    message.addUnpackedSint32  (705);
+    message.addUnpackedSint64  (706);
+    message.addUnpackedFixed32 (707);
+    message.addUnpackedFixed64 (708);
+    message.addUnpackedSfixed32(709);
+    message.addUnpackedSfixed64(710);
+    message.addUnpackedFloat   (711);
+    message.addUnpackedDouble  (712);
+    message.addUnpackedBool    (false);
+    message.addUnpackedEnum    (ForeignEnum.FOREIGN_BAZ);
+  }
+
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all fields of
+   * {@code message} are set to the values assigned by {@code setPackedFields}.
+   */
+  public static void assertPackedFieldsSet(TestPackedTypes message) {
+    Assert.assertEquals(2, message.getPackedInt32Count   ());
+    Assert.assertEquals(2, message.getPackedInt64Count   ());
+    Assert.assertEquals(2, message.getPackedUint32Count  ());
+    Assert.assertEquals(2, message.getPackedUint64Count  ());
+    Assert.assertEquals(2, message.getPackedSint32Count  ());
+    Assert.assertEquals(2, message.getPackedSint64Count  ());
+    Assert.assertEquals(2, message.getPackedFixed32Count ());
+    Assert.assertEquals(2, message.getPackedFixed64Count ());
+    Assert.assertEquals(2, message.getPackedSfixed32Count());
+    Assert.assertEquals(2, message.getPackedSfixed64Count());
+    Assert.assertEquals(2, message.getPackedFloatCount   ());
+    Assert.assertEquals(2, message.getPackedDoubleCount  ());
+    Assert.assertEquals(2, message.getPackedBoolCount    ());
+    Assert.assertEquals(2, message.getPackedEnumCount   ());
+    Assert.assertEquals(601  , message.getPackedInt32   (0));
+    Assert.assertEquals(602  , message.getPackedInt64   (0));
+    Assert.assertEquals(603  , message.getPackedUint32  (0));
+    Assert.assertEquals(604  , message.getPackedUint64  (0));
+    Assert.assertEquals(605  , message.getPackedSint32  (0));
+    Assert.assertEquals(606  , message.getPackedSint64  (0));
+    Assert.assertEquals(607  , message.getPackedFixed32 (0));
+    Assert.assertEquals(608  , message.getPackedFixed64 (0));
+    Assert.assertEquals(609  , message.getPackedSfixed32(0));
+    Assert.assertEquals(610  , message.getPackedSfixed64(0));
+    Assert.assertEquals(611  , message.getPackedFloat   (0), 0.0);
+    Assert.assertEquals(612  , message.getPackedDouble  (0), 0.0);
+    Assert.assertEquals(true , message.getPackedBool    (0));
+    Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getPackedEnum(0));
+    Assert.assertEquals(701  , message.getPackedInt32   (1));
+    Assert.assertEquals(702  , message.getPackedInt64   (1));
+    Assert.assertEquals(703  , message.getPackedUint32  (1));
+    Assert.assertEquals(704  , message.getPackedUint64  (1));
+    Assert.assertEquals(705  , message.getPackedSint32  (1));
+    Assert.assertEquals(706  , message.getPackedSint64  (1));
+    Assert.assertEquals(707  , message.getPackedFixed32 (1));
+    Assert.assertEquals(708  , message.getPackedFixed64 (1));
+    Assert.assertEquals(709  , message.getPackedSfixed32(1));
+    Assert.assertEquals(710  , message.getPackedSfixed64(1));
+    Assert.assertEquals(711  , message.getPackedFloat   (1), 0.0);
+    Assert.assertEquals(712  , message.getPackedDouble  (1), 0.0);
+    Assert.assertEquals(false, message.getPackedBool    (1));
+    Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getPackedEnum(1));
+  }
+
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all fields of
+   * {@code message} are set to the values assigned by {@code setUnpackedFields}.
+   */
+  public static void assertUnpackedFieldsSet(TestUnpackedTypes message) {
+    Assert.assertEquals(2, message.getUnpackedInt32Count   ());
+    Assert.assertEquals(2, message.getUnpackedInt64Count   ());
+    Assert.assertEquals(2, message.getUnpackedUint32Count  ());
+    Assert.assertEquals(2, message.getUnpackedUint64Count  ());
+    Assert.assertEquals(2, message.getUnpackedSint32Count  ());
+    Assert.assertEquals(2, message.getUnpackedSint64Count  ());
+    Assert.assertEquals(2, message.getUnpackedFixed32Count ());
+    Assert.assertEquals(2, message.getUnpackedFixed64Count ());
+    Assert.assertEquals(2, message.getUnpackedSfixed32Count());
+    Assert.assertEquals(2, message.getUnpackedSfixed64Count());
+    Assert.assertEquals(2, message.getUnpackedFloatCount   ());
+    Assert.assertEquals(2, message.getUnpackedDoubleCount  ());
+    Assert.assertEquals(2, message.getUnpackedBoolCount    ());
+    Assert.assertEquals(2, message.getUnpackedEnumCount   ());
+    Assert.assertEquals(601  , message.getUnpackedInt32   (0));
+    Assert.assertEquals(602  , message.getUnpackedInt64   (0));
+    Assert.assertEquals(603  , message.getUnpackedUint32  (0));
+    Assert.assertEquals(604  , message.getUnpackedUint64  (0));
+    Assert.assertEquals(605  , message.getUnpackedSint32  (0));
+    Assert.assertEquals(606  , message.getUnpackedSint64  (0));
+    Assert.assertEquals(607  , message.getUnpackedFixed32 (0));
+    Assert.assertEquals(608  , message.getUnpackedFixed64 (0));
+    Assert.assertEquals(609  , message.getUnpackedSfixed32(0));
+    Assert.assertEquals(610  , message.getUnpackedSfixed64(0));
+    Assert.assertEquals(611  , message.getUnpackedFloat   (0), 0.0);
+    Assert.assertEquals(612  , message.getUnpackedDouble  (0), 0.0);
+    Assert.assertEquals(true , message.getUnpackedBool    (0));
+    Assert.assertEquals(ForeignEnum.FOREIGN_BAR, message.getUnpackedEnum(0));
+    Assert.assertEquals(701  , message.getUnpackedInt32   (1));
+    Assert.assertEquals(702  , message.getUnpackedInt64   (1));
+    Assert.assertEquals(703  , message.getUnpackedUint32  (1));
+    Assert.assertEquals(704  , message.getUnpackedUint64  (1));
+    Assert.assertEquals(705  , message.getUnpackedSint32  (1));
+    Assert.assertEquals(706  , message.getUnpackedSint64  (1));
+    Assert.assertEquals(707  , message.getUnpackedFixed32 (1));
+    Assert.assertEquals(708  , message.getUnpackedFixed64 (1));
+    Assert.assertEquals(709  , message.getUnpackedSfixed32(1));
+    Assert.assertEquals(710  , message.getUnpackedSfixed64(1));
+    Assert.assertEquals(711  , message.getUnpackedFloat   (1), 0.0);
+    Assert.assertEquals(712  , message.getUnpackedDouble  (1), 0.0);
+    Assert.assertEquals(false, message.getUnpackedBool    (1));
+    Assert.assertEquals(ForeignEnum.FOREIGN_BAZ, message.getUnpackedEnum(1));
+  }
+
+  // ===================================================================
+  // Like above, but for extensions
+
+  // Java gets confused with things like assertEquals(int, Integer):  it can't
+  // decide whether to call assertEquals(int, int) or assertEquals(Object,
+  // Object).  So we define these methods to help it.
+  private static void assertEqualsExactType(int a, int b) {
+    Assert.assertEquals(a, b);
+  }
+  private static void assertEqualsExactType(long a, long b) {
+    Assert.assertEquals(a, b);
+  }
+  private static void assertEqualsExactType(float a, float b) {
+    Assert.assertEquals(a, b, 0.0);
+  }
+  private static void assertEqualsExactType(double a, double b) {
+    Assert.assertEquals(a, b, 0.0);
+  }
+  private static void assertEqualsExactType(boolean a, boolean b) {
+    Assert.assertEquals(a, b);
+  }
+  private static void assertEqualsExactType(String a, String b) {
+    Assert.assertEquals(a, b);
+  }
+  private static void assertEqualsExactType(ByteString a, ByteString b) {
+    Assert.assertEquals(a, b);
+  }
+  private static void assertEqualsExactType(TestAllTypes.NestedEnum a,
+                                            TestAllTypes.NestedEnum b) {
+    Assert.assertEquals(a, b);
+  }
+  private static void assertEqualsExactType(ForeignEnum a, ForeignEnum b) {
+    Assert.assertEquals(a, b);
+  }
+  private static void assertEqualsExactType(ImportEnum a, ImportEnum b) {
+    Assert.assertEquals(a, b);
+  }
+  private static void assertEqualsExactType(TestAllTypesLite.NestedEnum a,
+                                            TestAllTypesLite.NestedEnum b) {
+    Assert.assertEquals(a, b);
+  }
+  private static void assertEqualsExactType(ForeignEnumLite a,
+                                            ForeignEnumLite b) {
+    Assert.assertEquals(a, b);
+  }
+  private static void assertEqualsExactType(ImportEnumLite a,
+                                            ImportEnumLite b) {
+    Assert.assertEquals(a, b);
+  }
+
+  /**
+   * Get an unmodifiable {@link ExtensionRegistry} containing all the
+   * extensions of {@code TestAllExtensions}.
+   */
+  public static ExtensionRegistry getExtensionRegistry() {
+    ExtensionRegistry registry = ExtensionRegistry.newInstance();
+    registerAllExtensions(registry);
+    return registry.getUnmodifiable();
+  }
+
+  public static ExtensionRegistryLite getExtensionRegistryLite() {
+    ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
+    registerAllExtensionsLite(registry);
+    return registry.getUnmodifiable();
+  }
+
+  /**
+   * Register all of {@code TestAllExtensions}'s extensions with the
+   * given {@link ExtensionRegistry}.
+   */
+  public static void registerAllExtensions(ExtensionRegistry registry) {
+    UnittestProto.registerAllExtensions(registry);
+    registerAllExtensionsLite(registry);
+  }
+
+  public static void registerAllExtensionsLite(ExtensionRegistryLite registry) {
+    UnittestLite.registerAllExtensions(registry);
+  }
+
+  /**
+   * Set every field of {@code message} to the values expected by
+   * {@code assertAllExtensionsSet()}.
+   */
+  public static void setAllExtensions(TestAllExtensions.Builder message) {
+    message.setExtension(optionalInt32Extension   , 101);
+    message.setExtension(optionalInt64Extension   , 102L);
+    message.setExtension(optionalUint32Extension  , 103);
+    message.setExtension(optionalUint64Extension  , 104L);
+    message.setExtension(optionalSint32Extension  , 105);
+    message.setExtension(optionalSint64Extension  , 106L);
+    message.setExtension(optionalFixed32Extension , 107);
+    message.setExtension(optionalFixed64Extension , 108L);
+    message.setExtension(optionalSfixed32Extension, 109);
+    message.setExtension(optionalSfixed64Extension, 110L);
+    message.setExtension(optionalFloatExtension   , 111F);
+    message.setExtension(optionalDoubleExtension  , 112D);
+    message.setExtension(optionalBoolExtension    , true);
+    message.setExtension(optionalStringExtension  , "115");
+    message.setExtension(optionalBytesExtension   , toBytes("116"));
+
+    message.setExtension(optionalGroupExtension,
+      OptionalGroup_extension.newBuilder().setA(117).build());
+    message.setExtension(optionalNestedMessageExtension,
+      TestAllTypes.NestedMessage.newBuilder().setBb(118).build());
+    message.setExtension(optionalForeignMessageExtension,
+      ForeignMessage.newBuilder().setC(119).build());
+    message.setExtension(optionalImportMessageExtension,
+      ImportMessage.newBuilder().setD(120).build());
+    message.setExtension(optionalPublicImportMessageExtension,
+      PublicImportMessage.newBuilder().setE(126).build());
+    message.setExtension(optionalLazyMessageExtension,
+      TestAllTypes.NestedMessage.newBuilder().setBb(127).build());
+
+    message.setExtension(optionalNestedEnumExtension, TestAllTypes.NestedEnum.BAZ);
+    message.setExtension(optionalForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
+    message.setExtension(optionalImportEnumExtension, ImportEnum.IMPORT_BAZ);
+
+    message.setExtension(optionalStringPieceExtension, "124");
+    message.setExtension(optionalCordExtension, "125");
+
+    // -----------------------------------------------------------------
+
+    message.addExtension(repeatedInt32Extension   , 201);
+    message.addExtension(repeatedInt64Extension   , 202L);
+    message.addExtension(repeatedUint32Extension  , 203);
+    message.addExtension(repeatedUint64Extension  , 204L);
+    message.addExtension(repeatedSint32Extension  , 205);
+    message.addExtension(repeatedSint64Extension  , 206L);
+    message.addExtension(repeatedFixed32Extension , 207);
+    message.addExtension(repeatedFixed64Extension , 208L);
+    message.addExtension(repeatedSfixed32Extension, 209);
+    message.addExtension(repeatedSfixed64Extension, 210L);
+    message.addExtension(repeatedFloatExtension   , 211F);
+    message.addExtension(repeatedDoubleExtension  , 212D);
+    message.addExtension(repeatedBoolExtension    , true);
+    message.addExtension(repeatedStringExtension  , "215");
+    message.addExtension(repeatedBytesExtension   , toBytes("216"));
+
+    message.addExtension(repeatedGroupExtension,
+      RepeatedGroup_extension.newBuilder().setA(217).build());
+    message.addExtension(repeatedNestedMessageExtension,
+      TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+    message.addExtension(repeatedForeignMessageExtension,
+      ForeignMessage.newBuilder().setC(219).build());
+    message.addExtension(repeatedImportMessageExtension,
+      ImportMessage.newBuilder().setD(220).build());
+    message.addExtension(repeatedLazyMessageExtension,
+      TestAllTypes.NestedMessage.newBuilder().setBb(227).build());
+
+    message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAR);
+    message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAR);
+    message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAR);
+
+    message.addExtension(repeatedStringPieceExtension, "224");
+    message.addExtension(repeatedCordExtension, "225");
+
+    // Add a second one of each field.
+    message.addExtension(repeatedInt32Extension   , 301);
+    message.addExtension(repeatedInt64Extension   , 302L);
+    message.addExtension(repeatedUint32Extension  , 303);
+    message.addExtension(repeatedUint64Extension  , 304L);
+    message.addExtension(repeatedSint32Extension  , 305);
+    message.addExtension(repeatedSint64Extension  , 306L);
+    message.addExtension(repeatedFixed32Extension , 307);
+    message.addExtension(repeatedFixed64Extension , 308L);
+    message.addExtension(repeatedSfixed32Extension, 309);
+    message.addExtension(repeatedSfixed64Extension, 310L);
+    message.addExtension(repeatedFloatExtension   , 311F);
+    message.addExtension(repeatedDoubleExtension  , 312D);
+    message.addExtension(repeatedBoolExtension    , false);
+    message.addExtension(repeatedStringExtension  , "315");
+    message.addExtension(repeatedBytesExtension   , toBytes("316"));
+
+    message.addExtension(repeatedGroupExtension,
+      RepeatedGroup_extension.newBuilder().setA(317).build());
+    message.addExtension(repeatedNestedMessageExtension,
+      TestAllTypes.NestedMessage.newBuilder().setBb(318).build());
+    message.addExtension(repeatedForeignMessageExtension,
+      ForeignMessage.newBuilder().setC(319).build());
+    message.addExtension(repeatedImportMessageExtension,
+      ImportMessage.newBuilder().setD(320).build());
+    message.addExtension(repeatedLazyMessageExtension,
+      TestAllTypes.NestedMessage.newBuilder().setBb(327).build());
+
+    message.addExtension(repeatedNestedEnumExtension, TestAllTypes.NestedEnum.BAZ);
+    message.addExtension(repeatedForeignEnumExtension, ForeignEnum.FOREIGN_BAZ);
+    message.addExtension(repeatedImportEnumExtension, ImportEnum.IMPORT_BAZ);
+
+    message.addExtension(repeatedStringPieceExtension, "324");
+    message.addExtension(repeatedCordExtension, "325");
+
+    // -----------------------------------------------------------------
+
+    message.setExtension(defaultInt32Extension   , 401);
+    message.setExtension(defaultInt64Extension   , 402L);
+    message.setExtension(defaultUint32Extension  , 403);
+    message.setExtension(defaultUint64Extension  , 404L);
+    message.setExtension(defaultSint32Extension  , 405);
+    message.setExtension(defaultSint64Extension  , 406L);
+    message.setExtension(defaultFixed32Extension , 407);
+    message.setExtension(defaultFixed64Extension , 408L);
+    message.setExtension(defaultSfixed32Extension, 409);
+    message.setExtension(defaultSfixed64Extension, 410L);
+    message.setExtension(defaultFloatExtension   , 411F);
+    message.setExtension(defaultDoubleExtension  , 412D);
+    message.setExtension(defaultBoolExtension    , false);
+    message.setExtension(defaultStringExtension  , "415");
+    message.setExtension(defaultBytesExtension   , toBytes("416"));
+
+    message.setExtension(defaultNestedEnumExtension, TestAllTypes.NestedEnum.FOO);
+    message.setExtension(defaultForeignEnumExtension, ForeignEnum.FOREIGN_FOO);
+    message.setExtension(defaultImportEnumExtension, ImportEnum.IMPORT_FOO);
+
+    message.setExtension(defaultStringPieceExtension, "424");
+    message.setExtension(defaultCordExtension, "425");
+
+    message.setExtension(oneofUint32Extension, 601);
+    message.setExtension(oneofNestedMessageExtension,
+      TestAllTypes.NestedMessage.newBuilder().setBb(602).build());
+    message.setExtension(oneofStringExtension, "603");
+    message.setExtension(oneofBytesExtension, toBytes("604"));
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Modify the repeated extensions of {@code message} to contain the values
+   * expected by {@code assertRepeatedExtensionsModified()}.
+   */
+  public static void modifyRepeatedExtensions(
+      TestAllExtensions.Builder message) {
+    message.setExtension(repeatedInt32Extension   , 1, 501);
+    message.setExtension(repeatedInt64Extension   , 1, 502L);
+    message.setExtension(repeatedUint32Extension  , 1, 503);
+    message.setExtension(repeatedUint64Extension  , 1, 504L);
+    message.setExtension(repeatedSint32Extension  , 1, 505);
+    message.setExtension(repeatedSint64Extension  , 1, 506L);
+    message.setExtension(repeatedFixed32Extension , 1, 507);
+    message.setExtension(repeatedFixed64Extension , 1, 508L);
+    message.setExtension(repeatedSfixed32Extension, 1, 509);
+    message.setExtension(repeatedSfixed64Extension, 1, 510L);
+    message.setExtension(repeatedFloatExtension   , 1, 511F);
+    message.setExtension(repeatedDoubleExtension  , 1, 512D);
+    message.setExtension(repeatedBoolExtension    , 1, true);
+    message.setExtension(repeatedStringExtension  , 1, "515");
+    message.setExtension(repeatedBytesExtension   , 1, toBytes("516"));
+
+    message.setExtension(repeatedGroupExtension, 1,
+      RepeatedGroup_extension.newBuilder().setA(517).build());
+    message.setExtension(repeatedNestedMessageExtension, 1,
+      TestAllTypes.NestedMessage.newBuilder().setBb(518).build());
+    message.setExtension(repeatedForeignMessageExtension, 1,
+      ForeignMessage.newBuilder().setC(519).build());
+    message.setExtension(repeatedImportMessageExtension, 1,
+      ImportMessage.newBuilder().setD(520).build());
+    message.setExtension(repeatedLazyMessageExtension, 1,
+      TestAllTypes.NestedMessage.newBuilder().setBb(527).build());
+
+    message.setExtension(repeatedNestedEnumExtension , 1, TestAllTypes.NestedEnum.FOO);
+    message.setExtension(repeatedForeignEnumExtension, 1, ForeignEnum.FOREIGN_FOO);
+    message.setExtension(repeatedImportEnumExtension , 1, ImportEnum.IMPORT_FOO);
+
+    message.setExtension(repeatedStringPieceExtension, 1, "524");
+    message.setExtension(repeatedCordExtension, 1, "525");
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all extensions of
+   * {@code message} are set to the values assigned by {@code setAllExtensions}.
+   */
+  public static void assertAllExtensionsSet(
+      TestAllExtensionsOrBuilder message) {
+    Assert.assertTrue(message.hasExtension(optionalInt32Extension   ));
+    Assert.assertTrue(message.hasExtension(optionalInt64Extension   ));
+    Assert.assertTrue(message.hasExtension(optionalUint32Extension  ));
+    Assert.assertTrue(message.hasExtension(optionalUint64Extension  ));
+    Assert.assertTrue(message.hasExtension(optionalSint32Extension  ));
+    Assert.assertTrue(message.hasExtension(optionalSint64Extension  ));
+    Assert.assertTrue(message.hasExtension(optionalFixed32Extension ));
+    Assert.assertTrue(message.hasExtension(optionalFixed64Extension ));
+    Assert.assertTrue(message.hasExtension(optionalSfixed32Extension));
+    Assert.assertTrue(message.hasExtension(optionalSfixed64Extension));
+    Assert.assertTrue(message.hasExtension(optionalFloatExtension   ));
+    Assert.assertTrue(message.hasExtension(optionalDoubleExtension  ));
+    Assert.assertTrue(message.hasExtension(optionalBoolExtension    ));
+    Assert.assertTrue(message.hasExtension(optionalStringExtension  ));
+    Assert.assertTrue(message.hasExtension(optionalBytesExtension   ));
+
+    Assert.assertTrue(message.hasExtension(optionalGroupExtension         ));
+    Assert.assertTrue(message.hasExtension(optionalNestedMessageExtension ));
+    Assert.assertTrue(message.hasExtension(optionalForeignMessageExtension));
+    Assert.assertTrue(message.hasExtension(optionalImportMessageExtension ));
+
+    Assert.assertTrue(message.getExtension(optionalGroupExtension         ).hasA());
+    Assert.assertTrue(message.getExtension(optionalNestedMessageExtension ).hasBb());
+    Assert.assertTrue(message.getExtension(optionalForeignMessageExtension).hasC());
+    Assert.assertTrue(message.getExtension(optionalImportMessageExtension ).hasD());
+
+    Assert.assertTrue(message.hasExtension(optionalNestedEnumExtension ));
+    Assert.assertTrue(message.hasExtension(optionalForeignEnumExtension));
+    Assert.assertTrue(message.hasExtension(optionalImportEnumExtension ));
+
+    Assert.assertTrue(message.hasExtension(optionalStringPieceExtension));
+    Assert.assertTrue(message.hasExtension(optionalCordExtension));
+
+    assertEqualsExactType(101  , message.getExtension(optionalInt32Extension   ));
+    assertEqualsExactType(102L , message.getExtension(optionalInt64Extension   ));
+    assertEqualsExactType(103  , message.getExtension(optionalUint32Extension  ));
+    assertEqualsExactType(104L , message.getExtension(optionalUint64Extension  ));
+    assertEqualsExactType(105  , message.getExtension(optionalSint32Extension  ));
+    assertEqualsExactType(106L , message.getExtension(optionalSint64Extension  ));
+    assertEqualsExactType(107  , message.getExtension(optionalFixed32Extension ));
+    assertEqualsExactType(108L , message.getExtension(optionalFixed64Extension ));
+    assertEqualsExactType(109  , message.getExtension(optionalSfixed32Extension));
+    assertEqualsExactType(110L , message.getExtension(optionalSfixed64Extension));
+    assertEqualsExactType(111F , message.getExtension(optionalFloatExtension   ));
+    assertEqualsExactType(112D , message.getExtension(optionalDoubleExtension  ));
+    assertEqualsExactType(true , message.getExtension(optionalBoolExtension    ));
+    assertEqualsExactType("115", message.getExtension(optionalStringExtension  ));
+    assertEqualsExactType(toBytes("116"), message.getExtension(optionalBytesExtension));
+
+    assertEqualsExactType(117, message.getExtension(optionalGroupExtension              ).getA());
+    assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtension      ).getBb());
+    assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtension     ).getC());
+    assertEqualsExactType(120, message.getExtension(optionalImportMessageExtension      ).getD());
+    assertEqualsExactType(126, message.getExtension(optionalPublicImportMessageExtension).getE());
+    assertEqualsExactType(127, message.getExtension(optionalLazyMessageExtension        ).getBb());
+
+    assertEqualsExactType(TestAllTypes.NestedEnum.BAZ,
+      message.getExtension(optionalNestedEnumExtension));
+    assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
+      message.getExtension(optionalForeignEnumExtension));
+    assertEqualsExactType(ImportEnum.IMPORT_BAZ,
+      message.getExtension(optionalImportEnumExtension));
+
+    assertEqualsExactType("124", message.getExtension(optionalStringPieceExtension));
+    assertEqualsExactType("125", message.getExtension(optionalCordExtension));
+
+    // -----------------------------------------------------------------
+
+    Assert.assertEquals(2, message.getExtensionCount(repeatedInt32Extension   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension    ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension   ));
+
+    Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension         ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtension   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension    ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension    ));
+
+    Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension));
+
+    assertEqualsExactType(201  , message.getExtension(repeatedInt32Extension   , 0));
+    assertEqualsExactType(202L , message.getExtension(repeatedInt64Extension   , 0));
+    assertEqualsExactType(203  , message.getExtension(repeatedUint32Extension  , 0));
+    assertEqualsExactType(204L , message.getExtension(repeatedUint64Extension  , 0));
+    assertEqualsExactType(205  , message.getExtension(repeatedSint32Extension  , 0));
+    assertEqualsExactType(206L , message.getExtension(repeatedSint64Extension  , 0));
+    assertEqualsExactType(207  , message.getExtension(repeatedFixed32Extension , 0));
+    assertEqualsExactType(208L , message.getExtension(repeatedFixed64Extension , 0));
+    assertEqualsExactType(209  , message.getExtension(repeatedSfixed32Extension, 0));
+    assertEqualsExactType(210L , message.getExtension(repeatedSfixed64Extension, 0));
+    assertEqualsExactType(211F , message.getExtension(repeatedFloatExtension   , 0));
+    assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtension  , 0));
+    assertEqualsExactType(true , message.getExtension(repeatedBoolExtension    , 0));
+    assertEqualsExactType("215", message.getExtension(repeatedStringExtension  , 0));
+    assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0));
+
+    assertEqualsExactType(217, message.getExtension(repeatedGroupExtension         , 0).getA());
+    assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension , 0).getBb());
+    assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC());
+    assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension , 0).getD());
+    assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtension   , 0).getBb());
+
+    assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
+      message.getExtension(repeatedNestedEnumExtension, 0));
+    assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+      message.getExtension(repeatedForeignEnumExtension, 0));
+    assertEqualsExactType(ImportEnum.IMPORT_BAR,
+      message.getExtension(repeatedImportEnumExtension, 0));
+
+    assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0));
+    assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0));
+
+    assertEqualsExactType(301  , message.getExtension(repeatedInt32Extension   , 1));
+    assertEqualsExactType(302L , message.getExtension(repeatedInt64Extension   , 1));
+    assertEqualsExactType(303  , message.getExtension(repeatedUint32Extension  , 1));
+    assertEqualsExactType(304L , message.getExtension(repeatedUint64Extension  , 1));
+    assertEqualsExactType(305  , message.getExtension(repeatedSint32Extension  , 1));
+    assertEqualsExactType(306L , message.getExtension(repeatedSint64Extension  , 1));
+    assertEqualsExactType(307  , message.getExtension(repeatedFixed32Extension , 1));
+    assertEqualsExactType(308L , message.getExtension(repeatedFixed64Extension , 1));
+    assertEqualsExactType(309  , message.getExtension(repeatedSfixed32Extension, 1));
+    assertEqualsExactType(310L , message.getExtension(repeatedSfixed64Extension, 1));
+    assertEqualsExactType(311F , message.getExtension(repeatedFloatExtension   , 1));
+    assertEqualsExactType(312D , message.getExtension(repeatedDoubleExtension  , 1));
+    assertEqualsExactType(false, message.getExtension(repeatedBoolExtension    , 1));
+    assertEqualsExactType("315", message.getExtension(repeatedStringExtension  , 1));
+    assertEqualsExactType(toBytes("316"), message.getExtension(repeatedBytesExtension, 1));
+
+    assertEqualsExactType(317, message.getExtension(repeatedGroupExtension         , 1).getA());
+    assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtension , 1).getBb());
+    assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtension, 1).getC());
+    assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtension , 1).getD());
+    assertEqualsExactType(327, message.getExtension(repeatedLazyMessageExtension   , 1).getBb());
+
+    assertEqualsExactType(TestAllTypes.NestedEnum.BAZ,
+      message.getExtension(repeatedNestedEnumExtension, 1));
+    assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
+      message.getExtension(repeatedForeignEnumExtension, 1));
+    assertEqualsExactType(ImportEnum.IMPORT_BAZ,
+      message.getExtension(repeatedImportEnumExtension, 1));
+
+    assertEqualsExactType("324", message.getExtension(repeatedStringPieceExtension, 1));
+    assertEqualsExactType("325", message.getExtension(repeatedCordExtension, 1));
+
+    // -----------------------------------------------------------------
+
+    Assert.assertTrue(message.hasExtension(defaultInt32Extension   ));
+    Assert.assertTrue(message.hasExtension(defaultInt64Extension   ));
+    Assert.assertTrue(message.hasExtension(defaultUint32Extension  ));
+    Assert.assertTrue(message.hasExtension(defaultUint64Extension  ));
+    Assert.assertTrue(message.hasExtension(defaultSint32Extension  ));
+    Assert.assertTrue(message.hasExtension(defaultSint64Extension  ));
+    Assert.assertTrue(message.hasExtension(defaultFixed32Extension ));
+    Assert.assertTrue(message.hasExtension(defaultFixed64Extension ));
+    Assert.assertTrue(message.hasExtension(defaultSfixed32Extension));
+    Assert.assertTrue(message.hasExtension(defaultSfixed64Extension));
+    Assert.assertTrue(message.hasExtension(defaultFloatExtension   ));
+    Assert.assertTrue(message.hasExtension(defaultDoubleExtension  ));
+    Assert.assertTrue(message.hasExtension(defaultBoolExtension    ));
+    Assert.assertTrue(message.hasExtension(defaultStringExtension  ));
+    Assert.assertTrue(message.hasExtension(defaultBytesExtension   ));
+
+    Assert.assertTrue(message.hasExtension(defaultNestedEnumExtension ));
+    Assert.assertTrue(message.hasExtension(defaultForeignEnumExtension));
+    Assert.assertTrue(message.hasExtension(defaultImportEnumExtension ));
+
+    Assert.assertTrue(message.hasExtension(defaultStringPieceExtension));
+    Assert.assertTrue(message.hasExtension(defaultCordExtension));
+
+    assertEqualsExactType(401  , message.getExtension(defaultInt32Extension   ));
+    assertEqualsExactType(402L , message.getExtension(defaultInt64Extension   ));
+    assertEqualsExactType(403  , message.getExtension(defaultUint32Extension  ));
+    assertEqualsExactType(404L , message.getExtension(defaultUint64Extension  ));
+    assertEqualsExactType(405  , message.getExtension(defaultSint32Extension  ));
+    assertEqualsExactType(406L , message.getExtension(defaultSint64Extension  ));
+    assertEqualsExactType(407  , message.getExtension(defaultFixed32Extension ));
+    assertEqualsExactType(408L , message.getExtension(defaultFixed64Extension ));
+    assertEqualsExactType(409  , message.getExtension(defaultSfixed32Extension));
+    assertEqualsExactType(410L , message.getExtension(defaultSfixed64Extension));
+    assertEqualsExactType(411F , message.getExtension(defaultFloatExtension   ));
+    assertEqualsExactType(412D , message.getExtension(defaultDoubleExtension  ));
+    assertEqualsExactType(false, message.getExtension(defaultBoolExtension    ));
+    assertEqualsExactType("415", message.getExtension(defaultStringExtension  ));
+    assertEqualsExactType(toBytes("416"), message.getExtension(defaultBytesExtension));
+
+    assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
+      message.getExtension(defaultNestedEnumExtension ));
+    assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
+      message.getExtension(defaultForeignEnumExtension));
+    assertEqualsExactType(ImportEnum.IMPORT_FOO,
+      message.getExtension(defaultImportEnumExtension));
+
+    assertEqualsExactType("424", message.getExtension(defaultStringPieceExtension));
+    assertEqualsExactType("425", message.getExtension(defaultCordExtension));
+
+    Assert.assertTrue(message.hasExtension(oneofBytesExtension));
+
+    assertEqualsExactType(toBytes("604"), message.getExtension(oneofBytesExtension));
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all extensions of
+   * {@code message} are cleared, and that getting the extensions returns their
+   * default values.
+   */
+  public static void assertExtensionsClear(TestAllExtensionsOrBuilder message) {
+    // hasBlah() should initially be false for all optional fields.
+    Assert.assertFalse(message.hasExtension(optionalInt32Extension   ));
+    Assert.assertFalse(message.hasExtension(optionalInt64Extension   ));
+    Assert.assertFalse(message.hasExtension(optionalUint32Extension  ));
+    Assert.assertFalse(message.hasExtension(optionalUint64Extension  ));
+    Assert.assertFalse(message.hasExtension(optionalSint32Extension  ));
+    Assert.assertFalse(message.hasExtension(optionalSint64Extension  ));
+    Assert.assertFalse(message.hasExtension(optionalFixed32Extension ));
+    Assert.assertFalse(message.hasExtension(optionalFixed64Extension ));
+    Assert.assertFalse(message.hasExtension(optionalSfixed32Extension));
+    Assert.assertFalse(message.hasExtension(optionalSfixed64Extension));
+    Assert.assertFalse(message.hasExtension(optionalFloatExtension   ));
+    Assert.assertFalse(message.hasExtension(optionalDoubleExtension  ));
+    Assert.assertFalse(message.hasExtension(optionalBoolExtension    ));
+    Assert.assertFalse(message.hasExtension(optionalStringExtension  ));
+    Assert.assertFalse(message.hasExtension(optionalBytesExtension   ));
+
+    Assert.assertFalse(message.hasExtension(optionalGroupExtension         ));
+    Assert.assertFalse(message.hasExtension(optionalNestedMessageExtension ));
+    Assert.assertFalse(message.hasExtension(optionalForeignMessageExtension));
+    Assert.assertFalse(message.hasExtension(optionalImportMessageExtension ));
+
+    Assert.assertFalse(message.hasExtension(optionalNestedEnumExtension ));
+    Assert.assertFalse(message.hasExtension(optionalForeignEnumExtension));
+    Assert.assertFalse(message.hasExtension(optionalImportEnumExtension ));
+
+    Assert.assertFalse(message.hasExtension(optionalStringPieceExtension));
+    Assert.assertFalse(message.hasExtension(optionalCordExtension));
+
+    // Optional fields without defaults are set to zero or something like it.
+    assertEqualsExactType(0    , message.getExtension(optionalInt32Extension   ));
+    assertEqualsExactType(0L   , message.getExtension(optionalInt64Extension   ));
+    assertEqualsExactType(0    , message.getExtension(optionalUint32Extension  ));
+    assertEqualsExactType(0L   , message.getExtension(optionalUint64Extension  ));
+    assertEqualsExactType(0    , message.getExtension(optionalSint32Extension  ));
+    assertEqualsExactType(0L   , message.getExtension(optionalSint64Extension  ));
+    assertEqualsExactType(0    , message.getExtension(optionalFixed32Extension ));
+    assertEqualsExactType(0L   , message.getExtension(optionalFixed64Extension ));
+    assertEqualsExactType(0    , message.getExtension(optionalSfixed32Extension));
+    assertEqualsExactType(0L   , message.getExtension(optionalSfixed64Extension));
+    assertEqualsExactType(0F   , message.getExtension(optionalFloatExtension   ));
+    assertEqualsExactType(0D   , message.getExtension(optionalDoubleExtension  ));
+    assertEqualsExactType(false, message.getExtension(optionalBoolExtension    ));
+    assertEqualsExactType(""   , message.getExtension(optionalStringExtension  ));
+    assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtension));
+
+    // Embedded messages should also be clear.
+    Assert.assertFalse(message.getExtension(optionalGroupExtension         ).hasA());
+    Assert.assertFalse(message.getExtension(optionalNestedMessageExtension ).hasBb());
+    Assert.assertFalse(message.getExtension(optionalForeignMessageExtension).hasC());
+    Assert.assertFalse(message.getExtension(optionalImportMessageExtension ).hasD());
+
+    assertEqualsExactType(0, message.getExtension(optionalGroupExtension         ).getA());
+    assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtension ).getBb());
+    assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtension).getC());
+    assertEqualsExactType(0, message.getExtension(optionalImportMessageExtension ).getD());
+
+    // Enums without defaults are set to the first value in the enum.
+    assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
+      message.getExtension(optionalNestedEnumExtension ));
+    assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
+      message.getExtension(optionalForeignEnumExtension));
+    assertEqualsExactType(ImportEnum.IMPORT_FOO,
+      message.getExtension(optionalImportEnumExtension));
+
+    assertEqualsExactType("", message.getExtension(optionalStringPieceExtension));
+    assertEqualsExactType("", message.getExtension(optionalCordExtension));
+
+    // Repeated fields are empty.
+    Assert.assertEquals(0, message.getExtensionCount(repeatedInt32Extension   ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedInt64Extension   ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedUint32Extension  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedUint64Extension  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedSint32Extension  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedSint64Extension  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedFixed32Extension ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedFixed64Extension ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed32Extension));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed64Extension));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedFloatExtension   ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedDoubleExtension  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedBoolExtension    ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedStringExtension  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedBytesExtension   ));
+
+    Assert.assertEquals(0, message.getExtensionCount(repeatedGroupExtension         ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtension ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtension));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtension ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedLazyMessageExtension   ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtension    ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtension   ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtension    ));
+
+    Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtension));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtension));
+
+    // Repeated fields are empty via getExtension().size().
+    Assert.assertEquals(0, message.getExtension(repeatedInt32Extension   ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedInt64Extension   ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedUint32Extension  ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedUint64Extension  ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedSint32Extension  ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedSint64Extension  ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedFixed32Extension ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedFixed64Extension ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedSfixed32Extension).size());
+    Assert.assertEquals(0, message.getExtension(repeatedSfixed64Extension).size());
+    Assert.assertEquals(0, message.getExtension(repeatedFloatExtension   ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedDoubleExtension  ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedBoolExtension    ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedStringExtension  ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedBytesExtension   ).size());
+
+    Assert.assertEquals(0, message.getExtension(repeatedGroupExtension         ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedNestedMessageExtension ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedForeignMessageExtension).size());
+    Assert.assertEquals(0, message.getExtension(repeatedImportMessageExtension ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedLazyMessageExtension   ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedNestedEnumExtension    ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedForeignEnumExtension   ).size());
+    Assert.assertEquals(0, message.getExtension(repeatedImportEnumExtension    ).size());
+
+    Assert.assertEquals(0, message.getExtension(repeatedStringPieceExtension).size());
+    Assert.assertEquals(0, message.getExtension(repeatedCordExtension).size());
+
+    // hasBlah() should also be false for all default fields.
+    Assert.assertFalse(message.hasExtension(defaultInt32Extension   ));
+    Assert.assertFalse(message.hasExtension(defaultInt64Extension   ));
+    Assert.assertFalse(message.hasExtension(defaultUint32Extension  ));
+    Assert.assertFalse(message.hasExtension(defaultUint64Extension  ));
+    Assert.assertFalse(message.hasExtension(defaultSint32Extension  ));
+    Assert.assertFalse(message.hasExtension(defaultSint64Extension  ));
+    Assert.assertFalse(message.hasExtension(defaultFixed32Extension ));
+    Assert.assertFalse(message.hasExtension(defaultFixed64Extension ));
+    Assert.assertFalse(message.hasExtension(defaultSfixed32Extension));
+    Assert.assertFalse(message.hasExtension(defaultSfixed64Extension));
+    Assert.assertFalse(message.hasExtension(defaultFloatExtension   ));
+    Assert.assertFalse(message.hasExtension(defaultDoubleExtension  ));
+    Assert.assertFalse(message.hasExtension(defaultBoolExtension    ));
+    Assert.assertFalse(message.hasExtension(defaultStringExtension  ));
+    Assert.assertFalse(message.hasExtension(defaultBytesExtension   ));
+
+    Assert.assertFalse(message.hasExtension(defaultNestedEnumExtension ));
+    Assert.assertFalse(message.hasExtension(defaultForeignEnumExtension));
+    Assert.assertFalse(message.hasExtension(defaultImportEnumExtension ));
+
+    Assert.assertFalse(message.hasExtension(defaultStringPieceExtension));
+    Assert.assertFalse(message.hasExtension(defaultCordExtension));
+
+    // Fields with defaults have their default values (duh).
+    assertEqualsExactType( 41    , message.getExtension(defaultInt32Extension   ));
+    assertEqualsExactType( 42L   , message.getExtension(defaultInt64Extension   ));
+    assertEqualsExactType( 43    , message.getExtension(defaultUint32Extension  ));
+    assertEqualsExactType( 44L   , message.getExtension(defaultUint64Extension  ));
+    assertEqualsExactType(-45    , message.getExtension(defaultSint32Extension  ));
+    assertEqualsExactType( 46L   , message.getExtension(defaultSint64Extension  ));
+    assertEqualsExactType( 47    , message.getExtension(defaultFixed32Extension ));
+    assertEqualsExactType( 48L   , message.getExtension(defaultFixed64Extension ));
+    assertEqualsExactType( 49    , message.getExtension(defaultSfixed32Extension));
+    assertEqualsExactType(-50L   , message.getExtension(defaultSfixed64Extension));
+    assertEqualsExactType( 51.5F , message.getExtension(defaultFloatExtension   ));
+    assertEqualsExactType( 52e3D , message.getExtension(defaultDoubleExtension  ));
+    assertEqualsExactType(true   , message.getExtension(defaultBoolExtension    ));
+    assertEqualsExactType("hello", message.getExtension(defaultStringExtension  ));
+    assertEqualsExactType(toBytes("world"), message.getExtension(defaultBytesExtension));
+
+    assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
+      message.getExtension(defaultNestedEnumExtension ));
+    assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+      message.getExtension(defaultForeignEnumExtension));
+    assertEqualsExactType(ImportEnum.IMPORT_BAR,
+      message.getExtension(defaultImportEnumExtension));
+
+    assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtension));
+    assertEqualsExactType("123", message.getExtension(defaultCordExtension));
+
+    Assert.assertFalse(message.hasExtension(oneofUint32Extension));
+    Assert.assertFalse(message.hasExtension(oneofNestedMessageExtension));
+    Assert.assertFalse(message.hasExtension(oneofStringExtension));
+    Assert.assertFalse(message.hasExtension(oneofBytesExtension));
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all extensions of
+   * {@code message} are set to the values assigned by {@code setAllExtensions}
+   * followed by {@code modifyRepeatedExtensions}.
+   */
+  public static void assertRepeatedExtensionsModified(
+      TestAllExtensionsOrBuilder 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.assertEquals(2, message.getExtensionCount(repeatedInt32Extension   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedInt64Extension   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedUint32Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedUint64Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSint32Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSint64Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32Extension ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64Extension ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32Extension));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64Extension));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtension   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtension    ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtension  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtension   ));
+
+    Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtension         ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtension ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtension));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtension ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtension   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtension    ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtension   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtension    ));
+
+    Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtension));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtension));
+
+    assertEqualsExactType(201  , message.getExtension(repeatedInt32Extension   , 0));
+    assertEqualsExactType(202L , message.getExtension(repeatedInt64Extension   , 0));
+    assertEqualsExactType(203  , message.getExtension(repeatedUint32Extension  , 0));
+    assertEqualsExactType(204L , message.getExtension(repeatedUint64Extension  , 0));
+    assertEqualsExactType(205  , message.getExtension(repeatedSint32Extension  , 0));
+    assertEqualsExactType(206L , message.getExtension(repeatedSint64Extension  , 0));
+    assertEqualsExactType(207  , message.getExtension(repeatedFixed32Extension , 0));
+    assertEqualsExactType(208L , message.getExtension(repeatedFixed64Extension , 0));
+    assertEqualsExactType(209  , message.getExtension(repeatedSfixed32Extension, 0));
+    assertEqualsExactType(210L , message.getExtension(repeatedSfixed64Extension, 0));
+    assertEqualsExactType(211F , message.getExtension(repeatedFloatExtension   , 0));
+    assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtension  , 0));
+    assertEqualsExactType(true , message.getExtension(repeatedBoolExtension    , 0));
+    assertEqualsExactType("215", message.getExtension(repeatedStringExtension  , 0));
+    assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtension, 0));
+
+    assertEqualsExactType(217, message.getExtension(repeatedGroupExtension         , 0).getA());
+    assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtension , 0).getBb());
+    assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtension, 0).getC());
+    assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtension , 0).getD());
+    assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtension   , 0).getBb());
+
+    assertEqualsExactType(TestAllTypes.NestedEnum.BAR,
+      message.getExtension(repeatedNestedEnumExtension, 0));
+    assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+      message.getExtension(repeatedForeignEnumExtension, 0));
+    assertEqualsExactType(ImportEnum.IMPORT_BAR,
+      message.getExtension(repeatedImportEnumExtension, 0));
+
+    assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtension, 0));
+    assertEqualsExactType("225", message.getExtension(repeatedCordExtension, 0));
+
+    // Actually verify the second (modified) elements now.
+    assertEqualsExactType(501  , message.getExtension(repeatedInt32Extension   , 1));
+    assertEqualsExactType(502L , message.getExtension(repeatedInt64Extension   , 1));
+    assertEqualsExactType(503  , message.getExtension(repeatedUint32Extension  , 1));
+    assertEqualsExactType(504L , message.getExtension(repeatedUint64Extension  , 1));
+    assertEqualsExactType(505  , message.getExtension(repeatedSint32Extension  , 1));
+    assertEqualsExactType(506L , message.getExtension(repeatedSint64Extension  , 1));
+    assertEqualsExactType(507  , message.getExtension(repeatedFixed32Extension , 1));
+    assertEqualsExactType(508L , message.getExtension(repeatedFixed64Extension , 1));
+    assertEqualsExactType(509  , message.getExtension(repeatedSfixed32Extension, 1));
+    assertEqualsExactType(510L , message.getExtension(repeatedSfixed64Extension, 1));
+    assertEqualsExactType(511F , message.getExtension(repeatedFloatExtension   , 1));
+    assertEqualsExactType(512D , message.getExtension(repeatedDoubleExtension  , 1));
+    assertEqualsExactType(true , message.getExtension(repeatedBoolExtension    , 1));
+    assertEqualsExactType("515", message.getExtension(repeatedStringExtension  , 1));
+    assertEqualsExactType(toBytes("516"), message.getExtension(repeatedBytesExtension, 1));
+
+    assertEqualsExactType(517, message.getExtension(repeatedGroupExtension         , 1).getA());
+    assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtension , 1).getBb());
+    assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtension, 1).getC());
+    assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtension , 1).getD());
+    assertEqualsExactType(527, message.getExtension(repeatedLazyMessageExtension   , 1).getBb());
+
+    assertEqualsExactType(TestAllTypes.NestedEnum.FOO,
+      message.getExtension(repeatedNestedEnumExtension, 1));
+    assertEqualsExactType(ForeignEnum.FOREIGN_FOO,
+      message.getExtension(repeatedForeignEnumExtension, 1));
+    assertEqualsExactType(ImportEnum.IMPORT_FOO,
+      message.getExtension(repeatedImportEnumExtension, 1));
+
+    assertEqualsExactType("524", message.getExtension(repeatedStringPieceExtension, 1));
+    assertEqualsExactType("525", message.getExtension(repeatedCordExtension, 1));
+  }
+
+  public static void setPackedExtensions(TestPackedExtensions.Builder message) {
+    message.addExtension(packedInt32Extension   , 601);
+    message.addExtension(packedInt64Extension   , 602L);
+    message.addExtension(packedUint32Extension  , 603);
+    message.addExtension(packedUint64Extension  , 604L);
+    message.addExtension(packedSint32Extension  , 605);
+    message.addExtension(packedSint64Extension  , 606L);
+    message.addExtension(packedFixed32Extension , 607);
+    message.addExtension(packedFixed64Extension , 608L);
+    message.addExtension(packedSfixed32Extension, 609);
+    message.addExtension(packedSfixed64Extension, 610L);
+    message.addExtension(packedFloatExtension   , 611F);
+    message.addExtension(packedDoubleExtension  , 612D);
+    message.addExtension(packedBoolExtension    , true);
+    message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAR);
+    // Add a second one of each field.
+    message.addExtension(packedInt32Extension   , 701);
+    message.addExtension(packedInt64Extension   , 702L);
+    message.addExtension(packedUint32Extension  , 703);
+    message.addExtension(packedUint64Extension  , 704L);
+    message.addExtension(packedSint32Extension  , 705);
+    message.addExtension(packedSint64Extension  , 706L);
+    message.addExtension(packedFixed32Extension , 707);
+    message.addExtension(packedFixed64Extension , 708L);
+    message.addExtension(packedSfixed32Extension, 709);
+    message.addExtension(packedSfixed64Extension, 710L);
+    message.addExtension(packedFloatExtension   , 711F);
+    message.addExtension(packedDoubleExtension  , 712D);
+    message.addExtension(packedBoolExtension    , false);
+    message.addExtension(packedEnumExtension, ForeignEnum.FOREIGN_BAZ);
+  }
+
+  public static void assertPackedExtensionsSet(TestPackedExtensions message) {
+    Assert.assertEquals(2, message.getExtensionCount(packedInt32Extension   ));
+    Assert.assertEquals(2, message.getExtensionCount(packedInt64Extension   ));
+    Assert.assertEquals(2, message.getExtensionCount(packedUint32Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(packedUint64Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(packedSint32Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(packedSint64Extension  ));
+    Assert.assertEquals(2, message.getExtensionCount(packedFixed32Extension ));
+    Assert.assertEquals(2, message.getExtensionCount(packedFixed64Extension ));
+    Assert.assertEquals(2, message.getExtensionCount(packedSfixed32Extension));
+    Assert.assertEquals(2, message.getExtensionCount(packedSfixed64Extension));
+    Assert.assertEquals(2, message.getExtensionCount(packedFloatExtension   ));
+    Assert.assertEquals(2, message.getExtensionCount(packedDoubleExtension  ));
+    Assert.assertEquals(2, message.getExtensionCount(packedBoolExtension    ));
+    Assert.assertEquals(2, message.getExtensionCount(packedEnumExtension));
+    assertEqualsExactType(601  , message.getExtension(packedInt32Extension   , 0));
+    assertEqualsExactType(602L , message.getExtension(packedInt64Extension   , 0));
+    assertEqualsExactType(603  , message.getExtension(packedUint32Extension  , 0));
+    assertEqualsExactType(604L , message.getExtension(packedUint64Extension  , 0));
+    assertEqualsExactType(605  , message.getExtension(packedSint32Extension  , 0));
+    assertEqualsExactType(606L , message.getExtension(packedSint64Extension  , 0));
+    assertEqualsExactType(607  , message.getExtension(packedFixed32Extension , 0));
+    assertEqualsExactType(608L , message.getExtension(packedFixed64Extension , 0));
+    assertEqualsExactType(609  , message.getExtension(packedSfixed32Extension, 0));
+    assertEqualsExactType(610L , message.getExtension(packedSfixed64Extension, 0));
+    assertEqualsExactType(611F , message.getExtension(packedFloatExtension   , 0));
+    assertEqualsExactType(612D , message.getExtension(packedDoubleExtension  , 0));
+    assertEqualsExactType(true , message.getExtension(packedBoolExtension    , 0));
+    assertEqualsExactType(ForeignEnum.FOREIGN_BAR,
+                          message.getExtension(packedEnumExtension, 0));
+    assertEqualsExactType(701  , message.getExtension(packedInt32Extension   , 1));
+    assertEqualsExactType(702L , message.getExtension(packedInt64Extension   , 1));
+    assertEqualsExactType(703  , message.getExtension(packedUint32Extension  , 1));
+    assertEqualsExactType(704L , message.getExtension(packedUint64Extension  , 1));
+    assertEqualsExactType(705  , message.getExtension(packedSint32Extension  , 1));
+    assertEqualsExactType(706L , message.getExtension(packedSint64Extension  , 1));
+    assertEqualsExactType(707  , message.getExtension(packedFixed32Extension , 1));
+    assertEqualsExactType(708L , message.getExtension(packedFixed64Extension , 1));
+    assertEqualsExactType(709  , message.getExtension(packedSfixed32Extension, 1));
+    assertEqualsExactType(710L , message.getExtension(packedSfixed64Extension, 1));
+    assertEqualsExactType(711F , message.getExtension(packedFloatExtension   , 1));
+    assertEqualsExactType(712D , message.getExtension(packedDoubleExtension  , 1));
+    assertEqualsExactType(false, message.getExtension(packedBoolExtension    , 1));
+    assertEqualsExactType(ForeignEnum.FOREIGN_BAZ,
+                          message.getExtension(packedEnumExtension, 1));
+  }
+
+  // ===================================================================
+  // Lite extensions
+
+  /**
+   * Set every field of {@code message} to the values expected by
+   * {@code assertAllExtensionsSet()}.
+   */
+  public static void setAllExtensions(TestAllExtensionsLite.Builder message) {
+    message.setExtension(optionalInt32ExtensionLite   , 101);
+    message.setExtension(optionalInt64ExtensionLite   , 102L);
+    message.setExtension(optionalUint32ExtensionLite  , 103);
+    message.setExtension(optionalUint64ExtensionLite  , 104L);
+    message.setExtension(optionalSint32ExtensionLite  , 105);
+    message.setExtension(optionalSint64ExtensionLite  , 106L);
+    message.setExtension(optionalFixed32ExtensionLite , 107);
+    message.setExtension(optionalFixed64ExtensionLite , 108L);
+    message.setExtension(optionalSfixed32ExtensionLite, 109);
+    message.setExtension(optionalSfixed64ExtensionLite, 110L);
+    message.setExtension(optionalFloatExtensionLite   , 111F);
+    message.setExtension(optionalDoubleExtensionLite  , 112D);
+    message.setExtension(optionalBoolExtensionLite    , true);
+    message.setExtension(optionalStringExtensionLite  , "115");
+    message.setExtension(optionalBytesExtensionLite   , toBytes("116"));
+
+    message.setExtension(optionalGroupExtensionLite,
+      OptionalGroup_extension_lite.newBuilder().setA(117).build());
+    message.setExtension(optionalNestedMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(118).build());
+    message.setExtension(optionalForeignMessageExtensionLite,
+      ForeignMessageLite.newBuilder().setC(119).build());
+    message.setExtension(optionalImportMessageExtensionLite,
+      ImportMessageLite.newBuilder().setD(120).build());
+    message.setExtension(optionalPublicImportMessageExtensionLite,
+      PublicImportMessageLite.newBuilder().setE(126).build());
+    message.setExtension(optionalLazyMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(127).build());
+
+    message.setExtension(optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
+    message.setExtension(optionalForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+    message.setExtension(optionalImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
+
+    message.setExtension(optionalStringPieceExtensionLite, "124");
+    message.setExtension(optionalCordExtensionLite, "125");
+
+    // -----------------------------------------------------------------
+
+    message.addExtension(repeatedInt32ExtensionLite   , 201);
+    message.addExtension(repeatedInt64ExtensionLite   , 202L);
+    message.addExtension(repeatedUint32ExtensionLite  , 203);
+    message.addExtension(repeatedUint64ExtensionLite  , 204L);
+    message.addExtension(repeatedSint32ExtensionLite  , 205);
+    message.addExtension(repeatedSint64ExtensionLite  , 206L);
+    message.addExtension(repeatedFixed32ExtensionLite , 207);
+    message.addExtension(repeatedFixed64ExtensionLite , 208L);
+    message.addExtension(repeatedSfixed32ExtensionLite, 209);
+    message.addExtension(repeatedSfixed64ExtensionLite, 210L);
+    message.addExtension(repeatedFloatExtensionLite   , 211F);
+    message.addExtension(repeatedDoubleExtensionLite  , 212D);
+    message.addExtension(repeatedBoolExtensionLite    , true);
+    message.addExtension(repeatedStringExtensionLite  , "215");
+    message.addExtension(repeatedBytesExtensionLite   , toBytes("216"));
+
+    message.addExtension(repeatedGroupExtensionLite,
+      RepeatedGroup_extension_lite.newBuilder().setA(217).build());
+    message.addExtension(repeatedNestedMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(218).build());
+    message.addExtension(repeatedForeignMessageExtensionLite,
+      ForeignMessageLite.newBuilder().setC(219).build());
+    message.addExtension(repeatedImportMessageExtensionLite,
+      ImportMessageLite.newBuilder().setD(220).build());
+    message.addExtension(repeatedLazyMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(227).build());
+
+    message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAR);
+    message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
+    message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAR);
+
+    message.addExtension(repeatedStringPieceExtensionLite, "224");
+    message.addExtension(repeatedCordExtensionLite, "225");
+
+    // Add a second one of each field.
+    message.addExtension(repeatedInt32ExtensionLite   , 301);
+    message.addExtension(repeatedInt64ExtensionLite   , 302L);
+    message.addExtension(repeatedUint32ExtensionLite  , 303);
+    message.addExtension(repeatedUint64ExtensionLite  , 304L);
+    message.addExtension(repeatedSint32ExtensionLite  , 305);
+    message.addExtension(repeatedSint64ExtensionLite  , 306L);
+    message.addExtension(repeatedFixed32ExtensionLite , 307);
+    message.addExtension(repeatedFixed64ExtensionLite , 308L);
+    message.addExtension(repeatedSfixed32ExtensionLite, 309);
+    message.addExtension(repeatedSfixed64ExtensionLite, 310L);
+    message.addExtension(repeatedFloatExtensionLite   , 311F);
+    message.addExtension(repeatedDoubleExtensionLite  , 312D);
+    message.addExtension(repeatedBoolExtensionLite    , false);
+    message.addExtension(repeatedStringExtensionLite  , "315");
+    message.addExtension(repeatedBytesExtensionLite   , toBytes("316"));
+
+    message.addExtension(repeatedGroupExtensionLite,
+      RepeatedGroup_extension_lite.newBuilder().setA(317).build());
+    message.addExtension(repeatedNestedMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(318).build());
+    message.addExtension(repeatedForeignMessageExtensionLite,
+      ForeignMessageLite.newBuilder().setC(319).build());
+    message.addExtension(repeatedImportMessageExtensionLite,
+      ImportMessageLite.newBuilder().setD(320).build());
+    message.addExtension(repeatedLazyMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(327).build());
+
+    message.addExtension(repeatedNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ);
+    message.addExtension(repeatedForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+    message.addExtension(repeatedImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_BAZ);
+
+    message.addExtension(repeatedStringPieceExtensionLite, "324");
+    message.addExtension(repeatedCordExtensionLite, "325");
+
+    // -----------------------------------------------------------------
+
+    message.setExtension(defaultInt32ExtensionLite   , 401);
+    message.setExtension(defaultInt64ExtensionLite   , 402L);
+    message.setExtension(defaultUint32ExtensionLite  , 403);
+    message.setExtension(defaultUint64ExtensionLite  , 404L);
+    message.setExtension(defaultSint32ExtensionLite  , 405);
+    message.setExtension(defaultSint64ExtensionLite  , 406L);
+    message.setExtension(defaultFixed32ExtensionLite , 407);
+    message.setExtension(defaultFixed64ExtensionLite , 408L);
+    message.setExtension(defaultSfixed32ExtensionLite, 409);
+    message.setExtension(defaultSfixed64ExtensionLite, 410L);
+    message.setExtension(defaultFloatExtensionLite   , 411F);
+    message.setExtension(defaultDoubleExtensionLite  , 412D);
+    message.setExtension(defaultBoolExtensionLite    , false);
+    message.setExtension(defaultStringExtensionLite  , "415");
+    message.setExtension(defaultBytesExtensionLite   , toBytes("416"));
+
+    message.setExtension(defaultNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.FOO);
+    message.setExtension(defaultForeignEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_FOO);
+    message.setExtension(defaultImportEnumExtensionLite, ImportEnumLite.IMPORT_LITE_FOO);
+
+    message.setExtension(defaultStringPieceExtensionLite, "424");
+    message.setExtension(defaultCordExtensionLite, "425");
+
+    message.setExtension(oneofUint32ExtensionLite, 601);
+    message.setExtension(oneofNestedMessageExtensionLite,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(602).build());
+    message.setExtension(oneofStringExtensionLite, "603");
+    message.setExtension(oneofBytesExtensionLite, toBytes("604"));
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Modify the repeated extensions of {@code message} to contain the values
+   * expected by {@code assertRepeatedExtensionsModified()}.
+   */
+  public static void modifyRepeatedExtensions(
+      TestAllExtensionsLite.Builder message) {
+    message.setExtension(repeatedInt32ExtensionLite   , 1, 501);
+    message.setExtension(repeatedInt64ExtensionLite   , 1, 502L);
+    message.setExtension(repeatedUint32ExtensionLite  , 1, 503);
+    message.setExtension(repeatedUint64ExtensionLite  , 1, 504L);
+    message.setExtension(repeatedSint32ExtensionLite  , 1, 505);
+    message.setExtension(repeatedSint64ExtensionLite  , 1, 506L);
+    message.setExtension(repeatedFixed32ExtensionLite , 1, 507);
+    message.setExtension(repeatedFixed64ExtensionLite , 1, 508L);
+    message.setExtension(repeatedSfixed32ExtensionLite, 1, 509);
+    message.setExtension(repeatedSfixed64ExtensionLite, 1, 510L);
+    message.setExtension(repeatedFloatExtensionLite   , 1, 511F);
+    message.setExtension(repeatedDoubleExtensionLite  , 1, 512D);
+    message.setExtension(repeatedBoolExtensionLite    , 1, true);
+    message.setExtension(repeatedStringExtensionLite  , 1, "515");
+    message.setExtension(repeatedBytesExtensionLite   , 1, toBytes("516"));
+
+    message.setExtension(repeatedGroupExtensionLite, 1,
+      RepeatedGroup_extension_lite.newBuilder().setA(517).build());
+    message.setExtension(repeatedNestedMessageExtensionLite, 1,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(518).build());
+    message.setExtension(repeatedForeignMessageExtensionLite, 1,
+      ForeignMessageLite.newBuilder().setC(519).build());
+    message.setExtension(repeatedImportMessageExtensionLite, 1,
+      ImportMessageLite.newBuilder().setD(520).build());
+    message.setExtension(repeatedLazyMessageExtensionLite, 1,
+      TestAllTypesLite.NestedMessage.newBuilder().setBb(527).build());
+
+    message.setExtension(repeatedNestedEnumExtensionLite , 1, TestAllTypesLite.NestedEnum.FOO);
+    message.setExtension(repeatedForeignEnumExtensionLite, 1, ForeignEnumLite.FOREIGN_LITE_FOO);
+    message.setExtension(repeatedImportEnumExtensionLite , 1, ImportEnumLite.IMPORT_LITE_FOO);
+
+    message.setExtension(repeatedStringPieceExtensionLite, 1, "524");
+    message.setExtension(repeatedCordExtensionLite, 1, "525");
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all extensions of
+   * {@code message} are set to the values assigned by {@code setAllExtensions}.
+   */
+  public static void assertAllExtensionsSet(
+      TestAllExtensionsLiteOrBuilder message) {
+    Assert.assertTrue(message.hasExtension(optionalInt32ExtensionLite   ));
+    Assert.assertTrue(message.hasExtension(optionalInt64ExtensionLite   ));
+    Assert.assertTrue(message.hasExtension(optionalUint32ExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(optionalUint64ExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(optionalSint32ExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(optionalSint64ExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(optionalFixed32ExtensionLite ));
+    Assert.assertTrue(message.hasExtension(optionalFixed64ExtensionLite ));
+    Assert.assertTrue(message.hasExtension(optionalSfixed32ExtensionLite));
+    Assert.assertTrue(message.hasExtension(optionalSfixed64ExtensionLite));
+    Assert.assertTrue(message.hasExtension(optionalFloatExtensionLite   ));
+    Assert.assertTrue(message.hasExtension(optionalDoubleExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(optionalBoolExtensionLite    ));
+    Assert.assertTrue(message.hasExtension(optionalStringExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(optionalBytesExtensionLite   ));
+
+    Assert.assertTrue(message.hasExtension(optionalGroupExtensionLite         ));
+    Assert.assertTrue(message.hasExtension(optionalNestedMessageExtensionLite ));
+    Assert.assertTrue(message.hasExtension(optionalForeignMessageExtensionLite));
+    Assert.assertTrue(message.hasExtension(optionalImportMessageExtensionLite ));
+
+    Assert.assertTrue(message.getExtension(optionalGroupExtensionLite         ).hasA());
+    Assert.assertTrue(message.getExtension(optionalNestedMessageExtensionLite ).hasBb());
+    Assert.assertTrue(message.getExtension(optionalForeignMessageExtensionLite).hasC());
+    Assert.assertTrue(message.getExtension(optionalImportMessageExtensionLite ).hasD());
+
+    Assert.assertTrue(message.hasExtension(optionalNestedEnumExtensionLite ));
+    Assert.assertTrue(message.hasExtension(optionalForeignEnumExtensionLite));
+    Assert.assertTrue(message.hasExtension(optionalImportEnumExtensionLite ));
+
+    Assert.assertTrue(message.hasExtension(optionalStringPieceExtensionLite));
+    Assert.assertTrue(message.hasExtension(optionalCordExtensionLite));
+
+    assertEqualsExactType(101  , message.getExtension(optionalInt32ExtensionLite   ));
+    assertEqualsExactType(102L , message.getExtension(optionalInt64ExtensionLite   ));
+    assertEqualsExactType(103  , message.getExtension(optionalUint32ExtensionLite  ));
+    assertEqualsExactType(104L , message.getExtension(optionalUint64ExtensionLite  ));
+    assertEqualsExactType(105  , message.getExtension(optionalSint32ExtensionLite  ));
+    assertEqualsExactType(106L , message.getExtension(optionalSint64ExtensionLite  ));
+    assertEqualsExactType(107  , message.getExtension(optionalFixed32ExtensionLite ));
+    assertEqualsExactType(108L , message.getExtension(optionalFixed64ExtensionLite ));
+    assertEqualsExactType(109  , message.getExtension(optionalSfixed32ExtensionLite));
+    assertEqualsExactType(110L , message.getExtension(optionalSfixed64ExtensionLite));
+    assertEqualsExactType(111F , message.getExtension(optionalFloatExtensionLite   ));
+    assertEqualsExactType(112D , message.getExtension(optionalDoubleExtensionLite  ));
+    assertEqualsExactType(true , message.getExtension(optionalBoolExtensionLite    ));
+    assertEqualsExactType("115", message.getExtension(optionalStringExtensionLite  ));
+    assertEqualsExactType(toBytes("116"), message.getExtension(optionalBytesExtensionLite));
+
+    assertEqualsExactType(117, message.getExtension(optionalGroupExtensionLite         ).getA());
+    assertEqualsExactType(118, message.getExtension(optionalNestedMessageExtensionLite ).getBb());
+    assertEqualsExactType(119, message.getExtension(optionalForeignMessageExtensionLite).getC());
+    assertEqualsExactType(120, message.getExtension(optionalImportMessageExtensionLite ).getD());
+    assertEqualsExactType(126, message.getExtension(
+        optionalPublicImportMessageExtensionLite).getE());
+    assertEqualsExactType(127, message.getExtension(optionalLazyMessageExtensionLite).getBb());
+
+    assertEqualsExactType(TestAllTypesLite.NestedEnum.BAZ,
+      message.getExtension(optionalNestedEnumExtensionLite));
+    assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAZ,
+      message.getExtension(optionalForeignEnumExtensionLite));
+    assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAZ,
+      message.getExtension(optionalImportEnumExtensionLite));
+
+    assertEqualsExactType("124", message.getExtension(optionalStringPieceExtensionLite));
+    assertEqualsExactType("125", message.getExtension(optionalCordExtensionLite));
+
+    // -----------------------------------------------------------------
+
+    Assert.assertEquals(2, message.getExtensionCount(repeatedInt32ExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedInt64ExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedUint32ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedUint64ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSint32ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSint64ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32ExtensionLite ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64ExtensionLite ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32ExtensionLite));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64ExtensionLite));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtensionLite    ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtensionLite   ));
+
+    Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtensionLite         ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtensionLite ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtensionLite));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtensionLite ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtensionLite    ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtensionLite    ));
+
+    Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtensionLite));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtensionLite));
+
+    assertEqualsExactType(201  , message.getExtension(repeatedInt32ExtensionLite   , 0));
+    assertEqualsExactType(202L , message.getExtension(repeatedInt64ExtensionLite   , 0));
+    assertEqualsExactType(203  , message.getExtension(repeatedUint32ExtensionLite  , 0));
+    assertEqualsExactType(204L , message.getExtension(repeatedUint64ExtensionLite  , 0));
+    assertEqualsExactType(205  , message.getExtension(repeatedSint32ExtensionLite  , 0));
+    assertEqualsExactType(206L , message.getExtension(repeatedSint64ExtensionLite  , 0));
+    assertEqualsExactType(207  , message.getExtension(repeatedFixed32ExtensionLite , 0));
+    assertEqualsExactType(208L , message.getExtension(repeatedFixed64ExtensionLite , 0));
+    assertEqualsExactType(209  , message.getExtension(repeatedSfixed32ExtensionLite, 0));
+    assertEqualsExactType(210L , message.getExtension(repeatedSfixed64ExtensionLite, 0));
+    assertEqualsExactType(211F , message.getExtension(repeatedFloatExtensionLite   , 0));
+    assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtensionLite  , 0));
+    assertEqualsExactType(true , message.getExtension(repeatedBoolExtensionLite    , 0));
+    assertEqualsExactType("215", message.getExtension(repeatedStringExtensionLite  , 0));
+    assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtensionLite, 0));
+
+    assertEqualsExactType(217, message.getExtension(repeatedGroupExtensionLite         ,0).getA());
+    assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtensionLite ,0).getBb());
+    assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtensionLite,0).getC());
+    assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtensionLite ,0).getD());
+    assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtensionLite   ,0).getBb());
+
+    assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR,
+      message.getExtension(repeatedNestedEnumExtensionLite, 0));
+    assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR,
+      message.getExtension(repeatedForeignEnumExtensionLite, 0));
+    assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAR,
+      message.getExtension(repeatedImportEnumExtensionLite, 0));
+
+    assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtensionLite, 0));
+    assertEqualsExactType("225", message.getExtension(repeatedCordExtensionLite, 0));
+
+    assertEqualsExactType(301  , message.getExtension(repeatedInt32ExtensionLite   , 1));
+    assertEqualsExactType(302L , message.getExtension(repeatedInt64ExtensionLite   , 1));
+    assertEqualsExactType(303  , message.getExtension(repeatedUint32ExtensionLite  , 1));
+    assertEqualsExactType(304L , message.getExtension(repeatedUint64ExtensionLite  , 1));
+    assertEqualsExactType(305  , message.getExtension(repeatedSint32ExtensionLite  , 1));
+    assertEqualsExactType(306L , message.getExtension(repeatedSint64ExtensionLite  , 1));
+    assertEqualsExactType(307  , message.getExtension(repeatedFixed32ExtensionLite , 1));
+    assertEqualsExactType(308L , message.getExtension(repeatedFixed64ExtensionLite , 1));
+    assertEqualsExactType(309  , message.getExtension(repeatedSfixed32ExtensionLite, 1));
+    assertEqualsExactType(310L , message.getExtension(repeatedSfixed64ExtensionLite, 1));
+    assertEqualsExactType(311F , message.getExtension(repeatedFloatExtensionLite   , 1));
+    assertEqualsExactType(312D , message.getExtension(repeatedDoubleExtensionLite  , 1));
+    assertEqualsExactType(false, message.getExtension(repeatedBoolExtensionLite    , 1));
+    assertEqualsExactType("315", message.getExtension(repeatedStringExtensionLite  , 1));
+    assertEqualsExactType(toBytes("316"), message.getExtension(repeatedBytesExtensionLite, 1));
+
+    assertEqualsExactType(317, message.getExtension(repeatedGroupExtensionLite         ,1).getA());
+    assertEqualsExactType(318, message.getExtension(repeatedNestedMessageExtensionLite ,1).getBb());
+    assertEqualsExactType(319, message.getExtension(repeatedForeignMessageExtensionLite,1).getC());
+    assertEqualsExactType(320, message.getExtension(repeatedImportMessageExtensionLite ,1).getD());
+    assertEqualsExactType(327, message.getExtension(repeatedLazyMessageExtensionLite   ,1).getBb());
+
+    assertEqualsExactType(TestAllTypesLite.NestedEnum.BAZ,
+      message.getExtension(repeatedNestedEnumExtensionLite, 1));
+    assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAZ,
+      message.getExtension(repeatedForeignEnumExtensionLite, 1));
+    assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAZ,
+      message.getExtension(repeatedImportEnumExtensionLite, 1));
+
+    assertEqualsExactType("324", message.getExtension(repeatedStringPieceExtensionLite, 1));
+    assertEqualsExactType("325", message.getExtension(repeatedCordExtensionLite, 1));
+
+    // -----------------------------------------------------------------
+
+    Assert.assertTrue(message.hasExtension(defaultInt32ExtensionLite   ));
+    Assert.assertTrue(message.hasExtension(defaultInt64ExtensionLite   ));
+    Assert.assertTrue(message.hasExtension(defaultUint32ExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(defaultUint64ExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(defaultSint32ExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(defaultSint64ExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(defaultFixed32ExtensionLite ));
+    Assert.assertTrue(message.hasExtension(defaultFixed64ExtensionLite ));
+    Assert.assertTrue(message.hasExtension(defaultSfixed32ExtensionLite));
+    Assert.assertTrue(message.hasExtension(defaultSfixed64ExtensionLite));
+    Assert.assertTrue(message.hasExtension(defaultFloatExtensionLite   ));
+    Assert.assertTrue(message.hasExtension(defaultDoubleExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(defaultBoolExtensionLite    ));
+    Assert.assertTrue(message.hasExtension(defaultStringExtensionLite  ));
+    Assert.assertTrue(message.hasExtension(defaultBytesExtensionLite   ));
+
+    Assert.assertTrue(message.hasExtension(defaultNestedEnumExtensionLite ));
+    Assert.assertTrue(message.hasExtension(defaultForeignEnumExtensionLite));
+    Assert.assertTrue(message.hasExtension(defaultImportEnumExtensionLite ));
+
+    Assert.assertTrue(message.hasExtension(defaultStringPieceExtensionLite));
+    Assert.assertTrue(message.hasExtension(defaultCordExtensionLite));
+
+    assertEqualsExactType(401  , message.getExtension(defaultInt32ExtensionLite   ));
+    assertEqualsExactType(402L , message.getExtension(defaultInt64ExtensionLite   ));
+    assertEqualsExactType(403  , message.getExtension(defaultUint32ExtensionLite  ));
+    assertEqualsExactType(404L , message.getExtension(defaultUint64ExtensionLite  ));
+    assertEqualsExactType(405  , message.getExtension(defaultSint32ExtensionLite  ));
+    assertEqualsExactType(406L , message.getExtension(defaultSint64ExtensionLite  ));
+    assertEqualsExactType(407  , message.getExtension(defaultFixed32ExtensionLite ));
+    assertEqualsExactType(408L , message.getExtension(defaultFixed64ExtensionLite ));
+    assertEqualsExactType(409  , message.getExtension(defaultSfixed32ExtensionLite));
+    assertEqualsExactType(410L , message.getExtension(defaultSfixed64ExtensionLite));
+    assertEqualsExactType(411F , message.getExtension(defaultFloatExtensionLite   ));
+    assertEqualsExactType(412D , message.getExtension(defaultDoubleExtensionLite  ));
+    assertEqualsExactType(false, message.getExtension(defaultBoolExtensionLite    ));
+    assertEqualsExactType("415", message.getExtension(defaultStringExtensionLite  ));
+    assertEqualsExactType(toBytes("416"), message.getExtension(defaultBytesExtensionLite));
+
+    assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO,
+      message.getExtension(defaultNestedEnumExtensionLite ));
+    assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_FOO,
+      message.getExtension(defaultForeignEnumExtensionLite));
+    assertEqualsExactType(ImportEnumLite.IMPORT_LITE_FOO,
+      message.getExtension(defaultImportEnumExtensionLite));
+
+    assertEqualsExactType("424", message.getExtension(defaultStringPieceExtensionLite));
+    assertEqualsExactType("425", message.getExtension(defaultCordExtensionLite));
+
+    Assert.assertTrue(message.hasExtension(oneofBytesExtensionLite));
+
+    assertEqualsExactType(toBytes("604"), message.getExtension(oneofBytesExtensionLite));
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all extensions of
+   * {@code message} are cleared, and that getting the extensions returns their
+   * default values.
+   */
+  public static void assertExtensionsClear(
+      TestAllExtensionsLiteOrBuilder message) {
+    // hasBlah() should initially be false for all optional fields.
+    Assert.assertFalse(message.hasExtension(optionalInt32ExtensionLite   ));
+    Assert.assertFalse(message.hasExtension(optionalInt64ExtensionLite   ));
+    Assert.assertFalse(message.hasExtension(optionalUint32ExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(optionalUint64ExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(optionalSint32ExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(optionalSint64ExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(optionalFixed32ExtensionLite ));
+    Assert.assertFalse(message.hasExtension(optionalFixed64ExtensionLite ));
+    Assert.assertFalse(message.hasExtension(optionalSfixed32ExtensionLite));
+    Assert.assertFalse(message.hasExtension(optionalSfixed64ExtensionLite));
+    Assert.assertFalse(message.hasExtension(optionalFloatExtensionLite   ));
+    Assert.assertFalse(message.hasExtension(optionalDoubleExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(optionalBoolExtensionLite    ));
+    Assert.assertFalse(message.hasExtension(optionalStringExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(optionalBytesExtensionLite   ));
+
+    Assert.assertFalse(message.hasExtension(optionalGroupExtensionLite              ));
+    Assert.assertFalse(message.hasExtension(optionalNestedMessageExtensionLite      ));
+    Assert.assertFalse(message.hasExtension(optionalForeignMessageExtensionLite     ));
+    Assert.assertFalse(message.hasExtension(optionalImportMessageExtensionLite      ));
+    Assert.assertFalse(message.hasExtension(optionalPublicImportMessageExtensionLite));
+    Assert.assertFalse(message.hasExtension(optionalLazyMessageExtensionLite        ));
+
+    Assert.assertFalse(message.hasExtension(optionalNestedEnumExtensionLite ));
+    Assert.assertFalse(message.hasExtension(optionalForeignEnumExtensionLite));
+    Assert.assertFalse(message.hasExtension(optionalImportEnumExtensionLite ));
+
+    Assert.assertFalse(message.hasExtension(optionalStringPieceExtensionLite));
+    Assert.assertFalse(message.hasExtension(optionalCordExtensionLite));
+
+    // Optional fields without defaults are set to zero or something like it.
+    assertEqualsExactType(0    , message.getExtension(optionalInt32ExtensionLite   ));
+    assertEqualsExactType(0L   , message.getExtension(optionalInt64ExtensionLite   ));
+    assertEqualsExactType(0    , message.getExtension(optionalUint32ExtensionLite  ));
+    assertEqualsExactType(0L   , message.getExtension(optionalUint64ExtensionLite  ));
+    assertEqualsExactType(0    , message.getExtension(optionalSint32ExtensionLite  ));
+    assertEqualsExactType(0L   , message.getExtension(optionalSint64ExtensionLite  ));
+    assertEqualsExactType(0    , message.getExtension(optionalFixed32ExtensionLite ));
+    assertEqualsExactType(0L   , message.getExtension(optionalFixed64ExtensionLite ));
+    assertEqualsExactType(0    , message.getExtension(optionalSfixed32ExtensionLite));
+    assertEqualsExactType(0L   , message.getExtension(optionalSfixed64ExtensionLite));
+    assertEqualsExactType(0F   , message.getExtension(optionalFloatExtensionLite   ));
+    assertEqualsExactType(0D   , message.getExtension(optionalDoubleExtensionLite  ));
+    assertEqualsExactType(false, message.getExtension(optionalBoolExtensionLite    ));
+    assertEqualsExactType(""   , message.getExtension(optionalStringExtensionLite  ));
+    assertEqualsExactType(ByteString.EMPTY, message.getExtension(optionalBytesExtensionLite));
+
+    // Embedded messages should also be clear.
+    Assert.assertFalse(message.getExtension(optionalGroupExtensionLite              ).hasA());
+    Assert.assertFalse(message.getExtension(optionalNestedMessageExtensionLite      ).hasBb());
+    Assert.assertFalse(message.getExtension(optionalForeignMessageExtensionLite     ).hasC());
+    Assert.assertFalse(message.getExtension(optionalImportMessageExtensionLite      ).hasD());
+    Assert.assertFalse(message.getExtension(optionalPublicImportMessageExtensionLite).hasE());
+    Assert.assertFalse(message.getExtension(optionalLazyMessageExtensionLite        ).hasBb());
+
+    assertEqualsExactType(0, message.getExtension(optionalGroupExtensionLite         ).getA());
+    assertEqualsExactType(0, message.getExtension(optionalNestedMessageExtensionLite ).getBb());
+    assertEqualsExactType(0, message.getExtension(optionalForeignMessageExtensionLite).getC());
+    assertEqualsExactType(0, message.getExtension(optionalImportMessageExtensionLite ).getD());
+    assertEqualsExactType(0, message.getExtension(
+        optionalPublicImportMessageExtensionLite).getE());
+    assertEqualsExactType(0, message.getExtension(optionalLazyMessageExtensionLite   ).getBb());
+
+    // Enums without defaults are set to the first value in the enum.
+    assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO,
+      message.getExtension(optionalNestedEnumExtensionLite ));
+    assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_FOO,
+      message.getExtension(optionalForeignEnumExtensionLite));
+    assertEqualsExactType(ImportEnumLite.IMPORT_LITE_FOO,
+      message.getExtension(optionalImportEnumExtensionLite));
+
+    assertEqualsExactType("", message.getExtension(optionalStringPieceExtensionLite));
+    assertEqualsExactType("", message.getExtension(optionalCordExtensionLite));
+
+    // Repeated fields are empty.
+    Assert.assertEquals(0, message.getExtensionCount(repeatedInt32ExtensionLite   ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedInt64ExtensionLite   ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedUint32ExtensionLite  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedUint64ExtensionLite  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedSint32ExtensionLite  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedSint64ExtensionLite  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedFixed32ExtensionLite ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedFixed64ExtensionLite ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed32ExtensionLite));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedSfixed64ExtensionLite));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedFloatExtensionLite   ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedDoubleExtensionLite  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedBoolExtensionLite    ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedStringExtensionLite  ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedBytesExtensionLite   ));
+
+    Assert.assertEquals(0, message.getExtensionCount(repeatedGroupExtensionLite         ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedNestedMessageExtensionLite ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedForeignMessageExtensionLite));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedImportMessageExtensionLite ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedLazyMessageExtensionLite   ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedNestedEnumExtensionLite    ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedForeignEnumExtensionLite   ));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedImportEnumExtensionLite    ));
+
+    Assert.assertEquals(0, message.getExtensionCount(repeatedStringPieceExtensionLite));
+    Assert.assertEquals(0, message.getExtensionCount(repeatedCordExtensionLite));
+
+    // hasBlah() should also be false for all default fields.
+    Assert.assertFalse(message.hasExtension(defaultInt32ExtensionLite   ));
+    Assert.assertFalse(message.hasExtension(defaultInt64ExtensionLite   ));
+    Assert.assertFalse(message.hasExtension(defaultUint32ExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(defaultUint64ExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(defaultSint32ExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(defaultSint64ExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(defaultFixed32ExtensionLite ));
+    Assert.assertFalse(message.hasExtension(defaultFixed64ExtensionLite ));
+    Assert.assertFalse(message.hasExtension(defaultSfixed32ExtensionLite));
+    Assert.assertFalse(message.hasExtension(defaultSfixed64ExtensionLite));
+    Assert.assertFalse(message.hasExtension(defaultFloatExtensionLite   ));
+    Assert.assertFalse(message.hasExtension(defaultDoubleExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(defaultBoolExtensionLite    ));
+    Assert.assertFalse(message.hasExtension(defaultStringExtensionLite  ));
+    Assert.assertFalse(message.hasExtension(defaultBytesExtensionLite   ));
+
+    Assert.assertFalse(message.hasExtension(defaultNestedEnumExtensionLite ));
+    Assert.assertFalse(message.hasExtension(defaultForeignEnumExtensionLite));
+    Assert.assertFalse(message.hasExtension(defaultImportEnumExtensionLite ));
+
+    Assert.assertFalse(message.hasExtension(defaultStringPieceExtensionLite));
+    Assert.assertFalse(message.hasExtension(defaultCordExtensionLite));
+
+    // Fields with defaults have their default values (duh).
+    assertEqualsExactType( 41    , message.getExtension(defaultInt32ExtensionLite   ));
+    assertEqualsExactType( 42L   , message.getExtension(defaultInt64ExtensionLite   ));
+    assertEqualsExactType( 43    , message.getExtension(defaultUint32ExtensionLite  ));
+    assertEqualsExactType( 44L   , message.getExtension(defaultUint64ExtensionLite  ));
+    assertEqualsExactType(-45    , message.getExtension(defaultSint32ExtensionLite  ));
+    assertEqualsExactType( 46L   , message.getExtension(defaultSint64ExtensionLite  ));
+    assertEqualsExactType( 47    , message.getExtension(defaultFixed32ExtensionLite ));
+    assertEqualsExactType( 48L   , message.getExtension(defaultFixed64ExtensionLite ));
+    assertEqualsExactType( 49    , message.getExtension(defaultSfixed32ExtensionLite));
+    assertEqualsExactType(-50L   , message.getExtension(defaultSfixed64ExtensionLite));
+    assertEqualsExactType( 51.5F , message.getExtension(defaultFloatExtensionLite   ));
+    assertEqualsExactType( 52e3D , message.getExtension(defaultDoubleExtensionLite  ));
+    assertEqualsExactType(true   , message.getExtension(defaultBoolExtensionLite    ));
+    assertEqualsExactType("hello", message.getExtension(defaultStringExtensionLite  ));
+    assertEqualsExactType(toBytes("world"), message.getExtension(defaultBytesExtensionLite));
+
+    assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR,
+      message.getExtension(defaultNestedEnumExtensionLite ));
+    assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR,
+      message.getExtension(defaultForeignEnumExtensionLite));
+    assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAR,
+      message.getExtension(defaultImportEnumExtensionLite));
+
+    assertEqualsExactType("abc", message.getExtension(defaultStringPieceExtensionLite));
+    assertEqualsExactType("123", message.getExtension(defaultCordExtensionLite));
+
+    Assert.assertFalse(message.hasExtension(oneofUint32ExtensionLite));
+    Assert.assertFalse(message.hasExtension(oneofNestedMessageExtensionLite));
+    Assert.assertFalse(message.hasExtension(oneofStringExtensionLite));
+    Assert.assertFalse(message.hasExtension(oneofBytesExtensionLite));
+  }
+
+  // -------------------------------------------------------------------
+
+  /**
+   * Assert (using {@code junit.framework.Assert}} that all extensions of
+   * {@code message} are set to the values assigned by {@code setAllExtensions}
+   * followed by {@code modifyRepeatedExtensions}.
+   */
+  public static void assertRepeatedExtensionsModified(
+      TestAllExtensionsLiteOrBuilder 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.assertEquals(2, message.getExtensionCount(repeatedInt32ExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedInt64ExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedUint32ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedUint64ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSint32ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSint64ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed32ExtensionLite ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFixed64ExtensionLite ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed32ExtensionLite));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedSfixed64ExtensionLite));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedFloatExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedDoubleExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedBoolExtensionLite    ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedStringExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedBytesExtensionLite   ));
+
+    Assert.assertEquals(2, message.getExtensionCount(repeatedGroupExtensionLite         ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedMessageExtensionLite ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignMessageExtensionLite));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedImportMessageExtensionLite ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedLazyMessageExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedNestedEnumExtensionLite    ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedForeignEnumExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedImportEnumExtensionLite    ));
+
+    Assert.assertEquals(2, message.getExtensionCount(repeatedStringPieceExtensionLite));
+    Assert.assertEquals(2, message.getExtensionCount(repeatedCordExtensionLite));
+
+    assertEqualsExactType(201  , message.getExtension(repeatedInt32ExtensionLite   , 0));
+    assertEqualsExactType(202L , message.getExtension(repeatedInt64ExtensionLite   , 0));
+    assertEqualsExactType(203  , message.getExtension(repeatedUint32ExtensionLite  , 0));
+    assertEqualsExactType(204L , message.getExtension(repeatedUint64ExtensionLite  , 0));
+    assertEqualsExactType(205  , message.getExtension(repeatedSint32ExtensionLite  , 0));
+    assertEqualsExactType(206L , message.getExtension(repeatedSint64ExtensionLite  , 0));
+    assertEqualsExactType(207  , message.getExtension(repeatedFixed32ExtensionLite , 0));
+    assertEqualsExactType(208L , message.getExtension(repeatedFixed64ExtensionLite , 0));
+    assertEqualsExactType(209  , message.getExtension(repeatedSfixed32ExtensionLite, 0));
+    assertEqualsExactType(210L , message.getExtension(repeatedSfixed64ExtensionLite, 0));
+    assertEqualsExactType(211F , message.getExtension(repeatedFloatExtensionLite   , 0));
+    assertEqualsExactType(212D , message.getExtension(repeatedDoubleExtensionLite  , 0));
+    assertEqualsExactType(true , message.getExtension(repeatedBoolExtensionLite    , 0));
+    assertEqualsExactType("215", message.getExtension(repeatedStringExtensionLite  , 0));
+    assertEqualsExactType(toBytes("216"), message.getExtension(repeatedBytesExtensionLite, 0));
+
+    assertEqualsExactType(217, message.getExtension(repeatedGroupExtensionLite         ,0).getA());
+    assertEqualsExactType(218, message.getExtension(repeatedNestedMessageExtensionLite ,0).getBb());
+    assertEqualsExactType(219, message.getExtension(repeatedForeignMessageExtensionLite,0).getC());
+    assertEqualsExactType(220, message.getExtension(repeatedImportMessageExtensionLite ,0).getD());
+    assertEqualsExactType(227, message.getExtension(repeatedLazyMessageExtensionLite   ,0).getBb());
+
+    assertEqualsExactType(TestAllTypesLite.NestedEnum.BAR,
+      message.getExtension(repeatedNestedEnumExtensionLite, 0));
+    assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR,
+      message.getExtension(repeatedForeignEnumExtensionLite, 0));
+    assertEqualsExactType(ImportEnumLite.IMPORT_LITE_BAR,
+      message.getExtension(repeatedImportEnumExtensionLite, 0));
+
+    assertEqualsExactType("224", message.getExtension(repeatedStringPieceExtensionLite, 0));
+    assertEqualsExactType("225", message.getExtension(repeatedCordExtensionLite, 0));
+
+    // Actually verify the second (modified) elements now.
+    assertEqualsExactType(501  , message.getExtension(repeatedInt32ExtensionLite   , 1));
+    assertEqualsExactType(502L , message.getExtension(repeatedInt64ExtensionLite   , 1));
+    assertEqualsExactType(503  , message.getExtension(repeatedUint32ExtensionLite  , 1));
+    assertEqualsExactType(504L , message.getExtension(repeatedUint64ExtensionLite  , 1));
+    assertEqualsExactType(505  , message.getExtension(repeatedSint32ExtensionLite  , 1));
+    assertEqualsExactType(506L , message.getExtension(repeatedSint64ExtensionLite  , 1));
+    assertEqualsExactType(507  , message.getExtension(repeatedFixed32ExtensionLite , 1));
+    assertEqualsExactType(508L , message.getExtension(repeatedFixed64ExtensionLite , 1));
+    assertEqualsExactType(509  , message.getExtension(repeatedSfixed32ExtensionLite, 1));
+    assertEqualsExactType(510L , message.getExtension(repeatedSfixed64ExtensionLite, 1));
+    assertEqualsExactType(511F , message.getExtension(repeatedFloatExtensionLite   , 1));
+    assertEqualsExactType(512D , message.getExtension(repeatedDoubleExtensionLite  , 1));
+    assertEqualsExactType(true , message.getExtension(repeatedBoolExtensionLite    , 1));
+    assertEqualsExactType("515", message.getExtension(repeatedStringExtensionLite  , 1));
+    assertEqualsExactType(toBytes("516"), message.getExtension(repeatedBytesExtensionLite, 1));
+
+    assertEqualsExactType(517, message.getExtension(repeatedGroupExtensionLite         ,1).getA());
+    assertEqualsExactType(518, message.getExtension(repeatedNestedMessageExtensionLite ,1).getBb());
+    assertEqualsExactType(519, message.getExtension(repeatedForeignMessageExtensionLite,1).getC());
+    assertEqualsExactType(520, message.getExtension(repeatedImportMessageExtensionLite ,1).getD());
+    assertEqualsExactType(527, message.getExtension(repeatedLazyMessageExtensionLite   ,1).getBb());
+
+    assertEqualsExactType(TestAllTypesLite.NestedEnum.FOO,
+      message.getExtension(repeatedNestedEnumExtensionLite, 1));
+    assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_FOO,
+      message.getExtension(repeatedForeignEnumExtensionLite, 1));
+    assertEqualsExactType(ImportEnumLite.IMPORT_LITE_FOO,
+      message.getExtension(repeatedImportEnumExtensionLite, 1));
+
+    assertEqualsExactType("524", message.getExtension(repeatedStringPieceExtensionLite, 1));
+    assertEqualsExactType("525", message.getExtension(repeatedCordExtensionLite, 1));
+  }
+
+  public static void setPackedExtensions(TestPackedExtensionsLite.Builder message) {
+    message.addExtension(packedInt32ExtensionLite   , 601);
+    message.addExtension(packedInt64ExtensionLite   , 602L);
+    message.addExtension(packedUint32ExtensionLite  , 603);
+    message.addExtension(packedUint64ExtensionLite  , 604L);
+    message.addExtension(packedSint32ExtensionLite  , 605);
+    message.addExtension(packedSint64ExtensionLite  , 606L);
+    message.addExtension(packedFixed32ExtensionLite , 607);
+    message.addExtension(packedFixed64ExtensionLite , 608L);
+    message.addExtension(packedSfixed32ExtensionLite, 609);
+    message.addExtension(packedSfixed64ExtensionLite, 610L);
+    message.addExtension(packedFloatExtensionLite   , 611F);
+    message.addExtension(packedDoubleExtensionLite  , 612D);
+    message.addExtension(packedBoolExtensionLite    , true);
+    message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAR);
+    // Add a second one of each field.
+    message.addExtension(packedInt32ExtensionLite   , 701);
+    message.addExtension(packedInt64ExtensionLite   , 702L);
+    message.addExtension(packedUint32ExtensionLite  , 703);
+    message.addExtension(packedUint64ExtensionLite  , 704L);
+    message.addExtension(packedSint32ExtensionLite  , 705);
+    message.addExtension(packedSint64ExtensionLite  , 706L);
+    message.addExtension(packedFixed32ExtensionLite , 707);
+    message.addExtension(packedFixed64ExtensionLite , 708L);
+    message.addExtension(packedSfixed32ExtensionLite, 709);
+    message.addExtension(packedSfixed64ExtensionLite, 710L);
+    message.addExtension(packedFloatExtensionLite   , 711F);
+    message.addExtension(packedDoubleExtensionLite  , 712D);
+    message.addExtension(packedBoolExtensionLite    , false);
+    message.addExtension(packedEnumExtensionLite, ForeignEnumLite.FOREIGN_LITE_BAZ);
+  }
+
+  public static void assertPackedExtensionsSet(TestPackedExtensionsLite message) {
+    Assert.assertEquals(2, message.getExtensionCount(packedInt32ExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(packedInt64ExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(packedUint32ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(packedUint64ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(packedSint32ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(packedSint64ExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(packedFixed32ExtensionLite ));
+    Assert.assertEquals(2, message.getExtensionCount(packedFixed64ExtensionLite ));
+    Assert.assertEquals(2, message.getExtensionCount(packedSfixed32ExtensionLite));
+    Assert.assertEquals(2, message.getExtensionCount(packedSfixed64ExtensionLite));
+    Assert.assertEquals(2, message.getExtensionCount(packedFloatExtensionLite   ));
+    Assert.assertEquals(2, message.getExtensionCount(packedDoubleExtensionLite  ));
+    Assert.assertEquals(2, message.getExtensionCount(packedBoolExtensionLite    ));
+    Assert.assertEquals(2, message.getExtensionCount(packedEnumExtensionLite));
+    assertEqualsExactType(601  , message.getExtension(packedInt32ExtensionLite   , 0));
+    assertEqualsExactType(602L , message.getExtension(packedInt64ExtensionLite   , 0));
+    assertEqualsExactType(603  , message.getExtension(packedUint32ExtensionLite  , 0));
+    assertEqualsExactType(604L , message.getExtension(packedUint64ExtensionLite  , 0));
+    assertEqualsExactType(605  , message.getExtension(packedSint32ExtensionLite  , 0));
+    assertEqualsExactType(606L , message.getExtension(packedSint64ExtensionLite  , 0));
+    assertEqualsExactType(607  , message.getExtension(packedFixed32ExtensionLite , 0));
+    assertEqualsExactType(608L , message.getExtension(packedFixed64ExtensionLite , 0));
+    assertEqualsExactType(609  , message.getExtension(packedSfixed32ExtensionLite, 0));
+    assertEqualsExactType(610L , message.getExtension(packedSfixed64ExtensionLite, 0));
+    assertEqualsExactType(611F , message.getExtension(packedFloatExtensionLite   , 0));
+    assertEqualsExactType(612D , message.getExtension(packedDoubleExtensionLite  , 0));
+    assertEqualsExactType(true , message.getExtension(packedBoolExtensionLite    , 0));
+    assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAR,
+                          message.getExtension(packedEnumExtensionLite, 0));
+    assertEqualsExactType(701  , message.getExtension(packedInt32ExtensionLite   , 1));
+    assertEqualsExactType(702L , message.getExtension(packedInt64ExtensionLite   , 1));
+    assertEqualsExactType(703  , message.getExtension(packedUint32ExtensionLite  , 1));
+    assertEqualsExactType(704L , message.getExtension(packedUint64ExtensionLite  , 1));
+    assertEqualsExactType(705  , message.getExtension(packedSint32ExtensionLite  , 1));
+    assertEqualsExactType(706L , message.getExtension(packedSint64ExtensionLite  , 1));
+    assertEqualsExactType(707  , message.getExtension(packedFixed32ExtensionLite , 1));
+    assertEqualsExactType(708L , message.getExtension(packedFixed64ExtensionLite , 1));
+    assertEqualsExactType(709  , message.getExtension(packedSfixed32ExtensionLite, 1));
+    assertEqualsExactType(710L , message.getExtension(packedSfixed64ExtensionLite, 1));
+    assertEqualsExactType(711F , message.getExtension(packedFloatExtensionLite   , 1));
+    assertEqualsExactType(712D , message.getExtension(packedDoubleExtensionLite  , 1));
+    assertEqualsExactType(false, message.getExtension(packedBoolExtensionLite    , 1));
+    assertEqualsExactType(ForeignEnumLite.FOREIGN_LITE_BAZ,
+                          message.getExtension(packedEnumExtensionLite, 1));
+  }
+
+  // ===================================================================
+  // oneof
+  public static void setOneof(TestOneof2.Builder message) {
+    message.setFooLazyMessage(
+        TestOneof2.NestedMessage.newBuilder().setQuxInt(100).build());
+    message.setBarString("101");
+    message.setBazInt(102);
+    message.setBazString("103");
+  }
+
+  public static void assertOneofSet(TestOneof2 message) {
+    Assert.assertTrue(message.hasFooLazyMessage            ());
+    Assert.assertTrue(message.getFooLazyMessage().hasQuxInt());
+
+    Assert.assertTrue(message.hasBarString());
+    Assert.assertTrue(message.hasBazInt   ());
+    Assert.assertTrue(message.hasBazString());
+
+    Assert.assertEquals(100  , message.getFooLazyMessage().getQuxInt());
+    Assert.assertEquals("101", message.getBarString                 ());
+    Assert.assertEquals(102  , message.getBazInt                    ());
+    Assert.assertEquals("103", message.getBazString                 ());
+  }
+
+  public static void assertAtMostOneFieldSetOneof(TestOneof2 message) {
+    int count = 0;
+    if (message.hasFooInt()) { ++count; }
+    if (message.hasFooString()) { ++count; }
+    if (message.hasFooCord()) { ++count; }
+    if (message.hasFooStringPiece()) { ++count; }
+    if (message.hasFooBytes()) { ++count; }
+    if (message.hasFooEnum()) { ++count; }
+    if (message.hasFooMessage()) { ++count; }
+    if (message.hasFooGroup()) { ++count; }
+    if (message.hasFooLazyMessage()) { ++count; }
+    Assert.assertTrue(count <= 1);
+
+    count = 0;
+    if (message.hasBarInt()) { ++count; }
+    if (message.hasBarString()) { ++count; }
+    if (message.hasBarCord()) { ++count; }
+    if (message.hasBarStringPiece()) { ++count; }
+    if (message.hasBarBytes()) { ++count; }
+    if (message.hasBarEnum()) { ++count; }
+    Assert.assertTrue(count <= 1);
+
+    switch (message.getFooCase()) {
+      case FOO_INT:
+        Assert.assertTrue(message.hasFooInt());
+        break;
+      case FOO_STRING:
+        Assert.assertTrue(message.hasFooString());
+        break;
+      case FOO_CORD:
+        Assert.assertTrue(message.hasFooCord());
+        break;
+      case FOO_BYTES:
+        Assert.assertTrue(message.hasFooBytes());
+        break;
+      case FOO_ENUM:
+        Assert.assertTrue(message.hasFooEnum());
+        break;
+      case FOO_MESSAGE:
+        Assert.assertTrue(message.hasFooMessage());
+        break;
+      case FOOGROUP:
+        Assert.assertTrue(message.hasFooGroup());
+        break;
+      case FOO_LAZY_MESSAGE:
+        Assert.assertTrue(message.hasFooLazyMessage());
+        break;
+      case FOO_NOT_SET:
+        break;
+    }
+  }
+
+  // =================================================================
+
+  /**
+   * Performs the same things that the methods of {@code TestUtil} do, but
+   * via the reflection interface.  This is its own class because it needs
+   * to know what descriptor to use.
+   */
+  public static class ReflectionTester {
+    private final Descriptors.Descriptor baseDescriptor;
+    private final ExtensionRegistry extensionRegistry;
+
+    private final Descriptors.FileDescriptor file;
+    private final Descriptors.FileDescriptor importFile;
+    private final Descriptors.FileDescriptor publicImportFile;
+
+    private final Descriptors.Descriptor optionalGroup;
+    private final Descriptors.Descriptor repeatedGroup;
+    private final Descriptors.Descriptor nestedMessage;
+    private final Descriptors.Descriptor foreignMessage;
+    private final Descriptors.Descriptor importMessage;
+    private final Descriptors.Descriptor publicImportMessage;
+
+    private final Descriptors.FieldDescriptor groupA;
+    private final Descriptors.FieldDescriptor repeatedGroupA;
+    private final Descriptors.FieldDescriptor nestedB;
+    private final Descriptors.FieldDescriptor foreignC;
+    private final Descriptors.FieldDescriptor importD;
+    private final Descriptors.FieldDescriptor importE;
+
+    private final Descriptors.EnumDescriptor nestedEnum;
+    private final Descriptors.EnumDescriptor foreignEnum;
+    private final Descriptors.EnumDescriptor importEnum;
+
+    private final Descriptors.EnumValueDescriptor nestedFoo;
+    private final Descriptors.EnumValueDescriptor nestedBar;
+    private final Descriptors.EnumValueDescriptor nestedBaz;
+    private final Descriptors.EnumValueDescriptor foreignFoo;
+    private final Descriptors.EnumValueDescriptor foreignBar;
+    private final Descriptors.EnumValueDescriptor foreignBaz;
+    private final Descriptors.EnumValueDescriptor importFoo;
+    private final Descriptors.EnumValueDescriptor importBar;
+    private final Descriptors.EnumValueDescriptor importBaz;
+
+    /**
+     * Construct a {@code ReflectionTester} that will expect messages using
+     * the given descriptor.
+     *
+     * Normally {@code baseDescriptor} should be a descriptor for the type
+     * {@code TestAllTypes}, defined in
+     * {@code google/protobuf/unittest.proto}.  However, if
+     * {@code extensionRegistry} is non-null, then {@code baseDescriptor} should
+     * be for {@code TestAllExtensions} instead, and instead of reading and
+     * writing normal fields, the tester will read and write extensions.
+     * All of {@code TestAllExtensions}' extensions must be registered in the
+     * registry.
+     */
+    public ReflectionTester(Descriptors.Descriptor baseDescriptor,
+                            ExtensionRegistry extensionRegistry) {
+      this.baseDescriptor = baseDescriptor;
+      this.extensionRegistry = extensionRegistry;
+
+      this.file = baseDescriptor.getFile();
+      Assert.assertEquals(1, file.getDependencies().size());
+      this.importFile = file.getDependencies().get(0);
+      this.publicImportFile = importFile.getDependencies().get(0);
+
+      Descriptors.Descriptor testAllTypes;
+      if (baseDescriptor.getName() == "TestAllTypes") {
+        testAllTypes = baseDescriptor;
+      } else {
+        testAllTypes = file.findMessageTypeByName("TestAllTypes");
+        Assert.assertNotNull(testAllTypes);
+      }
+
+      if (extensionRegistry == null) {
+        // Use testAllTypes, rather than baseDescriptor, to allow
+        // initialization using TestPackedTypes descriptors. These objects
+        // won't be used by the methods for packed fields.
+        this.optionalGroup =
+          testAllTypes.findNestedTypeByName("OptionalGroup");
+        this.repeatedGroup =
+          testAllTypes.findNestedTypeByName("RepeatedGroup");
+      } else {
+        this.optionalGroup =
+          file.findMessageTypeByName("OptionalGroup_extension");
+        this.repeatedGroup =
+          file.findMessageTypeByName("RepeatedGroup_extension");
+      }
+      this.nestedMessage = testAllTypes.findNestedTypeByName("NestedMessage");
+      this.foreignMessage = file.findMessageTypeByName("ForeignMessage");
+      this.importMessage = importFile.findMessageTypeByName("ImportMessage");
+      this.publicImportMessage = publicImportFile.findMessageTypeByName(
+          "PublicImportMessage");
+
+      this.nestedEnum = testAllTypes.findEnumTypeByName("NestedEnum");
+      this.foreignEnum = file.findEnumTypeByName("ForeignEnum");
+      this.importEnum = importFile.findEnumTypeByName("ImportEnum");
+
+      Assert.assertNotNull(optionalGroup );
+      Assert.assertNotNull(repeatedGroup );
+      Assert.assertNotNull(nestedMessage );
+      Assert.assertNotNull(foreignMessage);
+      Assert.assertNotNull(importMessage );
+      Assert.assertNotNull(nestedEnum    );
+      Assert.assertNotNull(foreignEnum   );
+      Assert.assertNotNull(importEnum    );
+
+      this.nestedB  = nestedMessage .findFieldByName("bb");
+      this.foreignC = foreignMessage.findFieldByName("c");
+      this.importD  = importMessage .findFieldByName("d");
+      this.importE  = publicImportMessage.findFieldByName("e");
+      this.nestedFoo = nestedEnum.findValueByName("FOO");
+      this.nestedBar = nestedEnum.findValueByName("BAR");
+      this.nestedBaz = nestedEnum.findValueByName("BAZ");
+      this.foreignFoo = foreignEnum.findValueByName("FOREIGN_FOO");
+      this.foreignBar = foreignEnum.findValueByName("FOREIGN_BAR");
+      this.foreignBaz = foreignEnum.findValueByName("FOREIGN_BAZ");
+      this.importFoo = importEnum.findValueByName("IMPORT_FOO");
+      this.importBar = importEnum.findValueByName("IMPORT_BAR");
+      this.importBaz = importEnum.findValueByName("IMPORT_BAZ");
+
+      this.groupA = optionalGroup.findFieldByName("a");
+      this.repeatedGroupA = repeatedGroup.findFieldByName("a");
+
+      Assert.assertNotNull(groupA        );
+      Assert.assertNotNull(repeatedGroupA);
+      Assert.assertNotNull(nestedB       );
+      Assert.assertNotNull(foreignC      );
+      Assert.assertNotNull(importD       );
+      Assert.assertNotNull(importE       );
+      Assert.assertNotNull(nestedFoo     );
+      Assert.assertNotNull(nestedBar     );
+      Assert.assertNotNull(nestedBaz     );
+      Assert.assertNotNull(foreignFoo    );
+      Assert.assertNotNull(foreignBar    );
+      Assert.assertNotNull(foreignBaz    );
+      Assert.assertNotNull(importFoo     );
+      Assert.assertNotNull(importBar     );
+      Assert.assertNotNull(importBaz     );
+    }
+
+    /**
+     * Shorthand to get a FieldDescriptor for a field of unittest::TestAllTypes.
+     */
+    private Descriptors.FieldDescriptor f(String name) {
+      Descriptors.FieldDescriptor result;
+      if (extensionRegistry == null) {
+        result = baseDescriptor.findFieldByName(name);
+      } else {
+        result = file.findExtensionByName(name + "_extension");
+      }
+      Assert.assertNotNull(result);
+      return result;
+    }
+
+    /**
+     * Calls {@code parent.newBuilderForField()} or uses the
+     * {@code ExtensionRegistry} to find an appropriate builder, depending
+     * on what type is being tested.
+     */
+    private Message.Builder newBuilderForField(
+        Message.Builder parent, Descriptors.FieldDescriptor field) {
+      if (extensionRegistry == null) {
+        return parent.newBuilderForField(field);
+      } else {
+        ExtensionRegistry.ExtensionInfo extension =
+          extensionRegistry.findImmutableExtensionByNumber(
+              field.getContainingType(), field.getNumber());
+        Assert.assertNotNull(extension);
+        Assert.assertNotNull(extension.defaultInstance);
+        return extension.defaultInstance.newBuilderForType();
+      }
+    }
+
+    // -------------------------------------------------------------------
+
+    /**
+     * Set every field of {@code message} to the values expected by
+     * {@code assertAllFieldsSet()}, using the {@link Message.Builder}
+     * reflection interface.
+     */
+    void setAllFieldsViaReflection(Message.Builder message) {
+      message.setField(f("optional_int32"   ), 101 );
+      message.setField(f("optional_int64"   ), 102L);
+      message.setField(f("optional_uint32"  ), 103 );
+      message.setField(f("optional_uint64"  ), 104L);
+      message.setField(f("optional_sint32"  ), 105 );
+      message.setField(f("optional_sint64"  ), 106L);
+      message.setField(f("optional_fixed32" ), 107 );
+      message.setField(f("optional_fixed64" ), 108L);
+      message.setField(f("optional_sfixed32"), 109 );
+      message.setField(f("optional_sfixed64"), 110L);
+      message.setField(f("optional_float"   ), 111F);
+      message.setField(f("optional_double"  ), 112D);
+      message.setField(f("optional_bool"    ), true);
+      message.setField(f("optional_string"  ), "115");
+      message.setField(f("optional_bytes"   ), toBytes("116"));
+
+      message.setField(f("optionalgroup"),
+        newBuilderForField(message, f("optionalgroup"))
+               .setField(groupA, 117).build());
+      message.setField(f("optional_nested_message"),
+        newBuilderForField(message, f("optional_nested_message"))
+               .setField(nestedB, 118).build());
+      message.setField(f("optional_foreign_message"),
+        newBuilderForField(message, f("optional_foreign_message"))
+               .setField(foreignC, 119).build());
+      message.setField(f("optional_import_message"),
+        newBuilderForField(message, f("optional_import_message"))
+               .setField(importD, 120).build());
+      message.setField(f("optional_public_import_message"),
+        newBuilderForField(message, f("optional_public_import_message"))
+               .setField(importE, 126).build());
+      message.setField(f("optional_lazy_message"),
+        newBuilderForField(message, f("optional_lazy_message"))
+               .setField(nestedB, 127).build());
+
+      message.setField(f("optional_nested_enum" ),  nestedBaz);
+      message.setField(f("optional_foreign_enum"), foreignBaz);
+      message.setField(f("optional_import_enum" ),  importBaz);
+
+      message.setField(f("optional_string_piece" ), "124");
+      message.setField(f("optional_cord" ), "125");
+
+      // -----------------------------------------------------------------
+
+      message.addRepeatedField(f("repeated_int32"   ), 201 );
+      message.addRepeatedField(f("repeated_int64"   ), 202L);
+      message.addRepeatedField(f("repeated_uint32"  ), 203 );
+      message.addRepeatedField(f("repeated_uint64"  ), 204L);
+      message.addRepeatedField(f("repeated_sint32"  ), 205 );
+      message.addRepeatedField(f("repeated_sint64"  ), 206L);
+      message.addRepeatedField(f("repeated_fixed32" ), 207 );
+      message.addRepeatedField(f("repeated_fixed64" ), 208L);
+      message.addRepeatedField(f("repeated_sfixed32"), 209 );
+      message.addRepeatedField(f("repeated_sfixed64"), 210L);
+      message.addRepeatedField(f("repeated_float"   ), 211F);
+      message.addRepeatedField(f("repeated_double"  ), 212D);
+      message.addRepeatedField(f("repeated_bool"    ), true);
+      message.addRepeatedField(f("repeated_string"  ), "215");
+      message.addRepeatedField(f("repeated_bytes"   ), toBytes("216"));
+
+      message.addRepeatedField(f("repeatedgroup"),
+        newBuilderForField(message, f("repeatedgroup"))
+               .setField(repeatedGroupA, 217).build());
+      message.addRepeatedField(f("repeated_nested_message"),
+        newBuilderForField(message, f("repeated_nested_message"))
+               .setField(nestedB, 218).build());
+      message.addRepeatedField(f("repeated_foreign_message"),
+        newBuilderForField(message, f("repeated_foreign_message"))
+               .setField(foreignC, 219).build());
+      message.addRepeatedField(f("repeated_import_message"),
+        newBuilderForField(message, f("repeated_import_message"))
+               .setField(importD, 220).build());
+      message.addRepeatedField(f("repeated_lazy_message"),
+        newBuilderForField(message, f("repeated_lazy_message"))
+               .setField(nestedB, 227).build());
+
+      message.addRepeatedField(f("repeated_nested_enum" ),  nestedBar);
+      message.addRepeatedField(f("repeated_foreign_enum"), foreignBar);
+      message.addRepeatedField(f("repeated_import_enum" ),  importBar);
+
+      message.addRepeatedField(f("repeated_string_piece" ), "224");
+      message.addRepeatedField(f("repeated_cord" ), "225");
+
+      // Add a second one of each field.
+      message.addRepeatedField(f("repeated_int32"   ), 301 );
+      message.addRepeatedField(f("repeated_int64"   ), 302L);
+      message.addRepeatedField(f("repeated_uint32"  ), 303 );
+      message.addRepeatedField(f("repeated_uint64"  ), 304L);
+      message.addRepeatedField(f("repeated_sint32"  ), 305 );
+      message.addRepeatedField(f("repeated_sint64"  ), 306L);
+      message.addRepeatedField(f("repeated_fixed32" ), 307 );
+      message.addRepeatedField(f("repeated_fixed64" ), 308L);
+      message.addRepeatedField(f("repeated_sfixed32"), 309 );
+      message.addRepeatedField(f("repeated_sfixed64"), 310L);
+      message.addRepeatedField(f("repeated_float"   ), 311F);
+      message.addRepeatedField(f("repeated_double"  ), 312D);
+      message.addRepeatedField(f("repeated_bool"    ), false);
+      message.addRepeatedField(f("repeated_string"  ), "315");
+      message.addRepeatedField(f("repeated_bytes"   ), toBytes("316"));
+
+      message.addRepeatedField(f("repeatedgroup"),
+        newBuilderForField(message, f("repeatedgroup"))
+               .setField(repeatedGroupA, 317).build());
+      message.addRepeatedField(f("repeated_nested_message"),
+        newBuilderForField(message, f("repeated_nested_message"))
+               .setField(nestedB, 318).build());
+      message.addRepeatedField(f("repeated_foreign_message"),
+        newBuilderForField(message, f("repeated_foreign_message"))
+               .setField(foreignC, 319).build());
+      message.addRepeatedField(f("repeated_import_message"),
+        newBuilderForField(message, f("repeated_import_message"))
+               .setField(importD, 320).build());
+      message.addRepeatedField(f("repeated_lazy_message"),
+        newBuilderForField(message, f("repeated_lazy_message"))
+               .setField(nestedB, 327).build());
+
+      message.addRepeatedField(f("repeated_nested_enum" ),  nestedBaz);
+      message.addRepeatedField(f("repeated_foreign_enum"), foreignBaz);
+      message.addRepeatedField(f("repeated_import_enum" ),  importBaz);
+
+      message.addRepeatedField(f("repeated_string_piece" ), "324");
+      message.addRepeatedField(f("repeated_cord" ), "325");
+
+      // -----------------------------------------------------------------
+
+      message.setField(f("default_int32"   ), 401 );
+      message.setField(f("default_int64"   ), 402L);
+      message.setField(f("default_uint32"  ), 403 );
+      message.setField(f("default_uint64"  ), 404L);
+      message.setField(f("default_sint32"  ), 405 );
+      message.setField(f("default_sint64"  ), 406L);
+      message.setField(f("default_fixed32" ), 407 );
+      message.setField(f("default_fixed64" ), 408L);
+      message.setField(f("default_sfixed32"), 409 );
+      message.setField(f("default_sfixed64"), 410L);
+      message.setField(f("default_float"   ), 411F);
+      message.setField(f("default_double"  ), 412D);
+      message.setField(f("default_bool"    ), false);
+      message.setField(f("default_string"  ), "415");
+      message.setField(f("default_bytes"   ), toBytes("416"));
+
+      message.setField(f("default_nested_enum" ),  nestedFoo);
+      message.setField(f("default_foreign_enum"), foreignFoo);
+      message.setField(f("default_import_enum" ),  importFoo);
+
+      message.setField(f("default_string_piece" ), "424");
+      message.setField(f("default_cord" ), "425");
+
+      message.setField(f("oneof_uint32" ), 601);
+      message.setField(f("oneof_nested_message"),
+        newBuilderForField(message, f("oneof_nested_message"))
+          .setField(nestedB, 602).build());
+      message.setField(f("oneof_string" ), "603");
+      message.setField(f("oneof_bytes" ), toBytes("604"));
+    }
+
+    // -------------------------------------------------------------------
+
+    /**
+     * Modify the repeated fields of {@code message} to contain the values
+     * expected by {@code assertRepeatedFieldsModified()}, using the
+     * {@link Message.Builder} reflection interface.
+     */
+    void modifyRepeatedFieldsViaReflection(Message.Builder message) {
+      message.setRepeatedField(f("repeated_int32"   ), 1, 501 );
+      message.setRepeatedField(f("repeated_int64"   ), 1, 502L);
+      message.setRepeatedField(f("repeated_uint32"  ), 1, 503 );
+      message.setRepeatedField(f("repeated_uint64"  ), 1, 504L);
+      message.setRepeatedField(f("repeated_sint32"  ), 1, 505 );
+      message.setRepeatedField(f("repeated_sint64"  ), 1, 506L);
+      message.setRepeatedField(f("repeated_fixed32" ), 1, 507 );
+      message.setRepeatedField(f("repeated_fixed64" ), 1, 508L);
+      message.setRepeatedField(f("repeated_sfixed32"), 1, 509 );
+      message.setRepeatedField(f("repeated_sfixed64"), 1, 510L);
+      message.setRepeatedField(f("repeated_float"   ), 1, 511F);
+      message.setRepeatedField(f("repeated_double"  ), 1, 512D);
+      message.setRepeatedField(f("repeated_bool"    ), 1, true);
+      message.setRepeatedField(f("repeated_string"  ), 1, "515");
+      message.setRepeatedField(f("repeated_bytes"   ), 1, toBytes("516"));
+
+      message.setRepeatedField(f("repeatedgroup"), 1,
+        newBuilderForField(message, f("repeatedgroup"))
+               .setField(repeatedGroupA, 517).build());
+      message.setRepeatedField(f("repeated_nested_message"), 1,
+        newBuilderForField(message, f("repeated_nested_message"))
+               .setField(nestedB, 518).build());
+      message.setRepeatedField(f("repeated_foreign_message"), 1,
+        newBuilderForField(message, f("repeated_foreign_message"))
+               .setField(foreignC, 519).build());
+      message.setRepeatedField(f("repeated_import_message"), 1,
+        newBuilderForField(message, f("repeated_import_message"))
+               .setField(importD, 520).build());
+      message.setRepeatedField(f("repeated_lazy_message"), 1,
+        newBuilderForField(message, f("repeated_lazy_message"))
+               .setField(nestedB, 527).build());
+
+      message.setRepeatedField(f("repeated_nested_enum" ), 1,  nestedFoo);
+      message.setRepeatedField(f("repeated_foreign_enum"), 1, foreignFoo);
+      message.setRepeatedField(f("repeated_import_enum" ), 1,  importFoo);
+
+      message.setRepeatedField(f("repeated_string_piece"), 1, "524");
+      message.setRepeatedField(f("repeated_cord"), 1, "525");
+    }
+
+    // -------------------------------------------------------------------
+
+    /**
+     * Assert (using {@code junit.framework.Assert}} that all fields of
+     * {@code message} are set to the values assigned by {@code setAllFields},
+     * using the {@link Message} reflection interface.
+     */
+    public void assertAllFieldsSetViaReflection(MessageOrBuilder message) {
+      Assert.assertTrue(message.hasField(f("optional_int32"   )));
+      Assert.assertTrue(message.hasField(f("optional_int64"   )));
+      Assert.assertTrue(message.hasField(f("optional_uint32"  )));
+      Assert.assertTrue(message.hasField(f("optional_uint64"  )));
+      Assert.assertTrue(message.hasField(f("optional_sint32"  )));
+      Assert.assertTrue(message.hasField(f("optional_sint64"  )));
+      Assert.assertTrue(message.hasField(f("optional_fixed32" )));
+      Assert.assertTrue(message.hasField(f("optional_fixed64" )));
+      Assert.assertTrue(message.hasField(f("optional_sfixed32")));
+      Assert.assertTrue(message.hasField(f("optional_sfixed64")));
+      Assert.assertTrue(message.hasField(f("optional_float"   )));
+      Assert.assertTrue(message.hasField(f("optional_double"  )));
+      Assert.assertTrue(message.hasField(f("optional_bool"    )));
+      Assert.assertTrue(message.hasField(f("optional_string"  )));
+      Assert.assertTrue(message.hasField(f("optional_bytes"   )));
+
+      Assert.assertTrue(message.hasField(f("optionalgroup"           )));
+      Assert.assertTrue(message.hasField(f("optional_nested_message" )));
+      Assert.assertTrue(message.hasField(f("optional_foreign_message")));
+      Assert.assertTrue(message.hasField(f("optional_import_message" )));
+
+      Assert.assertTrue(
+        ((Message)message.getField(f("optionalgroup"))).hasField(groupA));
+      Assert.assertTrue(
+        ((Message)message.getField(f("optional_nested_message")))
+                         .hasField(nestedB));
+      Assert.assertTrue(
+        ((Message)message.getField(f("optional_foreign_message")))
+                         .hasField(foreignC));
+      Assert.assertTrue(
+        ((Message)message.getField(f("optional_import_message")))
+                         .hasField(importD));
+
+      Assert.assertTrue(message.hasField(f("optional_nested_enum" )));
+      Assert.assertTrue(message.hasField(f("optional_foreign_enum")));
+      Assert.assertTrue(message.hasField(f("optional_import_enum" )));
+
+      Assert.assertTrue(message.hasField(f("optional_string_piece")));
+      Assert.assertTrue(message.hasField(f("optional_cord")));
+
+      Assert.assertEquals(101  , message.getField(f("optional_int32"   )));
+      Assert.assertEquals(102L , message.getField(f("optional_int64"   )));
+      Assert.assertEquals(103  , message.getField(f("optional_uint32"  )));
+      Assert.assertEquals(104L , message.getField(f("optional_uint64"  )));
+      Assert.assertEquals(105  , message.getField(f("optional_sint32"  )));
+      Assert.assertEquals(106L , message.getField(f("optional_sint64"  )));
+      Assert.assertEquals(107  , message.getField(f("optional_fixed32" )));
+      Assert.assertEquals(108L , message.getField(f("optional_fixed64" )));
+      Assert.assertEquals(109  , message.getField(f("optional_sfixed32")));
+      Assert.assertEquals(110L , message.getField(f("optional_sfixed64")));
+      Assert.assertEquals(111F , message.getField(f("optional_float"   )));
+      Assert.assertEquals(112D , message.getField(f("optional_double"  )));
+      Assert.assertEquals(true , message.getField(f("optional_bool"    )));
+      Assert.assertEquals("115", message.getField(f("optional_string"  )));
+      Assert.assertEquals(toBytes("116"), message.getField(f("optional_bytes")));
+
+      Assert.assertEquals(117,
+        ((Message)message.getField(f("optionalgroup"))).getField(groupA));
+      Assert.assertEquals(118,
+        ((Message)message.getField(f("optional_nested_message")))
+                         .getField(nestedB));
+      Assert.assertEquals(119,
+        ((Message)message.getField(f("optional_foreign_message")))
+                         .getField(foreignC));
+      Assert.assertEquals(120,
+        ((Message)message.getField(f("optional_import_message")))
+                         .getField(importD));
+      Assert.assertEquals(126,
+        ((Message)message.getField(f("optional_public_import_message")))
+                         .getField(importE));
+      Assert.assertEquals(127,
+        ((Message)message.getField(f("optional_lazy_message")))
+                         .getField(nestedB));
+
+      Assert.assertEquals( nestedBaz, message.getField(f("optional_nested_enum" )));
+      Assert.assertEquals(foreignBaz, message.getField(f("optional_foreign_enum")));
+      Assert.assertEquals( importBaz, message.getField(f("optional_import_enum" )));
+
+      Assert.assertEquals("124", message.getField(f("optional_string_piece")));
+      Assert.assertEquals("125", message.getField(f("optional_cord")));
+
+      // -----------------------------------------------------------------
+
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int32"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int64"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint32"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint64"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint32"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint64"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed32" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed64" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed32")));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed64")));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_float"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_double"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bool"    )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bytes"   )));
+
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeatedgroup"           )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_message" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_message")));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_message" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_lazy_message" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_enum"    )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_enum"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_enum"    )));
+
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string_piece")));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_cord")));
+
+      Assert.assertEquals(201  , message.getRepeatedField(f("repeated_int32"   ), 0));
+      Assert.assertEquals(202L , message.getRepeatedField(f("repeated_int64"   ), 0));
+      Assert.assertEquals(203  , message.getRepeatedField(f("repeated_uint32"  ), 0));
+      Assert.assertEquals(204L , message.getRepeatedField(f("repeated_uint64"  ), 0));
+      Assert.assertEquals(205  , message.getRepeatedField(f("repeated_sint32"  ), 0));
+      Assert.assertEquals(206L , message.getRepeatedField(f("repeated_sint64"  ), 0));
+      Assert.assertEquals(207  , message.getRepeatedField(f("repeated_fixed32" ), 0));
+      Assert.assertEquals(208L , message.getRepeatedField(f("repeated_fixed64" ), 0));
+      Assert.assertEquals(209  , message.getRepeatedField(f("repeated_sfixed32"), 0));
+      Assert.assertEquals(210L , message.getRepeatedField(f("repeated_sfixed64"), 0));
+      Assert.assertEquals(211F , message.getRepeatedField(f("repeated_float"   ), 0));
+      Assert.assertEquals(212D , message.getRepeatedField(f("repeated_double"  ), 0));
+      Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool"    ), 0));
+      Assert.assertEquals("215", message.getRepeatedField(f("repeated_string"  ), 0));
+      Assert.assertEquals(toBytes("216"), message.getRepeatedField(f("repeated_bytes"), 0));
+
+      Assert.assertEquals(217,
+        ((Message)message.getRepeatedField(f("repeatedgroup"), 0))
+                         .getField(repeatedGroupA));
+      Assert.assertEquals(218,
+        ((Message)message.getRepeatedField(f("repeated_nested_message"), 0))
+                         .getField(nestedB));
+      Assert.assertEquals(219,
+        ((Message)message.getRepeatedField(f("repeated_foreign_message"), 0))
+                         .getField(foreignC));
+      Assert.assertEquals(220,
+        ((Message)message.getRepeatedField(f("repeated_import_message"), 0))
+                         .getField(importD));
+      Assert.assertEquals(227,
+        ((Message)message.getRepeatedField(f("repeated_lazy_message"), 0))
+                         .getField(nestedB));
+
+      Assert.assertEquals( nestedBar, message.getRepeatedField(f("repeated_nested_enum" ),0));
+      Assert.assertEquals(foreignBar, message.getRepeatedField(f("repeated_foreign_enum"),0));
+      Assert.assertEquals( importBar, message.getRepeatedField(f("repeated_import_enum" ),0));
+
+      Assert.assertEquals("224", message.getRepeatedField(f("repeated_string_piece"), 0));
+      Assert.assertEquals("225", message.getRepeatedField(f("repeated_cord"), 0));
+
+      Assert.assertEquals(301  , message.getRepeatedField(f("repeated_int32"   ), 1));
+      Assert.assertEquals(302L , message.getRepeatedField(f("repeated_int64"   ), 1));
+      Assert.assertEquals(303  , message.getRepeatedField(f("repeated_uint32"  ), 1));
+      Assert.assertEquals(304L , message.getRepeatedField(f("repeated_uint64"  ), 1));
+      Assert.assertEquals(305  , message.getRepeatedField(f("repeated_sint32"  ), 1));
+      Assert.assertEquals(306L , message.getRepeatedField(f("repeated_sint64"  ), 1));
+      Assert.assertEquals(307  , message.getRepeatedField(f("repeated_fixed32" ), 1));
+      Assert.assertEquals(308L , message.getRepeatedField(f("repeated_fixed64" ), 1));
+      Assert.assertEquals(309  , message.getRepeatedField(f("repeated_sfixed32"), 1));
+      Assert.assertEquals(310L , message.getRepeatedField(f("repeated_sfixed64"), 1));
+      Assert.assertEquals(311F , message.getRepeatedField(f("repeated_float"   ), 1));
+      Assert.assertEquals(312D , message.getRepeatedField(f("repeated_double"  ), 1));
+      Assert.assertEquals(false, message.getRepeatedField(f("repeated_bool"    ), 1));
+      Assert.assertEquals("315", message.getRepeatedField(f("repeated_string"  ), 1));
+      Assert.assertEquals(toBytes("316"), message.getRepeatedField(f("repeated_bytes"), 1));
+
+      Assert.assertEquals(317,
+        ((Message)message.getRepeatedField(f("repeatedgroup"), 1))
+                         .getField(repeatedGroupA));
+      Assert.assertEquals(318,
+        ((Message)message.getRepeatedField(f("repeated_nested_message"), 1))
+                         .getField(nestedB));
+      Assert.assertEquals(319,
+        ((Message)message.getRepeatedField(f("repeated_foreign_message"), 1))
+                         .getField(foreignC));
+      Assert.assertEquals(320,
+        ((Message)message.getRepeatedField(f("repeated_import_message"), 1))
+                         .getField(importD));
+      Assert.assertEquals(327,
+        ((Message)message.getRepeatedField(f("repeated_lazy_message"), 1))
+                         .getField(nestedB));
+
+      Assert.assertEquals( nestedBaz, message.getRepeatedField(f("repeated_nested_enum" ),1));
+      Assert.assertEquals(foreignBaz, message.getRepeatedField(f("repeated_foreign_enum"),1));
+      Assert.assertEquals( importBaz, message.getRepeatedField(f("repeated_import_enum" ),1));
+
+      Assert.assertEquals("324", message.getRepeatedField(f("repeated_string_piece"), 1));
+      Assert.assertEquals("325", message.getRepeatedField(f("repeated_cord"), 1));
+
+      // -----------------------------------------------------------------
+
+      Assert.assertTrue(message.hasField(f("default_int32"   )));
+      Assert.assertTrue(message.hasField(f("default_int64"   )));
+      Assert.assertTrue(message.hasField(f("default_uint32"  )));
+      Assert.assertTrue(message.hasField(f("default_uint64"  )));
+      Assert.assertTrue(message.hasField(f("default_sint32"  )));
+      Assert.assertTrue(message.hasField(f("default_sint64"  )));
+      Assert.assertTrue(message.hasField(f("default_fixed32" )));
+      Assert.assertTrue(message.hasField(f("default_fixed64" )));
+      Assert.assertTrue(message.hasField(f("default_sfixed32")));
+      Assert.assertTrue(message.hasField(f("default_sfixed64")));
+      Assert.assertTrue(message.hasField(f("default_float"   )));
+      Assert.assertTrue(message.hasField(f("default_double"  )));
+      Assert.assertTrue(message.hasField(f("default_bool"    )));
+      Assert.assertTrue(message.hasField(f("default_string"  )));
+      Assert.assertTrue(message.hasField(f("default_bytes"   )));
+
+      Assert.assertTrue(message.hasField(f("default_nested_enum" )));
+      Assert.assertTrue(message.hasField(f("default_foreign_enum")));
+      Assert.assertTrue(message.hasField(f("default_import_enum" )));
+
+      Assert.assertTrue(message.hasField(f("default_string_piece")));
+      Assert.assertTrue(message.hasField(f("default_cord")));
+
+      Assert.assertEquals(401  , message.getField(f("default_int32"   )));
+      Assert.assertEquals(402L , message.getField(f("default_int64"   )));
+      Assert.assertEquals(403  , message.getField(f("default_uint32"  )));
+      Assert.assertEquals(404L , message.getField(f("default_uint64"  )));
+      Assert.assertEquals(405  , message.getField(f("default_sint32"  )));
+      Assert.assertEquals(406L , message.getField(f("default_sint64"  )));
+      Assert.assertEquals(407  , message.getField(f("default_fixed32" )));
+      Assert.assertEquals(408L , message.getField(f("default_fixed64" )));
+      Assert.assertEquals(409  , message.getField(f("default_sfixed32")));
+      Assert.assertEquals(410L , message.getField(f("default_sfixed64")));
+      Assert.assertEquals(411F , message.getField(f("default_float"   )));
+      Assert.assertEquals(412D , message.getField(f("default_double"  )));
+      Assert.assertEquals(false, message.getField(f("default_bool"    )));
+      Assert.assertEquals("415", message.getField(f("default_string"  )));
+      Assert.assertEquals(toBytes("416"), message.getField(f("default_bytes")));
+
+      Assert.assertEquals( nestedFoo, message.getField(f("default_nested_enum" )));
+      Assert.assertEquals(foreignFoo, message.getField(f("default_foreign_enum")));
+      Assert.assertEquals( importFoo, message.getField(f("default_import_enum" )));
+
+      Assert.assertEquals("424", message.getField(f("default_string_piece")));
+      Assert.assertEquals("425", message.getField(f("default_cord")));
+
+      Assert.assertTrue(message.hasField(f("oneof_bytes")));
+      Assert.assertEquals(toBytes("604"), message.getField(f("oneof_bytes")));
+
+      if (extensionRegistry == null) {
+        Assert.assertFalse(message.hasField(f("oneof_uint32")));
+        Assert.assertFalse(message.hasField(f("oneof_nested_message")));
+        Assert.assertFalse(message.hasField(f("oneof_string")));
+      } else {
+        Assert.assertTrue(message.hasField(f("oneof_uint32")));
+        Assert.assertTrue(message.hasField(f("oneof_nested_message")));
+        Assert.assertTrue(message.hasField(f("oneof_string")));
+        Assert.assertEquals(601, message.getField(f("oneof_uint32")));
+        Assert.assertEquals(602,
+            ((MessageOrBuilder) message.getField(f("oneof_nested_message")))
+            .getField(nestedB));
+        Assert.assertEquals("603", message.getField(f("oneof_string")));
+      }
+    }
+
+    // -------------------------------------------------------------------
+
+    /**
+     * Assert (using {@code junit.framework.Assert}} that all fields of
+     * {@code message} are cleared, and that getting the fields returns their
+     * default values, using the {@link Message} reflection interface.
+     */
+    public void assertClearViaReflection(MessageOrBuilder message) {
+      // has_blah() should initially be false for all optional fields.
+      Assert.assertFalse(message.hasField(f("optional_int32"   )));
+      Assert.assertFalse(message.hasField(f("optional_int64"   )));
+      Assert.assertFalse(message.hasField(f("optional_uint32"  )));
+      Assert.assertFalse(message.hasField(f("optional_uint64"  )));
+      Assert.assertFalse(message.hasField(f("optional_sint32"  )));
+      Assert.assertFalse(message.hasField(f("optional_sint64"  )));
+      Assert.assertFalse(message.hasField(f("optional_fixed32" )));
+      Assert.assertFalse(message.hasField(f("optional_fixed64" )));
+      Assert.assertFalse(message.hasField(f("optional_sfixed32")));
+      Assert.assertFalse(message.hasField(f("optional_sfixed64")));
+      Assert.assertFalse(message.hasField(f("optional_float"   )));
+      Assert.assertFalse(message.hasField(f("optional_double"  )));
+      Assert.assertFalse(message.hasField(f("optional_bool"    )));
+      Assert.assertFalse(message.hasField(f("optional_string"  )));
+      Assert.assertFalse(message.hasField(f("optional_bytes"   )));
+
+      Assert.assertFalse(message.hasField(f("optionalgroup"           )));
+      Assert.assertFalse(message.hasField(f("optional_nested_message" )));
+      Assert.assertFalse(message.hasField(f("optional_foreign_message")));
+      Assert.assertFalse(message.hasField(f("optional_import_message" )));
+
+      Assert.assertFalse(message.hasField(f("optional_nested_enum" )));
+      Assert.assertFalse(message.hasField(f("optional_foreign_enum")));
+      Assert.assertFalse(message.hasField(f("optional_import_enum" )));
+
+      Assert.assertFalse(message.hasField(f("optional_string_piece")));
+      Assert.assertFalse(message.hasField(f("optional_cord")));
+
+      // Optional fields without defaults are set to zero or something like it.
+      Assert.assertEquals(0    , message.getField(f("optional_int32"   )));
+      Assert.assertEquals(0L   , message.getField(f("optional_int64"   )));
+      Assert.assertEquals(0    , message.getField(f("optional_uint32"  )));
+      Assert.assertEquals(0L   , message.getField(f("optional_uint64"  )));
+      Assert.assertEquals(0    , message.getField(f("optional_sint32"  )));
+      Assert.assertEquals(0L   , message.getField(f("optional_sint64"  )));
+      Assert.assertEquals(0    , message.getField(f("optional_fixed32" )));
+      Assert.assertEquals(0L   , message.getField(f("optional_fixed64" )));
+      Assert.assertEquals(0    , message.getField(f("optional_sfixed32")));
+      Assert.assertEquals(0L   , message.getField(f("optional_sfixed64")));
+      Assert.assertEquals(0F   , message.getField(f("optional_float"   )));
+      Assert.assertEquals(0D   , message.getField(f("optional_double"  )));
+      Assert.assertEquals(false, message.getField(f("optional_bool"    )));
+      Assert.assertEquals(""   , message.getField(f("optional_string"  )));
+      Assert.assertEquals(ByteString.EMPTY, message.getField(f("optional_bytes")));
+
+      // Embedded messages should also be clear.
+      Assert.assertFalse(
+        ((Message)message.getField(f("optionalgroup"))).hasField(groupA));
+      Assert.assertFalse(
+        ((Message)message.getField(f("optional_nested_message")))
+                         .hasField(nestedB));
+      Assert.assertFalse(
+        ((Message)message.getField(f("optional_foreign_message")))
+                         .hasField(foreignC));
+      Assert.assertFalse(
+        ((Message)message.getField(f("optional_import_message")))
+                         .hasField(importD));
+      Assert.assertFalse(
+        ((Message)message.getField(f("optional_public_import_message")))
+                         .hasField(importE));
+      Assert.assertFalse(
+        ((Message)message.getField(f("optional_lazy_message")))
+                         .hasField(nestedB));
+
+      Assert.assertEquals(0,
+        ((Message)message.getField(f("optionalgroup"))).getField(groupA));
+      Assert.assertEquals(0,
+        ((Message)message.getField(f("optional_nested_message")))
+                         .getField(nestedB));
+      Assert.assertEquals(0,
+        ((Message)message.getField(f("optional_foreign_message")))
+                         .getField(foreignC));
+      Assert.assertEquals(0,
+        ((Message)message.getField(f("optional_import_message")))
+                         .getField(importD));
+      Assert.assertEquals(0,
+        ((Message)message.getField(f("optional_public_import_message")))
+                         .getField(importE));
+      Assert.assertEquals(0,
+        ((Message)message.getField(f("optional_lazy_message")))
+                         .getField(nestedB));
+
+      // Enums without defaults are set to the first value in the enum.
+      Assert.assertEquals( nestedFoo, message.getField(f("optional_nested_enum" )));
+      Assert.assertEquals(foreignFoo, message.getField(f("optional_foreign_enum")));
+      Assert.assertEquals( importFoo, message.getField(f("optional_import_enum" )));
+
+      Assert.assertEquals("", message.getField(f("optional_string_piece")));
+      Assert.assertEquals("", message.getField(f("optional_cord")));
+
+      // Repeated fields are empty.
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_int32"   )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_int64"   )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_uint32"  )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_uint64"  )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sint32"  )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sint64"  )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_fixed32" )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_fixed64" )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sfixed32")));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_sfixed64")));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_float"   )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_double"  )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_bool"    )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_string"  )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_bytes"   )));
+
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeatedgroup"           )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_nested_message" )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_foreign_message")));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_import_message" )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_lazy_message"   )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_nested_enum"    )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_foreign_enum"   )));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_import_enum"    )));
+
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_string_piece")));
+      Assert.assertEquals(0, message.getRepeatedFieldCount(f("repeated_cord")));
+
+      // has_blah() should also be false for all default fields.
+      Assert.assertFalse(message.hasField(f("default_int32"   )));
+      Assert.assertFalse(message.hasField(f("default_int64"   )));
+      Assert.assertFalse(message.hasField(f("default_uint32"  )));
+      Assert.assertFalse(message.hasField(f("default_uint64"  )));
+      Assert.assertFalse(message.hasField(f("default_sint32"  )));
+      Assert.assertFalse(message.hasField(f("default_sint64"  )));
+      Assert.assertFalse(message.hasField(f("default_fixed32" )));
+      Assert.assertFalse(message.hasField(f("default_fixed64" )));
+      Assert.assertFalse(message.hasField(f("default_sfixed32")));
+      Assert.assertFalse(message.hasField(f("default_sfixed64")));
+      Assert.assertFalse(message.hasField(f("default_float"   )));
+      Assert.assertFalse(message.hasField(f("default_double"  )));
+      Assert.assertFalse(message.hasField(f("default_bool"    )));
+      Assert.assertFalse(message.hasField(f("default_string"  )));
+      Assert.assertFalse(message.hasField(f("default_bytes"   )));
+
+      Assert.assertFalse(message.hasField(f("default_nested_enum" )));
+      Assert.assertFalse(message.hasField(f("default_foreign_enum")));
+      Assert.assertFalse(message.hasField(f("default_import_enum" )));
+
+      Assert.assertFalse(message.hasField(f("default_string_piece" )));
+      Assert.assertFalse(message.hasField(f("default_cord" )));
+
+      // Fields with defaults have their default values (duh).
+      Assert.assertEquals( 41    , message.getField(f("default_int32"   )));
+      Assert.assertEquals( 42L   , message.getField(f("default_int64"   )));
+      Assert.assertEquals( 43    , message.getField(f("default_uint32"  )));
+      Assert.assertEquals( 44L   , message.getField(f("default_uint64"  )));
+      Assert.assertEquals(-45    , message.getField(f("default_sint32"  )));
+      Assert.assertEquals( 46L   , message.getField(f("default_sint64"  )));
+      Assert.assertEquals( 47    , message.getField(f("default_fixed32" )));
+      Assert.assertEquals( 48L   , message.getField(f("default_fixed64" )));
+      Assert.assertEquals( 49    , message.getField(f("default_sfixed32")));
+      Assert.assertEquals(-50L   , message.getField(f("default_sfixed64")));
+      Assert.assertEquals( 51.5F , message.getField(f("default_float"   )));
+      Assert.assertEquals( 52e3D , message.getField(f("default_double"  )));
+      Assert.assertEquals(true   , message.getField(f("default_bool"    )));
+      Assert.assertEquals("hello", message.getField(f("default_string"  )));
+      Assert.assertEquals(toBytes("world"), message.getField(f("default_bytes")));
+
+      Assert.assertEquals( nestedBar, message.getField(f("default_nested_enum" )));
+      Assert.assertEquals(foreignBar, message.getField(f("default_foreign_enum")));
+      Assert.assertEquals( importBar, message.getField(f("default_import_enum" )));
+
+      Assert.assertEquals("abc", message.getField(f("default_string_piece")));
+      Assert.assertEquals("123", message.getField(f("default_cord")));
+
+      Assert.assertFalse(message.hasField(f("oneof_uint32")));
+      Assert.assertFalse(message.hasField(f("oneof_nested_message")));
+      Assert.assertFalse(message.hasField(f("oneof_string")));
+      Assert.assertFalse(message.hasField(f("oneof_bytes")));
+
+      Assert.assertEquals(0, message.getField(f("oneof_uint32")));
+      Assert.assertEquals("", message.getField(f("oneof_string")));
+      Assert.assertEquals(toBytes(""), message.getField(f("oneof_bytes")));
+    }
+
+
+    // ---------------------------------------------------------------
+
+    public void assertRepeatedFieldsModifiedViaReflection(
+        MessageOrBuilder 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.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int32"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_int64"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint32"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_uint64"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint32"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sint64"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed32" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_fixed64" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed32")));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_sfixed64")));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_float"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_double"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bool"    )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_bytes"   )));
+
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeatedgroup"           )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_message" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_message")));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_message" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_lazy_message"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_nested_enum"    )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_foreign_enum"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_import_enum"    )));
+
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_string_piece")));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("repeated_cord")));
+
+      Assert.assertEquals(201  , message.getRepeatedField(f("repeated_int32"   ), 0));
+      Assert.assertEquals(202L , message.getRepeatedField(f("repeated_int64"   ), 0));
+      Assert.assertEquals(203  , message.getRepeatedField(f("repeated_uint32"  ), 0));
+      Assert.assertEquals(204L , message.getRepeatedField(f("repeated_uint64"  ), 0));
+      Assert.assertEquals(205  , message.getRepeatedField(f("repeated_sint32"  ), 0));
+      Assert.assertEquals(206L , message.getRepeatedField(f("repeated_sint64"  ), 0));
+      Assert.assertEquals(207  , message.getRepeatedField(f("repeated_fixed32" ), 0));
+      Assert.assertEquals(208L , message.getRepeatedField(f("repeated_fixed64" ), 0));
+      Assert.assertEquals(209  , message.getRepeatedField(f("repeated_sfixed32"), 0));
+      Assert.assertEquals(210L , message.getRepeatedField(f("repeated_sfixed64"), 0));
+      Assert.assertEquals(211F , message.getRepeatedField(f("repeated_float"   ), 0));
+      Assert.assertEquals(212D , message.getRepeatedField(f("repeated_double"  ), 0));
+      Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool"    ), 0));
+      Assert.assertEquals("215", message.getRepeatedField(f("repeated_string"  ), 0));
+      Assert.assertEquals(toBytes("216"), message.getRepeatedField(f("repeated_bytes"), 0));
+
+      Assert.assertEquals(217,
+        ((Message)message.getRepeatedField(f("repeatedgroup"), 0))
+                         .getField(repeatedGroupA));
+      Assert.assertEquals(218,
+        ((Message)message.getRepeatedField(f("repeated_nested_message"), 0))
+                         .getField(nestedB));
+      Assert.assertEquals(219,
+        ((Message)message.getRepeatedField(f("repeated_foreign_message"), 0))
+                         .getField(foreignC));
+      Assert.assertEquals(220,
+        ((Message)message.getRepeatedField(f("repeated_import_message"), 0))
+                         .getField(importD));
+      Assert.assertEquals(227,
+        ((Message)message.getRepeatedField(f("repeated_lazy_message"), 0))
+                         .getField(nestedB));
+
+      Assert.assertEquals( nestedBar, message.getRepeatedField(f("repeated_nested_enum" ),0));
+      Assert.assertEquals(foreignBar, message.getRepeatedField(f("repeated_foreign_enum"),0));
+      Assert.assertEquals( importBar, message.getRepeatedField(f("repeated_import_enum" ),0));
+
+      Assert.assertEquals("224", message.getRepeatedField(f("repeated_string_piece"), 0));
+      Assert.assertEquals("225", message.getRepeatedField(f("repeated_cord"), 0));
+
+      Assert.assertEquals(501  , message.getRepeatedField(f("repeated_int32"   ), 1));
+      Assert.assertEquals(502L , message.getRepeatedField(f("repeated_int64"   ), 1));
+      Assert.assertEquals(503  , message.getRepeatedField(f("repeated_uint32"  ), 1));
+      Assert.assertEquals(504L , message.getRepeatedField(f("repeated_uint64"  ), 1));
+      Assert.assertEquals(505  , message.getRepeatedField(f("repeated_sint32"  ), 1));
+      Assert.assertEquals(506L , message.getRepeatedField(f("repeated_sint64"  ), 1));
+      Assert.assertEquals(507  , message.getRepeatedField(f("repeated_fixed32" ), 1));
+      Assert.assertEquals(508L , message.getRepeatedField(f("repeated_fixed64" ), 1));
+      Assert.assertEquals(509  , message.getRepeatedField(f("repeated_sfixed32"), 1));
+      Assert.assertEquals(510L , message.getRepeatedField(f("repeated_sfixed64"), 1));
+      Assert.assertEquals(511F , message.getRepeatedField(f("repeated_float"   ), 1));
+      Assert.assertEquals(512D , message.getRepeatedField(f("repeated_double"  ), 1));
+      Assert.assertEquals(true , message.getRepeatedField(f("repeated_bool"    ), 1));
+      Assert.assertEquals("515", message.getRepeatedField(f("repeated_string"  ), 1));
+      Assert.assertEquals(toBytes("516"), message.getRepeatedField(f("repeated_bytes"), 1));
+
+      Assert.assertEquals(517,
+        ((Message)message.getRepeatedField(f("repeatedgroup"), 1))
+                         .getField(repeatedGroupA));
+      Assert.assertEquals(518,
+        ((Message)message.getRepeatedField(f("repeated_nested_message"), 1))
+                         .getField(nestedB));
+      Assert.assertEquals(519,
+        ((Message)message.getRepeatedField(f("repeated_foreign_message"), 1))
+                         .getField(foreignC));
+      Assert.assertEquals(520,
+        ((Message)message.getRepeatedField(f("repeated_import_message"), 1))
+                         .getField(importD));
+      Assert.assertEquals(527,
+        ((Message)message.getRepeatedField(f("repeated_lazy_message"), 1))
+                         .getField(nestedB));
+
+      Assert.assertEquals( nestedFoo, message.getRepeatedField(f("repeated_nested_enum" ),1));
+      Assert.assertEquals(foreignFoo, message.getRepeatedField(f("repeated_foreign_enum"),1));
+      Assert.assertEquals( importFoo, message.getRepeatedField(f("repeated_import_enum" ),1));
+
+      Assert.assertEquals("524", message.getRepeatedField(f("repeated_string_piece"), 1));
+      Assert.assertEquals("525", message.getRepeatedField(f("repeated_cord"), 1));
+    }
+
+    public void setPackedFieldsViaReflection(Message.Builder message) {
+      message.addRepeatedField(f("packed_int32"   ), 601 );
+      message.addRepeatedField(f("packed_int64"   ), 602L);
+      message.addRepeatedField(f("packed_uint32"  ), 603 );
+      message.addRepeatedField(f("packed_uint64"  ), 604L);
+      message.addRepeatedField(f("packed_sint32"  ), 605 );
+      message.addRepeatedField(f("packed_sint64"  ), 606L);
+      message.addRepeatedField(f("packed_fixed32" ), 607 );
+      message.addRepeatedField(f("packed_fixed64" ), 608L);
+      message.addRepeatedField(f("packed_sfixed32"), 609 );
+      message.addRepeatedField(f("packed_sfixed64"), 610L);
+      message.addRepeatedField(f("packed_float"   ), 611F);
+      message.addRepeatedField(f("packed_double"  ), 612D);
+      message.addRepeatedField(f("packed_bool"    ), true);
+      message.addRepeatedField(f("packed_enum" ),  foreignBar);
+      // Add a second one of each field.
+      message.addRepeatedField(f("packed_int32"   ), 701 );
+      message.addRepeatedField(f("packed_int64"   ), 702L);
+      message.addRepeatedField(f("packed_uint32"  ), 703 );
+      message.addRepeatedField(f("packed_uint64"  ), 704L);
+      message.addRepeatedField(f("packed_sint32"  ), 705 );
+      message.addRepeatedField(f("packed_sint64"  ), 706L);
+      message.addRepeatedField(f("packed_fixed32" ), 707 );
+      message.addRepeatedField(f("packed_fixed64" ), 708L);
+      message.addRepeatedField(f("packed_sfixed32"), 709 );
+      message.addRepeatedField(f("packed_sfixed64"), 710L);
+      message.addRepeatedField(f("packed_float"   ), 711F);
+      message.addRepeatedField(f("packed_double"  ), 712D);
+      message.addRepeatedField(f("packed_bool"    ), false);
+      message.addRepeatedField(f("packed_enum" ),  foreignBaz);
+    }
+
+    public void assertPackedFieldsSetViaReflection(MessageOrBuilder message) {
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int32"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_int64"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint32"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_uint64"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sint32"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sint64"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_fixed32" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_fixed64" )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sfixed32")));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_sfixed64")));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_float"   )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_double"  )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_bool"    )));
+      Assert.assertEquals(2, message.getRepeatedFieldCount(f("packed_enum"   )));
+      Assert.assertEquals(601  , message.getRepeatedField(f("packed_int32"   ), 0));
+      Assert.assertEquals(602L , message.getRepeatedField(f("packed_int64"   ), 0));
+      Assert.assertEquals(603  , message.getRepeatedField(f("packed_uint32"  ), 0));
+      Assert.assertEquals(604L , message.getRepeatedField(f("packed_uint64"  ), 0));
+      Assert.assertEquals(605  , message.getRepeatedField(f("packed_sint32"  ), 0));
+      Assert.assertEquals(606L , message.getRepeatedField(f("packed_sint64"  ), 0));
+      Assert.assertEquals(607  , message.getRepeatedField(f("packed_fixed32" ), 0));
+      Assert.assertEquals(608L , message.getRepeatedField(f("packed_fixed64" ), 0));
+      Assert.assertEquals(609  , message.getRepeatedField(f("packed_sfixed32"), 0));
+      Assert.assertEquals(610L , message.getRepeatedField(f("packed_sfixed64"), 0));
+      Assert.assertEquals(611F , message.getRepeatedField(f("packed_float"   ), 0));
+      Assert.assertEquals(612D , message.getRepeatedField(f("packed_double"  ), 0));
+      Assert.assertEquals(true , message.getRepeatedField(f("packed_bool"    ), 0));
+      Assert.assertEquals(foreignBar, message.getRepeatedField(f("packed_enum" ),0));
+      Assert.assertEquals(701  , message.getRepeatedField(f("packed_int32"   ), 1));
+      Assert.assertEquals(702L , message.getRepeatedField(f("packed_int64"   ), 1));
+      Assert.assertEquals(703  , message.getRepeatedField(f("packed_uint32"  ), 1));
+      Assert.assertEquals(704L , message.getRepeatedField(f("packed_uint64"  ), 1));
+      Assert.assertEquals(705  , message.getRepeatedField(f("packed_sint32"  ), 1));
+      Assert.assertEquals(706L , message.getRepeatedField(f("packed_sint64"  ), 1));
+      Assert.assertEquals(707  , message.getRepeatedField(f("packed_fixed32" ), 1));
+      Assert.assertEquals(708L , message.getRepeatedField(f("packed_fixed64" ), 1));
+      Assert.assertEquals(709  , message.getRepeatedField(f("packed_sfixed32"), 1));
+      Assert.assertEquals(710L , message.getRepeatedField(f("packed_sfixed64"), 1));
+      Assert.assertEquals(711F , message.getRepeatedField(f("packed_float"   ), 1));
+      Assert.assertEquals(712D , message.getRepeatedField(f("packed_double"  ), 1));
+      Assert.assertEquals(false, message.getRepeatedField(f("packed_bool"    ), 1));
+      Assert.assertEquals(foreignBaz, message.getRepeatedField(f("packed_enum" ),1));
+    }
+
+    /**
+     * Verifies that the reflection setters for the given.Builder object throw a
+     * NullPointerException if they are passed a null value.  Uses Assert to throw an
+     * appropriate assertion failure, if the condition is not verified.
+     */
+    public void assertReflectionSettersRejectNull(Message.Builder builder)
+        throws Exception {
+      try {
+        builder.setField(f("optional_string"), null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+      try {
+        builder.setField(f("optional_bytes"), null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+      try {
+        builder.setField(f("optional_nested_enum"), null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+      try {
+        builder.setField(f("optional_nested_message"),
+                         (TestAllTypes.NestedMessage) null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+      try {
+        builder.setField(f("optional_nested_message"),
+                         (TestAllTypes.NestedMessage.Builder) null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+
+      try {
+        builder.addRepeatedField(f("repeated_string"), null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+      try {
+        builder.addRepeatedField(f("repeated_bytes"), null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+      try {
+        builder.addRepeatedField(f("repeated_nested_enum"), null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+      try {
+        builder.addRepeatedField(f("repeated_nested_message"), null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+    }
+
+    /**
+     * Verifies that the reflection repeated setters for the given Builder object throw a
+     * NullPointerException if they are passed a null value.  Uses Assert to throw an appropriate
+     * assertion failure, if the condition is not verified.
+     */
+    public void assertReflectionRepeatedSettersRejectNull(Message.Builder builder)
+        throws Exception {
+      builder.addRepeatedField(f("repeated_string"), "one");
+      try {
+        builder.setRepeatedField(f("repeated_string"), 0, null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+
+      builder.addRepeatedField(f("repeated_bytes"), toBytes("one"));
+      try {
+        builder.setRepeatedField(f("repeated_bytes"), 0, null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+
+      builder.addRepeatedField(f("repeated_nested_enum"), nestedBaz);
+      try {
+        builder.setRepeatedField(f("repeated_nested_enum"), 0, null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+
+      builder.addRepeatedField(
+          f("repeated_nested_message"),
+          TestAllTypes.NestedMessage.newBuilder().setBb(218).build());
+      try {
+        builder.setRepeatedField(f("repeated_nested_message"), 0, null);
+        Assert.fail("Exception was not thrown");
+      } catch (NullPointerException e) {
+        // We expect this exception.
+      }
+    }
+  }
+
+  /**
+   * @param filePath The path relative to
+   * {@link #getTestDataDir}.
+   */
+  public static String readTextFromFile(String filePath) {
+    return readBytesFromFile(filePath).toStringUtf8();
+  }
+
+  private static File getTestDataDir() {
+    // Search each parent directory looking for "src/google/protobuf".
+    File ancestor = new File(".");
+    try {
+      ancestor = ancestor.getCanonicalFile();
+    } catch (IOException e) {
+      throw new RuntimeException(
+        "Couldn't get canonical name of working directory.", e);
+    }
+    while (ancestor != null && ancestor.exists()) {
+      if (new File(ancestor, "src/google/protobuf").exists()) {
+        return new File(ancestor, "src/google/protobuf/testdata");
+      }
+      ancestor = ancestor.getParentFile();
+    }
+
+    throw new RuntimeException(
+      "Could not find golden files.  This test must be run from within the " +
+      "protobuf source package so that it can read test data files from the " +
+      "C++ source tree.");
+  }
+
+  /**
+   * @param filename The path relative to
+   * {@link #getTestDataDir}.
+   */
+  public static ByteString readBytesFromFile(String filename) {
+    File fullPath = new File(getTestDataDir(), filename);
+    try {
+      RandomAccessFile file = new RandomAccessFile(fullPath, "r");
+      byte[] content = new byte[(int) file.length()];
+      file.readFully(content);
+      return ByteString.copyFrom(content);
+    } catch (IOException e) {
+      // Throw a RuntimeException here so that we can call this function from
+      // static initializers.
+      throw new IllegalArgumentException(
+        "Couldn't read file: " + fullPath.getPath(), e);
+    }
+  }
+
+  /**
+   * Get the bytes of the "golden message".  This is a serialized TestAllTypes
+   * with all fields set as they would be by
+   * {@link #setAllFields(TestAllTypes.Builder)}, but it is loaded from a file
+   * on disk rather than generated dynamically.  The file is actually generated
+   * by C++ code, so testing against it verifies compatibility with C++.
+   */
+  public static ByteString getGoldenMessage() {
+    if (goldenMessage == null) {
+      goldenMessage = readBytesFromFile("golden_message_oneof_implemented");
+    }
+    return goldenMessage;
+  }
+  private static ByteString goldenMessage = null;
+
+  /**
+   * Get the bytes of the "golden packed fields message".  This is a serialized
+   * TestPackedTypes with all fields set as they would be by
+   * {@link #setPackedFields(TestPackedTypes.Builder)}, but it is loaded from a
+   * file on disk rather than generated dynamically.  The file is actually
+   * generated by C++ code, so testing against it verifies compatibility with
+   * C++.
+   */
+  public static ByteString getGoldenPackedFieldsMessage() {
+    if (goldenPackedFieldsMessage == null) {
+      goldenPackedFieldsMessage =
+          readBytesFromFile("golden_packed_fields_message");
+    }
+    return goldenPackedFieldsMessage;
+  }
+  private static ByteString goldenPackedFieldsMessage = null;
+
+  /**
+   * Mock implementation of {@link GeneratedMessage.BuilderParent} for testing.
+   *
+   * @author jonp@google.com (Jon Perlow)
+   */
+  public static class MockBuilderParent
+      implements GeneratedMessage.BuilderParent {
+
+    private int invalidations;
+
+    //@Override (Java 1.6 override semantics, but we must support 1.5)
+    public void markDirty() {
+      invalidations++;
+    }
+
+    public int getInvalidationCount() {
+      return invalidations;
+    }
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/TextFormatTest.java b/protobuf/java/src/test/java/com/google/protobuf/TextFormatTest.java
new file mode 100644
index 0000000..152bdad
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/TextFormatTest.java
@@ -0,0 +1,994 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import com.google.protobuf.TextFormat.Parser.SingularOverwritePolicy;
+import protobuf_unittest.UnittestMset.TestMessageSet;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
+import protobuf_unittest.UnittestProto.OneString;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
+import protobuf_unittest.UnittestProto.TestEmptyMessage;
+import protobuf_unittest.UnittestProto.TestOneof2;
+
+import junit.framework.TestCase;
+
+import java.io.StringReader;
+
+/**
+ * Test case for {@link TextFormat}.
+ *
+ * TODO(wenboz): ExtensionTest and rest of text_format_unittest.cc.
+ *
+ * @author wenboz@google.com (Wenbo Zhu)
+ */
+public class TextFormatTest extends TestCase {
+
+  // A basic string with different escapable characters for testing.
+  private final static 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.
+  private final static String kEscapeTestStringEscaped =
+      "\\\"A string with \\' characters \\n and \\r newlines "
+          + "and \\t tabs and \\001 slashes \\\\";
+
+  private static String allFieldsSetText = TestUtil.readTextFromFile(
+    "text_format_unittest_data_oneof_implemented.txt");
+  private static String allExtensionsSetText = TestUtil.readTextFromFile(
+    "text_format_unittest_extensions_data.txt");
+
+  private static String exoticText =
+    "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: .125\n" +
+    "repeated_double: -.125\n" +
+    "repeated_double: 1.23E17\n" +
+    "repeated_double: 1.23E+17\n" +
+    "repeated_double: -1.23e-17\n" +
+    "repeated_double: .23e+17\n" +
+    "repeated_double: -.23E17\n" +
+    "repeated_double: 1.235E22\n" +
+    "repeated_double: 1.235E-18\n" +
+    "repeated_double: 123.456789\n" +
+    "repeated_double: Infinity\n" +
+    "repeated_double: -Infinity\n" +
+    "repeated_double: NaN\n" +
+    "repeated_string: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"" +
+      "\\341\\210\\264\"\n" +
+    "repeated_bytes: \"\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"\\376\"\n";
+
+  private static String canonicalExoticText =
+      exoticText.replace(": .", ": 0.").replace(": -.", ": -0.")   // short-form double
+      .replace("23e", "23E").replace("E+", "E").replace("0.23E17", "2.3E16");
+
+  private String messageSetText =
+    "[protobuf_unittest.TestMessageSetExtension1] {\n" +
+    "  i: 123\n" +
+    "}\n" +
+    "[protobuf_unittest.TestMessageSetExtension2] {\n" +
+    "  str: \"foo\"\n" +
+    "}\n";
+
+  private String messageSetTextWithRepeatedExtension =
+      "[protobuf_unittest.TestMessageSetExtension1] {\n" +
+      "  i: 123\n" +
+      "}\n" +
+      "[protobuf_unittest.TestMessageSetExtension1] {\n" +
+      "  i: 456\n" +
+      "}\n";
+
+  private final TextFormat.Parser parserWithOverwriteForbidden =
+      TextFormat.Parser.newBuilder()
+          .setSingularOverwritePolicy(
+              SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES)
+          .build();
+
+  private final TextFormat.Parser defaultParser =
+      TextFormat.Parser.newBuilder().build();
+
+  /** Print TestAllTypes and compare with golden file. */
+  public void testPrintMessage() throws Exception {
+    String javaText = TextFormat.printToString(TestUtil.getAllSet());
+
+    // Java likes to add a trailing ".0" to floats and doubles.  C printf
+    // (with %g format) does not.  Our golden files are used for both
+    // C++ and Java TextFormat classes, so we need to conform.
+    javaText = javaText.replace(".0\n", "\n");
+
+    assertEquals(allFieldsSetText, javaText);
+  }
+
+  /** Print TestAllTypes as Builder and compare with golden file. */
+  public void testPrintMessageBuilder() throws Exception {
+    String javaText = TextFormat.printToString(TestUtil.getAllSetBuilder());
+
+    // Java likes to add a trailing ".0" to floats and doubles.  C printf
+    // (with %g format) does not.  Our golden files are used for both
+    // C++ and Java TextFormat classes, so we need to conform.
+    javaText = javaText.replace(".0\n", "\n");
+
+    assertEquals(allFieldsSetText, javaText);
+  }
+
+  /** Print TestAllExtensions and compare with golden file. */
+  public void testPrintExtensions() throws Exception {
+    String javaText = TextFormat.printToString(TestUtil.getAllExtensionsSet());
+
+    // Java likes to add a trailing ".0" to floats and doubles.  C printf
+    // (with %g format) does not.  Our golden files are used for both
+    // C++ and Java TextFormat classes, so we need to conform.
+    javaText = javaText.replace(".0\n", "\n");
+
+    assertEquals(allExtensionsSetText, javaText);
+  }
+
+  // Creates an example unknown field set.
+  private UnknownFieldSet makeUnknownFieldSet() {
+    return UnknownFieldSet.newBuilder()
+        .addField(5,
+            UnknownFieldSet.Field.newBuilder()
+            .addVarint(1)
+            .addFixed32(2)
+            .addFixed64(3)
+            .addLengthDelimited(ByteString.copyFromUtf8("4"))
+            .addGroup(
+                UnknownFieldSet.newBuilder()
+                .addField(10,
+                    UnknownFieldSet.Field.newBuilder()
+                    .addVarint(5)
+                    .build())
+                .build())
+            .build())
+        .addField(8,
+            UnknownFieldSet.Field.newBuilder()
+            .addVarint(1)
+            .addVarint(2)
+            .addVarint(3)
+            .build())
+        .addField(15,
+            UnknownFieldSet.Field.newBuilder()
+            .addVarint(0xABCDEF1234567890L)
+            .addFixed32(0xABCD1234)
+            .addFixed64(0xABCDEF1234567890L)
+            .build())
+        .build();
+  }
+
+  public void testPrintUnknownFields() throws Exception {
+    // Test printing of unknown fields in a message.
+
+    TestEmptyMessage message =
+      TestEmptyMessage.newBuilder()
+        .setUnknownFields(makeUnknownFieldSet())
+        .build();
+
+    assertEquals(
+      "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" +
+      "15: 12379813812177893520\n" +
+      "15: 0xabcd1234\n" +
+      "15: 0xabcdef1234567890\n",
+      TextFormat.printToString(message));
+  }
+
+  public void testPrintField() throws Exception {
+    final FieldDescriptor dataField =
+      OneString.getDescriptor().findFieldByName("data");
+    assertEquals(
+      "data: \"test data\"\n",
+      TextFormat.printFieldToString(dataField, "test data"));
+
+    final FieldDescriptor optionalField =
+      TestAllTypes.getDescriptor().findFieldByName("optional_nested_message");
+    final Object value = NestedMessage.newBuilder().setBb(42).build();
+
+    assertEquals(
+      "optional_nested_message {\n  bb: 42\n}\n",
+      TextFormat.printFieldToString(optionalField, value));
+  }
+
+  /**
+   * Helper to construct a ByteString from a String containing only 8-bit
+   * characters.  The characters are converted directly to bytes, *not*
+   * encoded using UTF-8.
+   */
+  private ByteString bytes(String str) throws Exception {
+    return ByteString.copyFrom(str.getBytes("ISO-8859-1"));
+  }
+
+  /**
+   * Helper to construct a ByteString from a bunch of bytes.  The inputs are
+   * actually ints so that I can use hex notation and not get stupid errors
+   * about precision.
+   */
+  private ByteString bytes(int... bytesAsInts) {
+    byte[] bytes = new byte[bytesAsInts.length];
+    for (int i = 0; i < bytesAsInts.length; i++) {
+      bytes[i] = (byte) bytesAsInts[i];
+    }
+    return ByteString.copyFrom(bytes);
+  }
+
+  public void testPrintExotic() throws Exception {
+    Message message = TestAllTypes.newBuilder()
+      // Signed vs. unsigned numbers.
+      .addRepeatedInt32 (-1)
+      .addRepeatedUint32(-1)
+      .addRepeatedInt64 (-1)
+      .addRepeatedUint64(-1)
+
+      .addRepeatedInt32 (1  << 31)
+      .addRepeatedUint32(1  << 31)
+      .addRepeatedInt64 (1L << 63)
+      .addRepeatedUint64(1L << 63)
+
+      // Floats of various precisions and exponents.
+      .addRepeatedDouble(123)
+      .addRepeatedDouble(123.5)
+      .addRepeatedDouble(0.125)
+      .addRepeatedDouble(.125)
+      .addRepeatedDouble(-.125)
+      .addRepeatedDouble(123e15)
+      .addRepeatedDouble(123e15)
+      .addRepeatedDouble(-1.23e-17)
+      .addRepeatedDouble(.23e17)
+      .addRepeatedDouble(-23e15)
+      .addRepeatedDouble(123.5e20)
+      .addRepeatedDouble(123.5e-20)
+      .addRepeatedDouble(123.456789)
+      .addRepeatedDouble(Double.POSITIVE_INFINITY)
+      .addRepeatedDouble(Double.NEGATIVE_INFINITY)
+      .addRepeatedDouble(Double.NaN)
+
+      // Strings and bytes that needing escaping.
+      .addRepeatedString("\0\001\007\b\f\n\r\t\013\\\'\"\u1234")
+      .addRepeatedBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"\u00fe"))
+      .build();
+
+    assertEquals(canonicalExoticText, message.toString());
+  }
+
+  public void testPrintMessageSet() throws Exception {
+    TestMessageSet messageSet =
+      TestMessageSet.newBuilder()
+        .setExtension(
+          TestMessageSetExtension1.messageSetExtension,
+          TestMessageSetExtension1.newBuilder().setI(123).build())
+        .setExtension(
+          TestMessageSetExtension2.messageSetExtension,
+          TestMessageSetExtension2.newBuilder().setStr("foo").build())
+        .build();
+
+    assertEquals(messageSetText, messageSet.toString());
+  }
+
+  // =================================================================
+
+  public void testParse() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge(allFieldsSetText, builder);
+    TestUtil.assertAllFieldsSet(builder.build());
+  }
+
+  public void testParseReader() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge(new StringReader(allFieldsSetText), builder);
+    TestUtil.assertAllFieldsSet(builder.build());
+  }
+
+  public void testParseExtensions() throws Exception {
+    TestAllExtensions.Builder builder = TestAllExtensions.newBuilder();
+    TextFormat.merge(allExtensionsSetText,
+                     TestUtil.getExtensionRegistry(),
+                     builder);
+    TestUtil.assertAllExtensionsSet(builder.build());
+  }
+
+  public void testParseCompatibility() throws Exception {
+    String original = "repeated_float: inf\n" +
+                      "repeated_float: -inf\n" +
+                      "repeated_float: nan\n" +
+                      "repeated_float: inff\n" +
+                      "repeated_float: -inff\n" +
+                      "repeated_float: nanf\n" +
+                      "repeated_float: 1.0f\n" +
+                      "repeated_float: infinityf\n" +
+                      "repeated_float: -Infinityf\n" +
+                      "repeated_double: infinity\n" +
+                      "repeated_double: -infinity\n" +
+                      "repeated_double: nan\n";
+    String canonical =  "repeated_float: Infinity\n" +
+                        "repeated_float: -Infinity\n" +
+                        "repeated_float: NaN\n" +
+                        "repeated_float: Infinity\n" +
+                        "repeated_float: -Infinity\n" +
+                        "repeated_float: NaN\n" +
+                        "repeated_float: 1.0\n" +
+                        "repeated_float: Infinity\n" +
+                        "repeated_float: -Infinity\n" +
+                        "repeated_double: Infinity\n" +
+                        "repeated_double: -Infinity\n" +
+                        "repeated_double: NaN\n";
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge(original, builder);
+    assertEquals(canonical, builder.build().toString());
+  }
+
+  public void testParseExotic() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge(exoticText, builder);
+
+    // Too lazy to check things individually.  Don't try to debug this
+    // if testPrintExotic() is failing.
+    assertEquals(canonicalExoticText, builder.build().toString());
+  }
+
+  public void testParseMessageSet() throws Exception {
+    ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+    extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+    extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
+
+    TestMessageSet.Builder builder = TestMessageSet.newBuilder();
+    TextFormat.merge(messageSetText, extensionRegistry, builder);
+    TestMessageSet messageSet = builder.build();
+
+    assertTrue(messageSet.hasExtension(
+      TestMessageSetExtension1.messageSetExtension));
+    assertEquals(123, messageSet.getExtension(
+      TestMessageSetExtension1.messageSetExtension).getI());
+    assertTrue(messageSet.hasExtension(
+      TestMessageSetExtension2.messageSetExtension));
+    assertEquals("foo", messageSet.getExtension(
+      TestMessageSetExtension2.messageSetExtension).getStr());
+
+    builder = TestMessageSet.newBuilder();
+    TextFormat.merge(messageSetTextWithRepeatedExtension, extensionRegistry,
+        builder);
+    messageSet = builder.build();
+    assertEquals(456, messageSet.getExtension(
+      TestMessageSetExtension1.messageSetExtension).getI());
+  }
+
+  public void testParseMessageSetWithOverwriteForbidden() throws Exception {
+    ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+    extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+    extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
+
+    TestMessageSet.Builder builder = TestMessageSet.newBuilder();
+    parserWithOverwriteForbidden.merge(
+        messageSetText, extensionRegistry, builder);
+    TestMessageSet messageSet = builder.build();
+    assertEquals(123, messageSet.getExtension(
+        TestMessageSetExtension1.messageSetExtension).getI());
+    assertEquals("foo", messageSet.getExtension(
+      TestMessageSetExtension2.messageSetExtension).getStr());
+
+    builder = TestMessageSet.newBuilder();
+    try {
+      parserWithOverwriteForbidden.merge(
+          messageSetTextWithRepeatedExtension, extensionRegistry, builder);
+      fail("expected parse exception");
+    } catch (TextFormat.ParseException e) {
+      assertEquals("6:1: Non-repeated field "
+          + "\"protobuf_unittest.TestMessageSetExtension1.message_set_extension\""
+          + " cannot be overwritten.",
+          e.getMessage());
+    }
+  }
+
+  public void testParseNumericEnum() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge("optional_nested_enum: 2", builder);
+    assertEquals(TestAllTypes.NestedEnum.BAR, builder.getOptionalNestedEnum());
+  }
+
+  public void testParseAngleBrackets() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge("OptionalGroup: < a: 1 >", builder);
+    assertTrue(builder.hasOptionalGroup());
+    assertEquals(1, builder.getOptionalGroup().getA());
+  }
+
+  public void testParseComment() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge(
+      "# this is a comment\n" +
+      "optional_int32: 1  # another comment\n" +
+      "optional_int64: 2\n" +
+      "# EOF comment", builder);
+    assertEquals(1, builder.getOptionalInt32());
+    assertEquals(2, builder.getOptionalInt64());
+  }
+
+  private void assertParseError(String error, String text) {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    try {
+      TextFormat.merge(text, TestUtil.getExtensionRegistry(), builder);
+      fail("Expected parse exception.");
+    } catch (TextFormat.ParseException e) {
+      assertEquals(error, e.getMessage());
+    }
+  }
+
+  private void assertParseErrorWithOverwriteForbidden(String error,
+      String text) {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    try {
+      parserWithOverwriteForbidden.merge(
+          text, TestUtil.getExtensionRegistry(), builder);
+      fail("Expected parse exception.");
+    } catch (TextFormat.ParseException e) {
+      assertEquals(error, e.getMessage());
+    }
+  }
+
+  private TestAllTypes assertParseSuccessWithOverwriteForbidden(
+      String text) throws TextFormat.ParseException {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    parserWithOverwriteForbidden.merge(
+        text, TestUtil.getExtensionRegistry(), builder);
+    return builder.build();
+  }
+
+  public void testParseErrors() throws Exception {
+    assertParseError(
+      "1:16: Expected \":\".",
+      "optional_int32 123");
+    assertParseError(
+      "1:23: Expected identifier. Found '?'",
+      "optional_nested_enum: ?");
+    assertParseError(
+      "1:18: Couldn't parse integer: Number must be positive: -1",
+      "optional_uint32: -1");
+    assertParseError(
+      "1:17: Couldn't parse integer: Number out of range for 32-bit signed " +
+        "integer: 82301481290849012385230157",
+      "optional_int32: 82301481290849012385230157");
+    assertParseError(
+      "1:16: Expected \"true\" or \"false\".",
+      "optional_bool: maybe");
+    assertParseError(
+      "1:16: Expected \"true\" or \"false\".",
+      "optional_bool: 2");
+    assertParseError(
+      "1:18: Expected string.",
+      "optional_string: 123");
+    assertParseError(
+      "1:18: String missing ending quote.",
+      "optional_string: \"ueoauaoe");
+    assertParseError(
+      "1:18: String missing ending quote.",
+      "optional_string: \"ueoauaoe\n" +
+      "optional_int32: 123");
+    assertParseError(
+      "1:18: Invalid escape sequence: '\\z'",
+      "optional_string: \"\\z\"");
+    assertParseError(
+      "1:18: String missing ending quote.",
+      "optional_string: \"ueoauaoe\n" +
+      "optional_int32: 123");
+    assertParseError(
+      "1:2: Extension \"nosuchext\" not found in the ExtensionRegistry.",
+      "[nosuchext]: 123");
+    assertParseError(
+      "1:20: Extension \"protobuf_unittest.optional_int32_extension\" does " +
+        "not extend message type \"protobuf_unittest.TestAllTypes\".",
+      "[protobuf_unittest.optional_int32_extension]: 123");
+    assertParseError(
+      "1:1: Message type \"protobuf_unittest.TestAllTypes\" has no field " +
+        "named \"nosuchfield\".",
+      "nosuchfield: 123");
+    assertParseError(
+      "1:21: Expected \">\".",
+      "OptionalGroup < a: 1");
+    assertParseError(
+      "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
+        "value named \"NO_SUCH_VALUE\".",
+      "optional_nested_enum: NO_SUCH_VALUE");
+    assertParseError(
+      "1:23: Enum type \"protobuf_unittest.TestAllTypes.NestedEnum\" has no " +
+        "value with number 123.",
+      "optional_nested_enum: 123");
+
+    // Delimiters must match.
+    assertParseError(
+      "1:22: Expected identifier. Found '}'",
+      "OptionalGroup < a: 1 }");
+    assertParseError(
+      "1:22: Expected identifier. Found '>'",
+      "OptionalGroup { a: 1 >");
+  }
+
+  // =================================================================
+
+  public void testEscape() throws Exception {
+    // Escape sequences.
+    assertEquals("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
+      TextFormat.escapeBytes(bytes("\0\001\007\b\f\n\r\t\013\\\'\"")));
+    assertEquals("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\"",
+      TextFormat.escapeText("\0\001\007\b\f\n\r\t\013\\\'\""));
+    assertEquals(bytes("\0\001\007\b\f\n\r\t\013\\\'\""),
+      TextFormat.unescapeBytes("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
+    assertEquals("\0\001\007\b\f\n\r\t\013\\\'\"",
+      TextFormat.unescapeText("\\000\\001\\a\\b\\f\\n\\r\\t\\v\\\\\\'\\\""));
+    assertEquals(kEscapeTestStringEscaped,
+      TextFormat.escapeText(kEscapeTestString));
+    assertEquals(kEscapeTestString,
+      TextFormat.unescapeText(kEscapeTestStringEscaped));
+
+    // Unicode handling.
+    assertEquals("\\341\\210\\264", TextFormat.escapeText("\u1234"));
+    assertEquals("\\341\\210\\264",
+                 TextFormat.escapeBytes(bytes(0xe1, 0x88, 0xb4)));
+    assertEquals("\u1234", TextFormat.unescapeText("\\341\\210\\264"));
+    assertEquals(bytes(0xe1, 0x88, 0xb4),
+                 TextFormat.unescapeBytes("\\341\\210\\264"));
+    assertEquals("\u1234", TextFormat.unescapeText("\\xe1\\x88\\xb4"));
+    assertEquals(bytes(0xe1, 0x88, 0xb4),
+                 TextFormat.unescapeBytes("\\xe1\\x88\\xb4"));
+
+    // Handling of strings with unescaped Unicode characters > 255.
+    final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c";
+    ByteString zhByteString = ByteString.copyFromUtf8(zh);
+    assertEquals(zhByteString, TextFormat.unescapeBytes(zh));
+
+    // Errors.
+    try {
+      TextFormat.unescapeText("\\x");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      // success
+    }
+
+    try {
+      TextFormat.unescapeText("\\z");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      // success
+    }
+
+    try {
+      TextFormat.unescapeText("\\");
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.InvalidEscapeSequenceException e) {
+      // success
+    }
+  }
+
+  public void testParseInteger() throws Exception {
+    assertEquals(          0, TextFormat.parseInt32(          "0"));
+    assertEquals(          1, TextFormat.parseInt32(          "1"));
+    assertEquals(         -1, TextFormat.parseInt32(         "-1"));
+    assertEquals(      12345, TextFormat.parseInt32(      "12345"));
+    assertEquals(     -12345, TextFormat.parseInt32(     "-12345"));
+    assertEquals( 2147483647, TextFormat.parseInt32( "2147483647"));
+    assertEquals(-2147483648, TextFormat.parseInt32("-2147483648"));
+
+    assertEquals(                0, TextFormat.parseUInt32(         "0"));
+    assertEquals(                1, TextFormat.parseUInt32(         "1"));
+    assertEquals(            12345, TextFormat.parseUInt32(     "12345"));
+    assertEquals(       2147483647, TextFormat.parseUInt32("2147483647"));
+    assertEquals((int) 2147483648L, TextFormat.parseUInt32("2147483648"));
+    assertEquals((int) 4294967295L, TextFormat.parseUInt32("4294967295"));
+
+    assertEquals(          0L, TextFormat.parseInt64(          "0"));
+    assertEquals(          1L, TextFormat.parseInt64(          "1"));
+    assertEquals(         -1L, TextFormat.parseInt64(         "-1"));
+    assertEquals(      12345L, TextFormat.parseInt64(      "12345"));
+    assertEquals(     -12345L, TextFormat.parseInt64(     "-12345"));
+    assertEquals( 2147483647L, TextFormat.parseInt64( "2147483647"));
+    assertEquals(-2147483648L, TextFormat.parseInt64("-2147483648"));
+    assertEquals( 4294967295L, TextFormat.parseInt64( "4294967295"));
+    assertEquals( 4294967296L, TextFormat.parseInt64( "4294967296"));
+    assertEquals(9223372036854775807L,
+                 TextFormat.parseInt64("9223372036854775807"));
+    assertEquals(-9223372036854775808L,
+                 TextFormat.parseInt64("-9223372036854775808"));
+
+    assertEquals(          0L, TextFormat.parseUInt64(          "0"));
+    assertEquals(          1L, TextFormat.parseUInt64(          "1"));
+    assertEquals(      12345L, TextFormat.parseUInt64(      "12345"));
+    assertEquals( 2147483647L, TextFormat.parseUInt64( "2147483647"));
+    assertEquals( 4294967295L, TextFormat.parseUInt64( "4294967295"));
+    assertEquals( 4294967296L, TextFormat.parseUInt64( "4294967296"));
+    assertEquals(9223372036854775807L,
+                 TextFormat.parseUInt64("9223372036854775807"));
+    assertEquals(-9223372036854775808L,
+                 TextFormat.parseUInt64("9223372036854775808"));
+    assertEquals(-1L, TextFormat.parseUInt64("18446744073709551615"));
+
+    // Hex
+    assertEquals(0x1234abcd, TextFormat.parseInt32("0x1234abcd"));
+    assertEquals(-0x1234abcd, TextFormat.parseInt32("-0x1234abcd"));
+    assertEquals(-1, TextFormat.parseUInt64("0xffffffffffffffff"));
+    assertEquals(0x7fffffffffffffffL,
+                 TextFormat.parseInt64("0x7fffffffffffffff"));
+
+    // Octal
+    assertEquals(01234567, TextFormat.parseInt32("01234567"));
+
+    // Out-of-range
+    try {
+      TextFormat.parseInt32("2147483648");
+      fail("Should have thrown an exception.");
+    } catch (NumberFormatException e) {
+      // success
+    }
+
+    try {
+      TextFormat.parseInt32("-2147483649");
+      fail("Should have thrown an exception.");
+    } catch (NumberFormatException e) {
+      // success
+    }
+
+    try {
+      TextFormat.parseUInt32("4294967296");
+      fail("Should have thrown an exception.");
+    } catch (NumberFormatException e) {
+      // success
+    }
+
+    try {
+      TextFormat.parseUInt32("-1");
+      fail("Should have thrown an exception.");
+    } catch (NumberFormatException e) {
+      // success
+    }
+
+    try {
+      TextFormat.parseInt64("9223372036854775808");
+      fail("Should have thrown an exception.");
+    } catch (NumberFormatException e) {
+      // success
+    }
+
+    try {
+      TextFormat.parseInt64("-9223372036854775809");
+      fail("Should have thrown an exception.");
+    } catch (NumberFormatException e) {
+      // success
+    }
+
+    try {
+      TextFormat.parseUInt64("18446744073709551616");
+      fail("Should have thrown an exception.");
+    } catch (NumberFormatException e) {
+      // success
+    }
+
+    try {
+      TextFormat.parseUInt64("-1");
+      fail("Should have thrown an exception.");
+    } catch (NumberFormatException e) {
+      // success
+    }
+
+    // Not a number.
+    try {
+      TextFormat.parseInt32("abcd");
+      fail("Should have thrown an exception.");
+    } catch (NumberFormatException e) {
+      // success
+    }
+  }
+
+  public void testParseString() throws Exception {
+    final String zh = "\u9999\u6e2f\u4e0a\u6d77\ud84f\udf80\u8c50\u9280\u884c";
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge("optional_string: \"" + zh + "\"", builder);
+    assertEquals(zh, builder.getOptionalString());
+  }
+
+  public void testParseLongString() throws Exception {
+    String longText =
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890" +
+      "123456789012345678901234567890123456789012345678901234567890";
+
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge("optional_string: \"" + longText + "\"", builder);
+    assertEquals(longText, builder.getOptionalString());
+  }
+
+  public void testParseBoolean() throws Exception {
+    String goodText =
+        "repeated_bool: t  repeated_bool : 0\n" +
+        "repeated_bool :f repeated_bool:1";
+    String goodTextCanonical =
+        "repeated_bool: true\n" +
+        "repeated_bool: false\n" +
+        "repeated_bool: false\n" +
+        "repeated_bool: true\n";
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge(goodText, builder);
+    assertEquals(goodTextCanonical, builder.build().toString());
+
+    try {
+      TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder();
+      TextFormat.merge("optional_bool:2", badBuilder);
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.ParseException e) {
+      // success
+    }
+    try {
+      TestAllTypes.Builder badBuilder = TestAllTypes.newBuilder();
+      TextFormat.merge("optional_bool: foo", badBuilder);
+      fail("Should have thrown an exception.");
+    } catch (TextFormat.ParseException e) {
+      // success
+    }
+  }
+
+  public void testParseAdjacentStringLiterals() throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge("optional_string: \"foo\" 'corge' \"grault\"", builder);
+    assertEquals("foocorgegrault", builder.getOptionalString());
+  }
+
+  public void testPrintFieldValue() throws Exception {
+    assertPrintFieldValue("\"Hello\"", "Hello", "repeated_string");
+    assertPrintFieldValue("123.0",  123f, "repeated_float");
+    assertPrintFieldValue("123.0",  123d, "repeated_double");
+    assertPrintFieldValue("123",  123, "repeated_int32");
+    assertPrintFieldValue("123",  123L, "repeated_int64");
+    assertPrintFieldValue("true",  true, "repeated_bool");
+    assertPrintFieldValue("4294967295", 0xFFFFFFFF, "repeated_uint32");
+    assertPrintFieldValue("18446744073709551615",  0xFFFFFFFFFFFFFFFFL,
+        "repeated_uint64");
+    assertPrintFieldValue("\"\\001\\002\\003\"",
+        ByteString.copyFrom(new byte[] {1, 2, 3}), "repeated_bytes");
+  }
+
+  private void assertPrintFieldValue(String expect, Object value,
+      String fieldName) throws Exception {
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    StringBuilder sb = new StringBuilder();
+    TextFormat.printFieldValue(
+        TestAllTypes.getDescriptor().findFieldByName(fieldName),
+        value, sb);
+    assertEquals(expect, sb.toString());
+  }
+
+  public void testShortDebugString() {
+    assertEquals("optional_nested_message { bb: 42 } repeated_int32: 1"
+        + " repeated_uint32: 2",
+        TextFormat.shortDebugString(TestAllTypes.newBuilder()
+            .addRepeatedInt32(1)
+            .addRepeatedUint32(2)
+            .setOptionalNestedMessage(
+                NestedMessage.newBuilder().setBb(42).build())
+            .build()));
+  }
+
+  public void testShortDebugString_unknown() {
+    assertEquals("5: 1 5: 0x00000002 5: 0x0000000000000003 5: \"4\" 5 { 10: 5 }"
+        + " 8: 1 8: 2 8: 3 15: 12379813812177893520 15: 0xabcd1234 15:"
+        + " 0xabcdef1234567890",
+        TextFormat.shortDebugString(makeUnknownFieldSet()));
+  }
+
+  public void testPrintToUnicodeString() throws Exception {
+    assertEquals(
+        "optional_string: \"abc\u3042efg\"\n" +
+        "optional_bytes: \"\\343\\201\\202\"\n" +
+        "repeated_string: \"\u3093XYZ\"\n",
+        TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+            .setOptionalString("abc\u3042efg")
+            .setOptionalBytes(bytes(0xe3, 0x81, 0x82))
+            .addRepeatedString("\u3093XYZ")
+            .build()));
+
+    // Double quotes and backslashes should be escaped
+    assertEquals(
+        "optional_string: \"a\\\\bc\\\"ef\\\"g\"\n",
+        TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+            .setOptionalString("a\\bc\"ef\"g")
+            .build()));
+
+    // Test escaping roundtrip
+    TestAllTypes message = TestAllTypes.newBuilder()
+        .setOptionalString("a\\bc\\\"ef\"g")
+        .build();
+    TestAllTypes.Builder builder = TestAllTypes.newBuilder();
+    TextFormat.merge(TextFormat.printToUnicodeString(message), builder);
+    assertEquals(message.getOptionalString(), builder.getOptionalString());
+  }
+  
+  public void testPrintToUnicodeStringWithNewlines() {
+    // No newlines at start and end
+    assertEquals("optional_string: \"test newlines\n\nin\nstring\"\n",
+        TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+            .setOptionalString("test newlines\n\nin\nstring")
+            .build()));
+
+    // Newlines at start and end
+    assertEquals("optional_string: \"\ntest\nnewlines\n\nin\nstring\n\"\n",
+        TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+            .setOptionalString("\ntest\nnewlines\n\nin\nstring\n")
+            .build()));
+
+    // Strings with 0, 1 and 2 newlines.
+    assertEquals("optional_string: \"\"\n",
+        TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+            .setOptionalString("")
+            .build()));
+    assertEquals("optional_string: \"\n\"\n",
+        TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+            .setOptionalString("\n")
+            .build()));
+    assertEquals("optional_string: \"\n\n\"\n",
+        TextFormat.printToUnicodeString(TestAllTypes.newBuilder()
+            .setOptionalString("\n\n")
+            .build()));
+  }
+
+  public void testPrintToUnicodeString_unknown() {
+    assertEquals(
+        "1: \"\\343\\201\\202\"\n",
+        TextFormat.printToUnicodeString(UnknownFieldSet.newBuilder()
+            .addField(1,
+                UnknownFieldSet.Field.newBuilder()
+                .addLengthDelimited(bytes(0xe3, 0x81, 0x82)).build())
+            .build()));
+  }
+
+  public void testParseNonRepeatedFields() throws Exception {
+    assertParseSuccessWithOverwriteForbidden(
+        "repeated_int32: 1\n" +
+        "repeated_int32: 2\n");
+    assertParseSuccessWithOverwriteForbidden(
+        "RepeatedGroup { a: 1 }\n" +
+        "RepeatedGroup { a: 2 }\n");
+    assertParseSuccessWithOverwriteForbidden(
+        "repeated_nested_message { bb: 1 }\n" +
+        "repeated_nested_message { bb: 2 }\n");
+    assertParseErrorWithOverwriteForbidden(
+        "3:17: Non-repeated field " +
+        "\"protobuf_unittest.TestAllTypes.optional_int32\" " +
+        "cannot be overwritten.",
+        "optional_int32: 1\n" +
+        "optional_bool: true\n" +
+        "optional_int32: 1\n");
+    assertParseErrorWithOverwriteForbidden(
+        "2:17: Non-repeated field " +
+        "\"protobuf_unittest.TestAllTypes.optionalgroup\" " +
+        "cannot be overwritten.",
+        "OptionalGroup { a: 1 }\n" +
+        "OptionalGroup { }\n");
+    assertParseErrorWithOverwriteForbidden(
+        "2:33: Non-repeated field " +
+        "\"protobuf_unittest.TestAllTypes.optional_nested_message\" " +
+        "cannot be overwritten.",
+        "optional_nested_message { }\n" +
+        "optional_nested_message { bb: 3 }\n");
+    assertParseErrorWithOverwriteForbidden(
+        "2:16: Non-repeated field " +
+        "\"protobuf_unittest.TestAllTypes.default_int32\" " +
+        "cannot be overwritten.",
+        "default_int32: 41\n" +  // the default value
+        "default_int32: 41\n");
+    assertParseErrorWithOverwriteForbidden(
+        "2:17: Non-repeated field " +
+        "\"protobuf_unittest.TestAllTypes.default_string\" " +
+        "cannot be overwritten.",
+        "default_string: \"zxcv\"\n" +
+        "default_string: \"asdf\"\n");
+  }
+
+  public void testParseShortRepeatedFormOfRepeatedFields() throws Exception {
+    assertParseSuccessWithOverwriteForbidden("repeated_foreign_enum: [FOREIGN_FOO, FOREIGN_BAR]");
+    assertParseSuccessWithOverwriteForbidden("repeated_int32: [ 1, 2 ]\n");
+    assertParseSuccessWithOverwriteForbidden("RepeatedGroup [{ a: 1 },{ a: 2 }]\n");
+    assertParseSuccessWithOverwriteForbidden("repeated_nested_message [{ bb: 1 }, { bb: 2 }]\n");
+  }
+
+  public void testParseShortRepeatedFormOfNonRepeatedFields() throws Exception {
+    assertParseErrorWithOverwriteForbidden(
+        "1:17: Couldn't parse integer: For input string: \"[\"",
+        "optional_int32: [1]\n");
+  }
+
+  // =======================================================================
+  // test oneof
+
+  public void testOneofTextFormat() throws Exception {
+    TestOneof2.Builder builder = TestOneof2.newBuilder();
+    TestUtil.setOneof(builder);
+    TestOneof2 message = builder.build();
+    TestOneof2.Builder dest = TestOneof2.newBuilder();
+    TextFormat.merge(TextFormat.printToUnicodeString(message), dest);
+    TestUtil.assertOneofSet(dest.build());
+  }
+
+  public void testOneofOverwriteForbidden() throws Exception {
+    String input = "foo_string: \"stringvalue\" foo_int: 123";
+    TestOneof2.Builder builder = TestOneof2.newBuilder();
+    try {
+      parserWithOverwriteForbidden.merge(
+          input, TestUtil.getExtensionRegistry(), builder);
+      fail("Expected parse exception.");
+    } catch (TextFormat.ParseException e) {
+      assertEquals("1:36: Field \"protobuf_unittest.TestOneof2.foo_int\""
+                   + " is specified along with field \"protobuf_unittest.TestOneof2.foo_string\","
+                   + " another member of oneof \"foo\".", e.getMessage());
+    }
+  }
+
+  public void testOneofOverwriteAllowed() throws Exception {
+    String input = "foo_string: \"stringvalue\" foo_int: 123";
+    TestOneof2.Builder builder = TestOneof2.newBuilder();
+    defaultParser.merge(input, TestUtil.getExtensionRegistry(), builder);
+    // Only the last value sticks.
+    TestOneof2 oneof = builder.build();
+    assertFalse(oneof.hasFooString());
+    assertTrue(oneof.hasFooInt());
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java b/protobuf/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
new file mode 100644
index 0000000..93a5ee2
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
@@ -0,0 +1,653 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.ForeignEnum;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestEmptyMessage;
+import protobuf_unittest.UnittestProto.TestEmptyMessageWithExtensions;
+import protobuf_unittest.UnittestProto.TestPackedExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ * Tests related to unknown field handling.
+ *
+ * @author kenton@google.com (Kenton Varda)
+ */
+public class UnknownFieldSetTest extends TestCase {
+  public void setUp() throws Exception {
+    descriptor = TestAllTypes.getDescriptor();
+    allFields = TestUtil.getAllSet();
+    allFieldsData = allFields.toByteString();
+    emptyMessage = TestEmptyMessage.parseFrom(allFieldsData);
+    unknownFields = emptyMessage.getUnknownFields();
+  }
+
+  UnknownFieldSet.Field getField(String name) {
+    Descriptors.FieldDescriptor field = descriptor.findFieldByName(name);
+    assertNotNull(field);
+    return unknownFields.getField(field.getNumber());
+  }
+
+  // Constructs a protocol buffer which contains fields with all the same
+  // numbers as allFieldsData except that each field is some other wire
+  // type.
+  ByteString getBizarroData() throws Exception {
+    UnknownFieldSet.Builder bizarroFields = UnknownFieldSet.newBuilder();
+
+    UnknownFieldSet.Field varintField =
+      UnknownFieldSet.Field.newBuilder().addVarint(1).build();
+    UnknownFieldSet.Field fixed32Field =
+      UnknownFieldSet.Field.newBuilder().addFixed32(1).build();
+
+    for (Map.Entry<Integer, UnknownFieldSet.Field> entry :
+         unknownFields.asMap().entrySet()) {
+      if (entry.getValue().getVarintList().isEmpty()) {
+        // Original field is not a varint, so use a varint.
+        bizarroFields.addField(entry.getKey(), varintField);
+      } else {
+        // Original field *is* a varint, so use something else.
+        bizarroFields.addField(entry.getKey(), fixed32Field);
+      }
+    }
+
+    return bizarroFields.build().toByteString();
+  }
+
+  Descriptors.Descriptor descriptor;
+  TestAllTypes allFields;
+  ByteString allFieldsData;
+
+  // An empty message that has been parsed from allFieldsData.  So, it has
+  // unknown fields of every type.
+  TestEmptyMessage emptyMessage;
+  UnknownFieldSet unknownFields;
+
+  // =================================================================
+
+  public void testVarint() throws Exception {
+    UnknownFieldSet.Field field = getField("optional_int32");
+    assertEquals(1, field.getVarintList().size());
+    assertEquals(allFields.getOptionalInt32(),
+                 (long) field.getVarintList().get(0));
+  }
+
+  public void testFixed32() throws Exception {
+    UnknownFieldSet.Field field = getField("optional_fixed32");
+    assertEquals(1, field.getFixed32List().size());
+    assertEquals(allFields.getOptionalFixed32(),
+                 (int) field.getFixed32List().get(0));
+  }
+
+  public void testFixed64() throws Exception {
+    UnknownFieldSet.Field field = getField("optional_fixed64");
+    assertEquals(1, field.getFixed64List().size());
+    assertEquals(allFields.getOptionalFixed64(),
+                 (long) field.getFixed64List().get(0));
+  }
+
+  public void testLengthDelimited() throws Exception {
+    UnknownFieldSet.Field field = getField("optional_bytes");
+    assertEquals(1, field.getLengthDelimitedList().size());
+    assertEquals(allFields.getOptionalBytes(),
+                 field.getLengthDelimitedList().get(0));
+  }
+
+  public void testGroup() throws Exception {
+    Descriptors.FieldDescriptor nestedFieldDescriptor =
+      TestAllTypes.OptionalGroup.getDescriptor().findFieldByName("a");
+    assertNotNull(nestedFieldDescriptor);
+
+    UnknownFieldSet.Field field = getField("optionalgroup");
+    assertEquals(1, field.getGroupList().size());
+
+    UnknownFieldSet group = field.getGroupList().get(0);
+    assertEquals(1, group.asMap().size());
+    assertTrue(group.hasField(nestedFieldDescriptor.getNumber()));
+
+    UnknownFieldSet.Field nestedField =
+      group.getField(nestedFieldDescriptor.getNumber());
+    assertEquals(1, nestedField.getVarintList().size());
+    assertEquals(allFields.getOptionalGroup().getA(),
+                 (long) nestedField.getVarintList().get(0));
+  }
+
+  public void testSerialize() throws Exception {
+    // Check that serializing the UnknownFieldSet produces the original data
+    // again.
+    ByteString data = emptyMessage.toByteString();
+    assertEquals(allFieldsData, data);
+  }
+
+  public void testCopyFrom() throws Exception {
+    TestEmptyMessage message =
+      TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).build();
+
+    assertEquals(emptyMessage.toString(), message.toString());
+  }
+
+  public void testMergeFrom() throws Exception {
+    TestEmptyMessage source =
+      TestEmptyMessage.newBuilder()
+        .setUnknownFields(
+          UnknownFieldSet.newBuilder()
+            .addField(2,
+              UnknownFieldSet.Field.newBuilder()
+                .addVarint(2).build())
+            .addField(3,
+              UnknownFieldSet.Field.newBuilder()
+                .addVarint(4).build())
+            .build())
+        .build();
+    TestEmptyMessage destination =
+      TestEmptyMessage.newBuilder()
+        .setUnknownFields(
+          UnknownFieldSet.newBuilder()
+            .addField(1,
+              UnknownFieldSet.Field.newBuilder()
+                .addVarint(1).build())
+            .addField(3,
+              UnknownFieldSet.Field.newBuilder()
+                .addVarint(3).build())
+            .build())
+        .mergeFrom(source)
+        .build();
+
+    assertEquals(
+      "1: 1\n" +
+      "2: 2\n" +
+      "3: 3\n" +
+      "3: 4\n",
+      destination.toString());
+  }
+
+  public void testClear() throws Exception {
+    UnknownFieldSet fields =
+      UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clear().build();
+    assertTrue(fields.asMap().isEmpty());
+  }
+
+  public void testClearMessage() throws Exception {
+    TestEmptyMessage message =
+      TestEmptyMessage.newBuilder().mergeFrom(emptyMessage).clear().build();
+    assertEquals(0, message.getSerializedSize());
+  }
+  
+  public void testClearField() throws Exception {
+    int fieldNumber = unknownFields.asMap().keySet().iterator().next();
+    UnknownFieldSet fields =
+        UnknownFieldSet.newBuilder().mergeFrom(unknownFields).clearField(fieldNumber).build();
+    assertFalse(fields.hasField(fieldNumber));
+  }
+
+  public void testParseKnownAndUnknown() throws Exception {
+    // Test mixing known and unknown fields when parsing.
+
+    UnknownFieldSet fields =
+      UnknownFieldSet.newBuilder(unknownFields)
+        .addField(123456,
+          UnknownFieldSet.Field.newBuilder().addVarint(654321).build())
+        .build();
+
+    ByteString data = fields.toByteString();
+    TestAllTypes destination = TestAllTypes.parseFrom(data);
+
+    TestUtil.assertAllFieldsSet(destination);
+    assertEquals(1, destination.getUnknownFields().asMap().size());
+
+    UnknownFieldSet.Field field =
+      destination.getUnknownFields().getField(123456);
+    assertEquals(1, field.getVarintList().size());
+    assertEquals(654321, (long) field.getVarintList().get(0));
+  }
+
+  public void testWrongTypeTreatedAsUnknown() throws Exception {
+    // Test that fields of the wrong wire type are treated like unknown fields
+    // when parsing.
+
+    ByteString bizarroData = getBizarroData();
+    TestAllTypes allTypesMessage = TestAllTypes.parseFrom(bizarroData);
+    TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);
+
+    // All fields should have been interpreted as unknown, so the debug strings
+    // should be the same.
+    assertEquals(emptyMessage.toString(), allTypesMessage.toString());
+  }
+
+  public void testUnknownExtensions() throws Exception {
+    // Make sure fields are properly parsed to the UnknownFieldSet even when
+    // they are declared as extension numbers.
+
+    TestEmptyMessageWithExtensions message =
+      TestEmptyMessageWithExtensions.parseFrom(allFieldsData);
+
+    assertEquals(unknownFields.asMap().size(),
+                 message.getUnknownFields().asMap().size());
+    assertEquals(allFieldsData, message.toByteString());
+  }
+
+  public void testWrongExtensionTypeTreatedAsUnknown() throws Exception {
+    // Test that fields of the wrong wire type are treated like unknown fields
+    // when parsing extensions.
+
+    ByteString bizarroData = getBizarroData();
+    TestAllExtensions allExtensionsMessage =
+      TestAllExtensions.parseFrom(bizarroData);
+    TestEmptyMessage emptyMessage = TestEmptyMessage.parseFrom(bizarroData);
+
+    // All fields should have been interpreted as unknown, so the debug strings
+    // should be the same.
+    assertEquals(emptyMessage.toString(),
+                 allExtensionsMessage.toString());
+  }
+
+  public void testParseUnknownEnumValue() throws Exception {
+    Descriptors.FieldDescriptor singularField =
+      TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum");
+    Descriptors.FieldDescriptor repeatedField =
+      TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum");
+    assertNotNull(singularField);
+    assertNotNull(repeatedField);
+
+    ByteString data =
+      UnknownFieldSet.newBuilder()
+        .addField(singularField.getNumber(),
+          UnknownFieldSet.Field.newBuilder()
+            .addVarint(TestAllTypes.NestedEnum.BAR.getNumber())
+            .addVarint(5)   // not valid
+            .build())
+        .addField(repeatedField.getNumber(),
+          UnknownFieldSet.Field.newBuilder()
+            .addVarint(TestAllTypes.NestedEnum.FOO.getNumber())
+            .addVarint(4)   // not valid
+            .addVarint(TestAllTypes.NestedEnum.BAZ.getNumber())
+            .addVarint(6)   // not valid
+            .build())
+        .build()
+        .toByteString();
+
+    {
+      TestAllTypes message = TestAllTypes.parseFrom(data);
+      assertEquals(TestAllTypes.NestedEnum.BAR,
+                   message.getOptionalNestedEnum());
+      assertEquals(
+        Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
+        message.getRepeatedNestedEnumList());
+      assertEquals(Arrays.asList(5L),
+                   message.getUnknownFields()
+                          .getField(singularField.getNumber())
+                          .getVarintList());
+      assertEquals(Arrays.asList(4L, 6L),
+                   message.getUnknownFields()
+                          .getField(repeatedField.getNumber())
+                          .getVarintList());
+    }
+
+    {
+      TestAllExtensions message =
+        TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
+      assertEquals(TestAllTypes.NestedEnum.BAR,
+        message.getExtension(UnittestProto.optionalNestedEnumExtension));
+      assertEquals(
+        Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
+        message.getExtension(UnittestProto.repeatedNestedEnumExtension));
+      assertEquals(Arrays.asList(5L),
+                   message.getUnknownFields()
+                          .getField(singularField.getNumber())
+                          .getVarintList());
+      assertEquals(Arrays.asList(4L, 6L),
+                   message.getUnknownFields()
+                          .getField(repeatedField.getNumber())
+                          .getVarintList());
+    }
+  }
+
+  public void testLargeVarint() throws Exception {
+    ByteString data =
+      UnknownFieldSet.newBuilder()
+        .addField(1,
+          UnknownFieldSet.Field.newBuilder()
+            .addVarint(0x7FFFFFFFFFFFFFFFL)
+            .build())
+        .build()
+        .toByteString();
+    UnknownFieldSet parsed = UnknownFieldSet.parseFrom(data);
+    UnknownFieldSet.Field field = parsed.getField(1);
+    assertEquals(1, field.getVarintList().size());
+    assertEquals(0x7FFFFFFFFFFFFFFFL, (long)field.getVarintList().get(0));
+  }
+
+  public void testEqualsAndHashCode() {
+    UnknownFieldSet.Field fixed32Field =
+        UnknownFieldSet.Field.newBuilder()
+            .addFixed32(1)
+            .build();
+    UnknownFieldSet.Field fixed64Field =
+        UnknownFieldSet.Field.newBuilder()
+            .addFixed64(1)
+            .build();
+    UnknownFieldSet.Field varIntField =
+        UnknownFieldSet.Field.newBuilder()
+            .addVarint(1)
+            .build();
+    UnknownFieldSet.Field lengthDelimitedField =
+        UnknownFieldSet.Field.newBuilder()
+            .addLengthDelimited(ByteString.EMPTY)
+            .build();
+    UnknownFieldSet.Field groupField =
+        UnknownFieldSet.Field.newBuilder()
+            .addGroup(unknownFields)
+            .build();
+
+    UnknownFieldSet a =
+        UnknownFieldSet.newBuilder()
+            .addField(1, fixed32Field)
+            .build();
+    UnknownFieldSet b =
+        UnknownFieldSet.newBuilder()
+            .addField(1, fixed64Field)
+            .build();
+    UnknownFieldSet c =
+        UnknownFieldSet.newBuilder()
+            .addField(1, varIntField)
+            .build();
+    UnknownFieldSet d =
+        UnknownFieldSet.newBuilder()
+            .addField(1, lengthDelimitedField)
+            .build();
+    UnknownFieldSet e =
+        UnknownFieldSet.newBuilder()
+            .addField(1, groupField)
+            .build();
+
+    checkEqualsIsConsistent(a);
+    checkEqualsIsConsistent(b);
+    checkEqualsIsConsistent(c);
+    checkEqualsIsConsistent(d);
+    checkEqualsIsConsistent(e);
+
+    checkNotEqual(a, b);
+    checkNotEqual(a, c);
+    checkNotEqual(a, d);
+    checkNotEqual(a, e);
+    checkNotEqual(b, c);
+    checkNotEqual(b, d);
+    checkNotEqual(b, e);
+    checkNotEqual(c, d);
+    checkNotEqual(c, e);
+    checkNotEqual(d, e);
+  }
+
+  /**
+   * Asserts that the given field sets are not equal and have different
+   * hash codes.
+   *
+   * @warning It's valid for non-equal objects to have the same hash code, so
+   *   this test is stricter than it needs to be. However, this should happen
+   *   relatively rarely.
+   */
+  private void checkNotEqual(UnknownFieldSet s1, UnknownFieldSet s2) {
+    String equalsError = String.format("%s should not be equal to %s", s1, s2);
+    assertFalse(equalsError, s1.equals(s2));
+    assertFalse(equalsError, s2.equals(s1));
+
+    assertFalse(
+        String.format("%s should have a different hash code from %s", s1, s2),
+        s1.hashCode() == s2.hashCode());
+  }
+
+  /**
+   * Asserts that the given field sets are equal and have identical hash codes.
+   */
+  private void checkEqualsIsConsistent(UnknownFieldSet set) {
+    // Object should be equal to itself.
+    assertEquals(set, set);
+
+    // Object should be equal to a copy of itself.
+    UnknownFieldSet copy = UnknownFieldSet.newBuilder(set).build();
+    assertEquals(set, copy);
+    assertEquals(copy, set);
+    assertEquals(set.hashCode(), copy.hashCode());
+  }
+
+  // =================================================================
+
+  public void testSerializeLite() throws Exception {
+    UnittestLite.TestEmptyMessageLite emptyMessageLite =
+        UnittestLite.TestEmptyMessageLite.parseFrom(allFieldsData);
+    assertEquals(allFieldsData.size(), emptyMessageLite.getSerializedSize());
+    ByteString data = emptyMessageLite.toByteString();
+    TestAllTypes message = TestAllTypes.parseFrom(data);
+    TestUtil.assertAllFieldsSet(message);
+    assertEquals(allFieldsData, data);
+  }
+
+  public void testAllExtensionsLite() throws Exception {
+    TestAllExtensions allExtensions = TestUtil.getAllExtensionsSet();
+    ByteString allExtensionsData = allExtensions.toByteString();
+    UnittestLite.TestEmptyMessageLite emptyMessageLite =
+        UnittestLite.TestEmptyMessageLite.PARSER.parseFrom(allExtensionsData);
+    ByteString data = emptyMessageLite.toByteString();
+    TestAllExtensions message =
+        TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
+    TestUtil.assertAllExtensionsSet(message);
+    assertEquals(allExtensionsData, data);
+  }
+
+  public void testAllPackedFieldsLite() throws Exception {
+    TestPackedTypes allPackedFields = TestUtil.getPackedSet();
+    ByteString allPackedData = allPackedFields.toByteString();
+    UnittestLite.TestEmptyMessageLite emptyMessageLite =
+        UnittestLite.TestEmptyMessageLite.parseFrom(allPackedData);
+    ByteString data = emptyMessageLite.toByteString();
+    TestPackedTypes message =
+        TestPackedTypes.parseFrom(data, TestUtil.getExtensionRegistry());
+    TestUtil.assertPackedFieldsSet(message);
+    assertEquals(allPackedData, data);
+  }
+
+  public void testAllPackedExtensionsLite() throws Exception {
+    TestPackedExtensions allPackedExtensions = TestUtil.getPackedExtensionsSet();
+    ByteString allPackedExtensionsData = allPackedExtensions.toByteString();
+    UnittestLite.TestEmptyMessageLite emptyMessageLite =
+        UnittestLite.TestEmptyMessageLite.parseFrom(allPackedExtensionsData);
+    ByteString data = emptyMessageLite.toByteString();
+    TestPackedExtensions message =
+        TestPackedExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
+    TestUtil.assertPackedExtensionsSet(message);
+    assertEquals(allPackedExtensionsData, data);
+  }
+
+  public void testCopyFromLite() throws Exception {
+    UnittestLite.TestEmptyMessageLite emptyMessageLite =
+        UnittestLite.TestEmptyMessageLite.parseFrom(allFieldsData);
+    UnittestLite.TestEmptyMessageLite emptyMessageLite2 =
+        UnittestLite.TestEmptyMessageLite.newBuilder()
+        .mergeFrom(emptyMessageLite).build();
+    assertEquals(emptyMessageLite.toByteString(), emptyMessageLite2.toByteString());
+  }
+
+  public void testMergeFromLite() throws Exception {
+    TestAllTypes message1 = TestAllTypes.newBuilder()
+        .setOptionalInt32(1)
+        .setOptionalString("foo")
+        .addRepeatedString("bar")
+        .setOptionalNestedEnum(TestAllTypes.NestedEnum.BAZ)
+        .build();
+
+    TestAllTypes message2 = TestAllTypes.newBuilder()
+        .setOptionalInt64(2)
+        .setOptionalString("baz")
+        .addRepeatedString("qux")
+        .setOptionalForeignEnum(ForeignEnum.FOREIGN_BAZ)
+        .build();
+
+    ByteString data1 = message1.toByteString();
+    UnittestLite.TestEmptyMessageLite emptyMessageLite1 =
+        UnittestLite.TestEmptyMessageLite.parseFrom(data1);
+    ByteString data2 = message2.toByteString();
+    UnittestLite.TestEmptyMessageLite emptyMessageLite2 =
+        UnittestLite.TestEmptyMessageLite.parseFrom(data2);
+
+    message1 = TestAllTypes.newBuilder(message1).mergeFrom(message2).build();
+    emptyMessageLite1 = UnittestLite.TestEmptyMessageLite.newBuilder(emptyMessageLite1)
+                        .mergeFrom(emptyMessageLite2).build();
+
+    data1 = emptyMessageLite1.toByteString();
+    message2 = TestAllTypes.parseFrom(data1);
+
+    assertEquals(message1, message2);
+  }
+
+  public void testWrongTypeTreatedAsUnknownLite() throws Exception {
+    // Test that fields of the wrong wire type are treated like unknown fields
+    // when parsing.
+
+    ByteString bizarroData = getBizarroData();
+    TestAllTypes allTypesMessage = TestAllTypes.parseFrom(bizarroData);
+    UnittestLite.TestEmptyMessageLite emptyMessageLite =
+        UnittestLite.TestEmptyMessageLite.parseFrom(bizarroData);
+    ByteString data = emptyMessageLite.toByteString();
+    TestAllTypes allTypesMessage2 = TestAllTypes.parseFrom(data);
+
+    assertEquals(allTypesMessage.toString(), allTypesMessage2.toString());
+  }
+
+  public void testUnknownExtensionsLite() throws Exception {
+    // Make sure fields are properly parsed to the UnknownFieldSet even when
+    // they are declared as extension numbers.
+
+    UnittestLite.TestEmptyMessageWithExtensionsLite message =
+      UnittestLite.TestEmptyMessageWithExtensionsLite.parseFrom(allFieldsData);
+
+    assertEquals(allFieldsData, message.toByteString());
+  }
+
+  public void testWrongExtensionTypeTreatedAsUnknownLite() throws Exception {
+    // Test that fields of the wrong wire type are treated like unknown fields
+    // when parsing extensions.
+
+    ByteString bizarroData = getBizarroData();
+    TestAllExtensions allExtensionsMessage =
+      TestAllExtensions.parseFrom(bizarroData);
+    UnittestLite.TestEmptyMessageLite emptyMessageLite =
+        UnittestLite.TestEmptyMessageLite.parseFrom(bizarroData);
+
+    // All fields should have been interpreted as unknown, so the byte strings
+    // should be the same.
+    assertEquals(emptyMessageLite.toByteString(),
+                 allExtensionsMessage.toByteString());
+  }
+
+  public void testParseUnknownEnumValueLite() throws Exception {
+    Descriptors.FieldDescriptor singularField =
+      TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum");
+    Descriptors.FieldDescriptor repeatedField =
+      TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum");
+    assertNotNull(singularField);
+    assertNotNull(repeatedField);
+
+    ByteString data =
+      UnknownFieldSet.newBuilder()
+        .addField(singularField.getNumber(),
+          UnknownFieldSet.Field.newBuilder()
+            .addVarint(TestAllTypes.NestedEnum.BAR.getNumber())
+            .addVarint(5)   // not valid
+            .build())
+        .addField(repeatedField.getNumber(),
+          UnknownFieldSet.Field.newBuilder()
+            .addVarint(TestAllTypes.NestedEnum.FOO.getNumber())
+            .addVarint(4)   // not valid
+            .addVarint(TestAllTypes.NestedEnum.BAZ.getNumber())
+            .addVarint(6)   // not valid
+            .build())
+        .build()
+        .toByteString();
+
+    UnittestLite.TestEmptyMessageLite emptyMessageLite =
+        UnittestLite.TestEmptyMessageLite.parseFrom(data);
+    data = emptyMessageLite.toByteString();
+
+    {
+      TestAllTypes message = TestAllTypes.parseFrom(data);
+      assertEquals(TestAllTypes.NestedEnum.BAR,
+                   message.getOptionalNestedEnum());
+      assertEquals(
+        Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
+        message.getRepeatedNestedEnumList());
+      assertEquals(Arrays.asList(5L),
+                   message.getUnknownFields()
+                          .getField(singularField.getNumber())
+                          .getVarintList());
+      assertEquals(Arrays.asList(4L, 6L),
+                   message.getUnknownFields()
+                          .getField(repeatedField.getNumber())
+                          .getVarintList());
+    }
+
+    {
+      TestAllExtensions message =
+        TestAllExtensions.parseFrom(data, TestUtil.getExtensionRegistry());
+      assertEquals(TestAllTypes.NestedEnum.BAR,
+        message.getExtension(UnittestProto.optionalNestedEnumExtension));
+      assertEquals(
+        Arrays.asList(TestAllTypes.NestedEnum.FOO, TestAllTypes.NestedEnum.BAZ),
+        message.getExtension(UnittestProto.repeatedNestedEnumExtension));
+      assertEquals(Arrays.asList(5L),
+                   message.getUnknownFields()
+                          .getField(singularField.getNumber())
+                          .getVarintList());
+      assertEquals(Arrays.asList(4L, 6L),
+                   message.getUnknownFields()
+                          .getField(repeatedField.getNumber())
+                          .getVarintList());
+    }
+  }
+
+  public void testClearLite() throws Exception {
+    UnittestLite.TestEmptyMessageLite emptyMessageLite1 =
+        UnittestLite.TestEmptyMessageLite.parseFrom(allFieldsData);
+    UnittestLite.TestEmptyMessageLite emptyMessageLite2 =
+        UnittestLite.TestEmptyMessageLite.newBuilder()
+        .mergeFrom(emptyMessageLite1).clear().build();
+    assertEquals(0, emptyMessageLite2.getSerializedSize());
+    ByteString data = emptyMessageLite2.toByteString();
+    assertEquals(0, data.size());
+  }
+
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java b/protobuf/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
new file mode 100644
index 0000000..b1c75fc
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java
@@ -0,0 +1,227 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * Tests for {@link UnmodifiableLazyStringList}.
+ *
+ * @author jonp@google.com (Jon Perlow)
+ */
+public class UnmodifiableLazyStringListTest extends TestCase {
+
+  private static String STRING_A = "A";
+  private static String STRING_B = "B";
+  private static String STRING_C = "C";
+
+  private static ByteString BYTE_STRING_A = ByteString.copyFromUtf8("A");
+  private static ByteString BYTE_STRING_B = ByteString.copyFromUtf8("B");
+  private static ByteString BYTE_STRING_C = ByteString.copyFromUtf8("C");
+
+  public void testReadOnlyMethods() {
+    LazyStringArrayList rawList = createSampleList();
+    UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+    assertEquals(3, list.size());
+    assertSame(STRING_A, list.get(0));
+    assertSame(STRING_B, list.get(1));
+    assertSame(STRING_C, list.get(2));
+    assertEquals(BYTE_STRING_A, list.getByteString(0));
+    assertEquals(BYTE_STRING_B, list.getByteString(1));
+    assertEquals(BYTE_STRING_C, list.getByteString(2));
+
+    List<ByteString> byteStringList = list.asByteStringList();
+    assertSame(list.getByteString(0), byteStringList.get(0));
+    assertSame(list.getByteString(1), byteStringList.get(1));
+    assertSame(list.getByteString(2), byteStringList.get(2));
+  }
+
+  public void testModifyMethods() {
+    LazyStringArrayList rawList = createSampleList();
+    UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+
+    try {
+      list.remove(0);
+      fail();
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+    assertEquals(3, list.size());
+
+    try {
+      list.add(STRING_B);
+      fail();
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+    assertEquals(3, list.size());
+
+    try {
+      list.set(1, STRING_B);
+      fail();
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+    assertEquals(3, list.size());
+
+    List<ByteString> byteStringList = list.asByteStringList();
+    try {
+      byteStringList.remove(0);
+      fail();
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+    assertEquals(3, list.size());
+    assertEquals(3, byteStringList.size());
+
+    try {
+      byteStringList.add(BYTE_STRING_B);
+      fail();
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+    assertEquals(3, list.size());
+    assertEquals(3, byteStringList.size());
+
+    try {
+      byteStringList.set(1, BYTE_STRING_B);
+      fail();
+    } catch (UnsupportedOperationException e) {
+      // expected
+    }
+    assertEquals(3, list.size());
+    assertEquals(3, byteStringList.size());
+  }
+
+  public void testIterator() {
+    LazyStringArrayList rawList = createSampleList();
+    UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+
+    Iterator<String> iter = list.iterator();
+    int count = 0;
+    while (iter.hasNext()) {
+      iter.next();
+      count++;
+      try {
+        iter.remove();
+        fail();
+      } catch (UnsupportedOperationException e) {
+        // expected
+      }
+    }
+    assertEquals(3, count);
+
+    List<ByteString> byteStringList = list.asByteStringList();
+    Iterator<ByteString> byteIter = byteStringList.iterator();
+    count = 0;
+    while (byteIter.hasNext()) {
+      byteIter.next();
+      count++;
+      try {
+        byteIter.remove();
+        fail();
+      } catch (UnsupportedOperationException e) {
+        // expected
+      }
+    }
+    assertEquals(3, count);
+  }
+
+  public void testListIterator() {
+    LazyStringArrayList rawList = createSampleList();
+    UnmodifiableLazyStringList list = new UnmodifiableLazyStringList(rawList);
+
+    ListIterator<String> iter = list.listIterator();
+    int count = 0;
+    while (iter.hasNext()) {
+      iter.next();
+      count++;
+      try {
+        iter.remove();
+        fail();
+      } catch (UnsupportedOperationException e) {
+        // expected
+      }
+      try {
+        iter.set("bar");
+        fail();
+      } catch (UnsupportedOperationException e) {
+        // expected
+      }
+      try {
+        iter.add("bar");
+        fail();
+      } catch (UnsupportedOperationException e) {
+        // expected
+      }
+    }
+    assertEquals(3, count);
+
+    List<ByteString> byteStringList = list.asByteStringList();
+    ListIterator<ByteString> byteIter = byteStringList.listIterator();
+    count = 0;
+    while (byteIter.hasNext()) {
+      byteIter.next();
+      count++;
+      try {
+        byteIter.remove();
+        fail();
+      } catch (UnsupportedOperationException e) {
+        // expected
+      }
+      try {
+        byteIter.set(BYTE_STRING_A);
+        fail();
+      } catch (UnsupportedOperationException e) {
+        // expected
+      }
+      try {
+        byteIter.add(BYTE_STRING_A);
+        fail();
+      } catch (UnsupportedOperationException e) {
+        // expected
+      }
+    }
+    assertEquals(3, count);
+  }
+
+  private LazyStringArrayList createSampleList() {
+    LazyStringArrayList rawList = new LazyStringArrayList();
+    rawList.add(STRING_A);
+    rawList.add(STRING_B);
+    rawList.add(STRING_C);
+    return rawList;
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/WireFormatTest.java b/protobuf/java/src/test/java/com/google/protobuf/WireFormatTest.java
new file mode 100644
index 0000000..6858524
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/WireFormatTest.java
@@ -0,0 +1,606 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+
+import protobuf_unittest.UnittestProto;
+import protobuf_unittest.UnittestProto.TestAllExtensions;
+import protobuf_unittest.UnittestProto.TestAllTypes;
+import protobuf_unittest.UnittestProto.TestFieldOrderings;
+import protobuf_unittest.UnittestProto.TestOneof2;
+import protobuf_unittest.UnittestProto.TestOneofBackwardsCompatible;
+import protobuf_unittest.UnittestProto.TestPackedExtensions;
+import protobuf_unittest.UnittestProto.TestPackedTypes;
+import protobuf_unittest.UnittestMset.TestMessageSet;
+import protobuf_unittest.UnittestMset.RawMessageSet;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension1;
+import protobuf_unittest.UnittestMset.TestMessageSetExtension2;
+import com.google.protobuf.UnittestLite.TestAllExtensionsLite;
+import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
+
+/**
+ * Tests related to parsing and serialization.
+ *
+ * @author kenton@google.com (Kenton Varda)
+ */
+public class WireFormatTest extends TestCase {
+  public void testSerialization() throws Exception {
+    TestAllTypes message = TestUtil.getAllSet();
+
+    ByteString rawBytes = message.toByteString();
+    assertEquals(rawBytes.size(), message.getSerializedSize());
+
+    TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+    TestUtil.assertAllFieldsSet(message2);
+  }
+
+  public void testSerializationPacked() throws Exception {
+    TestPackedTypes message = TestUtil.getPackedSet();
+
+    ByteString rawBytes = message.toByteString();
+    assertEquals(rawBytes.size(), message.getSerializedSize());
+
+    TestPackedTypes message2 = TestPackedTypes.parseFrom(rawBytes);
+
+    TestUtil.assertPackedFieldsSet(message2);
+  }
+
+  public void testSerializeExtensions() throws Exception {
+    // TestAllTypes and TestAllExtensions should have compatible wire formats,
+    // so if we serialize a TestAllExtensions then parse it as TestAllTypes
+    // it should work.
+
+    TestAllExtensions message = TestUtil.getAllExtensionsSet();
+    ByteString rawBytes = message.toByteString();
+    assertEquals(rawBytes.size(), message.getSerializedSize());
+
+    TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+    TestUtil.assertAllFieldsSet(message2);
+  }
+
+  public void testSerializePackedExtensions() throws Exception {
+    // TestPackedTypes and TestPackedExtensions should have compatible wire
+    // formats; check that they serialize to the same string.
+    TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
+    ByteString rawBytes = message.toByteString();
+
+    TestPackedTypes message2 = TestUtil.getPackedSet();
+    ByteString rawBytes2 = message2.toByteString();
+
+    assertEquals(rawBytes, rawBytes2);
+  }
+
+  public void testSerializationPackedWithoutGetSerializedSize()
+      throws Exception {
+    // Write directly to an OutputStream, without invoking getSerializedSize()
+    // This used to be a bug where the size of a packed field was incorrect,
+    // since getSerializedSize() was never invoked.
+    TestPackedTypes message = TestUtil.getPackedSet();
+
+    // Directly construct a CodedOutputStream around the actual OutputStream,
+    // in case writeTo(OutputStream output) invokes getSerializedSize();
+    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+    CodedOutputStream codedOutput = CodedOutputStream.newInstance(outputStream);
+
+    message.writeTo(codedOutput);
+
+    codedOutput.flush();
+
+    TestPackedTypes message2 = TestPackedTypes.parseFrom(
+        outputStream.toByteArray());
+
+    TestUtil.assertPackedFieldsSet(message2);
+  }
+
+  public void testSerializeExtensionsLite() throws Exception {
+    // TestAllTypes and TestAllExtensions should have compatible wire formats,
+    // so if we serialize a TestAllExtensions then parse it as TestAllTypes
+    // it should work.
+
+    TestAllExtensionsLite message = TestUtil.getAllLiteExtensionsSet();
+    ByteString rawBytes = message.toByteString();
+    assertEquals(rawBytes.size(), message.getSerializedSize());
+
+    TestAllTypes message2 = TestAllTypes.parseFrom(rawBytes);
+
+    TestUtil.assertAllFieldsSet(message2);
+  }
+
+  public void testSerializePackedExtensionsLite() throws Exception {
+    // TestPackedTypes and TestPackedExtensions should have compatible wire
+    // formats; check that they serialize to the same string.
+    TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet();
+    ByteString rawBytes = message.toByteString();
+
+    TestPackedTypes message2 = TestUtil.getPackedSet();
+    ByteString rawBytes2 = message2.toByteString();
+
+    assertEquals(rawBytes, rawBytes2);
+  }
+
+  public void testParseExtensions() throws Exception {
+    // TestAllTypes and TestAllExtensions should have compatible wire formats,
+    // so if we serialize a TestAllTypes then parse it as TestAllExtensions
+    // it should work.
+
+    TestAllTypes message = TestUtil.getAllSet();
+    ByteString rawBytes = message.toByteString();
+
+    ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+
+    TestAllExtensions message2 =
+      TestAllExtensions.parseFrom(rawBytes, registry);
+
+    TestUtil.assertAllExtensionsSet(message2);
+  }
+
+  public void testParsePackedExtensions() throws Exception {
+    // Ensure that packed extensions can be properly parsed.
+    TestPackedExtensions message = TestUtil.getPackedExtensionsSet();
+    ByteString rawBytes = message.toByteString();
+
+    ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+
+    TestPackedExtensions message2 =
+        TestPackedExtensions.parseFrom(rawBytes, registry);
+
+    TestUtil.assertPackedExtensionsSet(message2);
+  }
+
+  public void testParseExtensionsLite() throws Exception {
+    // TestAllTypes and TestAllExtensions should have compatible wire formats,
+    // so if we serialize a TestAllTypes then parse it as TestAllExtensions
+    // it should work.
+
+    TestAllTypes message = TestUtil.getAllSet();
+    ByteString rawBytes = message.toByteString();
+
+    ExtensionRegistryLite registry_lite = TestUtil.getExtensionRegistryLite();
+
+    TestAllExtensionsLite message2 =
+      TestAllExtensionsLite.parseFrom(rawBytes, registry_lite);
+
+    TestUtil.assertAllExtensionsSet(message2);
+
+    // Try again using a full extension registry.
+    ExtensionRegistry registry = TestUtil.getExtensionRegistry();
+
+    TestAllExtensionsLite message3 =
+      TestAllExtensionsLite.parseFrom(rawBytes, registry);
+
+    TestUtil.assertAllExtensionsSet(message3);
+  }
+
+  public void testParsePackedExtensionsLite() throws Exception {
+    // Ensure that packed extensions can be properly parsed.
+    TestPackedExtensionsLite message = TestUtil.getLitePackedExtensionsSet();
+    ByteString rawBytes = message.toByteString();
+
+    ExtensionRegistryLite registry = TestUtil.getExtensionRegistryLite();
+
+    TestPackedExtensionsLite message2 =
+        TestPackedExtensionsLite.parseFrom(rawBytes, registry);
+
+    TestUtil.assertPackedExtensionsSet(message2);
+  }
+
+  public void testExtensionsSerializedSize() throws Exception {
+    assertNotSame(TestUtil.getAllSet().getSerializedSize(),
+                  TestUtil.getAllExtensionsSet().getSerializedSize());
+  }
+
+  public void testSerializeDelimited() throws Exception {
+    ByteArrayOutputStream output = new ByteArrayOutputStream();
+    TestUtil.getAllSet().writeDelimitedTo(output);
+    output.write(12);
+    TestUtil.getPackedSet().writeDelimitedTo(output);
+    output.write(34);
+
+    ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
+
+    TestUtil.assertAllFieldsSet(TestAllTypes.parseDelimitedFrom(input));
+    assertEquals(12, input.read());
+    TestUtil.assertPackedFieldsSet(TestPackedTypes.parseDelimitedFrom(input));
+    assertEquals(34, input.read());
+    assertEquals(-1, input.read());
+
+    // We're at EOF, so parsing again should return null.
+    assertTrue(TestAllTypes.parseDelimitedFrom(input) == null);
+  }
+
+  private void assertFieldsInOrder(ByteString data) throws Exception {
+    CodedInputStream input = data.newCodedInput();
+    int previousTag = 0;
+
+    while (true) {
+      int tag = input.readTag();
+      if (tag == 0) {
+        break;
+      }
+
+      assertTrue(tag > previousTag);
+      previousTag = tag;
+      input.skipField(tag);
+    }
+  }
+
+  public void testInterleavedFieldsAndExtensions() throws Exception {
+    // Tests that fields are written in order even when extension ranges
+    // are interleaved with field numbers.
+    ByteString data =
+      TestFieldOrderings.newBuilder()
+        .setMyInt(1)
+        .setMyString("foo")
+        .setMyFloat(1.0F)
+        .setExtension(UnittestProto.myExtensionInt, 23)
+        .setExtension(UnittestProto.myExtensionString, "bar")
+        .build().toByteString();
+    assertFieldsInOrder(data);
+
+    Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor();
+    ByteString dynamic_data =
+      DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor())
+        .setField(descriptor.findFieldByName("my_int"), 1L)
+        .setField(descriptor.findFieldByName("my_string"), "foo")
+        .setField(descriptor.findFieldByName("my_float"), 1.0F)
+        .setField(UnittestProto.myExtensionInt.getDescriptor(), 23)
+        .setField(UnittestProto.myExtensionString.getDescriptor(), "bar")
+        .build().toByteString();
+    assertFieldsInOrder(dynamic_data);
+  }
+
+  private ExtensionRegistry getTestFieldOrderingsRegistry() {
+    ExtensionRegistry result = ExtensionRegistry.newInstance();
+    result.add(UnittestProto.myExtensionInt);
+    result.add(UnittestProto.myExtensionString);
+    return result;
+  }
+
+  public void testParseMultipleExtensionRanges() throws Exception {
+    // Make sure we can parse a message that contains multiple extensions
+    // ranges.
+    TestFieldOrderings source =
+      TestFieldOrderings.newBuilder()
+        .setMyInt(1)
+        .setMyString("foo")
+        .setMyFloat(1.0F)
+        .setExtension(UnittestProto.myExtensionInt, 23)
+        .setExtension(UnittestProto.myExtensionString, "bar")
+        .build();
+    TestFieldOrderings dest =
+      TestFieldOrderings.parseFrom(source.toByteString(),
+                                   getTestFieldOrderingsRegistry());
+    assertEquals(source, dest);
+  }
+
+  public void testParseMultipleExtensionRangesDynamic() throws Exception {
+    // Same as above except with DynamicMessage.
+    Descriptors.Descriptor descriptor = TestFieldOrderings.getDescriptor();
+    DynamicMessage source =
+      DynamicMessage.newBuilder(TestFieldOrderings.getDescriptor())
+        .setField(descriptor.findFieldByName("my_int"), 1L)
+        .setField(descriptor.findFieldByName("my_string"), "foo")
+        .setField(descriptor.findFieldByName("my_float"), 1.0F)
+        .setField(UnittestProto.myExtensionInt.getDescriptor(), 23)
+        .setField(UnittestProto.myExtensionString.getDescriptor(), "bar")
+        .build();
+    DynamicMessage dest =
+      DynamicMessage.parseFrom(descriptor, source.toByteString(),
+                               getTestFieldOrderingsRegistry());
+    assertEquals(source, dest);
+  }
+
+  private static final int UNKNOWN_TYPE_ID = 1550055;
+  private static final int TYPE_ID_1 =
+    TestMessageSetExtension1.getDescriptor().getExtensions().get(0).getNumber();
+  private static final int TYPE_ID_2 =
+    TestMessageSetExtension2.getDescriptor().getExtensions().get(0).getNumber();
+
+  public void testSerializeMessageSetEagerly() throws Exception {
+    testSerializeMessageSetWithFlag(true);
+  }
+
+  public void testSerializeMessageSetNotEagerly() throws Exception {
+    testSerializeMessageSetWithFlag(false);
+  }
+
+  private void testSerializeMessageSetWithFlag(boolean eagerParsing)
+      throws Exception {
+    ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
+    // Set up a TestMessageSet with two known messages and an unknown one.
+    TestMessageSet messageSet =
+      TestMessageSet.newBuilder()
+        .setExtension(
+          TestMessageSetExtension1.messageSetExtension,
+          TestMessageSetExtension1.newBuilder().setI(123).build())
+        .setExtension(
+          TestMessageSetExtension2.messageSetExtension,
+          TestMessageSetExtension2.newBuilder().setStr("foo").build())
+        .setUnknownFields(
+          UnknownFieldSet.newBuilder()
+            .addField(UNKNOWN_TYPE_ID,
+              UnknownFieldSet.Field.newBuilder()
+                .addLengthDelimited(ByteString.copyFromUtf8("bar"))
+                .build())
+            .build())
+        .build();
+
+    ByteString data = messageSet.toByteString();
+
+    // Parse back using RawMessageSet and check the contents.
+    RawMessageSet raw = RawMessageSet.parseFrom(data);
+
+    assertTrue(raw.getUnknownFields().asMap().isEmpty());
+
+    assertEquals(3, raw.getItemCount());
+    assertEquals(TYPE_ID_1, raw.getItem(0).getTypeId());
+    assertEquals(TYPE_ID_2, raw.getItem(1).getTypeId());
+    assertEquals(UNKNOWN_TYPE_ID, raw.getItem(2).getTypeId());
+
+    TestMessageSetExtension1 message1 =
+      TestMessageSetExtension1.parseFrom(
+        raw.getItem(0).getMessage().toByteArray());
+    assertEquals(123, message1.getI());
+
+    TestMessageSetExtension2 message2 =
+      TestMessageSetExtension2.parseFrom(
+        raw.getItem(1).getMessage().toByteArray());
+    assertEquals("foo", message2.getStr());
+
+    assertEquals("bar", raw.getItem(2).getMessage().toStringUtf8());
+  }
+
+  public void testParseMessageSetEagerly() throws Exception {
+    testParseMessageSetWithFlag(true);
+  }
+
+  public void testParseMessageSetNotEagerly()throws Exception {
+    testParseMessageSetWithFlag(false);
+  }
+
+  private void testParseMessageSetWithFlag(boolean eagerParsing)
+      throws Exception {
+    ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
+    ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+    extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+    extensionRegistry.add(TestMessageSetExtension2.messageSetExtension);
+
+    // Set up a RawMessageSet with two known messages and an unknown one.
+    RawMessageSet raw =
+      RawMessageSet.newBuilder()
+        .addItem(
+          RawMessageSet.Item.newBuilder()
+            .setTypeId(TYPE_ID_1)
+            .setMessage(
+              TestMessageSetExtension1.newBuilder()
+                .setI(123)
+                .build().toByteString())
+            .build())
+        .addItem(
+          RawMessageSet.Item.newBuilder()
+            .setTypeId(TYPE_ID_2)
+            .setMessage(
+              TestMessageSetExtension2.newBuilder()
+                .setStr("foo")
+                .build().toByteString())
+            .build())
+        .addItem(
+          RawMessageSet.Item.newBuilder()
+            .setTypeId(UNKNOWN_TYPE_ID)
+            .setMessage(ByteString.copyFromUtf8("bar"))
+            .build())
+        .build();
+
+    ByteString data = raw.toByteString();
+
+    // Parse as a TestMessageSet and check the contents.
+    TestMessageSet messageSet =
+      TestMessageSet.parseFrom(data, extensionRegistry);
+
+    assertEquals(123, messageSet.getExtension(
+      TestMessageSetExtension1.messageSetExtension).getI());
+    assertEquals("foo", messageSet.getExtension(
+      TestMessageSetExtension2.messageSetExtension).getStr());
+
+    // Check for unknown field with type LENGTH_DELIMITED,
+    //   number UNKNOWN_TYPE_ID, and contents "bar".
+    UnknownFieldSet unknownFields = messageSet.getUnknownFields();
+    assertEquals(1, unknownFields.asMap().size());
+    assertTrue(unknownFields.hasField(UNKNOWN_TYPE_ID));
+
+    UnknownFieldSet.Field field = unknownFields.getField(UNKNOWN_TYPE_ID);
+    assertEquals(1, field.getLengthDelimitedList().size());
+    assertEquals("bar", field.getLengthDelimitedList().get(0).toStringUtf8());
+  }
+
+  public void testParseMessageSetExtensionEagerly() throws Exception {
+    testParseMessageSetExtensionWithFlag(true);
+  }
+
+  public void testParseMessageSetExtensionNotEagerly() throws Exception {
+    testParseMessageSetExtensionWithFlag(false);
+  }
+
+  private void testParseMessageSetExtensionWithFlag(boolean eagerParsing)
+      throws Exception {
+    ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
+    ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+    extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+
+    // Set up a RawMessageSet with a known messages.
+    int TYPE_ID_1 =
+        TestMessageSetExtension1
+            .getDescriptor().getExtensions().get(0).getNumber();
+    RawMessageSet raw =
+      RawMessageSet.newBuilder()
+        .addItem(
+          RawMessageSet.Item.newBuilder()
+            .setTypeId(TYPE_ID_1)
+            .setMessage(
+              TestMessageSetExtension1.newBuilder()
+                .setI(123)
+                .build().toByteString())
+            .build())
+        .build();
+
+    ByteString data = raw.toByteString();
+
+    // Parse as a TestMessageSet and check the contents.
+    TestMessageSet messageSet =
+        TestMessageSet.parseFrom(data, extensionRegistry);
+    assertEquals(123, messageSet.getExtension(
+        TestMessageSetExtension1.messageSetExtension).getI());
+  }
+
+  public void testMergeLazyMessageSetExtensionEagerly() throws Exception {
+    testMergeLazyMessageSetExtensionWithFlag(true);
+  }
+
+  public void testMergeLazyMessageSetExtensionNotEagerly() throws Exception {
+    testMergeLazyMessageSetExtensionWithFlag(false);
+  }
+
+  private void testMergeLazyMessageSetExtensionWithFlag(boolean eagerParsing)
+      throws Exception {
+    ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
+    ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+    extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+
+    // Set up a RawMessageSet with a known messages.
+    int TYPE_ID_1 =
+        TestMessageSetExtension1
+            .getDescriptor().getExtensions().get(0).getNumber();
+    RawMessageSet raw =
+      RawMessageSet.newBuilder()
+        .addItem(
+          RawMessageSet.Item.newBuilder()
+            .setTypeId(TYPE_ID_1)
+            .setMessage(
+              TestMessageSetExtension1.newBuilder()
+                .setI(123)
+                .build().toByteString())
+            .build())
+        .build();
+
+    ByteString data = raw.toByteString();
+
+    // Parse as a TestMessageSet and store value into lazy field
+    TestMessageSet messageSet =
+        TestMessageSet.parseFrom(data, extensionRegistry);
+    // Merge lazy field check the contents.
+    messageSet =
+        messageSet.toBuilder().mergeFrom(data, extensionRegistry).build();
+    assertEquals(123, messageSet.getExtension(
+        TestMessageSetExtension1.messageSetExtension).getI());
+  }
+
+  public void testMergeMessageSetExtensionEagerly() throws Exception {
+    testMergeMessageSetExtensionWithFlag(true);
+  }
+
+  public void testMergeMessageSetExtensionNotEagerly() throws Exception {
+    testMergeMessageSetExtensionWithFlag(false);
+  }
+
+  private void testMergeMessageSetExtensionWithFlag(boolean eagerParsing)
+      throws Exception {
+    ExtensionRegistryLite.setEagerlyParseMessageSets(eagerParsing);
+    ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
+    extensionRegistry.add(TestMessageSetExtension1.messageSetExtension);
+
+    // Set up a RawMessageSet with a known messages.
+    int TYPE_ID_1 =
+        TestMessageSetExtension1
+            .getDescriptor().getExtensions().get(0).getNumber();
+    RawMessageSet raw =
+      RawMessageSet.newBuilder()
+        .addItem(
+          RawMessageSet.Item.newBuilder()
+            .setTypeId(TYPE_ID_1)
+            .setMessage(
+              TestMessageSetExtension1.newBuilder()
+                .setI(123)
+                .build().toByteString())
+            .build())
+        .build();
+
+    // Serialize RawMessageSet unnormally (message value before type id)
+    ByteString.CodedBuilder out = ByteString.newCodedBuilder(
+        raw.getSerializedSize());
+    CodedOutputStream output = out.getCodedOutput();
+    List<RawMessageSet.Item> items = raw.getItemList();
+    for (int i = 0; i < items.size(); i++) {
+      RawMessageSet.Item item = items.get(i);
+      output.writeTag(1, WireFormat.WIRETYPE_START_GROUP);
+      output.writeBytes(3, item.getMessage());
+      output.writeInt32(2, item.getTypeId());
+      output.writeTag(1, WireFormat.WIRETYPE_END_GROUP);
+    }
+    ByteString data = out.build();
+
+    // Merge bytes into TestMessageSet and check the contents.
+    TestMessageSet messageSet =
+        TestMessageSet.newBuilder().mergeFrom(data, extensionRegistry).build();
+    assertEquals(123, messageSet.getExtension(
+        TestMessageSetExtension1.messageSetExtension).getI());
+  }
+
+  // ================================================================
+  // oneof
+  public void testOneofWireFormat() throws Exception {
+    TestOneof2.Builder builder = TestOneof2.newBuilder();
+    TestUtil.setOneof(builder);
+    TestOneof2 message = builder.build();
+    ByteString rawBytes = message.toByteString();
+
+    assertEquals(rawBytes.size(), message.getSerializedSize());
+
+    TestOneof2 message2 = TestOneof2.parseFrom(rawBytes);
+    TestUtil.assertOneofSet(message2);
+  }
+
+  public void testOneofOnlyLastSet() throws Exception {
+    TestOneofBackwardsCompatible source = TestOneofBackwardsCompatible
+        .newBuilder().setFooInt(100).setFooString("101").build();
+
+    ByteString rawBytes = source.toByteString();
+    TestOneof2 message = TestOneof2.parseFrom(rawBytes);
+    assertFalse(message.hasFooInt());
+    assertTrue(message.hasFooString());
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto b/protobuf/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto
new file mode 100644
index 0000000..baed4e1
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/lazy_fields_lite.proto
@@ -0,0 +1,61 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Naoki Iwasaki (niwasaki@google.com)
+//
+// A proto file with lazy fields
+
+
+package protobuf_unittest;
+
+option optimize_for = LITE_RUNTIME;
+
+message LazyMessageLite {
+  optional int32 num = 1;
+  optional int32 num_with_default = 2 [default = 421];
+  optional LazyInnerMessageLite inner = 3 [lazy = true];
+  repeated LazyInnerMessageLite repeated_inner = 4 [lazy = true];
+
+  oneof oneof_field {
+    int32 oneof_num = 5;
+    LazyInnerMessageLite oneof_inner = 6 [lazy = true];
+  }
+}
+
+message LazyInnerMessageLite {
+  optional int32 num = 1;
+  optional int32 num_with_default = 2 [default = 42];
+  optional LazyNestedInnerMessageLite nested = 3 [lazy = true];
+}
+
+message LazyNestedInnerMessageLite {
+  optional int32 num = 1;
+  optional int32 num_with_default = 2 [default = 4];
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto b/protobuf/java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto
new file mode 100644
index 0000000..6861567
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/lite_equals_and_hash.proto
@@ -0,0 +1,55 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: pbogle@google.com (Phil Bogle)
+
+
+package protobuf_unittest.lite_equals_and_hash;
+
+// This proto definition is used to test that java_generate_equals_and_hash
+// works correctly with the LITE_RUNTIME.
+option java_generate_equals_and_hash = true;
+option optimize_for = LITE_RUNTIME;
+
+message Foo {
+  optional int32 value = 1;
+  repeated Bar bar = 2;
+}
+
+message Bar {
+  optional string name = 1;
+}
+
+message BarPrime {
+  optional string name = 1;
+}
+
+message Empty {
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/multiple_files_test.proto b/protobuf/java/src/test/java/com/google/protobuf/multiple_files_test.proto
new file mode 100644
index 0000000..7ec89a0
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/multiple_files_test.proto
@@ -0,0 +1,77 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// A proto file which tests the java_multiple_files option.
+
+
+// Some generic_services option(s) added automatically.
+// See:  http://go/proto2-generic-services-default
+option java_generic_services = true;   // auto-added
+
+import "google/protobuf/unittest.proto";
+import "google/protobuf/descriptor.proto";
+
+package protobuf_unittest;
+
+option java_multiple_files = true;
+option java_outer_classname = "MultipleFilesTestProto";
+
+
+message MessageWithNoOuter {
+  message NestedMessage {
+    optional int32 i = 1;
+  }
+  enum NestedEnum {
+    BAZ = 3;
+  }
+  optional NestedMessage nested = 1;
+  repeated TestAllTypes foreign = 2;
+  optional NestedEnum nested_enum = 3;
+  optional EnumWithNoOuter foreign_enum = 4;
+}
+
+extend google.protobuf.EnumValueOptions {
+  optional int32 enum_value_option = 7654321;
+}
+
+enum EnumWithNoOuter {
+  FOO = 1 [(enum_value_option) = 12345];
+  BAR = 2;
+}
+
+service ServiceWithNoOuter {
+  rpc Foo(MessageWithNoOuter) returns(TestAllTypes);
+}
+
+extend TestAllExtensions {
+  optional int32 extension_with_outer = 1234567;
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/nested_builders_test.proto b/protobuf/java/src/test/java/com/google/protobuf/nested_builders_test.proto
new file mode 100644
index 0000000..8ab4a43
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/nested_builders_test.proto
@@ -0,0 +1,53 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jonp@google.com (Jon Perlow)
+//
+
+package protobuf_unittest;
+
+option java_multiple_files = true;
+option java_outer_classname = "NestedBuilders";
+
+
+message Vehicle {
+  optional Engine engine = 1;
+  repeated Wheel wheel = 2;
+}
+
+message Engine {
+  optional int32 cylinder = 1;
+  optional int32 liters = 2;
+}
+
+message Wheel {
+  optional int32 radius = 1;
+  optional int32 width = 2;
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/nested_extension.proto b/protobuf/java/src/test/java/com/google/protobuf/nested_extension.proto
new file mode 100644
index 0000000..8649286
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/nested_extension.proto
@@ -0,0 +1,46 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with nested extensions. Note that this must be defined in
+// a separate file to properly test the initialization of the outer class.
+
+
+import "com/google/protobuf/non_nested_extension.proto";
+
+package protobuf_unittest;
+
+
+message MyNestedExtension {
+  extend MessageToBeExtended {
+    optional MessageToBeExtended recursiveExtension = 2;
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/nested_extension_lite.proto b/protobuf/java/src/test/java/com/google/protobuf/nested_extension_lite.proto
new file mode 100644
index 0000000..9c68682
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/nested_extension_lite.proto
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with nested extensions for a MessageLite messages. Note that
+// this must be defined in a separate file to properly test the initialization
+// of the outer class.
+
+
+package protobuf_unittest;
+
+option optimize_for = LITE_RUNTIME;
+
+import "com/google/protobuf/non_nested_extension_lite.proto";
+
+message MyNestedExtensionLite {
+  extend MessageLiteToBeExtended {
+    optional MessageLiteToBeExtended recursiveExtensionLite = 3;
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension.proto b/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension.proto
new file mode 100644
index 0000000..cb2f8b0
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension.proto
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with extensions.
+
+
+package protobuf_unittest;
+
+
+message MessageToBeExtended {
+  extensions 1 to max;
+}
+
+message MyNonNestedExtension {
+}
+
+extend MessageToBeExtended {
+  optional MyNonNestedExtension nonNestedExtension = 1;
+}
+
diff --git a/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto b/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto
new file mode 100644
index 0000000..c1f744b
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/non_nested_extension_lite.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Darick Tong (darick@google.com)
+//
+// A proto file with extensions for a MessageLite messages.
+
+
+package protobuf_unittest;
+
+option optimize_for = LITE_RUNTIME;
+
+message MessageLiteToBeExtended {
+  extensions 1 to max;
+}
+
+message MyNonNestedExtensionLite {
+}
+
+extend MessageLiteToBeExtended {
+  optional MyNonNestedExtensionLite nonNestedExtensionLite = 1;
+}
+
diff --git a/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test.proto b/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test.proto
new file mode 100644
index 0000000..c5114f8
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test.proto
@@ -0,0 +1,38 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package protobuf_unittest;
+
+
+// This message's name is the same with the default outer class name of this
+// proto file. It's used to test if the compiler can avoid this conflict
+// correctly.
+message OuterClassNameTest {
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test2.proto b/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test2.proto
new file mode 100644
index 0000000..741cd28
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test2.proto
@@ -0,0 +1,42 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package protobuf_unittest;
+
+
+message TestMessage2 {
+  message NestedMessage {
+    // This message's name is the same with the default outer class name of this
+    // proto file. It's used to test if the compiler can avoid this conflict
+    // correctly.
+    message OuterClassNameTest2 {
+    }
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test3.proto b/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test3.proto
new file mode 100644
index 0000000..5d5d4ac
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/outer_class_name_test3.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package protobuf_unittest;
+
+
+message TestMessage3 {
+  message NestedMessage {
+    // This enum's name is the same with the default outer class name of this
+    // proto file. It's used to test if the compiler can avoid this conflict
+    // correctly.
+    enum OuterClassNameTest3 {
+      DUMMY_VALUE = 1;
+    }
+  }
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto b/protobuf/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto
new file mode 100644
index 0000000..202e8c9
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/test_bad_identifiers.proto
@@ -0,0 +1,157 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jonp@google.com (Jon Perlow)
+
+// This file tests that various identifiers work as field and type names even
+// though the same identifiers are used internally by the java code generator.
+
+
+// Some generic_services option(s) added automatically.
+// See:  http://go/proto2-generic-services-default
+option java_generic_services = true;   // auto-added
+
+package io_protocol_tests;
+
+option java_package = "com.google.protobuf";
+option java_outer_classname = "TestBadIdentifiersProto";
+option java_generate_equals_and_hash = true;
+
+message TestMessage {
+  optional string cached_size = 1;
+  optional string serialized_size = 2;
+  optional string class = 3;
+}
+
+message Descriptor {
+  option no_standard_descriptor_accessor = true;
+  optional string descriptor = 1;
+  message NestedDescriptor {
+    option no_standard_descriptor_accessor = true;
+    optional string descriptor = 1;
+  }
+  optional NestedDescriptor nested_descriptor = 2;
+  enum NestedEnum {
+    FOO = 1;
+  }
+}
+
+message Parser {
+  enum ParserEnum {
+    PARSER = 1;
+  }
+  optional ParserEnum parser = 1;
+}
+
+message Deprecated {
+  enum TestEnum {
+    FOO = 1;
+
+    // Test if @Deprecated annotation conflicts with Deprecated message name.
+    BAR = 2 [ deprecated = true ];
+  }
+
+  optional int32 field1 = 1 [deprecated=true];
+  optional TestEnum field2 = 2 [deprecated=true];
+  optional TestMessage field3 = 3 [deprecated=true];
+}
+
+message Override {
+  optional int32 override = 1;
+}
+
+message Object {
+  optional int32 object = 1;
+  optional string string_object = 2;
+}
+
+message String {
+  optional string string = 1;
+}
+
+message Integer {
+  optional int32 integer = 1;
+}
+
+message Long {
+  optional int32 long = 1;
+}
+
+message Float {
+  optional float float = 1;
+}
+
+message Double {
+  optional double double = 1;
+}
+
+service TestConflictingMethodNames {
+  rpc Override(TestMessage) returns (TestMessage);
+}
+
+message TestConflictingFieldNames {
+  enum TestEnum {
+    FOO = 1;
+  }
+  message TestMessage {
+  }
+  repeated int32 int32_field = 1;
+  repeated TestEnum enum_field = 2;
+  repeated string string_field = 3;
+  repeated bytes bytes_field = 4;
+  repeated TestMessage message_field = 5;
+
+  optional int32 int32_field_count = 11;
+  optional TestEnum enum_field_count = 12;
+  optional string string_field_count = 13;
+  optional bytes bytes_field_count = 14;
+  optional TestMessage message_field_count = 15;
+
+  repeated int32 Int32Field = 21;
+  repeated TestEnum EnumField = 22;
+  repeated string StringField = 23;
+  repeated bytes BytesField = 24;
+  repeated TestMessage MessageField = 25;
+
+  // This field conflicts with "int32_field" as they both generate
+  // the method getInt32FieldList().
+  required int32 int32_field_list = 31;
+
+  extensions 1000 to max;
+
+  repeated int64 int64_field = 41;
+  extend TestConflictingFieldNames {
+    // We don't generate accessors for extensions so the following extension
+    // fields don't conflict with the repeated field "int64_field".
+    optional int64 int64_field_count = 1001;
+    optional int64 int64_field_list = 1002;
+  }
+}
+
diff --git a/protobuf/java/src/test/java/com/google/protobuf/test_check_utf8.proto b/protobuf/java/src/test/java/com/google/protobuf/test_check_utf8.proto
new file mode 100644
index 0000000..206946d
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/test_check_utf8.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Jacob Butcher (jbaum@google.com)
+//
+// Test file option java_string_check_utf8.
+
+package proto2_test_check_utf8;
+
+option java_outer_classname = "TestCheckUtf8";
+option java_string_check_utf8 = true;
+
+message StringWrapper {
+  required string req = 1;
+  optional string opt = 2;
+  repeated string rep = 3;
+}
+
+message BytesWrapper {
+  required bytes req = 1;
+  optional bytes opt = 2;
+  repeated bytes rep = 3;
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/test_check_utf8_size.proto b/protobuf/java/src/test/java/com/google/protobuf/test_check_utf8_size.proto
new file mode 100644
index 0000000..fa057a8
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/test_check_utf8_size.proto
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Jacob Butcher (jbaum@google.com)
+//
+// Test file option java_string_check_utf8.
+
+package proto2_test_check_utf8_size;
+
+option java_outer_classname = "TestCheckUtf8Size";
+option java_string_check_utf8 = true;
+option optimize_for = CODE_SIZE;
+
+message StringWrapperSize {
+  required string req = 1;
+  optional string opt = 2;
+  repeated string rep = 3;
+}
+
+message BytesWrapperSize {
+  required bytes req = 1;
+  optional bytes opt = 2;
+  repeated bytes rep = 3;
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/test_custom_options.proto b/protobuf/java/src/test/java/com/google/protobuf/test_custom_options.proto
new file mode 100644
index 0000000..f6a5ecd
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/test_custom_options.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Feng Xiao (xiaofeng@google.com)
+//
+// Test that custom options defined in a proto file's dependencies are properly
+// initialized.
+
+package protobuf_unittest;
+
+
+import "google/protobuf/unittest_custom_options.proto";
+
+message TestMessageWithCustomOptionsContainer {
+  optional TestMessageWithCustomOptions field = 1;
+}
diff --git a/protobuf/java/src/test/java/com/google/protobuf/test_extra_interfaces.proto b/protobuf/java/src/test/java/com/google/protobuf/test_extra_interfaces.proto
new file mode 100644
index 0000000..72e05a3
--- /dev/null
+++ b/protobuf/java/src/test/java/com/google/protobuf/test_extra_interfaces.proto
@@ -0,0 +1,60 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: Darick Tong (darick@google.com)
+
+package protobuf_unittest;
+
+message Proto1 {
+  option experimental_java_message_interface =
+      "com.google.protobuf.ExtraInterfaces.HasBoolValue";
+
+  option experimental_java_interface_extends =
+      "com.google.protobuf.ExtraInterfaces.HasByteValue";
+
+  option experimental_java_message_interface =
+      "com.google.protobuf.ExtraInterfaces.HasStringValue<Proto1>";
+
+  option experimental_java_builder_interface =
+      "com.google.protobuf.ExtraInterfaces.HasStringValueBuilder"
+      "<Proto1, Builder>";
+
+  optional string string_value = 1;
+  optional bool bool_value = 2;
+  optional bytes byte_value = 3;
+  optional int32 int_value = 4;
+}
+
+message Proto2 {
+  option experimental_java_message_interface =
+      "com.google.protobuf.ExtraInterfaces.HasBoolValue";
+
+  optional bool bool_value = 1;
+}
diff --git a/protobuf/ltmain.sh b/protobuf/ltmain.sh
new file mode 100644
index 0000000..a356aca
--- /dev/null
+++ b/protobuf/ltmain.sh
@@ -0,0 +1,9661 @@
+
+# libtool (GNU libtool) 2.4.2
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+#       --config             show all configuration variables
+#       --debug              enable verbose shell tracing
+#   -n, --dry-run            display commands without modifying any files
+#       --features           display basic configuration information and exit
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --no-warn            don't display warning messages
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
+#
+# MODE must be one of the following:
+#
+#         clean              remove files from the build directory
+#         compile            compile a source file into a libtool object
+#         execute            automatically set library path, then run a program
+#         finish             complete the installation of libtool libraries
+#         install            install libraries or executables
+#         link               create a library or an executable
+#         uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#         host-triplet:	$host
+#         shell:		$SHELL
+#         compiler:		$LTCC
+#         compiler flags:		$LTCFLAGS
+#         linker:		$LD (gnu? $with_gnu_ld)
+#         $progname:	(GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1
+#         automake:	$automake_version
+#         autoconf:	$autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
+
+PROGRAM=libtool
+PACKAGE=libtool
+VERSION="2.4.2 Debian-2.4.2-1.7ubuntu1"
+TIMESTAMP=""
+package_revision=1.3337
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
+# NLS nuisances: We save the old values to restore during execute mode.
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+          save_$lt_var=\$$lt_var
+          $lt_var=C
+	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+	fi"
+done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
+
+$lt_unset CDPATH
+
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+
+
+: ${CP="cp -f"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+    case ${2} in
+      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+		s@/\./@/@g
+		t dotsl
+		s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
+}
+
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
+
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
+
+# The name of this program:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=$func_dirname_result
+     progdir=`cd "$progdir" && pwd`
+     progpath="$progdir/$progname"
+     ;;
+  *)
+     save_IFS="$IFS"
+     IFS=${PATH_SEPARATOR-:}
+     for progdir in $PATH; do
+       IFS="$save_IFS"
+       test -x "$progdir/$progname" && break
+     done
+     IFS="$save_IFS"
+     test -n "$progdir" || progdir=`pwd`
+     progpath="$progdir/$progname"
+     ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
+
+    # bash bug again:
+    :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information."  ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    my_directory_path="$1"
+    my_dir_list=
+
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$my_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list incase some portion of path contains whitespace.
+        my_dir_list="$my_directory_path:$my_dir_list"
+
+        # If the last portion added has no slash in it, the list is done
+        case $my_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
+      done
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
+
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$my_dir" 2>/dev/null || :
+      done
+      IFS="$save_mkdir_p_IFS"
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
+    fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$opt_dry_run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+        # Failing that, at least try and use $RANDOM to avoid a race
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+        save_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
+
+    $ECHO "$my_tmpdir"
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
+
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "$1" | $SED \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
+
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
+
+    func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $opt_debug
+
+    $SED -n '/(C)/!b go
+	:more
+	/\./!{
+	  N
+	  s/\n# / /
+	  b more
+	}
+	:go
+	/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    echo
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
+}
+
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
+func_help ()
+{
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+	:print
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
+	p
+	d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
+    fi
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    $opt_debug
+
+    func_error "missing argument for $1."
+    exit_cmd=exit
+}
+
+
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
+
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
+
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
+
+
+
+
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+nonopt=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
+
+    exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+
+    exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+  # Global variable:
+  tagname="$1"
+
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
+
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
+    *)
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+    fi
+
+    exit $EXIT_MISMATCH
+  fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
+  ;;
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
+  ;;
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
+  ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
+
+
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+  # this just eases exit handling
+  while test $# -gt 0; do
+    opt="$1"
+    shift
+    case $opt in
+      --debug|-x)	opt_debug='set -x'
+			func_echo "enabling shell trace mode"
+			$opt_debug
+			;;
+      --dry-run|--dryrun|-n)
+			opt_dry_run=:
+			;;
+      --config)
+			opt_config=:
+func_config
+			;;
+      --dlopen|-dlopen)
+			optarg="$1"
+			opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
+			shift
+			;;
+      --preserve-dup-deps)
+			opt_preserve_dup_deps=:
+			;;
+      --features)
+			opt_features=:
+func_features
+			;;
+      --finish)
+			opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+			;;
+      --help)
+			opt_help=:
+			;;
+      --help-all)
+			opt_help_all=:
+opt_help=': help-all'
+			;;
+      --mode)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+			shift
+			;;
+      --no-silent|--no-quiet)
+			opt_silent=false
+func_append preserve_args " $opt"
+			;;
+      --no-warning|--no-warn)
+			opt_warning=false
+func_append preserve_args " $opt"
+			;;
+      --no-verbose)
+			opt_verbose=false
+func_append preserve_args " $opt"
+			;;
+      --silent|--quiet)
+			opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+			;;
+      --verbose|-v)
+			opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+			;;
+      --tag)
+			test $# = 0 && func_missing_arg $opt && break
+			optarg="$1"
+			opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
+			shift
+			;;
+
+      -\?|-h)		func_usage				;;
+      --help)		func_help				;;
+      --version)	func_version				;;
+
+      # Separate optargs to long options:
+      --*=*)
+			func_split_long_opt "$opt"
+			set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+			func_split_short_opt "$opt"
+			set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+			shift
+			;;
+
+      --)		break					;;
+      -*)		func_fatal_help "unrecognized option \`$opt'" ;;
+      *)		set dummy "$opt" ${1+"$@"};	shift; break  ;;
+    esac
+  done
+
+  # Validate options:
+
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
+  fi
+
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
+
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
+      ;;
+  esac
+
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
+
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
+    fi
+
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
+
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
+
+
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
+}
+
+
+
+
+## ----------- ##
+##    Main.    ##
+## ----------- ##
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case "$lalib_p_line" in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $opt_debug
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$save_ifs
+      eval cmd=\"$cmd\"
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $opt_debug
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
+
+
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case "$lt_sysroot:$1" in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result="=$func_stripname_result"
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $opt_debug
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+	func_append_quoted CC_quoted "$arg"
+      done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	      # Double-quote args containing other shell metacharacters.
+	      func_append_quoted CC_quoted "$arg"
+	    done
+	    CC_expanded=`func_echo_all $CC`
+	    CC_quoted_expanded=`func_echo_all $CC_quoted`
+	    case "$@ " in
+	    " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+	    " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with \`--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
+    else
+      write_lobj=none
+    fi
+
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
+    else
+      write_oldobj=none
+    fi
+
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+      $MV "${write_libobj}T" "${write_libobj}"
+    }
+}
+
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero error code, so we
+    # are forced to check the contents of stdout. On the other hand, if the
+    # command is not found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both error code of
+    # zero AND non-empty stdout, which explains the odd construction:
+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$lt_sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $opt_debug
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=""
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
+      fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $opt_debug
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $opt_debug
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  \`$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result="$1"
+  fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $opt_debug
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  \`$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result="$3"
+    fi
+  fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $opt_debug
+  case $4 in
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $opt_debug
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $opt_debug
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
+      ;;
+  esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $opt_debug
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
+  fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $opt_debug
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $opt_debug
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify \`-o' more than once"
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-pie | -fpie | -fPIE)
+          func_append pie_flag " $arg"
+	  continue
+	  ;;
+
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  func_append later " $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+	  for arg in $args; do
+	    IFS="$save_ifs"
+	    func_append_quoted lastarg "$arg"
+	  done
+	  IFS="$save_ifs"
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
+
+	  # Add the arguments to base_compile.
+	  func_append base_compile " $lastarg"
+	  continue
+	  ;;
+
+	*)
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      func_append_quoted base_compile "$lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with \`-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj="$func_basename_result"
+      }
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
+
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	continue
+	;;
+
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
+
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      func_append removelist " $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
+
+    $opt_dry_run || $RM $removelist
+    func_append removelist " $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      func_mkdir_p "$xdir$objdir"
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	func_append command " -o $lobj"
+      fi
+
+      func_show_eval_locale "$command"	\
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	func_append command " -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      func_append command "$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
+
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+      # Unlock the critical section if it was locked
+      if test "$need_locks" != no; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
+
+    exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $opt_mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
+
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
+  -Wc,FLAG          pass FLAG directly to the compiler
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+        ;;
+
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode \`$opt_mode'"
+        ;;
+    esac
+
+    echo
+    $ECHO "Try \`$progname --help' for more information about other modes."
+}
+
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test "$opt_help" = :; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	func_mode_help
+      done
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+	echo
+	func_mode_help
+      done
+    } |
+    sed '1d
+      /^When reporting/,/^Report/{
+	H
+	d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
+fi
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $opt_debug
+    # The first argument is the command name.
+    cmd="$nonopt"
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $opt_dlopen; do
+      test -f "$file" \
+	|| func_fatal_help "\`$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  func_append dir "/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+	;;
+
+      *)
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -* | *.la | *.lo ) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_append_quoted args "$file"
+    done
+
+    if test "X$opt_dry_run" = Xfalse; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+	      else
+		$lt_unset $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	echo "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $opt_debug
+    libs=
+    libdirs=
+    admincmds=
+
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+	func_append libdirs " $opt"
+
+      elif test -f "$opt"; then
+	if func_lalib_unsafe_p "$opt"; then
+	  func_append libs " $opt"
+	else
+	  func_warning "\`$opt' is not a valid libtool archive"
+	fi
+
+      else
+	func_fatal_error "invalid argument \`$opt'"
+      fi
+    done
+
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
+
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+	  sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+	    > $tmpdir/tmp-la
+	  mv -f $tmpdir/tmp-la $lib
+	done
+        ${RM}r "$tmpdir"
+      fi
+    fi
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || func_append admincmds "
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_silent && exit $EXIT_SUCCESS
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      echo "Libraries have been installed in:"
+      for libdir in $libdirs; do
+	$ECHO "   $libdir"
+      done
+      echo
+      echo "If you ever happen to want to link against installed libraries"
+      echo "in a given directory, LIBDIR, you must either use libtool, and"
+      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+      echo "flag during linking and do at least one of the following:"
+      if test -n "$shlibpath_var"; then
+	echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+	echo "     during execution"
+      fi
+      if test -n "$runpath_var"; then
+	echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+	echo "     during linking"
+      fi
+      if test -n "$hardcode_libdir_flag_spec"; then
+	libdir=LIBDIR
+	eval flag=\"$hardcode_libdir_flag_spec\"
+
+	$ECHO "   - use the \`$flag' linker flag"
+      fi
+      if test -n "$admincmds"; then
+	$ECHO "   - have your system administrator run these commands:$admincmds"
+      fi
+      if test -f /etc/ld.so.conf; then
+	echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+      fi
+      echo
+
+      echo "See any operating system documentation about shared libraries for"
+      case $host in
+	solaris2.[6789]|solaris2.1[0-9])
+	  echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	  echo "pages."
+	  ;;
+	*)
+	  echo "more information, such as the ld(1) and ld.so(8) manual pages."
+	  ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
+    exit $EXIT_SUCCESS
+}
+
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $opt_debug
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       case $nonopt in *shtool*) :;; *) false;; esac; then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    no_mode=:
+    for arg
+    do
+      arg2=
+      if test -n "$dest"; then
+	func_append files " $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f)
+	if $install_cp; then :; else
+	  prev=$arg
+	fi
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  if test "x$prev" = x-m && test -n "$install_override_mode"; then
+	    arg2=$install_override_mode
+	    no_mode=false
+	  fi
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
+      if test -n "$arg2"; then
+	func_quote_for_eval "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_for_eval_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prev' option requires an argument"
+
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+	func_quote_for_eval "$install_override_mode"
+	func_append install_shared_prog " -m $func_quote_for_eval_result"
+      fi
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "\`$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	func_append staticlibs " $file"
+	;;
+
+      *.la)
+	func_resolve_sysroot "$file"
+	file=$func_resolve_sysroot_result
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
+
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append current_libdirs " $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) func_append future_libdirs " $libdir" ;;
+	  esac
+	fi
+
+	func_dirname "$file" "/" ""
+	dir="$func_dirname_result"
+	func_append dir "$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  func_warning "relinking \`$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname="$1"
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme="$stripme"
+	  case $host_os in
+	  cygwin* | mingw* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=""
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try `ln -sf' first, because the `ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
+
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name="$func_basename_result"
+	instname="$dir/$name"i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && func_append staticlibs " $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=""
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  func_source "$wrapper"
+
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if test "$finalize" = yes; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_silent || {
+	          func_quote_for_expand "$relink_command"
+		  eval "func_echo $func_quote_for_expand_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink \`$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file="$outputname"
+	      else
+	        func_warning "cannot relink \`$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
+	fi
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name="$func_basename_result"
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+      tool_oldlib=$func_to_tool_file_result
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms="${my_outputname}S.c"
+      else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist="$output_objdir/${my_outputname}.nm"
+
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
+
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
+
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+	    func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+	    $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols="$output_objdir/$outputname.exp"
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
+	  else
+	    $opt_dry_run || {
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin* | *mingw* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
+	  fi
+	fi
+
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
+	  func_basename "$dlprefile"
+	  name="$func_basename_result"
+          case $host in
+	    *cygwin* | *mingw* | *cegcc* )
+	      # if an import library, we need to obtain dlname
+	      if func_win32_import_lib_p "$dlprefile"; then
+	        func_tr_sh "$dlprefile"
+	        eval "curr_lafile=\$libfile_$func_tr_sh_result"
+	        dlprefile_dlbasename=""
+	        if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+	          # Use subshell, to avoid clobbering current variable values
+	          dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+	          if test -n "$dlprefile_dlname" ; then
+	            func_basename "$dlprefile_dlname"
+	            dlprefile_dlbasename="$func_basename_result"
+	          else
+	            # no lafile. user explicitly requested -dlpreopen <import library>.
+	            $sharedlib_from_linklib_cmd "$dlprefile"
+	            dlprefile_dlbasename=$sharedlib_from_linklib_result
+	          fi
+	        fi
+	        $opt_dry_run || {
+	          if test -n "$dlprefile_dlbasename" ; then
+	            eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+	          else
+	            func_warning "Could not compute DLL name from $name"
+	            eval '$ECHO ": $name " >> "$nlist"'
+	          fi
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+	            $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+	        }
+	      else # not an import lib
+	        $opt_dry_run || {
+	          eval '$ECHO ": $name " >> "$nlist"'
+	          func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	          eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	        }
+	      fi
+	    ;;
+	    *)
+	      $opt_dry_run || {
+	        eval '$ECHO ": $name " >> "$nlist"'
+	        func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+	        eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	      }
+	    ;;
+          esac
+	done
+
+	$opt_dry_run || {
+	  # Make sure we have at least an empty file.
+	  test -f "$nlist" || : > "$nlist"
+
+	  if test -n "$exclude_expsyms"; then
+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	    $MV "$nlist"T "$nlist"
+	  fi
+
+	  # Try sorting and uniquifying the output.
+	  if $GREP -v "^: " < "$nlist" |
+	      if sort -k 3 </dev/null >/dev/null 2>&1; then
+		sort -k 3
+	      else
+		sort +2
+	      fi |
+	      uniq > "$nlist"S; then
+	    :
+	  else
+	    $GREP -v "^: " < "$nlist" > "$nlist"S
+	  fi
+
+	  if test -f "$nlist"S; then
+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+	  else
+	    echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
+
+	  echo >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+extern LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+LT_DLSYM_CONST lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+  { \"$my_originator\", (void *) 0 },"
+
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  echo >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
+	  *)
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
+	    ;;
+	  esac
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) func_append symtab_cflags " $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
+	case $host in
+	*cygwin* | *mingw* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	  else
+	    compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
+	;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
+
+      # Nullify the symbol file.
+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
+    fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
+func_win32_libid ()
+{
+  $opt_debug
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
+	$SED -n -e '
+	    1,100{
+		/ I /{
+		    s,.*,import,
+		    p
+		    q
+		}
+	    }'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
+
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $opt_debug
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $opt_debug
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[	 ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1" ; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=""
+  fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    if test "$lock_old_archive_extraction" = yes; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+		   'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test "$lock_old_archive_extraction" = yes; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $opt_debug
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib="$func_basename_result"
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
+	esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir="$my_gentop/$my_xlib_u"
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`basename "$darwin_archive"`
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+	      cd "$darwin_curdir"
+	      $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+	    done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
+    done
+
+    func_extract_archives_result="$my_oldobjs"
+}
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=${1-no}
+
+	$ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    file=\"\$0\""
+
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=\"$qECHO\"
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+"
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
+
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  case \" \$* \" in
+  *\\ --lt-*)
+    for lt_wr_arg
+    do
+      case \$lt_wr_arg in
+      --lt-*) ;;
+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+      esac
+      shift
+    done ;;
+  esac
+  func_exec_program_core \${1+\"\$@\"}
+}
+
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
+  done
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
+
+	  $ECHO "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$ECHO \"\$relink_command_output\" >&2
+	$RM \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# fixup the dll searchpath if we need to.
+	#
+	# Fix the DLL searchpath if we need to.  Do this before prepending
+	# to shlibpath, because on Windows, both are PATH and uninstalled
+	# libraries must come first.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+      func_exec_program \${1+\"\$@\"}
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
+
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+*/
+EOF
+	    cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+/* path handling portability macros */
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
+#else
+static int lt_debug = 0;
+#endif
+
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
+EOF
+
+	    cat <<EOF
+volatile const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_path "$temp_rpath"
+	      cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test -n "$dllsearchpath"; then
+              func_to_host_path "$dllsearchpath:"
+	      cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test "$fast_install" = yes; then
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+	    else
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+	    fi
+
+
+	    cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
+
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  intptr_t rval = 127;
+
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  newargz = XMALLOC (char *, argc + 1);
+
+  /* very simple arg parsing; don't want to rely on getopt
+   * also, copy all non cwrapper options to newargz, except
+   * argz[0], which is handled differently
+   */
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], dumpscript_opt) == 0)
+	{
+EOF
+	    case "$host" in
+	      *mingw* | *cygwin* )
+		# make stdout use "unix" line endings
+		echo "          setmode(1,_O_BINARY);"
+		;;
+	      esac
+
+	    cat <<"EOF"
+	  lt_dump_script (stdout);
+	  return 0;
+	}
+      if (strcmp (argv[i], debug_opt) == 0)
+	{
+          lt_debug = 1;
+          continue;
+	}
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal (__FILE__, __LINE__,
+		    "unrecognized %s option: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
+
+EOF
+	    cat <<EOF
+  /* The GNU banner must be the first non-error debug message */
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+	    cat <<"EOF"
+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
+
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (before symlink chase) at: %s\n",
+		  tmp_pathspec);
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (after symlink chase) at: %s\n",
+		  actual_cwrapper_path);
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(main) libtool target name: %s\n",
+		  target_name);
+EOF
+
+	    cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
+
+	    cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
+
+	    case $host_os in
+	      mingw*)
+	    cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+	*p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+	*p = '/';
+      }
+  }
+EOF
+	    ;;
+	    esac
+
+	    cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+     because on Windows, both *_VARNAMEs are PATH but uninstalled
+     libraries must come first. */
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+
+  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+		  nonnull (lt_argv_zero));
+  for (i = 0; i < newargc; i++)
+    {
+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+		      i, nonnull (newargz[i]));
+    }
+
+EOF
+
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      lt_debugprintf (__FILE__, __LINE__,
+		      "(main) failed to launch target \"%s\": %s\n",
+		      lt_argv_zero, nonnull (strerror (errno)));
+      return 127;
+    }
+  return rval;
+EOF
+		;;
+	      *)
+		cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+		;;
+	    esac
+
+	    cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal (__FILE__, __LINE__, "memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+			  string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable (const char *path)
+{
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char *concat_name;
+
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+	return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+	{
+	  concat_name = xstrdup (wrapper);
+	  if (check_executable (concat_name))
+	    return concat_name;
+	  XFREE (concat_name);
+	}
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+    }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+	has_slash = 1;
+	break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+	{
+	  for (p = path; *p; p = p_next)
+	    {
+	      const char *q;
+	      size_t p_len;
+	      for (q = p; *q; q++)
+		if (IS_PATH_SEPARATOR (*q))
+		  break;
+	      p_len = q - p;
+	      p_next = (*q == '\0' ? q : q + 1);
+	      if (p_len == 0)
+		{
+		  /* empty path: current directory */
+		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+		    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
+		  tmp_len = strlen (tmp);
+		  concat_name =
+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, tmp, tmp_len);
+		  concat_name[tmp_len] = '/';
+		  strcpy (concat_name + tmp_len + 1, wrapper);
+		}
+	      else
+		{
+		  concat_name =
+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, p, p_len);
+		  concat_name[p_len] = '/';
+		  strcpy (concat_name + p_len + 1, wrapper);
+		}
+	      if (check_executable (concat_name))
+		return concat_name;
+	      XFREE (concat_name);
+	    }
+	}
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      lt_debugprintf (__FILE__, __LINE__,
+		      "checking path component for symlinks: %s\n",
+		      tmp_pathspec);
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
+
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  lt_fatal (__FILE__, __LINE__,
+		    "error accessing file \"%s\": %s",
+		    tmp_pathspec, nonnull (strerror (errno)));
+	}
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal (__FILE__, __LINE__,
+		"could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert (str != NULL);
+  assert (pat != NULL);
+
+  len = strlen (str);
+  patlen = strlen (pat);
+
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (strcmp (str, pat) == 0)
+	*str = '\0';
+    }
+  return str;
+}
+
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
+
+static void
+lt_error_core (int exit_status, const char *file,
+	       int line, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *file, int line, const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
+  va_end (ap);
+}
+
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    int len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[len-1] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  lt_debugprintf (__FILE__, __LINE__,
+		  "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+EOF
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+	new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+	{
+	  int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+	  size_t length;
+	  unsigned int backslashes;
+	  const char *s;
+	  char *quoted_string;
+	  char *p;
+
+	  length = 0;
+	  backslashes = 0;
+	  if (quote_around)
+	    length++;
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		length += backslashes + 1;
+	      length++;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    length += backslashes + 1;
+
+	  quoted_string = XMALLOC (char, length + 1);
+
+	  p = quoted_string;
+	  backslashes = 0;
+	  if (quote_around)
+	    *p++ = '"';
+	  for (s = string; *s != '\0'; s++)
+	    {
+	      char c = *s;
+	      if (c == '"')
+		{
+		  unsigned int j;
+		  for (j = backslashes + 1; j > 0; j--)
+		    *p++ = '\\';
+		}
+	      *p++ = c;
+	      if (c == '\\')
+		backslashes++;
+	      else
+		backslashes = 0;
+	    }
+	  if (quote_around)
+	    {
+	      unsigned int j;
+	      for (j = backslashes; j > 0; j--)
+		*p++ = '\\';
+	      *p++ = '"';
+	    }
+	  *p = '\0';
+
+	  new_argv[i] = quoted_string;
+	}
+      else
+	new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
+EOF
+		;;
+	    esac
+
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+	    func_emit_wrapper yes |
+	      $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/  fputs ("\1", f);/p
+g
+D'
+            cat <<"EOF"
+}
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+    $opt_debug
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
+}
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $opt_debug
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    bindir=
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    single_module="${wl}-single_module"
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	bindir)
+	  bindir="$arg"
+	  prev=
+	  continue
+	  ;;
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append finalize_command " @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      func_append dlfiles " $arg"
+	    else
+	      func_append dlprefiles " $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file \`$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) func_append deplibs " $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      func_append moreargs " $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		func_source "$arg"
+
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
+		fi
+
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir="$func_dirname_result"
+
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
+
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      func_append dlfiles " $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    func_append dlprefiles " $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  func_append libobjs " $pic_object"
+		  arg="$pic_object"
+		fi
+
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
+
+		  # A standard non-PIC object
+		  func_append non_pic_objects " $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir="$func_dirname_result"
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "\`$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file \`$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "only absolute run-paths are allowed"
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) func_append rpath " $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) func_append xrpath " $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  func_append weak_libs " $arg"
+	  prev=
+	  continue
+	  ;;
+	xcclinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  func_append compiler_flags " $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  func_append linker_flags " $qarg"
+	  func_append compiler_flags " $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -bindir)
+	prev=bindir
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework)
+	prev=framework
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname "-L" '' "$arg"
+	if test -z "$func_stripname_result"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between \`-L' and \`$1'"
+	  else
+	    func_fatal_error "need path for \`-L' option"
+	  fi
+	fi
+	func_resolve_sysroot "$func_stripname_result"
+	dir=$func_resolve_sysroot_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "* | *" $arg "*)
+	  # Will only happen for absolute or sysroot arguments
+	  ;;
+	*)
+	  # Preserve sysroot, but never include relative directories
+	  case $dir in
+	    [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+	    *) func_append deplibs " -L$dir" ;;
+	  esac
+	  func_append lib_search_path " $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) func_append dllsearchpath ":$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    func_append deplibs " System.ltframework"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	func_append deplibs " $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot|--sysroot)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	prev=xcompiler
+	continue
+	;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	func_append compiler_flags " $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	case "$new_inherited_linker_flags " in
+	    *" $arg "*) ;;
+	    * ) func_append new_inherited_linker_flags " $arg" ;;
+	esac
+	continue
+	;;
+
+      -multi_module)
+	single_module="${wl}-multi_module"
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	func_stripname '-R' '' "$arg"
+	dir=$func_stripname_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	=*)
+	  func_stripname '=' '' "$dir"
+	  dir=$lt_sysroot$func_stripname_result
+	  ;;
+	*)
+	  func_fatal_error "only absolute run-paths are allowed"
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) func_append xrpath " $dir" ;;
+	esac
+	continue
+	;;
+
+      -shared)
+	# The effects of -shared are defined in a previous loop.
+	continue
+	;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -static | -static-libtool-libs)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -weak)
+        prev=weak
+	continue
+	;;
+
+      -Wc,*)
+	func_stripname '-Wc,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $func_quote_for_eval_result"
+	  func_append compiler_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Wl,*)
+	func_stripname '-Wl,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  func_append arg " $wl$func_quote_for_eval_result"
+	  func_append compiler_flags " $wl$func_quote_for_eval_result"
+	  func_append linker_flags " $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # -msg_* for osf cc
+      -msg_*)
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      # Flags to be passed through unchanged, with rationale:
+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
+      # -r[0-9][0-9]*        specify processor for the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+      # +DA*, +DD*           enable 64-bit mode for the HP compiler
+      # -q*                  compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+      # -F/path              path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
+      # @file                GCC response files
+      # -tp=*                Portland pgcc target processor selection
+      # --sysroot=*          for sysroot support
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        func_append compiler_flags " $arg"
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      *.$objext)
+	# A standard object.
+	func_append objs " $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if func_lalib_unsafe_p "$arg"; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  func_source "$arg"
+
+	  if test -z "$pic_object" ||
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  func_dirname "$arg" "/" ""
+	  xdir="$func_dirname_result"
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		func_append dlfiles " $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      func_append dlprefiles " $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    func_append libobjs " $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    func_append non_pic_objects " $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if $opt_dry_run; then
+	    # Extract subdirectory from the argument.
+	    func_dirname "$arg" "/" ""
+	    xdir="$func_dirname_result"
+
+	    func_lo2o "$arg"
+	    pic_object=$xdir$objdir/$func_lo2o_result
+	    non_pic_object=$xdir$func_lo2o_result
+	    func_append libobjs " $pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  else
+	    func_fatal_error "\`$arg' is not a valid libtool object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	func_append deplibs " $arg"
+	func_append old_deplibs " $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	func_resolve_sysroot "$arg"
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  func_append dlfiles " $func_resolve_sysroot_result"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  func_append dlprefiles " $func_resolve_sysroot_result"
+	  prev=
+	else
+	  func_append deplibs " $func_resolve_sysroot_result"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prevarg' option requires an argument"
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    func_dirname "$output" "/" ""
+    output_objdir="$func_dirname_result$objdir"
+    func_to_tool_file "$output_objdir/"
+    tool_output_objdir=$func_to_tool_file_result
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if $opt_preserve_dup_deps ; then
+	case "$libs " in
+	*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	esac
+      fi
+      func_append libs " $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if $opt_duplicate_compiler_generated_deps; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
+	  esac
+	  func_append pre_post_deps " $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+	passes="conv dlpreopen link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+
+    for pass in $passes; do
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test "$linkmode,$pass" = "lib,link"; then
+	## FIXME: Find the place where the list is rebuilt in the wrong
+	##        order, and fix it there properly
+        tmp_deplibs=
+	for deplib in $deplibs; do
+	  tmp_deplibs="$deplib $tmp_deplibs"
+	done
+	deplibs="$tmp_deplibs"
+      fi
+
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link)
+	  libs="$deplibs %DEPLIBS%"
+	  test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+	  ;;
+	esac
+      fi
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
+	# Collect and forward deplibs of preopened libtool libs
+	for lib in $dlprefiles; do
+	  # Ignore non-libtool-libs
+	  dependency_libs=
+	  func_resolve_sysroot "$lib"
+	  case $lib in
+	  *.la)	func_source "$func_resolve_sysroot_result" ;;
+	  esac
+
+	  # Collect preopened libtool deplibs, except any this library
+	  # has declared as weak libs
+	  for deplib in $dependency_libs; do
+	    func_basename "$deplib"
+            deplib_base=$func_basename_result
+	    case " $weak_libs " in
+	    *" $deplib_base "*) ;;
+	    *) func_append deplibs " $deplib" ;;
+	    esac
+	  done
+	done
+	libs="$dlprefiles"
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    func_append compiler_flags " $deplib"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
+	    continue
+	  fi
+	  func_stripname '-l' '' "$deplib"
+	  name=$func_stripname_result
+	  if test "$linkmode" = lib; then
+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+	  else
+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+	  fi
+	  for searchdir in $searchdirs; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if func_lalib_p "$lib"; then
+		  library_names=
+		  old_library=
+		  func_source "$lib"
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    func_dirname "$lib" "" "."
+		    ladir="$func_dirname_result"
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+		;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	*.ltframework)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    deplibs="$deplib $deplibs"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) func_append new_inherited_linker_flags " $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    func_stripname '-L' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    func_append newlib_search_path " $func_resolve_sysroot_result"
+	    ;;
+	  *)
+	    func_warning "\`-L' is ignored for archives/objects"
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    func_stripname '-R' '' "$deplib"
+	    func_resolve_sysroot "$func_stripname_result"
+	    dir=$func_resolve_sysroot_result
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) func_append xrpath " $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la)
+	  func_resolve_sysroot "$deplib"
+	  lib=$func_resolve_sysroot_result
+	  ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    # Linking convenience modules into shared libraries is allowed,
+	    # but linking other static libraries is non-portable.
+	    case " $dlpreconveniencelibs " in
+	    *" $deplib "*) ;;
+	    *)
+	      valid_a_lib=no
+	      case $deplibs_check_method in
+		match_pattern*)
+		  set dummy $deplibs_check_method; shift
+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+		  if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		    valid_a_lib=yes
+		  fi
+		;;
+		pass_all)
+		  valid_a_lib=yes
+		;;
+	      esac
+	      if test "$valid_a_lib" != yes; then
+		echo
+		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because the file extensions .$libext of this argument makes me believe"
+		echo "*** that it is just a static archive that I should not use here."
+	      else
+		echo
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
+	      fi
+	      ;;
+	    esac
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      func_append newdlprefiles " $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      func_append newdlfiles " $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$lib" \
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+	func_dirname "$lib" "" "."
+	ladir="$func_dirname_result"
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	inherited_linker_flags=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	func_source "$lib"
+
+	# Convert "-framework foo" to "foo.ltframework"
+	if test -n "$inherited_linker_flags"; then
+	  tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+	    case " $new_inherited_linker_flags " in
+	      *" $tmp_inherited_linker_flag "*) ;;
+	      *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
+	    esac
+	  done
+	fi
+	dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && func_append dlfiles " $dlopen"
+	  test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      func_fatal_error "cannot find name of link library for \`$lib'"
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    func_append convenience " $ladir/$objdir/$old_library"
+	    func_append old_convenience " $ladir/$objdir/$old_library"
+	    tmp_libs=
+	    for deplib in $dependency_libs; do
+	      deplibs="$deplib $deplibs"
+	      if $opt_preserve_dup_deps ; then
+		case "$tmp_libs " in
+		*" $deplib "*) func_append specialdeplibs " $deplib" ;;
+		esac
+	      fi
+	      func_append tmp_libs " $deplib"
+	    done
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
+	  fi
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	if test -n "$old_library" &&
+	   { test "$prefer_static_libs" = yes ||
+	     test "$prefer_static_libs,$installed" = "built,no"; }; then
+	  linklib=$old_library
+	else
+	  for l in $old_library $library_names; do
+	    linklib="$l"
+	  done
+	fi
+	if test -z "$linklib"; then
+	  func_fatal_error "cannot find name of link library for \`$lib'"
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  fi
+	  if test -z "$dlname" ||
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    func_append dlprefiles " $lib $dependency_libs"
+	  else
+	    func_append newdlfiles " $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
+	    func_warning "passing it literally to the linker, although it might fail"
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	func_basename "$lib"
+	laname="$func_basename_result"
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$lt_sysroot$libdir"
+	    absdir="$lt_sysroot$libdir"
+	  fi
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    func_append notinst_path " $abs_ladir"
+	  fi
+	fi # $installed = yes
+	func_stripname 'lib' '.la' "$laname"
+	name=$func_stripname_result
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+	  fi
+	  case "$host" in
+	    # special handling for platforms with PE-DLLs.
+	    *cygwin* | *mingw* | *cegcc* )
+	      # Linker will automatically link against shared library if both
+	      # static and shared are present.  Therefore, ensure we extract
+	      # symbols from the import library if a shared library is present
+	      # (otherwise, the dlopen module name will be incorrect).  We do
+	      # this by putting the import library name into $newdlprefiles.
+	      # We recover the dlopen module name by 'saving' the la file
+	      # name in a special purpose variable, and (later) extracting the
+	      # dlname from the la file.
+	      if test -n "$dlname"; then
+	        func_tr_sh "$dir/$linklib"
+	        eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+	        func_append newdlprefiles " $dir/$linklib"
+	      else
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      fi
+	    ;;
+	    * )
+	      # Prefer using a static library (so that no silly _DYNAMIC symbols
+	      # are required to link).
+	      if test -n "$old_library"; then
+	        func_append newdlprefiles " $dir/$old_library"
+	        # Keep a list of preopened convenience libraries to check
+	        # that they are being used correctly in the link pass.
+	        test -z "$libdir" && \
+	          func_append dlpreconveniencelibs " $dir/$old_library"
+	      # Otherwise, use the dlname, so that lt_dlopen finds it.
+	      elif test -n "$dlname"; then
+	        func_append newdlprefiles " $dir/$dlname"
+	      else
+	        func_append newdlprefiles " $dir/$linklib"
+	      fi
+	    ;;
+	  esac
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  func_append newlib_search_path " $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) func_stripname '-L' '' "$deplib"
+	         func_resolve_sysroot "$func_stripname_result"
+	         func_append newlib_search_path " $func_resolve_sysroot_result"
+		 ;;
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { { test "$prefer_static_libs" = no ||
+	         test "$prefer_static_libs,$installed" = "built,yes"; } ||
+	       test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath:" in
+	      *"$absdir:"*) ;;
+	      *) func_append temp_rpath "$absdir:" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc*)
+	      # No point in relinking DLLs because paths are not encoded
+	      func_append notinst_deplibs " $lib"
+	      need_relink=no
+	    ;;
+	  *)
+	    if test "$installed" = no; then
+	      func_append notinst_deplibs " $lib"
+	      need_relink=yes
+	    fi
+	    ;;
+	  esac
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on some
+	  # systems (darwin).  Don't bleat about dlopened modules though!
+	  dlopenmodule=""
+	  for dlpremoduletest in $dlprefiles; do
+	    if test "X$dlpremoduletest" = "X$lib"; then
+	      dlopenmodule="$dlpremoduletest"
+	      break
+	    fi
+	  done
+	  if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+	    echo
+	    if test "$linkmode" = prog; then
+	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $ECHO "*** $linklib is not portable!"
+	  fi
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) func_append compile_rpath " $absdir" ;;
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append finalize_rpath " $libdir" ;;
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    shift
+	    realname="$1"
+	    shift
+	    libname=`eval "\\$ECHO \"$libname_spec\""`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw* | *cegcc*)
+	        func_arith $current - $age
+		major=$func_arith_result
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    func_basename "$soroot"
+	    soname="$func_basename_result"
+	    func_stripname 'lib' '.dll' "$soname"
+	    newlib=libimp-$func_stripname_result.a
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      func_verbose "extracting exported symbol list from \`$soname'"
+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      func_verbose "generating import library for \`$soname'"
+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$opt_mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a (non-dlopened) module then we can not
+		    # link against it, someone is ignoring the earlier warnings
+		    if /usr/bin/file -L $add 2> /dev/null |
+			 $GREP ": [^:]* bundle" >/dev/null ; then
+		      if test "X$dlopenmodule" != "X$lib"; then
+			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
+			if test -z "$old_library" ; then
+			  echo
+			  echo "*** And there doesn't seem to be a static archive available"
+			  echo "*** The link will probably fail, sorry"
+			else
+			  add="$dir/$old_library"
+			fi
+		      elif test -n "$old_library"; then
+			add="$dir/$old_library"
+		      fi
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$absdir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      func_append add_dir " -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      func_fatal_configuration "unsupported hardcode properties"
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) func_append compile_shlibpath "$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes &&
+		 test "$hardcode_minus_L" != yes &&
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) func_append finalize_shlibpath "$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$opt_mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) func_append finalize_shlibpath "$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+		add="$inst_prefix_dir$libdir/$linklib"
+	      else
+		add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    func_append add_dir " -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    echo
+	    $ECHO "*** Warning: This system can not link to static lib archive $lib."
+	    echo "*** I have the capability to make that library automatically link in when"
+	    echo "*** you link to this library.  But I can only do this if you have a"
+	    echo "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      echo "*** But as you try to build a module library, libtool will still create "
+	      echo "*** a static module, that should work as long as the dlopening application"
+	      echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		echo
+		echo "*** However, this would only work if libtool was able to extract symbol"
+		echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		echo "*** not find such a program.  So, this module is probably useless."
+		echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test "$linkmode" = lib; then
+	  if test -n "$dependency_libs" &&
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) func_stripname '-R' '' "$libdir"
+	           temp_xrpath=$func_stripname_result
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) func_append xrpath " $temp_xrpath";;
+		   esac;;
+	      *) func_append temp_deplibs " $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  func_append newlib_search_path " $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    case $deplib in
+              -L*) func_stripname '-L' '' "$deplib"
+                   func_resolve_sysroot "$func_stripname_result";;
+              *) func_resolve_sysroot "$deplib" ;;
+            esac
+	    if $opt_preserve_dup_deps ; then
+	      case "$tmp_libs " in
+	      *" $func_resolve_sysroot_result "*)
+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
+	      esac
+	    fi
+	    func_append tmp_libs " $func_resolve_sysroot_result"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      path=
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+	        func_resolve_sysroot "$deplib"
+	        deplib=$func_resolve_sysroot_result
+	        func_dirname "$deplib" "" "."
+		dir=$func_dirname_result
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if $GREP "^installed=no" $deplib > /dev/null; then
+		case $host in
+		*-*-darwin*)
+		  depdepl=
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+		      func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
+		      path=
+		    fi
+		  fi
+		  ;;
+		*)
+		  path="-L$absdir/$objdir"
+		  ;;
+		esac
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  test -z "$libdir" && \
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
+		  test "$absdir" != "$libdir" && \
+		    func_warning "\`$deplib' seems to be moved"
+
+		  path="-L$absdir"
+		fi
+		;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+	else
+	  compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	fi
+      fi
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) func_append lib_search_path " $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) func_append tmp_libs " $deplib" ;;
+	      esac
+	      ;;
+	    *) func_append tmp_libs " $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=""
+	  ;;
+	esac
+	if test -n "$i" ; then
+	  func_append tmp_libs " $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+    fi
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+	func_warning "\`-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      func_append objs "$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	func_stripname 'lib' '.la' "$outputname"
+	name=$func_stripname_result
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  func_stripname '' '.la' "$outputname"
+	  name=$func_stripname_result
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  func_stripname '' '.la' "$outputname"
+	  libname=$func_stripname_result
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+	else
+	  echo
+	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+	  $ECHO "*** objects $objs is not portable!"
+	  func_append libobjs " $objs"
+	fi
+      fi
+
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+      install_libdir="$1"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a `.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	test -n "$vinfo" && \
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+	test -n "$release" && \
+	  func_warning "\`-release' is ignored for convenience libraries"
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	shift
+	IFS="$save_ifs"
+
+	test -n "$7" && \
+	  func_fatal_help "too many parameters to \`-version-info'"
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major="$1"
+	  number_minor="$2"
+	  number_revision="$3"
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # which has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  # correct linux to gnu/linux during the next big refactor
+	  darwin|linux|osf|windows|none)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|qnx|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_minor"
+	    lt_irix_increment=no
+	    ;;
+	  *)
+	    func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$1"
+	  revision="$2"
+	  age="$3"
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  func_arith $current + 1
+	  minor_current=$func_arith_result
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	irix | nonstopux)
+	  if test "X$lt_irix_increment" = "Xno"; then
+	    func_arith $current - $age
+	  else
+	    func_arith $current - $age + 1
+	  fi
+	  major=$func_arith_result
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring="$verstring_prefix$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test "$loop" -ne 0; do
+	    func_arith $revision - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux) # correct to gnu/linux during the next big refactor
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test "$loop" -ne 0; do
+	    func_arith $current - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  func_append verstring ":${current}.0"
+	  ;;
+
+	qnx)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  func_arith $current - $age
+	  major=$func_arith_result
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  func_fatal_configuration "unknown library version type \`$version_type'"
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" "yes"
+      func_append libobjs " $symfileobj"
+      test "X$libobjs" = "X " && libobjs=
+
+      if test "$opt_mode" != relink; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$ECHO "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext | *.gcno)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
+		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+		 then
+		   continue
+		 fi
+	       fi
+	       func_append removelist " $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	test -n "$removelist" && \
+	  func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	func_append oldlibs " $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+      #	deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+      #	dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  func_replace_sysroot "$libdir"
+	  func_append temp_xrpath " -R$func_replace_sysroot_result"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) func_append dlfiles " $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) func_append dlprefiles " $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    func_append deplibs " System.ltframework"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      func_append deplibs " -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $opt_dry_run || $RM conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $opt_dry_run || $RM conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    func_append newdeplibs " $i"
+		    i=""
+		    ;;
+		  esac
+		fi
+		if test -n "$i" ; then
+		  libname=`eval "\\$ECHO \"$libname_spec\""`
+		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		  set dummy $deplib_matches; shift
+		  deplib_match=$1
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    func_append newdeplibs " $i"
+		  else
+		    droppeddeps=yes
+		    echo
+		    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		    echo "*** I have the capability to make that library automatically link in when"
+		    echo "*** you link to this library.  But I can only do this if you have a"
+		    echo "*** shared version of the library, which I believe you do not have"
+		    echo "*** because a test_compile did reveal that the linker did not use it for"
+		    echo "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		$opt_dry_run || $RM conftest
+		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+		  ldd_output=`ldd conftest`
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      func_append newdeplibs " $i"
+		      i=""
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i" ; then
+		    libname=`eval "\\$ECHO \"$libname_spec\""`
+		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		    set dummy $deplib_matches; shift
+		    deplib_match=$1
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      func_append newdeplibs " $i"
+		    else
+		      droppeddeps=yes
+		      echo
+		      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		      echo "*** I have the capability to make that library automatically link in when"
+		      echo "*** you link to this library.  But I can only do this if you have a"
+		      echo "*** shared version of the library, which you do not appear to have"
+		      echo "*** because a test_compile did reveal that the linker did not use this one"
+		      echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  echo
+		  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
+		  echo "*** make it link in!  You will probably need to install it or some"
+		  echo "*** library that it depends on before this library will be fully"
+		  echo "*** functional.  Installing it before continuing would be even better."
+		fi
+		;;
+	      *)
+		func_append newdeplibs " $i"
+		;;
+	      esac
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method; shift
+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		if test -n "$file_magic_glob"; then
+		  libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+		else
+		  libnameglob=$libname
+		fi
+		test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  if test "$want_nocaseglob" = yes; then
+		    shopt -s nocaseglob
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		    $nocaseglob
+		  else
+		    potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+		  fi
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null |
+			 $GREP " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+			 $SED -e 10q |
+			 $EGREP "$file_magic_regex" > /dev/null; then
+			func_append newdeplibs " $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method; shift
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  func_append newdeplibs " $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
+		    if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
+		       $EGREP "$match_pattern_regex" > /dev/null; then
+		      func_append newdeplibs " $a_deplib"
+		      a_deplib=""
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		echo
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		echo "*** I have the capability to make that library automatically link in when"
+		echo "*** you link to this library.  But I can only do this if you have a"
+		echo "*** shared version of the library, which you do not appear to have"
+		echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      func_append newdeplibs " $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
+	    done
+	  fi
+	  case $tmp_deplibs in
+	  *[!\	\ ]*)
+	    echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	    ;;
+	  esac
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library with the System framework
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
+	  ;;
+	esac
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    echo
+	    echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
+	    echo "*** a static module, that should work as long as the dlopening"
+	    echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      echo
+	      echo "*** However, this would only work if libtool was able to extract symbol"
+	      echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      echo "*** not find such a program.  So, this module is probably useless."
+	      echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    echo "*** The inter-library dependencies that have been dropped here will be"
+	    echo "*** automatically added whenever a program is linked with this library"
+	    echo "*** or is declared to -dlopen it."
+
+	    if test "$allow_undefined" = no; then
+	      echo
+	      echo "*** Since this library must not contain undefined symbols,"
+	      echo "*** because either the platform does not support them or"
+	      echo "*** it was explicitly requested with -no-undefined,"
+	      echo "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+	*-*-darwin*)
+	  newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  ;;
+      esac
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      deplibs="$new_libs"
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	# Remove ${wl} instances when linking with ld.
+	# FIXME: should test the right _cmds variable.
+	case $archive_cmds in
+	  *\$LD\ *) wl= ;;
+        esac
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		func_replace_sysroot "$libdir"
+		libdir=$func_replace_sysroot_result
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		func_append dep_rpath " $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) func_append perm_rpath " $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      func_append rpath "$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath="$finalize_shlibpath"
+	test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	shift
+	realname="$1"
+	shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib="$output_objdir/$realname"
+	linknames=
+	for link
+	do
+	  func_append linknames " $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	test "X$libobjs" = "X " && libobjs=
+
+	delfiles=
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+	  export_symbols="$output_objdir/$libname.uexp"
+	  func_append delfiles " $export_symbols"
+	fi
+
+	orig_export_symbols=
+	case $host_os in
+	cygwin* | mingw* | cegcc*)
+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+	    # exporting using user supplied symfile
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+	      # and it's NOT already a .def file. Must figure out
+	      # which of the given symbols are data symbols and tag
+	      # them as such. So, trigger use of export_symbols_cmds.
+	      # export_symbols gets reassigned inside the "prepare
+	      # the list of exported symbols" if statement, so the
+	      # include_expsyms logic still works.
+	      orig_export_symbols="$export_symbols"
+	      export_symbols=
+	      always_export_symbols=yes
+	    fi
+	  fi
+	  ;;
+	esac
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $opt_dry_run || $RM $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd1 in $cmds; do
+	      IFS="$save_ifs"
+	      # Take the normal branch if the nm_file_list_spec branch
+	      # doesn't work or if tool conversion is not needed.
+	      case $nm_file_list_spec~$to_tool_file_cmd in
+		*~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+		  try_normal_branch=yes
+		  eval cmd=\"$cmd1\"
+		  func_len " $cmd"
+		  len=$func_len_result
+		  ;;
+		*)
+		  try_normal_branch=no
+		  ;;
+	      esac
+	      if test "$try_normal_branch" = yes \
+		 && { test "$len" -lt "$max_cmd_len" \
+		      || test "$max_cmd_len" -le -1; }
+	      then
+		func_show_eval "$cmd" 'exit $?'
+		skipped_export=false
+	      elif test -n "$nm_file_list_spec"; then
+		func_basename "$output"
+		output_la=$func_basename_result
+		save_libobjs=$libobjs
+		save_output=$output
+		output=${output_objdir}/${output_la}.nm
+		func_to_tool_file "$output"
+		libobjs=$nm_file_list_spec$func_to_tool_file_result
+		func_append delfiles " $output"
+		func_verbose "creating $NM input file list: $output"
+		for obj in $save_libobjs; do
+		  func_to_tool_file "$obj"
+		  $ECHO "$func_to_tool_file_result"
+		done > "$output"
+		eval cmd=\"$cmd1\"
+		func_show_eval "$cmd" 'exit $?'
+		output=$save_output
+		libobjs=$save_libobjs
+		skipped_export=false
+	      else
+		# The command line is too long to execute in one step.
+		func_verbose "using reloadable object file for export list..."
+		skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	  $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	fi
+
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+	  # The given exports_symbols file has to be filtered, so filter it.
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	  # 's' commands which not all seds can handle. GNU sed should be fine
+	  # though. Also, the filter scales superlinearly with the number of
+	  # global variables. join(1) would be nice here, but unfortunately
+	  # isn't a blessed tool.
+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	  func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	  export_symbols=$output_objdir/$libname.def
+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+	  case " $convenience " in
+	  *" $test_deplib "*) ;;
+	  *)
+	    func_append tmp_deplibs " $test_deplib"
+	    ;;
+	  esac
+	done
+	deplibs="$tmp_deplibs"
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec" &&
+	    test "$compiler_needs_object" = yes &&
+	    test -z "$libobjs"; then
+	    # extract the archives, so we have objects to list.
+	    # TODO: could optimize this to just extract one archive.
+	    whole_archive_flag_spec=
+	  fi
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    func_append generated " $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    func_append libobjs " $func_extract_archives_result"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  func_append linker_flags " $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$opt_mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test "$module" = yes && test -n "$module_cmds" ; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
+	else
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    eval test_cmds=\"$archive_expsym_cmds\"
+	    cmds=$archive_expsym_cmds
+	  else
+	    eval test_cmds=\"$archive_cmds\"
+	    cmds=$archive_cmds
+	  fi
+	fi
+
+	if test "X$skipped_export" != "X:" &&
+	   func_len " $test_cmds" &&
+	   len=$func_len_result &&
+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise
+	  # or, if using GNU ld and skipped_export is not :, use a linker
+	  # script.
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  func_basename "$output"
+	  output_la=$func_basename_result
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  last_robj=
+	  k=1
+
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    echo 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    echo ')' >> $output
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$func_to_tool_file_result
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
+	    func_verbose "creating linker input file list: $output"
+	    : > $output
+	    set x $save_libobjs
+	    shift
+	    firstobj=
+	    if test "$compiler_needs_object" = yes; then
+	      firstobj="$1 "
+	      shift
+	    fi
+	    for obj
+	    do
+	      func_to_tool_file "$obj"
+	      $ECHO "$func_to_tool_file_result" >> $output
+	    done
+	    func_append delfiles " $output"
+	    func_to_tool_file "$output"
+	    output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
+	  else
+	    if test -n "$save_libobjs"; then
+	      func_verbose "creating reloadable object files..."
+	      output=$output_objdir/$output_la-${k}.$objext
+	      eval test_cmds=\"$reload_cmds\"
+	      func_len " $test_cmds"
+	      len0=$func_len_result
+	      len=$len0
+
+	      # Loop over the list of objects to be linked.
+	      for obj in $save_libobjs
+	      do
+		func_len " $obj"
+		func_arith $len + $func_len_result
+		len=$func_arith_result
+		if test "X$objlist" = X ||
+		   test "$len" -lt "$max_cmd_len"; then
+		  func_append objlist " $obj"
+		else
+		  # The command $test_cmds is almost too long, add a
+		  # command to the queue.
+		  if test "$k" -eq 1 ; then
+		    # The first file doesn't have a previous command to add.
+		    reload_objs=$objlist
+		    eval concat_cmds=\"$reload_cmds\"
+		  else
+		    # All subsequent reloadable object files will link in
+		    # the last one created.
+		    reload_objs="$objlist $last_robj"
+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
+		  fi
+		  last_robj=$output_objdir/$output_la-${k}.$objext
+		  func_arith $k + 1
+		  k=$func_arith_result
+		  output=$output_objdir/$output_la-${k}.$objext
+		  objlist=" $obj"
+		  func_len " $last_robj"
+		  func_arith $len0 + $func_len_result
+		  len=$func_arith_result
+		fi
+	      done
+	      # Handle the remaining objects by creating one last
+	      # reloadable object file.  All subsequent reloadable object
+	      # files will link in the last one created.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      reload_objs="$objlist $last_robj"
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
+	      if test -n "$last_robj"; then
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+	      fi
+	      func_append delfiles " $output"
+
+	    else
+	      output=
+	    fi
+
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
+	      $opt_dry_run || $RM $export_symbols
+	      libobjs=$output
+	      # Append the command to create the export file.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+	      if test -n "$last_robj"; then
+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	    fi
+
+	    test -n "$save_libobjs" &&
+	      func_verbose "creating a temporary reloadable object file: $output"
+
+	    # Loop through the commands generated above and execute them.
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $concat_cmds; do
+	      IFS="$save_ifs"
+	      $opt_silent || {
+		  func_quote_for_expand "$cmd"
+		  eval "func_echo $func_quote_for_expand_result"
+	      }
+	      $opt_dry_run || eval "$cmd" || {
+		lt_exit=$?
+
+		# Restore the uninstalled library and exit
+		if test "$opt_mode" = relink; then
+		  ( cd "$output_objdir" && \
+		    $RM "${realname}T" && \
+		    $MV "${realname}U" "$realname" )
+		fi
+
+		exit $lt_exit
+	      }
+	    done
+	    IFS="$save_ifs"
+
+	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+
+          if ${skipped_export-false}; then
+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	      $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
+	    fi
+
+	    if test -n "$orig_export_symbols"; then
+	      # The given exports_symbols file has to be filtered, so filter it.
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	      # 's' commands which not all seds can handle. GNU sed should be fine
+	      # though. Also, the filter scales superlinearly with the number of
+	      # global variables. join(1) would be nice here, but unfortunately
+	      # isn't a blessed tool.
+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	      func_append delfiles " $export_symbols $output_objdir/$libname.filter"
+	      export_symbols=$output_objdir/$libname.def
+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	    fi
+	  fi
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test "$module" = yes && test -n "$module_cmds" ; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
+	  else
+	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	      cmds=$archive_expsym_cmds
+	    else
+	      cmds=$archive_cmds
+	    fi
+	  fi
+	fi
+
+	if test -n "$delfiles"; then
+	  # Append the command to remove temporary files to $cmds.
+	  eval cmds=\"\$cmds~\$RM $delfiles\"
+	fi
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append libobjs " $func_extract_archives_result"
+	  test "X$libobjs" = "X " && libobjs=
+	fi
+
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $opt_silent || {
+	    func_quote_for_expand "$cmd"
+	    eval "func_echo $func_quote_for_expand_result"
+	  }
+	  $opt_dry_run || eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test "$opt_mode" = relink; then
+	      ( cd "$output_objdir" && \
+	        $RM "${realname}T" && \
+		$MV "${realname}U" "$realname" )
+	    fi
+
+	    exit $lt_exit
+	  }
+	done
+	IFS="$save_ifs"
+
+	# Restore the uninstalled library and exit
+	if test "$opt_mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      func_show_eval '${RM}r "$gentop"'
+	    fi
+	  fi
+
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for objects"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for objects"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for objects"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+	test -n "$objs$old_deplibs" && \
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+	libobj=$output
+	func_lo2o "$libobj"
+	obj=$func_lo2o_result
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $opt_dry_run || $RM $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+	  reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
+	else
+	  gentop="$output_objdir/${obj}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # If we're not building shared, we need to use non_pic_objs
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+	func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) func_stripname '' '.exe' "$output"
+	          output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for programs"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for programs"
+
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
+	;;
+      esac
+
+      case $host in
+      *-*-darwin*)
+	# Don't allow lazy linking, it breaks C++ global constructors
+	# But is supposedly fixed on 10.4 or later (yay!).
+	if test "$tagname" = CXX ; then
+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+	    10.[0123])
+	      func_append compile_command " ${wl}-bind_at_load"
+	      func_append finalize_command " ${wl}-bind_at_load"
+	    ;;
+	  esac
+	fi
+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
+	compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+	;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    func_append new_libs " -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) func_append new_libs " $deplib" ;;
+	  esac
+	  ;;
+	*) func_append new_libs " $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_rpath " $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append perm_rpath " $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  ::) dllsearchpath=$libdir;;
+	  *) func_append dllsearchpath ":$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) func_append dllsearchpath ":$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    func_append rpath " $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) func_append finalize_perm_rpath " $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+	finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+      fi
+
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+	func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
+
+      wrappers_required=yes
+      case $host in
+      *cegcc* | *mingw32ce*)
+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
+        wrappers_required=no
+        ;;
+      *cygwin* | *mingw* )
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      *)
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      esac
+      if test "$wrappers_required" = no; then
+	# Replace the output file specification.
+	compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	exit_status=0
+	func_show_eval "$link_command" 'exit_status=$?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	# Delete the generated files.
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+	fi
+
+	exit $exit_status
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    func_append rpath "$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$opt_dry_run || $RM $output
+	# Link the executable and exit
+	func_show_eval "$link_command" 'exit $?'
+
+	if test -n "$postlink_cmds"; then
+	  func_to_tool_file "$output"
+	  postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	  func_execute_cmds "$postlink_cmds" 'exit $?'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      func_show_eval "$link_command" 'exit $?'
+
+      if test -n "$postlink_cmds"; then
+	func_to_tool_file "$output_objdir/$outputname"
+	postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+	func_execute_cmds "$postlink_cmds" 'exit $?'
+      fi
+
+      # Now create the wrapper script.
+      func_verbose "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    func_quote_for_eval "$var_value"
+	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) func_stripname '' '.exe' "$output"
+	         output=$func_stripname_result ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    func_stripname '' '.exe' "$outputname"
+	    outputname=$func_stripname_result ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    func_dirname_and_basename "$output" "" "."
+	    output_name=$func_basename_result
+	    output_path=$func_dirname_result
+	    cwrappersource="$output_path/$objdir/lt-$output_name.c"
+	    cwrapper="$output_path/$output_name.exe"
+	    $RM $cwrappersource $cwrapper
+	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_cwrapperexe_src > $cwrappersource
+
+	    # The wrapper executable is built using the $host compiler,
+	    # because it contains $host paths and files. If cross-
+	    # compiling, it, like the target executable, must be
+	    # executed on the $host or under an emulation environment.
+	    $opt_dry_run || {
+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+	      $STRIP $cwrapper
+	    }
+
+	    # Now, create the wrapper script for func_source use:
+	    func_ltwrapper_scriptname $cwrapper
+	    $RM $func_ltwrapper_scriptname_result
+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+	    $opt_dry_run || {
+	      # note: this script will not be executed, so do not chmod.
+	      if test "x$build" = "x$host" ; then
+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+	      else
+		func_emit_wrapper no > $func_ltwrapper_scriptname_result
+	      fi
+	    }
+	  ;;
+	  * )
+	    $RM $output
+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_wrapper no > $output
+	    chmod +x $output
+	  ;;
+	esac
+      }
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save $symfileobj"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$old_deplibs $non_pic_objects"
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    func_append oldobjs " $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	func_append generated " $gentop"
+
+	func_extract_archives $gentop $addlibs
+	func_append oldobjs " $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	cmds=$old_archive_from_new_cmds
+      else
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  func_append oldobjs " $func_extract_archives_result"
+	fi
+
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      func_basename "$obj"
+	      $ECHO "$func_basename_result"
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  echo "copying selected object files to avoid basename conflicts..."
+	  gentop="$output_objdir/${outputname}x"
+	  func_append generated " $gentop"
+	  func_mkdir_p "$gentop"
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    func_basename "$obj"
+	    objbase="$func_basename_result"
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		func_arith $counter + 1
+		counter=$func_arith_result
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      func_append oldobjs " $gentop/$newobj"
+	      ;;
+	    *) func_append oldobjs " $obj" ;;
+	    esac
+	  done
+	fi
+	func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+	tool_oldlib=$func_to_tool_file_result
+	eval cmds=\"$old_archive_cmds\"
+
+	func_len " $cmds"
+	len=$func_len_result
+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	elif test -n "$archiver_list_spec"; then
+	  func_verbose "using command file archive linking..."
+	  for obj in $oldobjs
+	  do
+	    func_to_tool_file "$obj"
+	    $ECHO "$func_to_tool_file_result"
+	  done > $output_objdir/$libname.libcmd
+	  func_to_tool_file "$output_objdir/$libname.libcmd"
+	  oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  func_verbose "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  eval test_cmds=\"$old_archive_cmds\"
+	  func_len " $test_cmds"
+	  len0=$func_len_result
+	  len=$len0
+	  for obj in $save_oldobjs
+	  do
+	    func_len " $obj"
+	    func_arith $len + $func_len_result
+	    len=$func_arith_result
+	    func_append objlist " $obj"
+	    if test "$len" -lt "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj" ; then
+		RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+	      objlist=
+	      len=$len0
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test "X$oldobjs" = "X" ; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      func_execute_cmds "$cmds" 'exit $?'
+    done
+
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      func_verbose "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  func_quote_for_eval "$var_value"
+	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+	relink_command=
+      fi
+
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		func_basename "$deplib"
+		name="$func_basename_result"
+		func_resolve_sysroot "$deplib"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
+		func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      -L*)
+		func_stripname -L '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -L$func_replace_sysroot_result"
+		;;
+	      -R*)
+		func_stripname -R '' "$deplib"
+		func_replace_sysroot "$func_stripname_result"
+		func_append newdependency_libs " -R$func_replace_sysroot_result"
+		;;
+	      *) func_append newdependency_libs " $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+
+	    for lib in $dlfiles; do
+	      case $lib in
+	      *.la)
+	        func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      *) func_append newdlfiles " $lib" ;;
+	      esac
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+	      *.la)
+		# Only pass preopened files to the pseudo-archive (for
+		# eventual linking with the app. that links it) if we
+		# didn't already link the preopened objects directly into
+		# the library:
+		func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
+		;;
+	      esac
+	    done
+	    dlprefiles="$newdlprefiles"
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlfiles " $abs"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      func_append newdlprefiles " $abs"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $RM $output
+	  # place dlname in correct position for cygwin
+	  # In fact, it would be nice if we could use this code for all target
+	  # systems that can't hard-code library paths into their executables
+	  # and that have no shared library path variable independent of PATH,
+	  # but it turns out we can't easily determine that from inspecting
+	  # libtool variables, so we have to hard-code the OSs to which it
+	  # applies here; at the moment, that means platforms that use the PE
+	  # object format with DLL files.  See the long comment at the top of
+	  # tests/bindir.at for full details.
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+	      # If a -bindir argument was supplied, place the dll there.
+	      if test "x$bindir" != x ;
+	      then
+		func_relative_path "$install_libdir" "$bindir"
+		tdlname=$func_relative_path_result$dlname
+	      else
+		# Otherwise fall back on heuristic.
+		tdlname=../bin/$dlname
+	      fi
+	      ;;
+	  esac
+	  $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test "$need_relink" = yes; then
+	    $ECHO >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      }
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
+
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
+    func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $opt_debug
+    RM="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) func_append RM " $arg"; rmforce=yes ;;
+      -*) func_append RM " $arg" ;;
+      *) func_append files " $arg" ;;
+      esac
+    done
+
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
+
+    rmdirs=
+
+    for file in $files; do
+      func_dirname "$file" "" "."
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	odir="$objdir"
+      else
+	odir="$dir/$objdir"
+      fi
+      func_basename "$file"
+      name="$func_basename_result"
+      test "$opt_mode" = uninstall && odir="$dir"
+
+      # Remember odir for removal later, being careful to avoid duplicates
+      if test "$opt_mode" = clean; then
+	case " $rmdirs " in
+	  *" $odir "*) ;;
+	  *) func_append rmdirs " $odir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if { test -L "$file"; } >/dev/null 2>&1 ||
+	 { test -h "$file"; } >/dev/null 2>&1 ||
+	 test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif test "$rmforce" = yes; then
+	continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if func_lalib_p "$file"; then
+	  func_source $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    func_append rmfiles " $odir/$n"
+	  done
+	  test -n "$old_library" && func_append rmfiles " $odir/$old_library"
+
+	  case "$opt_mode" in
+	  clean)
+	    case " $library_names " in
+	    *" $dlname "*) ;;
+	    *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
+	    esac
+	    test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if func_lalib_p "$file"; then
+
+	  # Read the .lo file
+	  func_source $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
+	    func_append rmfiles " $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" &&
+	     test "$non_pic_object" != none; then
+	    func_append rmfiles " $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test "$opt_mode" = clean ; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    func_stripname '' '.exe' "$file"
+	    file=$func_stripname_result
+	    func_stripname '' '.exe' "$name"
+	    noexename=$func_stripname_result
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    func_append rmfiles " $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if func_ltwrapper_p "$file"; then
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      relink_command=
+	      func_source $func_ltwrapper_scriptname_result
+	      func_append rmfiles " $func_ltwrapper_scriptname_result"
+	    else
+	      relink_command=
+	      func_source $dir/$noexename
+	    fi
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
+	      func_append rmfiles " $odir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name" ; then
+	      func_append rmfiles " $odir/lt-${noexename}.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
+    done
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	func_show_eval "rmdir $dir >/dev/null 2>&1"
+      fi
+    done
+
+    exit $exit_status
+}
+
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
+
+test -z "$opt_mode" && {
+  help="$generic_help"
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode \`$opt_mode'"
+
+if test -n "$exec_cmd"; then
+  eval exec "$exec_cmd"
+  exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/protobuf/m4/ac_system_extensions.m4 b/protobuf/m4/ac_system_extensions.m4
new file mode 100644
index 0000000..1ca2eeb
--- /dev/null
+++ b/protobuf/m4/ac_system_extensions.m4
@@ -0,0 +1,37 @@
+dnl Provide AC_USE_SYSTEM_EXTENSIONS for old autoconf machines.
+AC_DEFUN([ACX_USE_SYSTEM_EXTENSIONS],[
+  ifdef([AC_USE_SYSTEM_EXTENSIONS],[
+    AC_USE_SYSTEM_EXTENSIONS
+  ],[
+    AC_BEFORE([$0], [AC_COMPILE_IFELSE])
+    AC_BEFORE([$0], [AC_RUN_IFELSE])
+
+    AC_REQUIRE([AC_GNU_SOURCE])
+    AC_REQUIRE([AC_AIX])
+    AC_REQUIRE([AC_MINIX])
+
+    AH_VERBATIM([__EXTENSIONS__],
+[/* Enable extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif])
+    AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__],
+      [ac_cv_safe_to_define___extensions__],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([
+#           define __EXTENSIONS__ 1
+            AC_INCLUDES_DEFAULT])],
+         [ac_cv_safe_to_define___extensions__=yes],
+         [ac_cv_safe_to_define___extensions__=no])])
+    test $ac_cv_safe_to_define___extensions__ = yes &&
+      AC_DEFINE([__EXTENSIONS__])
+    AC_DEFINE([_POSIX_PTHREAD_SEMANTICS])
+    AC_DEFINE([_TANDEM_SOURCE])
+  ])
+])
diff --git a/protobuf/m4/acx_check_suncc.m4 b/protobuf/m4/acx_check_suncc.m4
new file mode 100644
index 0000000..8918593
--- /dev/null
+++ b/protobuf/m4/acx_check_suncc.m4
@@ -0,0 +1,75 @@
+dnl Check for the presence of the Sun Studio compiler.
+dnl If Sun Studio compiler is found, set appropriate flags.
+dnl Additionally, Sun Studio doesn't default to 64-bit by itself,
+dnl nor does it automatically look in standard Solaris places for
+dnl 64-bit libs, so we must add those options and paths to the search
+dnl paths.
+
+dnl TODO(kenton):  This is pretty hacky.  It sets CXXFLAGS, which the autoconf
+dnl docs say should never be overridden except by the user.  It also isn't
+dnl cross-compile safe.  We should fix these problems, but since I don't have
+dnl Sun CC at my disposal for testing, someone else will have to do it.
+
+AC_DEFUN([ACX_CHECK_SUNCC],[
+
+  AC_LANG_PUSH([C++])
+  AC_CHECK_DECL([__SUNPRO_CC], [SUNCC="yes"], [SUNCC="no"])
+  AC_LANG_POP()
+
+
+  AC_ARG_ENABLE([64bit-solaris],
+    [AS_HELP_STRING([--disable-64bit-solaris],
+      [Build 64 bit binary on Solaris @<:@default=on@:>@])],
+             [ac_enable_64bit="$enableval"],
+             [ac_enable_64bit="yes"])
+
+  AS_IF([test "$SUNCC" = "yes" -a "x${ac_cv_env_CXXFLAGS_set}" = "x"],[
+    dnl Sun Studio has a crashing bug with -xO4 in some cases. Keep this
+    dnl at -xO3 until a proper test to detect those crashes can be done.
+    CXXFLAGS="-g0 -xO3 -xlibmil -xdepend -xbuiltin -mt -compat=5 -library=stlport4 -library=Crun -template=no%extdef ${CXXFLAGS}"
+  ])
+
+  case $host_os in
+    *solaris*)
+      AC_CHECK_PROGS(ISAINFO, [isainfo], [no])
+      AS_IF([test "x$ISAINFO" != "xno"],
+            [isainfo_b=`${ISAINFO} -b`],
+            [isainfo_b="x"])
+
+      AS_IF([test "$isainfo_b" != "x"],[
+
+        isainfo_k=`${ISAINFO} -k`
+
+        AS_IF([test "x$ac_enable_64bit" = "xyes"],[
+
+          AC_DEFINE([SOLARIS_64BIT_ENABLED], [1], [64bit enabled])
+          AS_IF([test "x$libdir" = "x\${exec_prefix}/lib"],[
+           dnl The user hasn't overridden the default libdir, so we'll
+           dnl the dir suffix to match solaris 32/64-bit policy
+           libdir="${libdir}/${isainfo_k}"
+          ])
+
+          dnl This should just be set in CPPFLAGS and in LDFLAGS, but libtool
+          dnl does the wrong thing if you don't put it into CXXFLAGS. sigh.
+          dnl (It also needs it in CFLAGS, or it does a different wrong thing!)
+          AS_IF([test "x${ac_cv_env_CXXFLAGS_set}" = "x"],[
+            CXXFLAGS="${CXXFLAGS} -m64"
+            ac_cv_env_CXXFLAGS_set=set
+            ac_cv_env_CXXFLAGS_value='-m64'
+          ])
+
+          AS_IF([test "x${ac_cv_env_CFLAGS_set}" = "x"],[
+            CFLAGS="${CFLAGS} -m64"
+            ac_cv_env_CFLAGS_set=set
+            ac_cv_env_CFLAGS_value='-m64'
+          ])
+
+          AS_IF([test "$target_cpu" = "sparc" -a "x$SUNCC" = "xyes" ],[
+            CXXFLAGS="-xmemalign=8s ${CXXFLAGS}"
+          ])
+        ])
+      ])
+    ;;
+  esac
+
+])
diff --git a/protobuf/m4/acx_pthread.m4 b/protobuf/m4/acx_pthread.m4
new file mode 100644
index 0000000..89d42c7
--- /dev/null
+++ b/protobuf/m4/acx_pthread.m4
@@ -0,0 +1,397 @@
+# This was retrieved from
+#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
+# See also (perhaps for new versions?)
+#    http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
+#
+# We've rewritten the inconsistency check code (from avahi), to work
+# more broadly.  In particular, it no longer assumes ld accepts -zdefs.
+# This caused a restructing of the code, but the functionality has only
+# changed a little.
+
+dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+dnl
+dnl @summary figure out how to build C programs using POSIX threads
+dnl
+dnl This macro figures out how to build C programs using POSIX threads.
+dnl It sets the PTHREAD_LIBS output variable to the threads library and
+dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
+dnl C compiler flags that are needed. (The user can also force certain
+dnl compiler flags/libs to be tested by setting these environment
+dnl variables.)
+dnl
+dnl Also sets PTHREAD_CC to any special C compiler that is needed for
+dnl multi-threaded programs (defaults to the value of CC otherwise).
+dnl (This is necessary on AIX to use the special cc_r compiler alias.)
+dnl
+dnl NOTE: You are assumed to not only compile your program with these
+dnl flags, but also link it with them as well. e.g. you should link
+dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
+dnl $LIBS
+dnl
+dnl If you are only building threads programs, you may wish to use
+dnl these variables in your default LIBS, CFLAGS, and CC:
+dnl
+dnl        LIBS="$PTHREAD_LIBS $LIBS"
+dnl        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+dnl        CC="$PTHREAD_CC"
+dnl
+dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
+dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
+dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+dnl
+dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
+dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
+dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
+dnl default action will define HAVE_PTHREAD.
+dnl
+dnl Please let the authors know if this macro fails on any platform, or
+dnl if you have any other suggestions or comments. This macro was based
+dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
+dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
+dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
+dnl We are also grateful for the helpful feedback of numerous users.
+dnl
+dnl @category InstalledPackages
+dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
+dnl @version 2006-05-29
+dnl @license GPLWithACException
+dnl 
+dnl Checks for GCC shared/pthread inconsistency based on work by
+dnl Marcin Owsiany <marcin@owsiany.pl>
+
+
+AC_DEFUN([ACX_PTHREAD], [
+AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_SAVE
+AC_LANG_C
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
+        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+fi
+
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
+
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
+
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
+
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+#      ... -mt is also the pthreads flag for HP/aCC
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
+
+case "${host_cpu}-${host_os}" in
+        *solaris*)
+
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
+
+        acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+        ;;
+esac
+
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
+
+        case $flag in
+                none)
+                AC_MSG_CHECKING([whether pthreads work without any flags])
+                ;;
+
+                -*)
+                AC_MSG_CHECKING([whether pthreads work with $flag])
+                PTHREAD_CFLAGS="$flag"
+                ;;
+
+		pthread-config)
+		AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
+		if test x"$acx_pthread_config" = xno; then continue; fi
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
+
+                *)
+                AC_MSG_CHECKING([for the pthreads library -l$flag])
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        AC_TRY_LINK([#include <pthread.h>],
+                    [pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+                    [acx_pthread_ok=yes])
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        AC_MSG_RESULT($acx_pthread_ok)
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
+
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
+
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	AC_MSG_CHECKING([for joinable pthread attribute])
+	attr_name=unknown
+	for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+	    AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
+                        [attr_name=$attr; break])
+	done
+        AC_MSG_RESULT($attr_name)
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+                               [Define to necessary symbol if this constant
+                                uses a non-standard name on your system.])
+        fi
+
+        AC_MSG_CHECKING([if more special flags are required for pthreads])
+        flag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
+        esac
+        AC_MSG_RESULT(${flag})
+        if test "x$flag" != xno; then
+            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+        # More AIX lossage: must compile with xlc_r or cc_r
+	if test x"$GCC" != xyes; then
+          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
+        else
+          PTHREAD_CC=$CC
+	fi
+
+	# The next part tries to detect GCC inconsistency with -shared on some
+	# architectures and systems. The problem is that in certain
+	# configurations, when -shared is specified, GCC "forgets" to
+	# internally use various flags which are still necessary.
+	
+	#
+	# Prepare the flags
+	#
+	save_CFLAGS="$CFLAGS"
+	save_LIBS="$LIBS"
+	save_CC="$CC"
+	
+	# Try with the flags determined by the earlier checks.
+	#
+	# -Wl,-z,defs forces link-time symbol resolution, so that the
+	# linking checks with -shared actually have any value
+	#
+	# FIXME: -fPIC is required for -shared on many architectures,
+	# so we specify it here, but the right way would probably be to
+	# properly detect whether it is actually required.
+	CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+	CC="$PTHREAD_CC"
+	
+	# In order not to create several levels of indentation, we test
+	# the value of "$done" until we find the cure or run out of ideas.
+	done="no"
+	
+	# First, make sure the CFLAGS we added are actually accepted by our
+	# compiler.  If not (and OS X's ld, for instance, does not accept -z),
+	# then we can't do this test.
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
+	   AC_TRY_LINK(,, , [done=yes])
+	
+	   if test "x$done" = xyes ; then
+	      AC_MSG_RESULT([no])
+	   else
+	      AC_MSG_RESULT([yes])
+	   fi
+	fi
+	
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes])
+	   
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	
+	#
+	# Linux gcc on some architectures such as mips/mipsel forgets
+	# about -lpthread
+	#
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lpthread fixes that])
+	   LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	      pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	      pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes])
+	
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	#
+	# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
+	#
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lc_r fixes that])
+	   LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	       [pthread_t th; pthread_join(th, 0);
+	        pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	        pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	       [done=yes])
+	
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
+	   else
+	      AC_MSG_RESULT([no])
+	   fi
+	fi
+	if test x"$done" = xno; then
+	   # OK, we have run out of ideas
+	   AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
+	
+	   # so it's not safe to assume that we may use pthreads
+	   acx_pthread_ok=no
+	fi
+	
+	AC_MSG_CHECKING([whether what we have so far is sufficient with -nostdlib])
+	CFLAGS="-nostdlib $CFLAGS"
+	# we need c with nostdlib
+	LIBS="$LIBS -lc"
+	AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	       pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	       pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes],[done=no])
+
+	if test "x$done" = xyes; then
+	   AC_MSG_RESULT([yes])
+	else
+	   AC_MSG_RESULT([no])
+	fi
+	
+	if test x"$done" = xno; then
+	   AC_MSG_CHECKING([whether -lpthread saves the day])
+	   LIBS="-lpthread $LIBS"
+	   AC_TRY_LINK([#include <pthread.h>],
+	      [pthread_t th; pthread_join(th, 0);
+	       pthread_attr_init(0); pthread_cleanup_push(0, 0);
+	       pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
+	      [done=yes],[done=no])
+
+	   if test "x$done" = xyes; then
+	      AC_MSG_RESULT([yes])
+	      PTHREAD_LIBS="$PTHREAD_LIBS -lpthread"
+	   else
+	      AC_MSG_RESULT([no])
+	      AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries and -nostdlib])
+	   fi
+	fi
+
+	CFLAGS="$save_CFLAGS"
+	LIBS="$save_LIBS"
+	CC="$save_CC"
+else
+        PTHREAD_CC="$CC"
+fi
+
+AC_SUBST(PTHREAD_LIBS)
+AC_SUBST(PTHREAD_CFLAGS)
+AC_SUBST(PTHREAD_CC)
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
+        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        :
+else
+        acx_pthread_ok=no
+        $2
+fi
+AC_LANG_RESTORE
+])dnl ACX_PTHREAD
diff --git a/protobuf/m4/libtool.m4 b/protobuf/m4/libtool.m4
new file mode 100644
index 0000000..d7c043f
--- /dev/null
+++ b/protobuf/m4/libtool.m4
@@ -0,0 +1,7997 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 57 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    _LT_PATH_MAGIC
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable.  If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins.  After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script.  The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+lt_cl_silent=false
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+  -h, --help      print this help, then exit
+  -V, --version   print version number, then exit
+  -q, --quiet     do not print progress messages
+  -d, --debug     don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2011 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
+
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+lt_cl_success=:
+test "$silent" = yes &&
+  lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+  _LT_PROG_LTMAIN
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  _LT_PROG_REPLACE_SHELLFNS
+
+   mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Go],			[_LT_LANG(GO)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_GO.  When it is available in    #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC],     [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+  fi
+fi
+if test -z "$GOC"; then
+  AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+  [LT_LANG(GO)],
+  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	# If there is a non-empty error log, and "single_module"
+	# appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	# Otherwise, if the output was created with a 0 exit code from
+	# the compiler, it worked.
+	elif test -f libconftest.dylib && test $_lt_result -eq 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS="$save_LDFLAGS"
+    ])
+
+    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+      [lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+	lt_cv_ld_force_load=yes
+      else
+	cat conftest.err >&AS_MESSAGE_LOG_FD
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+  else
+    _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  fi
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=func_echo_all
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    m4_if([$1], [CXX],
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+  lt_aix_libpath_sed='[
+      /Import File Strings/,/^$/ {
+	  /^0/ {
+	      s/^0  *\([^ ]*\) *$/\1/
+	      p
+	  }
+      }]'
+  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi],[])
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+  fi
+  ])
+  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*" 
+}
+
+case "$ECHO" in
+  printf*) AC_MSG_RESULT([printf]) ;;
+  print*) AC_MSG_RESULT([print -r]) ;;
+  *) AC_MSG_RESULT([cat]) ;;
+esac
+
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+  test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test "X`printf %s $ECHO`" = "X$ECHO" \
+      || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
+
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[  --with-sysroot[=DIR] Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted.  We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   AC_MSG_RESULT([${with_sysroot}])
+   AC_MSG_ERROR([The sysroot must be an absolute path.])
+   ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    case `/usr/bin/file conftest.o` in
+	      *x86-64*)
+		LD="${LD-ld} -m elf32_x86_64"
+		;;
+	      *)
+		LD="${LD-ld} -m elf_i386"
+		;;
+	    esac
+	    ;;
+	  powerpc64le-*)
+	    LD="${LD-ld} -m elf32lppclinux"
+	    ;;
+	  powerpc64-*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  powerpcle-*)
+	    LD="${LD-ld} -m elf64lppc"
+	    ;;
+	  powerpc-*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+  [lt_cv_ar_at_file=no
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+     [echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([lt_ar_try])
+      if test "$ac_status" -eq 0; then
+	# Ensure the archiver fails upon bogus file names.
+	rm -f conftest.$ac_objext libconftest.a
+	AC_TRY_EVAL([lt_ar_try])
+	if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+     ])
+  ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+  [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[_LT_PROG_AR
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+    [Whether to use a lock for old archive extraction])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len" && \
+	test undefined != "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+	         = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line $LINENO "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else
+        {
+	  if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+	}
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[[4-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+m4_if([$1], [],[
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
+    ;;
+
+  *)
+    # Assume MSVC wrapper
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
+    ;;
+  esac
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[23]].*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2.*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+  postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux # correct to gnu/linux during the next big refactor
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+
+  # Some binutils ld are patched to set DT_RUNPATH
+  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+    [lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+	 LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+      [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+	 [lt_cv_shlibpath_overrides_runpath=yes])])
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+    ])
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsdelf*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='NetBSD ld.elf_so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux # correct to gnu/linux during the next big refactor
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+    [Permission mode override for installation of shared libraries])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc*)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd* | netbsdelf*-gnu)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+    [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+    [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
+  AC_SUBST([DUMPBIN])
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+    [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+  [lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  case $cc_basename in
+  nvcc*)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+  esac
+
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT@&t@_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+LT@&t@_DLSYM_CONST struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_globsym_save_LIBS=$LIBS
+	  lt_globsym_save_CFLAGS=$CFLAGS
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS=$lt_globsym_save_LIBS
+	  CFLAGS=$lt_globsym_save_CFLAGS
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+    [Specify filename containing input files for $NM])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      mingw* | cygwin* | os2* | pw32* | cegcc*)
+	# This hack is so that the source file can tell whether it is being
+	# built for inclusion in a dll (and should export symbols for example).
+	m4_if([$1], [GCJ], [],
+	  [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+	    # IBM XL 8.0, 9.0 on PPC and BlueGene
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd* | netbsdelf*-gnu)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+      if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+      fi
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      nagfor*)
+	# NAG Fortran compiler
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl* | bgxl* | bgf* | mpixl*)
+	# IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	*Sun\ F* | *Sun*Fortran*)
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	  ;;
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+        *Intel*\ [[CF]]*Compiler*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	  ;;
+	*Portland\ Group*)
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
+
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+    ;;
+  cygwin* | mingw* | cegcc*)
+    case $cc_basename in
+    cl*)
+      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      ;;
+    esac
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+    ;;
+  esac
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
+    _LT_TAGVAR(link_all_deplibs, $1)=no
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
+  if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+	# The AIX port of GNU ld has always aspired to compatibility
+	# with the native linker.  However, as the warning in the GNU ld
+	# block says, versions before 2.19.5* couldn't really create working
+	# shared libraries, regardless of the interface used.
+	case `$LD -v 2>&1` in
+	  *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+	  *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+	  *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+	  *)
+	    lt_use_gnu_ld_interface=yes
+	    ;;
+	esac
+	;;
+      *)
+	lt_use_gnu_ld_interface=yes
+	;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    haiku*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=' $pic_flag'
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95* | pgfortran*)
+					# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+	xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	nvcc*)	# Cuda Compiler Driver 2.2
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf* | bgf* | bgxlf* | mpixlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix[[4-9]]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	# Also, AIX nm treats weak defined symbols like other global
+	# defined symbols, whereas GNU nm marks them as "W".
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+	_LT_TAGVAR(link_all_deplibs, $1)=no
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX([$1])
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX([$1])
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  if test "$with_gnu_ld" = yes; then
+	    # We only use this code for GNU lds that support --whole-archive.
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	  else
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  fi
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      case $cc_basename in
+      cl*)
+	# Native MSVC
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	_LT_TAGVAR(always_export_symbols, $1)=yes
+	_LT_TAGVAR(file_list_spec, $1)='@'
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	  else
+	    sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	  fi~
+	  $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	  linknames='
+	# The linker will not automatically build a static lib if we build a DLL.
+	# _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+	_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+	# Don't use ranlib
+	_LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	_LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+	  lt_tool_outputfile="@TOOL_OUTPUT@"~
+	  case $lt_outputfile in
+	    *.exe|*.EXE) ;;
+	    *)
+	      lt_outputfile="$lt_outputfile.exe"
+	      lt_tool_outputfile="$lt_tool_outputfile.exe"
+	      ;;
+	  esac~
+	  if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	    $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	    $RM "$lt_outputfile.manifest";
+	  fi'
+	;;
+      *)
+	# Assume MSVC wrapper
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Tell ltmain to make .lib files, not .a files.
+	libext=lib
+	# Tell ltmain to make .dll files, not .so files.
+	shrext_cmds=".dll"
+	# FIXME: Setting linknames here is a bad hack.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+	# The linker will automatically build a .lib file if we build a DLL.
+	_LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	# FIXME: Should let the user specify the lib program.
+	_LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+	_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	;;
+      esac
+      ;;
+
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
+
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2.*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	m4_if($1, [], [
+	  # Older versions of the 11.00 compiler do not understand -b yet
+	  # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+	  _LT_LINKER_OPTION([if $CC understands -b],
+	    _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+	    [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+	    [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+	  [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+	# This should be the same for all languages, so no per-tag cache variable.
+	AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+	  [lt_cv_irix_exported_symbol],
+	  [save_LDFLAGS="$LDFLAGS"
+	   LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+	   AC_LINK_IFELSE(
+	     [AC_LANG_SOURCE(
+	        [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+			      [C++], [[int foo (void) { return 0; }]],
+			      [Fortran 77], [[
+      subroutine foo
+      end]],
+			      [Fortran], [[
+      subroutine foo
+      end]])])],
+	      [lt_cv_irix_exported_symbol=yes],
+	      [lt_cv_irix_exported_symbol=no])
+           LDFLAGS="$save_LDFLAGS"])
+	if test "$lt_cv_irix_exported_symbol" = yes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+	fi
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd* | netbsdelf*-gnu)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+	[lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+	[$RM conftest*
+	echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+	if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+	  soname=conftest
+	  lib=conftest
+	  libobjs=conftest.$ac_objext
+	  deplibs=
+	  wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	  pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+	  compiler_flags=-v
+	  linker_flags=-v
+	  verstring=
+	  output_objdir=.
+	  libname=conftest
+	  lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+	  _LT_TAGVAR(allow_undefined_flag, $1)=
+	  if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+	  then
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	  else
+	    lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  fi
+	  _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+	else
+	  cat conftest.err 1>&5
+	fi
+	$RM conftest*
+	])
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+    [Commands necessary for finishing linking programs])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report which library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[[4-9]]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  AC_MSG_RESULT([$enable_shared])
+
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
+
+  _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+      LT_PATH_LD
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+      aix[[4-9]]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX([$1])
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX([$1])
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    if test "$with_gnu_ld" = yes; then
+	      # We only use this code for GNU lds that support --whole-archive.
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    else
+	      # Exported symbols can be pulled into shared objects from archives
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    fi
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+	case $GXX,$cc_basename in
+	,cl* | no,cl*)
+	  # Native MSVC
+	  # hardcode_libdir_flag_spec is actually meaningless, as there is
+	  # no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=yes
+	  _LT_TAGVAR(file_list_spec, $1)='@'
+	  # Tell ltmain to make .lib files, not .a files.
+	  libext=lib
+	  # Tell ltmain to make .dll files, not .so files.
+	  shrext_cmds=".dll"
+	  # FIXME: Setting linknames here is a bad hack.
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+	    else
+	      $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+	    fi~
+	    $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+	    linknames='
+	  # The linker will not automatically build a static lib if we build a DLL.
+	  # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+	  # Don't use ranlib
+	  _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+	  _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+	    lt_tool_outputfile="@TOOL_OUTPUT@"~
+	    case $lt_outputfile in
+	      *.exe|*.EXE) ;;
+	      *)
+		lt_outputfile="$lt_outputfile.exe"
+		lt_tool_outputfile="$lt_tool_outputfile.exe"
+		;;
+	    esac~
+	    func_to_tool_file "$lt_outputfile"~
+	    if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+	      $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+	      $RM "$lt_outputfile.manifest";
+	    fi'
+	  ;;
+	*)
+	  # g++
+	  # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+	  # as there is no search path for DLLs.
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  _LT_TAGVAR(always_export_symbols, $1)=no
+	  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+	  if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	    # If the export-symbols file already is a .def file (1st line
+	    # is EXPORTS), use it as is; otherwise, prepend...
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	      cp $export_symbols $output_objdir/$soname.def;
+	    else
+	      echo EXPORTS > $output_objdir/$soname.def;
+	      cat $export_symbols >> $output_objdir/$soname.def;
+	    fi~
+	    $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	  ;;
+	esac
+	;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      freebsd2.*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      haiku*)
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+	    ;;
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
+        ;;
+
+      linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
+		$RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 and above use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+	    ;;
+	  xl* | mpixl* | bgxl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='func_echo_all'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=func_echo_all
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC* | sunCC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+	    output_verbose_link_cmd='func_echo_all'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+	      '"$_LT_TAGVAR(old_archive_cmds, $1)"
+	    _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+	      '"$_LT_TAGVAR(reload_cmds, $1)"
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
+
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
+])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case ${prev}${p} in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       fi
+
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
+       if test "$pre_test_object_deps_done" = no; then
+	 case ${prev} in
+	 -L | -R)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+	 fi
+       fi
+       prev=
+       ;;
+
+    *.lto.$objext) ;; # Ignore GCC LTO objects
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC* | sunCC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${F77-"f77"}
+  CFLAGS=$FFLAGS
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+  CFLAGS="$lt_save_CFLAGS"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+  _lt_disable_FC=yes
+fi
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
+  CC=${FC-"f95"}
+  CFLAGS=$FCFLAGS
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
+
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+CFLAGS=
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([	 ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
+
+
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary parameter first.
+    func_stripname_result=${3}
+    func_stripname_result=${func_stripname_result#"${1}"}
+    func_stripname_result=${func_stripname_result%"${2}"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
+
+  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+    case ${1} in
+      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+      *)    func_lo2o_result=${1} ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
+
+  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
+
+  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+    func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
+
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+         [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+         [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/protobuf/m4/ltoptions.m4 b/protobuf/m4/ltoptions.m4
new file mode 100644
index 0000000..5d9acd8
--- /dev/null
+++ b/protobuf/m4/ltoptions.m4
@@ -0,0 +1,384 @@
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+#   Inc.
+#   Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 7 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+        _LT_MANGLE_DEFUN([$1], [$2]),
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+		      [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME.  If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+    [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+  dnl
+  dnl Simply set some default values (i.e off) if boolean options were not
+  dnl specified:
+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+  ])
+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+  ])
+  dnl
+  dnl If no reference was made to various pairs of opposing options, then
+  dnl we run the default mode handler for the pair.  For example, if neither
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
+  dnl archives by default:
+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+  		   [_LT_ENABLE_FAST_INSTALL])
+  ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS],      [1], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+    _LT_DECL([build_libtool_libs], [enable_shared], [0],
+	[Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+    _LT_DECL([build_old_libs], [enable_static], [0],
+	[Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+	 [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+    [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+	IFS="$lt_save_ifs"
+	if test "X$lt_pkg" = "X$lt_p"; then
+	  pic_mode=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+		 [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+		 [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+		 [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+		 [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+		 [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/protobuf/m4/ltsugar.m4 b/protobuf/m4/ltsugar.m4
new file mode 100644
index 0000000..9000a05
--- /dev/null
+++ b/protobuf/m4/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/protobuf/m4/ltversion.m4 b/protobuf/m4/ltversion.m4
new file mode 100644
index 0000000..07a8602
--- /dev/null
+++ b/protobuf/m4/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# @configure_input@
+
+# serial 3337 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.4.2'
+macro_revision='1.3337'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/protobuf/m4/lt~obsolete.m4 b/protobuf/m4/lt~obsolete.m4
new file mode 100644
index 0000000..c573da9
--- /dev/null
+++ b/protobuf/m4/lt~obsolete.m4
@@ -0,0 +1,98 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 5 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],	[AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP],		[AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],	[AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77],		[AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC],		[AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX],		[AC_DEFUN([_LT_PROG_CXX])])
diff --git a/protobuf/m4/stl_hash.m4 b/protobuf/m4/stl_hash.m4
new file mode 100644
index 0000000..0722b14
--- /dev/null
+++ b/protobuf/m4/stl_hash.m4
@@ -0,0 +1,72 @@
+# We check two things: where the include file is for
+# unordered_map/hash_map (we prefer the first form), and what
+# namespace unordered/hash_map lives in within that include file.  We
+# include AC_TRY_COMPILE for all the combinations we've seen in the
+# wild.  We define HASH_MAP_H to the location of the header file, and
+# HASH_NAMESPACE to the namespace the class (unordered_map or
+# hash_map) is in.  We define HAVE_UNORDERED_MAP if the class we found
+# is named unordered_map, or leave it undefined if not.
+
+# This also checks if unordered map exists.
+AC_DEFUN([AC_CXX_STL_HASH],
+  [
+   AC_MSG_CHECKING(the location of hash_map)
+   AC_LANG_SAVE
+   AC_LANG_CPLUSPLUS
+   ac_cv_cxx_hash_map=""
+   # First try unordered_map, but not on gcc's before 4.2 -- I've
+   # seen unexplainable unordered_map bugs with -O2 on older gcc's.
+   AC_TRY_COMPILE([#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
+                   # error GCC too old for unordered_map
+                   #endif
+                   ],
+                   [/* no program body necessary */],
+                   [stl_hash_old_gcc=no],
+                   [stl_hash_old_gcc=yes])
+   for location in unordered_map tr1/unordered_map; do
+     for namespace in std std::tr1; do
+       if test -z "$ac_cv_cxx_hash_map" -a "$stl_hash_old_gcc" != yes; then
+         # Some older gcc's have a buggy tr1, so test a bit of code.
+         AC_TRY_COMPILE([#include <$location>],
+                        [const ${namespace}::unordered_map<int, int> t;
+                         return t.find(5) == t.end();],
+                        [ac_cv_cxx_hash_map="<$location>";
+                         ac_cv_cxx_hash_namespace="$namespace";
+                         ac_cv_cxx_hash_map_class="unordered_map";])
+       fi
+     done
+   done
+   # Now try hash_map
+   for location in ext/hash_map hash_map; do
+     for namespace in __gnu_cxx "" std stdext; do
+       if test -z "$ac_cv_cxx_hash_map"; then
+         AC_TRY_COMPILE([#include <$location>],
+                        [${namespace}::hash_map<int, int> t],
+                        [ac_cv_cxx_hash_map="<$location>";
+                         ac_cv_cxx_hash_namespace="$namespace";
+                         ac_cv_cxx_hash_map_class="hash_map";])
+       fi
+     done
+   done
+   ac_cv_cxx_hash_set=`echo "$ac_cv_cxx_hash_map" | sed s/map/set/`;
+   ac_cv_cxx_hash_set_class=`echo "$ac_cv_cxx_hash_map_class" | sed s/map/set/`;
+   if test -n "$ac_cv_cxx_hash_map"; then
+      AC_DEFINE(HAVE_HASH_MAP, 1, [define if the compiler has hash_map])
+      AC_DEFINE(HAVE_HASH_SET, 1, [define if the compiler has hash_set])
+      AC_DEFINE_UNQUOTED(HASH_MAP_H,$ac_cv_cxx_hash_map,
+                         [the location of <unordered_map> or <hash_map>])
+      AC_DEFINE_UNQUOTED(HASH_SET_H,$ac_cv_cxx_hash_set,
+                         [the location of <unordered_set> or <hash_set>])
+      AC_DEFINE_UNQUOTED(HASH_NAMESPACE,$ac_cv_cxx_hash_namespace,
+                         [the namespace of hash_map/hash_set])
+      AC_DEFINE_UNQUOTED(HASH_MAP_CLASS,$ac_cv_cxx_hash_map_class,
+                         [the name of <hash_map>])
+      AC_DEFINE_UNQUOTED(HASH_SET_CLASS,$ac_cv_cxx_hash_set_class,
+                         [the name of <hash_set>])
+      AC_MSG_RESULT([$ac_cv_cxx_hash_map])
+   else
+      AC_MSG_RESULT()
+      AC_MSG_WARN([could not find an STL hash_map])
+   fi
+])
+
diff --git a/protobuf/missing b/protobuf/missing
new file mode 100755
index 0000000..db98974
--- /dev/null
+++ b/protobuf/missing
@@ -0,0 +1,215 @@
+#! /bin/sh
+# Common wrapper for a few potentially missing GNU programs.
+
+scriptversion=2013-10-28.13; # UTC
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try '$0 --help' for more information"
+  exit 1
+fi
+
+case $1 in
+
+  --is-lightweight)
+    # Used by our autoconf macros to check whether the available missing
+    # script is modern enough.
+    exit 0
+    ;;
+
+  --run)
+    # Back-compat with the calling convention used by older automake.
+    shift
+    ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
+to PROGRAM being missing or too old.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal   autoconf  autoheader   autom4te  automake  makeinfo
+  bison     yacc      flex         lex       help2man
+
+Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
+'g' are ignored when checking the name.
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: unknown '$1' option"
+    echo 1>&2 "Try '$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Run the given program, remember its exit status.
+"$@"; st=$?
+
+# If it succeeded, we are done.
+test $st -eq 0 && exit 0
+
+# Also exit now if we it failed (or wasn't found), and '--version' was
+# passed; such an option is passed most likely to detect whether the
+# program is present and works.
+case $2 in --version|--help) exit $st;; esac
+
+# Exit code 63 means version mismatch.  This often happens when the user
+# tries to use an ancient version of a tool on a file that requires a
+# minimum version.
+if test $st -eq 63; then
+  msg="probably too old"
+elif test $st -eq 127; then
+  # Program was missing.
+  msg="missing on your system"
+else
+  # Program was found and executed, but failed.  Give up.
+  exit $st
+fi
+
+perl_URL=http://www.perl.org/
+flex_URL=http://flex.sourceforge.net/
+gnu_software_URL=http://www.gnu.org/software
+
+program_details ()
+{
+  case $1 in
+    aclocal|automake)
+      echo "The '$1' program is part of the GNU Automake package:"
+      echo "<$gnu_software_URL/automake>"
+      echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/autoconf>"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+    autoconf|autom4te|autoheader)
+      echo "The '$1' program is part of the GNU Autoconf package:"
+      echo "<$gnu_software_URL/autoconf/>"
+      echo "It also requires GNU m4 and Perl in order to run:"
+      echo "<$gnu_software_URL/m4/>"
+      echo "<$perl_URL>"
+      ;;
+  esac
+}
+
+give_advice ()
+{
+  # Normalize program name to check for.
+  normalized_program=`echo "$1" | sed '
+    s/^gnu-//; t
+    s/^gnu//; t
+    s/^g//; t'`
+
+  printf '%s\n' "'$1' is $msg."
+
+  configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
+  case $normalized_program in
+    autoconf*)
+      echo "You should only need it if you modified 'configure.ac',"
+      echo "or m4 files included by it."
+      program_details 'autoconf'
+      ;;
+    autoheader*)
+      echo "You should only need it if you modified 'acconfig.h' or"
+      echo "$configure_deps."
+      program_details 'autoheader'
+      ;;
+    automake*)
+      echo "You should only need it if you modified 'Makefile.am' or"
+      echo "$configure_deps."
+      program_details 'automake'
+      ;;
+    aclocal*)
+      echo "You should only need it if you modified 'acinclude.m4' or"
+      echo "$configure_deps."
+      program_details 'aclocal'
+      ;;
+   autom4te*)
+      echo "You might have modified some maintainer files that require"
+      echo "the 'autom4te' program to be rebuilt."
+      program_details 'autom4te'
+      ;;
+    bison*|yacc*)
+      echo "You should only need it if you modified a '.y' file."
+      echo "You may want to install the GNU Bison package:"
+      echo "<$gnu_software_URL/bison/>"
+      ;;
+    lex*|flex*)
+      echo "You should only need it if you modified a '.l' file."
+      echo "You may want to install the Fast Lexical Analyzer package:"
+      echo "<$flex_URL>"
+      ;;
+    help2man*)
+      echo "You should only need it if you modified a dependency" \
+           "of a man page."
+      echo "You may want to install the GNU Help2man package:"
+      echo "<$gnu_software_URL/help2man/>"
+    ;;
+    makeinfo*)
+      echo "You should only need it if you modified a '.texi' file, or"
+      echo "any other file indirectly affecting the aspect of the manual."
+      echo "You might want to install the Texinfo package:"
+      echo "<$gnu_software_URL/texinfo/>"
+      echo "The spurious makeinfo call might also be the consequence of"
+      echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
+      echo "want to install GNU make:"
+      echo "<$gnu_software_URL/make/>"
+      ;;
+    *)
+      echo "You might have modified some files without having the proper"
+      echo "tools for further handling them.  Check the 'README' file, it"
+      echo "often tells you about the needed prerequisites for installing"
+      echo "this package.  You may also peek at any GNU archive site, in"
+      echo "case some other package contains this missing '$1' program."
+      ;;
+  esac
+}
+
+give_advice "$1" | sed -e '1s/^/WARNING: /' \
+                       -e '2,$s/^/         /' >&2
+
+# Propagate the correct exit status (expected to be 127 for a program
+# not found, 63 for a program that failed due to version mismatch).
+exit $st
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/protobuf/more_tests/Makefile b/protobuf/more_tests/Makefile
new file mode 100755
index 0000000..286cf0f
--- /dev/null
+++ b/protobuf/more_tests/Makefile
@@ -0,0 +1,41 @@
+# Additional tests to run before releasing a package.
+#
+# Run like:
+#   make PACKAGE=/path/to/protobuf-VERSION.tar.gz
+#
+# Some of these tests require tools or make assumptions that may not be
+# available on end-user machines, so these cannot be part of "make check".  For
+# example, we test that the headers compile with strict warning settings, but
+# since different compilers produce wildly different warnings we cannot assume
+# that this test will pass everywhere.  If we ran it as part of "make check",
+# it could unnecessarily block users from running the real tests just because
+# their compiler produces some extra warnings that probably aren't a big deal.
+# So we run it separately. 
+
+all: header_warning_test
+
+clean:
+	rm -rf src target header_warning_test.cc header_warning_test.o header_warning_test
+
+# Unpack the package into src, then install it into target.
+PACKAGE=protobuf.tar.gz
+
+src: $(PACKAGE)
+	tar zxvf $(PACKAGE)
+	mv `basename $(PACKAGE) .tar.gz` src
+
+target: src
+	(cd src && ./configure --prefix=$$PWD/../target --disable-shared)
+	(cd src && make -j4 check)
+	(cd src && make install)
+
+# Verify that headers produce no warnings even under strict settings.
+header_warning_test.cc: target
+	( (cd target/include && find google/protobuf -name '*.h') | \
+	  awk '{print "#include \""$$1"\""} ' > header_warning_test.cc )
+
+header_warning_test: header_warning_test.cc
+	# TODO(kenton):  Consider adding -pedantic and -Weffc++.  Currently these
+	#   produce tons of extra warnings so we'll need to do some work first.
+	g++ -Itarget/include -Wall -Werror -Wsign-compare -O2 -c header_warning_test.cc
+	touch header_warning_test
diff --git a/protobuf/post_process_dist.sh b/protobuf/post_process_dist.sh
new file mode 100755
index 0000000..7b2e599
--- /dev/null
+++ b/protobuf/post_process_dist.sh
@@ -0,0 +1,60 @@
+#! /bin/sh
+
+# This script takes the result of "make dist" and:
+# 1) Unpacks it.
+# 2) Ensures all contents are user-writable.  Some version control systems
+#    keep code read-only until you explicitly ask to edit it, and the normal
+#    "make dist" process does not correct for this, so the result is that
+#    the entire dist is still marked read-only when unpacked, which is
+#    annoying.  So, we fix it.
+# 3) Convert MSVC project files to MSVC 2005, so that anyone who has version
+#    2005 *or* 2008 can open them.  (In version control, we keep things in
+#    MSVC 2008 format since that's what we use in development.)
+# 4) Uses the result to create .tar.gz, .tar.bz2, and .zip versions and
+#    deposites them in the "dist" directory.  In the .zip version, all
+#    non-testdata .txt files are converted to Windows-style line endings.
+# 5) Cleans up after itself.
+
+if [ "$1" == "" ]; then
+  echo "USAGE:  $1 DISTFILE" >&2
+  exit 1
+fi
+
+if [ ! -e $1 ]; then
+  echo $1": File not found." >&2
+  exit 1
+fi
+
+set -ex
+
+BASENAME=`basename $1 .tar.gz`
+
+# Create a directory called "dist", copy the tarball there and unpack it.
+mkdir dist
+cp $1 dist
+cd dist
+tar zxvf $BASENAME.tar.gz
+rm $BASENAME.tar.gz
+
+# Set the entire contents to be user-writable.
+chmod -R u+w $BASENAME
+
+# Convert the MSVC projects to MSVC 2005 format.
+cd $BASENAME/vsprojects
+./convert2008to2005.sh
+cd ..
+
+# Build the dist again in .tar.gz and .tar.bz2 formats.
+./configure
+make dist-gzip
+make dist-bzip2
+
+# Convert all text files to use DOS-style line endings, then build a .zip
+# distribution.
+todos *.txt */*.txt
+make dist-zip
+
+# Clean up.
+mv $BASENAME.tar.gz $BASENAME.tar.bz2 $BASENAME.zip ..
+cd ..
+rm -rf $BASENAME
diff --git a/protobuf/protobuf-lite.pc.in b/protobuf/protobuf-lite.pc.in
new file mode 100644
index 0000000..29c218e
--- /dev/null
+++ b/protobuf/protobuf-lite.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Protocol Buffers
+Description: Google's Data Interchange Format
+Version: @VERSION@
+Libs: -L${libdir} -lprotobuf-lite @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
+Cflags: -I${includedir} @PTHREAD_CFLAGS@
+# Commented out because it crashes pkg-config *sigh*:
+#   http://bugs.freedesktop.org/show_bug.cgi?id=13265
+# Conflicts: protobuf
diff --git a/protobuf/protobuf.pc.in b/protobuf/protobuf.pc.in
new file mode 100644
index 0000000..29f2487
--- /dev/null
+++ b/protobuf/protobuf.pc.in
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Protocol Buffers
+Description: Google's Data Interchange Format
+Version: @VERSION@
+Libs: -L${libdir} -lprotobuf @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
+Libs.private: @LIBS@
+Cflags: -I${includedir} @PTHREAD_CFLAGS@
+# Commented out because it crashes pkg-config *sigh*:
+#   http://bugs.freedesktop.org/show_bug.cgi?id=13265
+# Conflicts: protobuf-lite
diff --git a/protobuf/python/README.txt b/protobuf/python/README.txt
new file mode 100644
index 0000000..da044af
--- /dev/null
+++ b/protobuf/python/README.txt
@@ -0,0 +1,105 @@
+Protocol Buffers - Google's data interchange format
+Copyright 2008 Google Inc.
+
+This directory contains the Python Protocol Buffers runtime library.
+
+Normally, this directory comes as part of the protobuf package, available
+from:
+
+  https://developers.google.com/protocol-buffers/
+
+The complete package includes the C++ source code, which includes the
+Protocol Compiler (protoc).  If you downloaded this package from PyPI
+or some other Python-specific source, you may have received only the
+Python part of the code.  In this case, you will need to obtain the
+Protocol Compiler from some other source before you can use this
+package.
+
+Development Warning
+===================
+
+The Python implementation of Protocol Buffers is not as mature as the C++
+and Java implementations.  It may be more buggy, and it is known to be
+pretty slow at this time.  If you would like to help fix these issues,
+join the Protocol Buffers discussion list and let us know!
+
+Installation
+============
+
+1) Make sure you have Python 2.4 or newer.  If in doubt, run:
+
+     $ python -V
+
+2) If you do not have setuptools installed, note that it will be
+   downloaded and installed automatically as soon as you run setup.py.
+   If you would rather install it manually, you may do so by following
+   the instructions on this page:
+
+     http://peak.telecommunity.com/DevCenter/EasyInstall#installation-instructions
+
+3) Build the C++ code, or install a binary distribution of protoc.  If
+   you install a binary distribution, make sure that it is the same
+   version as this package.  If in doubt, run:
+
+     $ protoc --version
+
+4) Build and run the tests:
+
+     $ python setup.py build
+     $ python setup.py google_test
+
+     If you want to test c++ implementation, run:
+     $ python setup.py test --cpp_implementation
+
+   If some tests fail, this library may not work correctly on your
+   system.  Continue at your own risk.
+
+   Please note that there is a known problem with some versions of
+   Python on Cygwin which causes the tests to fail after printing the
+   error:  "sem_init: Resource temporarily unavailable".  This appears
+   to be a bug either in Cygwin or in Python:
+     http://www.cygwin.com/ml/cygwin/2005-07/msg01378.html
+   We do not know if or when it might me fixed.  We also do not know
+   how likely it is that this bug will affect users in practice.
+
+5) Install:
+
+     $ python setup.py install
+     or:
+     $ python setup.py install --cpp_implementation
+
+   This step may require superuser privileges.
+   NOTE: To use C++ implementation, you need to install C++ protobuf runtime
+   library of the same version and export the environment variable before this
+   step. See the "C++ Implementation" section below for more details.
+
+Usage
+=====
+
+The complete documentation for Protocol Buffers is available via the
+web at:
+
+  https://developers.google.com/protocol-buffers/
+
+C++ Implementation
+==================
+
+The C++ implementation for Python messages is built as a Python extension to
+improve the overall protobuf Python performance.
+
+To use the C++ implementation, you need to:
+1) Install the C++ protobuf runtime library, please see instructions in the
+   parent directory.
+2) Export an environment variable:
+
+  $ export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
+  $ export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=2
+
+You need to export this variable before running setup.py script to build and
+install the extension.  You must also set the variable at runtime, otherwise
+the pure-Python implementation will be used. In a future release, we will
+change the default so that C++ implementation is used whenever it is available.
+It is strongly recommended to run `python setup.py test` after setting the
+variable to "cpp", so the tests will be against C++ implemented Python
+messages.
+
diff --git a/protobuf/python/ez_setup.py b/protobuf/python/ez_setup.py
new file mode 100755
index 0000000..3aec98e
--- /dev/null
+++ b/protobuf/python/ez_setup.py
@@ -0,0 +1,284 @@
+#!python
+
+# This file was obtained from:
+#   http://peak.telecommunity.com/dist/ez_setup.py
+# on 2011/1/21.
+
+"""Bootstrap setuptools installation
+
+If you want to use setuptools in your package's setup.py, just include this
+file in the same directory with it, and add this to the top of your setup.py::
+
+    from ez_setup import use_setuptools
+    use_setuptools()
+
+If you want to require a specific version of setuptools, set a download
+mirror, or use an alternate download directory, you can do so by supplying
+the appropriate options to ``use_setuptools()``.
+
+This file can also be run as a script to install or upgrade setuptools.
+"""
+import sys
+DEFAULT_VERSION = "0.6c11"
+DEFAULT_URL     = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
+
+md5_data = {
+    'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
+    'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
+    'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
+    'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
+    'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
+    'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
+    'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
+    'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
+    'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
+    'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
+    'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
+    'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
+    'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
+    'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
+    'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
+    'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
+    'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
+    'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
+    'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
+    'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
+    'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
+    'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
+    'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
+    'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
+    'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
+    'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
+    'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
+    'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
+    'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
+    'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
+    'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
+    'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
+    'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
+    'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
+    'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
+    'setuptools-0.6c8-py2.3.egg': '50759d29b349db8cfd807ba8303f1902',
+    'setuptools-0.6c8-py2.4.egg': 'cba38d74f7d483c06e9daa6070cce6de',
+    'setuptools-0.6c8-py2.5.egg': '1721747ee329dc150590a58b3e1ac95b',
+    'setuptools-0.6c9-py2.3.egg': 'a83c4020414807b496e4cfbe08507c03',
+    'setuptools-0.6c9-py2.4.egg': '260a2be2e5388d66bdaee06abec6342a',
+    'setuptools-0.6c9-py2.5.egg': 'fe67c3e5a17b12c0e7c541b7ea43a8e6',
+    'setuptools-0.6c9-py2.6.egg': 'ca37b1ff16fa2ede6e19383e7b59245a',
+}
+
+import sys, os
+try: from hashlib import md5
+except ImportError: from md5 import md5
+
+def _validate_md5(egg_name, data):
+    if egg_name in md5_data:
+        digest = md5(data).hexdigest()
+        if digest != md5_data[egg_name]:
+            print >>sys.stderr, (
+                "md5 validation of %s failed!  (Possible download problem?)"
+                % egg_name
+            )
+            sys.exit(2)
+    return data
+
+def use_setuptools(
+    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+    download_delay=15
+):
+    """Automatically find/download setuptools and make it available on sys.path
+
+    `version` should be a valid setuptools version number that is available
+    as an egg for download under the `download_base` URL (which should end with
+    a '/').  `to_dir` is the directory where setuptools will be downloaded, if
+    it is not already available.  If `download_delay` is specified, it should
+    be the number of seconds that will be paused before initiating a download,
+    should one be required.  If an older version of setuptools is installed,
+    this routine will print a message to ``sys.stderr`` and raise SystemExit in
+    an attempt to abort the calling script.
+    """
+    was_imported = 'pkg_resources' in sys.modules or 'setuptools' in sys.modules
+    def do_download():
+        egg = download_setuptools(version, download_base, to_dir, download_delay)
+        sys.path.insert(0, egg)
+        import setuptools; setuptools.bootstrap_install_from = egg
+    try:
+        import pkg_resources
+    except ImportError:
+        return do_download()       
+    try:
+        return do_download()
+        pkg_resources.require("setuptools>="+version); return
+    except pkg_resources.VersionConflict, e:
+        if was_imported:
+            print >>sys.stderr, (
+            "The required version of setuptools (>=%s) is not available, and\n"
+            "can't be installed while this script is running. Please install\n"
+            " a more recent version first, using 'easy_install -U setuptools'."
+            "\n\n(Currently using %r)"
+            ) % (version, e.args[0])
+            sys.exit(2)
+    except pkg_resources.DistributionNotFound:
+        pass
+
+    del pkg_resources, sys.modules['pkg_resources']    # reload ok
+    return do_download()
+
+def download_setuptools(
+    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
+    delay = 15
+):
+    """Download setuptools from a specified location and return its filename
+
+    `version` should be a valid setuptools version number that is available
+    as an egg for download under the `download_base` URL (which should end
+    with a '/'). `to_dir` is the directory where the egg will be downloaded.
+    `delay` is the number of seconds to pause before an actual download attempt.
+    """
+    import urllib2, shutil
+    egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
+    url = download_base + egg_name
+    saveto = os.path.join(to_dir, egg_name)
+    src = dst = None
+    if not os.path.exists(saveto):  # Avoid repeated downloads
+        try:
+            from distutils import log
+            if delay:
+                log.warn("""
+---------------------------------------------------------------------------
+This script requires setuptools version %s to run (even to display
+help).  I will attempt to download it for you (from
+%s), but
+you may need to enable firewall access for this script first.
+I will start the download in %d seconds.
+
+(Note: if this machine does not have network access, please obtain the file
+
+   %s
+
+and place it in this directory before rerunning this script.)
+---------------------------------------------------------------------------""",
+                    version, download_base, delay, url
+                ); from time import sleep; sleep(delay)
+            log.warn("Downloading %s", url)
+            src = urllib2.urlopen(url)
+            # Read/write all in one block, so we don't create a corrupt file
+            # if the download is interrupted.
+            data = _validate_md5(egg_name, src.read())
+            dst = open(saveto,"wb"); dst.write(data)
+        finally:
+            if src: src.close()
+            if dst: dst.close()
+    return os.path.realpath(saveto)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+def main(argv, version=DEFAULT_VERSION):
+    """Install or upgrade setuptools and EasyInstall"""
+    try:
+        import setuptools
+    except ImportError:
+        egg = None
+        try:
+            egg = download_setuptools(version, delay=0)
+            sys.path.insert(0,egg)
+            from setuptools.command.easy_install import main
+            return main(list(argv)+[egg])   # we're done here
+        finally:
+            if egg and os.path.exists(egg):
+                os.unlink(egg)
+    else:
+        if setuptools.__version__ == '0.0.1':
+            print >>sys.stderr, (
+            "You have an obsolete version of setuptools installed.  Please\n"
+            "remove it from your system entirely before rerunning this script."
+            )
+            sys.exit(2)
+
+    req = "setuptools>="+version
+    import pkg_resources
+    try:
+        pkg_resources.require(req)
+    except pkg_resources.VersionConflict:
+        try:
+            from setuptools.command.easy_install import main
+        except ImportError:
+            from easy_install import main
+        main(list(argv)+[download_setuptools(delay=0)])
+        sys.exit(0) # try to force an exit
+    else:
+        if argv:
+            from setuptools.command.easy_install import main
+            main(argv)
+        else:
+            print "Setuptools version",version,"or greater has been installed."
+            print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
+
+def update_md5(filenames):
+    """Update our built-in md5 registry"""
+
+    import re
+
+    for name in filenames:
+        base = os.path.basename(name)
+        f = open(name,'rb')
+        md5_data[base] = md5(f.read()).hexdigest()
+        f.close()
+
+    data = ["    %r: %r,\n" % it for it in md5_data.items()]
+    data.sort()
+    repl = "".join(data)
+
+    import inspect
+    srcfile = inspect.getsourcefile(sys.modules[__name__])
+    f = open(srcfile, 'rb'); src = f.read(); f.close()
+
+    match = re.search("\nmd5_data = {\n([^}]+)}", src)
+    if not match:
+        print >>sys.stderr, "Internal error!"
+        sys.exit(2)
+
+    src = src[:match.start(1)] + repl + src[match.end(1):]
+    f = open(srcfile,'w')
+    f.write(src)
+    f.close()
+
+
+if __name__=='__main__':
+    if len(sys.argv)>2 and sys.argv[1]=='--md5update':
+        update_md5(sys.argv[2:])
+    else:
+        main(sys.argv[1:])
diff --git a/protobuf/python/google/__init__.py b/protobuf/python/google/__init__.py
new file mode 100755
index 0000000..de40ea7
--- /dev/null
+++ b/protobuf/python/google/__init__.py
@@ -0,0 +1 @@
+__import__('pkg_resources').declare_namespace(__name__)
diff --git a/protobuf/python/google/protobuf/__init__.py b/protobuf/python/google/protobuf/__init__.py
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/protobuf/python/google/protobuf/__init__.py
diff --git a/protobuf/python/google/protobuf/descriptor.py b/protobuf/python/google/protobuf/descriptor.py
new file mode 100755
index 0000000..6da8bb0
--- /dev/null
+++ b/protobuf/python/google/protobuf/descriptor.py
@@ -0,0 +1,849 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Needs to stay compatible with Python 2.5 due to GAE.
+#
+# Copyright 2007 Google Inc. All Rights Reserved.
+
+"""Descriptors essentially contain exactly the information found in a .proto
+file, in types that make this information accessible in Python.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+from google.protobuf.internal import api_implementation
+
+
+if api_implementation.Type() == 'cpp':
+  # Used by MakeDescriptor in cpp mode
+  import os
+  import uuid
+
+  if api_implementation.Version() == 2:
+    from google.protobuf.pyext import _message
+  else:
+    from google.protobuf.internal import cpp_message
+
+
+class Error(Exception):
+  """Base error for this module."""
+
+
+class TypeTransformationError(Error):
+  """Error transforming between python proto type and corresponding C++ type."""
+
+
+class DescriptorBase(object):
+
+  """Descriptors base class.
+
+  This class is the base of all descriptor classes. It provides common options
+  related functionaility.
+
+  Attributes:
+    has_options:  True if the descriptor has non-default options.  Usually it
+        is not necessary to read this -- just call GetOptions() which will
+        happily return the default instance.  However, it's sometimes useful
+        for efficiency, and also useful inside the protobuf implementation to
+        avoid some bootstrapping issues.
+  """
+
+  def __init__(self, options, options_class_name):
+    """Initialize the descriptor given its options message and the name of the
+    class of the options message. The name of the class is required in case
+    the options message is None and has to be created.
+    """
+    self._options = options
+    self._options_class_name = options_class_name
+
+    # Does this descriptor have non-default options?
+    self.has_options = options is not None
+
+  def _SetOptions(self, options, options_class_name):
+    """Sets the descriptor's options
+
+    This function is used in generated proto2 files to update descriptor
+    options. It must not be used outside proto2.
+    """
+    self._options = options
+    self._options_class_name = options_class_name
+
+    # Does this descriptor have non-default options?
+    self.has_options = options is not None
+
+  def GetOptions(self):
+    """Retrieves descriptor options.
+
+    This method returns the options set or creates the default options for the
+    descriptor.
+    """
+    if self._options:
+      return self._options
+    from google.protobuf import descriptor_pb2
+    try:
+      options_class = getattr(descriptor_pb2, self._options_class_name)
+    except AttributeError:
+      raise RuntimeError('Unknown options class name %s!' %
+                         (self._options_class_name))
+    self._options = options_class()
+    return self._options
+
+
+class _NestedDescriptorBase(DescriptorBase):
+  """Common class for descriptors that can be nested."""
+
+  def __init__(self, options, options_class_name, name, full_name,
+               file, containing_type, serialized_start=None,
+               serialized_end=None):
+    """Constructor.
+
+    Args:
+      options: Protocol message options or None
+        to use default message options.
+      options_class_name: (str) The class name of the above options.
+
+      name: (str) Name of this protocol message type.
+      full_name: (str) Fully-qualified name of this protocol message type,
+        which will include protocol "package" name and the name of any
+        enclosing types.
+      file: (FileDescriptor) Reference to file info.
+      containing_type: if provided, this is a nested descriptor, with this
+        descriptor as parent, otherwise None.
+      serialized_start: The start index (inclusive) in block in the
+        file.serialized_pb that describes this descriptor.
+      serialized_end: The end index (exclusive) in block in the
+        file.serialized_pb that describes this descriptor.
+    """
+    super(_NestedDescriptorBase, self).__init__(
+        options, options_class_name)
+
+    self.name = name
+    # TODO(falk): Add function to calculate full_name instead of having it in
+    #             memory?
+    self.full_name = full_name
+    self.file = file
+    self.containing_type = containing_type
+
+    self._serialized_start = serialized_start
+    self._serialized_end = serialized_end
+
+  def GetTopLevelContainingType(self):
+    """Returns the root if this is a nested type, or itself if its the root."""
+    desc = self
+    while desc.containing_type is not None:
+      desc = desc.containing_type
+    return desc
+
+  def CopyToProto(self, proto):
+    """Copies this to the matching proto in descriptor_pb2.
+
+    Args:
+      proto: An empty proto instance from descriptor_pb2.
+
+    Raises:
+      Error: If self couldnt be serialized, due to to few constructor arguments.
+    """
+    if (self.file is not None and
+        self._serialized_start is not None and
+        self._serialized_end is not None):
+      proto.ParseFromString(self.file.serialized_pb[
+          self._serialized_start:self._serialized_end])
+    else:
+      raise Error('Descriptor does not contain serialization.')
+
+
+class Descriptor(_NestedDescriptorBase):
+
+  """Descriptor for a protocol message type.
+
+  A Descriptor instance has the following attributes:
+
+    name: (str) Name of this protocol message type.
+    full_name: (str) Fully-qualified name of this protocol message type,
+      which will include protocol "package" name and the name of any
+      enclosing types.
+
+    containing_type: (Descriptor) Reference to the descriptor of the
+      type containing us, or None if this is top-level.
+
+    fields: (list of FieldDescriptors) Field descriptors for all
+      fields in this type.
+    fields_by_number: (dict int -> FieldDescriptor) Same FieldDescriptor
+      objects as in |fields|, but indexed by "number" attribute in each
+      FieldDescriptor.
+    fields_by_name: (dict str -> FieldDescriptor) Same FieldDescriptor
+      objects as in |fields|, but indexed by "name" attribute in each
+      FieldDescriptor.
+
+    nested_types: (list of Descriptors) Descriptor references
+      for all protocol message types nested within this one.
+    nested_types_by_name: (dict str -> Descriptor) Same Descriptor
+      objects as in |nested_types|, but indexed by "name" attribute
+      in each Descriptor.
+
+    enum_types: (list of EnumDescriptors) EnumDescriptor references
+      for all enums contained within this type.
+    enum_types_by_name: (dict str ->EnumDescriptor) Same EnumDescriptor
+      objects as in |enum_types|, but indexed by "name" attribute
+      in each EnumDescriptor.
+    enum_values_by_name: (dict str -> EnumValueDescriptor) Dict mapping
+      from enum value name to EnumValueDescriptor for that value.
+
+    extensions: (list of FieldDescriptor) All extensions defined directly
+      within this message type (NOT within a nested type).
+    extensions_by_name: (dict, string -> FieldDescriptor) Same FieldDescriptor
+      objects as |extensions|, but indexed by "name" attribute of each
+      FieldDescriptor.
+
+    is_extendable:  Does this type define any extension ranges?
+
+    options: (descriptor_pb2.MessageOptions) Protocol message options or None
+      to use default message options.
+
+    oneofs: (list of OneofDescriptor) The list of descriptors for oneof fields
+      in this message.
+    oneofs_by_name: (dict str -> OneofDescriptor) Same objects as in |oneofs|,
+      but indexed by "name" attribute.
+
+    file: (FileDescriptor) Reference to file descriptor.
+  """
+
+  # NOTE(tmarek): The file argument redefining a builtin is nothing we can
+  # fix right now since we don't know how many clients already rely on the
+  # name of the argument.
+  def __init__(self, name, full_name, filename, containing_type, fields,
+               nested_types, enum_types, extensions, options=None,
+               is_extendable=True, extension_ranges=None, oneofs=None,
+               file=None, serialized_start=None, serialized_end=None):  # pylint:disable=redefined-builtin
+    """Arguments to __init__() are as described in the description
+    of Descriptor fields above.
+
+    Note that filename is an obsolete argument, that is not used anymore.
+    Please use file.name to access this as an attribute.
+    """
+    super(Descriptor, self).__init__(
+        options, 'MessageOptions', name, full_name, file,
+        containing_type, serialized_start=serialized_start,
+        serialized_end=serialized_end)
+
+    # We have fields in addition to fields_by_name and fields_by_number,
+    # so that:
+    #   1. Clients can index fields by "order in which they're listed."
+    #   2. Clients can easily iterate over all fields with the terse
+    #      syntax: for f in descriptor.fields: ...
+    self.fields = fields
+    for field in self.fields:
+      field.containing_type = self
+    self.fields_by_number = dict((f.number, f) for f in fields)
+    self.fields_by_name = dict((f.name, f) for f in fields)
+
+    self.nested_types = nested_types
+    for nested_type in nested_types:
+      nested_type.containing_type = self
+    self.nested_types_by_name = dict((t.name, t) for t in nested_types)
+
+    self.enum_types = enum_types
+    for enum_type in self.enum_types:
+      enum_type.containing_type = self
+    self.enum_types_by_name = dict((t.name, t) for t in enum_types)
+    self.enum_values_by_name = dict(
+        (v.name, v) for t in enum_types for v in t.values)
+
+    self.extensions = extensions
+    for extension in self.extensions:
+      extension.extension_scope = self
+    self.extensions_by_name = dict((f.name, f) for f in extensions)
+    self.is_extendable = is_extendable
+    self.extension_ranges = extension_ranges
+    self.oneofs = oneofs if oneofs is not None else []
+    self.oneofs_by_name = dict((o.name, o) for o in self.oneofs)
+    for oneof in self.oneofs:
+      oneof.containing_type = self
+
+  def EnumValueName(self, enum, value):
+    """Returns the string name of an enum value.
+
+    This is just a small helper method to simplify a common operation.
+
+    Args:
+      enum: string name of the Enum.
+      value: int, value of the enum.
+
+    Returns:
+      string name of the enum value.
+
+    Raises:
+      KeyError if either the Enum doesn't exist or the value is not a valid
+        value for the enum.
+    """
+    return self.enum_types_by_name[enum].values_by_number[value].name
+
+  def CopyToProto(self, proto):
+    """Copies this to a descriptor_pb2.DescriptorProto.
+
+    Args:
+      proto: An empty descriptor_pb2.DescriptorProto.
+    """
+    # This function is overriden to give a better doc comment.
+    super(Descriptor, self).CopyToProto(proto)
+
+
+# TODO(robinson): We should have aggressive checking here,
+# for example:
+#   * If you specify a repeated field, you should not be allowed
+#     to specify a default value.
+#   * [Other examples here as needed].
+#
+# TODO(robinson): for this and other *Descriptor classes, we
+# might also want to lock things down aggressively (e.g.,
+# prevent clients from setting the attributes).  Having
+# stronger invariants here in general will reduce the number
+# of runtime checks we must do in reflection.py...
+class FieldDescriptor(DescriptorBase):
+
+  """Descriptor for a single field in a .proto file.
+
+  A FieldDescriptor instance has the following attributes:
+
+    name: (str) Name of this field, exactly as it appears in .proto.
+    full_name: (str) Name of this field, including containing scope.  This is
+      particularly relevant for extensions.
+    index: (int) Dense, 0-indexed index giving the order that this
+      field textually appears within its message in the .proto file.
+    number: (int) Tag number declared for this field in the .proto file.
+
+    type: (One of the TYPE_* constants below) Declared type.
+    cpp_type: (One of the CPPTYPE_* constants below) C++ type used to
+      represent this field.
+
+    label: (One of the LABEL_* constants below) Tells whether this
+      field is optional, required, or repeated.
+    has_default_value: (bool) True if this field has a default value defined,
+      otherwise false.
+    default_value: (Varies) Default value of this field.  Only
+      meaningful for non-repeated scalar fields.  Repeated fields
+      should always set this to [], and non-repeated composite
+      fields should always set this to None.
+
+    containing_type: (Descriptor) Descriptor of the protocol message
+      type that contains this field.  Set by the Descriptor constructor
+      if we're passed into one.
+      Somewhat confusingly, for extension fields, this is the
+      descriptor of the EXTENDED message, not the descriptor
+      of the message containing this field.  (See is_extension and
+      extension_scope below).
+    message_type: (Descriptor) If a composite field, a descriptor
+      of the message type contained in this field.  Otherwise, this is None.
+    enum_type: (EnumDescriptor) If this field contains an enum, a
+      descriptor of that enum.  Otherwise, this is None.
+
+    is_extension: True iff this describes an extension field.
+    extension_scope: (Descriptor) Only meaningful if is_extension is True.
+      Gives the message that immediately contains this extension field.
+      Will be None iff we're a top-level (file-level) extension field.
+
+    options: (descriptor_pb2.FieldOptions) Protocol message field options or
+      None to use default field options.
+
+    containing_oneof: (OneofDescriptor) If the field is a member of a oneof
+      union, contains its descriptor. Otherwise, None.
+  """
+
+  # Must be consistent with C++ FieldDescriptor::Type enum in
+  # descriptor.h.
+  #
+  # TODO(robinson): Find a way to eliminate this repetition.
+  TYPE_DOUBLE         = 1
+  TYPE_FLOAT          = 2
+  TYPE_INT64          = 3
+  TYPE_UINT64         = 4
+  TYPE_INT32          = 5
+  TYPE_FIXED64        = 6
+  TYPE_FIXED32        = 7
+  TYPE_BOOL           = 8
+  TYPE_STRING         = 9
+  TYPE_GROUP          = 10
+  TYPE_MESSAGE        = 11
+  TYPE_BYTES          = 12
+  TYPE_UINT32         = 13
+  TYPE_ENUM           = 14
+  TYPE_SFIXED32       = 15
+  TYPE_SFIXED64       = 16
+  TYPE_SINT32         = 17
+  TYPE_SINT64         = 18
+  MAX_TYPE            = 18
+
+  # Must be consistent with C++ FieldDescriptor::CppType enum in
+  # descriptor.h.
+  #
+  # TODO(robinson): Find a way to eliminate this repetition.
+  CPPTYPE_INT32       = 1
+  CPPTYPE_INT64       = 2
+  CPPTYPE_UINT32      = 3
+  CPPTYPE_UINT64      = 4
+  CPPTYPE_DOUBLE      = 5
+  CPPTYPE_FLOAT       = 6
+  CPPTYPE_BOOL        = 7
+  CPPTYPE_ENUM        = 8
+  CPPTYPE_STRING      = 9
+  CPPTYPE_MESSAGE     = 10
+  MAX_CPPTYPE         = 10
+
+  _PYTHON_TO_CPP_PROTO_TYPE_MAP = {
+      TYPE_DOUBLE: CPPTYPE_DOUBLE,
+      TYPE_FLOAT: CPPTYPE_FLOAT,
+      TYPE_ENUM: CPPTYPE_ENUM,
+      TYPE_INT64: CPPTYPE_INT64,
+      TYPE_SINT64: CPPTYPE_INT64,
+      TYPE_SFIXED64: CPPTYPE_INT64,
+      TYPE_UINT64: CPPTYPE_UINT64,
+      TYPE_FIXED64: CPPTYPE_UINT64,
+      TYPE_INT32: CPPTYPE_INT32,
+      TYPE_SFIXED32: CPPTYPE_INT32,
+      TYPE_SINT32: CPPTYPE_INT32,
+      TYPE_UINT32: CPPTYPE_UINT32,
+      TYPE_FIXED32: CPPTYPE_UINT32,
+      TYPE_BYTES: CPPTYPE_STRING,
+      TYPE_STRING: CPPTYPE_STRING,
+      TYPE_BOOL: CPPTYPE_BOOL,
+      TYPE_MESSAGE: CPPTYPE_MESSAGE,
+      TYPE_GROUP: CPPTYPE_MESSAGE
+      }
+
+  # Must be consistent with C++ FieldDescriptor::Label enum in
+  # descriptor.h.
+  #
+  # TODO(robinson): Find a way to eliminate this repetition.
+  LABEL_OPTIONAL      = 1
+  LABEL_REQUIRED      = 2
+  LABEL_REPEATED      = 3
+  MAX_LABEL           = 3
+
+  # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber,
+  # and kLastReservedNumber in descriptor.h
+  MAX_FIELD_NUMBER = (1 << 29) - 1
+  FIRST_RESERVED_FIELD_NUMBER = 19000
+  LAST_RESERVED_FIELD_NUMBER = 19999
+
+  def __init__(self, name, full_name, index, number, type, cpp_type, label,
+               default_value, message_type, enum_type, containing_type,
+               is_extension, extension_scope, options=None,
+               has_default_value=True, containing_oneof=None):
+    """The arguments are as described in the description of FieldDescriptor
+    attributes above.
+
+    Note that containing_type may be None, and may be set later if necessary
+    (to deal with circular references between message types, for example).
+    Likewise for extension_scope.
+    """
+    super(FieldDescriptor, self).__init__(options, 'FieldOptions')
+    self.name = name
+    self.full_name = full_name
+    self.index = index
+    self.number = number
+    self.type = type
+    self.cpp_type = cpp_type
+    self.label = label
+    self.has_default_value = has_default_value
+    self.default_value = default_value
+    self.containing_type = containing_type
+    self.message_type = message_type
+    self.enum_type = enum_type
+    self.is_extension = is_extension
+    self.extension_scope = extension_scope
+    self.containing_oneof = containing_oneof
+    if api_implementation.Type() == 'cpp':
+      if is_extension:
+        if api_implementation.Version() == 2:
+          # pylint: disable=protected-access
+          self._cdescriptor = (
+              _message.Message._GetExtensionDescriptor(full_name))
+          # pylint: enable=protected-access
+        else:
+          self._cdescriptor = cpp_message.GetExtensionDescriptor(full_name)
+      else:
+        if api_implementation.Version() == 2:
+          # pylint: disable=protected-access
+          self._cdescriptor = _message.Message._GetFieldDescriptor(full_name)
+          # pylint: enable=protected-access
+        else:
+          self._cdescriptor = cpp_message.GetFieldDescriptor(full_name)
+    else:
+      self._cdescriptor = None
+
+  @staticmethod
+  def ProtoTypeToCppProtoType(proto_type):
+    """Converts from a Python proto type to a C++ Proto Type.
+
+    The Python ProtocolBuffer classes specify both the 'Python' datatype and the
+    'C++' datatype - and they're not the same. This helper method should
+    translate from one to another.
+
+    Args:
+      proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*)
+    Returns:
+      descriptor.FieldDescriptor.CPPTYPE_*, the C++ type.
+    Raises:
+      TypeTransformationError: when the Python proto type isn't known.
+    """
+    try:
+      return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type]
+    except KeyError:
+      raise TypeTransformationError('Unknown proto_type: %s' % proto_type)
+
+
+class EnumDescriptor(_NestedDescriptorBase):
+
+  """Descriptor for an enum defined in a .proto file.
+
+  An EnumDescriptor instance has the following attributes:
+
+    name: (str) Name of the enum type.
+    full_name: (str) Full name of the type, including package name
+      and any enclosing type(s).
+
+    values: (list of EnumValueDescriptors) List of the values
+      in this enum.
+    values_by_name: (dict str -> EnumValueDescriptor) Same as |values|,
+      but indexed by the "name" field of each EnumValueDescriptor.
+    values_by_number: (dict int -> EnumValueDescriptor) Same as |values|,
+      but indexed by the "number" field of each EnumValueDescriptor.
+    containing_type: (Descriptor) Descriptor of the immediate containing
+      type of this enum, or None if this is an enum defined at the
+      top level in a .proto file.  Set by Descriptor's constructor
+      if we're passed into one.
+    file: (FileDescriptor) Reference to file descriptor.
+    options: (descriptor_pb2.EnumOptions) Enum options message or
+      None to use default enum options.
+  """
+
+  def __init__(self, name, full_name, filename, values,
+               containing_type=None, options=None, file=None,
+               serialized_start=None, serialized_end=None):
+    """Arguments are as described in the attribute description above.
+
+    Note that filename is an obsolete argument, that is not used anymore.
+    Please use file.name to access this as an attribute.
+    """
+    super(EnumDescriptor, self).__init__(
+        options, 'EnumOptions', name, full_name, file,
+        containing_type, serialized_start=serialized_start,
+        serialized_end=serialized_end)
+
+    self.values = values
+    for value in self.values:
+      value.type = self
+    self.values_by_name = dict((v.name, v) for v in values)
+    self.values_by_number = dict((v.number, v) for v in values)
+
+  def CopyToProto(self, proto):
+    """Copies this to a descriptor_pb2.EnumDescriptorProto.
+
+    Args:
+      proto: An empty descriptor_pb2.EnumDescriptorProto.
+    """
+    # This function is overriden to give a better doc comment.
+    super(EnumDescriptor, self).CopyToProto(proto)
+
+
+class EnumValueDescriptor(DescriptorBase):
+
+  """Descriptor for a single value within an enum.
+
+    name: (str) Name of this value.
+    index: (int) Dense, 0-indexed index giving the order that this
+      value appears textually within its enum in the .proto file.
+    number: (int) Actual number assigned to this enum value.
+    type: (EnumDescriptor) EnumDescriptor to which this value
+      belongs.  Set by EnumDescriptor's constructor if we're
+      passed into one.
+    options: (descriptor_pb2.EnumValueOptions) Enum value options message or
+      None to use default enum value options options.
+  """
+
+  def __init__(self, name, index, number, type=None, options=None):
+    """Arguments are as described in the attribute description above."""
+    super(EnumValueDescriptor, self).__init__(options, 'EnumValueOptions')
+    self.name = name
+    self.index = index
+    self.number = number
+    self.type = type
+
+
+class OneofDescriptor(object):
+  """Descriptor for a oneof field.
+
+    name: (str) Name of the oneof field.
+    full_name: (str) Full name of the oneof field, including package name.
+    index: (int) 0-based index giving the order of the oneof field inside
+      its containing type.
+    containing_type: (Descriptor) Descriptor of the protocol message
+      type that contains this field.  Set by the Descriptor constructor
+      if we're passed into one.
+    fields: (list of FieldDescriptor) The list of field descriptors this
+      oneof can contain.
+  """
+
+  def __init__(self, name, full_name, index, containing_type, fields):
+    """Arguments are as described in the attribute description above."""
+    self.name = name
+    self.full_name = full_name
+    self.index = index
+    self.containing_type = containing_type
+    self.fields = fields
+
+
+class ServiceDescriptor(_NestedDescriptorBase):
+
+  """Descriptor for a service.
+
+    name: (str) Name of the service.
+    full_name: (str) Full name of the service, including package name.
+    index: (int) 0-indexed index giving the order that this services
+      definition appears withing the .proto file.
+    methods: (list of MethodDescriptor) List of methods provided by this
+      service.
+    options: (descriptor_pb2.ServiceOptions) Service options message or
+      None to use default service options.
+    file: (FileDescriptor) Reference to file info.
+  """
+
+  def __init__(self, name, full_name, index, methods, options=None, file=None,
+               serialized_start=None, serialized_end=None):
+    super(ServiceDescriptor, self).__init__(
+        options, 'ServiceOptions', name, full_name, file,
+        None, serialized_start=serialized_start,
+        serialized_end=serialized_end)
+    self.index = index
+    self.methods = methods
+    # Set the containing service for each method in this service.
+    for method in self.methods:
+      method.containing_service = self
+
+  def FindMethodByName(self, name):
+    """Searches for the specified method, and returns its descriptor."""
+    for method in self.methods:
+      if name == method.name:
+        return method
+    return None
+
+  def CopyToProto(self, proto):
+    """Copies this to a descriptor_pb2.ServiceDescriptorProto.
+
+    Args:
+      proto: An empty descriptor_pb2.ServiceDescriptorProto.
+    """
+    # This function is overriden to give a better doc comment.
+    super(ServiceDescriptor, self).CopyToProto(proto)
+
+
+class MethodDescriptor(DescriptorBase):
+
+  """Descriptor for a method in a service.
+
+  name: (str) Name of the method within the service.
+  full_name: (str) Full name of method.
+  index: (int) 0-indexed index of the method inside the service.
+  containing_service: (ServiceDescriptor) The service that contains this
+    method.
+  input_type: The descriptor of the message that this method accepts.
+  output_type: The descriptor of the message that this method returns.
+  options: (descriptor_pb2.MethodOptions) Method options message or
+    None to use default method options.
+  """
+
+  def __init__(self, name, full_name, index, containing_service,
+               input_type, output_type, options=None):
+    """The arguments are as described in the description of MethodDescriptor
+    attributes above.
+
+    Note that containing_service may be None, and may be set later if necessary.
+    """
+    super(MethodDescriptor, self).__init__(options, 'MethodOptions')
+    self.name = name
+    self.full_name = full_name
+    self.index = index
+    self.containing_service = containing_service
+    self.input_type = input_type
+    self.output_type = output_type
+
+
+class FileDescriptor(DescriptorBase):
+  """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto.
+
+  Note that enum_types_by_name, extensions_by_name, and dependencies
+  fields are only set by the message_factory module, and not by the
+  generated proto code.
+
+  name: name of file, relative to root of source tree.
+  package: name of the package
+  serialized_pb: (str) Byte string of serialized
+    descriptor_pb2.FileDescriptorProto.
+  dependencies: List of other FileDescriptors this FileDescriptor depends on.
+  message_types_by_name: Dict of message names of their descriptors.
+  enum_types_by_name: Dict of enum names and their descriptors.
+  extensions_by_name: Dict of extension names and their descriptors.
+  """
+
+  def __init__(self, name, package, options=None, serialized_pb=None,
+               dependencies=None):
+    """Constructor."""
+    super(FileDescriptor, self).__init__(options, 'FileOptions')
+
+    self.message_types_by_name = {}
+    self.name = name
+    self.package = package
+    self.serialized_pb = serialized_pb
+
+    self.enum_types_by_name = {}
+    self.extensions_by_name = {}
+    self.dependencies = (dependencies or [])
+
+    if (api_implementation.Type() == 'cpp' and
+        self.serialized_pb is not None):
+      if api_implementation.Version() == 2:
+        # pylint: disable=protected-access
+        _message.Message._BuildFile(self.serialized_pb)
+        # pylint: enable=protected-access
+      else:
+        cpp_message.BuildFile(self.serialized_pb)
+
+  def CopyToProto(self, proto):
+    """Copies this to a descriptor_pb2.FileDescriptorProto.
+
+    Args:
+      proto: An empty descriptor_pb2.FileDescriptorProto.
+    """
+    proto.ParseFromString(self.serialized_pb)
+
+
+def _ParseOptions(message, string):
+  """Parses serialized options.
+
+  This helper function is used to parse serialized options in generated
+  proto2 files. It must not be used outside proto2.
+  """
+  message.ParseFromString(string)
+  return message
+
+
+def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True):
+  """Make a protobuf Descriptor given a DescriptorProto protobuf.
+
+  Handles nested descriptors. Note that this is limited to the scope of defining
+  a message inside of another message. Composite fields can currently only be
+  resolved if the message is defined in the same scope as the field.
+
+  Args:
+    desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
+    package: Optional package name for the new message Descriptor (string).
+    build_file_if_cpp: Update the C++ descriptor pool if api matches.
+                       Set to False on recursion, so no duplicates are created.
+  Returns:
+    A Descriptor for protobuf messages.
+  """
+  if api_implementation.Type() == 'cpp' and build_file_if_cpp:
+    # The C++ implementation requires all descriptors to be backed by the same
+    # definition in the C++ descriptor pool. To do this, we build a
+    # FileDescriptorProto with the same definition as this descriptor and build
+    # it into the pool.
+    from google.protobuf import descriptor_pb2
+    file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+    file_descriptor_proto.message_type.add().MergeFrom(desc_proto)
+
+    # Generate a random name for this proto file to prevent conflicts with
+    # any imported ones. We need to specify a file name so BuildFile accepts
+    # our FileDescriptorProto, but it is not important what that file name
+    # is actually set to.
+    proto_name = str(uuid.uuid4())
+
+    if package:
+      file_descriptor_proto.name = os.path.join(package.replace('.', '/'),
+                                                proto_name + '.proto')
+      file_descriptor_proto.package = package
+    else:
+      file_descriptor_proto.name = proto_name + '.proto'
+
+    if api_implementation.Version() == 2:
+      # pylint: disable=protected-access
+      _message.Message._BuildFile(file_descriptor_proto.SerializeToString())
+      # pylint: enable=protected-access
+    else:
+      cpp_message.BuildFile(file_descriptor_proto.SerializeToString())
+
+  full_message_name = [desc_proto.name]
+  if package: full_message_name.insert(0, package)
+
+  # Create Descriptors for enum types
+  enum_types = {}
+  for enum_proto in desc_proto.enum_type:
+    full_name = '.'.join(full_message_name + [enum_proto.name])
+    enum_desc = EnumDescriptor(
+      enum_proto.name, full_name, None, [
+          EnumValueDescriptor(enum_val.name, ii, enum_val.number)
+          for ii, enum_val in enumerate(enum_proto.value)])
+    enum_types[full_name] = enum_desc
+
+  # Create Descriptors for nested types
+  nested_types = {}
+  for nested_proto in desc_proto.nested_type:
+    full_name = '.'.join(full_message_name + [nested_proto.name])
+    # Nested types are just those defined inside of the message, not all types
+    # used by fields in the message, so no loops are possible here.
+    nested_desc = MakeDescriptor(nested_proto,
+                                 package='.'.join(full_message_name),
+                                 build_file_if_cpp=False)
+    nested_types[full_name] = nested_desc
+
+  fields = []
+  for field_proto in desc_proto.field:
+    full_name = '.'.join(full_message_name + [field_proto.name])
+    enum_desc = None
+    nested_desc = None
+    if field_proto.HasField('type_name'):
+      type_name = field_proto.type_name
+      full_type_name = '.'.join(full_message_name +
+                                [type_name[type_name.rfind('.')+1:]])
+      if full_type_name in nested_types:
+        nested_desc = nested_types[full_type_name]
+      elif full_type_name in enum_types:
+        enum_desc = enum_types[full_type_name]
+      # Else type_name references a non-local type, which isn't implemented
+    field = FieldDescriptor(
+        field_proto.name, full_name, field_proto.number - 1,
+        field_proto.number, field_proto.type,
+        FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type),
+        field_proto.label, None, nested_desc, enum_desc, None, False, None,
+        has_default_value=False)
+    fields.append(field)
+
+  desc_name = '.'.join(full_message_name)
+  return Descriptor(desc_proto.name, desc_name, None, None, fields,
+                    nested_types.values(), enum_types.values(), [])
diff --git a/protobuf/python/google/protobuf/descriptor_database.py b/protobuf/python/google/protobuf/descriptor_database.py
new file mode 100644
index 0000000..55fb8c7
--- /dev/null
+++ b/protobuf/python/google/protobuf/descriptor_database.py
@@ -0,0 +1,137 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Provides a container for DescriptorProtos."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+
+class Error(Exception):
+  pass
+
+
+class DescriptorDatabaseConflictingDefinitionError(Error):
+  """Raised when a proto is added with the same name & different descriptor."""
+
+
+class DescriptorDatabase(object):
+  """A container accepting FileDescriptorProtos and maps DescriptorProtos."""
+
+  def __init__(self):
+    self._file_desc_protos_by_file = {}
+    self._file_desc_protos_by_symbol = {}
+
+  def Add(self, file_desc_proto):
+    """Adds the FileDescriptorProto and its types to this database.
+
+    Args:
+      file_desc_proto: The FileDescriptorProto to add.
+    Raises:
+      DescriptorDatabaseException: if an attempt is made to add a proto
+        with the same name but different definition than an exisiting
+        proto in the database.
+    """
+    proto_name = file_desc_proto.name
+    if proto_name not in self._file_desc_protos_by_file:
+      self._file_desc_protos_by_file[proto_name] = file_desc_proto
+    elif self._file_desc_protos_by_file[proto_name] != file_desc_proto:
+      raise DescriptorDatabaseConflictingDefinitionError(
+          '%s already added, but with different descriptor.' % proto_name)
+
+    package = file_desc_proto.package
+    for message in file_desc_proto.message_type:
+      self._file_desc_protos_by_symbol.update(
+          (name, file_desc_proto) for name in _ExtractSymbols(message, package))
+    for enum in file_desc_proto.enum_type:
+      self._file_desc_protos_by_symbol[
+          '.'.join((package, enum.name))] = file_desc_proto
+
+  def FindFileByName(self, name):
+    """Finds the file descriptor proto by file name.
+
+    Typically the file name is a relative path ending to a .proto file. The
+    proto with the given name will have to have been added to this database
+    using the Add method or else an error will be raised.
+
+    Args:
+      name: The file name to find.
+
+    Returns:
+      The file descriptor proto matching the name.
+
+    Raises:
+      KeyError if no file by the given name was added.
+    """
+
+    return self._file_desc_protos_by_file[name]
+
+  def FindFileContainingSymbol(self, symbol):
+    """Finds the file descriptor proto containing the specified symbol.
+
+    The symbol should be a fully qualified name including the file descriptor's
+    package and any containing messages. Some examples:
+
+    'some.package.name.Message'
+    'some.package.name.Message.NestedEnum'
+
+    The file descriptor proto containing the specified symbol must be added to
+    this database using the Add method or else an error will be raised.
+
+    Args:
+      symbol: The fully qualified symbol name.
+
+    Returns:
+      The file descriptor proto containing the symbol.
+
+    Raises:
+      KeyError if no file contains the specified symbol.
+    """
+
+    return self._file_desc_protos_by_symbol[symbol]
+
+
+def _ExtractSymbols(desc_proto, package):
+  """Pulls out all the symbols from a descriptor proto.
+
+  Args:
+    desc_proto: The proto to extract symbols from.
+    package: The package containing the descriptor type.
+
+  Yields:
+    The fully qualified name found in the descriptor.
+  """
+
+  message_name = '.'.join((package, desc_proto.name))
+  yield message_name
+  for nested_type in desc_proto.nested_type:
+    for symbol in _ExtractSymbols(nested_type, message_name):
+      yield symbol
+    for enum_type in desc_proto.enum_type:
+      yield '.'.join((message_name, enum_type.name))
diff --git a/protobuf/python/google/protobuf/descriptor_pool.py b/protobuf/python/google/protobuf/descriptor_pool.py
new file mode 100644
index 0000000..cf234cf
--- /dev/null
+++ b/protobuf/python/google/protobuf/descriptor_pool.py
@@ -0,0 +1,643 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Provides DescriptorPool to use as a container for proto2 descriptors.
+
+The DescriptorPool is used in conjection with a DescriptorDatabase to maintain
+a collection of protocol buffer descriptors for use when dynamically creating
+message types at runtime.
+
+For most applications protocol buffers should be used via modules generated by
+the protocol buffer compiler tool. This should only be used when the type of
+protocol buffers used in an application or library cannot be predetermined.
+
+Below is a straightforward example on how to use this class:
+
+  pool = DescriptorPool()
+  file_descriptor_protos = [ ... ]
+  for file_descriptor_proto in file_descriptor_protos:
+    pool.Add(file_descriptor_proto)
+  my_message_descriptor = pool.FindMessageTypeByName('some.package.MessageType')
+
+The message descriptor can be used in conjunction with the message_factory
+module in order to create a protocol buffer class that can be encoded and
+decoded.
+
+If you want to get a Python class for the specified proto, use the
+helper functions inside google.protobuf.message_factory
+directly instead of this class.
+"""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+import sys
+
+from google.protobuf import descriptor
+from google.protobuf import descriptor_database
+from google.protobuf import text_encoding
+
+
+def _NormalizeFullyQualifiedName(name):
+  """Remove leading period from fully-qualified type name.
+
+  Due to b/13860351 in descriptor_database.py, types in the root namespace are
+  generated with a leading period. This function removes that prefix.
+
+  Args:
+    name: A str, the fully-qualified symbol name.
+
+  Returns:
+    A str, the normalized fully-qualified symbol name.
+  """
+  return name.lstrip('.')
+
+
+class DescriptorPool(object):
+  """A collection of protobufs dynamically constructed by descriptor protos."""
+
+  def __init__(self, descriptor_db=None):
+    """Initializes a Pool of proto buffs.
+
+    The descriptor_db argument to the constructor is provided to allow
+    specialized file descriptor proto lookup code to be triggered on demand. An
+    example would be an implementation which will read and compile a file
+    specified in a call to FindFileByName() and not require the call to Add()
+    at all. Results from this database will be cached internally here as well.
+
+    Args:
+      descriptor_db: A secondary source of file descriptors.
+    """
+
+    self._internal_db = descriptor_database.DescriptorDatabase()
+    self._descriptor_db = descriptor_db
+    self._descriptors = {}
+    self._enum_descriptors = {}
+    self._file_descriptors = {}
+
+  def Add(self, file_desc_proto):
+    """Adds the FileDescriptorProto and its types to this pool.
+
+    Args:
+      file_desc_proto: The FileDescriptorProto to add.
+    """
+
+    self._internal_db.Add(file_desc_proto)
+
+  def AddDescriptor(self, desc):
+    """Adds a Descriptor to the pool, non-recursively.
+
+    If the Descriptor contains nested messages or enums, the caller must
+    explicitly register them. This method also registers the FileDescriptor
+    associated with the message.
+
+    Args:
+      desc: A Descriptor.
+    """
+    if not isinstance(desc, descriptor.Descriptor):
+      raise TypeError('Expected instance of descriptor.Descriptor.')
+
+    self._descriptors[desc.full_name] = desc
+    self.AddFileDescriptor(desc.file)
+
+  def AddEnumDescriptor(self, enum_desc):
+    """Adds an EnumDescriptor to the pool.
+
+    This method also registers the FileDescriptor associated with the message.
+
+    Args:
+      enum_desc: An EnumDescriptor.
+    """
+
+    if not isinstance(enum_desc, descriptor.EnumDescriptor):
+      raise TypeError('Expected instance of descriptor.EnumDescriptor.')
+
+    self._enum_descriptors[enum_desc.full_name] = enum_desc
+    self.AddFileDescriptor(enum_desc.file)
+
+  def AddFileDescriptor(self, file_desc):
+    """Adds a FileDescriptor to the pool, non-recursively.
+
+    If the FileDescriptor contains messages or enums, the caller must explicitly
+    register them.
+
+    Args:
+      file_desc: A FileDescriptor.
+    """
+
+    if not isinstance(file_desc, descriptor.FileDescriptor):
+      raise TypeError('Expected instance of descriptor.FileDescriptor.')
+    self._file_descriptors[file_desc.name] = file_desc
+
+  def FindFileByName(self, file_name):
+    """Gets a FileDescriptor by file name.
+
+    Args:
+      file_name: The path to the file to get a descriptor for.
+
+    Returns:
+      A FileDescriptor for the named file.
+
+    Raises:
+      KeyError: if the file can not be found in the pool.
+    """
+
+    try:
+      return self._file_descriptors[file_name]
+    except KeyError:
+      pass
+
+    try:
+      file_proto = self._internal_db.FindFileByName(file_name)
+    except KeyError:
+      _, error, _ = sys.exc_info()  #PY25 compatible for GAE.
+      if self._descriptor_db:
+        file_proto = self._descriptor_db.FindFileByName(file_name)
+      else:
+        raise error
+    if not file_proto:
+      raise KeyError('Cannot find a file named %s' % file_name)
+    return self._ConvertFileProtoToFileDescriptor(file_proto)
+
+  def FindFileContainingSymbol(self, symbol):
+    """Gets the FileDescriptor for the file containing the specified symbol.
+
+    Args:
+      symbol: The name of the symbol to search for.
+
+    Returns:
+      A FileDescriptor that contains the specified symbol.
+
+    Raises:
+      KeyError: if the file can not be found in the pool.
+    """
+
+    symbol = _NormalizeFullyQualifiedName(symbol)
+    try:
+      return self._descriptors[symbol].file
+    except KeyError:
+      pass
+
+    try:
+      return self._enum_descriptors[symbol].file
+    except KeyError:
+      pass
+
+    try:
+      file_proto = self._internal_db.FindFileContainingSymbol(symbol)
+    except KeyError:
+      _, error, _ = sys.exc_info()  #PY25 compatible for GAE.
+      if self._descriptor_db:
+        file_proto = self._descriptor_db.FindFileContainingSymbol(symbol)
+      else:
+        raise error
+    if not file_proto:
+      raise KeyError('Cannot find a file containing %s' % symbol)
+    return self._ConvertFileProtoToFileDescriptor(file_proto)
+
+  def FindMessageTypeByName(self, full_name):
+    """Loads the named descriptor from the pool.
+
+    Args:
+      full_name: The full name of the descriptor to load.
+
+    Returns:
+      The descriptor for the named type.
+    """
+
+    full_name = _NormalizeFullyQualifiedName(full_name)
+    if full_name not in self._descriptors:
+      self.FindFileContainingSymbol(full_name)
+    return self._descriptors[full_name]
+
+  def FindEnumTypeByName(self, full_name):
+    """Loads the named enum descriptor from the pool.
+
+    Args:
+      full_name: The full name of the enum descriptor to load.
+
+    Returns:
+      The enum descriptor for the named type.
+    """
+
+    full_name = _NormalizeFullyQualifiedName(full_name)
+    if full_name not in self._enum_descriptors:
+      self.FindFileContainingSymbol(full_name)
+    return self._enum_descriptors[full_name]
+
+  def _ConvertFileProtoToFileDescriptor(self, file_proto):
+    """Creates a FileDescriptor from a proto or returns a cached copy.
+
+    This method also has the side effect of loading all the symbols found in
+    the file into the appropriate dictionaries in the pool.
+
+    Args:
+      file_proto: The proto to convert.
+
+    Returns:
+      A FileDescriptor matching the passed in proto.
+    """
+
+    if file_proto.name not in self._file_descriptors:
+      built_deps = list(self._GetDeps(file_proto.dependency))
+      direct_deps = [self.FindFileByName(n) for n in file_proto.dependency]
+
+      file_descriptor = descriptor.FileDescriptor(
+          name=file_proto.name,
+          package=file_proto.package,
+          options=file_proto.options,
+          serialized_pb=file_proto.SerializeToString(),
+          dependencies=direct_deps)
+      scope = {}
+
+      # This loop extracts all the message and enum types from all the
+      # dependencoes of the file_proto. This is necessary to create the
+      # scope of available message types when defining the passed in
+      # file proto.
+      for dependency in built_deps:
+        scope.update(self._ExtractSymbols(
+            dependency.message_types_by_name.values()))
+        scope.update((_PrefixWithDot(enum.full_name), enum)
+                     for enum in dependency.enum_types_by_name.values())
+
+      for message_type in file_proto.message_type:
+        message_desc = self._ConvertMessageDescriptor(
+            message_type, file_proto.package, file_descriptor, scope)
+        file_descriptor.message_types_by_name[message_desc.name] = message_desc
+
+      for enum_type in file_proto.enum_type:
+        file_descriptor.enum_types_by_name[enum_type.name] = (
+            self._ConvertEnumDescriptor(enum_type, file_proto.package,
+                                        file_descriptor, None, scope))
+
+      for index, extension_proto in enumerate(file_proto.extension):
+        extension_desc = self.MakeFieldDescriptor(
+            extension_proto, file_proto.package, index, is_extension=True)
+        extension_desc.containing_type = self._GetTypeFromScope(
+            file_descriptor.package, extension_proto.extendee, scope)
+        self.SetFieldType(extension_proto, extension_desc,
+                          file_descriptor.package, scope)
+        file_descriptor.extensions_by_name[extension_desc.name] = extension_desc
+
+      for desc_proto in file_proto.message_type:
+        self.SetAllFieldTypes(file_proto.package, desc_proto, scope)
+
+      if file_proto.package:
+        desc_proto_prefix = _PrefixWithDot(file_proto.package)
+      else:
+        desc_proto_prefix = ''
+
+      for desc_proto in file_proto.message_type:
+        desc = self._GetTypeFromScope(desc_proto_prefix, desc_proto.name, scope)
+        file_descriptor.message_types_by_name[desc_proto.name] = desc
+      self.Add(file_proto)
+      self._file_descriptors[file_proto.name] = file_descriptor
+
+    return self._file_descriptors[file_proto.name]
+
+  def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None,
+                                scope=None):
+    """Adds the proto to the pool in the specified package.
+
+    Args:
+      desc_proto: The descriptor_pb2.DescriptorProto protobuf message.
+      package: The package the proto should be located in.
+      file_desc: The file containing this message.
+      scope: Dict mapping short and full symbols to message and enum types.
+
+    Returns:
+      The added descriptor.
+    """
+
+    if package:
+      desc_name = '.'.join((package, desc_proto.name))
+    else:
+      desc_name = desc_proto.name
+
+    if file_desc is None:
+      file_name = None
+    else:
+      file_name = file_desc.name
+
+    if scope is None:
+      scope = {}
+
+    nested = [
+        self._ConvertMessageDescriptor(nested, desc_name, file_desc, scope)
+        for nested in desc_proto.nested_type]
+    enums = [
+        self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope)
+        for enum in desc_proto.enum_type]
+    fields = [self.MakeFieldDescriptor(field, desc_name, index)
+              for index, field in enumerate(desc_proto.field)]
+    extensions = [
+        self.MakeFieldDescriptor(extension, desc_name, index, is_extension=True)
+        for index, extension in enumerate(desc_proto.extension)]
+    oneofs = [
+        descriptor.OneofDescriptor(desc.name, '.'.join((desc_name, desc.name)),
+                                   index, None, [])
+        for index, desc in enumerate(desc_proto.oneof_decl)]
+    extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range]
+    if extension_ranges:
+      is_extendable = True
+    else:
+      is_extendable = False
+    desc = descriptor.Descriptor(
+        name=desc_proto.name,
+        full_name=desc_name,
+        filename=file_name,
+        containing_type=None,
+        fields=fields,
+        oneofs=oneofs,
+        nested_types=nested,
+        enum_types=enums,
+        extensions=extensions,
+        options=desc_proto.options,
+        is_extendable=is_extendable,
+        extension_ranges=extension_ranges,
+        file=file_desc,
+        serialized_start=None,
+        serialized_end=None)
+    for nested in desc.nested_types:
+      nested.containing_type = desc
+    for enum in desc.enum_types:
+      enum.containing_type = desc
+    for field_index, field_desc in enumerate(desc_proto.field):
+      if field_desc.HasField('oneof_index'):
+        oneof_index = field_desc.oneof_index
+        oneofs[oneof_index].fields.append(fields[field_index])
+        fields[field_index].containing_oneof = oneofs[oneof_index]
+
+    scope[_PrefixWithDot(desc_name)] = desc
+    self._descriptors[desc_name] = desc
+    return desc
+
+  def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None,
+                             containing_type=None, scope=None):
+    """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf.
+
+    Args:
+      enum_proto: The descriptor_pb2.EnumDescriptorProto protobuf message.
+      package: Optional package name for the new message EnumDescriptor.
+      file_desc: The file containing the enum descriptor.
+      containing_type: The type containing this enum.
+      scope: Scope containing available types.
+
+    Returns:
+      The added descriptor
+    """
+
+    if package:
+      enum_name = '.'.join((package, enum_proto.name))
+    else:
+      enum_name = enum_proto.name
+
+    if file_desc is None:
+      file_name = None
+    else:
+      file_name = file_desc.name
+
+    values = [self._MakeEnumValueDescriptor(value, index)
+              for index, value in enumerate(enum_proto.value)]
+    desc = descriptor.EnumDescriptor(name=enum_proto.name,
+                                     full_name=enum_name,
+                                     filename=file_name,
+                                     file=file_desc,
+                                     values=values,
+                                     containing_type=containing_type,
+                                     options=enum_proto.options)
+    scope['.%s' % enum_name] = desc
+    self._enum_descriptors[enum_name] = desc
+    return desc
+
+  def MakeFieldDescriptor(self, field_proto, message_name, index,
+                          is_extension=False):
+    """Creates a field descriptor from a FieldDescriptorProto.
+
+    For message and enum type fields, this method will do a look up
+    in the pool for the appropriate descriptor for that type. If it
+    is unavailable, it will fall back to the _source function to
+    create it. If this type is still unavailable, construction will
+    fail.
+
+    Args:
+      field_proto: The proto describing the field.
+      message_name: The name of the containing message.
+      index: Index of the field
+      is_extension: Indication that this field is for an extension.
+
+    Returns:
+      An initialized FieldDescriptor object
+    """
+
+    if message_name:
+      full_name = '.'.join((message_name, field_proto.name))
+    else:
+      full_name = field_proto.name
+
+    return descriptor.FieldDescriptor(
+        name=field_proto.name,
+        full_name=full_name,
+        index=index,
+        number=field_proto.number,
+        type=field_proto.type,
+        cpp_type=None,
+        message_type=None,
+        enum_type=None,
+        containing_type=None,
+        label=field_proto.label,
+        has_default_value=False,
+        default_value=None,
+        is_extension=is_extension,
+        extension_scope=None,
+        options=field_proto.options)
+
+  def SetAllFieldTypes(self, package, desc_proto, scope):
+    """Sets all the descriptor's fields's types.
+
+    This method also sets the containing types on any extensions.
+
+    Args:
+      package: The current package of desc_proto.
+      desc_proto: The message descriptor to update.
+      scope: Enclosing scope of available types.
+    """
+
+    package = _PrefixWithDot(package)
+
+    main_desc = self._GetTypeFromScope(package, desc_proto.name, scope)
+
+    if package == '.':
+      nested_package = _PrefixWithDot(desc_proto.name)
+    else:
+      nested_package = '.'.join([package, desc_proto.name])
+
+    for field_proto, field_desc in zip(desc_proto.field, main_desc.fields):
+      self.SetFieldType(field_proto, field_desc, nested_package, scope)
+
+    for extension_proto, extension_desc in (
+        zip(desc_proto.extension, main_desc.extensions)):
+      extension_desc.containing_type = self._GetTypeFromScope(
+          nested_package, extension_proto.extendee, scope)
+      self.SetFieldType(extension_proto, extension_desc, nested_package, scope)
+
+    for nested_type in desc_proto.nested_type:
+      self.SetAllFieldTypes(nested_package, nested_type, scope)
+
+  def SetFieldType(self, field_proto, field_desc, package, scope):
+    """Sets the field's type, cpp_type, message_type and enum_type.
+
+    Args:
+      field_proto: Data about the field in proto format.
+      field_desc: The descriptor to modiy.
+      package: The package the field's container is in.
+      scope: Enclosing scope of available types.
+    """
+    if field_proto.type_name:
+      desc = self._GetTypeFromScope(package, field_proto.type_name, scope)
+    else:
+      desc = None
+
+    if not field_proto.HasField('type'):
+      if isinstance(desc, descriptor.Descriptor):
+        field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE
+      else:
+        field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM
+
+    field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType(
+        field_proto.type)
+
+    if (field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE
+        or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP):
+      field_desc.message_type = desc
+
+    if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
+      field_desc.enum_type = desc
+
+    if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+      field_desc.has_default_value = False
+      field_desc.default_value = []
+    elif field_proto.HasField('default_value'):
+      field_desc.has_default_value = True
+      if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or
+          field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT):
+        field_desc.default_value = float(field_proto.default_value)
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING:
+        field_desc.default_value = field_proto.default_value
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL:
+        field_desc.default_value = field_proto.default_value.lower() == 'true'
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM:
+        field_desc.default_value = field_desc.enum_type.values_by_name[
+            field_proto.default_value].index
+      elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES:
+        field_desc.default_value = text_encoding.CUnescape(
+            field_proto.default_value)
+      else:
+        field_desc.default_value = int(field_proto.default_value)
+    else:
+      field_desc.has_default_value = False
+      field_desc.default_value = None
+
+    field_desc.type = field_proto.type
+
+  def _MakeEnumValueDescriptor(self, value_proto, index):
+    """Creates a enum value descriptor object from a enum value proto.
+
+    Args:
+      value_proto: The proto describing the enum value.
+      index: The index of the enum value.
+
+    Returns:
+      An initialized EnumValueDescriptor object.
+    """
+
+    return descriptor.EnumValueDescriptor(
+        name=value_proto.name,
+        index=index,
+        number=value_proto.number,
+        options=value_proto.options,
+        type=None)
+
+  def _ExtractSymbols(self, descriptors):
+    """Pulls out all the symbols from descriptor protos.
+
+    Args:
+      descriptors: The messages to extract descriptors from.
+    Yields:
+      A two element tuple of the type name and descriptor object.
+    """
+
+    for desc in descriptors:
+      yield (_PrefixWithDot(desc.full_name), desc)
+      for symbol in self._ExtractSymbols(desc.nested_types):
+        yield symbol
+      for enum in desc.enum_types:
+        yield (_PrefixWithDot(enum.full_name), enum)
+
+  def _GetDeps(self, dependencies):
+    """Recursively finds dependencies for file protos.
+
+    Args:
+      dependencies: The names of the files being depended on.
+
+    Yields:
+      Each direct and indirect dependency.
+    """
+
+    for dependency in dependencies:
+      dep_desc = self.FindFileByName(dependency)
+      yield dep_desc
+      for parent_dep in dep_desc.dependencies:
+        yield parent_dep
+
+  def _GetTypeFromScope(self, package, type_name, scope):
+    """Finds a given type name in the current scope.
+
+    Args:
+      package: The package the proto should be located in.
+      type_name: The name of the type to be found in the scope.
+      scope: Dict mapping short and full symbols to message and enum types.
+
+    Returns:
+      The descriptor for the requested type.
+    """
+    if type_name not in scope:
+      components = _PrefixWithDot(package).split('.')
+      while components:
+        possible_match = '.'.join(components + [type_name])
+        if possible_match in scope:
+          type_name = possible_match
+          break
+        else:
+          components.pop(-1)
+    return scope[type_name]
+
+
+def _PrefixWithDot(name):
+  return name if name.startswith('.') else '.%s' % name
diff --git a/protobuf/python/google/protobuf/internal/__init__.py b/protobuf/python/google/protobuf/internal/__init__.py
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/__init__.py
diff --git a/protobuf/python/google/protobuf/internal/api_implementation.cc b/protobuf/python/google/protobuf/internal/api_implementation.cc
new file mode 100644
index 0000000..83db40b
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/api_implementation.cc
@@ -0,0 +1,139 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <Python.h>
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+// Version constant.
+// This is either 0 for python, 1 for CPP V1, 2 for CPP V2.
+//
+// 0 is default and is equivalent to
+//   PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python
+//
+// 1 is set with -DPYTHON_PROTO2_CPP_IMPL_V1 and is equivalent to
+//   PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
+// and
+//   PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=1
+//
+// 2 is set with -DPYTHON_PROTO2_CPP_IMPL_V2 and is equivalent to
+//   PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
+// and
+//   PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=2
+#ifdef PYTHON_PROTO2_CPP_IMPL_V1
+#if PY_MAJOR_VERSION >= 3
+#error "PYTHON_PROTO2_CPP_IMPL_V1 is not supported under Python 3."
+#endif
+static int kImplVersion = 1;
+#else
+#ifdef PYTHON_PROTO2_CPP_IMPL_V2
+static int kImplVersion = 2;
+#else
+#ifdef PYTHON_PROTO2_PYTHON_IMPL
+static int kImplVersion = 0;
+#else
+
+// The defaults are set here.  Python 3 uses the fast C++ APIv2 by default.
+// Python 2 still uses the Python version by default until some compatibility
+// issues can be worked around.
+#if PY_MAJOR_VERSION >= 3
+static int kImplVersion = 2;
+#else
+static int kImplVersion = 0;
+#endif
+
+#endif  // PYTHON_PROTO2_PYTHON_IMPL
+#endif  // PYTHON_PROTO2_CPP_IMPL_V2
+#endif  // PYTHON_PROTO2_CPP_IMPL_V1
+
+static const char* kImplVersionName = "api_version";
+
+static const char* kModuleName = "_api_implementation";
+static const char kModuleDocstring[] =
+"_api_implementation is a module that exposes compile-time constants that\n"
+"determine the default API implementation to use for Python proto2.\n"
+"\n"
+"It complements api_implementation.py by setting defaults using compile-time\n"
+"constants defined in C, such that one can set defaults at compilation\n"
+"(e.g. with blaze flag --copt=-DPYTHON_PROTO2_CPP_IMPL_V2).";
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef _module = {
+  PyModuleDef_HEAD_INIT,
+  kModuleName,
+  kModuleDocstring,
+  -1,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL
+};
+#define INITFUNC PyInit__api_implementation
+#define INITFUNC_ERRORVAL NULL
+#else
+#define INITFUNC init_api_implementation
+#define INITFUNC_ERRORVAL
+#endif
+
+extern "C" {
+  PyMODINIT_FUNC INITFUNC() {
+#if PY_MAJOR_VERSION >= 3
+    PyObject *module = PyModule_Create(&_module);
+#else
+    PyObject *module = Py_InitModule3(
+        const_cast<char*>(kModuleName),
+        NULL,
+        const_cast<char*>(kModuleDocstring));
+#endif
+    if (module == NULL) {
+      return INITFUNC_ERRORVAL;
+    }
+
+    // Adds the module variable "api_version".
+    if (PyModule_AddIntConstant(
+        module,
+        const_cast<char*>(kImplVersionName),
+        kImplVersion))
+#if PY_MAJOR_VERSION < 3
+      return;
+#else
+      { Py_DECREF(module); return NULL; }
+
+    return module;
+#endif
+  }
+}
+
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/python/google/protobuf/internal/api_implementation.py b/protobuf/python/google/protobuf/internal/api_implementation.py
new file mode 100755
index 0000000..f7926c1
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/api_implementation.py
@@ -0,0 +1,89 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Determine which implementation of the protobuf API is used in this process.
+"""
+
+import os
+import sys
+
+try:
+  # pylint: disable=g-import-not-at-top
+  from google.protobuf.internal import _api_implementation
+  # The compile-time constants in the _api_implementation module can be used to
+  # switch to a certain implementation of the Python API at build time.
+  _api_version = _api_implementation.api_version
+  del _api_implementation
+except ImportError:
+  _api_version = 0
+
+_default_implementation_type = (
+    'python' if _api_version == 0 else 'cpp')
+_default_version_str = (
+    '1' if _api_version <= 1 else '2')
+
+# This environment variable can be used to switch to a certain implementation
+# of the Python API, overriding the compile-time constants in the
+# _api_implementation module. Right now only 'python' and 'cpp' are valid
+# values. Any other value will be ignored.
+_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION',
+                                 _default_implementation_type)
+
+if _implementation_type != 'python':
+  _implementation_type = 'cpp'
+
+# This environment variable can be used to switch between the two
+# 'cpp' implementations, overriding the compile-time constants in the
+# _api_implementation module. Right now only 1 and 2 are valid values. Any other
+# value will be ignored.
+_implementation_version_str = os.getenv(
+    'PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION',
+    _default_version_str)
+
+if _implementation_version_str not in ('1', '2'):
+  raise ValueError(
+      "unsupported PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION: '" +
+      _implementation_version_str + "' (supported versions: 1, 2)"
+      )
+
+_implementation_version = int(_implementation_version_str)
+
+
+# Usage of this function is discouraged. Clients shouldn't care which
+# implementation of the API is in use. Note that there is no guarantee
+# that differences between APIs will be maintained.
+# Please don't use this function if possible.
+def Type():
+  return _implementation_type
+
+
+# See comment on 'Type' above.
+def Version():
+  return _implementation_version
diff --git a/protobuf/python/google/protobuf/internal/api_implementation_default_test.py b/protobuf/python/google/protobuf/internal/api_implementation_default_test.py
new file mode 100644
index 0000000..78d5cf2
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/api_implementation_default_test.py
@@ -0,0 +1,63 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Test that the api_implementation defaults are what we expect."""
+
+import os
+import sys
+# Clear environment implementation settings before the google3 imports.
+os.environ.pop('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION', None)
+os.environ.pop('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION', None)
+
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+
+
+class ApiImplementationDefaultTest(basetest.TestCase):
+
+  if sys.version_info.major <= 2:
+
+    def testThatPythonIsTheDefault(self):
+      """If -DPYTHON_PROTO_*IMPL* was given at build time, this may fail."""
+      self.assertEqual('python', api_implementation.Type())
+
+  else:
+
+    def testThatCppApiV2IsTheDefault(self):
+      """If -DPYTHON_PROTO_*IMPL* was given at build time, this may fail."""
+      self.assertEqual('cpp', api_implementation.Type())
+      self.assertEqual(2, api_implementation.Version())
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/containers.py b/protobuf/python/google/protobuf/internal/containers.py
new file mode 100755
index 0000000..20bfa85
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/containers.py
@@ -0,0 +1,269 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains container classes to represent different protocol buffer types.
+
+This file defines container classes which represent categories of protocol
+buffer field types which need extra maintenance. Currently these categories
+are:
+  - Repeated scalar fields - These are all repeated fields which aren't
+    composite (e.g. they are of simple types like int32, string, etc).
+  - Repeated composite fields - Repeated fields which are composite. This
+    includes groups and nested messages.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+
+class BaseContainer(object):
+
+  """Base container class."""
+
+  # Minimizes memory usage and disallows assignment to other attributes.
+  __slots__ = ['_message_listener', '_values']
+
+  def __init__(self, message_listener):
+    """
+    Args:
+      message_listener: A MessageListener implementation.
+        The RepeatedScalarFieldContainer will call this object's
+        Modified() method when it is modified.
+    """
+    self._message_listener = message_listener
+    self._values = []
+
+  def __getitem__(self, key):
+    """Retrieves item by the specified key."""
+    return self._values[key]
+
+  def __len__(self):
+    """Returns the number of elements in the container."""
+    return len(self._values)
+
+  def __ne__(self, other):
+    """Checks if another instance isn't equal to this one."""
+    # The concrete classes should define __eq__.
+    return not self == other
+
+  def __hash__(self):
+    raise TypeError('unhashable object')
+
+  def __repr__(self):
+    return repr(self._values)
+
+  def sort(self, *args, **kwargs):
+    # Continue to support the old sort_function keyword argument.
+    # This is expected to be a rare occurrence, so use LBYL to avoid
+    # the overhead of actually catching KeyError.
+    if 'sort_function' in kwargs:
+      kwargs['cmp'] = kwargs.pop('sort_function')
+    self._values.sort(*args, **kwargs)
+
+
+class RepeatedScalarFieldContainer(BaseContainer):
+
+  """Simple, type-checked, list-like container for holding repeated scalars."""
+
+  # Disallows assignment to other attributes.
+  __slots__ = ['_type_checker']
+
+  def __init__(self, message_listener, type_checker):
+    """
+    Args:
+      message_listener: A MessageListener implementation.
+        The RepeatedScalarFieldContainer will call this object's
+        Modified() method when it is modified.
+      type_checker: A type_checkers.ValueChecker instance to run on elements
+        inserted into this container.
+    """
+    super(RepeatedScalarFieldContainer, self).__init__(message_listener)
+    self._type_checker = type_checker
+
+  def append(self, value):
+    """Appends an item to the list. Similar to list.append()."""
+    self._values.append(self._type_checker.CheckValue(value))
+    if not self._message_listener.dirty:
+      self._message_listener.Modified()
+
+  def insert(self, key, value):
+    """Inserts the item at the specified position. Similar to list.insert()."""
+    self._values.insert(key, self._type_checker.CheckValue(value))
+    if not self._message_listener.dirty:
+      self._message_listener.Modified()
+
+  def extend(self, elem_seq):
+    """Extends by appending the given sequence. Similar to list.extend()."""
+    if not elem_seq:
+      return
+
+    new_values = []
+    for elem in elem_seq:
+      new_values.append(self._type_checker.CheckValue(elem))
+    self._values.extend(new_values)
+    self._message_listener.Modified()
+
+  def MergeFrom(self, other):
+    """Appends the contents of another repeated field of the same type to this
+    one. We do not check the types of the individual fields.
+    """
+    self._values.extend(other._values)
+    self._message_listener.Modified()
+
+  def remove(self, elem):
+    """Removes an item from the list. Similar to list.remove()."""
+    self._values.remove(elem)
+    self._message_listener.Modified()
+
+  def __setitem__(self, key, value):
+    """Sets the item on the specified position."""
+    if isinstance(key, slice):  # PY3
+      if key.step is not None:
+        raise ValueError('Extended slices not supported')
+      self.__setslice__(key.start, key.stop, value)
+    else:
+      self._values[key] = self._type_checker.CheckValue(value)
+      self._message_listener.Modified()
+
+  def __getslice__(self, start, stop):
+    """Retrieves the subset of items from between the specified indices."""
+    return self._values[start:stop]
+
+  def __setslice__(self, start, stop, values):
+    """Sets the subset of items from between the specified indices."""
+    new_values = []
+    for value in values:
+      new_values.append(self._type_checker.CheckValue(value))
+    self._values[start:stop] = new_values
+    self._message_listener.Modified()
+
+  def __delitem__(self, key):
+    """Deletes the item at the specified position."""
+    del self._values[key]
+    self._message_listener.Modified()
+
+  def __delslice__(self, start, stop):
+    """Deletes the subset of items from between the specified indices."""
+    del self._values[start:stop]
+    self._message_listener.Modified()
+
+  def __eq__(self, other):
+    """Compares the current instance with another one."""
+    if self is other:
+      return True
+    # Special case for the same type which should be common and fast.
+    if isinstance(other, self.__class__):
+      return other._values == self._values
+    # We are presumably comparing against some other sequence type.
+    return other == self._values
+
+
+class RepeatedCompositeFieldContainer(BaseContainer):
+
+  """Simple, list-like container for holding repeated composite fields."""
+
+  # Disallows assignment to other attributes.
+  __slots__ = ['_message_descriptor']
+
+  def __init__(self, message_listener, message_descriptor):
+    """
+    Note that we pass in a descriptor instead of the generated directly,
+    since at the time we construct a _RepeatedCompositeFieldContainer we
+    haven't yet necessarily initialized the type that will be contained in the
+    container.
+
+    Args:
+      message_listener: A MessageListener implementation.
+        The RepeatedCompositeFieldContainer will call this object's
+        Modified() method when it is modified.
+      message_descriptor: A Descriptor instance describing the protocol type
+        that should be present in this container.  We'll use the
+        _concrete_class field of this descriptor when the client calls add().
+    """
+    super(RepeatedCompositeFieldContainer, self).__init__(message_listener)
+    self._message_descriptor = message_descriptor
+
+  def add(self, **kwargs):
+    """Adds a new element at the end of the list and returns it. Keyword
+    arguments may be used to initialize the element.
+    """
+    new_element = self._message_descriptor._concrete_class(**kwargs)
+    new_element._SetListener(self._message_listener)
+    self._values.append(new_element)
+    if not self._message_listener.dirty:
+      self._message_listener.Modified()
+    return new_element
+
+  def extend(self, elem_seq):
+    """Extends by appending the given sequence of elements of the same type
+    as this one, copying each individual message.
+    """
+    message_class = self._message_descriptor._concrete_class
+    listener = self._message_listener
+    values = self._values
+    for message in elem_seq:
+      new_element = message_class()
+      new_element._SetListener(listener)
+      new_element.MergeFrom(message)
+      values.append(new_element)
+    listener.Modified()
+
+  def MergeFrom(self, other):
+    """Appends the contents of another repeated field of the same type to this
+    one, copying each individual message.
+    """
+    self.extend(other._values)
+
+  def remove(self, elem):
+    """Removes an item from the list. Similar to list.remove()."""
+    self._values.remove(elem)
+    self._message_listener.Modified()
+
+  def __getslice__(self, start, stop):
+    """Retrieves the subset of items from between the specified indices."""
+    return self._values[start:stop]
+
+  def __delitem__(self, key):
+    """Deletes the item at the specified position."""
+    del self._values[key]
+    self._message_listener.Modified()
+
+  def __delslice__(self, start, stop):
+    """Deletes the subset of items from between the specified indices."""
+    del self._values[start:stop]
+    self._message_listener.Modified()
+
+  def __eq__(self, other):
+    """Compares the current instance with another one."""
+    if self is other:
+      return True
+    if not isinstance(other, self.__class__):
+      raise TypeError('Can only compare repeated composite fields against '
+                      'other repeated composite fields.')
+    return self._values == other._values
diff --git a/protobuf/python/google/protobuf/internal/cpp_message.py b/protobuf/python/google/protobuf/internal/cpp_message.py
new file mode 100755
index 0000000..0313cb0
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/cpp_message.py
@@ -0,0 +1,663 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains helper functions used to create protocol message classes from
+Descriptor objects at runtime backed by the protocol buffer C++ API.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+import copy_reg
+import operator
+from google.protobuf.internal import _net_proto2___python
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import message
+
+
+_LABEL_REPEATED = _net_proto2___python.LABEL_REPEATED
+_LABEL_OPTIONAL = _net_proto2___python.LABEL_OPTIONAL
+_CPPTYPE_MESSAGE = _net_proto2___python.CPPTYPE_MESSAGE
+_TYPE_MESSAGE = _net_proto2___python.TYPE_MESSAGE
+
+
+def GetDescriptorPool():
+  """Creates a new DescriptorPool C++ object."""
+  return _net_proto2___python.NewCDescriptorPool()
+
+
+_pool = GetDescriptorPool()
+
+
+def GetFieldDescriptor(full_field_name):
+  """Searches for a field descriptor given a full field name."""
+  return _pool.FindFieldByName(full_field_name)
+
+
+def BuildFile(content):
+  """Registers a new proto file in the underlying C++ descriptor pool."""
+  _net_proto2___python.BuildFile(content)
+
+
+def GetExtensionDescriptor(full_extension_name):
+  """Searches for extension descriptor given a full field name."""
+  return _pool.FindExtensionByName(full_extension_name)
+
+
+def NewCMessage(full_message_name):
+  """Creates a new C++ protocol message by its name."""
+  return _net_proto2___python.NewCMessage(full_message_name)
+
+
+def ScalarProperty(cdescriptor):
+  """Returns a scalar property for the given descriptor."""
+
+  def Getter(self):
+    return self._cmsg.GetScalar(cdescriptor)
+
+  def Setter(self, value):
+    self._cmsg.SetScalar(cdescriptor, value)
+
+  return property(Getter, Setter)
+
+
+def CompositeProperty(cdescriptor, message_type):
+  """Returns a Python property the given composite field."""
+
+  def Getter(self):
+    sub_message = self._composite_fields.get(cdescriptor.name, None)
+    if sub_message is None:
+      cmessage = self._cmsg.NewSubMessage(cdescriptor)
+      sub_message = message_type._concrete_class(__cmessage=cmessage)
+      self._composite_fields[cdescriptor.name] = sub_message
+    return sub_message
+
+  return property(Getter)
+
+
+class RepeatedScalarContainer(object):
+  """Container for repeated scalar fields."""
+
+  __slots__ = ['_message', '_cfield_descriptor', '_cmsg']
+
+  def __init__(self, msg, cfield_descriptor):
+    self._message = msg
+    self._cmsg = msg._cmsg
+    self._cfield_descriptor = cfield_descriptor
+
+  def append(self, value):
+    self._cmsg.AddRepeatedScalar(
+        self._cfield_descriptor, value)
+
+  def extend(self, sequence):
+    for element in sequence:
+      self.append(element)
+
+  def insert(self, key, value):
+    values = self[slice(None, None, None)]
+    values.insert(key, value)
+    self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+  def remove(self, value):
+    values = self[slice(None, None, None)]
+    values.remove(value)
+    self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+  def __setitem__(self, key, value):
+    values = self[slice(None, None, None)]
+    values[key] = value
+    self._cmsg.AssignRepeatedScalar(self._cfield_descriptor, values)
+
+  def __getitem__(self, key):
+    return self._cmsg.GetRepeatedScalar(self._cfield_descriptor, key)
+
+  def __delitem__(self, key):
+    self._cmsg.DeleteRepeatedField(self._cfield_descriptor, key)
+
+  def __len__(self):
+    return len(self[slice(None, None, None)])
+
+  def __eq__(self, other):
+    if self is other:
+      return True
+    if not operator.isSequenceType(other):
+      raise TypeError(
+          'Can only compare repeated scalar fields against sequences.')
+    # We are presumably comparing against some other sequence type.
+    return other == self[slice(None, None, None)]
+
+  def __ne__(self, other):
+    return not self == other
+
+  def __hash__(self):
+    raise TypeError('unhashable object')
+
+  def sort(self, *args, **kwargs):
+    # Maintain compatibility with the previous interface.
+    if 'sort_function' in kwargs:
+      kwargs['cmp'] = kwargs.pop('sort_function')
+    self._cmsg.AssignRepeatedScalar(self._cfield_descriptor,
+                                    sorted(self, *args, **kwargs))
+
+
+def RepeatedScalarProperty(cdescriptor):
+  """Returns a Python property the given repeated scalar field."""
+
+  def Getter(self):
+    container = self._composite_fields.get(cdescriptor.name, None)
+    if container is None:
+      container = RepeatedScalarContainer(self, cdescriptor)
+      self._composite_fields[cdescriptor.name] = container
+    return container
+
+  def Setter(self, new_value):
+    raise AttributeError('Assignment not allowed to repeated field '
+                         '"%s" in protocol message object.' % cdescriptor.name)
+
+  doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name
+  return property(Getter, Setter, doc=doc)
+
+
+class RepeatedCompositeContainer(object):
+  """Container for repeated composite fields."""
+
+  __slots__ = ['_message', '_subclass', '_cfield_descriptor', '_cmsg']
+
+  def __init__(self, msg, cfield_descriptor, subclass):
+    self._message = msg
+    self._cmsg = msg._cmsg
+    self._subclass = subclass
+    self._cfield_descriptor = cfield_descriptor
+
+  def add(self, **kwargs):
+    cmessage = self._cmsg.AddMessage(self._cfield_descriptor)
+    return self._subclass(__cmessage=cmessage, __owner=self._message, **kwargs)
+
+  def extend(self, elem_seq):
+    """Extends by appending the given sequence of elements of the same type
+    as this one, copying each individual message.
+    """
+    for message in elem_seq:
+      self.add().MergeFrom(message)
+
+  def remove(self, value):
+    # TODO(protocol-devel): This is inefficient as it needs to generate a
+    # message pointer for each message only to do index().  Move this to a C++
+    # extension function.
+    self.__delitem__(self[slice(None, None, None)].index(value))
+
+  def MergeFrom(self, other):
+    for message in other[:]:
+      self.add().MergeFrom(message)
+
+  def __getitem__(self, key):
+    cmessages = self._cmsg.GetRepeatedMessage(
+        self._cfield_descriptor, key)
+    subclass = self._subclass
+    if not isinstance(cmessages, list):
+      return subclass(__cmessage=cmessages, __owner=self._message)
+
+    return [subclass(__cmessage=m, __owner=self._message) for m in cmessages]
+
+  def __delitem__(self, key):
+    self._cmsg.DeleteRepeatedField(
+        self._cfield_descriptor, key)
+
+  def __len__(self):
+    return self._cmsg.FieldLength(self._cfield_descriptor)
+
+  def __eq__(self, other):
+    """Compares the current instance with another one."""
+    if self is other:
+      return True
+    if not isinstance(other, self.__class__):
+      raise TypeError('Can only compare repeated composite fields against '
+                      'other repeated composite fields.')
+    messages = self[slice(None, None, None)]
+    other_messages = other[slice(None, None, None)]
+    return messages == other_messages
+
+  def __hash__(self):
+    raise TypeError('unhashable object')
+
+  def sort(self, cmp=None, key=None, reverse=False, **kwargs):
+    # Maintain compatibility with the old interface.
+    if cmp is None and 'sort_function' in kwargs:
+      cmp = kwargs.pop('sort_function')
+
+    # The cmp function, if provided, is passed the results of the key function,
+    # so we only need to wrap one of them.
+    if key is None:
+      index_key = self.__getitem__
+    else:
+      index_key = lambda i: key(self[i])
+
+    # Sort the list of current indexes by the underlying object.
+    indexes = range(len(self))
+    indexes.sort(cmp=cmp, key=index_key, reverse=reverse)
+
+    # Apply the transposition.
+    for dest, src in enumerate(indexes):
+      if dest == src:
+        continue
+      self._cmsg.SwapRepeatedFieldElements(self._cfield_descriptor, dest, src)
+      # Don't swap the same value twice.
+      indexes[src] = src
+
+
+def RepeatedCompositeProperty(cdescriptor, message_type):
+  """Returns a Python property for the given repeated composite field."""
+
+  def Getter(self):
+    container = self._composite_fields.get(cdescriptor.name, None)
+    if container is None:
+      container = RepeatedCompositeContainer(
+          self, cdescriptor, message_type._concrete_class)
+      self._composite_fields[cdescriptor.name] = container
+    return container
+
+  def Setter(self, new_value):
+    raise AttributeError('Assignment not allowed to repeated field '
+                         '"%s" in protocol message object.' % cdescriptor.name)
+
+  doc = 'Magic attribute generated for "%s" proto field.' % cdescriptor.name
+  return property(Getter, Setter, doc=doc)
+
+
+class ExtensionDict(object):
+  """Extension dictionary added to each protocol message."""
+
+  def __init__(self, msg):
+    self._message = msg
+    self._cmsg = msg._cmsg
+    self._values = {}
+
+  def __setitem__(self, extension, value):
+    from google.protobuf import descriptor
+    if not isinstance(extension, descriptor.FieldDescriptor):
+      raise KeyError('Bad extension %r.' % (extension,))
+    cdescriptor = extension._cdescriptor
+    if (cdescriptor.label != _LABEL_OPTIONAL or
+        cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+      raise TypeError('Extension %r is repeated and/or a composite type.' % (
+          extension.full_name,))
+    self._cmsg.SetScalar(cdescriptor, value)
+    self._values[extension] = value
+
+  def __getitem__(self, extension):
+    from google.protobuf import descriptor
+    if not isinstance(extension, descriptor.FieldDescriptor):
+      raise KeyError('Bad extension %r.' % (extension,))
+
+    cdescriptor = extension._cdescriptor
+    if (cdescriptor.label != _LABEL_REPEATED and
+        cdescriptor.cpp_type != _CPPTYPE_MESSAGE):
+      return self._cmsg.GetScalar(cdescriptor)
+
+    ext = self._values.get(extension, None)
+    if ext is not None:
+      return ext
+
+    ext = self._CreateNewHandle(extension)
+    self._values[extension] = ext
+    return ext
+
+  def ClearExtension(self, extension):
+    from google.protobuf import descriptor
+    if not isinstance(extension, descriptor.FieldDescriptor):
+      raise KeyError('Bad extension %r.' % (extension,))
+    self._cmsg.ClearFieldByDescriptor(extension._cdescriptor)
+    if extension in self._values:
+      del self._values[extension]
+
+  def HasExtension(self, extension):
+    from google.protobuf import descriptor
+    if not isinstance(extension, descriptor.FieldDescriptor):
+      raise KeyError('Bad extension %r.' % (extension,))
+    return self._cmsg.HasFieldByDescriptor(extension._cdescriptor)
+
+  def _FindExtensionByName(self, name):
+    """Tries to find a known extension with the specified name.
+
+    Args:
+      name: Extension full name.
+
+    Returns:
+      Extension field descriptor.
+    """
+    return self._message._extensions_by_name.get(name, None)
+
+  def _CreateNewHandle(self, extension):
+    cdescriptor = extension._cdescriptor
+    if (cdescriptor.label != _LABEL_REPEATED and
+        cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+      cmessage = self._cmsg.NewSubMessage(cdescriptor)
+      return extension.message_type._concrete_class(__cmessage=cmessage)
+
+    if cdescriptor.label == _LABEL_REPEATED:
+      if cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+        return RepeatedCompositeContainer(
+            self._message, cdescriptor, extension.message_type._concrete_class)
+      else:
+        return RepeatedScalarContainer(self._message, cdescriptor)
+    # This shouldn't happen!
+    assert False
+    return None
+
+
+def NewMessage(bases, message_descriptor, dictionary):
+  """Creates a new protocol message *class*."""
+  _AddClassAttributesForNestedExtensions(message_descriptor, dictionary)
+  _AddEnumValues(message_descriptor, dictionary)
+  _AddDescriptors(message_descriptor, dictionary)
+  return bases
+
+
+def InitMessage(message_descriptor, cls):
+  """Constructs a new message instance (called before instance's __init__)."""
+  cls._extensions_by_name = {}
+  _AddInitMethod(message_descriptor, cls)
+  _AddMessageMethods(message_descriptor, cls)
+  _AddPropertiesForExtensions(message_descriptor, cls)
+  copy_reg.pickle(cls, lambda obj: (cls, (), obj.__getstate__()))
+
+
+def _AddDescriptors(message_descriptor, dictionary):
+  """Sets up a new protocol message class dictionary.
+
+  Args:
+    message_descriptor: A Descriptor instance describing this message type.
+    dictionary: Class dictionary to which we'll add a '__slots__' entry.
+  """
+  dictionary['__descriptors'] = {}
+  for field in message_descriptor.fields:
+    dictionary['__descriptors'][field.name] = GetFieldDescriptor(
+        field.full_name)
+
+  dictionary['__slots__'] = list(dictionary['__descriptors'].iterkeys()) + [
+      '_cmsg', '_owner', '_composite_fields', 'Extensions', '_HACK_REFCOUNTS']
+
+
+def _AddEnumValues(message_descriptor, dictionary):
+  """Sets class-level attributes for all enum fields defined in this message.
+
+  Args:
+    message_descriptor: Descriptor object for this message type.
+    dictionary: Class dictionary that should be populated.
+  """
+  for enum_type in message_descriptor.enum_types:
+    dictionary[enum_type.name] = enum_type_wrapper.EnumTypeWrapper(enum_type)
+    for enum_value in enum_type.values:
+      dictionary[enum_value.name] = enum_value.number
+
+
+def _AddClassAttributesForNestedExtensions(message_descriptor, dictionary):
+  """Adds class attributes for the nested extensions."""
+  extension_dict = message_descriptor.extensions_by_name
+  for extension_name, extension_field in extension_dict.iteritems():
+    assert extension_name not in dictionary
+    dictionary[extension_name] = extension_field
+
+
+def _AddInitMethod(message_descriptor, cls):
+  """Adds an __init__ method to cls."""
+
+  # Create and attach message field properties to the message class.
+  # This can be done just once per message class, since property setters and
+  # getters are passed the message instance.
+  # This makes message instantiation extremely fast, and at the same time it
+  # doesn't require the creation of property objects for each message instance,
+  # which saves a lot of memory.
+  for field in message_descriptor.fields:
+    field_cdescriptor = cls.__descriptors[field.name]
+    if field.label == _LABEL_REPEATED:
+      if field.cpp_type == _CPPTYPE_MESSAGE:
+        value = RepeatedCompositeProperty(field_cdescriptor, field.message_type)
+      else:
+        value = RepeatedScalarProperty(field_cdescriptor)
+    elif field.cpp_type == _CPPTYPE_MESSAGE:
+      value = CompositeProperty(field_cdescriptor, field.message_type)
+    else:
+      value = ScalarProperty(field_cdescriptor)
+    setattr(cls, field.name, value)
+
+    # Attach a constant with the field number.
+    constant_name = field.name.upper() + '_FIELD_NUMBER'
+    setattr(cls, constant_name, field.number)
+
+  def Init(self, **kwargs):
+    """Message constructor."""
+    cmessage = kwargs.pop('__cmessage', None)
+    if cmessage:
+      self._cmsg = cmessage
+    else:
+      self._cmsg = NewCMessage(message_descriptor.full_name)
+
+    # Keep a reference to the owner, as the owner keeps a reference to the
+    # underlying protocol buffer message.
+    owner = kwargs.pop('__owner', None)
+    if owner:
+      self._owner = owner
+
+    if message_descriptor.is_extendable:
+      self.Extensions = ExtensionDict(self)
+    else:
+      # Reference counting in the C++ code is broken and depends on
+      # the Extensions reference to keep this object alive during unit
+      # tests (see b/4856052).  Remove this once b/4945904 is fixed.
+      self._HACK_REFCOUNTS = self
+    self._composite_fields = {}
+
+    for field_name, field_value in kwargs.iteritems():
+      field_cdescriptor = self.__descriptors.get(field_name, None)
+      if not field_cdescriptor:
+        raise ValueError('Protocol message has no "%s" field.' % field_name)
+      if field_cdescriptor.label == _LABEL_REPEATED:
+        if field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+          field_name = getattr(self, field_name)
+          for val in field_value:
+            field_name.add().MergeFrom(val)
+        else:
+          getattr(self, field_name).extend(field_value)
+      elif field_cdescriptor.cpp_type == _CPPTYPE_MESSAGE:
+        getattr(self, field_name).MergeFrom(field_value)
+      else:
+        setattr(self, field_name, field_value)
+
+  Init.__module__ = None
+  Init.__doc__ = None
+  cls.__init__ = Init
+
+
+def _IsMessageSetExtension(field):
+  """Checks if a field is a message set extension."""
+  return (field.is_extension and
+          field.containing_type.has_options and
+          field.containing_type.GetOptions().message_set_wire_format and
+          field.type == _TYPE_MESSAGE and
+          field.message_type == field.extension_scope and
+          field.label == _LABEL_OPTIONAL)
+
+
+def _AddMessageMethods(message_descriptor, cls):
+  """Adds the methods to a protocol message class."""
+  if message_descriptor.is_extendable:
+
+    def ClearExtension(self, extension):
+      self.Extensions.ClearExtension(extension)
+
+    def HasExtension(self, extension):
+      return self.Extensions.HasExtension(extension)
+
+  def HasField(self, field_name):
+    return self._cmsg.HasField(field_name)
+
+  def ClearField(self, field_name):
+    child_cmessage = None
+    if field_name in self._composite_fields:
+      child_field = self._composite_fields[field_name]
+      del self._composite_fields[field_name]
+
+      child_cdescriptor = self.__descriptors[field_name]
+      # TODO(anuraag): Support clearing repeated message fields as well.
+      if (child_cdescriptor.label != _LABEL_REPEATED and
+          child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+        child_field._owner = None
+        child_cmessage = child_field._cmsg
+
+    if child_cmessage is not None:
+      self._cmsg.ClearField(field_name, child_cmessage)
+    else:
+      self._cmsg.ClearField(field_name)
+
+  def Clear(self):
+    cmessages_to_release = []
+    for field_name, child_field in self._composite_fields.iteritems():
+      child_cdescriptor = self.__descriptors[field_name]
+      # TODO(anuraag): Support clearing repeated message fields as well.
+      if (child_cdescriptor.label != _LABEL_REPEATED and
+          child_cdescriptor.cpp_type == _CPPTYPE_MESSAGE):
+        child_field._owner = None
+        cmessages_to_release.append((child_cdescriptor, child_field._cmsg))
+    self._composite_fields.clear()
+    self._cmsg.Clear(cmessages_to_release)
+
+  def IsInitialized(self, errors=None):
+    if self._cmsg.IsInitialized():
+      return True
+    if errors is not None:
+      errors.extend(self.FindInitializationErrors());
+    return False
+
+  def SerializeToString(self):
+    if not self.IsInitialized():
+      raise message.EncodeError(
+          'Message %s is missing required fields: %s' % (
+          self._cmsg.full_name, ','.join(self.FindInitializationErrors())))
+    return self._cmsg.SerializeToString()
+
+  def SerializePartialToString(self):
+    return self._cmsg.SerializePartialToString()
+
+  def ParseFromString(self, serialized):
+    self.Clear()
+    self.MergeFromString(serialized)
+
+  def MergeFromString(self, serialized):
+    byte_size = self._cmsg.MergeFromString(serialized)
+    if byte_size < 0:
+      raise message.DecodeError('Unable to merge from string.')
+    return byte_size
+
+  def MergeFrom(self, msg):
+    if not isinstance(msg, cls):
+      raise TypeError(
+          "Parameter to MergeFrom() must be instance of same class: "
+          "expected %s got %s." % (cls.__name__, type(msg).__name__))
+    self._cmsg.MergeFrom(msg._cmsg)
+
+  def CopyFrom(self, msg):
+    self._cmsg.CopyFrom(msg._cmsg)
+
+  def ByteSize(self):
+    return self._cmsg.ByteSize()
+
+  def SetInParent(self):
+    return self._cmsg.SetInParent()
+
+  def ListFields(self):
+    all_fields = []
+    field_list = self._cmsg.ListFields()
+    fields_by_name = cls.DESCRIPTOR.fields_by_name
+    for is_extension, field_name in field_list:
+      if is_extension:
+        extension = cls._extensions_by_name[field_name]
+        all_fields.append((extension, self.Extensions[extension]))
+      else:
+        field_descriptor = fields_by_name[field_name]
+        all_fields.append(
+            (field_descriptor, getattr(self, field_name)))
+    all_fields.sort(key=lambda item: item[0].number)
+    return all_fields
+
+  def FindInitializationErrors(self):
+    return self._cmsg.FindInitializationErrors()
+
+  def __str__(self):
+    return str(self._cmsg)
+
+  def __eq__(self, other):
+    if self is other:
+      return True
+    if not isinstance(other, self.__class__):
+      return False
+    return self.ListFields() == other.ListFields()
+
+  def __ne__(self, other):
+    return not self == other
+
+  def __hash__(self):
+    raise TypeError('unhashable object')
+
+  def __unicode__(self):
+    # Lazy import to prevent circular import when text_format imports this file.
+    from google.protobuf import text_format
+    return text_format.MessageToString(self, as_utf8=True).decode('utf-8')
+
+  # Attach the local methods to the message class.
+  for key, value in locals().copy().iteritems():
+    if key not in ('key', 'value', '__builtins__', '__name__', '__doc__'):
+      setattr(cls, key, value)
+
+  # Static methods:
+
+  def RegisterExtension(extension_handle):
+    extension_handle.containing_type = cls.DESCRIPTOR
+    cls._extensions_by_name[extension_handle.full_name] = extension_handle
+
+    if _IsMessageSetExtension(extension_handle):
+      # MessageSet extension.  Also register under type name.
+      cls._extensions_by_name[
+          extension_handle.message_type.full_name] = extension_handle
+  cls.RegisterExtension = staticmethod(RegisterExtension)
+
+  def FromString(string):
+    msg = cls()
+    msg.MergeFromString(string)
+    return msg
+  cls.FromString = staticmethod(FromString)
+
+
+
+def _AddPropertiesForExtensions(message_descriptor, cls):
+  """Adds properties for all fields in this protocol message type."""
+  extension_dict = message_descriptor.extensions_by_name
+  for extension_name, extension_field in extension_dict.iteritems():
+    constant_name = extension_name.upper() + '_FIELD_NUMBER'
+    setattr(cls, constant_name, extension_field.number)
diff --git a/protobuf/python/google/protobuf/internal/decoder.py b/protobuf/python/google/protobuf/internal/decoder.py
new file mode 100755
index 0000000..a4b9060
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/decoder.py
@@ -0,0 +1,831 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#PY25 compatible for GAE.
+#
+# Copyright 2009 Google Inc. All Rights Reserved.
+
+"""Code for decoding protocol buffer primitives.
+
+This code is very similar to encoder.py -- read the docs for that module first.
+
+A "decoder" is a function with the signature:
+  Decode(buffer, pos, end, message, field_dict)
+The arguments are:
+  buffer:     The string containing the encoded message.
+  pos:        The current position in the string.
+  end:        The position in the string where the current message ends.  May be
+              less than len(buffer) if we're reading a sub-message.
+  message:    The message object into which we're parsing.
+  field_dict: message._fields (avoids a hashtable lookup).
+The decoder reads the field and stores it into field_dict, returning the new
+buffer position.  A decoder for a repeated field may proactively decode all of
+the elements of that field, if they appear consecutively.
+
+Note that decoders may throw any of the following:
+  IndexError:  Indicates a truncated message.
+  struct.error:  Unpacking of a fixed-width field failed.
+  message.DecodeError:  Other errors.
+
+Decoders are expected to raise an exception if they are called with pos > end.
+This allows callers to be lax about bounds checking:  it's fineto read past
+"end" as long as you are sure that someone else will notice and throw an
+exception later on.
+
+Something up the call stack is expected to catch IndexError and struct.error
+and convert them to message.DecodeError.
+
+Decoders are constructed using decoder constructors with the signature:
+  MakeDecoder(field_number, is_repeated, is_packed, key, new_default)
+The arguments are:
+  field_number:  The field number of the field we want to decode.
+  is_repeated:   Is the field a repeated field? (bool)
+  is_packed:     Is the field a packed field? (bool)
+  key:           The key to use when looking up the field within field_dict.
+                 (This is actually the FieldDescriptor but nothing in this
+                 file should depend on that.)
+  new_default:   A function which takes a message object as a parameter and
+                 returns a new instance of the default value for this field.
+                 (This is called for repeated fields and sub-messages, when an
+                 instance does not already exist.)
+
+As with encoders, we define a decoder constructor for every type of field.
+Then, for every field of every message class we construct an actual decoder.
+That decoder goes into a dict indexed by tag, so when we decode a message
+we repeatedly read a tag, look up the corresponding decoder, and invoke it.
+"""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+import struct
+import sys  ##PY25
+_PY2 = sys.version_info[0] < 3  ##PY25
+from google.protobuf.internal import encoder
+from google.protobuf.internal import wire_format
+from google.protobuf import message
+
+
+# This will overflow and thus become IEEE-754 "infinity".  We would use
+# "float('inf')" but it doesn't work on Windows pre-Python-2.6.
+_POS_INF = 1e10000
+_NEG_INF = -_POS_INF
+_NAN = _POS_INF * 0
+
+
+# This is not for optimization, but rather to avoid conflicts with local
+# variables named "message".
+_DecodeError = message.DecodeError
+
+
+def _VarintDecoder(mask, result_type):
+  """Return an encoder for a basic varint value (does not include tag).
+
+  Decoded values will be bitwise-anded with the given mask before being
+  returned, e.g. to limit them to 32 bits.  The returned decoder does not
+  take the usual "end" parameter -- the caller is expected to do bounds checking
+  after the fact (often the caller can defer such checking until later).  The
+  decoder returns a (value, new_pos) pair.
+  """
+
+  local_ord = ord
+  py2 = _PY2  ##PY25
+##!PY25  py2 = str is bytes
+  def DecodeVarint(buffer, pos):
+    result = 0
+    shift = 0
+    while 1:
+      b = local_ord(buffer[pos]) if py2 else buffer[pos]
+      result |= ((b & 0x7f) << shift)
+      pos += 1
+      if not (b & 0x80):
+        result &= mask
+        result = result_type(result)
+        return (result, pos)
+      shift += 7
+      if shift >= 64:
+        raise _DecodeError('Too many bytes when decoding varint.')
+  return DecodeVarint
+
+
+def _SignedVarintDecoder(mask, result_type):
+  """Like _VarintDecoder() but decodes signed values."""
+
+  local_ord = ord
+  py2 = _PY2  ##PY25
+##!PY25  py2 = str is bytes
+  def DecodeVarint(buffer, pos):
+    result = 0
+    shift = 0
+    while 1:
+      b = local_ord(buffer[pos]) if py2 else buffer[pos]
+      result |= ((b & 0x7f) << shift)
+      pos += 1
+      if not (b & 0x80):
+        if result > 0x7fffffffffffffff:
+          result -= (1 << 64)
+          result |= ~mask
+        else:
+          result &= mask
+        result = result_type(result)
+        return (result, pos)
+      shift += 7
+      if shift >= 64:
+        raise _DecodeError('Too many bytes when decoding varint.')
+  return DecodeVarint
+
+# We force 32-bit values to int and 64-bit values to long to make
+# alternate implementations where the distinction is more significant
+# (e.g. the C++ implementation) simpler.
+
+_DecodeVarint = _VarintDecoder((1 << 64) - 1, long)
+_DecodeSignedVarint = _SignedVarintDecoder((1 << 64) - 1, long)
+
+# Use these versions for values which must be limited to 32 bits.
+_DecodeVarint32 = _VarintDecoder((1 << 32) - 1, int)
+_DecodeSignedVarint32 = _SignedVarintDecoder((1 << 32) - 1, int)
+
+
+def ReadTag(buffer, pos):
+  """Read a tag from the buffer, and return a (tag_bytes, new_pos) tuple.
+
+  We return the raw bytes of the tag rather than decoding them.  The raw
+  bytes can then be used to look up the proper decoder.  This effectively allows
+  us to trade some work that would be done in pure-python (decoding a varint)
+  for work that is done in C (searching for a byte string in a hash table).
+  In a low-level language it would be much cheaper to decode the varint and
+  use that, but not in Python.
+  """
+
+  py2 = _PY2  ##PY25
+##!PY25  py2 = str is bytes
+  start = pos
+  while (ord(buffer[pos]) if py2 else buffer[pos]) & 0x80:
+    pos += 1
+  pos += 1
+  return (buffer[start:pos], pos)
+
+
+# --------------------------------------------------------------------
+
+
+def _SimpleDecoder(wire_type, decode_value):
+  """Return a constructor for a decoder for fields of a particular type.
+
+  Args:
+      wire_type:  The field's wire type.
+      decode_value:  A function which decodes an individual value, e.g.
+        _DecodeVarint()
+  """
+
+  def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default):
+    if is_packed:
+      local_DecodeVarint = _DecodeVarint
+      def DecodePackedField(buffer, pos, end, message, field_dict):
+        value = field_dict.get(key)
+        if value is None:
+          value = field_dict.setdefault(key, new_default(message))
+        (endpoint, pos) = local_DecodeVarint(buffer, pos)
+        endpoint += pos
+        if endpoint > end:
+          raise _DecodeError('Truncated message.')
+        while pos < endpoint:
+          (element, pos) = decode_value(buffer, pos)
+          value.append(element)
+        if pos > endpoint:
+          del value[-1]   # Discard corrupt value.
+          raise _DecodeError('Packed element was truncated.')
+        return pos
+      return DecodePackedField
+    elif is_repeated:
+      tag_bytes = encoder.TagBytes(field_number, wire_type)
+      tag_len = len(tag_bytes)
+      def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+        value = field_dict.get(key)
+        if value is None:
+          value = field_dict.setdefault(key, new_default(message))
+        while 1:
+          (element, new_pos) = decode_value(buffer, pos)
+          value.append(element)
+          # Predict that the next tag is another copy of the same repeated
+          # field.
+          pos = new_pos + tag_len
+          if buffer[new_pos:pos] != tag_bytes or new_pos >= end:
+            # Prediction failed.  Return.
+            if new_pos > end:
+              raise _DecodeError('Truncated message.')
+            return new_pos
+      return DecodeRepeatedField
+    else:
+      def DecodeField(buffer, pos, end, message, field_dict):
+        (field_dict[key], pos) = decode_value(buffer, pos)
+        if pos > end:
+          del field_dict[key]  # Discard corrupt value.
+          raise _DecodeError('Truncated message.')
+        return pos
+      return DecodeField
+
+  return SpecificDecoder
+
+
+def _ModifiedDecoder(wire_type, decode_value, modify_value):
+  """Like SimpleDecoder but additionally invokes modify_value on every value
+  before storing it.  Usually modify_value is ZigZagDecode.
+  """
+
+  # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but
+  # not enough to make a significant difference.
+
+  def InnerDecode(buffer, pos):
+    (result, new_pos) = decode_value(buffer, pos)
+    return (modify_value(result), new_pos)
+  return _SimpleDecoder(wire_type, InnerDecode)
+
+
+def _StructPackDecoder(wire_type, format):
+  """Return a constructor for a decoder for a fixed-width field.
+
+  Args:
+      wire_type:  The field's wire type.
+      format:  The format string to pass to struct.unpack().
+  """
+
+  value_size = struct.calcsize(format)
+  local_unpack = struct.unpack
+
+  # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but
+  # not enough to make a significant difference.
+
+  # Note that we expect someone up-stack to catch struct.error and convert
+  # it to _DecodeError -- this way we don't have to set up exception-
+  # handling blocks every time we parse one value.
+
+  def InnerDecode(buffer, pos):
+    new_pos = pos + value_size
+    result = local_unpack(format, buffer[pos:new_pos])[0]
+    return (result, new_pos)
+  return _SimpleDecoder(wire_type, InnerDecode)
+
+
+def _FloatDecoder():
+  """Returns a decoder for a float field.
+
+  This code works around a bug in struct.unpack for non-finite 32-bit
+  floating-point values.
+  """
+
+  local_unpack = struct.unpack
+  b = (lambda x:x) if _PY2 else lambda x:x.encode('latin1')  ##PY25
+
+  def InnerDecode(buffer, pos):
+    # We expect a 32-bit value in little-endian byte order.  Bit 1 is the sign
+    # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand.
+    new_pos = pos + 4
+    float_bytes = buffer[pos:new_pos]
+
+    # If this value has all its exponent bits set, then it's non-finite.
+    # In Python 2.4, struct.unpack will convert it to a finite 64-bit value.
+    # To avoid that, we parse it specially.
+    if ((float_bytes[3:4] in b('\x7F\xFF'))  ##PY25
+##!PY25    if ((float_bytes[3:4] in b'\x7F\xFF')
+        and (float_bytes[2:3] >= b('\x80'))):  ##PY25
+##!PY25        and (float_bytes[2:3] >= b'\x80')):
+      # If at least one significand bit is set...
+      if float_bytes[0:3] != b('\x00\x00\x80'):  ##PY25
+##!PY25      if float_bytes[0:3] != b'\x00\x00\x80':
+        return (_NAN, new_pos)
+      # If sign bit is set...
+      if float_bytes[3:4] == b('\xFF'):  ##PY25
+##!PY25      if float_bytes[3:4] == b'\xFF':
+        return (_NEG_INF, new_pos)
+      return (_POS_INF, new_pos)
+
+    # Note that we expect someone up-stack to catch struct.error and convert
+    # it to _DecodeError -- this way we don't have to set up exception-
+    # handling blocks every time we parse one value.
+    result = local_unpack('<f', float_bytes)[0]
+    return (result, new_pos)
+  return _SimpleDecoder(wire_format.WIRETYPE_FIXED32, InnerDecode)
+
+
+def _DoubleDecoder():
+  """Returns a decoder for a double field.
+
+  This code works around a bug in struct.unpack for not-a-number.
+  """
+
+  local_unpack = struct.unpack
+  b = (lambda x:x) if _PY2 else lambda x:x.encode('latin1')  ##PY25
+
+  def InnerDecode(buffer, pos):
+    # We expect a 64-bit value in little-endian byte order.  Bit 1 is the sign
+    # bit, bits 2-12 represent the exponent, and bits 13-64 are the significand.
+    new_pos = pos + 8
+    double_bytes = buffer[pos:new_pos]
+
+    # If this value has all its exponent bits set and at least one significand
+    # bit set, it's not a number.  In Python 2.4, struct.unpack will treat it
+    # as inf or -inf.  To avoid that, we treat it specially.
+##!PY25    if ((double_bytes[7:8] in b'\x7F\xFF')
+##!PY25        and (double_bytes[6:7] >= b'\xF0')
+##!PY25        and (double_bytes[0:7] != b'\x00\x00\x00\x00\x00\x00\xF0')):
+    if ((double_bytes[7:8] in b('\x7F\xFF'))  ##PY25
+        and (double_bytes[6:7] >= b('\xF0'))  ##PY25
+        and (double_bytes[0:7] != b('\x00\x00\x00\x00\x00\x00\xF0'))):  ##PY25
+      return (_NAN, new_pos)
+
+    # Note that we expect someone up-stack to catch struct.error and convert
+    # it to _DecodeError -- this way we don't have to set up exception-
+    # handling blocks every time we parse one value.
+    result = local_unpack('<d', double_bytes)[0]
+    return (result, new_pos)
+  return _SimpleDecoder(wire_format.WIRETYPE_FIXED64, InnerDecode)
+
+
+def EnumDecoder(field_number, is_repeated, is_packed, key, new_default):
+  enum_type = key.enum_type
+  if is_packed:
+    local_DecodeVarint = _DecodeVarint
+    def DecodePackedField(buffer, pos, end, message, field_dict):
+      value = field_dict.get(key)
+      if value is None:
+        value = field_dict.setdefault(key, new_default(message))
+      (endpoint, pos) = local_DecodeVarint(buffer, pos)
+      endpoint += pos
+      if endpoint > end:
+        raise _DecodeError('Truncated message.')
+      while pos < endpoint:
+        value_start_pos = pos
+        (element, pos) = _DecodeSignedVarint32(buffer, pos)
+        if element in enum_type.values_by_number:
+          value.append(element)
+        else:
+          if not message._unknown_fields:
+            message._unknown_fields = []
+          tag_bytes = encoder.TagBytes(field_number,
+                                       wire_format.WIRETYPE_VARINT)
+          message._unknown_fields.append(
+              (tag_bytes, buffer[value_start_pos:pos]))
+      if pos > endpoint:
+        if element in enum_type.values_by_number:
+          del value[-1]   # Discard corrupt value.
+        else:
+          del message._unknown_fields[-1]
+        raise _DecodeError('Packed element was truncated.')
+      return pos
+    return DecodePackedField
+  elif is_repeated:
+    tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT)
+    tag_len = len(tag_bytes)
+    def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+      value = field_dict.get(key)
+      if value is None:
+        value = field_dict.setdefault(key, new_default(message))
+      while 1:
+        (element, new_pos) = _DecodeSignedVarint32(buffer, pos)
+        if element in enum_type.values_by_number:
+          value.append(element)
+        else:
+          if not message._unknown_fields:
+            message._unknown_fields = []
+          message._unknown_fields.append(
+              (tag_bytes, buffer[pos:new_pos]))
+        # Predict that the next tag is another copy of the same repeated
+        # field.
+        pos = new_pos + tag_len
+        if buffer[new_pos:pos] != tag_bytes or new_pos >= end:
+          # Prediction failed.  Return.
+          if new_pos > end:
+            raise _DecodeError('Truncated message.')
+          return new_pos
+    return DecodeRepeatedField
+  else:
+    def DecodeField(buffer, pos, end, message, field_dict):
+      value_start_pos = pos
+      (enum_value, pos) = _DecodeSignedVarint32(buffer, pos)
+      if pos > end:
+        raise _DecodeError('Truncated message.')
+      if enum_value in enum_type.values_by_number:
+        field_dict[key] = enum_value
+      else:
+        if not message._unknown_fields:
+          message._unknown_fields = []
+        tag_bytes = encoder.TagBytes(field_number,
+                                     wire_format.WIRETYPE_VARINT)
+        message._unknown_fields.append(
+          (tag_bytes, buffer[value_start_pos:pos]))
+      return pos
+    return DecodeField
+
+
+# --------------------------------------------------------------------
+
+
+Int32Decoder = _SimpleDecoder(
+    wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32)
+
+Int64Decoder = _SimpleDecoder(
+    wire_format.WIRETYPE_VARINT, _DecodeSignedVarint)
+
+UInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32)
+UInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint)
+
+SInt32Decoder = _ModifiedDecoder(
+    wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode)
+SInt64Decoder = _ModifiedDecoder(
+    wire_format.WIRETYPE_VARINT, _DecodeVarint, wire_format.ZigZagDecode)
+
+# Note that Python conveniently guarantees that when using the '<' prefix on
+# formats, they will also have the same size across all platforms (as opposed
+# to without the prefix, where their sizes depend on the C compiler's basic
+# type sizes).
+Fixed32Decoder  = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<I')
+Fixed64Decoder  = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<Q')
+SFixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, '<i')
+SFixed64Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED64, '<q')
+FloatDecoder = _FloatDecoder()
+DoubleDecoder = _DoubleDecoder()
+
+BoolDecoder = _ModifiedDecoder(
+    wire_format.WIRETYPE_VARINT, _DecodeVarint, bool)
+
+
+def StringDecoder(field_number, is_repeated, is_packed, key, new_default):
+  """Returns a decoder for a string field."""
+
+  local_DecodeVarint = _DecodeVarint
+  local_unicode = unicode
+
+  def _ConvertToUnicode(byte_str):
+    try:
+      return local_unicode(byte_str, 'utf-8')
+    except UnicodeDecodeError, e:
+      # add more information to the error message and re-raise it.
+      e.reason = '%s in field: %s' % (e, key.full_name)
+      raise
+
+  assert not is_packed
+  if is_repeated:
+    tag_bytes = encoder.TagBytes(field_number,
+                                 wire_format.WIRETYPE_LENGTH_DELIMITED)
+    tag_len = len(tag_bytes)
+    def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+      value = field_dict.get(key)
+      if value is None:
+        value = field_dict.setdefault(key, new_default(message))
+      while 1:
+        (size, pos) = local_DecodeVarint(buffer, pos)
+        new_pos = pos + size
+        if new_pos > end:
+          raise _DecodeError('Truncated string.')
+        value.append(_ConvertToUnicode(buffer[pos:new_pos]))
+        # Predict that the next tag is another copy of the same repeated field.
+        pos = new_pos + tag_len
+        if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+          # Prediction failed.  Return.
+          return new_pos
+    return DecodeRepeatedField
+  else:
+    def DecodeField(buffer, pos, end, message, field_dict):
+      (size, pos) = local_DecodeVarint(buffer, pos)
+      new_pos = pos + size
+      if new_pos > end:
+        raise _DecodeError('Truncated string.')
+      field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos])
+      return new_pos
+    return DecodeField
+
+
+def BytesDecoder(field_number, is_repeated, is_packed, key, new_default):
+  """Returns a decoder for a bytes field."""
+
+  local_DecodeVarint = _DecodeVarint
+
+  assert not is_packed
+  if is_repeated:
+    tag_bytes = encoder.TagBytes(field_number,
+                                 wire_format.WIRETYPE_LENGTH_DELIMITED)
+    tag_len = len(tag_bytes)
+    def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+      value = field_dict.get(key)
+      if value is None:
+        value = field_dict.setdefault(key, new_default(message))
+      while 1:
+        (size, pos) = local_DecodeVarint(buffer, pos)
+        new_pos = pos + size
+        if new_pos > end:
+          raise _DecodeError('Truncated string.')
+        value.append(buffer[pos:new_pos])
+        # Predict that the next tag is another copy of the same repeated field.
+        pos = new_pos + tag_len
+        if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+          # Prediction failed.  Return.
+          return new_pos
+    return DecodeRepeatedField
+  else:
+    def DecodeField(buffer, pos, end, message, field_dict):
+      (size, pos) = local_DecodeVarint(buffer, pos)
+      new_pos = pos + size
+      if new_pos > end:
+        raise _DecodeError('Truncated string.')
+      field_dict[key] = buffer[pos:new_pos]
+      return new_pos
+    return DecodeField
+
+
+def GroupDecoder(field_number, is_repeated, is_packed, key, new_default):
+  """Returns a decoder for a group field."""
+
+  end_tag_bytes = encoder.TagBytes(field_number,
+                                   wire_format.WIRETYPE_END_GROUP)
+  end_tag_len = len(end_tag_bytes)
+
+  assert not is_packed
+  if is_repeated:
+    tag_bytes = encoder.TagBytes(field_number,
+                                 wire_format.WIRETYPE_START_GROUP)
+    tag_len = len(tag_bytes)
+    def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+      value = field_dict.get(key)
+      if value is None:
+        value = field_dict.setdefault(key, new_default(message))
+      while 1:
+        value = field_dict.get(key)
+        if value is None:
+          value = field_dict.setdefault(key, new_default(message))
+        # Read sub-message.
+        pos = value.add()._InternalParse(buffer, pos, end)
+        # Read end tag.
+        new_pos = pos+end_tag_len
+        if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
+          raise _DecodeError('Missing group end tag.')
+        # Predict that the next tag is another copy of the same repeated field.
+        pos = new_pos + tag_len
+        if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+          # Prediction failed.  Return.
+          return new_pos
+    return DecodeRepeatedField
+  else:
+    def DecodeField(buffer, pos, end, message, field_dict):
+      value = field_dict.get(key)
+      if value is None:
+        value = field_dict.setdefault(key, new_default(message))
+      # Read sub-message.
+      pos = value._InternalParse(buffer, pos, end)
+      # Read end tag.
+      new_pos = pos+end_tag_len
+      if buffer[pos:new_pos] != end_tag_bytes or new_pos > end:
+        raise _DecodeError('Missing group end tag.')
+      return new_pos
+    return DecodeField
+
+
+def MessageDecoder(field_number, is_repeated, is_packed, key, new_default):
+  """Returns a decoder for a message field."""
+
+  local_DecodeVarint = _DecodeVarint
+
+  assert not is_packed
+  if is_repeated:
+    tag_bytes = encoder.TagBytes(field_number,
+                                 wire_format.WIRETYPE_LENGTH_DELIMITED)
+    tag_len = len(tag_bytes)
+    def DecodeRepeatedField(buffer, pos, end, message, field_dict):
+      value = field_dict.get(key)
+      if value is None:
+        value = field_dict.setdefault(key, new_default(message))
+      while 1:
+        value = field_dict.get(key)
+        if value is None:
+          value = field_dict.setdefault(key, new_default(message))
+        # Read length.
+        (size, pos) = local_DecodeVarint(buffer, pos)
+        new_pos = pos + size
+        if new_pos > end:
+          raise _DecodeError('Truncated message.')
+        # Read sub-message.
+        if value.add()._InternalParse(buffer, pos, new_pos) != new_pos:
+          # The only reason _InternalParse would return early is if it
+          # encountered an end-group tag.
+          raise _DecodeError('Unexpected end-group tag.')
+        # Predict that the next tag is another copy of the same repeated field.
+        pos = new_pos + tag_len
+        if buffer[new_pos:pos] != tag_bytes or new_pos == end:
+          # Prediction failed.  Return.
+          return new_pos
+    return DecodeRepeatedField
+  else:
+    def DecodeField(buffer, pos, end, message, field_dict):
+      value = field_dict.get(key)
+      if value is None:
+        value = field_dict.setdefault(key, new_default(message))
+      # Read length.
+      (size, pos) = local_DecodeVarint(buffer, pos)
+      new_pos = pos + size
+      if new_pos > end:
+        raise _DecodeError('Truncated message.')
+      # Read sub-message.
+      if value._InternalParse(buffer, pos, new_pos) != new_pos:
+        # The only reason _InternalParse would return early is if it encountered
+        # an end-group tag.
+        raise _DecodeError('Unexpected end-group tag.')
+      return new_pos
+    return DecodeField
+
+
+# --------------------------------------------------------------------
+
+MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP)
+
+def MessageSetItemDecoder(extensions_by_number):
+  """Returns a decoder for a MessageSet item.
+
+  The parameter is the _extensions_by_number map for the message class.
+
+  The message set message looks like this:
+    message MessageSet {
+      repeated group Item = 1 {
+        required int32 type_id = 2;
+        required string message = 3;
+      }
+    }
+  """
+
+  type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT)
+  message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED)
+  item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP)
+
+  local_ReadTag = ReadTag
+  local_DecodeVarint = _DecodeVarint
+  local_SkipField = SkipField
+
+  def DecodeItem(buffer, pos, end, message, field_dict):
+    message_set_item_start = pos
+    type_id = -1
+    message_start = -1
+    message_end = -1
+
+    # Technically, type_id and message can appear in any order, so we need
+    # a little loop here.
+    while 1:
+      (tag_bytes, pos) = local_ReadTag(buffer, pos)
+      if tag_bytes == type_id_tag_bytes:
+        (type_id, pos) = local_DecodeVarint(buffer, pos)
+      elif tag_bytes == message_tag_bytes:
+        (size, message_start) = local_DecodeVarint(buffer, pos)
+        pos = message_end = message_start + size
+      elif tag_bytes == item_end_tag_bytes:
+        break
+      else:
+        pos = SkipField(buffer, pos, end, tag_bytes)
+        if pos == -1:
+          raise _DecodeError('Missing group end tag.')
+
+    if pos > end:
+      raise _DecodeError('Truncated message.')
+
+    if type_id == -1:
+      raise _DecodeError('MessageSet item missing type_id.')
+    if message_start == -1:
+      raise _DecodeError('MessageSet item missing message.')
+
+    extension = extensions_by_number.get(type_id)
+    if extension is not None:
+      value = field_dict.get(extension)
+      if value is None:
+        value = field_dict.setdefault(
+            extension, extension.message_type._concrete_class())
+      if value._InternalParse(buffer, message_start,message_end) != message_end:
+        # The only reason _InternalParse would return early is if it encountered
+        # an end-group tag.
+        raise _DecodeError('Unexpected end-group tag.')
+    else:
+      if not message._unknown_fields:
+        message._unknown_fields = []
+      message._unknown_fields.append((MESSAGE_SET_ITEM_TAG,
+                                      buffer[message_set_item_start:pos]))
+
+    return pos
+
+  return DecodeItem
+
+# --------------------------------------------------------------------
+# Optimization is not as heavy here because calls to SkipField() are rare,
+# except for handling end-group tags.
+
+def _SkipVarint(buffer, pos, end):
+  """Skip a varint value.  Returns the new position."""
+  # Previously ord(buffer[pos]) raised IndexError when pos is out of range.
+  # With this code, ord(b'') raises TypeError.  Both are handled in
+  # python_message.py to generate a 'Truncated message' error.
+  while ord(buffer[pos:pos+1]) & 0x80:
+    pos += 1
+  pos += 1
+  if pos > end:
+    raise _DecodeError('Truncated message.')
+  return pos
+
+def _SkipFixed64(buffer, pos, end):
+  """Skip a fixed64 value.  Returns the new position."""
+
+  pos += 8
+  if pos > end:
+    raise _DecodeError('Truncated message.')
+  return pos
+
+def _SkipLengthDelimited(buffer, pos, end):
+  """Skip a length-delimited value.  Returns the new position."""
+
+  (size, pos) = _DecodeVarint(buffer, pos)
+  pos += size
+  if pos > end:
+    raise _DecodeError('Truncated message.')
+  return pos
+
+def _SkipGroup(buffer, pos, end):
+  """Skip sub-group.  Returns the new position."""
+
+  while 1:
+    (tag_bytes, pos) = ReadTag(buffer, pos)
+    new_pos = SkipField(buffer, pos, end, tag_bytes)
+    if new_pos == -1:
+      return pos
+    pos = new_pos
+
+def _EndGroup(buffer, pos, end):
+  """Skipping an END_GROUP tag returns -1 to tell the parent loop to break."""
+
+  return -1
+
+def _SkipFixed32(buffer, pos, end):
+  """Skip a fixed32 value.  Returns the new position."""
+
+  pos += 4
+  if pos > end:
+    raise _DecodeError('Truncated message.')
+  return pos
+
+def _RaiseInvalidWireType(buffer, pos, end):
+  """Skip function for unknown wire types.  Raises an exception."""
+
+  raise _DecodeError('Tag had invalid wire type.')
+
+def _FieldSkipper():
+  """Constructs the SkipField function."""
+
+  WIRETYPE_TO_SKIPPER = [
+      _SkipVarint,
+      _SkipFixed64,
+      _SkipLengthDelimited,
+      _SkipGroup,
+      _EndGroup,
+      _SkipFixed32,
+      _RaiseInvalidWireType,
+      _RaiseInvalidWireType,
+      ]
+
+  wiretype_mask = wire_format.TAG_TYPE_MASK
+
+  def SkipField(buffer, pos, end, tag_bytes):
+    """Skips a field with the specified tag.
+
+    |pos| should point to the byte immediately after the tag.
+
+    Returns:
+        The new position (after the tag value), or -1 if the tag is an end-group
+        tag (in which case the calling loop should break).
+    """
+
+    # The wire type is always in the first byte since varints are little-endian.
+    wire_type = ord(tag_bytes[0:1]) & wiretype_mask
+    return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end)
+
+  return SkipField
+
+SkipField = _FieldSkipper()
diff --git a/protobuf/python/google/protobuf/internal/descriptor_database_test.py b/protobuf/python/google/protobuf/internal/descriptor_database_test.py
new file mode 100644
index 0000000..fc65b69
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/descriptor_database_test.py
@@ -0,0 +1,63 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.descriptor_database."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+from google.apputils import basetest
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor_database
+
+
+class DescriptorDatabaseTest(basetest.TestCase):
+
+  def testAdd(self):
+    db = descriptor_database.DescriptorDatabase()
+    file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString(
+        factory_test2_pb2.DESCRIPTOR.serialized_pb)
+    db.Add(file_desc_proto)
+
+    self.assertEquals(file_desc_proto, db.FindFileByName(
+        'google/protobuf/internal/factory_test2.proto'))
+    self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Message'))
+    self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Message.NestedFactory2Message'))
+    self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Enum'))
+    self.assertEquals(file_desc_proto, db.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Message.NestedFactory2Enum'))
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/descriptor_pool_test.py b/protobuf/python/google/protobuf/internal/descriptor_pool_test.py
new file mode 100644
index 0000000..d2f8557
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/descriptor_pool_test.py
@@ -0,0 +1,564 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.descriptor_pool."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+import os
+import unittest
+
+from google.apputils import basetest
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import descriptor_pool_test1_pb2
+from google.protobuf.internal import descriptor_pool_test2_pb2
+from google.protobuf.internal import factory_test1_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+
+
+class DescriptorPoolTest(basetest.TestCase):
+
+  def setUp(self):
+    self.pool = descriptor_pool.DescriptorPool()
+    self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString(
+        factory_test1_pb2.DESCRIPTOR.serialized_pb)
+    self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
+        factory_test2_pb2.DESCRIPTOR.serialized_pb)
+    self.pool.Add(self.factory_test1_fd)
+    self.pool.Add(self.factory_test2_fd)
+
+  def testFindFileByName(self):
+    name1 = 'google/protobuf/internal/factory_test1.proto'
+    file_desc1 = self.pool.FindFileByName(name1)
+    self.assertIsInstance(file_desc1, descriptor.FileDescriptor)
+    self.assertEquals(name1, file_desc1.name)
+    self.assertEquals('google.protobuf.python.internal', file_desc1.package)
+    self.assertIn('Factory1Message', file_desc1.message_types_by_name)
+
+    name2 = 'google/protobuf/internal/factory_test2.proto'
+    file_desc2 = self.pool.FindFileByName(name2)
+    self.assertIsInstance(file_desc2, descriptor.FileDescriptor)
+    self.assertEquals(name2, file_desc2.name)
+    self.assertEquals('google.protobuf.python.internal', file_desc2.package)
+    self.assertIn('Factory2Message', file_desc2.message_types_by_name)
+
+  def testFindFileByNameFailure(self):
+    with self.assertRaises(KeyError):
+      self.pool.FindFileByName('Does not exist')
+
+  def testFindFileContainingSymbol(self):
+    file_desc1 = self.pool.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory1Message')
+    self.assertIsInstance(file_desc1, descriptor.FileDescriptor)
+    self.assertEquals('google/protobuf/internal/factory_test1.proto',
+                      file_desc1.name)
+    self.assertEquals('google.protobuf.python.internal', file_desc1.package)
+    self.assertIn('Factory1Message', file_desc1.message_types_by_name)
+
+    file_desc2 = self.pool.FindFileContainingSymbol(
+        'google.protobuf.python.internal.Factory2Message')
+    self.assertIsInstance(file_desc2, descriptor.FileDescriptor)
+    self.assertEquals('google/protobuf/internal/factory_test2.proto',
+                      file_desc2.name)
+    self.assertEquals('google.protobuf.python.internal', file_desc2.package)
+    self.assertIn('Factory2Message', file_desc2.message_types_by_name)
+
+  def testFindFileContainingSymbolFailure(self):
+    with self.assertRaises(KeyError):
+      self.pool.FindFileContainingSymbol('Does not exist')
+
+  def testFindMessageTypeByName(self):
+    msg1 = self.pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory1Message')
+    self.assertIsInstance(msg1, descriptor.Descriptor)
+    self.assertEquals('Factory1Message', msg1.name)
+    self.assertEquals('google.protobuf.python.internal.Factory1Message',
+                      msg1.full_name)
+    self.assertEquals(None, msg1.containing_type)
+
+    nested_msg1 = msg1.nested_types[0]
+    self.assertEquals('NestedFactory1Message', nested_msg1.name)
+    self.assertEquals(msg1, nested_msg1.containing_type)
+
+    nested_enum1 = msg1.enum_types[0]
+    self.assertEquals('NestedFactory1Enum', nested_enum1.name)
+    self.assertEquals(msg1, nested_enum1.containing_type)
+
+    self.assertEquals(nested_msg1, msg1.fields_by_name[
+        'nested_factory_1_message'].message_type)
+    self.assertEquals(nested_enum1, msg1.fields_by_name[
+        'nested_factory_1_enum'].enum_type)
+
+    msg2 = self.pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory2Message')
+    self.assertIsInstance(msg2, descriptor.Descriptor)
+    self.assertEquals('Factory2Message', msg2.name)
+    self.assertEquals('google.protobuf.python.internal.Factory2Message',
+                      msg2.full_name)
+    self.assertIsNone(msg2.containing_type)
+
+    nested_msg2 = msg2.nested_types[0]
+    self.assertEquals('NestedFactory2Message', nested_msg2.name)
+    self.assertEquals(msg2, nested_msg2.containing_type)
+
+    nested_enum2 = msg2.enum_types[0]
+    self.assertEquals('NestedFactory2Enum', nested_enum2.name)
+    self.assertEquals(msg2, nested_enum2.containing_type)
+
+    self.assertEquals(nested_msg2, msg2.fields_by_name[
+        'nested_factory_2_message'].message_type)
+    self.assertEquals(nested_enum2, msg2.fields_by_name[
+        'nested_factory_2_enum'].enum_type)
+
+    self.assertTrue(msg2.fields_by_name['int_with_default'].has_default_value)
+    self.assertEquals(
+        1776, msg2.fields_by_name['int_with_default'].default_value)
+
+    self.assertTrue(
+        msg2.fields_by_name['double_with_default'].has_default_value)
+    self.assertEquals(
+        9.99, msg2.fields_by_name['double_with_default'].default_value)
+
+    self.assertTrue(
+        msg2.fields_by_name['string_with_default'].has_default_value)
+    self.assertEquals(
+        'hello world', msg2.fields_by_name['string_with_default'].default_value)
+
+    self.assertTrue(msg2.fields_by_name['bool_with_default'].has_default_value)
+    self.assertFalse(msg2.fields_by_name['bool_with_default'].default_value)
+
+    self.assertTrue(msg2.fields_by_name['enum_with_default'].has_default_value)
+    self.assertEquals(
+        1, msg2.fields_by_name['enum_with_default'].default_value)
+
+    msg3 = self.pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory2Message.NestedFactory2Message')
+    self.assertEquals(nested_msg2, msg3)
+
+    self.assertTrue(msg2.fields_by_name['bytes_with_default'].has_default_value)
+    self.assertEquals(
+        b'a\xfb\x00c',
+        msg2.fields_by_name['bytes_with_default'].default_value)
+
+    self.assertEqual(1, len(msg2.oneofs))
+    self.assertEqual(1, len(msg2.oneofs_by_name))
+    self.assertEqual(2, len(msg2.oneofs[0].fields))
+    for name in ['oneof_int', 'oneof_string']:
+      self.assertEqual(msg2.oneofs[0],
+                       msg2.fields_by_name[name].containing_oneof)
+      self.assertIn(msg2.fields_by_name[name], msg2.oneofs[0].fields)
+
+  def testFindMessageTypeByNameFailure(self):
+    with self.assertRaises(KeyError):
+      self.pool.FindMessageTypeByName('Does not exist')
+
+  def testFindEnumTypeByName(self):
+    enum1 = self.pool.FindEnumTypeByName(
+        'google.protobuf.python.internal.Factory1Enum')
+    self.assertIsInstance(enum1, descriptor.EnumDescriptor)
+    self.assertEquals(0, enum1.values_by_name['FACTORY_1_VALUE_0'].number)
+    self.assertEquals(1, enum1.values_by_name['FACTORY_1_VALUE_1'].number)
+
+    nested_enum1 = self.pool.FindEnumTypeByName(
+        'google.protobuf.python.internal.Factory1Message.NestedFactory1Enum')
+    self.assertIsInstance(nested_enum1, descriptor.EnumDescriptor)
+    self.assertEquals(
+        0, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_0'].number)
+    self.assertEquals(
+        1, nested_enum1.values_by_name['NESTED_FACTORY_1_VALUE_1'].number)
+
+    enum2 = self.pool.FindEnumTypeByName(
+        'google.protobuf.python.internal.Factory2Enum')
+    self.assertIsInstance(enum2, descriptor.EnumDescriptor)
+    self.assertEquals(0, enum2.values_by_name['FACTORY_2_VALUE_0'].number)
+    self.assertEquals(1, enum2.values_by_name['FACTORY_2_VALUE_1'].number)
+
+    nested_enum2 = self.pool.FindEnumTypeByName(
+        'google.protobuf.python.internal.Factory2Message.NestedFactory2Enum')
+    self.assertIsInstance(nested_enum2, descriptor.EnumDescriptor)
+    self.assertEquals(
+        0, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_0'].number)
+    self.assertEquals(
+        1, nested_enum2.values_by_name['NESTED_FACTORY_2_VALUE_1'].number)
+
+  def testFindEnumTypeByNameFailure(self):
+    with self.assertRaises(KeyError):
+      self.pool.FindEnumTypeByName('Does not exist')
+
+  def testUserDefinedDB(self):
+    db = descriptor_database.DescriptorDatabase()
+    self.pool = descriptor_pool.DescriptorPool(db)
+    db.Add(self.factory_test1_fd)
+    db.Add(self.factory_test2_fd)
+    self.testFindMessageTypeByName()
+
+  def testComplexNesting(self):
+    test1_desc = descriptor_pb2.FileDescriptorProto.FromString(
+        descriptor_pool_test1_pb2.DESCRIPTOR.serialized_pb)
+    test2_desc = descriptor_pb2.FileDescriptorProto.FromString(
+        descriptor_pool_test2_pb2.DESCRIPTOR.serialized_pb)
+    self.pool.Add(test1_desc)
+    self.pool.Add(test2_desc)
+    TEST1_FILE.CheckFile(self, self.pool)
+    TEST2_FILE.CheckFile(self, self.pool)
+
+
+
+class ProtoFile(object):
+
+  def __init__(self, name, package, messages, dependencies=None):
+    self.name = name
+    self.package = package
+    self.messages = messages
+    self.dependencies = dependencies or []
+
+  def CheckFile(self, test, pool):
+    file_desc = pool.FindFileByName(self.name)
+    test.assertEquals(self.name, file_desc.name)
+    test.assertEquals(self.package, file_desc.package)
+    dependencies_names = [f.name for f in file_desc.dependencies]
+    test.assertEqual(self.dependencies, dependencies_names)
+    for name, msg_type in self.messages.items():
+      msg_type.CheckType(test, None, name, file_desc)
+
+
+class EnumType(object):
+
+  def __init__(self, values):
+    self.values = values
+
+  def CheckType(self, test, msg_desc, name, file_desc):
+    enum_desc = msg_desc.enum_types_by_name[name]
+    test.assertEqual(name, enum_desc.name)
+    expected_enum_full_name = '.'.join([msg_desc.full_name, name])
+    test.assertEqual(expected_enum_full_name, enum_desc.full_name)
+    test.assertEqual(msg_desc, enum_desc.containing_type)
+    test.assertEqual(file_desc, enum_desc.file)
+    for index, (value, number) in enumerate(self.values):
+      value_desc = enum_desc.values_by_name[value]
+      test.assertEqual(value, value_desc.name)
+      test.assertEqual(index, value_desc.index)
+      test.assertEqual(number, value_desc.number)
+      test.assertEqual(enum_desc, value_desc.type)
+      test.assertIn(value, msg_desc.enum_values_by_name)
+
+
+class MessageType(object):
+
+  def __init__(self, type_dict, field_list, is_extendable=False,
+               extensions=None):
+    self.type_dict = type_dict
+    self.field_list = field_list
+    self.is_extendable = is_extendable
+    self.extensions = extensions or []
+
+  def CheckType(self, test, containing_type_desc, name, file_desc):
+    if containing_type_desc is None:
+      desc = file_desc.message_types_by_name[name]
+      expected_full_name = '.'.join([file_desc.package, name])
+    else:
+      desc = containing_type_desc.nested_types_by_name[name]
+      expected_full_name = '.'.join([containing_type_desc.full_name, name])
+
+    test.assertEqual(name, desc.name)
+    test.assertEqual(expected_full_name, desc.full_name)
+    test.assertEqual(containing_type_desc, desc.containing_type)
+    test.assertEqual(desc.file, file_desc)
+    test.assertEqual(self.is_extendable, desc.is_extendable)
+    for name, subtype in self.type_dict.items():
+      subtype.CheckType(test, desc, name, file_desc)
+
+    for index, (name, field) in enumerate(self.field_list):
+      field.CheckField(test, desc, name, index)
+
+    for index, (name, field) in enumerate(self.extensions):
+      field.CheckField(test, desc, name, index)
+
+
+class EnumField(object):
+
+  def __init__(self, number, type_name, default_value):
+    self.number = number
+    self.type_name = type_name
+    self.default_value = default_value
+
+  def CheckField(self, test, msg_desc, name, index):
+    field_desc = msg_desc.fields_by_name[name]
+    enum_desc = msg_desc.enum_types_by_name[self.type_name]
+    test.assertEqual(name, field_desc.name)
+    expected_field_full_name = '.'.join([msg_desc.full_name, name])
+    test.assertEqual(expected_field_full_name, field_desc.full_name)
+    test.assertEqual(index, field_desc.index)
+    test.assertEqual(self.number, field_desc.number)
+    test.assertEqual(descriptor.FieldDescriptor.TYPE_ENUM, field_desc.type)
+    test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_ENUM,
+                     field_desc.cpp_type)
+    test.assertTrue(field_desc.has_default_value)
+    test.assertEqual(enum_desc.values_by_name[self.default_value].index,
+                     field_desc.default_value)
+    test.assertEqual(msg_desc, field_desc.containing_type)
+    test.assertEqual(enum_desc, field_desc.enum_type)
+
+
+class MessageField(object):
+
+  def __init__(self, number, type_name):
+    self.number = number
+    self.type_name = type_name
+
+  def CheckField(self, test, msg_desc, name, index):
+    field_desc = msg_desc.fields_by_name[name]
+    field_type_desc = msg_desc.nested_types_by_name[self.type_name]
+    test.assertEqual(name, field_desc.name)
+    expected_field_full_name = '.'.join([msg_desc.full_name, name])
+    test.assertEqual(expected_field_full_name, field_desc.full_name)
+    test.assertEqual(index, field_desc.index)
+    test.assertEqual(self.number, field_desc.number)
+    test.assertEqual(descriptor.FieldDescriptor.TYPE_MESSAGE, field_desc.type)
+    test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_MESSAGE,
+                     field_desc.cpp_type)
+    test.assertFalse(field_desc.has_default_value)
+    test.assertEqual(msg_desc, field_desc.containing_type)
+    test.assertEqual(field_type_desc, field_desc.message_type)
+
+
+class StringField(object):
+
+  def __init__(self, number, default_value):
+    self.number = number
+    self.default_value = default_value
+
+  def CheckField(self, test, msg_desc, name, index):
+    field_desc = msg_desc.fields_by_name[name]
+    test.assertEqual(name, field_desc.name)
+    expected_field_full_name = '.'.join([msg_desc.full_name, name])
+    test.assertEqual(expected_field_full_name, field_desc.full_name)
+    test.assertEqual(index, field_desc.index)
+    test.assertEqual(self.number, field_desc.number)
+    test.assertEqual(descriptor.FieldDescriptor.TYPE_STRING, field_desc.type)
+    test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_STRING,
+                     field_desc.cpp_type)
+    test.assertTrue(field_desc.has_default_value)
+    test.assertEqual(self.default_value, field_desc.default_value)
+
+
+class ExtensionField(object):
+
+  def __init__(self, number, extended_type):
+    self.number = number
+    self.extended_type = extended_type
+
+  def CheckField(self, test, msg_desc, name, index):
+    field_desc = msg_desc.extensions_by_name[name]
+    test.assertEqual(name, field_desc.name)
+    expected_field_full_name = '.'.join([msg_desc.full_name, name])
+    test.assertEqual(expected_field_full_name, field_desc.full_name)
+    test.assertEqual(self.number, field_desc.number)
+    test.assertEqual(index, field_desc.index)
+    test.assertEqual(descriptor.FieldDescriptor.TYPE_MESSAGE, field_desc.type)
+    test.assertEqual(descriptor.FieldDescriptor.CPPTYPE_MESSAGE,
+                     field_desc.cpp_type)
+    test.assertFalse(field_desc.has_default_value)
+    test.assertTrue(field_desc.is_extension)
+    test.assertEqual(msg_desc, field_desc.extension_scope)
+    test.assertEqual(msg_desc, field_desc.message_type)
+    test.assertEqual(self.extended_type, field_desc.containing_type.name)
+
+
+class AddDescriptorTest(basetest.TestCase):
+
+  def _TestMessage(self, prefix):
+    pool = descriptor_pool.DescriptorPool()
+    pool.AddDescriptor(unittest_pb2.TestAllTypes.DESCRIPTOR)
+    self.assertEquals(
+        'protobuf_unittest.TestAllTypes',
+        pool.FindMessageTypeByName(
+            prefix + 'protobuf_unittest.TestAllTypes').full_name)
+
+    # AddDescriptor is not recursive.
+    with self.assertRaises(KeyError):
+      pool.FindMessageTypeByName(
+          prefix + 'protobuf_unittest.TestAllTypes.NestedMessage')
+
+    pool.AddDescriptor(unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR)
+    self.assertEquals(
+        'protobuf_unittest.TestAllTypes.NestedMessage',
+        pool.FindMessageTypeByName(
+            prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').full_name)
+
+    # Files are implicitly also indexed when messages are added.
+    self.assertEquals(
+        'google/protobuf/unittest.proto',
+        pool.FindFileByName(
+            'google/protobuf/unittest.proto').name)
+
+    self.assertEquals(
+        'google/protobuf/unittest.proto',
+        pool.FindFileContainingSymbol(
+            prefix + 'protobuf_unittest.TestAllTypes.NestedMessage').name)
+
+  def testMessage(self):
+    self._TestMessage('')
+    self._TestMessage('.')
+
+  def _TestEnum(self, prefix):
+    pool = descriptor_pool.DescriptorPool()
+    pool.AddEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
+    self.assertEquals(
+        'protobuf_unittest.ForeignEnum',
+        pool.FindEnumTypeByName(
+            prefix + 'protobuf_unittest.ForeignEnum').full_name)
+
+    # AddEnumDescriptor is not recursive.
+    with self.assertRaises(KeyError):
+      pool.FindEnumTypeByName(
+          prefix + 'protobuf_unittest.ForeignEnum.NestedEnum')
+
+    pool.AddEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
+    self.assertEquals(
+        'protobuf_unittest.TestAllTypes.NestedEnum',
+        pool.FindEnumTypeByName(
+            prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').full_name)
+
+    # Files are implicitly also indexed when enums are added.
+    self.assertEquals(
+        'google/protobuf/unittest.proto',
+        pool.FindFileByName(
+            'google/protobuf/unittest.proto').name)
+
+    self.assertEquals(
+        'google/protobuf/unittest.proto',
+        pool.FindFileContainingSymbol(
+            prefix + 'protobuf_unittest.TestAllTypes.NestedEnum').name)
+
+  def testEnum(self):
+    self._TestEnum('')
+    self._TestEnum('.')
+
+  def testFile(self):
+    pool = descriptor_pool.DescriptorPool()
+    pool.AddFileDescriptor(unittest_pb2.DESCRIPTOR)
+    self.assertEquals(
+        'google/protobuf/unittest.proto',
+        pool.FindFileByName(
+            'google/protobuf/unittest.proto').name)
+
+    # AddFileDescriptor is not recursive; messages and enums within files must
+    # be explicitly registered.
+    with self.assertRaises(KeyError):
+      pool.FindFileContainingSymbol(
+          'protobuf_unittest.TestAllTypes')
+
+
+TEST1_FILE = ProtoFile(
+    'google/protobuf/internal/descriptor_pool_test1.proto',
+    'google.protobuf.python.internal',
+    {
+        'DescriptorPoolTest1': MessageType({
+            'NestedEnum': EnumType([('ALPHA', 1), ('BETA', 2)]),
+            'NestedMessage': MessageType({
+                'NestedEnum': EnumType([('EPSILON', 5), ('ZETA', 6)]),
+                'DeepNestedMessage': MessageType({
+                    'NestedEnum': EnumType([('ETA', 7), ('THETA', 8)]),
+                }, [
+                    ('nested_enum', EnumField(1, 'NestedEnum', 'ETA')),
+                    ('nested_field', StringField(2, 'theta')),
+                ]),
+            }, [
+                ('nested_enum', EnumField(1, 'NestedEnum', 'ZETA')),
+                ('nested_field', StringField(2, 'beta')),
+                ('deep_nested_message', MessageField(3, 'DeepNestedMessage')),
+            ])
+        }, [
+            ('nested_enum', EnumField(1, 'NestedEnum', 'BETA')),
+            ('nested_message', MessageField(2, 'NestedMessage')),
+        ], is_extendable=True),
+
+        'DescriptorPoolTest2': MessageType({
+            'NestedEnum': EnumType([('GAMMA', 3), ('DELTA', 4)]),
+            'NestedMessage': MessageType({
+                'NestedEnum': EnumType([('IOTA', 9), ('KAPPA', 10)]),
+                'DeepNestedMessage': MessageType({
+                    'NestedEnum': EnumType([('LAMBDA', 11), ('MU', 12)]),
+                }, [
+                    ('nested_enum', EnumField(1, 'NestedEnum', 'MU')),
+                    ('nested_field', StringField(2, 'lambda')),
+                ]),
+            }, [
+                ('nested_enum', EnumField(1, 'NestedEnum', 'IOTA')),
+                ('nested_field', StringField(2, 'delta')),
+                ('deep_nested_message', MessageField(3, 'DeepNestedMessage')),
+            ])
+        }, [
+            ('nested_enum', EnumField(1, 'NestedEnum', 'GAMMA')),
+            ('nested_message', MessageField(2, 'NestedMessage')),
+        ]),
+    })
+
+
+TEST2_FILE = ProtoFile(
+    'google/protobuf/internal/descriptor_pool_test2.proto',
+    'google.protobuf.python.internal',
+    {
+        'DescriptorPoolTest3': MessageType({
+            'NestedEnum': EnumType([('NU', 13), ('XI', 14)]),
+            'NestedMessage': MessageType({
+                'NestedEnum': EnumType([('OMICRON', 15), ('PI', 16)]),
+                'DeepNestedMessage': MessageType({
+                    'NestedEnum': EnumType([('RHO', 17), ('SIGMA', 18)]),
+                }, [
+                    ('nested_enum', EnumField(1, 'NestedEnum', 'RHO')),
+                    ('nested_field', StringField(2, 'sigma')),
+                ]),
+            }, [
+                ('nested_enum', EnumField(1, 'NestedEnum', 'PI')),
+                ('nested_field', StringField(2, 'nu')),
+                ('deep_nested_message', MessageField(3, 'DeepNestedMessage')),
+            ])
+        }, [
+            ('nested_enum', EnumField(1, 'NestedEnum', 'XI')),
+            ('nested_message', MessageField(2, 'NestedMessage')),
+        ], extensions=[
+            ('descriptor_pool_test',
+             ExtensionField(1001, 'DescriptorPoolTest1')),
+        ]),
+    },
+    dependencies=['google/protobuf/internal/descriptor_pool_test1.proto'])
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/descriptor_pool_test1.proto b/protobuf/python/google/protobuf/internal/descriptor_pool_test1.proto
new file mode 100644
index 0000000..6dfe4ef
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/descriptor_pool_test1.proto
@@ -0,0 +1,94 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package google.protobuf.python.internal;
+
+
+message DescriptorPoolTest1 {
+  extensions 1000 to max;
+
+  enum NestedEnum {
+    ALPHA = 1;
+    BETA = 2;
+  }
+
+  optional NestedEnum nested_enum = 1 [default = BETA];
+
+  message NestedMessage {
+    enum NestedEnum {
+      EPSILON = 5;
+      ZETA = 6;
+    }
+    optional NestedEnum nested_enum = 1 [default = ZETA];
+    optional string nested_field = 2 [default = "beta"];
+    optional DeepNestedMessage deep_nested_message = 3;
+
+    message DeepNestedMessage {
+      enum NestedEnum {
+        ETA = 7;
+        THETA = 8;
+      }
+      optional NestedEnum nested_enum = 1 [default = ETA];
+      optional string nested_field = 2 [default = "theta"];
+    }
+  }
+
+  optional NestedMessage nested_message = 2;
+}
+
+message DescriptorPoolTest2 {
+  enum NestedEnum {
+    GAMMA = 3;
+    DELTA = 4;
+  }
+
+  optional NestedEnum nested_enum = 1 [default = GAMMA];
+
+  message NestedMessage {
+    enum NestedEnum {
+      IOTA = 9;
+      KAPPA = 10;
+    }
+    optional NestedEnum nested_enum = 1 [default = IOTA];
+    optional string nested_field = 2 [default = "delta"];
+    optional DeepNestedMessage deep_nested_message = 3;
+
+    message DeepNestedMessage {
+      enum NestedEnum {
+        LAMBDA = 11;
+        MU = 12;
+      }
+      optional NestedEnum nested_enum = 1 [default = MU];
+      optional string nested_field = 2 [default = "lambda"];
+    }
+  }
+
+  optional NestedMessage nested_message = 2;
+}
diff --git a/protobuf/python/google/protobuf/internal/descriptor_pool_test2.proto b/protobuf/python/google/protobuf/internal/descriptor_pool_test2.proto
new file mode 100644
index 0000000..fbc8438
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/descriptor_pool_test2.proto
@@ -0,0 +1,70 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package google.protobuf.python.internal;
+
+import "google/protobuf/internal/descriptor_pool_test1.proto";
+
+
+message DescriptorPoolTest3 {
+
+  extend DescriptorPoolTest1 {
+    optional DescriptorPoolTest3 descriptor_pool_test = 1001;
+  }
+
+  enum NestedEnum {
+    NU = 13;
+    XI = 14;
+  }
+
+  optional NestedEnum nested_enum = 1 [default = XI];
+
+  message NestedMessage {
+    enum NestedEnum {
+      OMICRON = 15;
+      PI = 16;
+    }
+    optional NestedEnum nested_enum = 1 [default = PI];
+    optional string nested_field = 2 [default = "nu"];
+    optional DeepNestedMessage deep_nested_message = 3;
+
+    message DeepNestedMessage {
+      enum NestedEnum {
+        RHO = 17;
+        SIGMA = 18;
+      }
+      optional NestedEnum nested_enum = 1 [default = RHO];
+      optional string nested_field = 2 [default = "sigma"];
+    }
+  }
+
+  optional NestedMessage nested_message = 2;
+}
+
diff --git a/protobuf/python/google/protobuf/internal/descriptor_python_test.py b/protobuf/python/google/protobuf/internal/descriptor_python_test.py
new file mode 100644
index 0000000..5471ae0
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/descriptor_python_test.py
@@ -0,0 +1,54 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unittest for descriptor.py for the pure Python implementation."""
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
+
+# We must set the implementation version above before the google3 imports.
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+# Run all tests from the original module by putting them in our namespace.
+# pylint: disable=wildcard-import
+from google.protobuf.internal.descriptor_test import *
+
+
+class ConfirmPurePythonTest(basetest.TestCase):
+
+  def testImplementationSetting(self):
+    self.assertEqual('python', api_implementation.Type())
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/descriptor_test.py b/protobuf/python/google/protobuf/internal/descriptor_test.py
new file mode 100755
index 0000000..b3777e3
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/descriptor_test.py
@@ -0,0 +1,669 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unittest for google.protobuf.internal.descriptor."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+from google.apputils import basetest
+from google.protobuf import unittest_custom_options_pb2
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor
+from google.protobuf import text_format
+
+
+TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII = """
+name: 'TestEmptyMessage'
+"""
+
+
+class DescriptorTest(basetest.TestCase):
+
+  def setUp(self):
+    self.my_file = descriptor.FileDescriptor(
+        name='some/filename/some.proto',
+        package='protobuf_unittest'
+        )
+    self.my_enum = descriptor.EnumDescriptor(
+        name='ForeignEnum',
+        full_name='protobuf_unittest.ForeignEnum',
+        filename=None,
+        file=self.my_file,
+        values=[
+          descriptor.EnumValueDescriptor(name='FOREIGN_FOO', index=0, number=4),
+          descriptor.EnumValueDescriptor(name='FOREIGN_BAR', index=1, number=5),
+          descriptor.EnumValueDescriptor(name='FOREIGN_BAZ', index=2, number=6),
+        ])
+    self.my_message = descriptor.Descriptor(
+        name='NestedMessage',
+        full_name='protobuf_unittest.TestAllTypes.NestedMessage',
+        filename=None,
+        file=self.my_file,
+        containing_type=None,
+        fields=[
+          descriptor.FieldDescriptor(
+            name='bb',
+            full_name='protobuf_unittest.TestAllTypes.NestedMessage.bb',
+            index=0, number=1,
+            type=5, cpp_type=1, label=1,
+            has_default_value=False, default_value=0,
+            message_type=None, enum_type=None, containing_type=None,
+            is_extension=False, extension_scope=None),
+        ],
+        nested_types=[],
+        enum_types=[
+          self.my_enum,
+        ],
+        extensions=[])
+    self.my_method = descriptor.MethodDescriptor(
+        name='Bar',
+        full_name='protobuf_unittest.TestService.Bar',
+        index=0,
+        containing_service=None,
+        input_type=None,
+        output_type=None)
+    self.my_service = descriptor.ServiceDescriptor(
+        name='TestServiceWithOptions',
+        full_name='protobuf_unittest.TestServiceWithOptions',
+        file=self.my_file,
+        index=0,
+        methods=[
+            self.my_method
+        ])
+
+  def testEnumValueName(self):
+    self.assertEqual(self.my_message.EnumValueName('ForeignEnum', 4),
+                     'FOREIGN_FOO')
+
+    self.assertEqual(
+        self.my_message.enum_types_by_name[
+            'ForeignEnum'].values_by_number[4].name,
+        self.my_message.EnumValueName('ForeignEnum', 4))
+
+  def testEnumFixups(self):
+    self.assertEqual(self.my_enum, self.my_enum.values[0].type)
+
+  def testContainingTypeFixups(self):
+    self.assertEqual(self.my_message, self.my_message.fields[0].containing_type)
+    self.assertEqual(self.my_message, self.my_enum.containing_type)
+
+  def testContainingServiceFixups(self):
+    self.assertEqual(self.my_service, self.my_method.containing_service)
+
+  def testGetOptions(self):
+    self.assertEqual(self.my_enum.GetOptions(),
+                     descriptor_pb2.EnumOptions())
+    self.assertEqual(self.my_enum.values[0].GetOptions(),
+                     descriptor_pb2.EnumValueOptions())
+    self.assertEqual(self.my_message.GetOptions(),
+                     descriptor_pb2.MessageOptions())
+    self.assertEqual(self.my_message.fields[0].GetOptions(),
+                     descriptor_pb2.FieldOptions())
+    self.assertEqual(self.my_method.GetOptions(),
+                     descriptor_pb2.MethodOptions())
+    self.assertEqual(self.my_service.GetOptions(),
+                     descriptor_pb2.ServiceOptions())
+
+  def testSimpleCustomOptions(self):
+    file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
+    message_descriptor =\
+        unittest_custom_options_pb2.TestMessageWithCustomOptions.DESCRIPTOR
+    field_descriptor = message_descriptor.fields_by_name["field1"]
+    enum_descriptor = message_descriptor.enum_types_by_name["AnEnum"]
+    enum_value_descriptor =\
+        message_descriptor.enum_values_by_name["ANENUM_VAL2"]
+    service_descriptor =\
+        unittest_custom_options_pb2.TestServiceWithCustomOptions.DESCRIPTOR
+    method_descriptor = service_descriptor.FindMethodByName("Foo")
+
+    file_options = file_descriptor.GetOptions()
+    file_opt1 = unittest_custom_options_pb2.file_opt1
+    self.assertEqual(9876543210, file_options.Extensions[file_opt1])
+    message_options = message_descriptor.GetOptions()
+    message_opt1 = unittest_custom_options_pb2.message_opt1
+    self.assertEqual(-56, message_options.Extensions[message_opt1])
+    field_options = field_descriptor.GetOptions()
+    field_opt1 = unittest_custom_options_pb2.field_opt1
+    self.assertEqual(8765432109, field_options.Extensions[field_opt1])
+    field_opt2 = unittest_custom_options_pb2.field_opt2
+    self.assertEqual(42, field_options.Extensions[field_opt2])
+    enum_options = enum_descriptor.GetOptions()
+    enum_opt1 = unittest_custom_options_pb2.enum_opt1
+    self.assertEqual(-789, enum_options.Extensions[enum_opt1])
+    enum_value_options = enum_value_descriptor.GetOptions()
+    enum_value_opt1 = unittest_custom_options_pb2.enum_value_opt1
+    self.assertEqual(123, enum_value_options.Extensions[enum_value_opt1])
+
+    service_options = service_descriptor.GetOptions()
+    service_opt1 = unittest_custom_options_pb2.service_opt1
+    self.assertEqual(-9876543210, service_options.Extensions[service_opt1])
+    method_options = method_descriptor.GetOptions()
+    method_opt1 = unittest_custom_options_pb2.method_opt1
+    self.assertEqual(unittest_custom_options_pb2.METHODOPT1_VAL2,
+                     method_options.Extensions[method_opt1])
+
+  def testDifferentCustomOptionTypes(self):
+    kint32min = -2**31
+    kint64min = -2**63
+    kint32max = 2**31 - 1
+    kint64max = 2**63 - 1
+    kuint32max = 2**32 - 1
+    kuint64max = 2**64 - 1
+
+    message_descriptor =\
+        unittest_custom_options_pb2.CustomOptionMinIntegerValues.DESCRIPTOR
+    message_options = message_descriptor.GetOptions()
+    self.assertEqual(False, message_options.Extensions[
+        unittest_custom_options_pb2.bool_opt])
+    self.assertEqual(kint32min, message_options.Extensions[
+        unittest_custom_options_pb2.int32_opt])
+    self.assertEqual(kint64min, message_options.Extensions[
+        unittest_custom_options_pb2.int64_opt])
+    self.assertEqual(0, message_options.Extensions[
+        unittest_custom_options_pb2.uint32_opt])
+    self.assertEqual(0, message_options.Extensions[
+        unittest_custom_options_pb2.uint64_opt])
+    self.assertEqual(kint32min, message_options.Extensions[
+        unittest_custom_options_pb2.sint32_opt])
+    self.assertEqual(kint64min, message_options.Extensions[
+        unittest_custom_options_pb2.sint64_opt])
+    self.assertEqual(0, message_options.Extensions[
+        unittest_custom_options_pb2.fixed32_opt])
+    self.assertEqual(0, message_options.Extensions[
+        unittest_custom_options_pb2.fixed64_opt])
+    self.assertEqual(kint32min, message_options.Extensions[
+        unittest_custom_options_pb2.sfixed32_opt])
+    self.assertEqual(kint64min, message_options.Extensions[
+        unittest_custom_options_pb2.sfixed64_opt])
+
+    message_descriptor =\
+        unittest_custom_options_pb2.CustomOptionMaxIntegerValues.DESCRIPTOR
+    message_options = message_descriptor.GetOptions()
+    self.assertEqual(True, message_options.Extensions[
+        unittest_custom_options_pb2.bool_opt])
+    self.assertEqual(kint32max, message_options.Extensions[
+        unittest_custom_options_pb2.int32_opt])
+    self.assertEqual(kint64max, message_options.Extensions[
+        unittest_custom_options_pb2.int64_opt])
+    self.assertEqual(kuint32max, message_options.Extensions[
+        unittest_custom_options_pb2.uint32_opt])
+    self.assertEqual(kuint64max, message_options.Extensions[
+        unittest_custom_options_pb2.uint64_opt])
+    self.assertEqual(kint32max, message_options.Extensions[
+        unittest_custom_options_pb2.sint32_opt])
+    self.assertEqual(kint64max, message_options.Extensions[
+        unittest_custom_options_pb2.sint64_opt])
+    self.assertEqual(kuint32max, message_options.Extensions[
+        unittest_custom_options_pb2.fixed32_opt])
+    self.assertEqual(kuint64max, message_options.Extensions[
+        unittest_custom_options_pb2.fixed64_opt])
+    self.assertEqual(kint32max, message_options.Extensions[
+        unittest_custom_options_pb2.sfixed32_opt])
+    self.assertEqual(kint64max, message_options.Extensions[
+        unittest_custom_options_pb2.sfixed64_opt])
+
+    message_descriptor =\
+        unittest_custom_options_pb2.CustomOptionOtherValues.DESCRIPTOR
+    message_options = message_descriptor.GetOptions()
+    self.assertEqual(-100, message_options.Extensions[
+        unittest_custom_options_pb2.int32_opt])
+    self.assertAlmostEqual(12.3456789, message_options.Extensions[
+        unittest_custom_options_pb2.float_opt], 6)
+    self.assertAlmostEqual(1.234567890123456789, message_options.Extensions[
+        unittest_custom_options_pb2.double_opt])
+    self.assertEqual("Hello, \"World\"", message_options.Extensions[
+        unittest_custom_options_pb2.string_opt])
+    self.assertEqual(b"Hello\0World", message_options.Extensions[
+        unittest_custom_options_pb2.bytes_opt])
+    dummy_enum = unittest_custom_options_pb2.DummyMessageContainingEnum
+    self.assertEqual(
+        dummy_enum.TEST_OPTION_ENUM_TYPE2,
+        message_options.Extensions[unittest_custom_options_pb2.enum_opt])
+
+    message_descriptor =\
+        unittest_custom_options_pb2.SettingRealsFromPositiveInts.DESCRIPTOR
+    message_options = message_descriptor.GetOptions()
+    self.assertAlmostEqual(12, message_options.Extensions[
+        unittest_custom_options_pb2.float_opt], 6)
+    self.assertAlmostEqual(154, message_options.Extensions[
+        unittest_custom_options_pb2.double_opt])
+
+    message_descriptor =\
+        unittest_custom_options_pb2.SettingRealsFromNegativeInts.DESCRIPTOR
+    message_options = message_descriptor.GetOptions()
+    self.assertAlmostEqual(-12, message_options.Extensions[
+        unittest_custom_options_pb2.float_opt], 6)
+    self.assertAlmostEqual(-154, message_options.Extensions[
+        unittest_custom_options_pb2.double_opt])
+
+  def testComplexExtensionOptions(self):
+    descriptor =\
+        unittest_custom_options_pb2.VariousComplexOptions.DESCRIPTOR
+    options = descriptor.GetOptions()
+    self.assertEqual(42, options.Extensions[
+        unittest_custom_options_pb2.complex_opt1].foo)
+    self.assertEqual(324, options.Extensions[
+        unittest_custom_options_pb2.complex_opt1].Extensions[
+            unittest_custom_options_pb2.quux])
+    self.assertEqual(876, options.Extensions[
+        unittest_custom_options_pb2.complex_opt1].Extensions[
+            unittest_custom_options_pb2.corge].qux)
+    self.assertEqual(987, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].baz)
+    self.assertEqual(654, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].Extensions[
+            unittest_custom_options_pb2.grault])
+    self.assertEqual(743, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].bar.foo)
+    self.assertEqual(1999, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].bar.Extensions[
+            unittest_custom_options_pb2.quux])
+    self.assertEqual(2008, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].bar.Extensions[
+            unittest_custom_options_pb2.corge].qux)
+    self.assertEqual(741, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].Extensions[
+            unittest_custom_options_pb2.garply].foo)
+    self.assertEqual(1998, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].Extensions[
+            unittest_custom_options_pb2.garply].Extensions[
+                unittest_custom_options_pb2.quux])
+    self.assertEqual(2121, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].Extensions[
+            unittest_custom_options_pb2.garply].Extensions[
+                unittest_custom_options_pb2.corge].qux)
+    self.assertEqual(1971, options.Extensions[
+        unittest_custom_options_pb2.ComplexOptionType2
+        .ComplexOptionType4.complex_opt4].waldo)
+    self.assertEqual(321, options.Extensions[
+        unittest_custom_options_pb2.complex_opt2].fred.waldo)
+    self.assertEqual(9, options.Extensions[
+        unittest_custom_options_pb2.complex_opt3].qux)
+    self.assertEqual(22, options.Extensions[
+        unittest_custom_options_pb2.complex_opt3].complexoptiontype5.plugh)
+    self.assertEqual(24, options.Extensions[
+        unittest_custom_options_pb2.complexopt6].xyzzy)
+
+  # Check that aggregate options were parsed and saved correctly in
+  # the appropriate descriptors.
+  def testAggregateOptions(self):
+    file_descriptor = unittest_custom_options_pb2.DESCRIPTOR
+    message_descriptor =\
+        unittest_custom_options_pb2.AggregateMessage.DESCRIPTOR
+    field_descriptor = message_descriptor.fields_by_name["fieldname"]
+    enum_descriptor = unittest_custom_options_pb2.AggregateEnum.DESCRIPTOR
+    enum_value_descriptor = enum_descriptor.values_by_name["VALUE"]
+    service_descriptor =\
+        unittest_custom_options_pb2.AggregateService.DESCRIPTOR
+    method_descriptor = service_descriptor.FindMethodByName("Method")
+
+    # Tests for the different types of data embedded in fileopt
+    file_options = file_descriptor.GetOptions().Extensions[
+        unittest_custom_options_pb2.fileopt]
+    self.assertEqual(100, file_options.i)
+    self.assertEqual("FileAnnotation", file_options.s)
+    self.assertEqual("NestedFileAnnotation", file_options.sub.s)
+    self.assertEqual("FileExtensionAnnotation", file_options.file.Extensions[
+        unittest_custom_options_pb2.fileopt].s)
+    self.assertEqual("EmbeddedMessageSetElement", file_options.mset.Extensions[
+        unittest_custom_options_pb2.AggregateMessageSetElement
+        .message_set_extension].s)
+
+    # Simple tests for all the other types of annotations
+    self.assertEqual(
+        "MessageAnnotation",
+        message_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.msgopt].s)
+    self.assertEqual(
+        "FieldAnnotation",
+        field_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.fieldopt].s)
+    self.assertEqual(
+        "EnumAnnotation",
+        enum_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.enumopt].s)
+    self.assertEqual(
+        "EnumValueAnnotation",
+        enum_value_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.enumvalopt].s)
+    self.assertEqual(
+        "ServiceAnnotation",
+        service_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.serviceopt].s)
+    self.assertEqual(
+        "MethodAnnotation",
+        method_descriptor.GetOptions().Extensions[
+            unittest_custom_options_pb2.methodopt].s)
+
+  def testNestedOptions(self):
+    nested_message =\
+        unittest_custom_options_pb2.NestedOptionType.NestedMessage.DESCRIPTOR
+    self.assertEqual(1001, nested_message.GetOptions().Extensions[
+        unittest_custom_options_pb2.message_opt1])
+    nested_field = nested_message.fields_by_name["nested_field"]
+    self.assertEqual(1002, nested_field.GetOptions().Extensions[
+        unittest_custom_options_pb2.field_opt1])
+    outer_message =\
+        unittest_custom_options_pb2.NestedOptionType.DESCRIPTOR
+    nested_enum = outer_message.enum_types_by_name["NestedEnum"]
+    self.assertEqual(1003, nested_enum.GetOptions().Extensions[
+        unittest_custom_options_pb2.enum_opt1])
+    nested_enum_value = outer_message.enum_values_by_name["NESTED_ENUM_VALUE"]
+    self.assertEqual(1004, nested_enum_value.GetOptions().Extensions[
+        unittest_custom_options_pb2.enum_value_opt1])
+    nested_extension = outer_message.extensions_by_name["nested_extension"]
+    self.assertEqual(1005, nested_extension.GetOptions().Extensions[
+        unittest_custom_options_pb2.field_opt2])
+
+  def testFileDescriptorReferences(self):
+    self.assertEqual(self.my_enum.file, self.my_file)
+    self.assertEqual(self.my_message.file, self.my_file)
+
+  def testFileDescriptor(self):
+    self.assertEqual(self.my_file.name, 'some/filename/some.proto')
+    self.assertEqual(self.my_file.package, 'protobuf_unittest')
+
+
+class DescriptorCopyToProtoTest(basetest.TestCase):
+  """Tests for CopyTo functions of Descriptor."""
+
+  def _AssertProtoEqual(self, actual_proto, expected_class, expected_ascii):
+    expected_proto = expected_class()
+    text_format.Merge(expected_ascii, expected_proto)
+
+    self.assertEqual(
+        actual_proto, expected_proto,
+        'Not equal,\nActual:\n%s\nExpected:\n%s\n'
+        % (str(actual_proto), str(expected_proto)))
+
+  def _InternalTestCopyToProto(self, desc, expected_proto_class,
+                               expected_proto_ascii):
+    actual = expected_proto_class()
+    desc.CopyToProto(actual)
+    self._AssertProtoEqual(
+        actual, expected_proto_class, expected_proto_ascii)
+
+  def testCopyToProto_EmptyMessage(self):
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestEmptyMessage.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_EMPTY_MESSAGE_DESCRIPTOR_ASCII)
+
+  def testCopyToProto_NestedMessage(self):
+    TEST_NESTED_MESSAGE_ASCII = """
+      name: 'NestedMessage'
+      field: <
+        name: 'bb'
+        number: 1
+        label: 1  # Optional
+        type: 5  # TYPE_INT32
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_NESTED_MESSAGE_ASCII)
+
+  def testCopyToProto_ForeignNestedMessage(self):
+    TEST_FOREIGN_NESTED_ASCII = """
+      name: 'TestForeignNested'
+      field: <
+        name: 'foreign_nested'
+        number: 1
+        label: 1  # Optional
+        type: 11  # TYPE_MESSAGE
+        type_name: '.protobuf_unittest.TestAllTypes.NestedMessage'
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestForeignNested.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_FOREIGN_NESTED_ASCII)
+
+  def testCopyToProto_ForeignEnum(self):
+    TEST_FOREIGN_ENUM_ASCII = """
+      name: 'ForeignEnum'
+      value: <
+        name: 'FOREIGN_FOO'
+        number: 4
+      >
+      value: <
+        name: 'FOREIGN_BAR'
+        number: 5
+      >
+      value: <
+        name: 'FOREIGN_BAZ'
+        number: 6
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2._FOREIGNENUM,
+        descriptor_pb2.EnumDescriptorProto,
+        TEST_FOREIGN_ENUM_ASCII)
+
+  def testCopyToProto_Options(self):
+    TEST_DEPRECATED_FIELDS_ASCII = """
+      name: 'TestDeprecatedFields'
+      field: <
+        name: 'deprecated_int32'
+        number: 1
+        label: 1  # Optional
+        type: 5  # TYPE_INT32
+        options: <
+          deprecated: true
+        >
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestDeprecatedFields.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_DEPRECATED_FIELDS_ASCII)
+
+  def testCopyToProto_AllExtensions(self):
+    TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII = """
+      name: 'TestEmptyMessageWithExtensions'
+      extension_range: <
+        start: 1
+        end: 536870912
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestEmptyMessageWithExtensions.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_EMPTY_MESSAGE_WITH_EXTENSIONS_ASCII)
+
+  def testCopyToProto_SeveralExtensions(self):
+    TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII = """
+      name: 'TestMultipleExtensionRanges'
+      extension_range: <
+        start: 42
+        end: 43
+      >
+      extension_range: <
+        start: 4143
+        end: 4244
+      >
+      extension_range: <
+        start: 65536
+        end: 536870912
+      >
+      """
+
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR,
+        descriptor_pb2.DescriptorProto,
+        TEST_MESSAGE_WITH_SEVERAL_EXTENSIONS_ASCII)
+
+  # Disable this test so we can make changes to the proto file.
+  # TODO(xiaofeng): Enable this test after cl/55530659 is submitted.
+  #
+  # def testCopyToProto_FileDescriptor(self):
+  #   UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII = ("""
+  #     name: 'google/protobuf/unittest_import.proto'
+  #     package: 'protobuf_unittest_import'
+  #     dependency: 'google/protobuf/unittest_import_public.proto'
+  #     message_type: <
+  #       name: 'ImportMessage'
+  #       field: <
+  #         name: 'd'
+  #         number: 1
+  #         label: 1  # Optional
+  #         type: 5  # TYPE_INT32
+  #       >
+  #     >
+  #     """ +
+  #     """enum_type: <
+  #       name: 'ImportEnum'
+  #       value: <
+  #         name: 'IMPORT_FOO'
+  #         number: 7
+  #       >
+  #       value: <
+  #         name: 'IMPORT_BAR'
+  #         number: 8
+  #       >
+  #       value: <
+  #         name: 'IMPORT_BAZ'
+  #         number: 9
+  #       >
+  #     >
+  #     options: <
+  #       java_package: 'com.google.protobuf.test'
+  #       optimize_for: 1  # SPEED
+  #     >
+  #     public_dependency: 0
+  #  """)
+  #  self._InternalTestCopyToProto(
+  #      unittest_import_pb2.DESCRIPTOR,
+  #      descriptor_pb2.FileDescriptorProto,
+  #      UNITTEST_IMPORT_FILE_DESCRIPTOR_ASCII)
+
+  def testCopyToProto_ServiceDescriptor(self):
+    TEST_SERVICE_ASCII = """
+      name: 'TestService'
+      method: <
+        name: 'Foo'
+        input_type: '.protobuf_unittest.FooRequest'
+        output_type: '.protobuf_unittest.FooResponse'
+      >
+      method: <
+        name: 'Bar'
+        input_type: '.protobuf_unittest.BarRequest'
+        output_type: '.protobuf_unittest.BarResponse'
+      >
+      """
+    self._InternalTestCopyToProto(
+        unittest_pb2.TestService.DESCRIPTOR,
+        descriptor_pb2.ServiceDescriptorProto,
+        TEST_SERVICE_ASCII)
+
+
+class MakeDescriptorTest(basetest.TestCase):
+
+  def testMakeDescriptorWithNestedFields(self):
+    file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+    file_descriptor_proto.name = 'Foo2'
+    message_type = file_descriptor_proto.message_type.add()
+    message_type.name = file_descriptor_proto.name
+    nested_type = message_type.nested_type.add()
+    nested_type.name = 'Sub'
+    enum_type = nested_type.enum_type.add()
+    enum_type.name = 'FOO'
+    enum_type_val = enum_type.value.add()
+    enum_type_val.name = 'BAR'
+    enum_type_val.number = 3
+    field = message_type.field.add()
+    field.number = 1
+    field.name = 'uint64_field'
+    field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+    field.type = descriptor.FieldDescriptor.TYPE_UINT64
+    field = message_type.field.add()
+    field.number = 2
+    field.name = 'nested_message_field'
+    field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+    field.type = descriptor.FieldDescriptor.TYPE_MESSAGE
+    field.type_name = 'Sub'
+    enum_field = nested_type.field.add()
+    enum_field.number = 2
+    enum_field.name = 'bar_field'
+    enum_field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+    enum_field.type = descriptor.FieldDescriptor.TYPE_ENUM
+    enum_field.type_name = 'Foo2.Sub.FOO'
+
+    result = descriptor.MakeDescriptor(message_type)
+    self.assertEqual(result.fields[0].cpp_type,
+                     descriptor.FieldDescriptor.CPPTYPE_UINT64)
+    self.assertEqual(result.fields[1].cpp_type,
+                     descriptor.FieldDescriptor.CPPTYPE_MESSAGE)
+    self.assertEqual(result.fields[1].message_type.containing_type,
+                     result)
+    self.assertEqual(result.nested_types[0].fields[0].full_name,
+                     'Foo2.Sub.bar_field')
+    self.assertEqual(result.nested_types[0].fields[0].enum_type,
+                     result.nested_types[0].enum_types[0])
+
+  def testMakeDescriptorWithUnsignedIntField(self):
+    file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+    file_descriptor_proto.name = 'Foo'
+    message_type = file_descriptor_proto.message_type.add()
+    message_type.name = file_descriptor_proto.name
+    enum_type = message_type.enum_type.add()
+    enum_type.name = 'FOO'
+    enum_type_val = enum_type.value.add()
+    enum_type_val.name = 'BAR'
+    enum_type_val.number = 3
+    field = message_type.field.add()
+    field.number = 1
+    field.name = 'uint64_field'
+    field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+    field.type = descriptor.FieldDescriptor.TYPE_UINT64
+    enum_field = message_type.field.add()
+    enum_field.number = 2
+    enum_field.name = 'bar_field'
+    enum_field.label = descriptor.FieldDescriptor.LABEL_REQUIRED
+    enum_field.type = descriptor.FieldDescriptor.TYPE_ENUM
+    enum_field.type_name = 'Foo.FOO'
+
+    result = descriptor.MakeDescriptor(message_type)
+    self.assertEqual(result.fields[0].cpp_type,
+                     descriptor.FieldDescriptor.CPPTYPE_UINT64)
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/encoder.py b/protobuf/python/google/protobuf/internal/encoder.py
new file mode 100755
index 0000000..38a5138
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/encoder.py
@@ -0,0 +1,788 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#PY25 compatible for GAE.
+#
+# Copyright 2009 Google Inc. All Rights Reserved.
+
+"""Code for encoding protocol message primitives.
+
+Contains the logic for encoding every logical protocol field type
+into one of the 5 physical wire types.
+
+This code is designed to push the Python interpreter's performance to the
+limits.
+
+The basic idea is that at startup time, for every field (i.e. every
+FieldDescriptor) we construct two functions:  a "sizer" and an "encoder".  The
+sizer takes a value of this field's type and computes its byte size.  The
+encoder takes a writer function and a value.  It encodes the value into byte
+strings and invokes the writer function to write those strings.  Typically the
+writer function is the write() method of a cStringIO.
+
+We try to do as much work as possible when constructing the writer and the
+sizer rather than when calling them.  In particular:
+* We copy any needed global functions to local variables, so that we do not need
+  to do costly global table lookups at runtime.
+* Similarly, we try to do any attribute lookups at startup time if possible.
+* Every field's tag is encoded to bytes at startup, since it can't change at
+  runtime.
+* Whatever component of the field size we can compute at startup, we do.
+* We *avoid* sharing code if doing so would make the code slower and not sharing
+  does not burden us too much.  For example, encoders for repeated fields do
+  not just call the encoders for singular fields in a loop because this would
+  add an extra function call overhead for every loop iteration; instead, we
+  manually inline the single-value encoder into the loop.
+* If a Python function lacks a return statement, Python actually generates
+  instructions to pop the result of the last statement off the stack, push
+  None onto the stack, and then return that.  If we really don't care what
+  value is returned, then we can save two instructions by returning the
+  result of the last statement.  It looks funny but it helps.
+* We assume that type and bounds checking has happened at a higher level.
+"""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+import struct
+import sys  ##PY25
+_PY2 = sys.version_info[0] < 3  ##PY25
+from google.protobuf.internal import wire_format
+
+
+# This will overflow and thus become IEEE-754 "infinity".  We would use
+# "float('inf')" but it doesn't work on Windows pre-Python-2.6.
+_POS_INF = 1e10000
+_NEG_INF = -_POS_INF
+
+
+def _VarintSize(value):
+  """Compute the size of a varint value."""
+  if value <= 0x7f: return 1
+  if value <= 0x3fff: return 2
+  if value <= 0x1fffff: return 3
+  if value <= 0xfffffff: return 4
+  if value <= 0x7ffffffff: return 5
+  if value <= 0x3ffffffffff: return 6
+  if value <= 0x1ffffffffffff: return 7
+  if value <= 0xffffffffffffff: return 8
+  if value <= 0x7fffffffffffffff: return 9
+  return 10
+
+
+def _SignedVarintSize(value):
+  """Compute the size of a signed varint value."""
+  if value < 0: return 10
+  if value <= 0x7f: return 1
+  if value <= 0x3fff: return 2
+  if value <= 0x1fffff: return 3
+  if value <= 0xfffffff: return 4
+  if value <= 0x7ffffffff: return 5
+  if value <= 0x3ffffffffff: return 6
+  if value <= 0x1ffffffffffff: return 7
+  if value <= 0xffffffffffffff: return 8
+  if value <= 0x7fffffffffffffff: return 9
+  return 10
+
+
+def _TagSize(field_number):
+  """Returns the number of bytes required to serialize a tag with this field
+  number."""
+  # Just pass in type 0, since the type won't affect the tag+type size.
+  return _VarintSize(wire_format.PackTag(field_number, 0))
+
+
+# --------------------------------------------------------------------
+# In this section we define some generic sizers.  Each of these functions
+# takes parameters specific to a particular field type, e.g. int32 or fixed64.
+# It returns another function which in turn takes parameters specific to a
+# particular field, e.g. the field number and whether it is repeated or packed.
+# Look at the next section to see how these are used.
+
+
+def _SimpleSizer(compute_value_size):
+  """A sizer which uses the function compute_value_size to compute the size of
+  each value.  Typically compute_value_size is _VarintSize."""
+
+  def SpecificSizer(field_number, is_repeated, is_packed):
+    tag_size = _TagSize(field_number)
+    if is_packed:
+      local_VarintSize = _VarintSize
+      def PackedFieldSize(value):
+        result = 0
+        for element in value:
+          result += compute_value_size(element)
+        return result + local_VarintSize(result) + tag_size
+      return PackedFieldSize
+    elif is_repeated:
+      def RepeatedFieldSize(value):
+        result = tag_size * len(value)
+        for element in value:
+          result += compute_value_size(element)
+        return result
+      return RepeatedFieldSize
+    else:
+      def FieldSize(value):
+        return tag_size + compute_value_size(value)
+      return FieldSize
+
+  return SpecificSizer
+
+
+def _ModifiedSizer(compute_value_size, modify_value):
+  """Like SimpleSizer, but modify_value is invoked on each value before it is
+  passed to compute_value_size.  modify_value is typically ZigZagEncode."""
+
+  def SpecificSizer(field_number, is_repeated, is_packed):
+    tag_size = _TagSize(field_number)
+    if is_packed:
+      local_VarintSize = _VarintSize
+      def PackedFieldSize(value):
+        result = 0
+        for element in value:
+          result += compute_value_size(modify_value(element))
+        return result + local_VarintSize(result) + tag_size
+      return PackedFieldSize
+    elif is_repeated:
+      def RepeatedFieldSize(value):
+        result = tag_size * len(value)
+        for element in value:
+          result += compute_value_size(modify_value(element))
+        return result
+      return RepeatedFieldSize
+    else:
+      def FieldSize(value):
+        return tag_size + compute_value_size(modify_value(value))
+      return FieldSize
+
+  return SpecificSizer
+
+
+def _FixedSizer(value_size):
+  """Like _SimpleSizer except for a fixed-size field.  The input is the size
+  of one value."""
+
+  def SpecificSizer(field_number, is_repeated, is_packed):
+    tag_size = _TagSize(field_number)
+    if is_packed:
+      local_VarintSize = _VarintSize
+      def PackedFieldSize(value):
+        result = len(value) * value_size
+        return result + local_VarintSize(result) + tag_size
+      return PackedFieldSize
+    elif is_repeated:
+      element_size = value_size + tag_size
+      def RepeatedFieldSize(value):
+        return len(value) * element_size
+      return RepeatedFieldSize
+    else:
+      field_size = value_size + tag_size
+      def FieldSize(value):
+        return field_size
+      return FieldSize
+
+  return SpecificSizer
+
+
+# ====================================================================
+# Here we declare a sizer constructor for each field type.  Each "sizer
+# constructor" is a function that takes (field_number, is_repeated, is_packed)
+# as parameters and returns a sizer, which in turn takes a field value as
+# a parameter and returns its encoded size.
+
+
+Int32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize)
+
+UInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize)
+
+SInt32Sizer = SInt64Sizer = _ModifiedSizer(
+    _SignedVarintSize, wire_format.ZigZagEncode)
+
+Fixed32Sizer = SFixed32Sizer = FloatSizer  = _FixedSizer(4)
+Fixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8)
+
+BoolSizer = _FixedSizer(1)
+
+
+def StringSizer(field_number, is_repeated, is_packed):
+  """Returns a sizer for a string field."""
+
+  tag_size = _TagSize(field_number)
+  local_VarintSize = _VarintSize
+  local_len = len
+  assert not is_packed
+  if is_repeated:
+    def RepeatedFieldSize(value):
+      result = tag_size * len(value)
+      for element in value:
+        l = local_len(element.encode('utf-8'))
+        result += local_VarintSize(l) + l
+      return result
+    return RepeatedFieldSize
+  else:
+    def FieldSize(value):
+      l = local_len(value.encode('utf-8'))
+      return tag_size + local_VarintSize(l) + l
+    return FieldSize
+
+
+def BytesSizer(field_number, is_repeated, is_packed):
+  """Returns a sizer for a bytes field."""
+
+  tag_size = _TagSize(field_number)
+  local_VarintSize = _VarintSize
+  local_len = len
+  assert not is_packed
+  if is_repeated:
+    def RepeatedFieldSize(value):
+      result = tag_size * len(value)
+      for element in value:
+        l = local_len(element)
+        result += local_VarintSize(l) + l
+      return result
+    return RepeatedFieldSize
+  else:
+    def FieldSize(value):
+      l = local_len(value)
+      return tag_size + local_VarintSize(l) + l
+    return FieldSize
+
+
+def GroupSizer(field_number, is_repeated, is_packed):
+  """Returns a sizer for a group field."""
+
+  tag_size = _TagSize(field_number) * 2
+  assert not is_packed
+  if is_repeated:
+    def RepeatedFieldSize(value):
+      result = tag_size * len(value)
+      for element in value:
+        result += element.ByteSize()
+      return result
+    return RepeatedFieldSize
+  else:
+    def FieldSize(value):
+      return tag_size + value.ByteSize()
+    return FieldSize
+
+
+def MessageSizer(field_number, is_repeated, is_packed):
+  """Returns a sizer for a message field."""
+
+  tag_size = _TagSize(field_number)
+  local_VarintSize = _VarintSize
+  assert not is_packed
+  if is_repeated:
+    def RepeatedFieldSize(value):
+      result = tag_size * len(value)
+      for element in value:
+        l = element.ByteSize()
+        result += local_VarintSize(l) + l
+      return result
+    return RepeatedFieldSize
+  else:
+    def FieldSize(value):
+      l = value.ByteSize()
+      return tag_size + local_VarintSize(l) + l
+    return FieldSize
+
+
+# --------------------------------------------------------------------
+# MessageSet is special.
+
+
+def MessageSetItemSizer(field_number):
+  """Returns a sizer for extensions of MessageSet.
+
+  The message set message looks like this:
+    message MessageSet {
+      repeated group Item = 1 {
+        required int32 type_id = 2;
+        required string message = 3;
+      }
+    }
+  """
+  static_size = (_TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) +
+                 _TagSize(3))
+  local_VarintSize = _VarintSize
+
+  def FieldSize(value):
+    l = value.ByteSize()
+    return static_size + local_VarintSize(l) + l
+
+  return FieldSize
+
+
+# ====================================================================
+# Encoders!
+
+
+def _VarintEncoder():
+  """Return an encoder for a basic varint value (does not include tag)."""
+
+  local_chr = _PY2 and chr or (lambda x: bytes((x,)))  ##PY25
+##!PY25  local_chr = chr if bytes is str else lambda x: bytes((x,))
+  def EncodeVarint(write, value):
+    bits = value & 0x7f
+    value >>= 7
+    while value:
+      write(local_chr(0x80|bits))
+      bits = value & 0x7f
+      value >>= 7
+    return write(local_chr(bits))
+
+  return EncodeVarint
+
+
+def _SignedVarintEncoder():
+  """Return an encoder for a basic signed varint value (does not include
+  tag)."""
+
+  local_chr = _PY2 and chr or (lambda x: bytes((x,)))  ##PY25
+##!PY25  local_chr = chr if bytes is str else lambda x: bytes((x,))
+  def EncodeSignedVarint(write, value):
+    if value < 0:
+      value += (1 << 64)
+    bits = value & 0x7f
+    value >>= 7
+    while value:
+      write(local_chr(0x80|bits))
+      bits = value & 0x7f
+      value >>= 7
+    return write(local_chr(bits))
+
+  return EncodeSignedVarint
+
+
+_EncodeVarint = _VarintEncoder()
+_EncodeSignedVarint = _SignedVarintEncoder()
+
+
+def _VarintBytes(value):
+  """Encode the given integer as a varint and return the bytes.  This is only
+  called at startup time so it doesn't need to be fast."""
+
+  pieces = []
+  _EncodeVarint(pieces.append, value)
+  return "".encode("latin1").join(pieces)  ##PY25
+##!PY25  return b"".join(pieces)
+
+
+def TagBytes(field_number, wire_type):
+  """Encode the given tag and return the bytes.  Only called at startup."""
+
+  return _VarintBytes(wire_format.PackTag(field_number, wire_type))
+
+# --------------------------------------------------------------------
+# As with sizers (see above), we have a number of common encoder
+# implementations.
+
+
+def _SimpleEncoder(wire_type, encode_value, compute_value_size):
+  """Return a constructor for an encoder for fields of a particular type.
+
+  Args:
+      wire_type:  The field's wire type, for encoding tags.
+      encode_value:  A function which encodes an individual value, e.g.
+        _EncodeVarint().
+      compute_value_size:  A function which computes the size of an individual
+        value, e.g. _VarintSize().
+  """
+
+  def SpecificEncoder(field_number, is_repeated, is_packed):
+    if is_packed:
+      tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+      local_EncodeVarint = _EncodeVarint
+      def EncodePackedField(write, value):
+        write(tag_bytes)
+        size = 0
+        for element in value:
+          size += compute_value_size(element)
+        local_EncodeVarint(write, size)
+        for element in value:
+          encode_value(write, element)
+      return EncodePackedField
+    elif is_repeated:
+      tag_bytes = TagBytes(field_number, wire_type)
+      def EncodeRepeatedField(write, value):
+        for element in value:
+          write(tag_bytes)
+          encode_value(write, element)
+      return EncodeRepeatedField
+    else:
+      tag_bytes = TagBytes(field_number, wire_type)
+      def EncodeField(write, value):
+        write(tag_bytes)
+        return encode_value(write, value)
+      return EncodeField
+
+  return SpecificEncoder
+
+
+def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value):
+  """Like SimpleEncoder but additionally invokes modify_value on every value
+  before passing it to encode_value.  Usually modify_value is ZigZagEncode."""
+
+  def SpecificEncoder(field_number, is_repeated, is_packed):
+    if is_packed:
+      tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+      local_EncodeVarint = _EncodeVarint
+      def EncodePackedField(write, value):
+        write(tag_bytes)
+        size = 0
+        for element in value:
+          size += compute_value_size(modify_value(element))
+        local_EncodeVarint(write, size)
+        for element in value:
+          encode_value(write, modify_value(element))
+      return EncodePackedField
+    elif is_repeated:
+      tag_bytes = TagBytes(field_number, wire_type)
+      def EncodeRepeatedField(write, value):
+        for element in value:
+          write(tag_bytes)
+          encode_value(write, modify_value(element))
+      return EncodeRepeatedField
+    else:
+      tag_bytes = TagBytes(field_number, wire_type)
+      def EncodeField(write, value):
+        write(tag_bytes)
+        return encode_value(write, modify_value(value))
+      return EncodeField
+
+  return SpecificEncoder
+
+
+def _StructPackEncoder(wire_type, format):
+  """Return a constructor for an encoder for a fixed-width field.
+
+  Args:
+      wire_type:  The field's wire type, for encoding tags.
+      format:  The format string to pass to struct.pack().
+  """
+
+  value_size = struct.calcsize(format)
+
+  def SpecificEncoder(field_number, is_repeated, is_packed):
+    local_struct_pack = struct.pack
+    if is_packed:
+      tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+      local_EncodeVarint = _EncodeVarint
+      def EncodePackedField(write, value):
+        write(tag_bytes)
+        local_EncodeVarint(write, len(value) * value_size)
+        for element in value:
+          write(local_struct_pack(format, element))
+      return EncodePackedField
+    elif is_repeated:
+      tag_bytes = TagBytes(field_number, wire_type)
+      def EncodeRepeatedField(write, value):
+        for element in value:
+          write(tag_bytes)
+          write(local_struct_pack(format, element))
+      return EncodeRepeatedField
+    else:
+      tag_bytes = TagBytes(field_number, wire_type)
+      def EncodeField(write, value):
+        write(tag_bytes)
+        return write(local_struct_pack(format, value))
+      return EncodeField
+
+  return SpecificEncoder
+
+
+def _FloatingPointEncoder(wire_type, format):
+  """Return a constructor for an encoder for float fields.
+
+  This is like StructPackEncoder, but catches errors that may be due to
+  passing non-finite floating-point values to struct.pack, and makes a
+  second attempt to encode those values.
+
+  Args:
+      wire_type:  The field's wire type, for encoding tags.
+      format:  The format string to pass to struct.pack().
+  """
+
+  b = _PY2 and (lambda x:x) or (lambda x:x.encode('latin1'))  ##PY25
+  value_size = struct.calcsize(format)
+  if value_size == 4:
+    def EncodeNonFiniteOrRaise(write, value):
+      # Remember that the serialized form uses little-endian byte order.
+      if value == _POS_INF:
+        write(b('\x00\x00\x80\x7F'))  ##PY25
+##!PY25        write(b'\x00\x00\x80\x7F')
+      elif value == _NEG_INF:
+        write(b('\x00\x00\x80\xFF'))  ##PY25
+##!PY25        write(b'\x00\x00\x80\xFF')
+      elif value != value:           # NaN
+        write(b('\x00\x00\xC0\x7F'))  ##PY25
+##!PY25        write(b'\x00\x00\xC0\x7F')
+      else:
+        raise
+  elif value_size == 8:
+    def EncodeNonFiniteOrRaise(write, value):
+      if value == _POS_INF:
+        write(b('\x00\x00\x00\x00\x00\x00\xF0\x7F'))  ##PY25
+##!PY25        write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F')
+      elif value == _NEG_INF:
+        write(b('\x00\x00\x00\x00\x00\x00\xF0\xFF'))  ##PY25
+##!PY25        write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF')
+      elif value != value:                         # NaN
+        write(b('\x00\x00\x00\x00\x00\x00\xF8\x7F'))  ##PY25
+##!PY25        write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F')
+      else:
+        raise
+  else:
+    raise ValueError('Can\'t encode floating-point values that are '
+                     '%d bytes long (only 4 or 8)' % value_size)
+
+  def SpecificEncoder(field_number, is_repeated, is_packed):
+    local_struct_pack = struct.pack
+    if is_packed:
+      tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+      local_EncodeVarint = _EncodeVarint
+      def EncodePackedField(write, value):
+        write(tag_bytes)
+        local_EncodeVarint(write, len(value) * value_size)
+        for element in value:
+          # This try/except block is going to be faster than any code that
+          # we could write to check whether element is finite.
+          try:
+            write(local_struct_pack(format, element))
+          except SystemError:
+            EncodeNonFiniteOrRaise(write, element)
+      return EncodePackedField
+    elif is_repeated:
+      tag_bytes = TagBytes(field_number, wire_type)
+      def EncodeRepeatedField(write, value):
+        for element in value:
+          write(tag_bytes)
+          try:
+            write(local_struct_pack(format, element))
+          except SystemError:
+            EncodeNonFiniteOrRaise(write, element)
+      return EncodeRepeatedField
+    else:
+      tag_bytes = TagBytes(field_number, wire_type)
+      def EncodeField(write, value):
+        write(tag_bytes)
+        try:
+          write(local_struct_pack(format, value))
+        except SystemError:
+          EncodeNonFiniteOrRaise(write, value)
+      return EncodeField
+
+  return SpecificEncoder
+
+
+# ====================================================================
+# Here we declare an encoder constructor for each field type.  These work
+# very similarly to sizer constructors, described earlier.
+
+
+Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder(
+    wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize)
+
+UInt32Encoder = UInt64Encoder = _SimpleEncoder(
+    wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize)
+
+SInt32Encoder = SInt64Encoder = _ModifiedEncoder(
+    wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize,
+    wire_format.ZigZagEncode)
+
+# Note that Python conveniently guarantees that when using the '<' prefix on
+# formats, they will also have the same size across all platforms (as opposed
+# to without the prefix, where their sizes depend on the C compiler's basic
+# type sizes).
+Fixed32Encoder  = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<I')
+Fixed64Encoder  = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<Q')
+SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<i')
+SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<q')
+FloatEncoder    = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED32, '<f')
+DoubleEncoder   = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED64, '<d')
+
+
+def BoolEncoder(field_number, is_repeated, is_packed):
+  """Returns an encoder for a boolean field."""
+
+##!PY25  false_byte = b'\x00'
+##!PY25  true_byte = b'\x01'
+  false_byte = '\x00'.encode('latin1')  ##PY25
+  true_byte = '\x01'.encode('latin1')  ##PY25
+  if is_packed:
+    tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+    local_EncodeVarint = _EncodeVarint
+    def EncodePackedField(write, value):
+      write(tag_bytes)
+      local_EncodeVarint(write, len(value))
+      for element in value:
+        if element:
+          write(true_byte)
+        else:
+          write(false_byte)
+    return EncodePackedField
+  elif is_repeated:
+    tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
+    def EncodeRepeatedField(write, value):
+      for element in value:
+        write(tag_bytes)
+        if element:
+          write(true_byte)
+        else:
+          write(false_byte)
+    return EncodeRepeatedField
+  else:
+    tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
+    def EncodeField(write, value):
+      write(tag_bytes)
+      if value:
+        return write(true_byte)
+      return write(false_byte)
+    return EncodeField
+
+
+def StringEncoder(field_number, is_repeated, is_packed):
+  """Returns an encoder for a string field."""
+
+  tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+  local_EncodeVarint = _EncodeVarint
+  local_len = len
+  assert not is_packed
+  if is_repeated:
+    def EncodeRepeatedField(write, value):
+      for element in value:
+        encoded = element.encode('utf-8')
+        write(tag)
+        local_EncodeVarint(write, local_len(encoded))
+        write(encoded)
+    return EncodeRepeatedField
+  else:
+    def EncodeField(write, value):
+      encoded = value.encode('utf-8')
+      write(tag)
+      local_EncodeVarint(write, local_len(encoded))
+      return write(encoded)
+    return EncodeField
+
+
+def BytesEncoder(field_number, is_repeated, is_packed):
+  """Returns an encoder for a bytes field."""
+
+  tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+  local_EncodeVarint = _EncodeVarint
+  local_len = len
+  assert not is_packed
+  if is_repeated:
+    def EncodeRepeatedField(write, value):
+      for element in value:
+        write(tag)
+        local_EncodeVarint(write, local_len(element))
+        write(element)
+    return EncodeRepeatedField
+  else:
+    def EncodeField(write, value):
+      write(tag)
+      local_EncodeVarint(write, local_len(value))
+      return write(value)
+    return EncodeField
+
+
+def GroupEncoder(field_number, is_repeated, is_packed):
+  """Returns an encoder for a group field."""
+
+  start_tag = TagBytes(field_number, wire_format.WIRETYPE_START_GROUP)
+  end_tag = TagBytes(field_number, wire_format.WIRETYPE_END_GROUP)
+  assert not is_packed
+  if is_repeated:
+    def EncodeRepeatedField(write, value):
+      for element in value:
+        write(start_tag)
+        element._InternalSerialize(write)
+        write(end_tag)
+    return EncodeRepeatedField
+  else:
+    def EncodeField(write, value):
+      write(start_tag)
+      value._InternalSerialize(write)
+      return write(end_tag)
+    return EncodeField
+
+
+def MessageEncoder(field_number, is_repeated, is_packed):
+  """Returns an encoder for a message field."""
+
+  tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
+  local_EncodeVarint = _EncodeVarint
+  assert not is_packed
+  if is_repeated:
+    def EncodeRepeatedField(write, value):
+      for element in value:
+        write(tag)
+        local_EncodeVarint(write, element.ByteSize())
+        element._InternalSerialize(write)
+    return EncodeRepeatedField
+  else:
+    def EncodeField(write, value):
+      write(tag)
+      local_EncodeVarint(write, value.ByteSize())
+      return value._InternalSerialize(write)
+    return EncodeField
+
+
+# --------------------------------------------------------------------
+# As before, MessageSet is special.
+
+
+def MessageSetItemEncoder(field_number):
+  """Encoder for extensions of MessageSet.
+
+  The message set message looks like this:
+    message MessageSet {
+      repeated group Item = 1 {
+        required int32 type_id = 2;
+        required string message = 3;
+      }
+    }
+  """
+  start_bytes = "".encode("latin1").join([  ##PY25
+##!PY25  start_bytes = b"".join([
+      TagBytes(1, wire_format.WIRETYPE_START_GROUP),
+      TagBytes(2, wire_format.WIRETYPE_VARINT),
+      _VarintBytes(field_number),
+      TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED)])
+  end_bytes = TagBytes(1, wire_format.WIRETYPE_END_GROUP)
+  local_EncodeVarint = _EncodeVarint
+
+  def EncodeField(write, value):
+    write(start_bytes)
+    local_EncodeVarint(write, value.ByteSize())
+    value._InternalSerialize(write)
+    return write(end_bytes)
+
+  return EncodeField
diff --git a/protobuf/python/google/protobuf/internal/enum_type_wrapper.py b/protobuf/python/google/protobuf/internal/enum_type_wrapper.py
new file mode 100644
index 0000000..1cffe35
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/enum_type_wrapper.py
@@ -0,0 +1,89 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""A simple wrapper around enum types to expose utility functions.
+
+Instances are created as properties with the same name as the enum they wrap
+on proto classes.  For usage, see:
+  reflection_test.py
+"""
+
+__author__ = 'rabsatt@google.com (Kevin Rabsatt)'
+
+
+class EnumTypeWrapper(object):
+  """A utility for finding the names of enum values."""
+
+  DESCRIPTOR = None
+
+  def __init__(self, enum_type):
+    """Inits EnumTypeWrapper with an EnumDescriptor."""
+    self._enum_type = enum_type
+    self.DESCRIPTOR = enum_type;
+
+  def Name(self, number):
+    """Returns a string containing the name of an enum value."""
+    if number in self._enum_type.values_by_number:
+      return self._enum_type.values_by_number[number].name
+    raise ValueError('Enum %s has no name defined for value %d' % (
+        self._enum_type.name, number))
+
+  def Value(self, name):
+    """Returns the value coresponding to the given enum name."""
+    if name in self._enum_type.values_by_name:
+      return self._enum_type.values_by_name[name].number
+    raise ValueError('Enum %s has no value defined for name %s' % (
+        self._enum_type.name, name))
+
+  def keys(self):
+    """Return a list of the string names in the enum.
+
+    These are returned in the order they were defined in the .proto file.
+    """
+
+    return [value_descriptor.name
+            for value_descriptor in self._enum_type.values]
+
+  def values(self):
+    """Return a list of the integer values in the enum.
+
+    These are returned in the order they were defined in the .proto file.
+    """
+
+    return [value_descriptor.number
+            for value_descriptor in self._enum_type.values]
+
+  def items(self):
+    """Return a list of the (name, value) pairs of the enum.
+
+    These are returned in the order they were defined in the .proto file.
+    """
+    return [(value_descriptor.name, value_descriptor.number)
+            for value_descriptor in self._enum_type.values]
diff --git a/protobuf/python/google/protobuf/internal/factory_test1.proto b/protobuf/python/google/protobuf/internal/factory_test1.proto
new file mode 100644
index 0000000..9f5a391
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/factory_test1.proto
@@ -0,0 +1,57 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: matthewtoia@google.com (Matt Toia)
+
+
+package google.protobuf.python.internal;
+
+
+enum Factory1Enum {
+  FACTORY_1_VALUE_0 = 0;
+  FACTORY_1_VALUE_1 = 1;
+}
+
+message Factory1Message {
+  optional Factory1Enum factory_1_enum = 1;
+  enum NestedFactory1Enum {
+    NESTED_FACTORY_1_VALUE_0 = 0;
+    NESTED_FACTORY_1_VALUE_1 = 1;
+  }
+  optional NestedFactory1Enum nested_factory_1_enum = 2;
+  message NestedFactory1Message {
+    optional string value = 1;
+  }
+  optional NestedFactory1Message nested_factory_1_message = 3;
+  optional int32 scalar_value = 4;
+  repeated string list_value = 5;
+
+  extensions 1000 to max;
+}
diff --git a/protobuf/python/google/protobuf/internal/factory_test2.proto b/protobuf/python/google/protobuf/internal/factory_test2.proto
new file mode 100644
index 0000000..27feb6c
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/factory_test2.proto
@@ -0,0 +1,92 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: matthewtoia@google.com (Matt Toia)
+
+
+package google.protobuf.python.internal;
+
+import "google/protobuf/internal/factory_test1.proto";
+
+
+enum Factory2Enum {
+  FACTORY_2_VALUE_0 = 0;
+  FACTORY_2_VALUE_1 = 1;
+}
+
+message Factory2Message {
+  required int32 mandatory = 1;
+  optional Factory2Enum factory_2_enum = 2;
+  enum NestedFactory2Enum {
+    NESTED_FACTORY_2_VALUE_0 = 0;
+    NESTED_FACTORY_2_VALUE_1 = 1;
+  }
+  optional NestedFactory2Enum nested_factory_2_enum = 3;
+  message NestedFactory2Message {
+    optional string value = 1;
+  }
+  optional NestedFactory2Message nested_factory_2_message = 4;
+  optional Factory1Message factory_1_message = 5;
+  optional Factory1Enum factory_1_enum = 6;
+  optional Factory1Message.NestedFactory1Enum nested_factory_1_enum = 7;
+  optional Factory1Message.NestedFactory1Message nested_factory_1_message = 8;
+  optional Factory2Message circular_message = 9;
+  optional string scalar_value = 10;
+  repeated string list_value = 11;
+  repeated group Grouped = 12 {
+    optional string part_1 = 13;
+    optional string part_2 = 14;
+  }
+  optional LoopMessage loop = 15;
+  optional int32 int_with_default = 16 [default = 1776];
+  optional double double_with_default = 17 [default = 9.99];
+  optional string string_with_default = 18 [default = "hello world"];
+  optional bool bool_with_default = 19 [default = false];
+  optional Factory2Enum enum_with_default = 20 [default = FACTORY_2_VALUE_1];
+  optional bytes bytes_with_default = 21 [default = "a\373\000c"];
+
+
+  extend Factory1Message {
+    optional string one_more_field = 1001;
+  }
+
+  oneof oneof_field {
+    int32 oneof_int = 22;
+    string oneof_string = 23;
+  }
+}
+
+message LoopMessage {
+  optional Factory2Message loop = 1;
+}
+
+extend Factory1Message {
+  optional string another_field = 1002;
+}
diff --git a/protobuf/python/google/protobuf/internal/generator_test.py b/protobuf/python/google/protobuf/internal/generator_test.py
new file mode 100755
index 0000000..422fa9a
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/generator_test.py
@@ -0,0 +1,343 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# TODO(robinson): Flesh this out considerably.  We focused on reflection_test.py
+# first, since it's testing the subtler code, and since it provides decent
+# indirect testing of the protocol compiler output.
+
+"""Unittest that directly tests the output of the pure-Python protocol
+compiler.  See //google/protobuf/reflection_test.py for a test which
+further ensures that we can use Python protocol message objects as we expect.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+from google.apputils import basetest
+from google.protobuf.internal import test_bad_identifiers_pb2
+from google.protobuf import unittest_custom_options_pb2
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_import_public_pb2
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_no_generic_services_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import service
+from google.protobuf import symbol_database
+
+MAX_EXTENSION = 536870912
+
+
+class GeneratorTest(basetest.TestCase):
+
+  def testNestedMessageDescriptor(self):
+    field_name = 'optional_nested_message'
+    proto_type = unittest_pb2.TestAllTypes
+    self.assertEqual(
+        proto_type.NestedMessage.DESCRIPTOR,
+        proto_type.DESCRIPTOR.fields_by_name[field_name].message_type)
+
+  def testEnums(self):
+    # We test only module-level enums here.
+    # TODO(robinson): Examine descriptors directly to check
+    # enum descriptor output.
+    self.assertEqual(4, unittest_pb2.FOREIGN_FOO)
+    self.assertEqual(5, unittest_pb2.FOREIGN_BAR)
+    self.assertEqual(6, unittest_pb2.FOREIGN_BAZ)
+
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(1, proto.FOO)
+    self.assertEqual(1, unittest_pb2.TestAllTypes.FOO)
+    self.assertEqual(2, proto.BAR)
+    self.assertEqual(2, unittest_pb2.TestAllTypes.BAR)
+    self.assertEqual(3, proto.BAZ)
+    self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ)
+
+  def testExtremeDefaultValues(self):
+    message = unittest_pb2.TestExtremeDefaultValues()
+
+    # Python pre-2.6 does not have isinf() or isnan() functions, so we have
+    # to provide our own.
+    def isnan(val):
+      # NaN is never equal to itself.
+      return val != val
+    def isinf(val):
+      # Infinity times zero equals NaN.
+      return not isnan(val) and isnan(val * 0)
+
+    self.assertTrue(isinf(message.inf_double))
+    self.assertTrue(message.inf_double > 0)
+    self.assertTrue(isinf(message.neg_inf_double))
+    self.assertTrue(message.neg_inf_double < 0)
+    self.assertTrue(isnan(message.nan_double))
+
+    self.assertTrue(isinf(message.inf_float))
+    self.assertTrue(message.inf_float > 0)
+    self.assertTrue(isinf(message.neg_inf_float))
+    self.assertTrue(message.neg_inf_float < 0)
+    self.assertTrue(isnan(message.nan_float))
+    self.assertEqual("? ? ?? ?? ??? ??/ ??-", message.cpp_trigraph)
+
+  def testHasDefaultValues(self):
+    desc = unittest_pb2.TestAllTypes.DESCRIPTOR
+
+    expected_has_default_by_name = {
+        'optional_int32': False,
+        'repeated_int32': False,
+        'optional_nested_message': False,
+        'default_int32': True,
+    }
+
+    has_default_by_name = dict(
+        [(f.name, f.has_default_value)
+         for f in desc.fields
+         if f.name in expected_has_default_by_name])
+    self.assertEqual(expected_has_default_by_name, has_default_by_name)
+
+  def testContainingTypeBehaviorForExtensions(self):
+    self.assertEqual(unittest_pb2.optional_int32_extension.containing_type,
+                     unittest_pb2.TestAllExtensions.DESCRIPTOR)
+    self.assertEqual(unittest_pb2.TestRequired.single.containing_type,
+                     unittest_pb2.TestAllExtensions.DESCRIPTOR)
+
+  def testExtensionScope(self):
+    self.assertEqual(unittest_pb2.optional_int32_extension.extension_scope,
+                     None)
+    self.assertEqual(unittest_pb2.TestRequired.single.extension_scope,
+                     unittest_pb2.TestRequired.DESCRIPTOR)
+
+  def testIsExtension(self):
+    self.assertTrue(unittest_pb2.optional_int32_extension.is_extension)
+    self.assertTrue(unittest_pb2.TestRequired.single.is_extension)
+
+    message_descriptor = unittest_pb2.TestRequired.DESCRIPTOR
+    non_extension_descriptor = message_descriptor.fields_by_name['a']
+    self.assertTrue(not non_extension_descriptor.is_extension)
+
+  def testOptions(self):
+    proto = unittest_mset_pb2.TestMessageSet()
+    self.assertTrue(proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+
+  def testMessageWithCustomOptions(self):
+    proto = unittest_custom_options_pb2.TestMessageWithCustomOptions()
+    enum_options = proto.DESCRIPTOR.enum_types_by_name['AnEnum'].GetOptions()
+    self.assertTrue(enum_options is not None)
+    # TODO(gps): We really should test for the presense of the enum_opt1
+    # extension and for its value to be set to -789.
+
+  def testNestedTypes(self):
+    self.assertEquals(
+        set(unittest_pb2.TestAllTypes.DESCRIPTOR.nested_types),
+        set([
+            unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
+            unittest_pb2.TestAllTypes.OptionalGroup.DESCRIPTOR,
+            unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR,
+        ]))
+    self.assertEqual(unittest_pb2.TestEmptyMessage.DESCRIPTOR.nested_types, [])
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.nested_types, [])
+
+  def testContainingType(self):
+    self.assertTrue(
+        unittest_pb2.TestEmptyMessage.DESCRIPTOR.containing_type is None)
+    self.assertTrue(
+        unittest_pb2.TestAllTypes.DESCRIPTOR.containing_type is None)
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type,
+        unittest_pb2.TestAllTypes.DESCRIPTOR)
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type,
+        unittest_pb2.TestAllTypes.DESCRIPTOR)
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR.containing_type,
+        unittest_pb2.TestAllTypes.DESCRIPTOR)
+
+  def testContainingTypeInEnumDescriptor(self):
+    self.assertTrue(unittest_pb2._FOREIGNENUM.containing_type is None)
+    self.assertEqual(unittest_pb2._TESTALLTYPES_NESTEDENUM.containing_type,
+                     unittest_pb2.TestAllTypes.DESCRIPTOR)
+
+  def testPackage(self):
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.DESCRIPTOR.file.package,
+        'protobuf_unittest')
+    desc = unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR
+    self.assertEqual(desc.file.package, 'protobuf_unittest')
+    self.assertEqual(
+        unittest_import_pb2.ImportMessage.DESCRIPTOR.file.package,
+        'protobuf_unittest_import')
+
+    self.assertEqual(
+        unittest_pb2._FOREIGNENUM.file.package, 'protobuf_unittest')
+    self.assertEqual(
+        unittest_pb2._TESTALLTYPES_NESTEDENUM.file.package,
+        'protobuf_unittest')
+    self.assertEqual(
+        unittest_import_pb2._IMPORTENUM.file.package,
+        'protobuf_unittest_import')
+
+  def testExtensionRange(self):
+    self.assertEqual(
+        unittest_pb2.TestAllTypes.DESCRIPTOR.extension_ranges, [])
+    self.assertEqual(
+        unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges,
+        [(1, MAX_EXTENSION)])
+    self.assertEqual(
+        unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges,
+        [(42, 43), (4143, 4244), (65536, MAX_EXTENSION)])
+
+  def testFileDescriptor(self):
+    self.assertEqual(unittest_pb2.DESCRIPTOR.name,
+                     'google/protobuf/unittest.proto')
+    self.assertEqual(unittest_pb2.DESCRIPTOR.package, 'protobuf_unittest')
+    self.assertFalse(unittest_pb2.DESCRIPTOR.serialized_pb is None)
+    self.assertEqual(unittest_pb2.DESCRIPTOR.dependencies,
+                     [unittest_import_pb2.DESCRIPTOR])
+    self.assertEqual(unittest_import_pb2.DESCRIPTOR.dependencies,
+                     [unittest_import_public_pb2.DESCRIPTOR])
+
+  def testNoGenericServices(self):
+    self.assertTrue(hasattr(unittest_no_generic_services_pb2, "TestMessage"))
+    self.assertTrue(hasattr(unittest_no_generic_services_pb2, "FOO"))
+    self.assertTrue(hasattr(unittest_no_generic_services_pb2, "test_extension"))
+
+    # Make sure unittest_no_generic_services_pb2 has no services subclassing
+    # Proto2 Service class.
+    if hasattr(unittest_no_generic_services_pb2, "TestService"):
+      self.assertFalse(issubclass(unittest_no_generic_services_pb2.TestService,
+                                  service.Service))
+
+  def testMessageTypesByName(self):
+    file_type = unittest_pb2.DESCRIPTOR
+    self.assertEqual(
+        unittest_pb2._TESTALLTYPES,
+        file_type.message_types_by_name[unittest_pb2._TESTALLTYPES.name])
+
+    # Nested messages shouldn't be included in the message_types_by_name
+    # dictionary (like in the C++ API).
+    self.assertFalse(
+        unittest_pb2._TESTALLTYPES_NESTEDMESSAGE.name in
+        file_type.message_types_by_name)
+
+  def testEnumTypesByName(self):
+    file_type = unittest_pb2.DESCRIPTOR
+    self.assertEqual(
+        unittest_pb2._FOREIGNENUM,
+        file_type.enum_types_by_name[unittest_pb2._FOREIGNENUM.name])
+
+  def testExtensionsByName(self):
+    file_type = unittest_pb2.DESCRIPTOR
+    self.assertEqual(
+        unittest_pb2.my_extension_string,
+        file_type.extensions_by_name[unittest_pb2.my_extension_string.name])
+
+  def testPublicImports(self):
+    # Test public imports as embedded message.
+    all_type_proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(0, all_type_proto.optional_public_import_message.e)
+
+    # PublicImportMessage is actually defined in unittest_import_public_pb2
+    # module, and is public imported by unittest_import_pb2 module.
+    public_import_proto = unittest_import_pb2.PublicImportMessage()
+    self.assertEqual(0, public_import_proto.e)
+    self.assertTrue(unittest_import_public_pb2.PublicImportMessage is
+                    unittest_import_pb2.PublicImportMessage)
+
+  def testBadIdentifiers(self):
+    # We're just testing that the code was imported without problems.
+    message = test_bad_identifiers_pb2.TestBadIdentifiers()
+    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.message],
+                     "foo")
+    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.descriptor],
+                     "bar")
+    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.reflection],
+                     "baz")
+    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.service],
+                     "qux")
+
+  def testOneof(self):
+    desc = unittest_pb2.TestAllTypes.DESCRIPTOR
+    self.assertEqual(1, len(desc.oneofs))
+    self.assertEqual('oneof_field', desc.oneofs[0].name)
+    self.assertEqual(0, desc.oneofs[0].index)
+    self.assertIs(desc, desc.oneofs[0].containing_type)
+    self.assertIs(desc.oneofs[0], desc.oneofs_by_name['oneof_field'])
+    nested_names = set(['oneof_uint32', 'oneof_nested_message',
+                        'oneof_string', 'oneof_bytes'])
+    self.assertSameElements(
+        nested_names,
+        [field.name for field in desc.oneofs[0].fields])
+    for field_name, field_desc in desc.fields_by_name.iteritems():
+      if field_name in nested_names:
+        self.assertIs(desc.oneofs[0], field_desc.containing_oneof)
+      else:
+        self.assertIsNone(field_desc.containing_oneof)
+
+
+class SymbolDatabaseRegistrationTest(basetest.TestCase):
+  """Checks that messages, enums and files are correctly registered."""
+
+  def testGetSymbol(self):
+    self.assertEquals(
+        unittest_pb2.TestAllTypes, symbol_database.Default().GetSymbol(
+            'protobuf_unittest.TestAllTypes'))
+    self.assertEquals(
+        unittest_pb2.TestAllTypes.NestedMessage,
+        symbol_database.Default().GetSymbol(
+            'protobuf_unittest.TestAllTypes.NestedMessage'))
+    with self.assertRaises(KeyError):
+      symbol_database.Default().GetSymbol('protobuf_unittest.NestedMessage')
+    self.assertEquals(
+        unittest_pb2.TestAllTypes.OptionalGroup,
+        symbol_database.Default().GetSymbol(
+            'protobuf_unittest.TestAllTypes.OptionalGroup'))
+    self.assertEquals(
+        unittest_pb2.TestAllTypes.RepeatedGroup,
+        symbol_database.Default().GetSymbol(
+            'protobuf_unittest.TestAllTypes.RepeatedGroup'))
+
+  def testEnums(self):
+    self.assertEquals(
+        'protobuf_unittest.ForeignEnum',
+        symbol_database.Default().pool.FindEnumTypeByName(
+            'protobuf_unittest.ForeignEnum').full_name)
+    self.assertEquals(
+        'protobuf_unittest.TestAllTypes.NestedEnum',
+        symbol_database.Default().pool.FindEnumTypeByName(
+            'protobuf_unittest.TestAllTypes.NestedEnum').full_name)
+
+  def testFindFileByName(self):
+    self.assertEquals(
+        'google/protobuf/unittest.proto',
+        symbol_database.Default().pool.FindFileByName(
+            'google/protobuf/unittest.proto').name)
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/message_factory_python_test.py b/protobuf/python/google/protobuf/internal/message_factory_python_test.py
new file mode 100644
index 0000000..85e02b2
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/message_factory_python_test.py
@@ -0,0 +1,54 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for ..public.message_factory for the pure Python implementation."""
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
+
+# We must set the implementation version above before the google3 imports.
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+# Run all tests from the original module by putting them in our namespace.
+# pylint: disable=wildcard-import
+from google.protobuf.internal.message_factory_test import *
+
+
+class ConfirmPurePythonTest(basetest.TestCase):
+
+  def testImplementationSetting(self):
+    self.assertEqual('python', api_implementation.Type())
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/message_factory_test.py b/protobuf/python/google/protobuf/internal/message_factory_test.py
new file mode 100644
index 0000000..fcf1341
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/message_factory_test.py
@@ -0,0 +1,131 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.message_factory."""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+from google.apputils import basetest
+from google.protobuf import descriptor_pb2
+from google.protobuf.internal import factory_test1_pb2
+from google.protobuf.internal import factory_test2_pb2
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+from google.protobuf import message_factory
+
+
+class MessageFactoryTest(basetest.TestCase):
+
+  def setUp(self):
+    self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString(
+        factory_test1_pb2.DESCRIPTOR.serialized_pb)
+    self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
+        factory_test2_pb2.DESCRIPTOR.serialized_pb)
+
+  def _ExerciseDynamicClass(self, cls):
+    msg = cls()
+    msg.mandatory = 42
+    msg.nested_factory_2_enum = 0
+    msg.nested_factory_2_message.value = 'nested message value'
+    msg.factory_1_message.factory_1_enum = 1
+    msg.factory_1_message.nested_factory_1_enum = 0
+    msg.factory_1_message.nested_factory_1_message.value = (
+        'nested message value')
+    msg.factory_1_message.scalar_value = 22
+    msg.factory_1_message.list_value.extend([u'one', u'two', u'three'])
+    msg.factory_1_message.list_value.append(u'four')
+    msg.factory_1_enum = 1
+    msg.nested_factory_1_enum = 0
+    msg.nested_factory_1_message.value = 'nested message value'
+    msg.circular_message.mandatory = 1
+    msg.circular_message.circular_message.mandatory = 2
+    msg.circular_message.scalar_value = 'one deep'
+    msg.scalar_value = 'zero deep'
+    msg.list_value.extend([u'four', u'three', u'two'])
+    msg.list_value.append(u'one')
+    msg.grouped.add()
+    msg.grouped[0].part_1 = 'hello'
+    msg.grouped[0].part_2 = 'world'
+    msg.grouped.add(part_1='testing', part_2='123')
+    msg.loop.loop.mandatory = 2
+    msg.loop.loop.loop.loop.mandatory = 4
+    serialized = msg.SerializeToString()
+    converted = factory_test2_pb2.Factory2Message.FromString(serialized)
+    reserialized = converted.SerializeToString()
+    self.assertEquals(serialized, reserialized)
+    result = cls.FromString(reserialized)
+    self.assertEquals(msg, result)
+
+  def testGetPrototype(self):
+    db = descriptor_database.DescriptorDatabase()
+    pool = descriptor_pool.DescriptorPool(db)
+    db.Add(self.factory_test1_fd)
+    db.Add(self.factory_test2_fd)
+    factory = message_factory.MessageFactory()
+    cls = factory.GetPrototype(pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory2Message'))
+    self.assertIsNot(cls, factory_test2_pb2.Factory2Message)
+    self._ExerciseDynamicClass(cls)
+    cls2 = factory.GetPrototype(pool.FindMessageTypeByName(
+        'google.protobuf.python.internal.Factory2Message'))
+    self.assertIs(cls, cls2)
+
+  def testGetMessages(self):
+    # performed twice because multiple calls with the same input must be allowed
+    for _ in range(2):
+      messages = message_factory.GetMessages([self.factory_test2_fd,
+                                              self.factory_test1_fd])
+      self.assertContainsSubset(
+          ['google.protobuf.python.internal.Factory2Message',
+           'google.protobuf.python.internal.Factory1Message'],
+          messages.keys())
+      self._ExerciseDynamicClass(
+          messages['google.protobuf.python.internal.Factory2Message'])
+      self.assertContainsSubset(
+          ['google.protobuf.python.internal.Factory2Message.one_more_field',
+           'google.protobuf.python.internal.another_field'],
+          (messages['google.protobuf.python.internal.Factory1Message']
+           ._extensions_by_name.keys()))
+      factory_msg1 = messages['google.protobuf.python.internal.Factory1Message']
+      msg1 = messages['google.protobuf.python.internal.Factory1Message']()
+      ext1 = factory_msg1._extensions_by_name[
+          'google.protobuf.python.internal.Factory2Message.one_more_field']
+      ext2 = factory_msg1._extensions_by_name[
+          'google.protobuf.python.internal.another_field']
+      msg1.Extensions[ext1] = 'test1'
+      msg1.Extensions[ext2] = 'test2'
+      self.assertEquals('test1', msg1.Extensions[ext1])
+      self.assertEquals('test2', msg1.Extensions[ext2])
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/message_listener.py b/protobuf/python/google/protobuf/internal/message_listener.py
new file mode 100755
index 0000000..0fc255a
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/message_listener.py
@@ -0,0 +1,78 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Defines a listener interface for observing certain
+state transitions on Message objects.
+
+Also defines a null implementation of this interface.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+
+class MessageListener(object):
+
+  """Listens for modifications made to a message.  Meant to be registered via
+  Message._SetListener().
+
+  Attributes:
+    dirty:  If True, then calling Modified() would be a no-op.  This can be
+            used to avoid these calls entirely in the common case.
+  """
+
+  def Modified(self):
+    """Called every time the message is modified in such a way that the parent
+    message may need to be updated.  This currently means either:
+    (a) The message was modified for the first time, so the parent message
+        should henceforth mark the message as present.
+    (b) The message's cached byte size became dirty -- i.e. the message was
+        modified for the first time after a previous call to ByteSize().
+        Therefore the parent should also mark its byte size as dirty.
+    Note that (a) implies (b), since new objects start out with a client cached
+    size (zero).  However, we document (a) explicitly because it is important.
+
+    Modified() will *only* be called in response to one of these two events --
+    not every time the sub-message is modified.
+
+    Note that if the listener's |dirty| attribute is true, then calling
+    Modified at the moment would be a no-op, so it can be skipped.  Performance-
+    sensitive callers should check this attribute directly before calling since
+    it will be true most of the time.
+    """
+
+    raise NotImplementedError
+
+
+class NullMessageListener(object):
+
+  """No-op MessageListener implementation."""
+
+  def Modified(self):
+    pass
diff --git a/protobuf/python/google/protobuf/internal/message_python_test.py b/protobuf/python/google/protobuf/internal/message_python_test.py
new file mode 100644
index 0000000..c40623a
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/message_python_test.py
@@ -0,0 +1,54 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for ..public.message for the pure Python implementation."""
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'
+
+# We must set the implementation version above before the google3 imports.
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+# Run all tests from the original module by putting them in our namespace.
+# pylint: disable=wildcard-import
+from google.protobuf.internal.message_test import *
+
+
+class ConfirmPurePythonTest(basetest.TestCase):
+
+  def testImplementationSetting(self):
+    self.assertEqual('python', api_implementation.Type())
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/message_test.py b/protobuf/python/google/protobuf/internal/message_test.py
new file mode 100755
index 0000000..48b7ffd
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/message_test.py
@@ -0,0 +1,681 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests python protocol buffers against the golden message.
+
+Note that the golden messages exercise every known field type, thus this
+test ends up exercising and verifying nearly all of the parsing and
+serialization code in the whole library.
+
+TODO(kenton):  Merge with wire_format_test?  It doesn't make a whole lot of
+sense to call this a test of the "message" module, which only declares an
+abstract interface.
+"""
+
+__author__ = 'gps@google.com (Gregory P. Smith)'
+
+import copy
+import math
+import operator
+import pickle
+import sys
+
+from google.apputils import basetest
+from google.protobuf import unittest_pb2
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import test_util
+from google.protobuf import message
+
+# Python pre-2.6 does not have isinf() or isnan() functions, so we have
+# to provide our own.
+def isnan(val):
+  # NaN is never equal to itself.
+  return val != val
+def isinf(val):
+  # Infinity times zero equals NaN.
+  return not isnan(val) and isnan(val * 0)
+def IsPosInf(val):
+  return isinf(val) and (val > 0)
+def IsNegInf(val):
+  return isinf(val) and (val < 0)
+
+
+class MessageTest(basetest.TestCase):
+
+  def testBadUtf8String(self):
+    if api_implementation.Type() != 'python':
+      self.skipTest("Skipping testBadUtf8String, currently only the python "
+                    "api implementation raises UnicodeDecodeError when a "
+                    "string field contains bad utf-8.")
+    bad_utf8_data = test_util.GoldenFileData('bad_utf8_string')
+    with self.assertRaises(UnicodeDecodeError) as context:
+      unittest_pb2.TestAllTypes.FromString(bad_utf8_data)
+    self.assertIn('field: protobuf_unittest.TestAllTypes.optional_string',
+                  str(context.exception))
+
+  def testGoldenMessage(self):
+    golden_data = test_util.GoldenFileData(
+        'golden_message_oneof_implemented')
+    golden_message = unittest_pb2.TestAllTypes()
+    golden_message.ParseFromString(golden_data)
+    test_util.ExpectAllFieldsSet(self, golden_message)
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+    golden_copy = copy.deepcopy(golden_message)
+    self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+  def testGoldenExtensions(self):
+    golden_data = test_util.GoldenFileData('golden_message')
+    golden_message = unittest_pb2.TestAllExtensions()
+    golden_message.ParseFromString(golden_data)
+    all_set = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(all_set)
+    self.assertEquals(all_set, golden_message)
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+    golden_copy = copy.deepcopy(golden_message)
+    self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+  def testGoldenPackedMessage(self):
+    golden_data = test_util.GoldenFileData('golden_packed_fields_message')
+    golden_message = unittest_pb2.TestPackedTypes()
+    golden_message.ParseFromString(golden_data)
+    all_set = unittest_pb2.TestPackedTypes()
+    test_util.SetAllPackedFields(all_set)
+    self.assertEquals(all_set, golden_message)
+    self.assertEqual(golden_data, all_set.SerializeToString())
+    golden_copy = copy.deepcopy(golden_message)
+    self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+  def testGoldenPackedExtensions(self):
+    golden_data = test_util.GoldenFileData('golden_packed_fields_message')
+    golden_message = unittest_pb2.TestPackedExtensions()
+    golden_message.ParseFromString(golden_data)
+    all_set = unittest_pb2.TestPackedExtensions()
+    test_util.SetAllPackedExtensions(all_set)
+    self.assertEquals(all_set, golden_message)
+    self.assertEqual(golden_data, all_set.SerializeToString())
+    golden_copy = copy.deepcopy(golden_message)
+    self.assertEqual(golden_data, golden_copy.SerializeToString())
+
+  def testPickleSupport(self):
+    golden_data = test_util.GoldenFileData('golden_message')
+    golden_message = unittest_pb2.TestAllTypes()
+    golden_message.ParseFromString(golden_data)
+    pickled_message = pickle.dumps(golden_message)
+
+    unpickled_message = pickle.loads(pickled_message)
+    self.assertEquals(unpickled_message, golden_message)
+
+
+  def testPickleIncompleteProto(self):
+    golden_message = unittest_pb2.TestRequired(a=1)
+    pickled_message = pickle.dumps(golden_message)
+
+    unpickled_message = pickle.loads(pickled_message)
+    self.assertEquals(unpickled_message, golden_message)
+    self.assertEquals(unpickled_message.a, 1)
+    # This is still an incomplete proto - so serializing should fail
+    self.assertRaises(message.EncodeError, unpickled_message.SerializeToString)
+
+  def testPositiveInfinity(self):
+    golden_data = (b'\x5D\x00\x00\x80\x7F'
+                   b'\x61\x00\x00\x00\x00\x00\x00\xF0\x7F'
+                   b'\xCD\x02\x00\x00\x80\x7F'
+                   b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\x7F')
+    golden_message = unittest_pb2.TestAllTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(IsPosInf(golden_message.optional_float))
+    self.assertTrue(IsPosInf(golden_message.optional_double))
+    self.assertTrue(IsPosInf(golden_message.repeated_float[0]))
+    self.assertTrue(IsPosInf(golden_message.repeated_double[0]))
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+
+  def testNegativeInfinity(self):
+    golden_data = (b'\x5D\x00\x00\x80\xFF'
+                   b'\x61\x00\x00\x00\x00\x00\x00\xF0\xFF'
+                   b'\xCD\x02\x00\x00\x80\xFF'
+                   b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF0\xFF')
+    golden_message = unittest_pb2.TestAllTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(IsNegInf(golden_message.optional_float))
+    self.assertTrue(IsNegInf(golden_message.optional_double))
+    self.assertTrue(IsNegInf(golden_message.repeated_float[0]))
+    self.assertTrue(IsNegInf(golden_message.repeated_double[0]))
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+
+  def testNotANumber(self):
+    golden_data = (b'\x5D\x00\x00\xC0\x7F'
+                   b'\x61\x00\x00\x00\x00\x00\x00\xF8\x7F'
+                   b'\xCD\x02\x00\x00\xC0\x7F'
+                   b'\xD1\x02\x00\x00\x00\x00\x00\x00\xF8\x7F')
+    golden_message = unittest_pb2.TestAllTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(isnan(golden_message.optional_float))
+    self.assertTrue(isnan(golden_message.optional_double))
+    self.assertTrue(isnan(golden_message.repeated_float[0]))
+    self.assertTrue(isnan(golden_message.repeated_double[0]))
+
+    # The protocol buffer may serialize to any one of multiple different
+    # representations of a NaN.  Rather than verify a specific representation,
+    # verify the serialized string can be converted into a correctly
+    # behaving protocol buffer.
+    serialized = golden_message.SerializeToString()
+    message = unittest_pb2.TestAllTypes()
+    message.ParseFromString(serialized)
+    self.assertTrue(isnan(message.optional_float))
+    self.assertTrue(isnan(message.optional_double))
+    self.assertTrue(isnan(message.repeated_float[0]))
+    self.assertTrue(isnan(message.repeated_double[0]))
+
+  def testPositiveInfinityPacked(self):
+    golden_data = (b'\xA2\x06\x04\x00\x00\x80\x7F'
+                   b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\x7F')
+    golden_message = unittest_pb2.TestPackedTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(IsPosInf(golden_message.packed_float[0]))
+    self.assertTrue(IsPosInf(golden_message.packed_double[0]))
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+
+  def testNegativeInfinityPacked(self):
+    golden_data = (b'\xA2\x06\x04\x00\x00\x80\xFF'
+                   b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF0\xFF')
+    golden_message = unittest_pb2.TestPackedTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(IsNegInf(golden_message.packed_float[0]))
+    self.assertTrue(IsNegInf(golden_message.packed_double[0]))
+    self.assertEqual(golden_data, golden_message.SerializeToString())
+
+  def testNotANumberPacked(self):
+    golden_data = (b'\xA2\x06\x04\x00\x00\xC0\x7F'
+                   b'\xAA\x06\x08\x00\x00\x00\x00\x00\x00\xF8\x7F')
+    golden_message = unittest_pb2.TestPackedTypes()
+    golden_message.ParseFromString(golden_data)
+    self.assertTrue(isnan(golden_message.packed_float[0]))
+    self.assertTrue(isnan(golden_message.packed_double[0]))
+
+    serialized = golden_message.SerializeToString()
+    message = unittest_pb2.TestPackedTypes()
+    message.ParseFromString(serialized)
+    self.assertTrue(isnan(message.packed_float[0]))
+    self.assertTrue(isnan(message.packed_double[0]))
+
+  def testExtremeFloatValues(self):
+    message = unittest_pb2.TestAllTypes()
+
+    # Most positive exponent, no significand bits set.
+    kMostPosExponentNoSigBits = math.pow(2, 127)
+    message.optional_float = kMostPosExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == kMostPosExponentNoSigBits)
+
+    # Most positive exponent, one significand bit set.
+    kMostPosExponentOneSigBit = 1.5 * math.pow(2, 127)
+    message.optional_float = kMostPosExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == kMostPosExponentOneSigBit)
+
+    # Repeat last two cases with values of same magnitude, but negative.
+    message.optional_float = -kMostPosExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == -kMostPosExponentNoSigBits)
+
+    message.optional_float = -kMostPosExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == -kMostPosExponentOneSigBit)
+
+    # Most negative exponent, no significand bits set.
+    kMostNegExponentNoSigBits = math.pow(2, -127)
+    message.optional_float = kMostNegExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == kMostNegExponentNoSigBits)
+
+    # Most negative exponent, one significand bit set.
+    kMostNegExponentOneSigBit = 1.5 * math.pow(2, -127)
+    message.optional_float = kMostNegExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == kMostNegExponentOneSigBit)
+
+    # Repeat last two cases with values of the same magnitude, but negative.
+    message.optional_float = -kMostNegExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == -kMostNegExponentNoSigBits)
+
+    message.optional_float = -kMostNegExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_float == -kMostNegExponentOneSigBit)
+
+  def testExtremeDoubleValues(self):
+    message = unittest_pb2.TestAllTypes()
+
+    # Most positive exponent, no significand bits set.
+    kMostPosExponentNoSigBits = math.pow(2, 1023)
+    message.optional_double = kMostPosExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == kMostPosExponentNoSigBits)
+
+    # Most positive exponent, one significand bit set.
+    kMostPosExponentOneSigBit = 1.5 * math.pow(2, 1023)
+    message.optional_double = kMostPosExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == kMostPosExponentOneSigBit)
+
+    # Repeat last two cases with values of same magnitude, but negative.
+    message.optional_double = -kMostPosExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == -kMostPosExponentNoSigBits)
+
+    message.optional_double = -kMostPosExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == -kMostPosExponentOneSigBit)
+
+    # Most negative exponent, no significand bits set.
+    kMostNegExponentNoSigBits = math.pow(2, -1023)
+    message.optional_double = kMostNegExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == kMostNegExponentNoSigBits)
+
+    # Most negative exponent, one significand bit set.
+    kMostNegExponentOneSigBit = 1.5 * math.pow(2, -1023)
+    message.optional_double = kMostNegExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == kMostNegExponentOneSigBit)
+
+    # Repeat last two cases with values of the same magnitude, but negative.
+    message.optional_double = -kMostNegExponentNoSigBits
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == -kMostNegExponentNoSigBits)
+
+    message.optional_double = -kMostNegExponentOneSigBit
+    message.ParseFromString(message.SerializeToString())
+    self.assertTrue(message.optional_double == -kMostNegExponentOneSigBit)
+
+  def testFloatPrinting(self):
+    message = unittest_pb2.TestAllTypes()
+    message.optional_float = 2.0
+    self.assertEqual(str(message), 'optional_float: 2.0\n')
+
+  def testHighPrecisionFloatPrinting(self):
+    message = unittest_pb2.TestAllTypes()
+    message.optional_double = 0.12345678912345678
+    if sys.version_info.major >= 3:
+      self.assertEqual(str(message), 'optional_double: 0.12345678912345678\n')
+    else:
+      self.assertEqual(str(message), 'optional_double: 0.123456789123\n')
+
+  def testUnknownFieldPrinting(self):
+    populated = unittest_pb2.TestAllTypes()
+    test_util.SetAllNonLazyFields(populated)
+    empty = unittest_pb2.TestEmptyMessage()
+    empty.ParseFromString(populated.SerializeToString())
+    self.assertEqual(str(empty), '')
+
+  def testSortingRepeatedScalarFieldsDefaultComparator(self):
+    """Check some different types with the default comparator."""
+    message = unittest_pb2.TestAllTypes()
+
+    # TODO(mattp): would testing more scalar types strengthen test?
+    message.repeated_int32.append(1)
+    message.repeated_int32.append(3)
+    message.repeated_int32.append(2)
+    message.repeated_int32.sort()
+    self.assertEqual(message.repeated_int32[0], 1)
+    self.assertEqual(message.repeated_int32[1], 2)
+    self.assertEqual(message.repeated_int32[2], 3)
+
+    message.repeated_float.append(1.1)
+    message.repeated_float.append(1.3)
+    message.repeated_float.append(1.2)
+    message.repeated_float.sort()
+    self.assertAlmostEqual(message.repeated_float[0], 1.1)
+    self.assertAlmostEqual(message.repeated_float[1], 1.2)
+    self.assertAlmostEqual(message.repeated_float[2], 1.3)
+
+    message.repeated_string.append('a')
+    message.repeated_string.append('c')
+    message.repeated_string.append('b')
+    message.repeated_string.sort()
+    self.assertEqual(message.repeated_string[0], 'a')
+    self.assertEqual(message.repeated_string[1], 'b')
+    self.assertEqual(message.repeated_string[2], 'c')
+
+    message.repeated_bytes.append(b'a')
+    message.repeated_bytes.append(b'c')
+    message.repeated_bytes.append(b'b')
+    message.repeated_bytes.sort()
+    self.assertEqual(message.repeated_bytes[0], b'a')
+    self.assertEqual(message.repeated_bytes[1], b'b')
+    self.assertEqual(message.repeated_bytes[2], b'c')
+
+  def testSortingRepeatedScalarFieldsCustomComparator(self):
+    """Check some different types with custom comparator."""
+    message = unittest_pb2.TestAllTypes()
+
+    message.repeated_int32.append(-3)
+    message.repeated_int32.append(-2)
+    message.repeated_int32.append(-1)
+    message.repeated_int32.sort(key=abs)
+    self.assertEqual(message.repeated_int32[0], -1)
+    self.assertEqual(message.repeated_int32[1], -2)
+    self.assertEqual(message.repeated_int32[2], -3)
+
+    message.repeated_string.append('aaa')
+    message.repeated_string.append('bb')
+    message.repeated_string.append('c')
+    message.repeated_string.sort(key=len)
+    self.assertEqual(message.repeated_string[0], 'c')
+    self.assertEqual(message.repeated_string[1], 'bb')
+    self.assertEqual(message.repeated_string[2], 'aaa')
+
+  def testSortingRepeatedCompositeFieldsCustomComparator(self):
+    """Check passing a custom comparator to sort a repeated composite field."""
+    message = unittest_pb2.TestAllTypes()
+
+    message.repeated_nested_message.add().bb = 1
+    message.repeated_nested_message.add().bb = 3
+    message.repeated_nested_message.add().bb = 2
+    message.repeated_nested_message.add().bb = 6
+    message.repeated_nested_message.add().bb = 5
+    message.repeated_nested_message.add().bb = 4
+    message.repeated_nested_message.sort(key=operator.attrgetter('bb'))
+    self.assertEqual(message.repeated_nested_message[0].bb, 1)
+    self.assertEqual(message.repeated_nested_message[1].bb, 2)
+    self.assertEqual(message.repeated_nested_message[2].bb, 3)
+    self.assertEqual(message.repeated_nested_message[3].bb, 4)
+    self.assertEqual(message.repeated_nested_message[4].bb, 5)
+    self.assertEqual(message.repeated_nested_message[5].bb, 6)
+
+  def testRepeatedCompositeFieldSortArguments(self):
+    """Check sorting a repeated composite field using list.sort() arguments."""
+    message = unittest_pb2.TestAllTypes()
+
+    get_bb = operator.attrgetter('bb')
+    cmp_bb = lambda a, b: cmp(a.bb, b.bb)
+    message.repeated_nested_message.add().bb = 1
+    message.repeated_nested_message.add().bb = 3
+    message.repeated_nested_message.add().bb = 2
+    message.repeated_nested_message.add().bb = 6
+    message.repeated_nested_message.add().bb = 5
+    message.repeated_nested_message.add().bb = 4
+    message.repeated_nested_message.sort(key=get_bb)
+    self.assertEqual([k.bb for k in message.repeated_nested_message],
+                     [1, 2, 3, 4, 5, 6])
+    message.repeated_nested_message.sort(key=get_bb, reverse=True)
+    self.assertEqual([k.bb for k in message.repeated_nested_message],
+                     [6, 5, 4, 3, 2, 1])
+    if sys.version_info.major >= 3: return  # No cmp sorting in PY3.
+    message.repeated_nested_message.sort(sort_function=cmp_bb)
+    self.assertEqual([k.bb for k in message.repeated_nested_message],
+                     [1, 2, 3, 4, 5, 6])
+    message.repeated_nested_message.sort(cmp=cmp_bb, reverse=True)
+    self.assertEqual([k.bb for k in message.repeated_nested_message],
+                     [6, 5, 4, 3, 2, 1])
+
+  def testRepeatedScalarFieldSortArguments(self):
+    """Check sorting a scalar field using list.sort() arguments."""
+    message = unittest_pb2.TestAllTypes()
+
+    message.repeated_int32.append(-3)
+    message.repeated_int32.append(-2)
+    message.repeated_int32.append(-1)
+    message.repeated_int32.sort(key=abs)
+    self.assertEqual(list(message.repeated_int32), [-1, -2, -3])
+    message.repeated_int32.sort(key=abs, reverse=True)
+    self.assertEqual(list(message.repeated_int32), [-3, -2, -1])
+    if sys.version_info.major < 3:  # No cmp sorting in PY3.
+      abs_cmp = lambda a, b: cmp(abs(a), abs(b))
+      message.repeated_int32.sort(sort_function=abs_cmp)
+      self.assertEqual(list(message.repeated_int32), [-1, -2, -3])
+      message.repeated_int32.sort(cmp=abs_cmp, reverse=True)
+      self.assertEqual(list(message.repeated_int32), [-3, -2, -1])
+
+    message.repeated_string.append('aaa')
+    message.repeated_string.append('bb')
+    message.repeated_string.append('c')
+    message.repeated_string.sort(key=len)
+    self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa'])
+    message.repeated_string.sort(key=len, reverse=True)
+    self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c'])
+    if sys.version_info.major < 3:  # No cmp sorting in PY3.
+      len_cmp = lambda a, b: cmp(len(a), len(b))
+      message.repeated_string.sort(sort_function=len_cmp)
+      self.assertEqual(list(message.repeated_string), ['c', 'bb', 'aaa'])
+      message.repeated_string.sort(cmp=len_cmp, reverse=True)
+      self.assertEqual(list(message.repeated_string), ['aaa', 'bb', 'c'])
+
+  def testRepeatedFieldsComparable(self):
+    m1 = unittest_pb2.TestAllTypes()
+    m2 = unittest_pb2.TestAllTypes()
+    m1.repeated_int32.append(0)
+    m1.repeated_int32.append(1)
+    m1.repeated_int32.append(2)
+    m2.repeated_int32.append(0)
+    m2.repeated_int32.append(1)
+    m2.repeated_int32.append(2)
+    m1.repeated_nested_message.add().bb = 1
+    m1.repeated_nested_message.add().bb = 2
+    m1.repeated_nested_message.add().bb = 3
+    m2.repeated_nested_message.add().bb = 1
+    m2.repeated_nested_message.add().bb = 2
+    m2.repeated_nested_message.add().bb = 3
+
+    if sys.version_info.major >= 3: return  # No cmp() in PY3.
+
+    # These comparisons should not raise errors.
+    _ = m1 < m2
+    _ = m1.repeated_nested_message < m2.repeated_nested_message
+
+    # Make sure cmp always works. If it wasn't defined, these would be
+    # id() comparisons and would all fail.
+    self.assertEqual(cmp(m1, m2), 0)
+    self.assertEqual(cmp(m1.repeated_int32, m2.repeated_int32), 0)
+    self.assertEqual(cmp(m1.repeated_int32, [0, 1, 2]), 0)
+    self.assertEqual(cmp(m1.repeated_nested_message,
+                         m2.repeated_nested_message), 0)
+    with self.assertRaises(TypeError):
+      # Can't compare repeated composite containers to lists.
+      cmp(m1.repeated_nested_message, m2.repeated_nested_message[:])
+
+    # TODO(anuraag): Implement extensiondict comparison in C++ and then add test
+
+  def testParsingMerge(self):
+    """Check the merge behavior when a required or optional field appears
+    multiple times in the input."""
+    messages = [
+        unittest_pb2.TestAllTypes(),
+        unittest_pb2.TestAllTypes(),
+        unittest_pb2.TestAllTypes() ]
+    messages[0].optional_int32 = 1
+    messages[1].optional_int64 = 2
+    messages[2].optional_int32 = 3
+    messages[2].optional_string = 'hello'
+
+    merged_message = unittest_pb2.TestAllTypes()
+    merged_message.optional_int32 = 3
+    merged_message.optional_int64 = 2
+    merged_message.optional_string = 'hello'
+
+    generator = unittest_pb2.TestParsingMerge.RepeatedFieldsGenerator()
+    generator.field1.extend(messages)
+    generator.field2.extend(messages)
+    generator.field3.extend(messages)
+    generator.ext1.extend(messages)
+    generator.ext2.extend(messages)
+    generator.group1.add().field1.MergeFrom(messages[0])
+    generator.group1.add().field1.MergeFrom(messages[1])
+    generator.group1.add().field1.MergeFrom(messages[2])
+    generator.group2.add().field1.MergeFrom(messages[0])
+    generator.group2.add().field1.MergeFrom(messages[1])
+    generator.group2.add().field1.MergeFrom(messages[2])
+
+    data = generator.SerializeToString()
+    parsing_merge = unittest_pb2.TestParsingMerge()
+    parsing_merge.ParseFromString(data)
+
+    # Required and optional fields should be merged.
+    self.assertEqual(parsing_merge.required_all_types, merged_message)
+    self.assertEqual(parsing_merge.optional_all_types, merged_message)
+    self.assertEqual(parsing_merge.optionalgroup.optional_group_all_types,
+                     merged_message)
+    self.assertEqual(parsing_merge.Extensions[
+                     unittest_pb2.TestParsingMerge.optional_ext],
+                     merged_message)
+
+    # Repeated fields should not be merged.
+    self.assertEqual(len(parsing_merge.repeated_all_types), 3)
+    self.assertEqual(len(parsing_merge.repeatedgroup), 3)
+    self.assertEqual(len(parsing_merge.Extensions[
+        unittest_pb2.TestParsingMerge.repeated_ext]), 3)
+
+  def ensureNestedMessageExists(self, msg, attribute):
+    """Make sure that a nested message object exists.
+
+    As soon as a nested message attribute is accessed, it will be present in the
+    _fields dict, without being marked as actually being set.
+    """
+    getattr(msg, attribute)
+    self.assertFalse(msg.HasField(attribute))
+
+  def testOneofGetCaseNonexistingField(self):
+    m = unittest_pb2.TestAllTypes()
+    self.assertRaises(ValueError, m.WhichOneof, 'no_such_oneof_field')
+
+  def testOneofSemantics(self):
+    m = unittest_pb2.TestAllTypes()
+    self.assertIs(None, m.WhichOneof('oneof_field'))
+
+    m.oneof_uint32 = 11
+    self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+    self.assertTrue(m.HasField('oneof_uint32'))
+
+    m.oneof_string = u'foo'
+    self.assertEqual('oneof_string', m.WhichOneof('oneof_field'))
+    self.assertFalse(m.HasField('oneof_uint32'))
+    self.assertTrue(m.HasField('oneof_string'))
+
+    m.oneof_nested_message.bb = 11
+    self.assertEqual('oneof_nested_message', m.WhichOneof('oneof_field'))
+    self.assertFalse(m.HasField('oneof_string'))
+    self.assertTrue(m.HasField('oneof_nested_message'))
+
+    m.oneof_bytes = b'bb'
+    self.assertEqual('oneof_bytes', m.WhichOneof('oneof_field'))
+    self.assertFalse(m.HasField('oneof_nested_message'))
+    self.assertTrue(m.HasField('oneof_bytes'))
+
+  def testOneofCompositeFieldReadAccess(self):
+    m = unittest_pb2.TestAllTypes()
+    m.oneof_uint32 = 11
+
+    self.ensureNestedMessageExists(m, 'oneof_nested_message')
+    self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+    self.assertEqual(11, m.oneof_uint32)
+
+  def testOneofHasField(self):
+    m = unittest_pb2.TestAllTypes()
+    self.assertFalse(m.HasField('oneof_field'))
+    m.oneof_uint32 = 11
+    self.assertTrue(m.HasField('oneof_field'))
+    m.oneof_bytes = b'bb'
+    self.assertTrue(m.HasField('oneof_field'))
+    m.ClearField('oneof_bytes')
+    self.assertFalse(m.HasField('oneof_field'))
+
+  def testOneofClearField(self):
+    m = unittest_pb2.TestAllTypes()
+    m.oneof_uint32 = 11
+    m.ClearField('oneof_field')
+    self.assertFalse(m.HasField('oneof_field'))
+    self.assertFalse(m.HasField('oneof_uint32'))
+    self.assertIs(None, m.WhichOneof('oneof_field'))
+
+  def testOneofClearSetField(self):
+    m = unittest_pb2.TestAllTypes()
+    m.oneof_uint32 = 11
+    m.ClearField('oneof_uint32')
+    self.assertFalse(m.HasField('oneof_field'))
+    self.assertFalse(m.HasField('oneof_uint32'))
+    self.assertIs(None, m.WhichOneof('oneof_field'))
+
+  def testOneofClearUnsetField(self):
+    m = unittest_pb2.TestAllTypes()
+    m.oneof_uint32 = 11
+    self.ensureNestedMessageExists(m, 'oneof_nested_message')
+    m.ClearField('oneof_nested_message')
+    self.assertEqual(11, m.oneof_uint32)
+    self.assertTrue(m.HasField('oneof_field'))
+    self.assertTrue(m.HasField('oneof_uint32'))
+    self.assertEqual('oneof_uint32', m.WhichOneof('oneof_field'))
+
+  def testOneofDeserialize(self):
+    m = unittest_pb2.TestAllTypes()
+    m.oneof_uint32 = 11
+    m2 = unittest_pb2.TestAllTypes()
+    m2.ParseFromString(m.SerializeToString())
+    self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+
+  def testSortEmptyRepeatedCompositeContainer(self):
+    """Exercise a scenario that has led to segfaults in the past.
+    """
+    m = unittest_pb2.TestAllTypes()
+    m.repeated_nested_message.sort()
+
+  def testHasFieldOnRepeatedField(self):
+    """Using HasField on a repeated field should raise an exception.
+    """
+    m = unittest_pb2.TestAllTypes()
+    with self.assertRaises(ValueError) as _:
+      m.HasField('repeated_int32')
+
+
+class ValidTypeNamesTest(basetest.TestCase):
+
+  def assertImportFromName(self, msg, base_name):
+    # Parse <type 'module.class_name'> to extra 'some.name' as a string.
+    tp_name = str(type(msg)).split("'")[1]
+    valid_names = ('Repeated%sContainer' % base_name,
+                   'Repeated%sFieldContainer' % base_name)
+    self.assertTrue(any(tp_name.endswith(v) for v in valid_names),
+                    '%r does end with any of %r' % (tp_name, valid_names))
+
+    parts = tp_name.split('.')
+    class_name = parts[-1]
+    module_name = '.'.join(parts[:-1])
+    __import__(module_name, fromlist=[class_name])
+
+  def testTypeNamesCanBeImported(self):
+    # If import doesn't work, pickling won't work either.
+    pb = unittest_pb2.TestAllTypes()
+    self.assertImportFromName(pb.repeated_int32, 'Scalar')
+    self.assertImportFromName(pb.repeated_nested_message, 'Composite')
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/missing_enum_values.proto b/protobuf/python/google/protobuf/internal/missing_enum_values.proto
new file mode 100644
index 0000000..e90f0cd
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/missing_enum_values.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package google.protobuf.python.internal;
+
+message TestEnumValues {
+  enum NestedEnum {
+    ZERO = 0;
+    ONE = 1;
+  }
+  optional NestedEnum optional_nested_enum = 1;
+  repeated NestedEnum repeated_nested_enum = 2;
+  repeated NestedEnum packed_nested_enum = 3 [packed = true];
+}
+
+message TestMissingEnumValues {
+  enum NestedEnum {
+    TWO = 2;
+  }
+  optional NestedEnum optional_nested_enum = 1;
+  repeated NestedEnum repeated_nested_enum = 2;
+  repeated NestedEnum packed_nested_enum = 3 [packed = true];
+}
diff --git a/protobuf/python/google/protobuf/internal/more_extensions.proto b/protobuf/python/google/protobuf/internal/more_extensions.proto
new file mode 100644
index 0000000..c04e597
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/more_extensions.proto
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: robinson@google.com (Will Robinson)
+
+
+package google.protobuf.internal;
+
+
+message TopLevelMessage {
+  optional ExtendedMessage submessage = 1;
+}
+
+
+message ExtendedMessage {
+  extensions 1 to max;
+}
+
+
+message ForeignMessage {
+  optional int32 foreign_message_int = 1;
+}
+
+
+extend ExtendedMessage {
+  optional int32 optional_int_extension = 1;
+  optional ForeignMessage optional_message_extension = 2;
+
+  repeated int32 repeated_int_extension = 3;
+  repeated ForeignMessage repeated_message_extension = 4;
+}
diff --git a/protobuf/python/google/protobuf/internal/more_extensions_dynamic.proto b/protobuf/python/google/protobuf/internal/more_extensions_dynamic.proto
new file mode 100644
index 0000000..88bd9c1
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/more_extensions_dynamic.proto
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jasonh@google.com (Jason Hsueh)
+//
+// This file is used to test a corner case in the CPP implementation where the
+// generated C++ type is available for the extendee, but the extension is
+// defined in a file whose C++ type is not in the binary.
+
+
+import "google/protobuf/internal/more_extensions.proto";
+
+package google.protobuf.internal;
+
+message DynamicMessageType {
+  optional int32 a = 1;
+}
+
+extend ExtendedMessage {
+  optional int32 dynamic_int32_extension = 100;
+  optional DynamicMessageType dynamic_message_extension = 101;
+}
diff --git a/protobuf/python/google/protobuf/internal/more_messages.proto b/protobuf/python/google/protobuf/internal/more_messages.proto
new file mode 100644
index 0000000..61db66c
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/more_messages.proto
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: robinson@google.com (Will Robinson)
+
+
+package google.protobuf.internal;
+
+// A message where tag numbers are listed out of order, to allow us to test our
+// canonicalization of serialized output, which should always be in tag order.
+// We also mix in some extensions for extra fun.
+message OutOfOrderFields {
+  optional   sint32 optional_sint32   =  5;
+  extensions 4 to 4;
+  optional   uint32 optional_uint32   =  3;
+  extensions 2 to 2;
+  optional    int32 optional_int32    =  1;
+};
+
+
+extend OutOfOrderFields {
+  optional   uint64 optional_uint64   =  4;
+  optional    int64 optional_int64    =  2;
+}
diff --git a/protobuf/python/google/protobuf/internal/python_message.py b/protobuf/python/google/protobuf/internal/python_message.py
new file mode 100755
index 0000000..a5c26f4
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/python_message.py
@@ -0,0 +1,1251 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Keep it Python2.5 compatible for GAE.
+#
+# Copyright 2007 Google Inc. All Rights Reserved.
+#
+# This code is meant to work on Python 2.4 and above only.
+#
+# TODO(robinson): Helpers for verbose, common checks like seeing if a
+# descriptor's cpp_type is CPPTYPE_MESSAGE.
+
+"""Contains a metaclass and helper functions used to create
+protocol message classes from Descriptor objects at runtime.
+
+Recall that a metaclass is the "type" of a class.
+(A class is to a metaclass what an instance is to a class.)
+
+In this case, we use the GeneratedProtocolMessageType metaclass
+to inject all the useful functionality into the classes
+output by the protocol compiler at compile-time.
+
+The upshot of all this is that the real implementation
+details for ALL pure-Python protocol buffers are *here in
+this file*.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import sys
+if sys.version_info[0] < 3:
+  try:
+    from cStringIO import StringIO as BytesIO
+  except ImportError:
+    from StringIO import StringIO as BytesIO
+  import copy_reg as copyreg
+else:
+  from io import BytesIO
+  import copyreg
+import struct
+import weakref
+
+# We use "as" to avoid name collisions with variables.
+from google.protobuf.internal import containers
+from google.protobuf.internal import decoder
+from google.protobuf.internal import encoder
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf.internal import message_listener as message_listener_mod
+from google.protobuf.internal import type_checkers
+from google.protobuf.internal import wire_format
+from google.protobuf import descriptor as descriptor_mod
+from google.protobuf import message as message_mod
+from google.protobuf import text_format
+
+_FieldDescriptor = descriptor_mod.FieldDescriptor
+
+
+def NewMessage(bases, descriptor, dictionary):
+  _AddClassAttributesForNestedExtensions(descriptor, dictionary)
+  _AddSlots(descriptor, dictionary)
+  return bases
+
+
+def InitMessage(descriptor, cls):
+  cls._decoders_by_tag = {}
+  cls._extensions_by_name = {}
+  cls._extensions_by_number = {}
+  if (descriptor.has_options and
+      descriptor.GetOptions().message_set_wire_format):
+    cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = (
+        decoder.MessageSetItemDecoder(cls._extensions_by_number), None)
+
+  # Attach stuff to each FieldDescriptor for quick lookup later on.
+  for field in descriptor.fields:
+    _AttachFieldHelpers(cls, field)
+
+  _AddEnumValues(descriptor, cls)
+  _AddInitMethod(descriptor, cls)
+  _AddPropertiesForFields(descriptor, cls)
+  _AddPropertiesForExtensions(descriptor, cls)
+  _AddStaticMethods(cls)
+  _AddMessageMethods(descriptor, cls)
+  _AddPrivateHelperMethods(descriptor, cls)
+  copyreg.pickle(cls, lambda obj: (cls, (), obj.__getstate__()))
+
+
+# Stateless helpers for GeneratedProtocolMessageType below.
+# Outside clients should not access these directly.
+#
+# I opted not to make any of these methods on the metaclass, to make it more
+# clear that I'm not really using any state there and to keep clients from
+# thinking that they have direct access to these construction helpers.
+
+
+def _PropertyName(proto_field_name):
+  """Returns the name of the public property attribute which
+  clients can use to get and (in some cases) set the value
+  of a protocol message field.
+
+  Args:
+    proto_field_name: The protocol message field name, exactly
+      as it appears (or would appear) in a .proto file.
+  """
+  # TODO(robinson): Escape Python keywords (e.g., yield), and test this support.
+  # nnorwitz makes my day by writing:
+  # """
+  # FYI.  See the keyword module in the stdlib. This could be as simple as:
+  #
+  # if keyword.iskeyword(proto_field_name):
+  #   return proto_field_name + "_"
+  # return proto_field_name
+  # """
+  # Kenton says:  The above is a BAD IDEA.  People rely on being able to use
+  #   getattr() and setattr() to reflectively manipulate field values.  If we
+  #   rename the properties, then every such user has to also make sure to apply
+  #   the same transformation.  Note that currently if you name a field "yield",
+  #   you can still access it just fine using getattr/setattr -- it's not even
+  #   that cumbersome to do so.
+  # TODO(kenton):  Remove this method entirely if/when everyone agrees with my
+  #   position.
+  return proto_field_name
+
+
+def _VerifyExtensionHandle(message, extension_handle):
+  """Verify that the given extension handle is valid."""
+
+  if not isinstance(extension_handle, _FieldDescriptor):
+    raise KeyError('HasExtension() expects an extension handle, got: %s' %
+                   extension_handle)
+
+  if not extension_handle.is_extension:
+    raise KeyError('"%s" is not an extension.' % extension_handle.full_name)
+
+  if not extension_handle.containing_type:
+    raise KeyError('"%s" is missing a containing_type.'
+                   % extension_handle.full_name)
+
+  if extension_handle.containing_type is not message.DESCRIPTOR:
+    raise KeyError('Extension "%s" extends message type "%s", but this '
+                   'message is of type "%s".' %
+                   (extension_handle.full_name,
+                    extension_handle.containing_type.full_name,
+                    message.DESCRIPTOR.full_name))
+
+
+def _AddSlots(message_descriptor, dictionary):
+  """Adds a __slots__ entry to dictionary, containing the names of all valid
+  attributes for this message type.
+
+  Args:
+    message_descriptor: A Descriptor instance describing this message type.
+    dictionary: Class dictionary to which we'll add a '__slots__' entry.
+  """
+  dictionary['__slots__'] = ['_cached_byte_size',
+                             '_cached_byte_size_dirty',
+                             '_fields',
+                             '_unknown_fields',
+                             '_is_present_in_parent',
+                             '_listener',
+                             '_listener_for_children',
+                             '__weakref__',
+                             '_oneofs']
+
+
+def _IsMessageSetExtension(field):
+  return (field.is_extension and
+          field.containing_type.has_options and
+          field.containing_type.GetOptions().message_set_wire_format and
+          field.type == _FieldDescriptor.TYPE_MESSAGE and
+          field.message_type == field.extension_scope and
+          field.label == _FieldDescriptor.LABEL_OPTIONAL)
+
+
+def _AttachFieldHelpers(cls, field_descriptor):
+  is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED)
+  is_packed = (field_descriptor.has_options and
+               field_descriptor.GetOptions().packed)
+
+  if _IsMessageSetExtension(field_descriptor):
+    field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number)
+    sizer = encoder.MessageSetItemSizer(field_descriptor.number)
+  else:
+    field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type](
+        field_descriptor.number, is_repeated, is_packed)
+    sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type](
+        field_descriptor.number, is_repeated, is_packed)
+
+  field_descriptor._encoder = field_encoder
+  field_descriptor._sizer = sizer
+  field_descriptor._default_constructor = _DefaultValueConstructorForField(
+      field_descriptor)
+
+  def AddDecoder(wiretype, is_packed):
+    tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype)
+    cls._decoders_by_tag[tag_bytes] = (
+        type_checkers.TYPE_TO_DECODER[field_descriptor.type](
+            field_descriptor.number, is_repeated, is_packed,
+            field_descriptor, field_descriptor._default_constructor),
+        field_descriptor if field_descriptor.containing_oneof is not None
+        else None)
+
+  AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type],
+             False)
+
+  if is_repeated and wire_format.IsTypePackable(field_descriptor.type):
+    # To support wire compatibility of adding packed = true, add a decoder for
+    # packed values regardless of the field's options.
+    AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True)
+
+
+def _AddClassAttributesForNestedExtensions(descriptor, dictionary):
+  extension_dict = descriptor.extensions_by_name
+  for extension_name, extension_field in extension_dict.iteritems():
+    assert extension_name not in dictionary
+    dictionary[extension_name] = extension_field
+
+
+def _AddEnumValues(descriptor, cls):
+  """Sets class-level attributes for all enum fields defined in this message.
+
+  Also exporting a class-level object that can name enum values.
+
+  Args:
+    descriptor: Descriptor object for this message type.
+    cls: Class we're constructing for this message type.
+  """
+  for enum_type in descriptor.enum_types:
+    setattr(cls, enum_type.name, enum_type_wrapper.EnumTypeWrapper(enum_type))
+    for enum_value in enum_type.values:
+      setattr(cls, enum_value.name, enum_value.number)
+
+
+def _DefaultValueConstructorForField(field):
+  """Returns a function which returns a default value for a field.
+
+  Args:
+    field: FieldDescriptor object for this field.
+
+  The returned function has one argument:
+    message: Message instance containing this field, or a weakref proxy
+      of same.
+
+  That function in turn returns a default value for this field.  The default
+    value may refer back to |message| via a weak reference.
+  """
+
+  if field.label == _FieldDescriptor.LABEL_REPEATED:
+    if field.has_default_value and field.default_value != []:
+      raise ValueError('Repeated field default value not empty list: %s' % (
+          field.default_value))
+    if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+      # We can't look at _concrete_class yet since it might not have
+      # been set.  (Depends on order in which we initialize the classes).
+      message_type = field.message_type
+      def MakeRepeatedMessageDefault(message):
+        return containers.RepeatedCompositeFieldContainer(
+            message._listener_for_children, field.message_type)
+      return MakeRepeatedMessageDefault
+    else:
+      type_checker = type_checkers.GetTypeChecker(field)
+      def MakeRepeatedScalarDefault(message):
+        return containers.RepeatedScalarFieldContainer(
+            message._listener_for_children, type_checker)
+      return MakeRepeatedScalarDefault
+
+  if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+    # _concrete_class may not yet be initialized.
+    message_type = field.message_type
+    def MakeSubMessageDefault(message):
+      result = message_type._concrete_class()
+      result._SetListener(message._listener_for_children)
+      return result
+    return MakeSubMessageDefault
+
+  def MakeScalarDefault(message):
+    # TODO(protobuf-team): This may be broken since there may not be
+    # default_value.  Combine with has_default_value somehow.
+    return field.default_value
+  return MakeScalarDefault
+
+
+def _AddInitMethod(message_descriptor, cls):
+  """Adds an __init__ method to cls."""
+  fields = message_descriptor.fields
+  def init(self, **kwargs):
+    self._cached_byte_size = 0
+    self._cached_byte_size_dirty = len(kwargs) > 0
+    self._fields = {}
+    # Contains a mapping from oneof field descriptors to the descriptor
+    # of the currently set field in that oneof field.
+    self._oneofs = {}
+
+    # _unknown_fields is () when empty for efficiency, and will be turned into
+    # a list if fields are added.
+    self._unknown_fields = ()
+    self._is_present_in_parent = False
+    self._listener = message_listener_mod.NullMessageListener()
+    self._listener_for_children = _Listener(self)
+    for field_name, field_value in kwargs.iteritems():
+      field = _GetFieldByName(message_descriptor, field_name)
+      if field is None:
+        raise TypeError("%s() got an unexpected keyword argument '%s'" %
+                        (message_descriptor.name, field_name))
+      if field.label == _FieldDescriptor.LABEL_REPEATED:
+        copy = field._default_constructor(self)
+        if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:  # Composite
+          for val in field_value:
+            copy.add().MergeFrom(val)
+        else:  # Scalar
+          copy.extend(field_value)
+        self._fields[field] = copy
+      elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+        copy = field._default_constructor(self)
+        copy.MergeFrom(field_value)
+        self._fields[field] = copy
+      else:
+        setattr(self, field_name, field_value)
+
+  init.__module__ = None
+  init.__doc__ = None
+  cls.__init__ = init
+
+
+def _GetFieldByName(message_descriptor, field_name):
+  """Returns a field descriptor by field name.
+
+  Args:
+    message_descriptor: A Descriptor describing all fields in message.
+    field_name: The name of the field to retrieve.
+  Returns:
+    The field descriptor associated with the field name.
+  """
+  try:
+    return message_descriptor.fields_by_name[field_name]
+  except KeyError:
+    raise ValueError('Protocol message has no "%s" field.' % field_name)
+
+
+def _AddPropertiesForFields(descriptor, cls):
+  """Adds properties for all fields in this protocol message type."""
+  for field in descriptor.fields:
+    _AddPropertiesForField(field, cls)
+
+  if descriptor.is_extendable:
+    # _ExtensionDict is just an adaptor with no state so we allocate a new one
+    # every time it is accessed.
+    cls.Extensions = property(lambda self: _ExtensionDict(self))
+
+
+def _AddPropertiesForField(field, cls):
+  """Adds a public property for a protocol message field.
+  Clients can use this property to get and (in the case
+  of non-repeated scalar fields) directly set the value
+  of a protocol message field.
+
+  Args:
+    field: A FieldDescriptor for this field.
+    cls: The class we're constructing.
+  """
+  # Catch it if we add other types that we should
+  # handle specially here.
+  assert _FieldDescriptor.MAX_CPPTYPE == 10
+
+  constant_name = field.name.upper() + "_FIELD_NUMBER"
+  setattr(cls, constant_name, field.number)
+
+  if field.label == _FieldDescriptor.LABEL_REPEATED:
+    _AddPropertiesForRepeatedField(field, cls)
+  elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+    _AddPropertiesForNonRepeatedCompositeField(field, cls)
+  else:
+    _AddPropertiesForNonRepeatedScalarField(field, cls)
+
+
+def _AddPropertiesForRepeatedField(field, cls):
+  """Adds a public property for a "repeated" protocol message field.  Clients
+  can use this property to get the value of the field, which will be either a
+  _RepeatedScalarFieldContainer or _RepeatedCompositeFieldContainer (see
+  below).
+
+  Note that when clients add values to these containers, we perform
+  type-checking in the case of repeated scalar fields, and we also set any
+  necessary "has" bits as a side-effect.
+
+  Args:
+    field: A FieldDescriptor for this field.
+    cls: The class we're constructing.
+  """
+  proto_field_name = field.name
+  property_name = _PropertyName(proto_field_name)
+
+  def getter(self):
+    field_value = self._fields.get(field)
+    if field_value is None:
+      # Construct a new object to represent this field.
+      field_value = field._default_constructor(self)
+
+      # Atomically check if another thread has preempted us and, if not, swap
+      # in the new object we just created.  If someone has preempted us, we
+      # take that object and discard ours.
+      # WARNING:  We are relying on setdefault() being atomic.  This is true
+      #   in CPython but we haven't investigated others.  This warning appears
+      #   in several other locations in this file.
+      field_value = self._fields.setdefault(field, field_value)
+    return field_value
+  getter.__module__ = None
+  getter.__doc__ = 'Getter for %s.' % proto_field_name
+
+  # We define a setter just so we can throw an exception with a more
+  # helpful error message.
+  def setter(self, new_value):
+    raise AttributeError('Assignment not allowed to repeated field '
+                         '"%s" in protocol message object.' % proto_field_name)
+
+  doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+  setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForNonRepeatedScalarField(field, cls):
+  """Adds a public property for a nonrepeated, scalar protocol message field.
+  Clients can use this property to get and directly set the value of the field.
+  Note that when the client sets the value of a field by using this property,
+  all necessary "has" bits are set as a side-effect, and we also perform
+  type-checking.
+
+  Args:
+    field: A FieldDescriptor for this field.
+    cls: The class we're constructing.
+  """
+  proto_field_name = field.name
+  property_name = _PropertyName(proto_field_name)
+  type_checker = type_checkers.GetTypeChecker(field)
+  default_value = field.default_value
+  valid_values = set()
+
+  def getter(self):
+    # TODO(protobuf-team): This may be broken since there may not be
+    # default_value.  Combine with has_default_value somehow.
+    return self._fields.get(field, default_value)
+  getter.__module__ = None
+  getter.__doc__ = 'Getter for %s.' % proto_field_name
+  def field_setter(self, new_value):
+    # pylint: disable=protected-access
+    self._fields[field] = type_checker.CheckValue(new_value)
+    # Check _cached_byte_size_dirty inline to improve performance, since scalar
+    # setters are called frequently.
+    if not self._cached_byte_size_dirty:
+      self._Modified()
+
+  if field.containing_oneof is not None:
+    def setter(self, new_value):
+      field_setter(self, new_value)
+      self._UpdateOneofState(field)
+  else:
+    setter = field_setter
+
+  setter.__module__ = None
+  setter.__doc__ = 'Setter for %s.' % proto_field_name
+
+  # Add a property to encapsulate the getter/setter.
+  doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+  setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForNonRepeatedCompositeField(field, cls):
+  """Adds a public property for a nonrepeated, composite protocol message field.
+  A composite field is a "group" or "message" field.
+
+  Clients can use this property to get the value of the field, but cannot
+  assign to the property directly.
+
+  Args:
+    field: A FieldDescriptor for this field.
+    cls: The class we're constructing.
+  """
+  # TODO(robinson): Remove duplication with similar method
+  # for non-repeated scalars.
+  proto_field_name = field.name
+  property_name = _PropertyName(proto_field_name)
+
+  # TODO(komarek): Can anyone explain to me why we cache the message_type this
+  # way, instead of referring to field.message_type inside of getter(self)?
+  # What if someone sets message_type later on (which makes for simpler
+  # dyanmic proto descriptor and class creation code).
+  message_type = field.message_type
+
+  def getter(self):
+    field_value = self._fields.get(field)
+    if field_value is None:
+      # Construct a new object to represent this field.
+      field_value = message_type._concrete_class()  # use field.message_type?
+      field_value._SetListener(
+          _OneofListener(self, field)
+          if field.containing_oneof is not None
+          else self._listener_for_children)
+
+      # Atomically check if another thread has preempted us and, if not, swap
+      # in the new object we just created.  If someone has preempted us, we
+      # take that object and discard ours.
+      # WARNING:  We are relying on setdefault() being atomic.  This is true
+      #   in CPython but we haven't investigated others.  This warning appears
+      #   in several other locations in this file.
+      field_value = self._fields.setdefault(field, field_value)
+    return field_value
+  getter.__module__ = None
+  getter.__doc__ = 'Getter for %s.' % proto_field_name
+
+  # We define a setter just so we can throw an exception with a more
+  # helpful error message.
+  def setter(self, new_value):
+    raise AttributeError('Assignment not allowed to composite field '
+                         '"%s" in protocol message object.' % proto_field_name)
+
+  # Add a property to encapsulate the getter.
+  doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name
+  setattr(cls, property_name, property(getter, setter, doc=doc))
+
+
+def _AddPropertiesForExtensions(descriptor, cls):
+  """Adds properties for all fields in this protocol message type."""
+  extension_dict = descriptor.extensions_by_name
+  for extension_name, extension_field in extension_dict.iteritems():
+    constant_name = extension_name.upper() + "_FIELD_NUMBER"
+    setattr(cls, constant_name, extension_field.number)
+
+
+def _AddStaticMethods(cls):
+  # TODO(robinson): This probably needs to be thread-safe(?)
+  def RegisterExtension(extension_handle):
+    extension_handle.containing_type = cls.DESCRIPTOR
+    _AttachFieldHelpers(cls, extension_handle)
+
+    # Try to insert our extension, failing if an extension with the same number
+    # already exists.
+    actual_handle = cls._extensions_by_number.setdefault(
+        extension_handle.number, extension_handle)
+    if actual_handle is not extension_handle:
+      raise AssertionError(
+          'Extensions "%s" and "%s" both try to extend message type "%s" with '
+          'field number %d.' %
+          (extension_handle.full_name, actual_handle.full_name,
+           cls.DESCRIPTOR.full_name, extension_handle.number))
+
+    cls._extensions_by_name[extension_handle.full_name] = extension_handle
+
+    handle = extension_handle  # avoid line wrapping
+    if _IsMessageSetExtension(handle):
+      # MessageSet extension.  Also register under type name.
+      cls._extensions_by_name[
+          extension_handle.message_type.full_name] = extension_handle
+
+  cls.RegisterExtension = staticmethod(RegisterExtension)
+
+  def FromString(s):
+    message = cls()
+    message.MergeFromString(s)
+    return message
+  cls.FromString = staticmethod(FromString)
+
+
+def _IsPresent(item):
+  """Given a (FieldDescriptor, value) tuple from _fields, return true if the
+  value should be included in the list returned by ListFields()."""
+
+  if item[0].label == _FieldDescriptor.LABEL_REPEATED:
+    return bool(item[1])
+  elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+    return item[1]._is_present_in_parent
+  else:
+    return True
+
+
+def _AddListFieldsMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+
+  def ListFields(self):
+    all_fields = [item for item in self._fields.iteritems() if _IsPresent(item)]
+    all_fields.sort(key = lambda item: item[0].number)
+    return all_fields
+
+  cls.ListFields = ListFields
+
+
+def _AddHasFieldMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+
+  singular_fields = {}
+  for field in message_descriptor.fields:
+    if field.label != _FieldDescriptor.LABEL_REPEATED:
+      singular_fields[field.name] = field
+  # Fields inside oneofs are never repeated (enforced by the compiler).
+  for field in message_descriptor.oneofs:
+    singular_fields[field.name] = field
+
+  def HasField(self, field_name):
+    try:
+      field = singular_fields[field_name]
+    except KeyError:
+      raise ValueError(
+          'Protocol message has no singular "%s" field.' % field_name)
+
+    if isinstance(field, descriptor_mod.OneofDescriptor):
+      try:
+        return HasField(self, self._oneofs[field].name)
+      except KeyError:
+        return False
+    else:
+      if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+        value = self._fields.get(field)
+        return value is not None and value._is_present_in_parent
+      else:
+        return field in self._fields
+
+  cls.HasField = HasField
+
+
+def _AddClearFieldMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+  def ClearField(self, field_name):
+    try:
+      field = message_descriptor.fields_by_name[field_name]
+    except KeyError:
+      try:
+        field = message_descriptor.oneofs_by_name[field_name]
+        if field in self._oneofs:
+          field = self._oneofs[field]
+        else:
+          return
+      except KeyError:
+        raise ValueError('Protocol message has no "%s" field.' % field_name)
+
+    if field in self._fields:
+      # Note:  If the field is a sub-message, its listener will still point
+      #   at us.  That's fine, because the worst than can happen is that it
+      #   will call _Modified() and invalidate our byte size.  Big deal.
+      del self._fields[field]
+
+      if self._oneofs.get(field.containing_oneof, None) is field:
+        del self._oneofs[field.containing_oneof]
+
+    # Always call _Modified() -- even if nothing was changed, this is
+    # a mutating method, and thus calling it should cause the field to become
+    # present in the parent message.
+    self._Modified()
+
+  cls.ClearField = ClearField
+
+
+def _AddClearExtensionMethod(cls):
+  """Helper for _AddMessageMethods()."""
+  def ClearExtension(self, extension_handle):
+    _VerifyExtensionHandle(self, extension_handle)
+
+    # Similar to ClearField(), above.
+    if extension_handle in self._fields:
+      del self._fields[extension_handle]
+    self._Modified()
+  cls.ClearExtension = ClearExtension
+
+
+def _AddClearMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+  def Clear(self):
+    # Clear fields.
+    self._fields = {}
+    self._unknown_fields = ()
+    self._Modified()
+  cls.Clear = Clear
+
+
+def _AddHasExtensionMethod(cls):
+  """Helper for _AddMessageMethods()."""
+  def HasExtension(self, extension_handle):
+    _VerifyExtensionHandle(self, extension_handle)
+    if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
+      raise KeyError('"%s" is repeated.' % extension_handle.full_name)
+
+    if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+      value = self._fields.get(extension_handle)
+      return value is not None and value._is_present_in_parent
+    else:
+      return extension_handle in self._fields
+  cls.HasExtension = HasExtension
+
+
+def _AddEqualsMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+  def __eq__(self, other):
+    if (not isinstance(other, message_mod.Message) or
+        other.DESCRIPTOR != self.DESCRIPTOR):
+      return False
+
+    if self is other:
+      return True
+
+    if not self.ListFields() == other.ListFields():
+      return False
+
+    # Sort unknown fields because their order shouldn't affect equality test.
+    unknown_fields = list(self._unknown_fields)
+    unknown_fields.sort()
+    other_unknown_fields = list(other._unknown_fields)
+    other_unknown_fields.sort()
+
+    return unknown_fields == other_unknown_fields
+
+  cls.__eq__ = __eq__
+
+
+def _AddStrMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+  def __str__(self):
+    return text_format.MessageToString(self)
+  cls.__str__ = __str__
+
+
+def _AddUnicodeMethod(unused_message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+
+  def __unicode__(self):
+    return text_format.MessageToString(self, as_utf8=True).decode('utf-8')
+  cls.__unicode__ = __unicode__
+
+
+def _AddSetListenerMethod(cls):
+  """Helper for _AddMessageMethods()."""
+  def SetListener(self, listener):
+    if listener is None:
+      self._listener = message_listener_mod.NullMessageListener()
+    else:
+      self._listener = listener
+  cls._SetListener = SetListener
+
+
+def _BytesForNonRepeatedElement(value, field_number, field_type):
+  """Returns the number of bytes needed to serialize a non-repeated element.
+  The returned byte count includes space for tag information and any
+  other additional space associated with serializing value.
+
+  Args:
+    value: Value we're serializing.
+    field_number: Field number of this value.  (Since the field number
+      is stored as part of a varint-encoded tag, this has an impact
+      on the total bytes required to serialize the value).
+    field_type: The type of the field.  One of the TYPE_* constants
+      within FieldDescriptor.
+  """
+  try:
+    fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type]
+    return fn(field_number, value)
+  except KeyError:
+    raise message_mod.EncodeError('Unrecognized field type: %d' % field_type)
+
+
+def _AddByteSizeMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+
+  def ByteSize(self):
+    if not self._cached_byte_size_dirty:
+      return self._cached_byte_size
+
+    size = 0
+    for field_descriptor, field_value in self.ListFields():
+      size += field_descriptor._sizer(field_value)
+
+    for tag_bytes, value_bytes in self._unknown_fields:
+      size += len(tag_bytes) + len(value_bytes)
+
+    self._cached_byte_size = size
+    self._cached_byte_size_dirty = False
+    self._listener_for_children.dirty = False
+    return size
+
+  cls.ByteSize = ByteSize
+
+
+def _AddSerializeToStringMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+
+  def SerializeToString(self):
+    # Check if the message has all of its required fields set.
+    errors = []
+    if not self.IsInitialized():
+      raise message_mod.EncodeError(
+          'Message %s is missing required fields: %s' % (
+          self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
+    return self.SerializePartialToString()
+  cls.SerializeToString = SerializeToString
+
+
+def _AddSerializePartialToStringMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+
+  def SerializePartialToString(self):
+    out = BytesIO()
+    self._InternalSerialize(out.write)
+    return out.getvalue()
+  cls.SerializePartialToString = SerializePartialToString
+
+  def InternalSerialize(self, write_bytes):
+    for field_descriptor, field_value in self.ListFields():
+      field_descriptor._encoder(write_bytes, field_value)
+    for tag_bytes, value_bytes in self._unknown_fields:
+      write_bytes(tag_bytes)
+      write_bytes(value_bytes)
+  cls._InternalSerialize = InternalSerialize
+
+
+def _AddMergeFromStringMethod(message_descriptor, cls):
+  """Helper for _AddMessageMethods()."""
+  def MergeFromString(self, serialized):
+    length = len(serialized)
+    try:
+      if self._InternalParse(serialized, 0, length) != length:
+        # The only reason _InternalParse would return early is if it
+        # encountered an end-group tag.
+        raise message_mod.DecodeError('Unexpected end-group tag.')
+    except (IndexError, TypeError):
+      # Now ord(buf[p:p+1]) == ord('') gets TypeError.
+      raise message_mod.DecodeError('Truncated message.')
+    except struct.error, e:
+      raise message_mod.DecodeError(e)
+    return length   # Return this for legacy reasons.
+  cls.MergeFromString = MergeFromString
+
+  local_ReadTag = decoder.ReadTag
+  local_SkipField = decoder.SkipField
+  decoders_by_tag = cls._decoders_by_tag
+
+  def InternalParse(self, buffer, pos, end):
+    self._Modified()
+    field_dict = self._fields
+    unknown_field_list = self._unknown_fields
+    while pos != end:
+      (tag_bytes, new_pos) = local_ReadTag(buffer, pos)
+      field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (None, None))
+      if field_decoder is None:
+        value_start_pos = new_pos
+        new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
+        if new_pos == -1:
+          return pos
+        if not unknown_field_list:
+          unknown_field_list = self._unknown_fields = []
+        unknown_field_list.append((tag_bytes, buffer[value_start_pos:new_pos]))
+        pos = new_pos
+      else:
+        pos = field_decoder(buffer, new_pos, end, self, field_dict)
+        if field_desc:
+          self._UpdateOneofState(field_desc)
+    return pos
+  cls._InternalParse = InternalParse
+
+
+def _AddIsInitializedMethod(message_descriptor, cls):
+  """Adds the IsInitialized and FindInitializationError methods to the
+  protocol message class."""
+
+  required_fields = [field for field in message_descriptor.fields
+                           if field.label == _FieldDescriptor.LABEL_REQUIRED]
+
+  def IsInitialized(self, errors=None):
+    """Checks if all required fields of a message are set.
+
+    Args:
+      errors:  A list which, if provided, will be populated with the field
+               paths of all missing required fields.
+
+    Returns:
+      True iff the specified message has all required fields set.
+    """
+
+    # Performance is critical so we avoid HasField() and ListFields().
+
+    for field in required_fields:
+      if (field not in self._fields or
+          (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and
+           not self._fields[field]._is_present_in_parent)):
+        if errors is not None:
+          errors.extend(self.FindInitializationErrors())
+        return False
+
+    for field, value in list(self._fields.items()):  # dict can change size!
+      if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+        if field.label == _FieldDescriptor.LABEL_REPEATED:
+          for element in value:
+            if not element.IsInitialized():
+              if errors is not None:
+                errors.extend(self.FindInitializationErrors())
+              return False
+        elif value._is_present_in_parent and not value.IsInitialized():
+          if errors is not None:
+            errors.extend(self.FindInitializationErrors())
+          return False
+
+    return True
+
+  cls.IsInitialized = IsInitialized
+
+  def FindInitializationErrors(self):
+    """Finds required fields which are not initialized.
+
+    Returns:
+      A list of strings.  Each string is a path to an uninitialized field from
+      the top-level message, e.g. "foo.bar[5].baz".
+    """
+
+    errors = []  # simplify things
+
+    for field in required_fields:
+      if not self.HasField(field.name):
+        errors.append(field.name)
+
+    for field, value in self.ListFields():
+      if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+        if field.is_extension:
+          name = "(%s)" % field.full_name
+        else:
+          name = field.name
+
+        if field.label == _FieldDescriptor.LABEL_REPEATED:
+          for i in xrange(len(value)):
+            element = value[i]
+            prefix = "%s[%d]." % (name, i)
+            sub_errors = element.FindInitializationErrors()
+            errors += [ prefix + error for error in sub_errors ]
+        else:
+          prefix = name + "."
+          sub_errors = value.FindInitializationErrors()
+          errors += [ prefix + error for error in sub_errors ]
+
+    return errors
+
+  cls.FindInitializationErrors = FindInitializationErrors
+
+
+def _AddMergeFromMethod(cls):
+  LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED
+  CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE
+
+  def MergeFrom(self, msg):
+    if not isinstance(msg, cls):
+      raise TypeError(
+          "Parameter to MergeFrom() must be instance of same class: "
+          "expected %s got %s." % (cls.__name__, type(msg).__name__))
+
+    assert msg is not self
+    self._Modified()
+
+    fields = self._fields
+
+    for field, value in msg._fields.iteritems():
+      if field.label == LABEL_REPEATED:
+        field_value = fields.get(field)
+        if field_value is None:
+          # Construct a new object to represent this field.
+          field_value = field._default_constructor(self)
+          fields[field] = field_value
+        field_value.MergeFrom(value)
+      elif field.cpp_type == CPPTYPE_MESSAGE:
+        if value._is_present_in_parent:
+          field_value = fields.get(field)
+          if field_value is None:
+            # Construct a new object to represent this field.
+            field_value = field._default_constructor(self)
+            fields[field] = field_value
+          field_value.MergeFrom(value)
+      else:
+        self._fields[field] = value
+
+    if msg._unknown_fields:
+      if not self._unknown_fields:
+        self._unknown_fields = []
+      self._unknown_fields.extend(msg._unknown_fields)
+
+  cls.MergeFrom = MergeFrom
+
+
+def _AddWhichOneofMethod(message_descriptor, cls):
+  def WhichOneof(self, oneof_name):
+    """Returns the name of the currently set field inside a oneof, or None."""
+    try:
+      field = message_descriptor.oneofs_by_name[oneof_name]
+    except KeyError:
+      raise ValueError(
+          'Protocol message has no oneof "%s" field.' % oneof_name)
+
+    nested_field = self._oneofs.get(field, None)
+    if nested_field is not None and self.HasField(nested_field.name):
+      return nested_field.name
+    else:
+      return None
+
+  cls.WhichOneof = WhichOneof
+
+
+def _AddMessageMethods(message_descriptor, cls):
+  """Adds implementations of all Message methods to cls."""
+  _AddListFieldsMethod(message_descriptor, cls)
+  _AddHasFieldMethod(message_descriptor, cls)
+  _AddClearFieldMethod(message_descriptor, cls)
+  if message_descriptor.is_extendable:
+    _AddClearExtensionMethod(cls)
+    _AddHasExtensionMethod(cls)
+  _AddClearMethod(message_descriptor, cls)
+  _AddEqualsMethod(message_descriptor, cls)
+  _AddStrMethod(message_descriptor, cls)
+  _AddUnicodeMethod(message_descriptor, cls)
+  _AddSetListenerMethod(cls)
+  _AddByteSizeMethod(message_descriptor, cls)
+  _AddSerializeToStringMethod(message_descriptor, cls)
+  _AddSerializePartialToStringMethod(message_descriptor, cls)
+  _AddMergeFromStringMethod(message_descriptor, cls)
+  _AddIsInitializedMethod(message_descriptor, cls)
+  _AddMergeFromMethod(cls)
+  _AddWhichOneofMethod(message_descriptor, cls)
+
+def _AddPrivateHelperMethods(message_descriptor, cls):
+  """Adds implementation of private helper methods to cls."""
+
+  def Modified(self):
+    """Sets the _cached_byte_size_dirty bit to true,
+    and propagates this to our listener iff this was a state change.
+    """
+
+    # Note:  Some callers check _cached_byte_size_dirty before calling
+    #   _Modified() as an extra optimization.  So, if this method is ever
+    #   changed such that it does stuff even when _cached_byte_size_dirty is
+    #   already true, the callers need to be updated.
+    if not self._cached_byte_size_dirty:
+      self._cached_byte_size_dirty = True
+      self._listener_for_children.dirty = True
+      self._is_present_in_parent = True
+      self._listener.Modified()
+
+  def _UpdateOneofState(self, field):
+    """Sets field as the active field in its containing oneof.
+
+    Will also delete currently active field in the oneof, if it is different
+    from the argument. Does not mark the message as modified.
+    """
+    other_field = self._oneofs.setdefault(field.containing_oneof, field)
+    if other_field is not field:
+      del self._fields[other_field]
+      self._oneofs[field.containing_oneof] = field
+
+  cls._Modified = Modified
+  cls.SetInParent = Modified
+  cls._UpdateOneofState = _UpdateOneofState
+
+
+class _Listener(object):
+
+  """MessageListener implementation that a parent message registers with its
+  child message.
+
+  In order to support semantics like:
+
+    foo.bar.baz.qux = 23
+    assert foo.HasField('bar')
+
+  ...child objects must have back references to their parents.
+  This helper class is at the heart of this support.
+  """
+
+  def __init__(self, parent_message):
+    """Args:
+      parent_message: The message whose _Modified() method we should call when
+        we receive Modified() messages.
+    """
+    # This listener establishes a back reference from a child (contained) object
+    # to its parent (containing) object.  We make this a weak reference to avoid
+    # creating cyclic garbage when the client finishes with the 'parent' object
+    # in the tree.
+    if isinstance(parent_message, weakref.ProxyType):
+      self._parent_message_weakref = parent_message
+    else:
+      self._parent_message_weakref = weakref.proxy(parent_message)
+
+    # As an optimization, we also indicate directly on the listener whether
+    # or not the parent message is dirty.  This way we can avoid traversing
+    # up the tree in the common case.
+    self.dirty = False
+
+  def Modified(self):
+    if self.dirty:
+      return
+    try:
+      # Propagate the signal to our parents iff this is the first field set.
+      self._parent_message_weakref._Modified()
+    except ReferenceError:
+      # We can get here if a client has kept a reference to a child object,
+      # and is now setting a field on it, but the child's parent has been
+      # garbage-collected.  This is not an error.
+      pass
+
+
+class _OneofListener(_Listener):
+  """Special listener implementation for setting composite oneof fields."""
+
+  def __init__(self, parent_message, field):
+    """Args:
+      parent_message: The message whose _Modified() method we should call when
+        we receive Modified() messages.
+      field: The descriptor of the field being set in the parent message.
+    """
+    super(_OneofListener, self).__init__(parent_message)
+    self._field = field
+
+  def Modified(self):
+    """Also updates the state of the containing oneof in the parent message."""
+    try:
+      self._parent_message_weakref._UpdateOneofState(self._field)
+      super(_OneofListener, self).Modified()
+    except ReferenceError:
+      pass
+
+
+# TODO(robinson): Move elsewhere?  This file is getting pretty ridiculous...
+# TODO(robinson): Unify error handling of "unknown extension" crap.
+# TODO(robinson): Support iteritems()-style iteration over all
+# extensions with the "has" bits turned on?
+class _ExtensionDict(object):
+
+  """Dict-like container for supporting an indexable "Extensions"
+  field on proto instances.
+
+  Note that in all cases we expect extension handles to be
+  FieldDescriptors.
+  """
+
+  def __init__(self, extended_message):
+    """extended_message: Message instance for which we are the Extensions dict.
+    """
+
+    self._extended_message = extended_message
+
+  def __getitem__(self, extension_handle):
+    """Returns the current value of the given extension handle."""
+
+    _VerifyExtensionHandle(self._extended_message, extension_handle)
+
+    result = self._extended_message._fields.get(extension_handle)
+    if result is not None:
+      return result
+
+    if extension_handle.label == _FieldDescriptor.LABEL_REPEATED:
+      result = extension_handle._default_constructor(self._extended_message)
+    elif extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE:
+      result = extension_handle.message_type._concrete_class()
+      try:
+        result._SetListener(self._extended_message._listener_for_children)
+      except ReferenceError:
+        pass
+    else:
+      # Singular scalar -- just return the default without inserting into the
+      # dict.
+      return extension_handle.default_value
+
+    # Atomically check if another thread has preempted us and, if not, swap
+    # in the new object we just created.  If someone has preempted us, we
+    # take that object and discard ours.
+    # WARNING:  We are relying on setdefault() being atomic.  This is true
+    #   in CPython but we haven't investigated others.  This warning appears
+    #   in several other locations in this file.
+    result = self._extended_message._fields.setdefault(
+        extension_handle, result)
+
+    return result
+
+  def __eq__(self, other):
+    if not isinstance(other, self.__class__):
+      return False
+
+    my_fields = self._extended_message.ListFields()
+    other_fields = other._extended_message.ListFields()
+
+    # Get rid of non-extension fields.
+    my_fields    = [ field for field in my_fields    if field.is_extension ]
+    other_fields = [ field for field in other_fields if field.is_extension ]
+
+    return my_fields == other_fields
+
+  def __ne__(self, other):
+    return not self == other
+
+  def __hash__(self):
+    raise TypeError('unhashable object')
+
+  # Note that this is only meaningful for non-repeated, scalar extension
+  # fields.  Note also that we may have to call _Modified() when we do
+  # successfully set a field this way, to set any necssary "has" bits in the
+  # ancestors of the extended message.
+  def __setitem__(self, extension_handle, value):
+    """If extension_handle specifies a non-repeated, scalar extension
+    field, sets the value of that field.
+    """
+
+    _VerifyExtensionHandle(self._extended_message, extension_handle)
+
+    if (extension_handle.label == _FieldDescriptor.LABEL_REPEATED or
+        extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE):
+      raise TypeError(
+          'Cannot assign to extension "%s" because it is a repeated or '
+          'composite type.' % extension_handle.full_name)
+
+    # It's slightly wasteful to lookup the type checker each time,
+    # but we expect this to be a vanishingly uncommon case anyway.
+    type_checker = type_checkers.GetTypeChecker(
+        extension_handle)
+    # pylint: disable=protected-access
+    self._extended_message._fields[extension_handle] = (
+      type_checker.CheckValue(value))
+    self._extended_message._Modified()
+
+  def _FindExtensionByName(self, name):
+    """Tries to find a known extension with the specified name.
+
+    Args:
+      name: Extension full name.
+
+    Returns:
+      Extension field descriptor.
+    """
+    return self._extended_message._extensions_by_name.get(name, None)
diff --git a/protobuf/python/google/protobuf/internal/reflection_test.py b/protobuf/python/google/protobuf/internal/reflection_test.py
new file mode 100755
index 0000000..d59815d
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/reflection_test.py
@@ -0,0 +1,2934 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unittest for reflection.py, which also indirectly tests the output of the
+pure-Python protocol compiler.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import copy
+import gc
+import operator
+import struct
+
+from google.apputils import basetest
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf import descriptor_pb2
+from google.protobuf import descriptor
+from google.protobuf import message
+from google.protobuf import reflection
+from google.protobuf import text_format
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import more_extensions_pb2
+from google.protobuf.internal import more_messages_pb2
+from google.protobuf.internal import wire_format
+from google.protobuf.internal import test_util
+from google.protobuf.internal import decoder
+
+
+class _MiniDecoder(object):
+  """Decodes a stream of values from a string.
+
+  Once upon a time we actually had a class called decoder.Decoder.  Then we
+  got rid of it during a redesign that made decoding much, much faster overall.
+  But a couple tests in this file used it to check that the serialized form of
+  a message was correct.  So, this class implements just the methods that were
+  used by said tests, so that we don't have to rewrite the tests.
+  """
+
+  def __init__(self, bytes):
+    self._bytes = bytes
+    self._pos = 0
+
+  def ReadVarint(self):
+    result, self._pos = decoder._DecodeVarint(self._bytes, self._pos)
+    return result
+
+  ReadInt32 = ReadVarint
+  ReadInt64 = ReadVarint
+  ReadUInt32 = ReadVarint
+  ReadUInt64 = ReadVarint
+
+  def ReadSInt64(self):
+    return wire_format.ZigZagDecode(self.ReadVarint())
+
+  ReadSInt32 = ReadSInt64
+
+  def ReadFieldNumberAndWireType(self):
+    return wire_format.UnpackTag(self.ReadVarint())
+
+  def ReadFloat(self):
+    result = struct.unpack("<f", self._bytes[self._pos:self._pos+4])[0]
+    self._pos += 4
+    return result
+
+  def ReadDouble(self):
+    result = struct.unpack("<d", self._bytes[self._pos:self._pos+8])[0]
+    self._pos += 8
+    return result
+
+  def EndOfStream(self):
+    return self._pos == len(self._bytes)
+
+
+class ReflectionTest(basetest.TestCase):
+
+  def assertListsEqual(self, values, others):
+    self.assertEqual(len(values), len(others))
+    for i in range(len(values)):
+      self.assertEqual(values[i], others[i])
+
+  def testScalarConstructor(self):
+    # Constructor with only scalar types should succeed.
+    proto = unittest_pb2.TestAllTypes(
+        optional_int32=24,
+        optional_double=54.321,
+        optional_string='optional_string')
+
+    self.assertEqual(24, proto.optional_int32)
+    self.assertEqual(54.321, proto.optional_double)
+    self.assertEqual('optional_string', proto.optional_string)
+
+  def testRepeatedScalarConstructor(self):
+    # Constructor with only repeated scalar types should succeed.
+    proto = unittest_pb2.TestAllTypes(
+        repeated_int32=[1, 2, 3, 4],
+        repeated_double=[1.23, 54.321],
+        repeated_bool=[True, False, False],
+        repeated_string=["optional_string"])
+
+    self.assertEquals([1, 2, 3, 4], list(proto.repeated_int32))
+    self.assertEquals([1.23, 54.321], list(proto.repeated_double))
+    self.assertEquals([True, False, False], list(proto.repeated_bool))
+    self.assertEquals(["optional_string"], list(proto.repeated_string))
+
+  def testRepeatedCompositeConstructor(self):
+    # Constructor with only repeated composite types should succeed.
+    proto = unittest_pb2.TestAllTypes(
+        repeated_nested_message=[
+            unittest_pb2.TestAllTypes.NestedMessage(
+                bb=unittest_pb2.TestAllTypes.FOO),
+            unittest_pb2.TestAllTypes.NestedMessage(
+                bb=unittest_pb2.TestAllTypes.BAR)],
+        repeated_foreign_message=[
+            unittest_pb2.ForeignMessage(c=-43),
+            unittest_pb2.ForeignMessage(c=45324),
+            unittest_pb2.ForeignMessage(c=12)],
+        repeatedgroup=[
+            unittest_pb2.TestAllTypes.RepeatedGroup(),
+            unittest_pb2.TestAllTypes.RepeatedGroup(a=1),
+            unittest_pb2.TestAllTypes.RepeatedGroup(a=2)])
+
+    self.assertEquals(
+        [unittest_pb2.TestAllTypes.NestedMessage(
+            bb=unittest_pb2.TestAllTypes.FOO),
+         unittest_pb2.TestAllTypes.NestedMessage(
+             bb=unittest_pb2.TestAllTypes.BAR)],
+        list(proto.repeated_nested_message))
+    self.assertEquals(
+        [unittest_pb2.ForeignMessage(c=-43),
+         unittest_pb2.ForeignMessage(c=45324),
+         unittest_pb2.ForeignMessage(c=12)],
+        list(proto.repeated_foreign_message))
+    self.assertEquals(
+        [unittest_pb2.TestAllTypes.RepeatedGroup(),
+         unittest_pb2.TestAllTypes.RepeatedGroup(a=1),
+         unittest_pb2.TestAllTypes.RepeatedGroup(a=2)],
+        list(proto.repeatedgroup))
+
+  def testMixedConstructor(self):
+    # Constructor with only mixed types should succeed.
+    proto = unittest_pb2.TestAllTypes(
+        optional_int32=24,
+        optional_string='optional_string',
+        repeated_double=[1.23, 54.321],
+        repeated_bool=[True, False, False],
+        repeated_nested_message=[
+            unittest_pb2.TestAllTypes.NestedMessage(
+                bb=unittest_pb2.TestAllTypes.FOO),
+            unittest_pb2.TestAllTypes.NestedMessage(
+                bb=unittest_pb2.TestAllTypes.BAR)],
+        repeated_foreign_message=[
+            unittest_pb2.ForeignMessage(c=-43),
+            unittest_pb2.ForeignMessage(c=45324),
+            unittest_pb2.ForeignMessage(c=12)])
+
+    self.assertEqual(24, proto.optional_int32)
+    self.assertEqual('optional_string', proto.optional_string)
+    self.assertEquals([1.23, 54.321], list(proto.repeated_double))
+    self.assertEquals([True, False, False], list(proto.repeated_bool))
+    self.assertEquals(
+        [unittest_pb2.TestAllTypes.NestedMessage(
+            bb=unittest_pb2.TestAllTypes.FOO),
+         unittest_pb2.TestAllTypes.NestedMessage(
+             bb=unittest_pb2.TestAllTypes.BAR)],
+        list(proto.repeated_nested_message))
+    self.assertEquals(
+        [unittest_pb2.ForeignMessage(c=-43),
+         unittest_pb2.ForeignMessage(c=45324),
+         unittest_pb2.ForeignMessage(c=12)],
+        list(proto.repeated_foreign_message))
+
+  def testConstructorTypeError(self):
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, optional_int32="foo")
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, optional_string=1234)
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, optional_nested_message=1234)
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_int32=1234)
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_int32=["foo"])
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_string=1234)
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_string=[1234])
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=1234)
+    self.assertRaises(
+        TypeError, unittest_pb2.TestAllTypes, repeated_nested_message=[1234])
+
+  def testConstructorInvalidatesCachedByteSize(self):
+    message = unittest_pb2.TestAllTypes(optional_int32 = 12)
+    self.assertEquals(2, message.ByteSize())
+
+    message = unittest_pb2.TestAllTypes(
+        optional_nested_message = unittest_pb2.TestAllTypes.NestedMessage())
+    self.assertEquals(3, message.ByteSize())
+
+    message = unittest_pb2.TestAllTypes(repeated_int32 = [12])
+    self.assertEquals(3, message.ByteSize())
+
+    message = unittest_pb2.TestAllTypes(
+        repeated_nested_message = [unittest_pb2.TestAllTypes.NestedMessage()])
+    self.assertEquals(3, message.ByteSize())
+
+  def testSimpleHasBits(self):
+    # Test a scalar.
+    proto = unittest_pb2.TestAllTypes()
+    self.assertTrue(not proto.HasField('optional_int32'))
+    self.assertEqual(0, proto.optional_int32)
+    # HasField() shouldn't be true if all we've done is
+    # read the default value.
+    self.assertTrue(not proto.HasField('optional_int32'))
+    proto.optional_int32 = 1
+    # Setting a value however *should* set the "has" bit.
+    self.assertTrue(proto.HasField('optional_int32'))
+    proto.ClearField('optional_int32')
+    # And clearing that value should unset the "has" bit.
+    self.assertTrue(not proto.HasField('optional_int32'))
+
+  def testHasBitsWithSinglyNestedScalar(self):
+    # Helper used to test foreign messages and groups.
+    #
+    # composite_field_name should be the name of a non-repeated
+    # composite (i.e., foreign or group) field in TestAllTypes,
+    # and scalar_field_name should be the name of an integer-valued
+    # scalar field within that composite.
+    #
+    # I never thought I'd miss C++ macros and templates so much. :(
+    # This helper is semantically just:
+    #
+    #   assert proto.composite_field.scalar_field == 0
+    #   assert not proto.composite_field.HasField('scalar_field')
+    #   assert not proto.HasField('composite_field')
+    #
+    #   proto.composite_field.scalar_field = 10
+    #   old_composite_field = proto.composite_field
+    #
+    #   assert proto.composite_field.scalar_field == 10
+    #   assert proto.composite_field.HasField('scalar_field')
+    #   assert proto.HasField('composite_field')
+    #
+    #   proto.ClearField('composite_field')
+    #
+    #   assert not proto.composite_field.HasField('scalar_field')
+    #   assert not proto.HasField('composite_field')
+    #   assert proto.composite_field.scalar_field == 0
+    #
+    #   # Now ensure that ClearField('composite_field') disconnected
+    #   # the old field object from the object tree...
+    #   assert old_composite_field is not proto.composite_field
+    #   old_composite_field.scalar_field = 20
+    #   assert not proto.composite_field.HasField('scalar_field')
+    #   assert not proto.HasField('composite_field')
+    def TestCompositeHasBits(composite_field_name, scalar_field_name):
+      proto = unittest_pb2.TestAllTypes()
+      # First, check that we can get the scalar value, and see that it's the
+      # default (0), but that proto.HasField('omposite') and
+      # proto.composite.HasField('scalar') will still return False.
+      composite_field = getattr(proto, composite_field_name)
+      original_scalar_value = getattr(composite_field, scalar_field_name)
+      self.assertEqual(0, original_scalar_value)
+      # Assert that the composite object does not "have" the scalar.
+      self.assertTrue(not composite_field.HasField(scalar_field_name))
+      # Assert that proto does not "have" the composite field.
+      self.assertTrue(not proto.HasField(composite_field_name))
+
+      # Now set the scalar within the composite field.  Ensure that the setting
+      # is reflected, and that proto.HasField('composite') and
+      # proto.composite.HasField('scalar') now both return True.
+      new_val = 20
+      setattr(composite_field, scalar_field_name, new_val)
+      self.assertEqual(new_val, getattr(composite_field, scalar_field_name))
+      # Hold on to a reference to the current composite_field object.
+      old_composite_field = composite_field
+      # Assert that the has methods now return true.
+      self.assertTrue(composite_field.HasField(scalar_field_name))
+      self.assertTrue(proto.HasField(composite_field_name))
+
+      # Now call the clear method...
+      proto.ClearField(composite_field_name)
+
+      # ...and ensure that the "has" bits are all back to False...
+      composite_field = getattr(proto, composite_field_name)
+      self.assertTrue(not composite_field.HasField(scalar_field_name))
+      self.assertTrue(not proto.HasField(composite_field_name))
+      # ...and ensure that the scalar field has returned to its default.
+      self.assertEqual(0, getattr(composite_field, scalar_field_name))
+
+      self.assertTrue(old_composite_field is not composite_field)
+      setattr(old_composite_field, scalar_field_name, new_val)
+      self.assertTrue(not composite_field.HasField(scalar_field_name))
+      self.assertTrue(not proto.HasField(composite_field_name))
+      self.assertEqual(0, getattr(composite_field, scalar_field_name))
+
+    # Test simple, single-level nesting when we set a scalar.
+    TestCompositeHasBits('optionalgroup', 'a')
+    TestCompositeHasBits('optional_nested_message', 'bb')
+    TestCompositeHasBits('optional_foreign_message', 'c')
+    TestCompositeHasBits('optional_import_message', 'd')
+
+  def testReferencesToNestedMessage(self):
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    del proto
+    # A previous version had a bug where this would raise an exception when
+    # hitting a now-dead weak reference.
+    nested.bb = 23
+
+  def testDisconnectingNestedMessageBeforeSettingField(self):
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    proto.ClearField('optional_nested_message')  # Should disconnect from parent
+    self.assertTrue(nested is not proto.optional_nested_message)
+    nested.bb = 23
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+    self.assertEqual(0, proto.optional_nested_message.bb)
+
+  def testGetDefaultMessageAfterDisconnectingDefaultMessage(self):
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    proto.ClearField('optional_nested_message')
+    del proto
+    del nested
+    # Force a garbage collect so that the underlying CMessages are freed along
+    # with the Messages they point to. This is to make sure we're not deleting
+    # default message instances.
+    gc.collect()
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+
+  def testDisconnectingNestedMessageAfterSettingField(self):
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    nested.bb = 5
+    self.assertTrue(proto.HasField('optional_nested_message'))
+    proto.ClearField('optional_nested_message')  # Should disconnect from parent
+    self.assertEqual(5, nested.bb)
+    self.assertEqual(0, proto.optional_nested_message.bb)
+    self.assertTrue(nested is not proto.optional_nested_message)
+    nested.bb = 23
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+    self.assertEqual(0, proto.optional_nested_message.bb)
+
+  def testDisconnectingNestedMessageBeforeGettingField(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+    proto.ClearField('optional_nested_message')
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+
+  def testDisconnectingNestedMessageAfterMerge(self):
+    # This test exercises the code path that does not use ReleaseMessage().
+    # The underlying fear is that if we use ReleaseMessage() incorrectly,
+    # we will have memory leaks.  It's hard to check that that doesn't happen,
+    # but at least we can exercise that code path to make sure it works.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.optional_nested_message.bb = 5
+    proto1.MergeFrom(proto2)
+    self.assertTrue(proto1.HasField('optional_nested_message'))
+    proto1.ClearField('optional_nested_message')
+    self.assertTrue(not proto1.HasField('optional_nested_message'))
+
+  def testDisconnectingLazyNestedMessage(self):
+    # This test exercises releasing a nested message that is lazy. This test
+    # only exercises real code in the C++ implementation as Python does not
+    # support lazy parsing, but the current C++ implementation results in
+    # memory corruption and a crash.
+    if api_implementation.Type() != 'python':
+      return
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_lazy_message.bb = 5
+    proto.ClearField('optional_lazy_message')
+    del proto
+    gc.collect()
+
+  def testHasBitsWhenModifyingRepeatedFields(self):
+    # Test nesting when we add an element to a repeated field in a submessage.
+    proto = unittest_pb2.TestNestedMessageHasBits()
+    proto.optional_nested_message.nestedmessage_repeated_int32.append(5)
+    self.assertEqual(
+        [5], proto.optional_nested_message.nestedmessage_repeated_int32)
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+    # Do the same test, but with a repeated composite field within the
+    # submessage.
+    proto.ClearField('optional_nested_message')
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+    proto.optional_nested_message.nestedmessage_repeated_foreignmessage.add()
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+  def testHasBitsForManyLevelsOfNesting(self):
+    # Test nesting many levels deep.
+    recursive_proto = unittest_pb2.TestMutualRecursionA()
+    self.assertTrue(not recursive_proto.HasField('bb'))
+    self.assertEqual(0, recursive_proto.bb.a.bb.a.bb.optional_int32)
+    self.assertTrue(not recursive_proto.HasField('bb'))
+    recursive_proto.bb.a.bb.a.bb.optional_int32 = 5
+    self.assertEqual(5, recursive_proto.bb.a.bb.a.bb.optional_int32)
+    self.assertTrue(recursive_proto.HasField('bb'))
+    self.assertTrue(recursive_proto.bb.HasField('a'))
+    self.assertTrue(recursive_proto.bb.a.HasField('bb'))
+    self.assertTrue(recursive_proto.bb.a.bb.HasField('a'))
+    self.assertTrue(recursive_proto.bb.a.bb.a.HasField('bb'))
+    self.assertTrue(not recursive_proto.bb.a.bb.a.bb.HasField('a'))
+    self.assertTrue(recursive_proto.bb.a.bb.a.bb.HasField('optional_int32'))
+
+  def testSingularListFields(self):
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_fixed32 = 1
+    proto.optional_int32 = 5
+    proto.optional_string = 'foo'
+    # Access sub-message but don't set it yet.
+    nested_message = proto.optional_nested_message
+    self.assertEqual(
+      [ (proto.DESCRIPTOR.fields_by_name['optional_int32'  ], 5),
+        (proto.DESCRIPTOR.fields_by_name['optional_fixed32'], 1),
+        (proto.DESCRIPTOR.fields_by_name['optional_string' ], 'foo') ],
+      proto.ListFields())
+
+    proto.optional_nested_message.bb = 123
+    self.assertEqual(
+      [ (proto.DESCRIPTOR.fields_by_name['optional_int32'  ], 5),
+        (proto.DESCRIPTOR.fields_by_name['optional_fixed32'], 1),
+        (proto.DESCRIPTOR.fields_by_name['optional_string' ], 'foo'),
+        (proto.DESCRIPTOR.fields_by_name['optional_nested_message' ],
+             nested_message) ],
+      proto.ListFields())
+
+  def testRepeatedListFields(self):
+    proto = unittest_pb2.TestAllTypes()
+    proto.repeated_fixed32.append(1)
+    proto.repeated_int32.append(5)
+    proto.repeated_int32.append(11)
+    proto.repeated_string.extend(['foo', 'bar'])
+    proto.repeated_string.extend([])
+    proto.repeated_string.append('baz')
+    proto.repeated_string.extend(str(x) for x in xrange(2))
+    proto.optional_int32 = 21
+    proto.repeated_bool  # Access but don't set anything; should not be listed.
+    self.assertEqual(
+      [ (proto.DESCRIPTOR.fields_by_name['optional_int32'  ], 21),
+        (proto.DESCRIPTOR.fields_by_name['repeated_int32'  ], [5, 11]),
+        (proto.DESCRIPTOR.fields_by_name['repeated_fixed32'], [1]),
+        (proto.DESCRIPTOR.fields_by_name['repeated_string' ],
+          ['foo', 'bar', 'baz', '0', '1']) ],
+      proto.ListFields())
+
+  def testSingularListExtensions(self):
+    proto = unittest_pb2.TestAllExtensions()
+    proto.Extensions[unittest_pb2.optional_fixed32_extension] = 1
+    proto.Extensions[unittest_pb2.optional_int32_extension  ] = 5
+    proto.Extensions[unittest_pb2.optional_string_extension ] = 'foo'
+    self.assertEqual(
+      [ (unittest_pb2.optional_int32_extension  , 5),
+        (unittest_pb2.optional_fixed32_extension, 1),
+        (unittest_pb2.optional_string_extension , 'foo') ],
+      proto.ListFields())
+
+  def testRepeatedListExtensions(self):
+    proto = unittest_pb2.TestAllExtensions()
+    proto.Extensions[unittest_pb2.repeated_fixed32_extension].append(1)
+    proto.Extensions[unittest_pb2.repeated_int32_extension  ].append(5)
+    proto.Extensions[unittest_pb2.repeated_int32_extension  ].append(11)
+    proto.Extensions[unittest_pb2.repeated_string_extension ].append('foo')
+    proto.Extensions[unittest_pb2.repeated_string_extension ].append('bar')
+    proto.Extensions[unittest_pb2.repeated_string_extension ].append('baz')
+    proto.Extensions[unittest_pb2.optional_int32_extension  ] = 21
+    self.assertEqual(
+      [ (unittest_pb2.optional_int32_extension  , 21),
+        (unittest_pb2.repeated_int32_extension  , [5, 11]),
+        (unittest_pb2.repeated_fixed32_extension, [1]),
+        (unittest_pb2.repeated_string_extension , ['foo', 'bar', 'baz']) ],
+      proto.ListFields())
+
+  def testListFieldsAndExtensions(self):
+    proto = unittest_pb2.TestFieldOrderings()
+    test_util.SetAllFieldsAndExtensions(proto)
+    unittest_pb2.my_extension_int
+    self.assertEqual(
+      [ (proto.DESCRIPTOR.fields_by_name['my_int'   ], 1),
+        (unittest_pb2.my_extension_int               , 23),
+        (proto.DESCRIPTOR.fields_by_name['my_string'], 'foo'),
+        (unittest_pb2.my_extension_string            , 'bar'),
+        (proto.DESCRIPTOR.fields_by_name['my_float' ], 1.0) ],
+      proto.ListFields())
+
+  def testDefaultValues(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(0, proto.optional_int32)
+    self.assertEqual(0, proto.optional_int64)
+    self.assertEqual(0, proto.optional_uint32)
+    self.assertEqual(0, proto.optional_uint64)
+    self.assertEqual(0, proto.optional_sint32)
+    self.assertEqual(0, proto.optional_sint64)
+    self.assertEqual(0, proto.optional_fixed32)
+    self.assertEqual(0, proto.optional_fixed64)
+    self.assertEqual(0, proto.optional_sfixed32)
+    self.assertEqual(0, proto.optional_sfixed64)
+    self.assertEqual(0.0, proto.optional_float)
+    self.assertEqual(0.0, proto.optional_double)
+    self.assertEqual(False, proto.optional_bool)
+    self.assertEqual('', proto.optional_string)
+    self.assertEqual(b'', proto.optional_bytes)
+
+    self.assertEqual(41, proto.default_int32)
+    self.assertEqual(42, proto.default_int64)
+    self.assertEqual(43, proto.default_uint32)
+    self.assertEqual(44, proto.default_uint64)
+    self.assertEqual(-45, proto.default_sint32)
+    self.assertEqual(46, proto.default_sint64)
+    self.assertEqual(47, proto.default_fixed32)
+    self.assertEqual(48, proto.default_fixed64)
+    self.assertEqual(49, proto.default_sfixed32)
+    self.assertEqual(-50, proto.default_sfixed64)
+    self.assertEqual(51.5, proto.default_float)
+    self.assertEqual(52e3, proto.default_double)
+    self.assertEqual(True, proto.default_bool)
+    self.assertEqual('hello', proto.default_string)
+    self.assertEqual(b'world', proto.default_bytes)
+    self.assertEqual(unittest_pb2.TestAllTypes.BAR, proto.default_nested_enum)
+    self.assertEqual(unittest_pb2.FOREIGN_BAR, proto.default_foreign_enum)
+    self.assertEqual(unittest_import_pb2.IMPORT_BAR,
+                     proto.default_import_enum)
+
+    proto = unittest_pb2.TestExtremeDefaultValues()
+    self.assertEqual(u'\u1234', proto.utf8_string)
+
+  def testHasFieldWithUnknownFieldName(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertRaises(ValueError, proto.HasField, 'nonexistent_field')
+
+  def testClearFieldWithUnknownFieldName(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertRaises(ValueError, proto.ClearField, 'nonexistent_field')
+
+  def testClearRemovesChildren(self):
+    # Make sure there aren't any implementation bugs that are only partially
+    # clearing the message (which can happen in the more complex C++
+    # implementation which has parallel message lists).
+    proto = unittest_pb2.TestRequiredForeign()
+    for i in range(10):
+      proto.repeated_message.add()
+    proto2 = unittest_pb2.TestRequiredForeign()
+    proto.CopyFrom(proto2)
+    self.assertRaises(IndexError, lambda: proto.repeated_message[5])
+
+  def testDisallowedAssignments(self):
+    # It's illegal to assign values directly to repeated fields
+    # or to nonrepeated composite fields.  Ensure that this fails.
+    proto = unittest_pb2.TestAllTypes()
+    # Repeated fields.
+    self.assertRaises(AttributeError, setattr, proto, 'repeated_int32', 10)
+    # Lists shouldn't work, either.
+    self.assertRaises(AttributeError, setattr, proto, 'repeated_int32', [10])
+    # Composite fields.
+    self.assertRaises(AttributeError, setattr, proto,
+                      'optional_nested_message', 23)
+    # Assignment to a repeated nested message field without specifying
+    # the index in the array of nested messages.
+    self.assertRaises(AttributeError, setattr, proto.repeated_nested_message,
+                      'bb', 34)
+    # Assignment to an attribute of a repeated field.
+    self.assertRaises(AttributeError, setattr, proto.repeated_float,
+                      'some_attribute', 34)
+    # proto.nonexistent_field = 23 should fail as well.
+    self.assertRaises(AttributeError, setattr, proto, 'nonexistent_field', 23)
+
+  def testSingleScalarTypeSafety(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertRaises(TypeError, setattr, proto, 'optional_int32', 1.1)
+    self.assertRaises(TypeError, setattr, proto, 'optional_int32', 'foo')
+    self.assertRaises(TypeError, setattr, proto, 'optional_string', 10)
+    self.assertRaises(TypeError, setattr, proto, 'optional_bytes', 10)
+
+  def testIntegerTypes(self):
+    def TestGetAndDeserialize(field_name, value, expected_type):
+      proto = unittest_pb2.TestAllTypes()
+      setattr(proto, field_name, value)
+      self.assertTrue(isinstance(getattr(proto, field_name), expected_type))
+      proto2 = unittest_pb2.TestAllTypes()
+      proto2.ParseFromString(proto.SerializeToString())
+      self.assertTrue(isinstance(getattr(proto2, field_name), expected_type))
+
+    TestGetAndDeserialize('optional_int32', 1, int)
+    TestGetAndDeserialize('optional_int32', 1 << 30, int)
+    TestGetAndDeserialize('optional_uint32', 1 << 30, int)
+    if struct.calcsize('L') == 4:
+      # Python only has signed ints, so 32-bit python can't fit an uint32
+      # in an int.
+      TestGetAndDeserialize('optional_uint32', 1 << 31, long)
+    else:
+      # 64-bit python can fit uint32 inside an int
+      TestGetAndDeserialize('optional_uint32', 1 << 31, int)
+    TestGetAndDeserialize('optional_int64', 1 << 30, long)
+    TestGetAndDeserialize('optional_int64', 1 << 60, long)
+    TestGetAndDeserialize('optional_uint64', 1 << 30, long)
+    TestGetAndDeserialize('optional_uint64', 1 << 60, long)
+
+  def testSingleScalarBoundsChecking(self):
+    def TestMinAndMaxIntegers(field_name, expected_min, expected_max):
+      pb = unittest_pb2.TestAllTypes()
+      setattr(pb, field_name, expected_min)
+      self.assertEqual(expected_min, getattr(pb, field_name))
+      setattr(pb, field_name, expected_max)
+      self.assertEqual(expected_max, getattr(pb, field_name))
+      self.assertRaises(ValueError, setattr, pb, field_name, expected_min - 1)
+      self.assertRaises(ValueError, setattr, pb, field_name, expected_max + 1)
+
+    TestMinAndMaxIntegers('optional_int32', -(1 << 31), (1 << 31) - 1)
+    TestMinAndMaxIntegers('optional_uint32', 0, 0xffffffff)
+    TestMinAndMaxIntegers('optional_int64', -(1 << 63), (1 << 63) - 1)
+    TestMinAndMaxIntegers('optional_uint64', 0, 0xffffffffffffffff)
+
+    pb = unittest_pb2.TestAllTypes()
+    pb.optional_nested_enum = 1
+    self.assertEqual(1, pb.optional_nested_enum)
+
+  def testRepeatedScalarTypeSafety(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertRaises(TypeError, proto.repeated_int32.append, 1.1)
+    self.assertRaises(TypeError, proto.repeated_int32.append, 'foo')
+    self.assertRaises(TypeError, proto.repeated_string, 10)
+    self.assertRaises(TypeError, proto.repeated_bytes, 10)
+
+    proto.repeated_int32.append(10)
+    proto.repeated_int32[0] = 23
+    self.assertRaises(IndexError, proto.repeated_int32.__setitem__, 500, 23)
+    self.assertRaises(TypeError, proto.repeated_int32.__setitem__, 0, 'abc')
+
+    # Repeated enums tests.
+    #proto.repeated_nested_enum.append(0)
+
+  def testSingleScalarGettersAndSetters(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(0, proto.optional_int32)
+    proto.optional_int32 = 1
+    self.assertEqual(1, proto.optional_int32)
+
+    proto.optional_uint64 = 0xffffffffffff
+    self.assertEqual(0xffffffffffff, proto.optional_uint64)
+    proto.optional_uint64 = 0xffffffffffffffff
+    self.assertEqual(0xffffffffffffffff, proto.optional_uint64)
+    # TODO(robinson): Test all other scalar field types.
+
+  def testSingleScalarClearField(self):
+    proto = unittest_pb2.TestAllTypes()
+    # Should be allowed to clear something that's not there (a no-op).
+    proto.ClearField('optional_int32')
+    proto.optional_int32 = 1
+    self.assertTrue(proto.HasField('optional_int32'))
+    proto.ClearField('optional_int32')
+    self.assertEqual(0, proto.optional_int32)
+    self.assertTrue(not proto.HasField('optional_int32'))
+    # TODO(robinson): Test all other scalar field types.
+
+  def testEnums(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(1, proto.FOO)
+    self.assertEqual(1, unittest_pb2.TestAllTypes.FOO)
+    self.assertEqual(2, proto.BAR)
+    self.assertEqual(2, unittest_pb2.TestAllTypes.BAR)
+    self.assertEqual(3, proto.BAZ)
+    self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ)
+
+  def testEnum_Name(self):
+    self.assertEqual('FOREIGN_FOO',
+                     unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_FOO))
+    self.assertEqual('FOREIGN_BAR',
+                     unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_BAR))
+    self.assertEqual('FOREIGN_BAZ',
+                     unittest_pb2.ForeignEnum.Name(unittest_pb2.FOREIGN_BAZ))
+    self.assertRaises(ValueError,
+                      unittest_pb2.ForeignEnum.Name, 11312)
+
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual('FOO',
+                     proto.NestedEnum.Name(proto.FOO))
+    self.assertEqual('FOO',
+                     unittest_pb2.TestAllTypes.NestedEnum.Name(proto.FOO))
+    self.assertEqual('BAR',
+                     proto.NestedEnum.Name(proto.BAR))
+    self.assertEqual('BAR',
+                     unittest_pb2.TestAllTypes.NestedEnum.Name(proto.BAR))
+    self.assertEqual('BAZ',
+                     proto.NestedEnum.Name(proto.BAZ))
+    self.assertEqual('BAZ',
+                     unittest_pb2.TestAllTypes.NestedEnum.Name(proto.BAZ))
+    self.assertRaises(ValueError,
+                      proto.NestedEnum.Name, 11312)
+    self.assertRaises(ValueError,
+                      unittest_pb2.TestAllTypes.NestedEnum.Name, 11312)
+
+  def testEnum_Value(self):
+    self.assertEqual(unittest_pb2.FOREIGN_FOO,
+                     unittest_pb2.ForeignEnum.Value('FOREIGN_FOO'))
+    self.assertEqual(unittest_pb2.FOREIGN_BAR,
+                     unittest_pb2.ForeignEnum.Value('FOREIGN_BAR'))
+    self.assertEqual(unittest_pb2.FOREIGN_BAZ,
+                     unittest_pb2.ForeignEnum.Value('FOREIGN_BAZ'))
+    self.assertRaises(ValueError,
+                      unittest_pb2.ForeignEnum.Value, 'FO')
+
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(proto.FOO,
+                     proto.NestedEnum.Value('FOO'))
+    self.assertEqual(proto.FOO,
+                     unittest_pb2.TestAllTypes.NestedEnum.Value('FOO'))
+    self.assertEqual(proto.BAR,
+                     proto.NestedEnum.Value('BAR'))
+    self.assertEqual(proto.BAR,
+                     unittest_pb2.TestAllTypes.NestedEnum.Value('BAR'))
+    self.assertEqual(proto.BAZ,
+                     proto.NestedEnum.Value('BAZ'))
+    self.assertEqual(proto.BAZ,
+                     unittest_pb2.TestAllTypes.NestedEnum.Value('BAZ'))
+    self.assertRaises(ValueError,
+                      proto.NestedEnum.Value, 'Foo')
+    self.assertRaises(ValueError,
+                      unittest_pb2.TestAllTypes.NestedEnum.Value, 'Foo')
+
+  def testEnum_KeysAndValues(self):
+    self.assertEqual(['FOREIGN_FOO', 'FOREIGN_BAR', 'FOREIGN_BAZ'],
+                     unittest_pb2.ForeignEnum.keys())
+    self.assertEqual([4, 5, 6],
+                     unittest_pb2.ForeignEnum.values())
+    self.assertEqual([('FOREIGN_FOO', 4), ('FOREIGN_BAR', 5),
+                      ('FOREIGN_BAZ', 6)],
+                     unittest_pb2.ForeignEnum.items())
+
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(['FOO', 'BAR', 'BAZ', 'NEG'], proto.NestedEnum.keys())
+    self.assertEqual([1, 2, 3, -1], proto.NestedEnum.values())
+    self.assertEqual([('FOO', 1), ('BAR', 2), ('BAZ', 3), ('NEG', -1)],
+                     proto.NestedEnum.items())
+
+  def testRepeatedScalars(self):
+    proto = unittest_pb2.TestAllTypes()
+
+    self.assertTrue(not proto.repeated_int32)
+    self.assertEqual(0, len(proto.repeated_int32))
+    proto.repeated_int32.append(5)
+    proto.repeated_int32.append(10)
+    proto.repeated_int32.append(15)
+    self.assertTrue(proto.repeated_int32)
+    self.assertEqual(3, len(proto.repeated_int32))
+
+    self.assertEqual([5, 10, 15], proto.repeated_int32)
+
+    # Test single retrieval.
+    self.assertEqual(5, proto.repeated_int32[0])
+    self.assertEqual(15, proto.repeated_int32[-1])
+    # Test out-of-bounds indices.
+    self.assertRaises(IndexError, proto.repeated_int32.__getitem__, 1234)
+    self.assertRaises(IndexError, proto.repeated_int32.__getitem__, -1234)
+    # Test incorrect types passed to __getitem__.
+    self.assertRaises(TypeError, proto.repeated_int32.__getitem__, 'foo')
+    self.assertRaises(TypeError, proto.repeated_int32.__getitem__, None)
+
+    # Test single assignment.
+    proto.repeated_int32[1] = 20
+    self.assertEqual([5, 20, 15], proto.repeated_int32)
+
+    # Test insertion.
+    proto.repeated_int32.insert(1, 25)
+    self.assertEqual([5, 25, 20, 15], proto.repeated_int32)
+
+    # Test slice retrieval.
+    proto.repeated_int32.append(30)
+    self.assertEqual([25, 20, 15], proto.repeated_int32[1:4])
+    self.assertEqual([5, 25, 20, 15, 30], proto.repeated_int32[:])
+
+    # Test slice assignment with an iterator
+    proto.repeated_int32[1:4] = (i for i in xrange(3))
+    self.assertEqual([5, 0, 1, 2, 30], proto.repeated_int32)
+
+    # Test slice assignment.
+    proto.repeated_int32[1:4] = [35, 40, 45]
+    self.assertEqual([5, 35, 40, 45, 30], proto.repeated_int32)
+
+    # Test that we can use the field as an iterator.
+    result = []
+    for i in proto.repeated_int32:
+      result.append(i)
+    self.assertEqual([5, 35, 40, 45, 30], result)
+
+    # Test single deletion.
+    del proto.repeated_int32[2]
+    self.assertEqual([5, 35, 45, 30], proto.repeated_int32)
+
+    # Test slice deletion.
+    del proto.repeated_int32[2:]
+    self.assertEqual([5, 35], proto.repeated_int32)
+
+    # Test extending.
+    proto.repeated_int32.extend([3, 13])
+    self.assertEqual([5, 35, 3, 13], proto.repeated_int32)
+
+    # Test clearing.
+    proto.ClearField('repeated_int32')
+    self.assertTrue(not proto.repeated_int32)
+    self.assertEqual(0, len(proto.repeated_int32))
+
+    proto.repeated_int32.append(1)
+    self.assertEqual(1, proto.repeated_int32[-1])
+    # Test assignment to a negative index.
+    proto.repeated_int32[-1] = 2
+    self.assertEqual(2, proto.repeated_int32[-1])
+
+    # Test deletion at negative indices.
+    proto.repeated_int32[:] = [0, 1, 2, 3]
+    del proto.repeated_int32[-1]
+    self.assertEqual([0, 1, 2], proto.repeated_int32)
+
+    del proto.repeated_int32[-2]
+    self.assertEqual([0, 2], proto.repeated_int32)
+
+    self.assertRaises(IndexError, proto.repeated_int32.__delitem__, -3)
+    self.assertRaises(IndexError, proto.repeated_int32.__delitem__, 300)
+
+    del proto.repeated_int32[-2:-1]
+    self.assertEqual([2], proto.repeated_int32)
+
+    del proto.repeated_int32[100:10000]
+    self.assertEqual([2], proto.repeated_int32)
+
+  def testRepeatedScalarsRemove(self):
+    proto = unittest_pb2.TestAllTypes()
+
+    self.assertTrue(not proto.repeated_int32)
+    self.assertEqual(0, len(proto.repeated_int32))
+    proto.repeated_int32.append(5)
+    proto.repeated_int32.append(10)
+    proto.repeated_int32.append(5)
+    proto.repeated_int32.append(5)
+
+    self.assertEqual(4, len(proto.repeated_int32))
+    proto.repeated_int32.remove(5)
+    self.assertEqual(3, len(proto.repeated_int32))
+    self.assertEqual(10, proto.repeated_int32[0])
+    self.assertEqual(5, proto.repeated_int32[1])
+    self.assertEqual(5, proto.repeated_int32[2])
+
+    proto.repeated_int32.remove(5)
+    self.assertEqual(2, len(proto.repeated_int32))
+    self.assertEqual(10, proto.repeated_int32[0])
+    self.assertEqual(5, proto.repeated_int32[1])
+
+    proto.repeated_int32.remove(10)
+    self.assertEqual(1, len(proto.repeated_int32))
+    self.assertEqual(5, proto.repeated_int32[0])
+
+    # Remove a non-existent element.
+    self.assertRaises(ValueError, proto.repeated_int32.remove, 123)
+
+  def testRepeatedComposites(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertTrue(not proto.repeated_nested_message)
+    self.assertEqual(0, len(proto.repeated_nested_message))
+    m0 = proto.repeated_nested_message.add()
+    m1 = proto.repeated_nested_message.add()
+    self.assertTrue(proto.repeated_nested_message)
+    self.assertEqual(2, len(proto.repeated_nested_message))
+    self.assertListsEqual([m0, m1], proto.repeated_nested_message)
+    self.assertTrue(isinstance(m0, unittest_pb2.TestAllTypes.NestedMessage))
+
+    # Test out-of-bounds indices.
+    self.assertRaises(IndexError, proto.repeated_nested_message.__getitem__,
+                      1234)
+    self.assertRaises(IndexError, proto.repeated_nested_message.__getitem__,
+                      -1234)
+
+    # Test incorrect types passed to __getitem__.
+    self.assertRaises(TypeError, proto.repeated_nested_message.__getitem__,
+                      'foo')
+    self.assertRaises(TypeError, proto.repeated_nested_message.__getitem__,
+                      None)
+
+    # Test slice retrieval.
+    m2 = proto.repeated_nested_message.add()
+    m3 = proto.repeated_nested_message.add()
+    m4 = proto.repeated_nested_message.add()
+    self.assertListsEqual(
+        [m1, m2, m3], proto.repeated_nested_message[1:4])
+    self.assertListsEqual(
+        [m0, m1, m2, m3, m4], proto.repeated_nested_message[:])
+    self.assertListsEqual(
+        [m0, m1], proto.repeated_nested_message[:2])
+    self.assertListsEqual(
+        [m2, m3, m4], proto.repeated_nested_message[2:])
+    self.assertEqual(
+        m0, proto.repeated_nested_message[0])
+    self.assertListsEqual(
+        [m0], proto.repeated_nested_message[:1])
+
+    # Test that we can use the field as an iterator.
+    result = []
+    for i in proto.repeated_nested_message:
+      result.append(i)
+    self.assertListsEqual([m0, m1, m2, m3, m4], result)
+
+    # Test single deletion.
+    del proto.repeated_nested_message[2]
+    self.assertListsEqual([m0, m1, m3, m4], proto.repeated_nested_message)
+
+    # Test slice deletion.
+    del proto.repeated_nested_message[2:]
+    self.assertListsEqual([m0, m1], proto.repeated_nested_message)
+
+    # Test extending.
+    n1 = unittest_pb2.TestAllTypes.NestedMessage(bb=1)
+    n2 = unittest_pb2.TestAllTypes.NestedMessage(bb=2)
+    proto.repeated_nested_message.extend([n1,n2])
+    self.assertEqual(4, len(proto.repeated_nested_message))
+    self.assertEqual(n1, proto.repeated_nested_message[2])
+    self.assertEqual(n2, proto.repeated_nested_message[3])
+
+    # Test clearing.
+    proto.ClearField('repeated_nested_message')
+    self.assertTrue(not proto.repeated_nested_message)
+    self.assertEqual(0, len(proto.repeated_nested_message))
+
+    # Test constructing an element while adding it.
+    proto.repeated_nested_message.add(bb=23)
+    self.assertEqual(1, len(proto.repeated_nested_message))
+    self.assertEqual(23, proto.repeated_nested_message[0].bb)
+
+  def testRepeatedCompositeRemove(self):
+    proto = unittest_pb2.TestAllTypes()
+
+    self.assertEqual(0, len(proto.repeated_nested_message))
+    m0 = proto.repeated_nested_message.add()
+    # Need to set some differentiating variable so m0 != m1 != m2:
+    m0.bb = len(proto.repeated_nested_message)
+    m1 = proto.repeated_nested_message.add()
+    m1.bb = len(proto.repeated_nested_message)
+    self.assertTrue(m0 != m1)
+    m2 = proto.repeated_nested_message.add()
+    m2.bb = len(proto.repeated_nested_message)
+    self.assertListsEqual([m0, m1, m2], proto.repeated_nested_message)
+
+    self.assertEqual(3, len(proto.repeated_nested_message))
+    proto.repeated_nested_message.remove(m0)
+    self.assertEqual(2, len(proto.repeated_nested_message))
+    self.assertEqual(m1, proto.repeated_nested_message[0])
+    self.assertEqual(m2, proto.repeated_nested_message[1])
+
+    # Removing m0 again or removing None should raise error
+    self.assertRaises(ValueError, proto.repeated_nested_message.remove, m0)
+    self.assertRaises(ValueError, proto.repeated_nested_message.remove, None)
+    self.assertEqual(2, len(proto.repeated_nested_message))
+
+    proto.repeated_nested_message.remove(m2)
+    self.assertEqual(1, len(proto.repeated_nested_message))
+    self.assertEqual(m1, proto.repeated_nested_message[0])
+
+  def testHandWrittenReflection(self):
+    # Hand written extensions are only supported by the pure-Python
+    # implementation of the API.
+    if api_implementation.Type() != 'python':
+      return
+
+    FieldDescriptor = descriptor.FieldDescriptor
+    foo_field_descriptor = FieldDescriptor(
+        name='foo_field', full_name='MyProto.foo_field',
+        index=0, number=1, type=FieldDescriptor.TYPE_INT64,
+        cpp_type=FieldDescriptor.CPPTYPE_INT64,
+        label=FieldDescriptor.LABEL_OPTIONAL, default_value=0,
+        containing_type=None, message_type=None, enum_type=None,
+        is_extension=False, extension_scope=None,
+        options=descriptor_pb2.FieldOptions())
+    mydescriptor = descriptor.Descriptor(
+        name='MyProto', full_name='MyProto', filename='ignored',
+        containing_type=None, nested_types=[], enum_types=[],
+        fields=[foo_field_descriptor], extensions=[],
+        options=descriptor_pb2.MessageOptions())
+    class MyProtoClass(message.Message):
+      DESCRIPTOR = mydescriptor
+      __metaclass__ = reflection.GeneratedProtocolMessageType
+    myproto_instance = MyProtoClass()
+    self.assertEqual(0, myproto_instance.foo_field)
+    self.assertTrue(not myproto_instance.HasField('foo_field'))
+    myproto_instance.foo_field = 23
+    self.assertEqual(23, myproto_instance.foo_field)
+    self.assertTrue(myproto_instance.HasField('foo_field'))
+
+  def testDescriptorProtoSupport(self):
+    # Hand written descriptors/reflection are only supported by the pure-Python
+    # implementation of the API.
+    if api_implementation.Type() != 'python':
+      return
+
+    def AddDescriptorField(proto, field_name, field_type):
+      AddDescriptorField.field_index += 1
+      new_field = proto.field.add()
+      new_field.name = field_name
+      new_field.type = field_type
+      new_field.number = AddDescriptorField.field_index
+      new_field.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL
+
+    AddDescriptorField.field_index = 0
+
+    desc_proto = descriptor_pb2.DescriptorProto()
+    desc_proto.name = 'Car'
+    fdp = descriptor_pb2.FieldDescriptorProto
+    AddDescriptorField(desc_proto, 'name', fdp.TYPE_STRING)
+    AddDescriptorField(desc_proto, 'year', fdp.TYPE_INT64)
+    AddDescriptorField(desc_proto, 'automatic', fdp.TYPE_BOOL)
+    AddDescriptorField(desc_proto, 'price', fdp.TYPE_DOUBLE)
+    # Add a repeated field
+    AddDescriptorField.field_index += 1
+    new_field = desc_proto.field.add()
+    new_field.name = 'owners'
+    new_field.type = fdp.TYPE_STRING
+    new_field.number = AddDescriptorField.field_index
+    new_field.label = descriptor_pb2.FieldDescriptorProto.LABEL_REPEATED
+
+    desc = descriptor.MakeDescriptor(desc_proto)
+    self.assertTrue(desc.fields_by_name.has_key('name'))
+    self.assertTrue(desc.fields_by_name.has_key('year'))
+    self.assertTrue(desc.fields_by_name.has_key('automatic'))
+    self.assertTrue(desc.fields_by_name.has_key('price'))
+    self.assertTrue(desc.fields_by_name.has_key('owners'))
+
+    class CarMessage(message.Message):
+      __metaclass__ = reflection.GeneratedProtocolMessageType
+      DESCRIPTOR = desc
+
+    prius = CarMessage()
+    prius.name = 'prius'
+    prius.year = 2010
+    prius.automatic = True
+    prius.price = 25134.75
+    prius.owners.extend(['bob', 'susan'])
+
+    serialized_prius = prius.SerializeToString()
+    new_prius = reflection.ParseMessage(desc, serialized_prius)
+    self.assertTrue(new_prius is not prius)
+    self.assertEqual(prius, new_prius)
+
+    # these are unnecessary assuming message equality works as advertised but
+    # explicitly check to be safe since we're mucking about in metaclass foo
+    self.assertEqual(prius.name, new_prius.name)
+    self.assertEqual(prius.year, new_prius.year)
+    self.assertEqual(prius.automatic, new_prius.automatic)
+    self.assertEqual(prius.price, new_prius.price)
+    self.assertEqual(prius.owners, new_prius.owners)
+
+  def testTopLevelExtensionsForOptionalScalar(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.optional_int32_extension
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    self.assertEqual(0, extendee_proto.Extensions[extension])
+    # As with normal scalar fields, just doing a read doesn't actually set the
+    # "has" bit.
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    # Actually set the thing.
+    extendee_proto.Extensions[extension] = 23
+    self.assertEqual(23, extendee_proto.Extensions[extension])
+    self.assertTrue(extendee_proto.HasExtension(extension))
+    # Ensure that clearing works as well.
+    extendee_proto.ClearExtension(extension)
+    self.assertEqual(0, extendee_proto.Extensions[extension])
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+
+  def testTopLevelExtensionsForRepeatedScalar(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.repeated_string_extension
+    self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+    extendee_proto.Extensions[extension].append('foo')
+    self.assertEqual(['foo'], extendee_proto.Extensions[extension])
+    string_list = extendee_proto.Extensions[extension]
+    extendee_proto.ClearExtension(extension)
+    self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+    self.assertTrue(string_list is not extendee_proto.Extensions[extension])
+    # Shouldn't be allowed to do Extensions[extension] = 'a'
+    self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
+                      extension, 'a')
+
+  def testTopLevelExtensionsForOptionalMessage(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.optional_foreign_message_extension
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    self.assertEqual(0, extendee_proto.Extensions[extension].c)
+    # As with normal (non-extension) fields, merely reading from the
+    # thing shouldn't set the "has" bit.
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    extendee_proto.Extensions[extension].c = 23
+    self.assertEqual(23, extendee_proto.Extensions[extension].c)
+    self.assertTrue(extendee_proto.HasExtension(extension))
+    # Save a reference here.
+    foreign_message = extendee_proto.Extensions[extension]
+    extendee_proto.ClearExtension(extension)
+    self.assertTrue(foreign_message is not extendee_proto.Extensions[extension])
+    # Setting a field on foreign_message now shouldn't set
+    # any "has" bits on extendee_proto.
+    foreign_message.c = 42
+    self.assertEqual(42, foreign_message.c)
+    self.assertTrue(foreign_message.HasField('c'))
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    # Shouldn't be allowed to do Extensions[extension] = 'a'
+    self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
+                      extension, 'a')
+
+  def testTopLevelExtensionsForRepeatedMessage(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.repeatedgroup_extension
+    self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+    group = extendee_proto.Extensions[extension].add()
+    group.a = 23
+    self.assertEqual(23, extendee_proto.Extensions[extension][0].a)
+    group.a = 42
+    self.assertEqual(42, extendee_proto.Extensions[extension][0].a)
+    group_list = extendee_proto.Extensions[extension]
+    extendee_proto.ClearExtension(extension)
+    self.assertEqual(0, len(extendee_proto.Extensions[extension]))
+    self.assertTrue(group_list is not extendee_proto.Extensions[extension])
+    # Shouldn't be allowed to do Extensions[extension] = 'a'
+    self.assertRaises(TypeError, operator.setitem, extendee_proto.Extensions,
+                      extension, 'a')
+
+  def testNestedExtensions(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.TestRequired.single
+
+    # We just test the non-repeated case.
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    required = extendee_proto.Extensions[extension]
+    self.assertEqual(0, required.a)
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+    required.a = 23
+    self.assertEqual(23, extendee_proto.Extensions[extension].a)
+    self.assertTrue(extendee_proto.HasExtension(extension))
+    extendee_proto.ClearExtension(extension)
+    self.assertTrue(required is not extendee_proto.Extensions[extension])
+    self.assertTrue(not extendee_proto.HasExtension(extension))
+
+  def testRegisteredExtensions(self):
+    self.assertTrue('protobuf_unittest.optional_int32_extension' in
+                    unittest_pb2.TestAllExtensions._extensions_by_name)
+    self.assertTrue(1 in unittest_pb2.TestAllExtensions._extensions_by_number)
+    # Make sure extensions haven't been registered into types that shouldn't
+    # have any.
+    self.assertEquals(0, len(unittest_pb2.TestAllTypes._extensions_by_name))
+
+  # If message A directly contains message B, and
+  # a.HasField('b') is currently False, then mutating any
+  # extension in B should change a.HasField('b') to True
+  # (and so on up the object tree).
+  def testHasBitsForAncestorsOfExtendedMessage(self):
+    # Optional scalar extension.
+    toplevel = more_extensions_pb2.TopLevelMessage()
+    self.assertTrue(not toplevel.HasField('submessage'))
+    self.assertEqual(0, toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_int_extension])
+    self.assertTrue(not toplevel.HasField('submessage'))
+    toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_int_extension] = 23
+    self.assertEqual(23, toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_int_extension])
+    self.assertTrue(toplevel.HasField('submessage'))
+
+    # Repeated scalar extension.
+    toplevel = more_extensions_pb2.TopLevelMessage()
+    self.assertTrue(not toplevel.HasField('submessage'))
+    self.assertEqual([], toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_int_extension])
+    self.assertTrue(not toplevel.HasField('submessage'))
+    toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_int_extension].append(23)
+    self.assertEqual([23], toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_int_extension])
+    self.assertTrue(toplevel.HasField('submessage'))
+
+    # Optional message extension.
+    toplevel = more_extensions_pb2.TopLevelMessage()
+    self.assertTrue(not toplevel.HasField('submessage'))
+    self.assertEqual(0, toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_message_extension].foreign_message_int)
+    self.assertTrue(not toplevel.HasField('submessage'))
+    toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_message_extension].foreign_message_int = 23
+    self.assertEqual(23, toplevel.submessage.Extensions[
+        more_extensions_pb2.optional_message_extension].foreign_message_int)
+    self.assertTrue(toplevel.HasField('submessage'))
+
+    # Repeated message extension.
+    toplevel = more_extensions_pb2.TopLevelMessage()
+    self.assertTrue(not toplevel.HasField('submessage'))
+    self.assertEqual(0, len(toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_message_extension]))
+    self.assertTrue(not toplevel.HasField('submessage'))
+    foreign = toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_message_extension].add()
+    self.assertEqual(foreign, toplevel.submessage.Extensions[
+        more_extensions_pb2.repeated_message_extension][0])
+    self.assertTrue(toplevel.HasField('submessage'))
+
+  def testDisconnectionAfterClearingEmptyMessage(self):
+    toplevel = more_extensions_pb2.TopLevelMessage()
+    extendee_proto = toplevel.submessage
+    extension = more_extensions_pb2.optional_message_extension
+    extension_proto = extendee_proto.Extensions[extension]
+    extendee_proto.ClearExtension(extension)
+    extension_proto.foreign_message_int = 23
+
+    self.assertTrue(extension_proto is not extendee_proto.Extensions[extension])
+
+  def testExtensionFailureModes(self):
+    extendee_proto = unittest_pb2.TestAllExtensions()
+
+    # Try non-extension-handle arguments to HasExtension,
+    # ClearExtension(), and Extensions[]...
+    self.assertRaises(KeyError, extendee_proto.HasExtension, 1234)
+    self.assertRaises(KeyError, extendee_proto.ClearExtension, 1234)
+    self.assertRaises(KeyError, extendee_proto.Extensions.__getitem__, 1234)
+    self.assertRaises(KeyError, extendee_proto.Extensions.__setitem__, 1234, 5)
+
+    # Try something that *is* an extension handle, just not for
+    # this message...
+    unknown_handle = more_extensions_pb2.optional_int_extension
+    self.assertRaises(KeyError, extendee_proto.HasExtension,
+                      unknown_handle)
+    self.assertRaises(KeyError, extendee_proto.ClearExtension,
+                      unknown_handle)
+    self.assertRaises(KeyError, extendee_proto.Extensions.__getitem__,
+                      unknown_handle)
+    self.assertRaises(KeyError, extendee_proto.Extensions.__setitem__,
+                      unknown_handle, 5)
+
+    # Try call HasExtension() with a valid handle, but for a
+    # *repeated* field.  (Just as with non-extension repeated
+    # fields, Has*() isn't supported for extension repeated fields).
+    self.assertRaises(KeyError, extendee_proto.HasExtension,
+                      unittest_pb2.repeated_string_extension)
+
+  def testStaticParseFrom(self):
+    proto1 = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(proto1)
+
+    string1 = proto1.SerializeToString()
+    proto2 = unittest_pb2.TestAllTypes.FromString(string1)
+
+    # Messages should be equal.
+    self.assertEqual(proto2, proto1)
+
+  def testMergeFromSingularField(self):
+    # Test merge with just a singular field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optional_int32 = 1
+
+    proto2 = unittest_pb2.TestAllTypes()
+    # This shouldn't get overwritten.
+    proto2.optional_string = 'value'
+
+    proto2.MergeFrom(proto1)
+    self.assertEqual(1, proto2.optional_int32)
+    self.assertEqual('value', proto2.optional_string)
+
+  def testMergeFromRepeatedField(self):
+    # Test merge with just a repeated field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.repeated_int32.append(1)
+    proto1.repeated_int32.append(2)
+
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.repeated_int32.append(0)
+    proto2.MergeFrom(proto1)
+
+    self.assertEqual(0, proto2.repeated_int32[0])
+    self.assertEqual(1, proto2.repeated_int32[1])
+    self.assertEqual(2, proto2.repeated_int32[2])
+
+  def testMergeFromOptionalGroup(self):
+    # Test merge with an optional group.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optionalgroup.a = 12
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.MergeFrom(proto1)
+    self.assertEqual(12, proto2.optionalgroup.a)
+
+  def testMergeFromRepeatedNestedMessage(self):
+    # Test merge with a repeated nested message.
+    proto1 = unittest_pb2.TestAllTypes()
+    m = proto1.repeated_nested_message.add()
+    m.bb = 123
+    m = proto1.repeated_nested_message.add()
+    m.bb = 321
+
+    proto2 = unittest_pb2.TestAllTypes()
+    m = proto2.repeated_nested_message.add()
+    m.bb = 999
+    proto2.MergeFrom(proto1)
+    self.assertEqual(999, proto2.repeated_nested_message[0].bb)
+    self.assertEqual(123, proto2.repeated_nested_message[1].bb)
+    self.assertEqual(321, proto2.repeated_nested_message[2].bb)
+
+    proto3 = unittest_pb2.TestAllTypes()
+    proto3.repeated_nested_message.MergeFrom(proto2.repeated_nested_message)
+    self.assertEqual(999, proto3.repeated_nested_message[0].bb)
+    self.assertEqual(123, proto3.repeated_nested_message[1].bb)
+    self.assertEqual(321, proto3.repeated_nested_message[2].bb)
+
+  def testMergeFromAllFields(self):
+    # With all fields set.
+    proto1 = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(proto1)
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.MergeFrom(proto1)
+
+    # Messages should be equal.
+    self.assertEqual(proto2, proto1)
+
+    # Serialized string should be equal too.
+    string1 = proto1.SerializeToString()
+    string2 = proto2.SerializeToString()
+    self.assertEqual(string1, string2)
+
+  def testMergeFromExtensionsSingular(self):
+    proto1 = unittest_pb2.TestAllExtensions()
+    proto1.Extensions[unittest_pb2.optional_int32_extension] = 1
+
+    proto2 = unittest_pb2.TestAllExtensions()
+    proto2.MergeFrom(proto1)
+    self.assertEqual(
+        1, proto2.Extensions[unittest_pb2.optional_int32_extension])
+
+  def testMergeFromExtensionsRepeated(self):
+    proto1 = unittest_pb2.TestAllExtensions()
+    proto1.Extensions[unittest_pb2.repeated_int32_extension].append(1)
+    proto1.Extensions[unittest_pb2.repeated_int32_extension].append(2)
+
+    proto2 = unittest_pb2.TestAllExtensions()
+    proto2.Extensions[unittest_pb2.repeated_int32_extension].append(0)
+    proto2.MergeFrom(proto1)
+    self.assertEqual(
+        3, len(proto2.Extensions[unittest_pb2.repeated_int32_extension]))
+    self.assertEqual(
+        0, proto2.Extensions[unittest_pb2.repeated_int32_extension][0])
+    self.assertEqual(
+        1, proto2.Extensions[unittest_pb2.repeated_int32_extension][1])
+    self.assertEqual(
+        2, proto2.Extensions[unittest_pb2.repeated_int32_extension][2])
+
+  def testMergeFromExtensionsNestedMessage(self):
+    proto1 = unittest_pb2.TestAllExtensions()
+    ext1 = proto1.Extensions[
+        unittest_pb2.repeated_nested_message_extension]
+    m = ext1.add()
+    m.bb = 222
+    m = ext1.add()
+    m.bb = 333
+
+    proto2 = unittest_pb2.TestAllExtensions()
+    ext2 = proto2.Extensions[
+        unittest_pb2.repeated_nested_message_extension]
+    m = ext2.add()
+    m.bb = 111
+
+    proto2.MergeFrom(proto1)
+    ext2 = proto2.Extensions[
+        unittest_pb2.repeated_nested_message_extension]
+    self.assertEqual(3, len(ext2))
+    self.assertEqual(111, ext2[0].bb)
+    self.assertEqual(222, ext2[1].bb)
+    self.assertEqual(333, ext2[2].bb)
+
+  def testMergeFromBug(self):
+    message1 = unittest_pb2.TestAllTypes()
+    message2 = unittest_pb2.TestAllTypes()
+
+    # Cause optional_nested_message to be instantiated within message1, even
+    # though it is not considered to be "present".
+    message1.optional_nested_message
+    self.assertFalse(message1.HasField('optional_nested_message'))
+
+    # Merge into message2.  This should not instantiate the field is message2.
+    message2.MergeFrom(message1)
+    self.assertFalse(message2.HasField('optional_nested_message'))
+
+  def testCopyFromSingularField(self):
+    # Test copy with just a singular field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optional_int32 = 1
+    proto1.optional_string = 'important-text'
+
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.optional_string = 'value'
+
+    proto2.CopyFrom(proto1)
+    self.assertEqual(1, proto2.optional_int32)
+    self.assertEqual('important-text', proto2.optional_string)
+
+  def testCopyFromRepeatedField(self):
+    # Test copy with a repeated field.
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.repeated_int32.append(1)
+    proto1.repeated_int32.append(2)
+
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.repeated_int32.append(0)
+    proto2.CopyFrom(proto1)
+
+    self.assertEqual(1, proto2.repeated_int32[0])
+    self.assertEqual(2, proto2.repeated_int32[1])
+
+  def testCopyFromAllFields(self):
+    # With all fields set.
+    proto1 = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(proto1)
+    proto2 = unittest_pb2.TestAllTypes()
+    proto2.CopyFrom(proto1)
+
+    # Messages should be equal.
+    self.assertEqual(proto2, proto1)
+
+    # Serialized string should be equal too.
+    string1 = proto1.SerializeToString()
+    string2 = proto2.SerializeToString()
+    self.assertEqual(string1, string2)
+
+  def testCopyFromSelf(self):
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.repeated_int32.append(1)
+    proto1.optional_int32 = 2
+    proto1.optional_string = 'important-text'
+
+    proto1.CopyFrom(proto1)
+    self.assertEqual(1, proto1.repeated_int32[0])
+    self.assertEqual(2, proto1.optional_int32)
+    self.assertEqual('important-text', proto1.optional_string)
+
+  def testCopyFromBadType(self):
+    # The python implementation doesn't raise an exception in this
+    # case. In theory it should.
+    if api_implementation.Type() == 'python':
+      return
+    proto1 = unittest_pb2.TestAllTypes()
+    proto2 = unittest_pb2.TestAllExtensions()
+    self.assertRaises(TypeError, proto1.CopyFrom, proto2)
+
+  def testDeepCopy(self):
+    proto1 = unittest_pb2.TestAllTypes()
+    proto1.optional_int32 = 1
+    proto2 = copy.deepcopy(proto1)
+    self.assertEqual(1, proto2.optional_int32)
+
+    proto1.repeated_int32.append(2)
+    proto1.repeated_int32.append(3)
+    container = copy.deepcopy(proto1.repeated_int32)
+    self.assertEqual([2, 3], container)
+
+    # TODO(anuraag): Implement deepcopy for repeated composite / extension dict
+
+  def testClear(self):
+    proto = unittest_pb2.TestAllTypes()
+    # C++ implementation does not support lazy fields right now so leave it
+    # out for now.
+    if api_implementation.Type() == 'python':
+      test_util.SetAllFields(proto)
+    else:
+      test_util.SetAllNonLazyFields(proto)
+    # Clear the message.
+    proto.Clear()
+    self.assertEquals(proto.ByteSize(), 0)
+    empty_proto = unittest_pb2.TestAllTypes()
+    self.assertEquals(proto, empty_proto)
+
+    # Test if extensions which were set are cleared.
+    proto = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(proto)
+    # Clear the message.
+    proto.Clear()
+    self.assertEquals(proto.ByteSize(), 0)
+    empty_proto = unittest_pb2.TestAllExtensions()
+    self.assertEquals(proto, empty_proto)
+
+  def testDisconnectingBeforeClear(self):
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    proto.Clear()
+    self.assertTrue(nested is not proto.optional_nested_message)
+    nested.bb = 23
+    self.assertTrue(not proto.HasField('optional_nested_message'))
+    self.assertEqual(0, proto.optional_nested_message.bb)
+
+    proto = unittest_pb2.TestAllTypes()
+    nested = proto.optional_nested_message
+    nested.bb = 5
+    foreign = proto.optional_foreign_message
+    foreign.c = 6
+
+    proto.Clear()
+    self.assertTrue(nested is not proto.optional_nested_message)
+    self.assertTrue(foreign is not proto.optional_foreign_message)
+    self.assertEqual(5, nested.bb)
+    self.assertEqual(6, foreign.c)
+    nested.bb = 15
+    foreign.c = 16
+    self.assertFalse(proto.HasField('optional_nested_message'))
+    self.assertEqual(0, proto.optional_nested_message.bb)
+    self.assertFalse(proto.HasField('optional_foreign_message'))
+    self.assertEqual(0, proto.optional_foreign_message.c)
+
+  def testOneOf(self):
+    proto = unittest_pb2.TestAllTypes()
+    proto.oneof_uint32 = 10
+    proto.oneof_nested_message.bb = 11
+    self.assertEqual(11, proto.oneof_nested_message.bb)
+    self.assertFalse(proto.HasField('oneof_uint32'))
+    nested = proto.oneof_nested_message
+    proto.oneof_string = 'abc'
+    self.assertEqual('abc', proto.oneof_string)
+    self.assertEqual(11, nested.bb)
+    self.assertFalse(proto.HasField('oneof_nested_message'))
+
+  def assertInitialized(self, proto):
+    self.assertTrue(proto.IsInitialized())
+    # Neither method should raise an exception.
+    proto.SerializeToString()
+    proto.SerializePartialToString()
+
+  def assertNotInitialized(self, proto):
+    self.assertFalse(proto.IsInitialized())
+    self.assertRaises(message.EncodeError, proto.SerializeToString)
+    # "Partial" serialization doesn't care if message is uninitialized.
+    proto.SerializePartialToString()
+
+  def testIsInitialized(self):
+    # Trivial cases - all optional fields and extensions.
+    proto = unittest_pb2.TestAllTypes()
+    self.assertInitialized(proto)
+    proto = unittest_pb2.TestAllExtensions()
+    self.assertInitialized(proto)
+
+    # The case of uninitialized required fields.
+    proto = unittest_pb2.TestRequired()
+    self.assertNotInitialized(proto)
+    proto.a = proto.b = proto.c = 2
+    self.assertInitialized(proto)
+
+    # The case of uninitialized submessage.
+    proto = unittest_pb2.TestRequiredForeign()
+    self.assertInitialized(proto)
+    proto.optional_message.a = 1
+    self.assertNotInitialized(proto)
+    proto.optional_message.b = 0
+    proto.optional_message.c = 0
+    self.assertInitialized(proto)
+
+    # Uninitialized repeated submessage.
+    message1 = proto.repeated_message.add()
+    self.assertNotInitialized(proto)
+    message1.a = message1.b = message1.c = 0
+    self.assertInitialized(proto)
+
+    # Uninitialized repeated group in an extension.
+    proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.TestRequired.multi
+    message1 = proto.Extensions[extension].add()
+    message2 = proto.Extensions[extension].add()
+    self.assertNotInitialized(proto)
+    message1.a = 1
+    message1.b = 1
+    message1.c = 1
+    self.assertNotInitialized(proto)
+    message2.a = 2
+    message2.b = 2
+    message2.c = 2
+    self.assertInitialized(proto)
+
+    # Uninitialized nonrepeated message in an extension.
+    proto = unittest_pb2.TestAllExtensions()
+    extension = unittest_pb2.TestRequired.single
+    proto.Extensions[extension].a = 1
+    self.assertNotInitialized(proto)
+    proto.Extensions[extension].b = 2
+    proto.Extensions[extension].c = 3
+    self.assertInitialized(proto)
+
+    # Try passing an errors list.
+    errors = []
+    proto = unittest_pb2.TestRequired()
+    self.assertFalse(proto.IsInitialized(errors))
+    self.assertEqual(errors, ['a', 'b', 'c'])
+
+  @basetest.unittest.skipIf(
+      api_implementation.Type() != 'cpp' or api_implementation.Version() != 2,
+      'Errors are only available from the most recent C++ implementation.')
+  def testFileDescriptorErrors(self):
+    file_name = 'test_file_descriptor_errors.proto'
+    package_name = 'test_file_descriptor_errors.proto'
+    file_descriptor_proto = descriptor_pb2.FileDescriptorProto()
+    file_descriptor_proto.name = file_name
+    file_descriptor_proto.package = package_name
+    m1 = file_descriptor_proto.message_type.add()
+    m1.name = 'msg1'
+    # Compiles the proto into the C++ descriptor pool
+    descriptor.FileDescriptor(
+        file_name,
+        package_name,
+        serialized_pb=file_descriptor_proto.SerializeToString())
+    # Add a FileDescriptorProto that has duplicate symbols
+    another_file_name = 'another_test_file_descriptor_errors.proto'
+    file_descriptor_proto.name = another_file_name
+    m2 = file_descriptor_proto.message_type.add()
+    m2.name = 'msg2'
+    with self.assertRaises(TypeError) as cm:
+      descriptor.FileDescriptor(
+          another_file_name,
+          package_name,
+          serialized_pb=file_descriptor_proto.SerializeToString())
+      self.assertTrue(hasattr(cm, 'exception'), '%s not raised' %
+                      getattr(cm.expected, '__name__', cm.expected))
+      self.assertIn('test_file_descriptor_errors.proto', str(cm.exception))
+      # Error message will say something about this definition being a
+      # duplicate, though we don't check the message exactly to avoid a
+      # dependency on the C++ logging code.
+      self.assertIn('test_file_descriptor_errors.msg1', str(cm.exception))
+
+  def testStringUTF8Encoding(self):
+    proto = unittest_pb2.TestAllTypes()
+
+    # Assignment of a unicode object to a field of type 'bytes' is not allowed.
+    self.assertRaises(TypeError,
+                      setattr, proto, 'optional_bytes', u'unicode object')
+
+    # Check that the default value is of python's 'unicode' type.
+    self.assertEqual(type(proto.optional_string), unicode)
+
+    proto.optional_string = unicode('Testing')
+    self.assertEqual(proto.optional_string, str('Testing'))
+
+    # Assign a value of type 'str' which can be encoded in UTF-8.
+    proto.optional_string = str('Testing')
+    self.assertEqual(proto.optional_string, unicode('Testing'))
+
+    # Try to assign a 'str' value which contains bytes that aren't 7-bit ASCII.
+    self.assertRaises(ValueError,
+                      setattr, proto, 'optional_string', b'a\x80a')
+    if str is bytes:  # PY2
+      # Assign a 'str' object which contains a UTF-8 encoded string.
+      self.assertRaises(ValueError,
+                        setattr, proto, 'optional_string', 'Тест')
+    else:
+      proto.optional_string = 'Тест'
+    # No exception thrown.
+    proto.optional_string = 'abc'
+
+  def testStringUTF8Serialization(self):
+    proto = unittest_mset_pb2.TestMessageSet()
+    extension_message = unittest_mset_pb2.TestMessageSetExtension2
+    extension = extension_message.message_set_extension
+
+    test_utf8 = u'Тест'
+    test_utf8_bytes = test_utf8.encode('utf-8')
+
+    # 'Test' in another language, using UTF-8 charset.
+    proto.Extensions[extension].str = test_utf8
+
+    # Serialize using the MessageSet wire format (this is specified in the
+    # .proto file).
+    serialized = proto.SerializeToString()
+
+    # Check byte size.
+    self.assertEqual(proto.ByteSize(), len(serialized))
+
+    raw = unittest_mset_pb2.RawMessageSet()
+    bytes_read = raw.MergeFromString(serialized)
+    self.assertEqual(len(serialized), bytes_read)
+
+    message2 = unittest_mset_pb2.TestMessageSetExtension2()
+
+    self.assertEqual(1, len(raw.item))
+    # Check that the type_id is the same as the tag ID in the .proto file.
+    self.assertEqual(raw.item[0].type_id, 1547769)
+
+    # Check the actual bytes on the wire.
+    self.assertTrue(
+        raw.item[0].message.endswith(test_utf8_bytes))
+    bytes_read = message2.MergeFromString(raw.item[0].message)
+    self.assertEqual(len(raw.item[0].message), bytes_read)
+
+    self.assertEqual(type(message2.str), unicode)
+    self.assertEqual(message2.str, test_utf8)
+
+    # The pure Python API throws an exception on MergeFromString(),
+    # if any of the string fields of the message can't be UTF-8 decoded.
+    # The C++ implementation of the API has no way to check that on
+    # MergeFromString and thus has no way to throw the exception.
+    #
+    # The pure Python API always returns objects of type 'unicode' (UTF-8
+    # encoded), or 'bytes' (in 7 bit ASCII).
+    badbytes = raw.item[0].message.replace(
+        test_utf8_bytes, len(test_utf8_bytes) * b'\xff')
+
+    unicode_decode_failed = False
+    try:
+      message2.MergeFromString(badbytes)
+    except UnicodeDecodeError:
+      unicode_decode_failed = True
+    string_field = message2.str
+    self.assertTrue(unicode_decode_failed or type(string_field) is bytes)
+
+  def testBytesInTextFormat(self):
+    proto = unittest_pb2.TestAllTypes(optional_bytes=b'\x00\x7f\x80\xff')
+    self.assertEqual(u'optional_bytes: "\\000\\177\\200\\377"\n',
+                     unicode(proto))
+
+  def testEmptyNestedMessage(self):
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_nested_message.MergeFrom(
+        unittest_pb2.TestAllTypes.NestedMessage())
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_nested_message.CopyFrom(
+        unittest_pb2.TestAllTypes.NestedMessage())
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+    proto = unittest_pb2.TestAllTypes()
+    bytes_read = proto.optional_nested_message.MergeFromString(b'')
+    self.assertEqual(0, bytes_read)
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_nested_message.ParseFromString(b'')
+    self.assertTrue(proto.HasField('optional_nested_message'))
+
+    serialized = proto.SerializeToString()
+    proto2 = unittest_pb2.TestAllTypes()
+    self.assertEqual(
+        len(serialized),
+        proto2.MergeFromString(serialized))
+    self.assertTrue(proto2.HasField('optional_nested_message'))
+
+  def testSetInParent(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertFalse(proto.HasField('optionalgroup'))
+    proto.optionalgroup.SetInParent()
+    self.assertTrue(proto.HasField('optionalgroup'))
+
+
+#  Since we had so many tests for protocol buffer equality, we broke these out
+#  into separate TestCase classes.
+
+
+class TestAllTypesEqualityTest(basetest.TestCase):
+
+  def setUp(self):
+    self.first_proto = unittest_pb2.TestAllTypes()
+    self.second_proto = unittest_pb2.TestAllTypes()
+
+  def testNotHashable(self):
+    self.assertRaises(TypeError, hash, self.first_proto)
+
+  def testSelfEquality(self):
+    self.assertEqual(self.first_proto, self.first_proto)
+
+  def testEmptyProtosEqual(self):
+    self.assertEqual(self.first_proto, self.second_proto)
+
+
+class FullProtosEqualityTest(basetest.TestCase):
+
+  """Equality tests using completely-full protos as a starting point."""
+
+  def setUp(self):
+    self.first_proto = unittest_pb2.TestAllTypes()
+    self.second_proto = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(self.first_proto)
+    test_util.SetAllFields(self.second_proto)
+
+  def testNotHashable(self):
+    self.assertRaises(TypeError, hash, self.first_proto)
+
+  def testNoneNotEqual(self):
+    self.assertNotEqual(self.first_proto, None)
+    self.assertNotEqual(None, self.second_proto)
+
+  def testNotEqualToOtherMessage(self):
+    third_proto = unittest_pb2.TestRequired()
+    self.assertNotEqual(self.first_proto, third_proto)
+    self.assertNotEqual(third_proto, self.second_proto)
+
+  def testAllFieldsFilledEquality(self):
+    self.assertEqual(self.first_proto, self.second_proto)
+
+  def testNonRepeatedScalar(self):
+    # Nonrepeated scalar field change should cause inequality.
+    self.first_proto.optional_int32 += 1
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    # ...as should clearing a field.
+    self.first_proto.ClearField('optional_int32')
+    self.assertNotEqual(self.first_proto, self.second_proto)
+
+  def testNonRepeatedComposite(self):
+    # Change a nonrepeated composite field.
+    self.first_proto.optional_nested_message.bb += 1
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.first_proto.optional_nested_message.bb -= 1
+    self.assertEqual(self.first_proto, self.second_proto)
+    # Clear a field in the nested message.
+    self.first_proto.optional_nested_message.ClearField('bb')
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.first_proto.optional_nested_message.bb = (
+        self.second_proto.optional_nested_message.bb)
+    self.assertEqual(self.first_proto, self.second_proto)
+    # Remove the nested message entirely.
+    self.first_proto.ClearField('optional_nested_message')
+    self.assertNotEqual(self.first_proto, self.second_proto)
+
+  def testRepeatedScalar(self):
+    # Change a repeated scalar field.
+    self.first_proto.repeated_int32.append(5)
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.first_proto.ClearField('repeated_int32')
+    self.assertNotEqual(self.first_proto, self.second_proto)
+
+  def testRepeatedComposite(self):
+    # Change value within a repeated composite field.
+    self.first_proto.repeated_nested_message[0].bb += 1
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.first_proto.repeated_nested_message[0].bb -= 1
+    self.assertEqual(self.first_proto, self.second_proto)
+    # Add a value to a repeated composite field.
+    self.first_proto.repeated_nested_message.add()
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.second_proto.repeated_nested_message.add()
+    self.assertEqual(self.first_proto, self.second_proto)
+
+  def testNonRepeatedScalarHasBits(self):
+    # Ensure that we test "has" bits as well as value for
+    # nonrepeated scalar field.
+    self.first_proto.ClearField('optional_int32')
+    self.second_proto.optional_int32 = 0
+    self.assertNotEqual(self.first_proto, self.second_proto)
+
+  def testNonRepeatedCompositeHasBits(self):
+    # Ensure that we test "has" bits as well as value for
+    # nonrepeated composite field.
+    self.first_proto.ClearField('optional_nested_message')
+    self.second_proto.optional_nested_message.ClearField('bb')
+    self.assertNotEqual(self.first_proto, self.second_proto)
+    self.first_proto.optional_nested_message.bb = 0
+    self.first_proto.optional_nested_message.ClearField('bb')
+    self.assertEqual(self.first_proto, self.second_proto)
+
+
+class ExtensionEqualityTest(basetest.TestCase):
+
+  def testExtensionEquality(self):
+    first_proto = unittest_pb2.TestAllExtensions()
+    second_proto = unittest_pb2.TestAllExtensions()
+    self.assertEqual(first_proto, second_proto)
+    test_util.SetAllExtensions(first_proto)
+    self.assertNotEqual(first_proto, second_proto)
+    test_util.SetAllExtensions(second_proto)
+    self.assertEqual(first_proto, second_proto)
+
+    # Ensure that we check value equality.
+    first_proto.Extensions[unittest_pb2.optional_int32_extension] += 1
+    self.assertNotEqual(first_proto, second_proto)
+    first_proto.Extensions[unittest_pb2.optional_int32_extension] -= 1
+    self.assertEqual(first_proto, second_proto)
+
+    # Ensure that we also look at "has" bits.
+    first_proto.ClearExtension(unittest_pb2.optional_int32_extension)
+    second_proto.Extensions[unittest_pb2.optional_int32_extension] = 0
+    self.assertNotEqual(first_proto, second_proto)
+    first_proto.Extensions[unittest_pb2.optional_int32_extension] = 0
+    self.assertEqual(first_proto, second_proto)
+
+    # Ensure that differences in cached values
+    # don't matter if "has" bits are both false.
+    first_proto = unittest_pb2.TestAllExtensions()
+    second_proto = unittest_pb2.TestAllExtensions()
+    self.assertEqual(
+        0, first_proto.Extensions[unittest_pb2.optional_int32_extension])
+    self.assertEqual(first_proto, second_proto)
+
+
+class MutualRecursionEqualityTest(basetest.TestCase):
+
+  def testEqualityWithMutualRecursion(self):
+    first_proto = unittest_pb2.TestMutualRecursionA()
+    second_proto = unittest_pb2.TestMutualRecursionA()
+    self.assertEqual(first_proto, second_proto)
+    first_proto.bb.a.bb.optional_int32 = 23
+    self.assertNotEqual(first_proto, second_proto)
+    second_proto.bb.a.bb.optional_int32 = 23
+    self.assertEqual(first_proto, second_proto)
+
+
+class ByteSizeTest(basetest.TestCase):
+
+  def setUp(self):
+    self.proto = unittest_pb2.TestAllTypes()
+    self.extended_proto = more_extensions_pb2.ExtendedMessage()
+    self.packed_proto = unittest_pb2.TestPackedTypes()
+    self.packed_extended_proto = unittest_pb2.TestPackedExtensions()
+
+  def Size(self):
+    return self.proto.ByteSize()
+
+  def testEmptyMessage(self):
+    self.assertEqual(0, self.proto.ByteSize())
+
+  def testSizedOnKwargs(self):
+    # Use a separate message to ensure testing right after creation.
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(0, proto.ByteSize())
+    proto_kwargs = unittest_pb2.TestAllTypes(optional_int64 = 1)
+    # One byte for the tag, one to encode varint 1.
+    self.assertEqual(2, proto_kwargs.ByteSize())
+
+  def testVarints(self):
+    def Test(i, expected_varint_size):
+      self.proto.Clear()
+      self.proto.optional_int64 = i
+      # Add one to the varint size for the tag info
+      # for tag 1.
+      self.assertEqual(expected_varint_size + 1, self.Size())
+    Test(0, 1)
+    Test(1, 1)
+    for i, num_bytes in zip(range(7, 63, 7), range(1, 10000)):
+      Test((1 << i) - 1, num_bytes)
+    Test(-1, 10)
+    Test(-2, 10)
+    Test(-(1 << 63), 10)
+
+  def testStrings(self):
+    self.proto.optional_string = ''
+    # Need one byte for tag info (tag #14), and one byte for length.
+    self.assertEqual(2, self.Size())
+
+    self.proto.optional_string = 'abc'
+    # Need one byte for tag info (tag #14), and one byte for length.
+    self.assertEqual(2 + len(self.proto.optional_string), self.Size())
+
+    self.proto.optional_string = 'x' * 128
+    # Need one byte for tag info (tag #14), and TWO bytes for length.
+    self.assertEqual(3 + len(self.proto.optional_string), self.Size())
+
+  def testOtherNumerics(self):
+    self.proto.optional_fixed32 = 1234
+    # One byte for tag and 4 bytes for fixed32.
+    self.assertEqual(5, self.Size())
+    self.proto = unittest_pb2.TestAllTypes()
+
+    self.proto.optional_fixed64 = 1234
+    # One byte for tag and 8 bytes for fixed64.
+    self.assertEqual(9, self.Size())
+    self.proto = unittest_pb2.TestAllTypes()
+
+    self.proto.optional_float = 1.234
+    # One byte for tag and 4 bytes for float.
+    self.assertEqual(5, self.Size())
+    self.proto = unittest_pb2.TestAllTypes()
+
+    self.proto.optional_double = 1.234
+    # One byte for tag and 8 bytes for float.
+    self.assertEqual(9, self.Size())
+    self.proto = unittest_pb2.TestAllTypes()
+
+    self.proto.optional_sint32 = 64
+    # One byte for tag and 2 bytes for zig-zag-encoded 64.
+    self.assertEqual(3, self.Size())
+    self.proto = unittest_pb2.TestAllTypes()
+
+  def testComposites(self):
+    # 3 bytes.
+    self.proto.optional_nested_message.bb = (1 << 14)
+    # Plus one byte for bb tag.
+    # Plus 1 byte for optional_nested_message serialized size.
+    # Plus two bytes for optional_nested_message tag.
+    self.assertEqual(3 + 1 + 1 + 2, self.Size())
+
+  def testGroups(self):
+    # 4 bytes.
+    self.proto.optionalgroup.a = (1 << 21)
+    # Plus two bytes for |a| tag.
+    # Plus 2 * two bytes for START_GROUP and END_GROUP tags.
+    self.assertEqual(4 + 2 + 2*2, self.Size())
+
+  def testRepeatedScalars(self):
+    self.proto.repeated_int32.append(10)  # 1 byte.
+    self.proto.repeated_int32.append(128)  # 2 bytes.
+    # Also need 2 bytes for each entry for tag.
+    self.assertEqual(1 + 2 + 2*2, self.Size())
+
+  def testRepeatedScalarsExtend(self):
+    self.proto.repeated_int32.extend([10, 128])  # 3 bytes.
+    # Also need 2 bytes for each entry for tag.
+    self.assertEqual(1 + 2 + 2*2, self.Size())
+
+  def testRepeatedScalarsRemove(self):
+    self.proto.repeated_int32.append(10)  # 1 byte.
+    self.proto.repeated_int32.append(128)  # 2 bytes.
+    # Also need 2 bytes for each entry for tag.
+    self.assertEqual(1 + 2 + 2*2, self.Size())
+    self.proto.repeated_int32.remove(128)
+    self.assertEqual(1 + 2, self.Size())
+
+  def testRepeatedComposites(self):
+    # Empty message.  2 bytes tag plus 1 byte length.
+    foreign_message_0 = self.proto.repeated_nested_message.add()
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    foreign_message_1 = self.proto.repeated_nested_message.add()
+    foreign_message_1.bb = 7
+    self.assertEqual(2 + 1 + 2 + 1 + 1 + 1, self.Size())
+
+  def testRepeatedCompositesDelete(self):
+    # Empty message.  2 bytes tag plus 1 byte length.
+    foreign_message_0 = self.proto.repeated_nested_message.add()
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    foreign_message_1 = self.proto.repeated_nested_message.add()
+    foreign_message_1.bb = 9
+    self.assertEqual(2 + 1 + 2 + 1 + 1 + 1, self.Size())
+
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    del self.proto.repeated_nested_message[0]
+    self.assertEqual(2 + 1 + 1 + 1, self.Size())
+
+    # Now add a new message.
+    foreign_message_2 = self.proto.repeated_nested_message.add()
+    foreign_message_2.bb = 12
+
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    self.assertEqual(2 + 1 + 1 + 1 + 2 + 1 + 1 + 1, self.Size())
+
+    # 2 bytes tag plus 1 byte length plus 1 byte bb tag 1 byte int.
+    del self.proto.repeated_nested_message[1]
+    self.assertEqual(2 + 1 + 1 + 1, self.Size())
+
+    del self.proto.repeated_nested_message[0]
+    self.assertEqual(0, self.Size())
+
+  def testRepeatedGroups(self):
+    # 2-byte START_GROUP plus 2-byte END_GROUP.
+    group_0 = self.proto.repeatedgroup.add()
+    # 2-byte START_GROUP plus 2-byte |a| tag + 1-byte |a|
+    # plus 2-byte END_GROUP.
+    group_1 = self.proto.repeatedgroup.add()
+    group_1.a =  7
+    self.assertEqual(2 + 2 + 2 + 2 + 1 + 2, self.Size())
+
+  def testExtensions(self):
+    proto = unittest_pb2.TestAllExtensions()
+    self.assertEqual(0, proto.ByteSize())
+    extension = unittest_pb2.optional_int32_extension  # Field #1, 1 byte.
+    proto.Extensions[extension] = 23
+    # 1 byte for tag, 1 byte for value.
+    self.assertEqual(2, proto.ByteSize())
+
+  def testCacheInvalidationForNonrepeatedScalar(self):
+    # Test non-extension.
+    self.proto.optional_int32 = 1
+    self.assertEqual(2, self.proto.ByteSize())
+    self.proto.optional_int32 = 128
+    self.assertEqual(3, self.proto.ByteSize())
+    self.proto.ClearField('optional_int32')
+    self.assertEqual(0, self.proto.ByteSize())
+
+    # Test within extension.
+    extension = more_extensions_pb2.optional_int_extension
+    self.extended_proto.Extensions[extension] = 1
+    self.assertEqual(2, self.extended_proto.ByteSize())
+    self.extended_proto.Extensions[extension] = 128
+    self.assertEqual(3, self.extended_proto.ByteSize())
+    self.extended_proto.ClearExtension(extension)
+    self.assertEqual(0, self.extended_proto.ByteSize())
+
+  def testCacheInvalidationForRepeatedScalar(self):
+    # Test non-extension.
+    self.proto.repeated_int32.append(1)
+    self.assertEqual(3, self.proto.ByteSize())
+    self.proto.repeated_int32.append(1)
+    self.assertEqual(6, self.proto.ByteSize())
+    self.proto.repeated_int32[1] = 128
+    self.assertEqual(7, self.proto.ByteSize())
+    self.proto.ClearField('repeated_int32')
+    self.assertEqual(0, self.proto.ByteSize())
+
+    # Test within extension.
+    extension = more_extensions_pb2.repeated_int_extension
+    repeated = self.extended_proto.Extensions[extension]
+    repeated.append(1)
+    self.assertEqual(2, self.extended_proto.ByteSize())
+    repeated.append(1)
+    self.assertEqual(4, self.extended_proto.ByteSize())
+    repeated[1] = 128
+    self.assertEqual(5, self.extended_proto.ByteSize())
+    self.extended_proto.ClearExtension(extension)
+    self.assertEqual(0, self.extended_proto.ByteSize())
+
+  def testCacheInvalidationForNonrepeatedMessage(self):
+    # Test non-extension.
+    self.proto.optional_foreign_message.c = 1
+    self.assertEqual(5, self.proto.ByteSize())
+    self.proto.optional_foreign_message.c = 128
+    self.assertEqual(6, self.proto.ByteSize())
+    self.proto.optional_foreign_message.ClearField('c')
+    self.assertEqual(3, self.proto.ByteSize())
+    self.proto.ClearField('optional_foreign_message')
+    self.assertEqual(0, self.proto.ByteSize())
+
+    if api_implementation.Type() == 'python':
+      # This is only possible in pure-Python implementation of the API.
+      child = self.proto.optional_foreign_message
+      self.proto.ClearField('optional_foreign_message')
+      child.c = 128
+      self.assertEqual(0, self.proto.ByteSize())
+
+    # Test within extension.
+    extension = more_extensions_pb2.optional_message_extension
+    child = self.extended_proto.Extensions[extension]
+    self.assertEqual(0, self.extended_proto.ByteSize())
+    child.foreign_message_int = 1
+    self.assertEqual(4, self.extended_proto.ByteSize())
+    child.foreign_message_int = 128
+    self.assertEqual(5, self.extended_proto.ByteSize())
+    self.extended_proto.ClearExtension(extension)
+    self.assertEqual(0, self.extended_proto.ByteSize())
+
+  def testCacheInvalidationForRepeatedMessage(self):
+    # Test non-extension.
+    child0 = self.proto.repeated_foreign_message.add()
+    self.assertEqual(3, self.proto.ByteSize())
+    self.proto.repeated_foreign_message.add()
+    self.assertEqual(6, self.proto.ByteSize())
+    child0.c = 1
+    self.assertEqual(8, self.proto.ByteSize())
+    self.proto.ClearField('repeated_foreign_message')
+    self.assertEqual(0, self.proto.ByteSize())
+
+    # Test within extension.
+    extension = more_extensions_pb2.repeated_message_extension
+    child_list = self.extended_proto.Extensions[extension]
+    child0 = child_list.add()
+    self.assertEqual(2, self.extended_proto.ByteSize())
+    child_list.add()
+    self.assertEqual(4, self.extended_proto.ByteSize())
+    child0.foreign_message_int = 1
+    self.assertEqual(6, self.extended_proto.ByteSize())
+    child0.ClearField('foreign_message_int')
+    self.assertEqual(4, self.extended_proto.ByteSize())
+    self.extended_proto.ClearExtension(extension)
+    self.assertEqual(0, self.extended_proto.ByteSize())
+
+  def testPackedRepeatedScalars(self):
+    self.assertEqual(0, self.packed_proto.ByteSize())
+
+    self.packed_proto.packed_int32.append(10)   # 1 byte.
+    self.packed_proto.packed_int32.append(128)  # 2 bytes.
+    # The tag is 2 bytes (the field number is 90), and the varint
+    # storing the length is 1 byte.
+    int_size = 1 + 2 + 3
+    self.assertEqual(int_size, self.packed_proto.ByteSize())
+
+    self.packed_proto.packed_double.append(4.2)   # 8 bytes
+    self.packed_proto.packed_double.append(3.25)  # 8 bytes
+    # 2 more tag bytes, 1 more length byte.
+    double_size = 8 + 8 + 3
+    self.assertEqual(int_size+double_size, self.packed_proto.ByteSize())
+
+    self.packed_proto.ClearField('packed_int32')
+    self.assertEqual(double_size, self.packed_proto.ByteSize())
+
+  def testPackedExtensions(self):
+    self.assertEqual(0, self.packed_extended_proto.ByteSize())
+    extension = self.packed_extended_proto.Extensions[
+        unittest_pb2.packed_fixed32_extension]
+    extension.extend([1, 2, 3, 4])   # 16 bytes
+    # Tag is 3 bytes.
+    self.assertEqual(19, self.packed_extended_proto.ByteSize())
+
+
+# Issues to be sure to cover include:
+#   * Handling of unrecognized tags ("uninterpreted_bytes").
+#   * Handling of MessageSets.
+#   * Consistent ordering of tags in the wire format,
+#     including ordering between extensions and non-extension
+#     fields.
+#   * Consistent serialization of negative numbers, especially
+#     negative int32s.
+#   * Handling of empty submessages (with and without "has"
+#     bits set).
+
+class SerializationTest(basetest.TestCase):
+
+  def testSerializeEmtpyMessage(self):
+    first_proto = unittest_pb2.TestAllTypes()
+    second_proto = unittest_pb2.TestAllTypes()
+    serialized = first_proto.SerializeToString()
+    self.assertEqual(first_proto.ByteSize(), len(serialized))
+    self.assertEqual(
+        len(serialized),
+        second_proto.MergeFromString(serialized))
+    self.assertEqual(first_proto, second_proto)
+
+  def testSerializeAllFields(self):
+    first_proto = unittest_pb2.TestAllTypes()
+    second_proto = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(first_proto)
+    serialized = first_proto.SerializeToString()
+    self.assertEqual(first_proto.ByteSize(), len(serialized))
+    self.assertEqual(
+        len(serialized),
+        second_proto.MergeFromString(serialized))
+    self.assertEqual(first_proto, second_proto)
+
+  def testSerializeAllExtensions(self):
+    first_proto = unittest_pb2.TestAllExtensions()
+    second_proto = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(first_proto)
+    serialized = first_proto.SerializeToString()
+    self.assertEqual(
+        len(serialized),
+        second_proto.MergeFromString(serialized))
+    self.assertEqual(first_proto, second_proto)
+
+  def testSerializeWithOptionalGroup(self):
+    first_proto = unittest_pb2.TestAllTypes()
+    second_proto = unittest_pb2.TestAllTypes()
+    first_proto.optionalgroup.a = 242
+    serialized = first_proto.SerializeToString()
+    self.assertEqual(
+        len(serialized),
+        second_proto.MergeFromString(serialized))
+    self.assertEqual(first_proto, second_proto)
+
+  def testSerializeNegativeValues(self):
+    first_proto = unittest_pb2.TestAllTypes()
+
+    first_proto.optional_int32 = -1
+    first_proto.optional_int64 = -(2 << 40)
+    first_proto.optional_sint32 = -3
+    first_proto.optional_sint64 = -(4 << 40)
+    first_proto.optional_sfixed32 = -5
+    first_proto.optional_sfixed64 = -(6 << 40)
+
+    second_proto = unittest_pb2.TestAllTypes.FromString(
+        first_proto.SerializeToString())
+
+    self.assertEqual(first_proto, second_proto)
+
+  def testParseTruncated(self):
+    # This test is only applicable for the Python implementation of the API.
+    if api_implementation.Type() != 'python':
+      return
+
+    first_proto = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(first_proto)
+    serialized = first_proto.SerializeToString()
+
+    for truncation_point in xrange(len(serialized) + 1):
+      try:
+        second_proto = unittest_pb2.TestAllTypes()
+        unknown_fields = unittest_pb2.TestEmptyMessage()
+        pos = second_proto._InternalParse(serialized, 0, truncation_point)
+        # If we didn't raise an error then we read exactly the amount expected.
+        self.assertEqual(truncation_point, pos)
+
+        # Parsing to unknown fields should not throw if parsing to known fields
+        # did not.
+        try:
+          pos2 = unknown_fields._InternalParse(serialized, 0, truncation_point)
+          self.assertEqual(truncation_point, pos2)
+        except message.DecodeError:
+          self.fail('Parsing unknown fields failed when parsing known fields '
+                    'did not.')
+      except message.DecodeError:
+        # Parsing unknown fields should also fail.
+        self.assertRaises(message.DecodeError, unknown_fields._InternalParse,
+                          serialized, 0, truncation_point)
+
+  def testCanonicalSerializationOrder(self):
+    proto = more_messages_pb2.OutOfOrderFields()
+    # These are also their tag numbers.  Even though we're setting these in
+    # reverse-tag order AND they're listed in reverse tag-order in the .proto
+    # file, they should nonetheless be serialized in tag order.
+    proto.optional_sint32 = 5
+    proto.Extensions[more_messages_pb2.optional_uint64] = 4
+    proto.optional_uint32 = 3
+    proto.Extensions[more_messages_pb2.optional_int64] = 2
+    proto.optional_int32 = 1
+    serialized = proto.SerializeToString()
+    self.assertEqual(proto.ByteSize(), len(serialized))
+    d = _MiniDecoder(serialized)
+    ReadTag = d.ReadFieldNumberAndWireType
+    self.assertEqual((1, wire_format.WIRETYPE_VARINT), ReadTag())
+    self.assertEqual(1, d.ReadInt32())
+    self.assertEqual((2, wire_format.WIRETYPE_VARINT), ReadTag())
+    self.assertEqual(2, d.ReadInt64())
+    self.assertEqual((3, wire_format.WIRETYPE_VARINT), ReadTag())
+    self.assertEqual(3, d.ReadUInt32())
+    self.assertEqual((4, wire_format.WIRETYPE_VARINT), ReadTag())
+    self.assertEqual(4, d.ReadUInt64())
+    self.assertEqual((5, wire_format.WIRETYPE_VARINT), ReadTag())
+    self.assertEqual(5, d.ReadSInt32())
+
+  def testCanonicalSerializationOrderSameAsCpp(self):
+    # Copy of the same test we use for C++.
+    proto = unittest_pb2.TestFieldOrderings()
+    test_util.SetAllFieldsAndExtensions(proto)
+    serialized = proto.SerializeToString()
+    test_util.ExpectAllFieldsAndExtensionsInOrder(serialized)
+
+  def testMergeFromStringWhenFieldsAlreadySet(self):
+    first_proto = unittest_pb2.TestAllTypes()
+    first_proto.repeated_string.append('foobar')
+    first_proto.optional_int32 = 23
+    first_proto.optional_nested_message.bb = 42
+    serialized = first_proto.SerializeToString()
+
+    second_proto = unittest_pb2.TestAllTypes()
+    second_proto.repeated_string.append('baz')
+    second_proto.optional_int32 = 100
+    second_proto.optional_nested_message.bb = 999
+
+    bytes_parsed = second_proto.MergeFromString(serialized)
+    self.assertEqual(len(serialized), bytes_parsed)
+
+    # Ensure that we append to repeated fields.
+    self.assertEqual(['baz', 'foobar'], list(second_proto.repeated_string))
+    # Ensure that we overwrite nonrepeatd scalars.
+    self.assertEqual(23, second_proto.optional_int32)
+    # Ensure that we recursively call MergeFromString() on
+    # submessages.
+    self.assertEqual(42, second_proto.optional_nested_message.bb)
+
+  def testMessageSetWireFormat(self):
+    proto = unittest_mset_pb2.TestMessageSet()
+    extension_message1 = unittest_mset_pb2.TestMessageSetExtension1
+    extension_message2 = unittest_mset_pb2.TestMessageSetExtension2
+    extension1 = extension_message1.message_set_extension
+    extension2 = extension_message2.message_set_extension
+    proto.Extensions[extension1].i = 123
+    proto.Extensions[extension2].str = 'foo'
+
+    # Serialize using the MessageSet wire format (this is specified in the
+    # .proto file).
+    serialized = proto.SerializeToString()
+
+    raw = unittest_mset_pb2.RawMessageSet()
+    self.assertEqual(False,
+                     raw.DESCRIPTOR.GetOptions().message_set_wire_format)
+    self.assertEqual(
+        len(serialized),
+        raw.MergeFromString(serialized))
+    self.assertEqual(2, len(raw.item))
+
+    message1 = unittest_mset_pb2.TestMessageSetExtension1()
+    self.assertEqual(
+        len(raw.item[0].message),
+        message1.MergeFromString(raw.item[0].message))
+    self.assertEqual(123, message1.i)
+
+    message2 = unittest_mset_pb2.TestMessageSetExtension2()
+    self.assertEqual(
+        len(raw.item[1].message),
+        message2.MergeFromString(raw.item[1].message))
+    self.assertEqual('foo', message2.str)
+
+    # Deserialize using the MessageSet wire format.
+    proto2 = unittest_mset_pb2.TestMessageSet()
+    self.assertEqual(
+        len(serialized),
+        proto2.MergeFromString(serialized))
+    self.assertEqual(123, proto2.Extensions[extension1].i)
+    self.assertEqual('foo', proto2.Extensions[extension2].str)
+
+    # Check byte size.
+    self.assertEqual(proto2.ByteSize(), len(serialized))
+    self.assertEqual(proto.ByteSize(), len(serialized))
+
+  def testMessageSetWireFormatUnknownExtension(self):
+    # Create a message using the message set wire format with an unknown
+    # message.
+    raw = unittest_mset_pb2.RawMessageSet()
+
+    # Add an item.
+    item = raw.item.add()
+    item.type_id = 1545008
+    extension_message1 = unittest_mset_pb2.TestMessageSetExtension1
+    message1 = unittest_mset_pb2.TestMessageSetExtension1()
+    message1.i = 12345
+    item.message = message1.SerializeToString()
+
+    # Add a second, unknown extension.
+    item = raw.item.add()
+    item.type_id = 1545009
+    extension_message1 = unittest_mset_pb2.TestMessageSetExtension1
+    message1 = unittest_mset_pb2.TestMessageSetExtension1()
+    message1.i = 12346
+    item.message = message1.SerializeToString()
+
+    # Add another unknown extension.
+    item = raw.item.add()
+    item.type_id = 1545010
+    message1 = unittest_mset_pb2.TestMessageSetExtension2()
+    message1.str = 'foo'
+    item.message = message1.SerializeToString()
+
+    serialized = raw.SerializeToString()
+
+    # Parse message using the message set wire format.
+    proto = unittest_mset_pb2.TestMessageSet()
+    self.assertEqual(
+        len(serialized),
+        proto.MergeFromString(serialized))
+
+    # Check that the message parsed well.
+    extension_message1 = unittest_mset_pb2.TestMessageSetExtension1
+    extension1 = extension_message1.message_set_extension
+    self.assertEquals(12345, proto.Extensions[extension1].i)
+
+  def testUnknownFields(self):
+    proto = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(proto)
+
+    serialized = proto.SerializeToString()
+
+    # The empty message should be parsable with all of the fields
+    # unknown.
+    proto2 = unittest_pb2.TestEmptyMessage()
+
+    # Parsing this message should succeed.
+    self.assertEqual(
+        len(serialized),
+        proto2.MergeFromString(serialized))
+
+    # Now test with a int64 field set.
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_int64 = 0x0fffffffffffffff
+    serialized = proto.SerializeToString()
+    # The empty message should be parsable with all of the fields
+    # unknown.
+    proto2 = unittest_pb2.TestEmptyMessage()
+    # Parsing this message should succeed.
+    self.assertEqual(
+        len(serialized),
+        proto2.MergeFromString(serialized))
+
+  def _CheckRaises(self, exc_class, callable_obj, exception):
+    """This method checks if the excpetion type and message are as expected."""
+    try:
+      callable_obj()
+    except exc_class as ex:
+      # Check if the exception message is the right one.
+      self.assertEqual(exception, str(ex))
+      return
+    else:
+      raise self.failureException('%s not raised' % str(exc_class))
+
+  def testSerializeUninitialized(self):
+    proto = unittest_pb2.TestRequired()
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Message protobuf_unittest.TestRequired is missing required fields: '
+        'a,b,c')
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto2 = unittest_pb2.TestRequired()
+    self.assertFalse(proto2.HasField('a'))
+    # proto2 ParseFromString does not check that required fields are set.
+    proto2.ParseFromString(partial)
+    self.assertFalse(proto2.HasField('a'))
+
+    proto.a = 1
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Message protobuf_unittest.TestRequired is missing required fields: b,c')
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto.b = 2
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Message protobuf_unittest.TestRequired is missing required fields: c')
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto.c = 3
+    serialized = proto.SerializeToString()
+    # Shouldn't raise exceptions.
+    partial = proto.SerializePartialToString()
+
+    proto2 = unittest_pb2.TestRequired()
+    self.assertEqual(
+        len(serialized),
+        proto2.MergeFromString(serialized))
+    self.assertEqual(1, proto2.a)
+    self.assertEqual(2, proto2.b)
+    self.assertEqual(3, proto2.c)
+    self.assertEqual(
+        len(partial),
+        proto2.MergeFromString(partial))
+    self.assertEqual(1, proto2.a)
+    self.assertEqual(2, proto2.b)
+    self.assertEqual(3, proto2.c)
+
+  def testSerializeUninitializedSubMessage(self):
+    proto = unittest_pb2.TestRequiredForeign()
+
+    # Sub-message doesn't exist yet, so this succeeds.
+    proto.SerializeToString()
+
+    proto.optional_message.a = 1
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Message protobuf_unittest.TestRequiredForeign '
+        'is missing required fields: '
+        'optional_message.b,optional_message.c')
+
+    proto.optional_message.b = 2
+    proto.optional_message.c = 3
+    proto.SerializeToString()
+
+    proto.repeated_message.add().a = 1
+    proto.repeated_message.add().b = 2
+    self._CheckRaises(
+        message.EncodeError,
+        proto.SerializeToString,
+        'Message protobuf_unittest.TestRequiredForeign is missing required fields: '
+        'repeated_message[0].b,repeated_message[0].c,'
+        'repeated_message[1].a,repeated_message[1].c')
+
+    proto.repeated_message[0].b = 2
+    proto.repeated_message[0].c = 3
+    proto.repeated_message[1].a = 1
+    proto.repeated_message[1].c = 3
+    proto.SerializeToString()
+
+  def testSerializeAllPackedFields(self):
+    first_proto = unittest_pb2.TestPackedTypes()
+    second_proto = unittest_pb2.TestPackedTypes()
+    test_util.SetAllPackedFields(first_proto)
+    serialized = first_proto.SerializeToString()
+    self.assertEqual(first_proto.ByteSize(), len(serialized))
+    bytes_read = second_proto.MergeFromString(serialized)
+    self.assertEqual(second_proto.ByteSize(), bytes_read)
+    self.assertEqual(first_proto, second_proto)
+
+  def testSerializeAllPackedExtensions(self):
+    first_proto = unittest_pb2.TestPackedExtensions()
+    second_proto = unittest_pb2.TestPackedExtensions()
+    test_util.SetAllPackedExtensions(first_proto)
+    serialized = first_proto.SerializeToString()
+    bytes_read = second_proto.MergeFromString(serialized)
+    self.assertEqual(second_proto.ByteSize(), bytes_read)
+    self.assertEqual(first_proto, second_proto)
+
+  def testMergePackedFromStringWhenSomeFieldsAlreadySet(self):
+    first_proto = unittest_pb2.TestPackedTypes()
+    first_proto.packed_int32.extend([1, 2])
+    first_proto.packed_double.append(3.0)
+    serialized = first_proto.SerializeToString()
+
+    second_proto = unittest_pb2.TestPackedTypes()
+    second_proto.packed_int32.append(3)
+    second_proto.packed_double.extend([1.0, 2.0])
+    second_proto.packed_sint32.append(4)
+
+    self.assertEqual(
+        len(serialized),
+        second_proto.MergeFromString(serialized))
+    self.assertEqual([3, 1, 2], second_proto.packed_int32)
+    self.assertEqual([1.0, 2.0, 3.0], second_proto.packed_double)
+    self.assertEqual([4], second_proto.packed_sint32)
+
+  def testPackedFieldsWireFormat(self):
+    proto = unittest_pb2.TestPackedTypes()
+    proto.packed_int32.extend([1, 2, 150, 3])  # 1 + 1 + 2 + 1 bytes
+    proto.packed_double.extend([1.0, 1000.0])  # 8 + 8 bytes
+    proto.packed_float.append(2.0)             # 4 bytes, will be before double
+    serialized = proto.SerializeToString()
+    self.assertEqual(proto.ByteSize(), len(serialized))
+    d = _MiniDecoder(serialized)
+    ReadTag = d.ReadFieldNumberAndWireType
+    self.assertEqual((90, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+    self.assertEqual(1+1+1+2, d.ReadInt32())
+    self.assertEqual(1, d.ReadInt32())
+    self.assertEqual(2, d.ReadInt32())
+    self.assertEqual(150, d.ReadInt32())
+    self.assertEqual(3, d.ReadInt32())
+    self.assertEqual((100, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+    self.assertEqual(4, d.ReadInt32())
+    self.assertEqual(2.0, d.ReadFloat())
+    self.assertEqual((101, wire_format.WIRETYPE_LENGTH_DELIMITED), ReadTag())
+    self.assertEqual(8+8, d.ReadInt32())
+    self.assertEqual(1.0, d.ReadDouble())
+    self.assertEqual(1000.0, d.ReadDouble())
+    self.assertTrue(d.EndOfStream())
+
+  def testParsePackedFromUnpacked(self):
+    unpacked = unittest_pb2.TestUnpackedTypes()
+    test_util.SetAllUnpackedFields(unpacked)
+    packed = unittest_pb2.TestPackedTypes()
+    serialized = unpacked.SerializeToString()
+    self.assertEqual(
+        len(serialized),
+        packed.MergeFromString(serialized))
+    expected = unittest_pb2.TestPackedTypes()
+    test_util.SetAllPackedFields(expected)
+    self.assertEqual(expected, packed)
+
+  def testParseUnpackedFromPacked(self):
+    packed = unittest_pb2.TestPackedTypes()
+    test_util.SetAllPackedFields(packed)
+    unpacked = unittest_pb2.TestUnpackedTypes()
+    serialized = packed.SerializeToString()
+    self.assertEqual(
+        len(serialized),
+        unpacked.MergeFromString(serialized))
+    expected = unittest_pb2.TestUnpackedTypes()
+    test_util.SetAllUnpackedFields(expected)
+    self.assertEqual(expected, unpacked)
+
+  def testFieldNumbers(self):
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(unittest_pb2.TestAllTypes.NestedMessage.BB_FIELD_NUMBER, 1)
+    self.assertEqual(unittest_pb2.TestAllTypes.OPTIONAL_INT32_FIELD_NUMBER, 1)
+    self.assertEqual(unittest_pb2.TestAllTypes.OPTIONALGROUP_FIELD_NUMBER, 16)
+    self.assertEqual(
+      unittest_pb2.TestAllTypes.OPTIONAL_NESTED_MESSAGE_FIELD_NUMBER, 18)
+    self.assertEqual(
+      unittest_pb2.TestAllTypes.OPTIONAL_NESTED_ENUM_FIELD_NUMBER, 21)
+    self.assertEqual(unittest_pb2.TestAllTypes.REPEATED_INT32_FIELD_NUMBER, 31)
+    self.assertEqual(unittest_pb2.TestAllTypes.REPEATEDGROUP_FIELD_NUMBER, 46)
+    self.assertEqual(
+      unittest_pb2.TestAllTypes.REPEATED_NESTED_MESSAGE_FIELD_NUMBER, 48)
+    self.assertEqual(
+      unittest_pb2.TestAllTypes.REPEATED_NESTED_ENUM_FIELD_NUMBER, 51)
+
+  def testExtensionFieldNumbers(self):
+    self.assertEqual(unittest_pb2.TestRequired.single.number, 1000)
+    self.assertEqual(unittest_pb2.TestRequired.SINGLE_FIELD_NUMBER, 1000)
+    self.assertEqual(unittest_pb2.TestRequired.multi.number, 1001)
+    self.assertEqual(unittest_pb2.TestRequired.MULTI_FIELD_NUMBER, 1001)
+    self.assertEqual(unittest_pb2.optional_int32_extension.number, 1)
+    self.assertEqual(unittest_pb2.OPTIONAL_INT32_EXTENSION_FIELD_NUMBER, 1)
+    self.assertEqual(unittest_pb2.optionalgroup_extension.number, 16)
+    self.assertEqual(unittest_pb2.OPTIONALGROUP_EXTENSION_FIELD_NUMBER, 16)
+    self.assertEqual(unittest_pb2.optional_nested_message_extension.number, 18)
+    self.assertEqual(
+      unittest_pb2.OPTIONAL_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 18)
+    self.assertEqual(unittest_pb2.optional_nested_enum_extension.number, 21)
+    self.assertEqual(unittest_pb2.OPTIONAL_NESTED_ENUM_EXTENSION_FIELD_NUMBER,
+      21)
+    self.assertEqual(unittest_pb2.repeated_int32_extension.number, 31)
+    self.assertEqual(unittest_pb2.REPEATED_INT32_EXTENSION_FIELD_NUMBER, 31)
+    self.assertEqual(unittest_pb2.repeatedgroup_extension.number, 46)
+    self.assertEqual(unittest_pb2.REPEATEDGROUP_EXTENSION_FIELD_NUMBER, 46)
+    self.assertEqual(unittest_pb2.repeated_nested_message_extension.number, 48)
+    self.assertEqual(
+      unittest_pb2.REPEATED_NESTED_MESSAGE_EXTENSION_FIELD_NUMBER, 48)
+    self.assertEqual(unittest_pb2.repeated_nested_enum_extension.number, 51)
+    self.assertEqual(unittest_pb2.REPEATED_NESTED_ENUM_EXTENSION_FIELD_NUMBER,
+      51)
+
+  def testInitKwargs(self):
+    proto = unittest_pb2.TestAllTypes(
+        optional_int32=1,
+        optional_string='foo',
+        optional_bool=True,
+        optional_bytes=b'bar',
+        optional_nested_message=unittest_pb2.TestAllTypes.NestedMessage(bb=1),
+        optional_foreign_message=unittest_pb2.ForeignMessage(c=1),
+        optional_nested_enum=unittest_pb2.TestAllTypes.FOO,
+        optional_foreign_enum=unittest_pb2.FOREIGN_FOO,
+        repeated_int32=[1, 2, 3])
+    self.assertTrue(proto.IsInitialized())
+    self.assertTrue(proto.HasField('optional_int32'))
+    self.assertTrue(proto.HasField('optional_string'))
+    self.assertTrue(proto.HasField('optional_bool'))
+    self.assertTrue(proto.HasField('optional_bytes'))
+    self.assertTrue(proto.HasField('optional_nested_message'))
+    self.assertTrue(proto.HasField('optional_foreign_message'))
+    self.assertTrue(proto.HasField('optional_nested_enum'))
+    self.assertTrue(proto.HasField('optional_foreign_enum'))
+    self.assertEqual(1, proto.optional_int32)
+    self.assertEqual('foo', proto.optional_string)
+    self.assertEqual(True, proto.optional_bool)
+    self.assertEqual(b'bar', proto.optional_bytes)
+    self.assertEqual(1, proto.optional_nested_message.bb)
+    self.assertEqual(1, proto.optional_foreign_message.c)
+    self.assertEqual(unittest_pb2.TestAllTypes.FOO,
+                     proto.optional_nested_enum)
+    self.assertEqual(unittest_pb2.FOREIGN_FOO, proto.optional_foreign_enum)
+    self.assertEqual([1, 2, 3], proto.repeated_int32)
+
+  def testInitArgsUnknownFieldName(self):
+    def InitalizeEmptyMessageWithExtraKeywordArg():
+      unused_proto = unittest_pb2.TestEmptyMessage(unknown='unknown')
+    self._CheckRaises(ValueError,
+                      InitalizeEmptyMessageWithExtraKeywordArg,
+                      'Protocol message has no "unknown" field.')
+
+  def testInitRequiredKwargs(self):
+    proto = unittest_pb2.TestRequired(a=1, b=1, c=1)
+    self.assertTrue(proto.IsInitialized())
+    self.assertTrue(proto.HasField('a'))
+    self.assertTrue(proto.HasField('b'))
+    self.assertTrue(proto.HasField('c'))
+    self.assertTrue(not proto.HasField('dummy2'))
+    self.assertEqual(1, proto.a)
+    self.assertEqual(1, proto.b)
+    self.assertEqual(1, proto.c)
+
+  def testInitRequiredForeignKwargs(self):
+    proto = unittest_pb2.TestRequiredForeign(
+        optional_message=unittest_pb2.TestRequired(a=1, b=1, c=1))
+    self.assertTrue(proto.IsInitialized())
+    self.assertTrue(proto.HasField('optional_message'))
+    self.assertTrue(proto.optional_message.IsInitialized())
+    self.assertTrue(proto.optional_message.HasField('a'))
+    self.assertTrue(proto.optional_message.HasField('b'))
+    self.assertTrue(proto.optional_message.HasField('c'))
+    self.assertTrue(not proto.optional_message.HasField('dummy2'))
+    self.assertEqual(unittest_pb2.TestRequired(a=1, b=1, c=1),
+                     proto.optional_message)
+    self.assertEqual(1, proto.optional_message.a)
+    self.assertEqual(1, proto.optional_message.b)
+    self.assertEqual(1, proto.optional_message.c)
+
+  def testInitRepeatedKwargs(self):
+    proto = unittest_pb2.TestAllTypes(repeated_int32=[1, 2, 3])
+    self.assertTrue(proto.IsInitialized())
+    self.assertEqual(1, proto.repeated_int32[0])
+    self.assertEqual(2, proto.repeated_int32[1])
+    self.assertEqual(3, proto.repeated_int32[2])
+
+
+class OptionsTest(basetest.TestCase):
+
+  def testMessageOptions(self):
+    proto = unittest_mset_pb2.TestMessageSet()
+    self.assertEqual(True,
+                     proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+    proto = unittest_pb2.TestAllTypes()
+    self.assertEqual(False,
+                     proto.DESCRIPTOR.GetOptions().message_set_wire_format)
+
+  def testPackedOptions(self):
+    proto = unittest_pb2.TestAllTypes()
+    proto.optional_int32 = 1
+    proto.optional_double = 3.0
+    for field_descriptor, _ in proto.ListFields():
+      self.assertEqual(False, field_descriptor.GetOptions().packed)
+
+    proto = unittest_pb2.TestPackedTypes()
+    proto.packed_int32.append(1)
+    proto.packed_double.append(3.0)
+    for field_descriptor, _ in proto.ListFields():
+      self.assertEqual(True, field_descriptor.GetOptions().packed)
+      self.assertEqual(reflection._FieldDescriptor.LABEL_REPEATED,
+                       field_descriptor.label)
+
+
+
+class ClassAPITest(basetest.TestCase):
+
+  def testMakeClassWithNestedDescriptor(self):
+    leaf_desc = descriptor.Descriptor('leaf', 'package.parent.child.leaf', '',
+                                      containing_type=None, fields=[],
+                                      nested_types=[], enum_types=[],
+                                      extensions=[])
+    child_desc = descriptor.Descriptor('child', 'package.parent.child', '',
+                                       containing_type=None, fields=[],
+                                       nested_types=[leaf_desc], enum_types=[],
+                                       extensions=[])
+    sibling_desc = descriptor.Descriptor('sibling', 'package.parent.sibling',
+                                         '', containing_type=None, fields=[],
+                                         nested_types=[], enum_types=[],
+                                         extensions=[])
+    parent_desc = descriptor.Descriptor('parent', 'package.parent', '',
+                                        containing_type=None, fields=[],
+                                        nested_types=[child_desc, sibling_desc],
+                                        enum_types=[], extensions=[])
+    message_class = reflection.MakeClass(parent_desc)
+    self.assertIn('child', message_class.__dict__)
+    self.assertIn('sibling', message_class.__dict__)
+    self.assertIn('leaf', message_class.child.__dict__)
+
+  def _GetSerializedFileDescriptor(self, name):
+    """Get a serialized representation of a test FileDescriptorProto.
+
+    Args:
+      name: All calls to this must use a unique message name, to avoid
+          collisions in the cpp descriptor pool.
+    Returns:
+      A string containing the serialized form of a test FileDescriptorProto.
+    """
+    file_descriptor_str = (
+        'message_type {'
+        '  name: "' + name + '"'
+        '  field {'
+        '    name: "flat"'
+        '    number: 1'
+        '    label: LABEL_REPEATED'
+        '    type: TYPE_UINT32'
+        '  }'
+        '  field {'
+        '    name: "bar"'
+        '    number: 2'
+        '    label: LABEL_OPTIONAL'
+        '    type: TYPE_MESSAGE'
+        '    type_name: "Bar"'
+        '  }'
+        '  nested_type {'
+        '    name: "Bar"'
+        '    field {'
+        '      name: "baz"'
+        '      number: 3'
+        '      label: LABEL_OPTIONAL'
+        '      type: TYPE_MESSAGE'
+        '      type_name: "Baz"'
+        '    }'
+        '    nested_type {'
+        '      name: "Baz"'
+        '      enum_type {'
+        '        name: "deep_enum"'
+        '        value {'
+        '          name: "VALUE_A"'
+        '          number: 0'
+        '        }'
+        '      }'
+        '      field {'
+        '        name: "deep"'
+        '        number: 4'
+        '        label: LABEL_OPTIONAL'
+        '        type: TYPE_UINT32'
+        '      }'
+        '    }'
+        '  }'
+        '}')
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    text_format.Merge(file_descriptor_str, file_descriptor)
+    return file_descriptor.SerializeToString()
+
+  def testParsingFlatClassWithExplicitClassDeclaration(self):
+    """Test that the generated class can parse a flat message."""
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('A'))
+    msg_descriptor = descriptor.MakeDescriptor(
+        file_descriptor.message_type[0])
+
+    class MessageClass(message.Message):
+      __metaclass__ = reflection.GeneratedProtocolMessageType
+      DESCRIPTOR = msg_descriptor
+    msg = MessageClass()
+    msg_str = (
+        'flat: 0 '
+        'flat: 1 '
+        'flat: 2 ')
+    text_format.Merge(msg_str, msg)
+    self.assertEqual(msg.flat, [0, 1, 2])
+
+  def testParsingFlatClass(self):
+    """Test that the generated class can parse a flat message."""
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('B'))
+    msg_descriptor = descriptor.MakeDescriptor(
+        file_descriptor.message_type[0])
+    msg_class = reflection.MakeClass(msg_descriptor)
+    msg = msg_class()
+    msg_str = (
+        'flat: 0 '
+        'flat: 1 '
+        'flat: 2 ')
+    text_format.Merge(msg_str, msg)
+    self.assertEqual(msg.flat, [0, 1, 2])
+
+  def testParsingNestedClass(self):
+    """Test that the generated class can parse a nested message."""
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    file_descriptor.ParseFromString(self._GetSerializedFileDescriptor('C'))
+    msg_descriptor = descriptor.MakeDescriptor(
+        file_descriptor.message_type[0])
+    msg_class = reflection.MakeClass(msg_descriptor)
+    msg = msg_class()
+    msg_str = (
+        'bar {'
+        '  baz {'
+        '    deep: 4'
+        '  }'
+        '}')
+    text_format.Merge(msg_str, msg)
+    self.assertEqual(msg.bar.baz.deep, 4)
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/service_reflection_test.py b/protobuf/python/google/protobuf/internal/service_reflection_test.py
new file mode 100755
index 0000000..07dcf44
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/service_reflection_test.py
@@ -0,0 +1,136 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.internal.service_reflection."""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+from google.apputils import basetest
+from google.protobuf import unittest_pb2
+from google.protobuf import service_reflection
+from google.protobuf import service
+
+
+class FooUnitTest(basetest.TestCase):
+
+  def testService(self):
+    class MockRpcChannel(service.RpcChannel):
+      def CallMethod(self, method, controller, request, response, callback):
+        self.method = method
+        self.controller = controller
+        self.request = request
+        callback(response)
+
+    class MockRpcController(service.RpcController):
+      def SetFailed(self, msg):
+        self.failure_message = msg
+
+    self.callback_response = None
+
+    class MyService(unittest_pb2.TestService):
+      pass
+
+    self.callback_response = None
+
+    def MyCallback(response):
+      self.callback_response = response
+
+    rpc_controller = MockRpcController()
+    channel = MockRpcChannel()
+    srvc = MyService()
+    srvc.Foo(rpc_controller, unittest_pb2.FooRequest(), MyCallback)
+    self.assertEqual('Method Foo not implemented.',
+                     rpc_controller.failure_message)
+    self.assertEqual(None, self.callback_response)
+
+    rpc_controller.failure_message = None
+
+    service_descriptor = unittest_pb2.TestService.GetDescriptor()
+    srvc.CallMethod(service_descriptor.methods[1], rpc_controller,
+                    unittest_pb2.BarRequest(), MyCallback)
+    self.assertEqual('Method Bar not implemented.',
+                     rpc_controller.failure_message)
+    self.assertEqual(None, self.callback_response)
+    
+    class MyServiceImpl(unittest_pb2.TestService):
+      def Foo(self, rpc_controller, request, done):
+        self.foo_called = True
+      def Bar(self, rpc_controller, request, done):
+        self.bar_called = True
+
+    srvc = MyServiceImpl()
+    rpc_controller.failure_message = None
+    srvc.Foo(rpc_controller, unittest_pb2.FooRequest(), MyCallback)
+    self.assertEqual(None, rpc_controller.failure_message)
+    self.assertEqual(True, srvc.foo_called)
+
+    rpc_controller.failure_message = None
+    srvc.CallMethod(service_descriptor.methods[1], rpc_controller,
+                    unittest_pb2.BarRequest(), MyCallback)
+    self.assertEqual(None, rpc_controller.failure_message)
+    self.assertEqual(True, srvc.bar_called)
+
+  def testServiceStub(self):
+    class MockRpcChannel(service.RpcChannel):
+      def CallMethod(self, method, controller, request,
+                     response_class, callback):
+        self.method = method
+        self.controller = controller
+        self.request = request
+        callback(response_class())
+
+    self.callback_response = None
+
+    def MyCallback(response):
+      self.callback_response = response
+
+    channel = MockRpcChannel()
+    stub = unittest_pb2.TestService_Stub(channel)
+    rpc_controller = 'controller'
+    request = 'request'
+
+    # GetDescriptor now static, still works as instance method for compatability
+    self.assertEqual(unittest_pb2.TestService_Stub.GetDescriptor(),
+                     stub.GetDescriptor())
+
+    # Invoke method.
+    stub.Foo(rpc_controller, request, MyCallback)
+
+    self.assertTrue(isinstance(self.callback_response,
+                               unittest_pb2.FooResponse))
+    self.assertEqual(request, channel.request)
+    self.assertEqual(rpc_controller, channel.controller)
+    self.assertEqual(stub.GetDescriptor().methods[0], channel.method)
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/symbol_database_test.py b/protobuf/python/google/protobuf/internal/symbol_database_test.py
new file mode 100644
index 0000000..47572d5
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/symbol_database_test.py
@@ -0,0 +1,120 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.symbol_database."""
+
+from google.apputils import basetest
+from google.protobuf import unittest_pb2
+from google.protobuf import symbol_database
+
+
+class SymbolDatabaseTest(basetest.TestCase):
+
+  def _Database(self):
+    db = symbol_database.SymbolDatabase()
+    # Register representative types from unittest_pb2.
+    db.RegisterFileDescriptor(unittest_pb2.DESCRIPTOR)
+    db.RegisterMessage(unittest_pb2.TestAllTypes)
+    db.RegisterMessage(unittest_pb2.TestAllTypes.NestedMessage)
+    db.RegisterMessage(unittest_pb2.TestAllTypes.OptionalGroup)
+    db.RegisterMessage(unittest_pb2.TestAllTypes.RepeatedGroup)
+    db.RegisterEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR)
+    db.RegisterEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR)
+    return db
+
+  def testGetPrototype(self):
+    instance = self._Database().GetPrototype(
+        unittest_pb2.TestAllTypes.DESCRIPTOR)
+    self.assertTrue(instance is unittest_pb2.TestAllTypes)
+
+  def testGetMessages(self):
+    messages = self._Database().GetMessages(
+        ['google/protobuf/unittest.proto'])
+    self.assertTrue(
+        unittest_pb2.TestAllTypes is
+        messages['protobuf_unittest.TestAllTypes'])
+
+  def testGetSymbol(self):
+    self.assertEquals(
+        unittest_pb2.TestAllTypes, self._Database().GetSymbol(
+            'protobuf_unittest.TestAllTypes'))
+    self.assertEquals(
+        unittest_pb2.TestAllTypes.NestedMessage, self._Database().GetSymbol(
+            'protobuf_unittest.TestAllTypes.NestedMessage'))
+    self.assertEquals(
+        unittest_pb2.TestAllTypes.OptionalGroup, self._Database().GetSymbol(
+            'protobuf_unittest.TestAllTypes.OptionalGroup'))
+    self.assertEquals(
+        unittest_pb2.TestAllTypes.RepeatedGroup, self._Database().GetSymbol(
+            'protobuf_unittest.TestAllTypes.RepeatedGroup'))
+
+  def testEnums(self):
+    # Check registration of types in the pool.
+    self.assertEquals(
+        'protobuf_unittest.ForeignEnum',
+        self._Database().pool.FindEnumTypeByName(
+            'protobuf_unittest.ForeignEnum').full_name)
+    self.assertEquals(
+        'protobuf_unittest.TestAllTypes.NestedEnum',
+        self._Database().pool.FindEnumTypeByName(
+            'protobuf_unittest.TestAllTypes.NestedEnum').full_name)
+
+  def testFindMessageTypeByName(self):
+    self.assertEquals(
+        'protobuf_unittest.TestAllTypes',
+        self._Database().pool.FindMessageTypeByName(
+            'protobuf_unittest.TestAllTypes').full_name)
+    self.assertEquals(
+        'protobuf_unittest.TestAllTypes.NestedMessage',
+        self._Database().pool.FindMessageTypeByName(
+            'protobuf_unittest.TestAllTypes.NestedMessage').full_name)
+
+  def testFindFindContainingSymbol(self):
+    # Lookup based on either enum or message.
+    self.assertEquals(
+        'google/protobuf/unittest.proto',
+        self._Database().pool.FindFileContainingSymbol(
+            'protobuf_unittest.TestAllTypes.NestedEnum').name)
+    self.assertEquals(
+        'google/protobuf/unittest.proto',
+        self._Database().pool.FindFileContainingSymbol(
+            'protobuf_unittest.TestAllTypes').name)
+
+  def testFindFileByName(self):
+    self.assertEquals(
+        'google/protobuf/unittest.proto',
+        self._Database().pool.FindFileByName(
+            'google/protobuf/unittest.proto').name)
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/test_bad_identifiers.proto b/protobuf/python/google/protobuf/internal/test_bad_identifiers.proto
new file mode 100644
index 0000000..9eb18cb
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/test_bad_identifiers.proto
@@ -0,0 +1,52 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+
+package protobuf_unittest;
+
+option py_generic_services = true;
+
+message TestBadIdentifiers {
+  extensions 100 to max;
+}
+
+// Make sure these reasonable extension names don't conflict with internal
+// variables.
+extend TestBadIdentifiers {
+  optional string message = 100 [default="foo"];
+  optional string descriptor = 101 [default="bar"];
+  optional string reflection = 102 [default="baz"];
+  optional string service = 103 [default="qux"];
+}
+
+message AnotherMessage {}
+service AnotherService {}
diff --git a/protobuf/python/google/protobuf/internal/test_util.py b/protobuf/python/google/protobuf/internal/test_util.py
new file mode 100755
index 0000000..787f465
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/test_util.py
@@ -0,0 +1,662 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Utilities for Python proto2 tests.
+
+This is intentionally modeled on C++ code in
+//google/protobuf/test_util.*.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import os.path
+
+from google.protobuf import unittest_import_pb2
+from google.protobuf import unittest_pb2
+
+
+def SetAllNonLazyFields(message):
+  """Sets every non-lazy field in the message to a unique value.
+
+  Args:
+    message: A unittest_pb2.TestAllTypes instance.
+  """
+
+  #
+  # Optional fields.
+  #
+
+  message.optional_int32    = 101
+  message.optional_int64    = 102
+  message.optional_uint32   = 103
+  message.optional_uint64   = 104
+  message.optional_sint32   = 105
+  message.optional_sint64   = 106
+  message.optional_fixed32  = 107
+  message.optional_fixed64  = 108
+  message.optional_sfixed32 = 109
+  message.optional_sfixed64 = 110
+  message.optional_float    = 111
+  message.optional_double   = 112
+  message.optional_bool     = True
+  message.optional_string   = u'115'
+  message.optional_bytes    = b'116'
+
+  message.optionalgroup.a = 117
+  message.optional_nested_message.bb = 118
+  message.optional_foreign_message.c = 119
+  message.optional_import_message.d = 120
+  message.optional_public_import_message.e = 126
+
+  message.optional_nested_enum = unittest_pb2.TestAllTypes.BAZ
+  message.optional_foreign_enum = unittest_pb2.FOREIGN_BAZ
+  message.optional_import_enum = unittest_import_pb2.IMPORT_BAZ
+
+  message.optional_string_piece = u'124'
+  message.optional_cord = u'125'
+
+  #
+  # Repeated fields.
+  #
+
+  message.repeated_int32.append(201)
+  message.repeated_int64.append(202)
+  message.repeated_uint32.append(203)
+  message.repeated_uint64.append(204)
+  message.repeated_sint32.append(205)
+  message.repeated_sint64.append(206)
+  message.repeated_fixed32.append(207)
+  message.repeated_fixed64.append(208)
+  message.repeated_sfixed32.append(209)
+  message.repeated_sfixed64.append(210)
+  message.repeated_float.append(211)
+  message.repeated_double.append(212)
+  message.repeated_bool.append(True)
+  message.repeated_string.append(u'215')
+  message.repeated_bytes.append(b'216')
+
+  message.repeatedgroup.add().a = 217
+  message.repeated_nested_message.add().bb = 218
+  message.repeated_foreign_message.add().c = 219
+  message.repeated_import_message.add().d = 220
+  message.repeated_lazy_message.add().bb = 227
+
+  message.repeated_nested_enum.append(unittest_pb2.TestAllTypes.BAR)
+  message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_BAR)
+  message.repeated_import_enum.append(unittest_import_pb2.IMPORT_BAR)
+
+  message.repeated_string_piece.append(u'224')
+  message.repeated_cord.append(u'225')
+
+  # Add a second one of each field.
+  message.repeated_int32.append(301)
+  message.repeated_int64.append(302)
+  message.repeated_uint32.append(303)
+  message.repeated_uint64.append(304)
+  message.repeated_sint32.append(305)
+  message.repeated_sint64.append(306)
+  message.repeated_fixed32.append(307)
+  message.repeated_fixed64.append(308)
+  message.repeated_sfixed32.append(309)
+  message.repeated_sfixed64.append(310)
+  message.repeated_float.append(311)
+  message.repeated_double.append(312)
+  message.repeated_bool.append(False)
+  message.repeated_string.append(u'315')
+  message.repeated_bytes.append(b'316')
+
+  message.repeatedgroup.add().a = 317
+  message.repeated_nested_message.add().bb = 318
+  message.repeated_foreign_message.add().c = 319
+  message.repeated_import_message.add().d = 320
+  message.repeated_lazy_message.add().bb = 327
+
+  message.repeated_nested_enum.append(unittest_pb2.TestAllTypes.BAZ)
+  message.repeated_foreign_enum.append(unittest_pb2.FOREIGN_BAZ)
+  message.repeated_import_enum.append(unittest_import_pb2.IMPORT_BAZ)
+
+  message.repeated_string_piece.append(u'324')
+  message.repeated_cord.append(u'325')
+
+  #
+  # Fields that have defaults.
+  #
+
+  message.default_int32 = 401
+  message.default_int64 = 402
+  message.default_uint32 = 403
+  message.default_uint64 = 404
+  message.default_sint32 = 405
+  message.default_sint64 = 406
+  message.default_fixed32 = 407
+  message.default_fixed64 = 408
+  message.default_sfixed32 = 409
+  message.default_sfixed64 = 410
+  message.default_float = 411
+  message.default_double = 412
+  message.default_bool = False
+  message.default_string = '415'
+  message.default_bytes = b'416'
+
+  message.default_nested_enum = unittest_pb2.TestAllTypes.FOO
+  message.default_foreign_enum = unittest_pb2.FOREIGN_FOO
+  message.default_import_enum = unittest_import_pb2.IMPORT_FOO
+
+  message.default_string_piece = '424'
+  message.default_cord = '425'
+
+  message.oneof_uint32 = 601
+  message.oneof_nested_message.bb = 602
+  message.oneof_string = '603'
+  message.oneof_bytes = b'604'
+
+
+def SetAllFields(message):
+  SetAllNonLazyFields(message)
+  message.optional_lazy_message.bb = 127
+
+
+def SetAllExtensions(message):
+  """Sets every extension in the message to a unique value.
+
+  Args:
+    message: A unittest_pb2.TestAllExtensions instance.
+  """
+
+  extensions = message.Extensions
+  pb2 = unittest_pb2
+  import_pb2 = unittest_import_pb2
+
+  #
+  # Optional fields.
+  #
+
+  extensions[pb2.optional_int32_extension] = 101
+  extensions[pb2.optional_int64_extension] = 102
+  extensions[pb2.optional_uint32_extension] = 103
+  extensions[pb2.optional_uint64_extension] = 104
+  extensions[pb2.optional_sint32_extension] = 105
+  extensions[pb2.optional_sint64_extension] = 106
+  extensions[pb2.optional_fixed32_extension] = 107
+  extensions[pb2.optional_fixed64_extension] = 108
+  extensions[pb2.optional_sfixed32_extension] = 109
+  extensions[pb2.optional_sfixed64_extension] = 110
+  extensions[pb2.optional_float_extension] = 111
+  extensions[pb2.optional_double_extension] = 112
+  extensions[pb2.optional_bool_extension] = True
+  extensions[pb2.optional_string_extension] = u'115'
+  extensions[pb2.optional_bytes_extension] = b'116'
+
+  extensions[pb2.optionalgroup_extension].a = 117
+  extensions[pb2.optional_nested_message_extension].bb = 118
+  extensions[pb2.optional_foreign_message_extension].c = 119
+  extensions[pb2.optional_import_message_extension].d = 120
+  extensions[pb2.optional_public_import_message_extension].e = 126
+  extensions[pb2.optional_lazy_message_extension].bb = 127
+
+  extensions[pb2.optional_nested_enum_extension] = pb2.TestAllTypes.BAZ
+  extensions[pb2.optional_nested_enum_extension] = pb2.TestAllTypes.BAZ
+  extensions[pb2.optional_foreign_enum_extension] = pb2.FOREIGN_BAZ
+  extensions[pb2.optional_import_enum_extension] = import_pb2.IMPORT_BAZ
+
+  extensions[pb2.optional_string_piece_extension] = u'124'
+  extensions[pb2.optional_cord_extension] = u'125'
+
+  #
+  # Repeated fields.
+  #
+
+  extensions[pb2.repeated_int32_extension].append(201)
+  extensions[pb2.repeated_int64_extension].append(202)
+  extensions[pb2.repeated_uint32_extension].append(203)
+  extensions[pb2.repeated_uint64_extension].append(204)
+  extensions[pb2.repeated_sint32_extension].append(205)
+  extensions[pb2.repeated_sint64_extension].append(206)
+  extensions[pb2.repeated_fixed32_extension].append(207)
+  extensions[pb2.repeated_fixed64_extension].append(208)
+  extensions[pb2.repeated_sfixed32_extension].append(209)
+  extensions[pb2.repeated_sfixed64_extension].append(210)
+  extensions[pb2.repeated_float_extension].append(211)
+  extensions[pb2.repeated_double_extension].append(212)
+  extensions[pb2.repeated_bool_extension].append(True)
+  extensions[pb2.repeated_string_extension].append(u'215')
+  extensions[pb2.repeated_bytes_extension].append(b'216')
+
+  extensions[pb2.repeatedgroup_extension].add().a = 217
+  extensions[pb2.repeated_nested_message_extension].add().bb = 218
+  extensions[pb2.repeated_foreign_message_extension].add().c = 219
+  extensions[pb2.repeated_import_message_extension].add().d = 220
+  extensions[pb2.repeated_lazy_message_extension].add().bb = 227
+
+  extensions[pb2.repeated_nested_enum_extension].append(pb2.TestAllTypes.BAR)
+  extensions[pb2.repeated_foreign_enum_extension].append(pb2.FOREIGN_BAR)
+  extensions[pb2.repeated_import_enum_extension].append(import_pb2.IMPORT_BAR)
+
+  extensions[pb2.repeated_string_piece_extension].append(u'224')
+  extensions[pb2.repeated_cord_extension].append(u'225')
+
+  # Append a second one of each field.
+  extensions[pb2.repeated_int32_extension].append(301)
+  extensions[pb2.repeated_int64_extension].append(302)
+  extensions[pb2.repeated_uint32_extension].append(303)
+  extensions[pb2.repeated_uint64_extension].append(304)
+  extensions[pb2.repeated_sint32_extension].append(305)
+  extensions[pb2.repeated_sint64_extension].append(306)
+  extensions[pb2.repeated_fixed32_extension].append(307)
+  extensions[pb2.repeated_fixed64_extension].append(308)
+  extensions[pb2.repeated_sfixed32_extension].append(309)
+  extensions[pb2.repeated_sfixed64_extension].append(310)
+  extensions[pb2.repeated_float_extension].append(311)
+  extensions[pb2.repeated_double_extension].append(312)
+  extensions[pb2.repeated_bool_extension].append(False)
+  extensions[pb2.repeated_string_extension].append(u'315')
+  extensions[pb2.repeated_bytes_extension].append(b'316')
+
+  extensions[pb2.repeatedgroup_extension].add().a = 317
+  extensions[pb2.repeated_nested_message_extension].add().bb = 318
+  extensions[pb2.repeated_foreign_message_extension].add().c = 319
+  extensions[pb2.repeated_import_message_extension].add().d = 320
+  extensions[pb2.repeated_lazy_message_extension].add().bb = 327
+
+  extensions[pb2.repeated_nested_enum_extension].append(pb2.TestAllTypes.BAZ)
+  extensions[pb2.repeated_foreign_enum_extension].append(pb2.FOREIGN_BAZ)
+  extensions[pb2.repeated_import_enum_extension].append(import_pb2.IMPORT_BAZ)
+
+  extensions[pb2.repeated_string_piece_extension].append(u'324')
+  extensions[pb2.repeated_cord_extension].append(u'325')
+
+  #
+  # Fields with defaults.
+  #
+
+  extensions[pb2.default_int32_extension] = 401
+  extensions[pb2.default_int64_extension] = 402
+  extensions[pb2.default_uint32_extension] = 403
+  extensions[pb2.default_uint64_extension] = 404
+  extensions[pb2.default_sint32_extension] = 405
+  extensions[pb2.default_sint64_extension] = 406
+  extensions[pb2.default_fixed32_extension] = 407
+  extensions[pb2.default_fixed64_extension] = 408
+  extensions[pb2.default_sfixed32_extension] = 409
+  extensions[pb2.default_sfixed64_extension] = 410
+  extensions[pb2.default_float_extension] = 411
+  extensions[pb2.default_double_extension] = 412
+  extensions[pb2.default_bool_extension] = False
+  extensions[pb2.default_string_extension] = u'415'
+  extensions[pb2.default_bytes_extension] = b'416'
+
+  extensions[pb2.default_nested_enum_extension] = pb2.TestAllTypes.FOO
+  extensions[pb2.default_foreign_enum_extension] = pb2.FOREIGN_FOO
+  extensions[pb2.default_import_enum_extension] = import_pb2.IMPORT_FOO
+
+  extensions[pb2.default_string_piece_extension] = u'424'
+  extensions[pb2.default_cord_extension] = '425'
+
+  extensions[pb2.oneof_uint32_extension] = 601
+  extensions[pb2.oneof_nested_message_extension].bb = 602
+  extensions[pb2.oneof_string_extension] = u'603'
+  extensions[pb2.oneof_bytes_extension] = b'604'
+
+
+def SetAllFieldsAndExtensions(message):
+  """Sets every field and extension in the message to a unique value.
+
+  Args:
+    message: A unittest_pb2.TestAllExtensions message.
+  """
+  message.my_int = 1
+  message.my_string = 'foo'
+  message.my_float = 1.0
+  message.Extensions[unittest_pb2.my_extension_int] = 23
+  message.Extensions[unittest_pb2.my_extension_string] = 'bar'
+
+
+def ExpectAllFieldsAndExtensionsInOrder(serialized):
+  """Ensures that serialized is the serialization we expect for a message
+  filled with SetAllFieldsAndExtensions().  (Specifically, ensures that the
+  serialization is in canonical, tag-number order).
+  """
+  my_extension_int = unittest_pb2.my_extension_int
+  my_extension_string = unittest_pb2.my_extension_string
+  expected_strings = []
+  message = unittest_pb2.TestFieldOrderings()
+  message.my_int = 1  # Field 1.
+  expected_strings.append(message.SerializeToString())
+  message.Clear()
+  message.Extensions[my_extension_int] = 23  # Field 5.
+  expected_strings.append(message.SerializeToString())
+  message.Clear()
+  message.my_string = 'foo'  # Field 11.
+  expected_strings.append(message.SerializeToString())
+  message.Clear()
+  message.Extensions[my_extension_string] = 'bar'  # Field 50.
+  expected_strings.append(message.SerializeToString())
+  message.Clear()
+  message.my_float = 1.0
+  expected_strings.append(message.SerializeToString())
+  message.Clear()
+  expected = b''.join(expected_strings)
+
+  if expected != serialized:
+    raise ValueError('Expected %r, found %r' % (expected, serialized))
+
+
+def ExpectAllFieldsSet(test_case, message):
+  """Check all fields for correct values have after Set*Fields() is called."""
+  test_case.assertTrue(message.HasField('optional_int32'))
+  test_case.assertTrue(message.HasField('optional_int64'))
+  test_case.assertTrue(message.HasField('optional_uint32'))
+  test_case.assertTrue(message.HasField('optional_uint64'))
+  test_case.assertTrue(message.HasField('optional_sint32'))
+  test_case.assertTrue(message.HasField('optional_sint64'))
+  test_case.assertTrue(message.HasField('optional_fixed32'))
+  test_case.assertTrue(message.HasField('optional_fixed64'))
+  test_case.assertTrue(message.HasField('optional_sfixed32'))
+  test_case.assertTrue(message.HasField('optional_sfixed64'))
+  test_case.assertTrue(message.HasField('optional_float'))
+  test_case.assertTrue(message.HasField('optional_double'))
+  test_case.assertTrue(message.HasField('optional_bool'))
+  test_case.assertTrue(message.HasField('optional_string'))
+  test_case.assertTrue(message.HasField('optional_bytes'))
+
+  test_case.assertTrue(message.HasField('optionalgroup'))
+  test_case.assertTrue(message.HasField('optional_nested_message'))
+  test_case.assertTrue(message.HasField('optional_foreign_message'))
+  test_case.assertTrue(message.HasField('optional_import_message'))
+
+  test_case.assertTrue(message.optionalgroup.HasField('a'))
+  test_case.assertTrue(message.optional_nested_message.HasField('bb'))
+  test_case.assertTrue(message.optional_foreign_message.HasField('c'))
+  test_case.assertTrue(message.optional_import_message.HasField('d'))
+
+  test_case.assertTrue(message.HasField('optional_nested_enum'))
+  test_case.assertTrue(message.HasField('optional_foreign_enum'))
+  test_case.assertTrue(message.HasField('optional_import_enum'))
+
+  test_case.assertTrue(message.HasField('optional_string_piece'))
+  test_case.assertTrue(message.HasField('optional_cord'))
+
+  test_case.assertEqual(101, message.optional_int32)
+  test_case.assertEqual(102, message.optional_int64)
+  test_case.assertEqual(103, message.optional_uint32)
+  test_case.assertEqual(104, message.optional_uint64)
+  test_case.assertEqual(105, message.optional_sint32)
+  test_case.assertEqual(106, message.optional_sint64)
+  test_case.assertEqual(107, message.optional_fixed32)
+  test_case.assertEqual(108, message.optional_fixed64)
+  test_case.assertEqual(109, message.optional_sfixed32)
+  test_case.assertEqual(110, message.optional_sfixed64)
+  test_case.assertEqual(111, message.optional_float)
+  test_case.assertEqual(112, message.optional_double)
+  test_case.assertEqual(True, message.optional_bool)
+  test_case.assertEqual('115', message.optional_string)
+  test_case.assertEqual(b'116', message.optional_bytes)
+
+  test_case.assertEqual(117, message.optionalgroup.a)
+  test_case.assertEqual(118, message.optional_nested_message.bb)
+  test_case.assertEqual(119, message.optional_foreign_message.c)
+  test_case.assertEqual(120, message.optional_import_message.d)
+  test_case.assertEqual(126, message.optional_public_import_message.e)
+  test_case.assertEqual(127, message.optional_lazy_message.bb)
+
+  test_case.assertEqual(unittest_pb2.TestAllTypes.BAZ,
+                        message.optional_nested_enum)
+  test_case.assertEqual(unittest_pb2.FOREIGN_BAZ,
+                        message.optional_foreign_enum)
+  test_case.assertEqual(unittest_import_pb2.IMPORT_BAZ,
+                        message.optional_import_enum)
+
+  # -----------------------------------------------------------------
+
+  test_case.assertEqual(2, len(message.repeated_int32))
+  test_case.assertEqual(2, len(message.repeated_int64))
+  test_case.assertEqual(2, len(message.repeated_uint32))
+  test_case.assertEqual(2, len(message.repeated_uint64))
+  test_case.assertEqual(2, len(message.repeated_sint32))
+  test_case.assertEqual(2, len(message.repeated_sint64))
+  test_case.assertEqual(2, len(message.repeated_fixed32))
+  test_case.assertEqual(2, len(message.repeated_fixed64))
+  test_case.assertEqual(2, len(message.repeated_sfixed32))
+  test_case.assertEqual(2, len(message.repeated_sfixed64))
+  test_case.assertEqual(2, len(message.repeated_float))
+  test_case.assertEqual(2, len(message.repeated_double))
+  test_case.assertEqual(2, len(message.repeated_bool))
+  test_case.assertEqual(2, len(message.repeated_string))
+  test_case.assertEqual(2, len(message.repeated_bytes))
+
+  test_case.assertEqual(2, len(message.repeatedgroup))
+  test_case.assertEqual(2, len(message.repeated_nested_message))
+  test_case.assertEqual(2, len(message.repeated_foreign_message))
+  test_case.assertEqual(2, len(message.repeated_import_message))
+  test_case.assertEqual(2, len(message.repeated_nested_enum))
+  test_case.assertEqual(2, len(message.repeated_foreign_enum))
+  test_case.assertEqual(2, len(message.repeated_import_enum))
+
+  test_case.assertEqual(2, len(message.repeated_string_piece))
+  test_case.assertEqual(2, len(message.repeated_cord))
+
+  test_case.assertEqual(201, message.repeated_int32[0])
+  test_case.assertEqual(202, message.repeated_int64[0])
+  test_case.assertEqual(203, message.repeated_uint32[0])
+  test_case.assertEqual(204, message.repeated_uint64[0])
+  test_case.assertEqual(205, message.repeated_sint32[0])
+  test_case.assertEqual(206, message.repeated_sint64[0])
+  test_case.assertEqual(207, message.repeated_fixed32[0])
+  test_case.assertEqual(208, message.repeated_fixed64[0])
+  test_case.assertEqual(209, message.repeated_sfixed32[0])
+  test_case.assertEqual(210, message.repeated_sfixed64[0])
+  test_case.assertEqual(211, message.repeated_float[0])
+  test_case.assertEqual(212, message.repeated_double[0])
+  test_case.assertEqual(True, message.repeated_bool[0])
+  test_case.assertEqual('215', message.repeated_string[0])
+  test_case.assertEqual(b'216', message.repeated_bytes[0])
+
+  test_case.assertEqual(217, message.repeatedgroup[0].a)
+  test_case.assertEqual(218, message.repeated_nested_message[0].bb)
+  test_case.assertEqual(219, message.repeated_foreign_message[0].c)
+  test_case.assertEqual(220, message.repeated_import_message[0].d)
+  test_case.assertEqual(227, message.repeated_lazy_message[0].bb)
+
+  test_case.assertEqual(unittest_pb2.TestAllTypes.BAR,
+                        message.repeated_nested_enum[0])
+  test_case.assertEqual(unittest_pb2.FOREIGN_BAR,
+                        message.repeated_foreign_enum[0])
+  test_case.assertEqual(unittest_import_pb2.IMPORT_BAR,
+                        message.repeated_import_enum[0])
+
+  test_case.assertEqual(301, message.repeated_int32[1])
+  test_case.assertEqual(302, message.repeated_int64[1])
+  test_case.assertEqual(303, message.repeated_uint32[1])
+  test_case.assertEqual(304, message.repeated_uint64[1])
+  test_case.assertEqual(305, message.repeated_sint32[1])
+  test_case.assertEqual(306, message.repeated_sint64[1])
+  test_case.assertEqual(307, message.repeated_fixed32[1])
+  test_case.assertEqual(308, message.repeated_fixed64[1])
+  test_case.assertEqual(309, message.repeated_sfixed32[1])
+  test_case.assertEqual(310, message.repeated_sfixed64[1])
+  test_case.assertEqual(311, message.repeated_float[1])
+  test_case.assertEqual(312, message.repeated_double[1])
+  test_case.assertEqual(False, message.repeated_bool[1])
+  test_case.assertEqual('315', message.repeated_string[1])
+  test_case.assertEqual(b'316', message.repeated_bytes[1])
+
+  test_case.assertEqual(317, message.repeatedgroup[1].a)
+  test_case.assertEqual(318, message.repeated_nested_message[1].bb)
+  test_case.assertEqual(319, message.repeated_foreign_message[1].c)
+  test_case.assertEqual(320, message.repeated_import_message[1].d)
+  test_case.assertEqual(327, message.repeated_lazy_message[1].bb)
+
+  test_case.assertEqual(unittest_pb2.TestAllTypes.BAZ,
+                        message.repeated_nested_enum[1])
+  test_case.assertEqual(unittest_pb2.FOREIGN_BAZ,
+                        message.repeated_foreign_enum[1])
+  test_case.assertEqual(unittest_import_pb2.IMPORT_BAZ,
+                        message.repeated_import_enum[1])
+
+  # -----------------------------------------------------------------
+
+  test_case.assertTrue(message.HasField('default_int32'))
+  test_case.assertTrue(message.HasField('default_int64'))
+  test_case.assertTrue(message.HasField('default_uint32'))
+  test_case.assertTrue(message.HasField('default_uint64'))
+  test_case.assertTrue(message.HasField('default_sint32'))
+  test_case.assertTrue(message.HasField('default_sint64'))
+  test_case.assertTrue(message.HasField('default_fixed32'))
+  test_case.assertTrue(message.HasField('default_fixed64'))
+  test_case.assertTrue(message.HasField('default_sfixed32'))
+  test_case.assertTrue(message.HasField('default_sfixed64'))
+  test_case.assertTrue(message.HasField('default_float'))
+  test_case.assertTrue(message.HasField('default_double'))
+  test_case.assertTrue(message.HasField('default_bool'))
+  test_case.assertTrue(message.HasField('default_string'))
+  test_case.assertTrue(message.HasField('default_bytes'))
+
+  test_case.assertTrue(message.HasField('default_nested_enum'))
+  test_case.assertTrue(message.HasField('default_foreign_enum'))
+  test_case.assertTrue(message.HasField('default_import_enum'))
+
+  test_case.assertEqual(401, message.default_int32)
+  test_case.assertEqual(402, message.default_int64)
+  test_case.assertEqual(403, message.default_uint32)
+  test_case.assertEqual(404, message.default_uint64)
+  test_case.assertEqual(405, message.default_sint32)
+  test_case.assertEqual(406, message.default_sint64)
+  test_case.assertEqual(407, message.default_fixed32)
+  test_case.assertEqual(408, message.default_fixed64)
+  test_case.assertEqual(409, message.default_sfixed32)
+  test_case.assertEqual(410, message.default_sfixed64)
+  test_case.assertEqual(411, message.default_float)
+  test_case.assertEqual(412, message.default_double)
+  test_case.assertEqual(False, message.default_bool)
+  test_case.assertEqual('415', message.default_string)
+  test_case.assertEqual(b'416', message.default_bytes)
+
+  test_case.assertEqual(unittest_pb2.TestAllTypes.FOO,
+                        message.default_nested_enum)
+  test_case.assertEqual(unittest_pb2.FOREIGN_FOO,
+                        message.default_foreign_enum)
+  test_case.assertEqual(unittest_import_pb2.IMPORT_FOO,
+                        message.default_import_enum)
+
+
+def GoldenFile(filename):
+  """Finds the given golden file and returns a file object representing it."""
+
+  # Search up the directory tree looking for the C++ protobuf source code.
+  path = '.'
+  while os.path.exists(path):
+    if os.path.exists(os.path.join(path, 'src/google/protobuf')):
+      # Found it.  Load the golden file from the testdata directory.
+      full_path = os.path.join(path, 'src/google/protobuf/testdata', filename)
+      return open(full_path, 'rb')
+    path = os.path.join(path, '..')
+
+  raise RuntimeError(
+      'Could not find golden files.  This test must be run from within the '
+      'protobuf source package so that it can read test data files from the '
+      'C++ source tree.')
+
+
+def GoldenFileData(filename):
+  """Finds the given golden file and returns its contents."""
+  with GoldenFile(filename) as f:
+    return f.read()
+
+
+def SetAllPackedFields(message):
+  """Sets every field in the message to a unique value.
+
+  Args:
+    message: A unittest_pb2.TestPackedTypes instance.
+  """
+  message.packed_int32.extend([601, 701])
+  message.packed_int64.extend([602, 702])
+  message.packed_uint32.extend([603, 703])
+  message.packed_uint64.extend([604, 704])
+  message.packed_sint32.extend([605, 705])
+  message.packed_sint64.extend([606, 706])
+  message.packed_fixed32.extend([607, 707])
+  message.packed_fixed64.extend([608, 708])
+  message.packed_sfixed32.extend([609, 709])
+  message.packed_sfixed64.extend([610, 710])
+  message.packed_float.extend([611.0, 711.0])
+  message.packed_double.extend([612.0, 712.0])
+  message.packed_bool.extend([True, False])
+  message.packed_enum.extend([unittest_pb2.FOREIGN_BAR,
+                              unittest_pb2.FOREIGN_BAZ])
+
+
+def SetAllPackedExtensions(message):
+  """Sets every extension in the message to a unique value.
+
+  Args:
+    message: A unittest_pb2.TestPackedExtensions instance.
+  """
+  extensions = message.Extensions
+  pb2 = unittest_pb2
+
+  extensions[pb2.packed_int32_extension].extend([601, 701])
+  extensions[pb2.packed_int64_extension].extend([602, 702])
+  extensions[pb2.packed_uint32_extension].extend([603, 703])
+  extensions[pb2.packed_uint64_extension].extend([604, 704])
+  extensions[pb2.packed_sint32_extension].extend([605, 705])
+  extensions[pb2.packed_sint64_extension].extend([606, 706])
+  extensions[pb2.packed_fixed32_extension].extend([607, 707])
+  extensions[pb2.packed_fixed64_extension].extend([608, 708])
+  extensions[pb2.packed_sfixed32_extension].extend([609, 709])
+  extensions[pb2.packed_sfixed64_extension].extend([610, 710])
+  extensions[pb2.packed_float_extension].extend([611.0, 711.0])
+  extensions[pb2.packed_double_extension].extend([612.0, 712.0])
+  extensions[pb2.packed_bool_extension].extend([True, False])
+  extensions[pb2.packed_enum_extension].extend([unittest_pb2.FOREIGN_BAR,
+                                                unittest_pb2.FOREIGN_BAZ])
+
+
+def SetAllUnpackedFields(message):
+  """Sets every field in the message to a unique value.
+
+  Args:
+    message: A unittest_pb2.TestUnpackedTypes instance.
+  """
+  message.unpacked_int32.extend([601, 701])
+  message.unpacked_int64.extend([602, 702])
+  message.unpacked_uint32.extend([603, 703])
+  message.unpacked_uint64.extend([604, 704])
+  message.unpacked_sint32.extend([605, 705])
+  message.unpacked_sint64.extend([606, 706])
+  message.unpacked_fixed32.extend([607, 707])
+  message.unpacked_fixed64.extend([608, 708])
+  message.unpacked_sfixed32.extend([609, 709])
+  message.unpacked_sfixed64.extend([610, 710])
+  message.unpacked_float.extend([611.0, 711.0])
+  message.unpacked_double.extend([612.0, 712.0])
+  message.unpacked_bool.extend([True, False])
+  message.unpacked_enum.extend([unittest_pb2.FOREIGN_BAR,
+                                unittest_pb2.FOREIGN_BAZ])
diff --git a/protobuf/python/google/protobuf/internal/text_encoding_test.py b/protobuf/python/google/protobuf/internal/text_encoding_test.py
new file mode 100755
index 0000000..db0222b
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/text_encoding_test.py
@@ -0,0 +1,68 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.text_encoding."""
+
+from google.apputils import basetest
+from google.protobuf import text_encoding
+
+TEST_VALUES = [
+    ("foo\\rbar\\nbaz\\t",
+     "foo\\rbar\\nbaz\\t",
+     b"foo\rbar\nbaz\t"),
+    ("\\'full of \\\"sound\\\" and \\\"fury\\\"\\'",
+     "\\'full of \\\"sound\\\" and \\\"fury\\\"\\'",
+     b"'full of \"sound\" and \"fury\"'"),
+    ("signi\\\\fying\\\\ nothing\\\\",
+     "signi\\\\fying\\\\ nothing\\\\",
+     b"signi\\fying\\ nothing\\"),
+    ("\\010\\t\\n\\013\\014\\r",
+     "\x08\\t\\n\x0b\x0c\\r",
+     b"\010\011\012\013\014\015")]
+
+
+class TextEncodingTestCase(basetest.TestCase):
+  def testCEscape(self):
+    for escaped, escaped_utf8, unescaped in TEST_VALUES:
+      self.assertEquals(escaped,
+                        text_encoding.CEscape(unescaped, as_utf8=False))
+      self.assertEquals(escaped_utf8,
+                        text_encoding.CEscape(unescaped, as_utf8=True))
+
+  def testCUnescape(self):
+    for escaped, escaped_utf8, unescaped in TEST_VALUES:
+      self.assertEquals(unescaped, text_encoding.CUnescape(escaped))
+      self.assertEquals(unescaped, text_encoding.CUnescape(escaped_utf8))
+
+
+if __name__ == "__main__":
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/text_format_test.py b/protobuf/python/google/protobuf/internal/text_format_test.py
new file mode 100755
index 0000000..b0a3a5f
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/text_format_test.py
@@ -0,0 +1,743 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Test for google.protobuf.text_format."""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+import re
+
+from google.apputils import basetest
+from google.protobuf import text_format
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import test_util
+from google.protobuf import unittest_pb2
+from google.protobuf import unittest_mset_pb2
+
+class TextFormatTest(basetest.TestCase):
+
+  def ReadGolden(self, golden_filename):
+    with test_util.GoldenFile(golden_filename) as f:
+      return (f.readlines() if str is bytes else  # PY3
+              [golden_line.decode('utf-8') for golden_line in f])
+
+  def CompareToGoldenFile(self, text, golden_filename):
+    golden_lines = self.ReadGolden(golden_filename)
+    self.assertMultiLineEqual(text, ''.join(golden_lines))
+
+  def CompareToGoldenText(self, text, golden_text):
+    self.assertMultiLineEqual(text, golden_text)
+
+  def testPrintAllFields(self):
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    self.CompareToGoldenFile(
+        self.RemoveRedundantZeros(text_format.MessageToString(message)),
+        'text_format_unittest_data_oneof_implemented.txt')
+
+  def testPrintInIndexOrder(self):
+    message = unittest_pb2.TestFieldOrderings()
+    message.my_string = '115'
+    message.my_int = 101
+    message.my_float = 111
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_format.MessageToString(
+            message, use_index_order=True)),
+        'my_string: \"115\"\nmy_int: 101\nmy_float: 111\n')
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_format.MessageToString(
+            message)), 'my_int: 101\nmy_string: \"115\"\nmy_float: 111\n')
+
+  def testPrintAllExtensions(self):
+    message = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(message)
+    self.CompareToGoldenFile(
+        self.RemoveRedundantZeros(text_format.MessageToString(message)),
+        'text_format_unittest_extensions_data.txt')
+
+  def testPrintAllFieldsPointy(self):
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    self.CompareToGoldenFile(
+        self.RemoveRedundantZeros(
+            text_format.MessageToString(message, pointy_brackets=True)),
+        'text_format_unittest_data_pointy_oneof.txt')
+
+  def testPrintAllExtensionsPointy(self):
+    message = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(message)
+    self.CompareToGoldenFile(
+        self.RemoveRedundantZeros(text_format.MessageToString(
+            message, pointy_brackets=True)),
+        'text_format_unittest_extensions_data_pointy.txt')
+
+  def testPrintMessageSet(self):
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+    ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+    message.message_set.Extensions[ext1].i = 23
+    message.message_set.Extensions[ext2].str = 'foo'
+    self.CompareToGoldenText(
+        text_format.MessageToString(message),
+        'message_set {\n'
+        '  [protobuf_unittest.TestMessageSetExtension1] {\n'
+        '    i: 23\n'
+        '  }\n'
+        '  [protobuf_unittest.TestMessageSetExtension2] {\n'
+        '    str: \"foo\"\n'
+        '  }\n'
+        '}\n')
+
+  def testPrintExotic(self):
+    message = unittest_pb2.TestAllTypes()
+    message.repeated_int64.append(-9223372036854775808)
+    message.repeated_uint64.append(18446744073709551615)
+    message.repeated_double.append(123.456)
+    message.repeated_double.append(1.23e22)
+    message.repeated_double.append(1.23e-18)
+    message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
+    message.repeated_string.append(u'\u00fc\ua71f')
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_format.MessageToString(message)),
+        'repeated_int64: -9223372036854775808\n'
+        'repeated_uint64: 18446744073709551615\n'
+        'repeated_double: 123.456\n'
+        'repeated_double: 1.23e+22\n'
+        'repeated_double: 1.23e-18\n'
+        'repeated_string:'
+        ' "\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
+        'repeated_string: "\\303\\274\\352\\234\\237"\n')
+
+  def testPrintExoticUnicodeSubclass(self):
+    class UnicodeSub(unicode):
+      pass
+    message = unittest_pb2.TestAllTypes()
+    message.repeated_string.append(UnicodeSub(u'\u00fc\ua71f'))
+    self.CompareToGoldenText(
+        text_format.MessageToString(message),
+        'repeated_string: "\\303\\274\\352\\234\\237"\n')
+
+  def testPrintNestedMessageAsOneLine(self):
+    message = unittest_pb2.TestAllTypes()
+    msg = message.repeated_nested_message.add()
+    msg.bb = 42
+    self.CompareToGoldenText(
+        text_format.MessageToString(message, as_one_line=True),
+        'repeated_nested_message { bb: 42 }')
+
+  def testPrintRepeatedFieldsAsOneLine(self):
+    message = unittest_pb2.TestAllTypes()
+    message.repeated_int32.append(1)
+    message.repeated_int32.append(1)
+    message.repeated_int32.append(3)
+    message.repeated_string.append("Google")
+    message.repeated_string.append("Zurich")
+    self.CompareToGoldenText(
+        text_format.MessageToString(message, as_one_line=True),
+        'repeated_int32: 1 repeated_int32: 1 repeated_int32: 3 '
+        'repeated_string: "Google" repeated_string: "Zurich"')
+
+  def testPrintNestedNewLineInStringAsOneLine(self):
+    message = unittest_pb2.TestAllTypes()
+    message.optional_string = "a\nnew\nline"
+    self.CompareToGoldenText(
+        text_format.MessageToString(message, as_one_line=True),
+        'optional_string: "a\\nnew\\nline"')
+
+  def testPrintMessageSetAsOneLine(self):
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+    ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+    message.message_set.Extensions[ext1].i = 23
+    message.message_set.Extensions[ext2].str = 'foo'
+    self.CompareToGoldenText(
+        text_format.MessageToString(message, as_one_line=True),
+        'message_set {'
+        ' [protobuf_unittest.TestMessageSetExtension1] {'
+        ' i: 23'
+        ' }'
+        ' [protobuf_unittest.TestMessageSetExtension2] {'
+        ' str: \"foo\"'
+        ' }'
+        ' }')
+
+  def testPrintExoticAsOneLine(self):
+    message = unittest_pb2.TestAllTypes()
+    message.repeated_int64.append(-9223372036854775808)
+    message.repeated_uint64.append(18446744073709551615)
+    message.repeated_double.append(123.456)
+    message.repeated_double.append(1.23e22)
+    message.repeated_double.append(1.23e-18)
+    message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
+    message.repeated_string.append(u'\u00fc\ua71f')
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(
+            text_format.MessageToString(message, as_one_line=True)),
+        'repeated_int64: -9223372036854775808'
+        ' repeated_uint64: 18446744073709551615'
+        ' repeated_double: 123.456'
+        ' repeated_double: 1.23e+22'
+        ' repeated_double: 1.23e-18'
+        ' repeated_string: '
+        '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""'
+        ' repeated_string: "\\303\\274\\352\\234\\237"')
+
+  def testRoundTripExoticAsOneLine(self):
+    message = unittest_pb2.TestAllTypes()
+    message.repeated_int64.append(-9223372036854775808)
+    message.repeated_uint64.append(18446744073709551615)
+    message.repeated_double.append(123.456)
+    message.repeated_double.append(1.23e22)
+    message.repeated_double.append(1.23e-18)
+    message.repeated_string.append('\000\001\a\b\f\n\r\t\v\\\'"')
+    message.repeated_string.append(u'\u00fc\ua71f')
+
+    # Test as_utf8 = False.
+    wire_text = text_format.MessageToString(
+        message, as_one_line=True, as_utf8=False)
+    parsed_message = unittest_pb2.TestAllTypes()
+    r = text_format.Parse(wire_text, parsed_message)
+    self.assertIs(r, parsed_message)
+    self.assertEquals(message, parsed_message)
+
+    # Test as_utf8 = True.
+    wire_text = text_format.MessageToString(
+        message, as_one_line=True, as_utf8=True)
+    parsed_message = unittest_pb2.TestAllTypes()
+    r = text_format.Parse(wire_text, parsed_message)
+    self.assertIs(r, parsed_message)
+    self.assertEquals(message, parsed_message,
+                      '\n%s != %s' % (message, parsed_message))
+
+  def testPrintRawUtf8String(self):
+    message = unittest_pb2.TestAllTypes()
+    message.repeated_string.append(u'\u00fc\ua71f')
+    text = text_format.MessageToString(message, as_utf8=True)
+    self.CompareToGoldenText(text, 'repeated_string: "\303\274\352\234\237"\n')
+    parsed_message = unittest_pb2.TestAllTypes()
+    text_format.Parse(text, parsed_message)
+    self.assertEquals(message, parsed_message,
+                      '\n%s != %s' % (message, parsed_message))
+
+  def testPrintFloatFormat(self):
+    # Check that float_format argument is passed to sub-message formatting.
+    message = unittest_pb2.NestedTestAllTypes()
+    # We use 1.25 as it is a round number in binary.  The proto 32-bit float
+    # will not gain additional imprecise digits as a 64-bit Python float and
+    # show up in its str.  32-bit 1.2 is noisy when extended to 64-bit:
+    #  >>> struct.unpack('f', struct.pack('f', 1.2))[0]
+    #  1.2000000476837158
+    #  >>> struct.unpack('f', struct.pack('f', 1.25))[0]
+    #  1.25
+    message.payload.optional_float = 1.25
+    # Check rounding at 15 significant digits
+    message.payload.optional_double = -.000003456789012345678
+    # Check no decimal point.
+    message.payload.repeated_float.append(-5642)
+    # Check no trailing zeros.
+    message.payload.repeated_double.append(.000078900)
+    formatted_fields = ['optional_float: 1.25',
+                        'optional_double: -3.45678901234568e-6',
+                        'repeated_float: -5642',
+                        'repeated_double: 7.89e-5']
+    text_message = text_format.MessageToString(message, float_format='.15g')
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_message),
+        'payload {{\n  {}\n  {}\n  {}\n  {}\n}}\n'.format(*formatted_fields))
+    # as_one_line=True is a separate code branch where float_format is passed.
+    text_message = text_format.MessageToString(message, as_one_line=True,
+                                               float_format='.15g')
+    self.CompareToGoldenText(
+        self.RemoveRedundantZeros(text_message),
+        'payload {{ {} {} {} {} }}'.format(*formatted_fields))
+
+  def testMessageToString(self):
+    message = unittest_pb2.ForeignMessage()
+    message.c = 123
+    self.assertEqual('c: 123\n', str(message))
+
+  def RemoveRedundantZeros(self, text):
+    # Some platforms print 1e+5 as 1e+005.  This is fine, but we need to remove
+    # these zeros in order to match the golden file.
+    text = text.replace('e+0','e+').replace('e+0','e+') \
+               .replace('e-0','e-').replace('e-0','e-')
+    # Floating point fields are printed with .0 suffix even if they are
+    # actualy integer numbers.
+    text = re.compile('\.0$', re.MULTILINE).sub('', text)
+    return text
+
+  def testParseGolden(self):
+    golden_text = '\n'.join(self.ReadGolden('text_format_unittest_data.txt'))
+    parsed_message = unittest_pb2.TestAllTypes()
+    r = text_format.Parse(golden_text, parsed_message)
+    self.assertIs(r, parsed_message)
+
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    self.assertEquals(message, parsed_message)
+
+  def testParseGoldenExtensions(self):
+    golden_text = '\n'.join(self.ReadGolden(
+        'text_format_unittest_extensions_data.txt'))
+    parsed_message = unittest_pb2.TestAllExtensions()
+    text_format.Parse(golden_text, parsed_message)
+
+    message = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(message)
+    self.assertEquals(message, parsed_message)
+
+  def testParseAllFields(self):
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    ascii_text = text_format.MessageToString(message)
+
+    parsed_message = unittest_pb2.TestAllTypes()
+    text_format.Parse(ascii_text, parsed_message)
+    self.assertEqual(message, parsed_message)
+    test_util.ExpectAllFieldsSet(self, message)
+
+  def testParseAllExtensions(self):
+    message = unittest_pb2.TestAllExtensions()
+    test_util.SetAllExtensions(message)
+    ascii_text = text_format.MessageToString(message)
+
+    parsed_message = unittest_pb2.TestAllExtensions()
+    text_format.Parse(ascii_text, parsed_message)
+    self.assertEqual(message, parsed_message)
+
+  def testParseMessageSet(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('repeated_uint64: 1\n'
+            'repeated_uint64: 2\n')
+    text_format.Parse(text, message)
+    self.assertEqual(1, message.repeated_uint64[0])
+    self.assertEqual(2, message.repeated_uint64[1])
+
+    message = unittest_mset_pb2.TestMessageSetContainer()
+    text = ('message_set {\n'
+            '  [protobuf_unittest.TestMessageSetExtension1] {\n'
+            '    i: 23\n'
+            '  }\n'
+            '  [protobuf_unittest.TestMessageSetExtension2] {\n'
+            '    str: \"foo\"\n'
+            '  }\n'
+            '}\n')
+    text_format.Parse(text, message)
+    ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
+    ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
+    self.assertEquals(23, message.message_set.Extensions[ext1].i)
+    self.assertEquals('foo', message.message_set.Extensions[ext2].str)
+
+  def testParseExotic(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('repeated_int64: -9223372036854775808\n'
+            'repeated_uint64: 18446744073709551615\n'
+            'repeated_double: 123.456\n'
+            'repeated_double: 1.23e+22\n'
+            'repeated_double: 1.23e-18\n'
+            'repeated_string: \n'
+            '"\\000\\001\\007\\010\\014\\n\\r\\t\\013\\\\\\\'\\""\n'
+            'repeated_string: "foo" \'corge\' "grault"\n'
+            'repeated_string: "\\303\\274\\352\\234\\237"\n'
+            'repeated_string: "\\xc3\\xbc"\n'
+            'repeated_string: "\xc3\xbc"\n')
+    text_format.Parse(text, message)
+
+    self.assertEqual(-9223372036854775808, message.repeated_int64[0])
+    self.assertEqual(18446744073709551615, message.repeated_uint64[0])
+    self.assertEqual(123.456, message.repeated_double[0])
+    self.assertEqual(1.23e22, message.repeated_double[1])
+    self.assertEqual(1.23e-18, message.repeated_double[2])
+    self.assertEqual(
+        '\000\001\a\b\f\n\r\t\v\\\'"', message.repeated_string[0])
+    self.assertEqual('foocorgegrault', message.repeated_string[1])
+    self.assertEqual(u'\u00fc\ua71f', message.repeated_string[2])
+    self.assertEqual(u'\u00fc', message.repeated_string[3])
+
+  def testParseTrailingCommas(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('repeated_int64: 100;\n'
+            'repeated_int64: 200;\n'
+            'repeated_int64: 300,\n'
+            'repeated_string: "one",\n'
+            'repeated_string: "two";\n')
+    text_format.Parse(text, message)
+
+    self.assertEqual(100, message.repeated_int64[0])
+    self.assertEqual(200, message.repeated_int64[1])
+    self.assertEqual(300, message.repeated_int64[2])
+    self.assertEqual(u'one', message.repeated_string[0])
+    self.assertEqual(u'two', message.repeated_string[1])
+
+  def testParseEmptyText(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ''
+    text_format.Parse(text, message)
+    self.assertEquals(unittest_pb2.TestAllTypes(), message)
+
+  def testParseInvalidUtf8(self):
+    message = unittest_pb2.TestAllTypes()
+    text = 'repeated_string: "\\xc3\\xc3"'
+    self.assertRaises(text_format.ParseError, text_format.Parse, text, message)
+
+  def testParseSingleWord(self):
+    message = unittest_pb2.TestAllTypes()
+    text = 'foo'
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError,
+        ('1:1 : Message type "protobuf_unittest.TestAllTypes" has no field named '
+         '"foo".'),
+        text_format.Parse, text, message)
+
+  def testParseUnknownField(self):
+    message = unittest_pb2.TestAllTypes()
+    text = 'unknown_field: 8\n'
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError,
+        ('1:1 : Message type "protobuf_unittest.TestAllTypes" has no field named '
+         '"unknown_field".'),
+        text_format.Parse, text, message)
+
+  def testParseBadExtension(self):
+    message = unittest_pb2.TestAllExtensions()
+    text = '[unknown_extension]: 8\n'
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError,
+        '1:2 : Extension "unknown_extension" not registered.',
+        text_format.Parse, text, message)
+    message = unittest_pb2.TestAllTypes()
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError,
+        ('1:2 : Message type "protobuf_unittest.TestAllTypes" does not have '
+         'extensions.'),
+        text_format.Parse, text, message)
+
+  def testParseGroupNotClosed(self):
+    message = unittest_pb2.TestAllTypes()
+    text = 'RepeatedGroup: <'
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError, '1:16 : Expected ">".',
+        text_format.Parse, text, message)
+
+    text = 'RepeatedGroup: {'
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError, '1:16 : Expected "}".',
+        text_format.Parse, text, message)
+
+  def testParseEmptyGroup(self):
+    message = unittest_pb2.TestAllTypes()
+    text = 'OptionalGroup: {}'
+    text_format.Parse(text, message)
+    self.assertTrue(message.HasField('optionalgroup'))
+
+    message.Clear()
+
+    message = unittest_pb2.TestAllTypes()
+    text = 'OptionalGroup: <>'
+    text_format.Parse(text, message)
+    self.assertTrue(message.HasField('optionalgroup'))
+
+  def testParseBadEnumValue(self):
+    message = unittest_pb2.TestAllTypes()
+    text = 'optional_nested_enum: BARR'
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError,
+        ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
+         'has no value named BARR.'),
+        text_format.Parse, text, message)
+
+    message = unittest_pb2.TestAllTypes()
+    text = 'optional_nested_enum: 100'
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError,
+        ('1:23 : Enum type "protobuf_unittest.TestAllTypes.NestedEnum" '
+         'has no value with number 100.'),
+        text_format.Parse, text, message)
+
+  def testParseBadIntValue(self):
+    message = unittest_pb2.TestAllTypes()
+    text = 'optional_int32: bork'
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError,
+        ('1:17 : Couldn\'t parse integer: bork'),
+        text_format.Parse, text, message)
+
+  def testParseStringFieldUnescape(self):
+    message = unittest_pb2.TestAllTypes()
+    text = r'''repeated_string: "\xf\x62"
+               repeated_string: "\\xf\\x62"
+               repeated_string: "\\\xf\\\x62"
+               repeated_string: "\\\\xf\\\\x62"
+               repeated_string: "\\\\\xf\\\\\x62"
+               repeated_string: "\x5cx20"'''
+    text_format.Parse(text, message)
+
+    SLASH = '\\'
+    self.assertEqual('\x0fb', message.repeated_string[0])
+    self.assertEqual(SLASH + 'xf' + SLASH + 'x62', message.repeated_string[1])
+    self.assertEqual(SLASH + '\x0f' + SLASH + 'b', message.repeated_string[2])
+    self.assertEqual(SLASH + SLASH + 'xf' + SLASH + SLASH + 'x62',
+                     message.repeated_string[3])
+    self.assertEqual(SLASH + SLASH + '\x0f' + SLASH + SLASH + 'b',
+                     message.repeated_string[4])
+    self.assertEqual(SLASH + 'x20', message.repeated_string[5])
+
+  def testMergeRepeatedScalars(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('optional_int32: 42 '
+            'optional_int32: 67')
+    r = text_format.Merge(text, message)
+    self.assertIs(r, message)
+    self.assertEqual(67, message.optional_int32)
+
+  def testParseRepeatedScalars(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('optional_int32: 42 '
+            'optional_int32: 67')
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError,
+        ('1:36 : Message type "protobuf_unittest.TestAllTypes" should not '
+         'have multiple "optional_int32" fields.'),
+        text_format.Parse, text, message)
+
+  def testMergeRepeatedNestedMessageScalars(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('optional_nested_message { bb: 1 } '
+            'optional_nested_message { bb: 2 }')
+    r = text_format.Merge(text, message)
+    self.assertTrue(r is message)
+    self.assertEqual(2, message.optional_nested_message.bb)
+
+  def testParseRepeatedNestedMessageScalars(self):
+    message = unittest_pb2.TestAllTypes()
+    text = ('optional_nested_message { bb: 1 } '
+            'optional_nested_message { bb: 2 }')
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError,
+        ('1:65 : Message type "protobuf_unittest.TestAllTypes.NestedMessage" '
+         'should not have multiple "bb" fields.'),
+        text_format.Parse, text, message)
+
+  def testMergeRepeatedExtensionScalars(self):
+    message = unittest_pb2.TestAllExtensions()
+    text = ('[protobuf_unittest.optional_int32_extension]: 42 '
+            '[protobuf_unittest.optional_int32_extension]: 67')
+    text_format.Merge(text, message)
+    self.assertEqual(
+        67,
+        message.Extensions[unittest_pb2.optional_int32_extension])
+
+  def testParseRepeatedExtensionScalars(self):
+    message = unittest_pb2.TestAllExtensions()
+    text = ('[protobuf_unittest.optional_int32_extension]: 42 '
+            '[protobuf_unittest.optional_int32_extension]: 67')
+    self.assertRaisesWithLiteralMatch(
+        text_format.ParseError,
+        ('1:96 : Message type "protobuf_unittest.TestAllExtensions" '
+         'should not have multiple '
+         '"protobuf_unittest.optional_int32_extension" extensions.'),
+        text_format.Parse, text, message)
+
+  def testParseLinesGolden(self):
+    opened = self.ReadGolden('text_format_unittest_data.txt')
+    parsed_message = unittest_pb2.TestAllTypes()
+    r = text_format.ParseLines(opened, parsed_message)
+    self.assertIs(r, parsed_message)
+
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    self.assertEquals(message, parsed_message)
+
+  def testMergeLinesGolden(self):
+    opened = self.ReadGolden('text_format_unittest_data.txt')
+    parsed_message = unittest_pb2.TestAllTypes()
+    r = text_format.MergeLines(opened, parsed_message)
+    self.assertIs(r, parsed_message)
+
+    message = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(message)
+    self.assertEqual(message, parsed_message)
+
+  def testParseOneof(self):
+    m = unittest_pb2.TestAllTypes()
+    m.oneof_uint32 = 11
+    m2 = unittest_pb2.TestAllTypes()
+    text_format.Parse(text_format.MessageToString(m), m2)
+    self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
+
+
+class TokenizerTest(basetest.TestCase):
+
+  def testSimpleTokenCases(self):
+    text = ('identifier1:"string1"\n     \n\n'
+            'identifier2 : \n \n123  \n  identifier3 :\'string\'\n'
+            'identifiER_4 : 1.1e+2 ID5:-0.23 ID6:\'aaaa\\\'bbbb\'\n'
+            'ID7 : "aa\\"bb"\n\n\n\n ID8: {A:inf B:-inf C:true D:false}\n'
+            'ID9: 22 ID10: -111111111111111111 ID11: -22\n'
+            'ID12: 2222222222222222222 ID13: 1.23456f ID14: 1.2e+2f '
+            'false_bool:  0 true_BOOL:t \n true_bool1:  1 false_BOOL1:f ')
+    tokenizer = text_format._Tokenizer(text.splitlines())
+    methods = [(tokenizer.ConsumeIdentifier, 'identifier1'),
+               ':',
+               (tokenizer.ConsumeString, 'string1'),
+               (tokenizer.ConsumeIdentifier, 'identifier2'),
+               ':',
+               (tokenizer.ConsumeInt32, 123),
+               (tokenizer.ConsumeIdentifier, 'identifier3'),
+               ':',
+               (tokenizer.ConsumeString, 'string'),
+               (tokenizer.ConsumeIdentifier, 'identifiER_4'),
+               ':',
+               (tokenizer.ConsumeFloat, 1.1e+2),
+               (tokenizer.ConsumeIdentifier, 'ID5'),
+               ':',
+               (tokenizer.ConsumeFloat, -0.23),
+               (tokenizer.ConsumeIdentifier, 'ID6'),
+               ':',
+               (tokenizer.ConsumeString, 'aaaa\'bbbb'),
+               (tokenizer.ConsumeIdentifier, 'ID7'),
+               ':',
+               (tokenizer.ConsumeString, 'aa\"bb'),
+               (tokenizer.ConsumeIdentifier, 'ID8'),
+               ':',
+               '{',
+               (tokenizer.ConsumeIdentifier, 'A'),
+               ':',
+               (tokenizer.ConsumeFloat, float('inf')),
+               (tokenizer.ConsumeIdentifier, 'B'),
+               ':',
+               (tokenizer.ConsumeFloat, -float('inf')),
+               (tokenizer.ConsumeIdentifier, 'C'),
+               ':',
+               (tokenizer.ConsumeBool, True),
+               (tokenizer.ConsumeIdentifier, 'D'),
+               ':',
+               (tokenizer.ConsumeBool, False),
+               '}',
+               (tokenizer.ConsumeIdentifier, 'ID9'),
+               ':',
+               (tokenizer.ConsumeUint32, 22),
+               (tokenizer.ConsumeIdentifier, 'ID10'),
+               ':',
+               (tokenizer.ConsumeInt64, -111111111111111111),
+               (tokenizer.ConsumeIdentifier, 'ID11'),
+               ':',
+               (tokenizer.ConsumeInt32, -22),
+               (tokenizer.ConsumeIdentifier, 'ID12'),
+               ':',
+               (tokenizer.ConsumeUint64, 2222222222222222222),
+               (tokenizer.ConsumeIdentifier, 'ID13'),
+               ':',
+               (tokenizer.ConsumeFloat, 1.23456),
+               (tokenizer.ConsumeIdentifier, 'ID14'),
+               ':',
+               (tokenizer.ConsumeFloat, 1.2e+2),
+               (tokenizer.ConsumeIdentifier, 'false_bool'),
+               ':',
+               (tokenizer.ConsumeBool, False),
+               (tokenizer.ConsumeIdentifier, 'true_BOOL'),
+               ':',
+               (tokenizer.ConsumeBool, True),
+               (tokenizer.ConsumeIdentifier, 'true_bool1'),
+               ':',
+               (tokenizer.ConsumeBool, True),
+               (tokenizer.ConsumeIdentifier, 'false_BOOL1'),
+               ':',
+               (tokenizer.ConsumeBool, False)]
+
+    i = 0
+    while not tokenizer.AtEnd():
+      m = methods[i]
+      if type(m) == str:
+        token = tokenizer.token
+        self.assertEqual(token, m)
+        tokenizer.NextToken()
+      else:
+        self.assertEqual(m[1], m[0]())
+      i += 1
+
+  def testConsumeIntegers(self):
+    # This test only tests the failures in the integer parsing methods as well
+    # as the '0' special cases.
+    int64_max = (1 << 63) - 1
+    uint32_max = (1 << 32) - 1
+    text = '-1 %d %d' % (uint32_max + 1, int64_max + 1)
+    tokenizer = text_format._Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32)
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint64)
+    self.assertEqual(-1, tokenizer.ConsumeInt32())
+
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeUint32)
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt32)
+    self.assertEqual(uint32_max + 1, tokenizer.ConsumeInt64())
+
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeInt64)
+    self.assertEqual(int64_max + 1, tokenizer.ConsumeUint64())
+    self.assertTrue(tokenizer.AtEnd())
+
+    text = '-0 -0 0 0'
+    tokenizer = text_format._Tokenizer(text.splitlines())
+    self.assertEqual(0, tokenizer.ConsumeUint32())
+    self.assertEqual(0, tokenizer.ConsumeUint64())
+    self.assertEqual(0, tokenizer.ConsumeUint32())
+    self.assertEqual(0, tokenizer.ConsumeUint64())
+    self.assertTrue(tokenizer.AtEnd())
+
+  def testConsumeByteString(self):
+    text = '"string1\''
+    tokenizer = text_format._Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+    text = 'string1"'
+    tokenizer = text_format._Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+    text = '\n"\\xt"'
+    tokenizer = text_format._Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+    text = '\n"\\"'
+    tokenizer = text_format._Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+    text = '\n"\\x"'
+    tokenizer = text_format._Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeByteString)
+
+  def testConsumeBool(self):
+    text = 'not-a-bool'
+    tokenizer = text_format._Tokenizer(text.splitlines())
+    self.assertRaises(text_format.ParseError, tokenizer.ConsumeBool)
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/type_checkers.py b/protobuf/python/google/protobuf/internal/type_checkers.py
new file mode 100755
index 0000000..56d2646
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/type_checkers.py
@@ -0,0 +1,328 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#PY25 compatible for GAE.
+#
+# Copyright 2008 Google Inc. All Rights Reserved.
+
+"""Provides type checking routines.
+
+This module defines type checking utilities in the forms of dictionaries:
+
+VALUE_CHECKERS: A dictionary of field types and a value validation object.
+TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing
+  function.
+TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization
+  function.
+FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their
+  coresponding wire types.
+TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization
+  function.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import sys  ##PY25
+if sys.version < '2.6': bytes = str  ##PY25
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import decoder
+from google.protobuf.internal import encoder
+from google.protobuf.internal import wire_format
+from google.protobuf import descriptor
+
+_FieldDescriptor = descriptor.FieldDescriptor
+
+
+def GetTypeChecker(field):
+  """Returns a type checker for a message field of the specified types.
+
+  Args:
+    field: FieldDescriptor object for this field.
+
+  Returns:
+    An instance of TypeChecker which can be used to verify the types
+    of values assigned to a field of the specified type.
+  """
+  if (field.cpp_type == _FieldDescriptor.CPPTYPE_STRING and
+      field.type == _FieldDescriptor.TYPE_STRING):
+    return UnicodeValueChecker()
+  if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM:
+    return EnumValueChecker(field.enum_type)
+  return _VALUE_CHECKERS[field.cpp_type]
+
+
+# None of the typecheckers below make any attempt to guard against people
+# subclassing builtin types and doing weird things.  We're not trying to
+# protect against malicious clients here, just people accidentally shooting
+# themselves in the foot in obvious ways.
+
+class TypeChecker(object):
+
+  """Type checker used to catch type errors as early as possible
+  when the client is setting scalar fields in protocol messages.
+  """
+
+  def __init__(self, *acceptable_types):
+    self._acceptable_types = acceptable_types
+
+  def CheckValue(self, proposed_value):
+    """Type check the provided value and return it.
+
+    The returned value might have been normalized to another type.
+    """
+    if not isinstance(proposed_value, self._acceptable_types):
+      message = ('%.1024r has type %s, but expected one of: %s' %
+                 (proposed_value, type(proposed_value), self._acceptable_types))
+      raise TypeError(message)
+    return proposed_value
+
+
+# IntValueChecker and its subclasses perform integer type-checks
+# and bounds-checks.
+class IntValueChecker(object):
+
+  """Checker used for integer fields.  Performs type-check and range check."""
+
+  def CheckValue(self, proposed_value):
+    if not isinstance(proposed_value, (int, long)):
+      message = ('%.1024r has type %s, but expected one of: %s' %
+                 (proposed_value, type(proposed_value), (int, long)))
+      raise TypeError(message)
+    if not self._MIN <= proposed_value <= self._MAX:
+      raise ValueError('Value out of range: %d' % proposed_value)
+    # We force 32-bit values to int and 64-bit values to long to make
+    # alternate implementations where the distinction is more significant
+    # (e.g. the C++ implementation) simpler.
+    proposed_value = self._TYPE(proposed_value)
+    return proposed_value
+
+
+class EnumValueChecker(object):
+
+  """Checker used for enum fields.  Performs type-check and range check."""
+
+  def __init__(self, enum_type):
+    self._enum_type = enum_type
+
+  def CheckValue(self, proposed_value):
+    if not isinstance(proposed_value, (int, long)):
+      message = ('%.1024r has type %s, but expected one of: %s' %
+                 (proposed_value, type(proposed_value), (int, long)))
+      raise TypeError(message)
+    if proposed_value not in self._enum_type.values_by_number:
+      raise ValueError('Unknown enum value: %d' % proposed_value)
+    return proposed_value
+
+
+class UnicodeValueChecker(object):
+
+  """Checker used for string fields.
+
+  Always returns a unicode value, even if the input is of type str.
+  """
+
+  def CheckValue(self, proposed_value):
+    if not isinstance(proposed_value, (bytes, unicode)):
+      message = ('%.1024r has type %s, but expected one of: %s' %
+                 (proposed_value, type(proposed_value), (bytes, unicode)))
+      raise TypeError(message)
+
+    # If the value is of type 'bytes' make sure that it is in 7-bit ASCII
+    # encoding.
+    if isinstance(proposed_value, bytes):
+      try:
+        proposed_value = proposed_value.decode('ascii')
+      except UnicodeDecodeError:
+        raise ValueError('%.1024r has type bytes, but isn\'t in 7-bit ASCII '
+                         'encoding. Non-ASCII strings must be converted to '
+                         'unicode objects before being added.' %
+                         (proposed_value))
+    return proposed_value
+
+
+class Int32ValueChecker(IntValueChecker):
+  # We're sure to use ints instead of longs here since comparison may be more
+  # efficient.
+  _MIN = -2147483648
+  _MAX = 2147483647
+  _TYPE = int
+
+
+class Uint32ValueChecker(IntValueChecker):
+  _MIN = 0
+  _MAX = (1 << 32) - 1
+  _TYPE = int
+
+
+class Int64ValueChecker(IntValueChecker):
+  _MIN = -(1 << 63)
+  _MAX = (1 << 63) - 1
+  _TYPE = long
+
+
+class Uint64ValueChecker(IntValueChecker):
+  _MIN = 0
+  _MAX = (1 << 64) - 1
+  _TYPE = long
+
+
+# Type-checkers for all scalar CPPTYPEs.
+_VALUE_CHECKERS = {
+    _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(),
+    _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(),
+    _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(),
+    _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(),
+    _FieldDescriptor.CPPTYPE_DOUBLE: TypeChecker(
+        float, int, long),
+    _FieldDescriptor.CPPTYPE_FLOAT: TypeChecker(
+        float, int, long),
+    _FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int),
+    _FieldDescriptor.CPPTYPE_STRING: TypeChecker(bytes),
+    }
+
+
+# Map from field type to a function F, such that F(field_num, value)
+# gives the total byte size for a value of the given type.  This
+# byte size includes tag information and any other additional space
+# associated with serializing "value".
+TYPE_TO_BYTE_SIZE_FN = {
+    _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize,
+    _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize,
+    _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize,
+    _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize,
+    _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize,
+    _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize,
+    _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize,
+    _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize,
+    _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize,
+    _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize,
+    _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize,
+    _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize,
+    _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize,
+    _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize,
+    _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize,
+    _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize,
+    _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize,
+    _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize
+    }
+
+
+# Maps from field types to encoder constructors.
+TYPE_TO_ENCODER = {
+    _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder,
+    _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder,
+    _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder,
+    _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder,
+    _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder,
+    _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder,
+    _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder,
+    _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder,
+    _FieldDescriptor.TYPE_STRING: encoder.StringEncoder,
+    _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder,
+    _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder,
+    _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder,
+    _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder,
+    _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder,
+    _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder,
+    _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder,
+    _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder,
+    _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder,
+    }
+
+
+# Maps from field types to sizer constructors.
+TYPE_TO_SIZER = {
+    _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer,
+    _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer,
+    _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer,
+    _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer,
+    _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer,
+    _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer,
+    _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer,
+    _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer,
+    _FieldDescriptor.TYPE_STRING: encoder.StringSizer,
+    _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer,
+    _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer,
+    _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer,
+    _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer,
+    _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer,
+    _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer,
+    _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer,
+    _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer,
+    _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer,
+    }
+
+
+# Maps from field type to a decoder constructor.
+TYPE_TO_DECODER = {
+    _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder,
+    _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder,
+    _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder,
+    _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder,
+    _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder,
+    _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder,
+    _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder,
+    _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder,
+    _FieldDescriptor.TYPE_STRING: decoder.StringDecoder,
+    _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder,
+    _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder,
+    _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder,
+    _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder,
+    _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder,
+    _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder,
+    _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder,
+    _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder,
+    _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder,
+    }
+
+# Maps from field type to expected wiretype.
+FIELD_TYPE_TO_WIRE_TYPE = {
+    _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64,
+    _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32,
+    _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT,
+    _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT,
+    _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT,
+    _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64,
+    _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32,
+    _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT,
+    _FieldDescriptor.TYPE_STRING:
+      wire_format.WIRETYPE_LENGTH_DELIMITED,
+    _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP,
+    _FieldDescriptor.TYPE_MESSAGE:
+      wire_format.WIRETYPE_LENGTH_DELIMITED,
+    _FieldDescriptor.TYPE_BYTES:
+      wire_format.WIRETYPE_LENGTH_DELIMITED,
+    _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT,
+    _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT,
+    _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32,
+    _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64,
+    _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT,
+    _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT,
+    }
diff --git a/protobuf/python/google/protobuf/internal/unknown_fields_test.py b/protobuf/python/google/protobuf/internal/unknown_fields_test.py
new file mode 100755
index 0000000..7177560
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/unknown_fields_test.py
@@ -0,0 +1,231 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Test for preservation of unknown fields in the pure Python implementation."""
+
+__author__ = 'bohdank@google.com (Bohdan Koval)'
+
+from google.apputils import basetest
+from google.protobuf import unittest_mset_pb2
+from google.protobuf import unittest_pb2
+from google.protobuf.internal import encoder
+from google.protobuf.internal import missing_enum_values_pb2
+from google.protobuf.internal import test_util
+from google.protobuf.internal import type_checkers
+
+
+class UnknownFieldsTest(basetest.TestCase):
+
+  def setUp(self):
+    self.descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
+    self.all_fields = unittest_pb2.TestAllTypes()
+    test_util.SetAllFields(self.all_fields)
+    self.all_fields_data = self.all_fields.SerializeToString()
+    self.empty_message = unittest_pb2.TestEmptyMessage()
+    self.empty_message.ParseFromString(self.all_fields_data)
+    self.unknown_fields = self.empty_message._unknown_fields
+
+  def GetField(self, name):
+    field_descriptor = self.descriptor.fields_by_name[name]
+    wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
+    field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
+    result_dict = {}
+    for tag_bytes, value in self.unknown_fields:
+      if tag_bytes == field_tag:
+        decoder = unittest_pb2.TestAllTypes._decoders_by_tag[tag_bytes][0]
+        decoder(value, 0, len(value), self.all_fields, result_dict)
+    return result_dict[field_descriptor]
+
+  def testEnum(self):
+    value = self.GetField('optional_nested_enum')
+    self.assertEqual(self.all_fields.optional_nested_enum, value)
+
+  def testRepeatedEnum(self):
+    value = self.GetField('repeated_nested_enum')
+    self.assertEqual(self.all_fields.repeated_nested_enum, value)
+
+  def testVarint(self):
+    value = self.GetField('optional_int32')
+    self.assertEqual(self.all_fields.optional_int32, value)
+
+  def testFixed32(self):
+    value = self.GetField('optional_fixed32')
+    self.assertEqual(self.all_fields.optional_fixed32, value)
+
+  def testFixed64(self):
+    value = self.GetField('optional_fixed64')
+    self.assertEqual(self.all_fields.optional_fixed64, value)
+
+  def testLengthDelimited(self):
+    value = self.GetField('optional_string')
+    self.assertEqual(self.all_fields.optional_string, value)
+
+  def testGroup(self):
+    value = self.GetField('optionalgroup')
+    self.assertEqual(self.all_fields.optionalgroup, value)
+
+  def testSerialize(self):
+    data = self.empty_message.SerializeToString()
+
+    # Don't use assertEqual because we don't want to dump raw binary data to
+    # stdout.
+    self.assertTrue(data == self.all_fields_data)
+
+  def testCopyFrom(self):
+    message = unittest_pb2.TestEmptyMessage()
+    message.CopyFrom(self.empty_message)
+    self.assertEqual(self.unknown_fields, message._unknown_fields)
+
+  def testMergeFrom(self):
+    message = unittest_pb2.TestAllTypes()
+    message.optional_int32 = 1
+    message.optional_uint32 = 2
+    source = unittest_pb2.TestEmptyMessage()
+    source.ParseFromString(message.SerializeToString())
+
+    message.ClearField('optional_int32')
+    message.optional_int64 = 3
+    message.optional_uint32 = 4
+    destination = unittest_pb2.TestEmptyMessage()
+    destination.ParseFromString(message.SerializeToString())
+    unknown_fields = destination._unknown_fields[:]
+
+    destination.MergeFrom(source)
+    self.assertEqual(unknown_fields + source._unknown_fields,
+                     destination._unknown_fields)
+
+  def testClear(self):
+    self.empty_message.Clear()
+    self.assertEqual(0, len(self.empty_message._unknown_fields))
+
+  def testByteSize(self):
+    self.assertEqual(self.all_fields.ByteSize(), self.empty_message.ByteSize())
+
+  def testUnknownExtensions(self):
+    message = unittest_pb2.TestEmptyMessageWithExtensions()
+    message.ParseFromString(self.all_fields_data)
+    self.assertEqual(self.empty_message._unknown_fields,
+                     message._unknown_fields)
+
+  def testListFields(self):
+    # Make sure ListFields doesn't return unknown fields.
+    self.assertEqual(0, len(self.empty_message.ListFields()))
+
+  def testSerializeMessageSetWireFormatUnknownExtension(self):
+    # Create a message using the message set wire format with an unknown
+    # message.
+    raw = unittest_mset_pb2.RawMessageSet()
+
+    # Add an unknown extension.
+    item = raw.item.add()
+    item.type_id = 1545009
+    message1 = unittest_mset_pb2.TestMessageSetExtension1()
+    message1.i = 12345
+    item.message = message1.SerializeToString()
+
+    serialized = raw.SerializeToString()
+
+    # Parse message using the message set wire format.
+    proto = unittest_mset_pb2.TestMessageSet()
+    proto.MergeFromString(serialized)
+
+    # Verify that the unknown extension is serialized unchanged
+    reserialized = proto.SerializeToString()
+    new_raw = unittest_mset_pb2.RawMessageSet()
+    new_raw.MergeFromString(reserialized)
+    self.assertEqual(raw, new_raw)
+
+  def testEquals(self):
+    message = unittest_pb2.TestEmptyMessage()
+    message.ParseFromString(self.all_fields_data)
+    self.assertEqual(self.empty_message, message)
+
+    self.all_fields.ClearField('optional_string')
+    message.ParseFromString(self.all_fields.SerializeToString())
+    self.assertNotEqual(self.empty_message, message)
+
+
+class UnknownFieldsTest(basetest.TestCase):
+
+  def setUp(self):
+    self.descriptor = missing_enum_values_pb2.TestEnumValues.DESCRIPTOR
+
+    self.message = missing_enum_values_pb2.TestEnumValues()
+    self.message.optional_nested_enum = (
+      missing_enum_values_pb2.TestEnumValues.ZERO)
+    self.message.repeated_nested_enum.extend([
+      missing_enum_values_pb2.TestEnumValues.ZERO,
+      missing_enum_values_pb2.TestEnumValues.ONE,
+      ])
+    self.message.packed_nested_enum.extend([
+      missing_enum_values_pb2.TestEnumValues.ZERO,
+      missing_enum_values_pb2.TestEnumValues.ONE,
+      ])
+    self.message_data = self.message.SerializeToString()
+    self.missing_message = missing_enum_values_pb2.TestMissingEnumValues()
+    self.missing_message.ParseFromString(self.message_data)
+    self.unknown_fields = self.missing_message._unknown_fields
+
+  def GetField(self, name):
+    field_descriptor = self.descriptor.fields_by_name[name]
+    wire_type = type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type]
+    field_tag = encoder.TagBytes(field_descriptor.number, wire_type)
+    result_dict = {}
+    for tag_bytes, value in self.unknown_fields:
+      if tag_bytes == field_tag:
+        decoder = missing_enum_values_pb2.TestEnumValues._decoders_by_tag[
+          tag_bytes][0]
+        decoder(value, 0, len(value), self.message, result_dict)
+    return result_dict[field_descriptor]
+
+  def testUnknownEnumValue(self):
+    self.assertFalse(self.missing_message.HasField('optional_nested_enum'))
+    value = self.GetField('optional_nested_enum')
+    self.assertEqual(self.message.optional_nested_enum, value)
+
+  def testUnknownRepeatedEnumValue(self):
+    value = self.GetField('repeated_nested_enum')
+    self.assertEqual(self.message.repeated_nested_enum, value)
+
+  def testUnknownPackedEnumValue(self):
+    value = self.GetField('packed_nested_enum')
+    self.assertEqual(self.message.packed_nested_enum, value)
+
+  def testRoundTrip(self):
+    new_message = missing_enum_values_pb2.TestEnumValues()
+    new_message.ParseFromString(self.missing_message.SerializeToString())
+    self.assertEqual(self.message, new_message)
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/internal/wire_format.py b/protobuf/python/google/protobuf/internal/wire_format.py
new file mode 100755
index 0000000..883f525
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/wire_format.py
@@ -0,0 +1,268 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Constants and static functions to support protocol buffer wire format."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+import struct
+from google.protobuf import descriptor
+from google.protobuf import message
+
+
+TAG_TYPE_BITS = 3  # Number of bits used to hold type info in a proto tag.
+TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1  # 0x7
+
+# These numbers identify the wire type of a protocol buffer value.
+# We use the least-significant TAG_TYPE_BITS bits of the varint-encoded
+# tag-and-type to store one of these WIRETYPE_* constants.
+# These values must match WireType enum in google/protobuf/wire_format.h.
+WIRETYPE_VARINT = 0
+WIRETYPE_FIXED64 = 1
+WIRETYPE_LENGTH_DELIMITED = 2
+WIRETYPE_START_GROUP = 3
+WIRETYPE_END_GROUP = 4
+WIRETYPE_FIXED32 = 5
+_WIRETYPE_MAX = 5
+
+
+# Bounds for various integer types.
+INT32_MAX = int((1 << 31) - 1)
+INT32_MIN = int(-(1 << 31))
+UINT32_MAX = (1 << 32) - 1
+
+INT64_MAX = (1 << 63) - 1
+INT64_MIN = -(1 << 63)
+UINT64_MAX = (1 << 64) - 1
+
+# "struct" format strings that will encode/decode the specified formats.
+FORMAT_UINT32_LITTLE_ENDIAN = '<I'
+FORMAT_UINT64_LITTLE_ENDIAN = '<Q'
+FORMAT_FLOAT_LITTLE_ENDIAN = '<f'
+FORMAT_DOUBLE_LITTLE_ENDIAN = '<d'
+
+
+# We'll have to provide alternate implementations of AppendLittleEndian*() on
+# any architectures where these checks fail.
+if struct.calcsize(FORMAT_UINT32_LITTLE_ENDIAN) != 4:
+  raise AssertionError('Format "I" is not a 32-bit number.')
+if struct.calcsize(FORMAT_UINT64_LITTLE_ENDIAN) != 8:
+  raise AssertionError('Format "Q" is not a 64-bit number.')
+
+
+def PackTag(field_number, wire_type):
+  """Returns an unsigned 32-bit integer that encodes the field number and
+  wire type information in standard protocol message wire format.
+
+  Args:
+    field_number: Expected to be an integer in the range [1, 1 << 29)
+    wire_type: One of the WIRETYPE_* constants.
+  """
+  if not 0 <= wire_type <= _WIRETYPE_MAX:
+    raise message.EncodeError('Unknown wire type: %d' % wire_type)
+  return (field_number << TAG_TYPE_BITS) | wire_type
+
+
+def UnpackTag(tag):
+  """The inverse of PackTag().  Given an unsigned 32-bit number,
+  returns a (field_number, wire_type) tuple.
+  """
+  return (tag >> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK)
+
+
+def ZigZagEncode(value):
+  """ZigZag Transform:  Encodes signed integers so that they can be
+  effectively used with varint encoding.  See wire_format.h for
+  more details.
+  """
+  if value >= 0:
+    return value << 1
+  return (value << 1) ^ (~0)
+
+
+def ZigZagDecode(value):
+  """Inverse of ZigZagEncode()."""
+  if not value & 0x1:
+    return value >> 1
+  return (value >> 1) ^ (~0)
+
+
+
+# The *ByteSize() functions below return the number of bytes required to
+# serialize "field number + type" information and then serialize the value.
+
+
+def Int32ByteSize(field_number, int32):
+  return Int64ByteSize(field_number, int32)
+
+
+def Int32ByteSizeNoTag(int32):
+  return _VarUInt64ByteSizeNoTag(0xffffffffffffffff & int32)
+
+
+def Int64ByteSize(field_number, int64):
+  # Have to convert to uint before calling UInt64ByteSize().
+  return UInt64ByteSize(field_number, 0xffffffffffffffff & int64)
+
+
+def UInt32ByteSize(field_number, uint32):
+  return UInt64ByteSize(field_number, uint32)
+
+
+def UInt64ByteSize(field_number, uint64):
+  return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64)
+
+
+def SInt32ByteSize(field_number, int32):
+  return UInt32ByteSize(field_number, ZigZagEncode(int32))
+
+
+def SInt64ByteSize(field_number, int64):
+  return UInt64ByteSize(field_number, ZigZagEncode(int64))
+
+
+def Fixed32ByteSize(field_number, fixed32):
+  return TagByteSize(field_number) + 4
+
+
+def Fixed64ByteSize(field_number, fixed64):
+  return TagByteSize(field_number) + 8
+
+
+def SFixed32ByteSize(field_number, sfixed32):
+  return TagByteSize(field_number) + 4
+
+
+def SFixed64ByteSize(field_number, sfixed64):
+  return TagByteSize(field_number) + 8
+
+
+def FloatByteSize(field_number, flt):
+  return TagByteSize(field_number) + 4
+
+
+def DoubleByteSize(field_number, double):
+  return TagByteSize(field_number) + 8
+
+
+def BoolByteSize(field_number, b):
+  return TagByteSize(field_number) + 1
+
+
+def EnumByteSize(field_number, enum):
+  return UInt32ByteSize(field_number, enum)
+
+
+def StringByteSize(field_number, string):
+  return BytesByteSize(field_number, string.encode('utf-8'))
+
+
+def BytesByteSize(field_number, b):
+  return (TagByteSize(field_number)
+          + _VarUInt64ByteSizeNoTag(len(b))
+          + len(b))
+
+
+def GroupByteSize(field_number, message):
+  return (2 * TagByteSize(field_number)  # START and END group.
+          + message.ByteSize())
+
+
+def MessageByteSize(field_number, message):
+  return (TagByteSize(field_number)
+          + _VarUInt64ByteSizeNoTag(message.ByteSize())
+          + message.ByteSize())
+
+
+def MessageSetItemByteSize(field_number, msg):
+  # First compute the sizes of the tags.
+  # There are 2 tags for the beginning and ending of the repeated group, that
+  # is field number 1, one with field number 2 (type_id) and one with field
+  # number 3 (message).
+  total_size = (2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3))
+
+  # Add the number of bytes for type_id.
+  total_size += _VarUInt64ByteSizeNoTag(field_number)
+
+  message_size = msg.ByteSize()
+
+  # The number of bytes for encoding the length of the message.
+  total_size += _VarUInt64ByteSizeNoTag(message_size)
+
+  # The size of the message.
+  total_size += message_size
+  return total_size
+
+
+def TagByteSize(field_number):
+  """Returns the bytes required to serialize a tag with this field number."""
+  # Just pass in type 0, since the type won't affect the tag+type size.
+  return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0))
+
+
+# Private helper function for the *ByteSize() functions above.
+
+def _VarUInt64ByteSizeNoTag(uint64):
+  """Returns the number of bytes required to serialize a single varint
+  using boundary value comparisons. (unrolled loop optimization -WPierce)
+  uint64 must be unsigned.
+  """
+  if uint64 <= 0x7f: return 1
+  if uint64 <= 0x3fff: return 2
+  if uint64 <= 0x1fffff: return 3
+  if uint64 <= 0xfffffff: return 4
+  if uint64 <= 0x7ffffffff: return 5
+  if uint64 <= 0x3ffffffffff: return 6
+  if uint64 <= 0x1ffffffffffff: return 7
+  if uint64 <= 0xffffffffffffff: return 8
+  if uint64 <= 0x7fffffffffffffff: return 9
+  if uint64 > UINT64_MAX:
+    raise message.EncodeError('Value out of range: %d' % uint64)
+  return 10
+
+
+NON_PACKABLE_TYPES = (
+  descriptor.FieldDescriptor.TYPE_STRING,
+  descriptor.FieldDescriptor.TYPE_GROUP,
+  descriptor.FieldDescriptor.TYPE_MESSAGE,
+  descriptor.FieldDescriptor.TYPE_BYTES
+)
+
+
+def IsTypePackable(field_type):
+  """Return true iff packable = true is valid for fields of this type.
+
+  Args:
+    field_type: a FieldDescriptor::Type value.
+
+  Returns:
+    True iff fields of this type are packable.
+  """
+  return field_type not in NON_PACKABLE_TYPES
diff --git a/protobuf/python/google/protobuf/internal/wire_format_test.py b/protobuf/python/google/protobuf/internal/wire_format_test.py
new file mode 100755
index 0000000..f39035c
--- /dev/null
+++ b/protobuf/python/google/protobuf/internal/wire_format_test.py
@@ -0,0 +1,253 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Test for google.protobuf.internal.wire_format."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+from google.apputils import basetest
+from google.protobuf import message
+from google.protobuf.internal import wire_format
+
+
+class WireFormatTest(basetest.TestCase):
+
+  def testPackTag(self):
+    field_number = 0xabc
+    tag_type = 2
+    self.assertEqual((field_number << 3) | tag_type,
+                     wire_format.PackTag(field_number, tag_type))
+    PackTag = wire_format.PackTag
+    # Number too high.
+    self.assertRaises(message.EncodeError, PackTag, field_number, 6)
+    # Number too low.
+    self.assertRaises(message.EncodeError, PackTag, field_number, -1)
+
+  def testUnpackTag(self):
+    # Test field numbers that will require various varint sizes.
+    for expected_field_number in (1, 15, 16, 2047, 2048):
+      for expected_wire_type in range(6):  # Highest-numbered wiretype is 5.
+        field_number, wire_type = wire_format.UnpackTag(
+            wire_format.PackTag(expected_field_number, expected_wire_type))
+        self.assertEqual(expected_field_number, field_number)
+        self.assertEqual(expected_wire_type, wire_type)
+
+    self.assertRaises(TypeError, wire_format.UnpackTag, None)
+    self.assertRaises(TypeError, wire_format.UnpackTag, 'abc')
+    self.assertRaises(TypeError, wire_format.UnpackTag, 0.0)
+    self.assertRaises(TypeError, wire_format.UnpackTag, object())
+
+  def testZigZagEncode(self):
+    Z = wire_format.ZigZagEncode
+    self.assertEqual(0, Z(0))
+    self.assertEqual(1, Z(-1))
+    self.assertEqual(2, Z(1))
+    self.assertEqual(3, Z(-2))
+    self.assertEqual(4, Z(2))
+    self.assertEqual(0xfffffffe, Z(0x7fffffff))
+    self.assertEqual(0xffffffff, Z(-0x80000000))
+    self.assertEqual(0xfffffffffffffffe, Z(0x7fffffffffffffff))
+    self.assertEqual(0xffffffffffffffff, Z(-0x8000000000000000))
+
+    self.assertRaises(TypeError, Z, None)
+    self.assertRaises(TypeError, Z, 'abcd')
+    self.assertRaises(TypeError, Z, 0.0)
+    self.assertRaises(TypeError, Z, object())
+
+  def testZigZagDecode(self):
+    Z = wire_format.ZigZagDecode
+    self.assertEqual(0, Z(0))
+    self.assertEqual(-1, Z(1))
+    self.assertEqual(1, Z(2))
+    self.assertEqual(-2, Z(3))
+    self.assertEqual(2, Z(4))
+    self.assertEqual(0x7fffffff, Z(0xfffffffe))
+    self.assertEqual(-0x80000000, Z(0xffffffff))
+    self.assertEqual(0x7fffffffffffffff, Z(0xfffffffffffffffe))
+    self.assertEqual(-0x8000000000000000, Z(0xffffffffffffffff))
+
+    self.assertRaises(TypeError, Z, None)
+    self.assertRaises(TypeError, Z, 'abcd')
+    self.assertRaises(TypeError, Z, 0.0)
+    self.assertRaises(TypeError, Z, object())
+
+  def NumericByteSizeTestHelper(self, byte_size_fn, value, expected_value_size):
+    # Use field numbers that cause various byte sizes for the tag information.
+    for field_number, tag_bytes in ((15, 1), (16, 2), (2047, 2), (2048, 3)):
+      expected_size = expected_value_size + tag_bytes
+      actual_size = byte_size_fn(field_number, value)
+      self.assertEqual(expected_size, actual_size,
+                       'byte_size_fn: %s, field_number: %d, value: %r\n'
+                       'Expected: %d, Actual: %d'% (
+          byte_size_fn, field_number, value, expected_size, actual_size))
+
+  def testByteSizeFunctions(self):
+    # Test all numeric *ByteSize() functions.
+    NUMERIC_ARGS = [
+        # Int32ByteSize().
+        [wire_format.Int32ByteSize, 0, 1],
+        [wire_format.Int32ByteSize, 127, 1],
+        [wire_format.Int32ByteSize, 128, 2],
+        [wire_format.Int32ByteSize, -1, 10],
+        # Int64ByteSize().
+        [wire_format.Int64ByteSize, 0, 1],
+        [wire_format.Int64ByteSize, 127, 1],
+        [wire_format.Int64ByteSize, 128, 2],
+        [wire_format.Int64ByteSize, -1, 10],
+        # UInt32ByteSize().
+        [wire_format.UInt32ByteSize, 0, 1],
+        [wire_format.UInt32ByteSize, 127, 1],
+        [wire_format.UInt32ByteSize, 128, 2],
+        [wire_format.UInt32ByteSize, wire_format.UINT32_MAX, 5],
+        # UInt64ByteSize().
+        [wire_format.UInt64ByteSize, 0, 1],
+        [wire_format.UInt64ByteSize, 127, 1],
+        [wire_format.UInt64ByteSize, 128, 2],
+        [wire_format.UInt64ByteSize, wire_format.UINT64_MAX, 10],
+        # SInt32ByteSize().
+        [wire_format.SInt32ByteSize, 0, 1],
+        [wire_format.SInt32ByteSize, -1, 1],
+        [wire_format.SInt32ByteSize, 1, 1],
+        [wire_format.SInt32ByteSize, -63, 1],
+        [wire_format.SInt32ByteSize, 63, 1],
+        [wire_format.SInt32ByteSize, -64, 1],
+        [wire_format.SInt32ByteSize, 64, 2],
+        # SInt64ByteSize().
+        [wire_format.SInt64ByteSize, 0, 1],
+        [wire_format.SInt64ByteSize, -1, 1],
+        [wire_format.SInt64ByteSize, 1, 1],
+        [wire_format.SInt64ByteSize, -63, 1],
+        [wire_format.SInt64ByteSize, 63, 1],
+        [wire_format.SInt64ByteSize, -64, 1],
+        [wire_format.SInt64ByteSize, 64, 2],
+        # Fixed32ByteSize().
+        [wire_format.Fixed32ByteSize, 0, 4],
+        [wire_format.Fixed32ByteSize, wire_format.UINT32_MAX, 4],
+        # Fixed64ByteSize().
+        [wire_format.Fixed64ByteSize, 0, 8],
+        [wire_format.Fixed64ByteSize, wire_format.UINT64_MAX, 8],
+        # SFixed32ByteSize().
+        [wire_format.SFixed32ByteSize, 0, 4],
+        [wire_format.SFixed32ByteSize, wire_format.INT32_MIN, 4],
+        [wire_format.SFixed32ByteSize, wire_format.INT32_MAX, 4],
+        # SFixed64ByteSize().
+        [wire_format.SFixed64ByteSize, 0, 8],
+        [wire_format.SFixed64ByteSize, wire_format.INT64_MIN, 8],
+        [wire_format.SFixed64ByteSize, wire_format.INT64_MAX, 8],
+        # FloatByteSize().
+        [wire_format.FloatByteSize, 0.0, 4],
+        [wire_format.FloatByteSize, 1000000000.0, 4],
+        [wire_format.FloatByteSize, -1000000000.0, 4],
+        # DoubleByteSize().
+        [wire_format.DoubleByteSize, 0.0, 8],
+        [wire_format.DoubleByteSize, 1000000000.0, 8],
+        [wire_format.DoubleByteSize, -1000000000.0, 8],
+        # BoolByteSize().
+        [wire_format.BoolByteSize, False, 1],
+        [wire_format.BoolByteSize, True, 1],
+        # EnumByteSize().
+        [wire_format.EnumByteSize, 0, 1],
+        [wire_format.EnumByteSize, 127, 1],
+        [wire_format.EnumByteSize, 128, 2],
+        [wire_format.EnumByteSize, wire_format.UINT32_MAX, 5],
+        ]
+    for args in NUMERIC_ARGS:
+      self.NumericByteSizeTestHelper(*args)
+
+    # Test strings and bytes.
+    for byte_size_fn in (wire_format.StringByteSize, wire_format.BytesByteSize):
+      # 1 byte for tag, 1 byte for length, 3 bytes for contents.
+      self.assertEqual(5, byte_size_fn(10, 'abc'))
+      # 2 bytes for tag, 1 byte for length, 3 bytes for contents.
+      self.assertEqual(6, byte_size_fn(16, 'abc'))
+      # 2 bytes for tag, 2 bytes for length, 128 bytes for contents.
+      self.assertEqual(132, byte_size_fn(16, 'a' * 128))
+
+    # Test UTF-8 string byte size calculation.
+    # 1 byte for tag, 1 byte for length, 8 bytes for content.
+    self.assertEqual(10, wire_format.StringByteSize(
+        5, b'\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82'.decode('utf-8')))
+
+    class MockMessage(object):
+      def __init__(self, byte_size):
+        self.byte_size = byte_size
+      def ByteSize(self):
+        return self.byte_size
+
+    message_byte_size = 10
+    mock_message = MockMessage(byte_size=message_byte_size)
+    # Test groups.
+    # (2 * 1) bytes for begin and end tags, plus message_byte_size.
+    self.assertEqual(2 + message_byte_size,
+                     wire_format.GroupByteSize(1, mock_message))
+    # (2 * 2) bytes for begin and end tags, plus message_byte_size.
+    self.assertEqual(4 + message_byte_size,
+                     wire_format.GroupByteSize(16, mock_message))
+
+    # Test messages.
+    # 1 byte for tag, plus 1 byte for length, plus contents.
+    self.assertEqual(2 + mock_message.byte_size,
+                     wire_format.MessageByteSize(1, mock_message))
+    # 2 bytes for tag, plus 1 byte for length, plus contents.
+    self.assertEqual(3 + mock_message.byte_size,
+                     wire_format.MessageByteSize(16, mock_message))
+    # 2 bytes for tag, plus 2 bytes for length, plus contents.
+    mock_message.byte_size = 128
+    self.assertEqual(4 + mock_message.byte_size,
+                     wire_format.MessageByteSize(16, mock_message))
+
+
+    # Test message set item byte size.
+    # 4 bytes for tags, plus 1 byte for length, plus 1 byte for type_id,
+    # plus contents.
+    mock_message.byte_size = 10
+    self.assertEqual(mock_message.byte_size + 6,
+                     wire_format.MessageSetItemByteSize(1, mock_message))
+
+    # 4 bytes for tags, plus 2 bytes for length, plus 1 byte for type_id,
+    # plus contents.
+    mock_message.byte_size = 128
+    self.assertEqual(mock_message.byte_size + 7,
+                     wire_format.MessageSetItemByteSize(1, mock_message))
+
+    # 4 bytes for tags, plus 2 bytes for length, plus 2 byte for type_id,
+    # plus contents.
+    self.assertEqual(mock_message.byte_size + 8,
+                     wire_format.MessageSetItemByteSize(128, mock_message))
+
+    # Too-long varint.
+    self.assertRaises(message.EncodeError,
+                      wire_format.UInt64ByteSize, 1, 1 << 128)
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/message.py b/protobuf/python/google/protobuf/message.py
new file mode 100755
index 0000000..c186452
--- /dev/null
+++ b/protobuf/python/google/protobuf/message.py
@@ -0,0 +1,284 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# TODO(robinson): We should just make these methods all "pure-virtual" and move
+# all implementation out, into reflection.py for now.
+
+
+"""Contains an abstract base class for protocol messages."""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+
+class Error(Exception): pass
+class DecodeError(Error): pass
+class EncodeError(Error): pass
+
+
+class Message(object):
+
+  """Abstract base class for protocol messages.
+
+  Protocol message classes are almost always generated by the protocol
+  compiler.  These generated types subclass Message and implement the methods
+  shown below.
+
+  TODO(robinson): Link to an HTML document here.
+
+  TODO(robinson): Document that instances of this class will also
+  have an Extensions attribute with __getitem__ and __setitem__.
+  Again, not sure how to best convey this.
+
+  TODO(robinson): Document that the class must also have a static
+    RegisterExtension(extension_field) method.
+    Not sure how to best express at this point.
+  """
+
+  # TODO(robinson): Document these fields and methods.
+
+  __slots__ = []
+
+  DESCRIPTOR = None
+
+  def __deepcopy__(self, memo=None):
+    clone = type(self)()
+    clone.MergeFrom(self)
+    return clone
+
+  def __eq__(self, other_msg):
+    """Recursively compares two messages by value and structure."""
+    raise NotImplementedError
+
+  def __ne__(self, other_msg):
+    # Can't just say self != other_msg, since that would infinitely recurse. :)
+    return not self == other_msg
+
+  def __hash__(self):
+    raise TypeError('unhashable object')
+
+  def __str__(self):
+    """Outputs a human-readable representation of the message."""
+    raise NotImplementedError
+
+  def __unicode__(self):
+    """Outputs a human-readable representation of the message."""
+    raise NotImplementedError
+
+  def MergeFrom(self, other_msg):
+    """Merges the contents of the specified message into current message.
+
+    This method merges the contents of the specified message into the current
+    message. Singular fields that are set in the specified message overwrite
+    the corresponding fields in the current message. Repeated fields are
+    appended. Singular sub-messages and groups are recursively merged.
+
+    Args:
+      other_msg: Message to merge into the current message.
+    """
+    raise NotImplementedError
+
+  def CopyFrom(self, other_msg):
+    """Copies the content of the specified message into the current message.
+
+    The method clears the current message and then merges the specified
+    message using MergeFrom.
+
+    Args:
+      other_msg: Message to copy into the current one.
+    """
+    if self is other_msg:
+      return
+    self.Clear()
+    self.MergeFrom(other_msg)
+
+  def Clear(self):
+    """Clears all data that was set in the message."""
+    raise NotImplementedError
+
+  def SetInParent(self):
+    """Mark this as present in the parent.
+
+    This normally happens automatically when you assign a field of a
+    sub-message, but sometimes you want to make the sub-message
+    present while keeping it empty.  If you find yourself using this,
+    you may want to reconsider your design."""
+    raise NotImplementedError
+
+  def IsInitialized(self):
+    """Checks if the message is initialized.
+
+    Returns:
+      The method returns True if the message is initialized (i.e. all of its
+      required fields are set).
+    """
+    raise NotImplementedError
+
+  # TODO(robinson): MergeFromString() should probably return None and be
+  # implemented in terms of a helper that returns the # of bytes read.  Our
+  # deserialization routines would use the helper when recursively
+  # deserializing, but the end user would almost always just want the no-return
+  # MergeFromString().
+
+  def MergeFromString(self, serialized):
+    """Merges serialized protocol buffer data into this message.
+
+    When we find a field in |serialized| that is already present
+    in this message:
+      - If it's a "repeated" field, we append to the end of our list.
+      - Else, if it's a scalar, we overwrite our field.
+      - Else, (it's a nonrepeated composite), we recursively merge
+        into the existing composite.
+
+    TODO(robinson): Document handling of unknown fields.
+
+    Args:
+      serialized: Any object that allows us to call buffer(serialized)
+        to access a string of bytes using the buffer interface.
+
+    TODO(robinson): When we switch to a helper, this will return None.
+
+    Returns:
+      The number of bytes read from |serialized|.
+      For non-group messages, this will always be len(serialized),
+      but for messages which are actually groups, this will
+      generally be less than len(serialized), since we must
+      stop when we reach an END_GROUP tag.  Note that if
+      we *do* stop because of an END_GROUP tag, the number
+      of bytes returned does not include the bytes
+      for the END_GROUP tag information.
+    """
+    raise NotImplementedError
+
+  def ParseFromString(self, serialized):
+    """Parse serialized protocol buffer data into this message.
+
+    Like MergeFromString(), except we clear the object first and
+    do not return the value that MergeFromString returns.
+    """
+    self.Clear()
+    self.MergeFromString(serialized)
+
+  def SerializeToString(self):
+    """Serializes the protocol message to a binary string.
+
+    Returns:
+      A binary string representation of the message if all of the required
+      fields in the message are set (i.e. the message is initialized).
+
+    Raises:
+      message.EncodeError if the message isn't initialized.
+    """
+    raise NotImplementedError
+
+  def SerializePartialToString(self):
+    """Serializes the protocol message to a binary string.
+
+    This method is similar to SerializeToString but doesn't check if the
+    message is initialized.
+
+    Returns:
+      A string representation of the partial message.
+    """
+    raise NotImplementedError
+
+  # TODO(robinson): Decide whether we like these better
+  # than auto-generated has_foo() and clear_foo() methods
+  # on the instances themselves.  This way is less consistent
+  # with C++, but it makes reflection-type access easier and
+  # reduces the number of magically autogenerated things.
+  #
+  # TODO(robinson): Be sure to document (and test) exactly
+  # which field names are accepted here.  Are we case-sensitive?
+  # What do we do with fields that share names with Python keywords
+  # like 'lambda' and 'yield'?
+  #
+  # nnorwitz says:
+  # """
+  # Typically (in python), an underscore is appended to names that are
+  # keywords. So they would become lambda_ or yield_.
+  # """
+  def ListFields(self):
+    """Returns a list of (FieldDescriptor, value) tuples for all
+    fields in the message which are not empty.  A singular field is non-empty
+    if HasField() would return true, and a repeated field is non-empty if
+    it contains at least one element.  The fields are ordered by field
+    number"""
+    raise NotImplementedError
+
+  def HasField(self, field_name):
+    """Checks if a certain field is set for the message. Note if the
+    field_name is not defined in the message descriptor, ValueError will be
+    raised."""
+    raise NotImplementedError
+
+  def ClearField(self, field_name):
+    raise NotImplementedError
+
+  def HasExtension(self, extension_handle):
+    raise NotImplementedError
+
+  def ClearExtension(self, extension_handle):
+    raise NotImplementedError
+
+  def ByteSize(self):
+    """Returns the serialized size of this message.
+    Recursively calls ByteSize() on all contained messages.
+    """
+    raise NotImplementedError
+
+  def _SetListener(self, message_listener):
+    """Internal method used by the protocol message implementation.
+    Clients should not call this directly.
+
+    Sets a listener that this message will call on certain state transitions.
+
+    The purpose of this method is to register back-edges from children to
+    parents at runtime, for the purpose of setting "has" bits and
+    byte-size-dirty bits in the parent and ancestor objects whenever a child or
+    descendant object is modified.
+
+    If the client wants to disconnect this Message from the object tree, she
+    explicitly sets callback to None.
+
+    If message_listener is None, unregisters any existing listener.  Otherwise,
+    message_listener must implement the MessageListener interface in
+    internal/message_listener.py, and we discard any listener registered
+    via a previous _SetListener() call.
+    """
+    raise NotImplementedError
+
+  def __getstate__(self):
+    """Support the pickle protocol."""
+    return dict(serialized=self.SerializePartialToString())
+
+  def __setstate__(self, state):
+    """Support the pickle protocol."""
+    self.__init__()
+    self.ParseFromString(state['serialized'])
diff --git a/protobuf/python/google/protobuf/message_factory.py b/protobuf/python/google/protobuf/message_factory.py
new file mode 100644
index 0000000..7fd7bec
--- /dev/null
+++ b/protobuf/python/google/protobuf/message_factory.py
@@ -0,0 +1,155 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#PY25 compatible for GAE.
+#
+# Copyright 2012 Google Inc. All Rights Reserved.
+
+"""Provides a factory class for generating dynamic messages.
+
+The easiest way to use this class is if you have access to the FileDescriptor
+protos containing the messages you want to create you can just do the following:
+
+message_classes = message_factory.GetMessages(iterable_of_file_descriptors)
+my_proto_instance = message_classes['some.proto.package.MessageName']()
+"""
+
+__author__ = 'matthewtoia@google.com (Matt Toia)'
+
+import sys  ##PY25
+from google.protobuf import descriptor_database
+from google.protobuf import descriptor_pool
+from google.protobuf import message
+from google.protobuf import reflection
+
+
+class MessageFactory(object):
+  """Factory for creating Proto2 messages from descriptors in a pool."""
+
+  def __init__(self, pool=None):
+    """Initializes a new factory."""
+    self.pool = (pool or descriptor_pool.DescriptorPool(
+        descriptor_database.DescriptorDatabase()))
+
+    # local cache of all classes built from protobuf descriptors
+    self._classes = {}
+
+  def GetPrototype(self, descriptor):
+    """Builds a proto2 message class based on the passed in descriptor.
+
+    Passing a descriptor with a fully qualified name matching a previous
+    invocation will cause the same class to be returned.
+
+    Args:
+      descriptor: The descriptor to build from.
+
+    Returns:
+      A class describing the passed in descriptor.
+    """
+    if descriptor.full_name not in self._classes:
+      descriptor_name = descriptor.name
+      if sys.version_info[0] < 3:  ##PY25
+##!PY25      if str is bytes:  # PY2
+        descriptor_name = descriptor.name.encode('ascii', 'ignore')
+      result_class = reflection.GeneratedProtocolMessageType(
+          descriptor_name,
+          (message.Message,),
+          {'DESCRIPTOR': descriptor, '__module__': None})
+          # If module not set, it wrongly points to the reflection.py module.
+      self._classes[descriptor.full_name] = result_class
+      for field in descriptor.fields:
+        if field.message_type:
+          self.GetPrototype(field.message_type)
+      for extension in result_class.DESCRIPTOR.extensions:
+        if extension.containing_type.full_name not in self._classes:
+          self.GetPrototype(extension.containing_type)
+        extended_class = self._classes[extension.containing_type.full_name]
+        extended_class.RegisterExtension(extension)
+    return self._classes[descriptor.full_name]
+
+  def GetMessages(self, files):
+    """Gets all the messages from a specified file.
+
+    This will find and resolve dependencies, failing if the descriptor
+    pool cannot satisfy them.
+
+    Args:
+      files: The file names to extract messages from.
+
+    Returns:
+      A dictionary mapping proto names to the message classes. This will include
+      any dependent messages as well as any messages defined in the same file as
+      a specified message.
+    """
+    result = {}
+    for file_name in files:
+      file_desc = self.pool.FindFileByName(file_name)
+      for name, msg in file_desc.message_types_by_name.iteritems():
+        if file_desc.package:
+          full_name = '.'.join([file_desc.package, name])
+        else:
+          full_name = msg.name
+        result[full_name] = self.GetPrototype(
+            self.pool.FindMessageTypeByName(full_name))
+
+      # While the extension FieldDescriptors are created by the descriptor pool,
+      # the python classes created in the factory need them to be registered
+      # explicitly, which is done below.
+      #
+      # The call to RegisterExtension will specifically check if the
+      # extension was already registered on the object and either
+      # ignore the registration if the original was the same, or raise
+      # an error if they were different.
+
+      for name, extension in file_desc.extensions_by_name.iteritems():
+        if extension.containing_type.full_name not in self._classes:
+          self.GetPrototype(extension.containing_type)
+        extended_class = self._classes[extension.containing_type.full_name]
+        extended_class.RegisterExtension(extension)
+    return result
+
+
+_FACTORY = MessageFactory()
+
+
+def GetMessages(file_protos):
+  """Builds a dictionary of all the messages available in a set of files.
+
+  Args:
+    file_protos: A sequence of file protos to build messages out of.
+
+  Returns:
+    A dictionary mapping proto names to the message classes. This will include
+    any dependent messages as well as any messages defined in the same file as
+    a specified message.
+  """
+  for file_proto in file_protos:
+    _FACTORY.pool.Add(file_proto)
+  return _FACTORY.GetMessages([file_proto.name for file_proto in file_protos])
diff --git a/protobuf/python/google/protobuf/pyext/README b/protobuf/python/google/protobuf/pyext/README
new file mode 100644
index 0000000..6d61cb4
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/README
@@ -0,0 +1,6 @@
+This is the 'v2' C++ implementation for python proto2.
+
+It is active when:
+
+PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=cpp
+PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION=2
diff --git a/protobuf/python/google/protobuf/pyext/__init__.py b/protobuf/python/google/protobuf/pyext/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/__init__.py
diff --git a/protobuf/python/google/protobuf/pyext/cpp_message.py b/protobuf/python/google/protobuf/pyext/cpp_message.py
new file mode 100644
index 0000000..dcf34a0
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/cpp_message.py
@@ -0,0 +1,61 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Protocol message implementation hooks for C++ implementation.
+
+Contains helper functions used to create protocol message classes from
+Descriptor objects at runtime backed by the protocol buffer C++ API.
+"""
+
+__author__ = 'tibell@google.com (Johan Tibell)'
+
+from google.protobuf.pyext import _message
+from google.protobuf import message
+
+
+def NewMessage(bases, message_descriptor, dictionary):
+  """Creates a new protocol message *class*."""
+  new_bases = []
+  for base in bases:
+    if base is message.Message:
+      # _message.Message must come before message.Message as it
+      # overrides methods in that class.
+      new_bases.append(_message.Message)
+    new_bases.append(base)
+  return tuple(new_bases)
+
+
+def InitMessage(message_descriptor, cls):
+  """Constructs a new message instance (called before instance's __init__)."""
+
+  def SubInit(self, **kwargs):
+    super(cls, self).__init__(message_descriptor, **kwargs)
+  cls.__init__ = SubInit
+  cls.AddDescriptors(message_descriptor)
diff --git a/protobuf/python/google/protobuf/pyext/descriptor.cc b/protobuf/python/google/protobuf/pyext/descriptor.cc
new file mode 100644
index 0000000..3f7be73
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/descriptor.cc
@@ -0,0 +1,357 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: petar@google.com (Petar Petrov)
+
+#include <Python.h>
+#include <string>
+
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/pyext/descriptor.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+
+#define C(str) const_cast<char*>(str)
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
+  #define PyInt_FromLong PyLong_FromLong
+  #if PY_VERSION_HEX < 0x03030000
+    #error "Python 3.0 - 3.2 are not supported."
+  #else
+  #define PyString_AsString(ob) \
+    (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AS_STRING(ob))
+  #endif
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+
+#ifndef PyVarObject_HEAD_INIT
+#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
+#endif
+#ifndef Py_TYPE
+#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+#endif
+
+
+static google::protobuf::DescriptorPool* g_descriptor_pool = NULL;
+
+namespace cfield_descriptor {
+
+static void Dealloc(CFieldDescriptor* self) {
+  Py_CLEAR(self->descriptor_field);
+  Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+static PyObject* GetFullName(CFieldDescriptor* self, void *closure) {
+  return PyString_FromStringAndSize(
+      self->descriptor->full_name().c_str(),
+      self->descriptor->full_name().size());
+}
+
+static PyObject* GetName(CFieldDescriptor *self, void *closure) {
+  return PyString_FromStringAndSize(
+      self->descriptor->name().c_str(),
+      self->descriptor->name().size());
+}
+
+static PyObject* GetCppType(CFieldDescriptor *self, void *closure) {
+  return PyInt_FromLong(self->descriptor->cpp_type());
+}
+
+static PyObject* GetLabel(CFieldDescriptor *self, void *closure) {
+  return PyInt_FromLong(self->descriptor->label());
+}
+
+static PyObject* GetID(CFieldDescriptor *self, void *closure) {
+  return PyLong_FromVoidPtr(self);
+}
+
+static PyGetSetDef Getters[] = {
+  { C("full_name"), (getter)GetFullName, NULL, "Full name", NULL},
+  { C("name"), (getter)GetName, NULL, "last name", NULL},
+  { C("cpp_type"), (getter)GetCppType, NULL, "C++ Type", NULL},
+  { C("label"), (getter)GetLabel, NULL, "Label", NULL},
+  { C("id"), (getter)GetID, NULL, "ID", NULL},
+  {NULL}
+};
+
+}  // namespace cfield_descriptor
+
+PyTypeObject CFieldDescriptor_Type = {
+  PyVarObject_HEAD_INIT(&PyType_Type, 0)
+  C("google.protobuf.internal."
+    "_net_proto2___python."
+    "CFieldDescriptor"),                // tp_name
+  sizeof(CFieldDescriptor),             // tp_basicsize
+  0,                                    // tp_itemsize
+  (destructor)cfield_descriptor::Dealloc,  // tp_dealloc
+  0,                                    // tp_print
+  0,                                    // tp_getattr
+  0,                                    // tp_setattr
+  0,                                    // tp_compare
+  0,                                    // tp_repr
+  0,                                    // tp_as_number
+  0,                                    // tp_as_sequence
+  0,                                    // tp_as_mapping
+  0,                                    // tp_hash
+  0,                                    // tp_call
+  0,                                    // tp_str
+  0,                                    // tp_getattro
+  0,                                    // tp_setattro
+  0,                                    // tp_as_buffer
+  Py_TPFLAGS_DEFAULT,                   // tp_flags
+  C("A Field Descriptor"),              // tp_doc
+  0,                                    // tp_traverse
+  0,                                    // tp_clear
+  0,                                    // tp_richcompare
+  0,                                    // tp_weaklistoffset
+  0,                                    // tp_iter
+  0,                                    // tp_iternext
+  0,                                    // tp_methods
+  0,                                    // tp_members
+  cfield_descriptor::Getters,           // tp_getset
+  0,                                    // tp_base
+  0,                                    // tp_dict
+  0,                                    // tp_descr_get
+  0,                                    // tp_descr_set
+  0,                                    // tp_dictoffset
+  0,                                    // tp_init
+  PyType_GenericAlloc,                  // tp_alloc
+  PyType_GenericNew,                    // tp_new
+  PyObject_Del,                         // tp_free
+};
+
+namespace cdescriptor_pool {
+
+static void Dealloc(CDescriptorPool* self) {
+  Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+static PyObject* NewCDescriptor(
+    const google::protobuf::FieldDescriptor* field_descriptor) {
+  CFieldDescriptor* cfield_descriptor = PyObject_New(
+      CFieldDescriptor, &CFieldDescriptor_Type);
+  if (cfield_descriptor == NULL) {
+    return NULL;
+  }
+  cfield_descriptor->descriptor = field_descriptor;
+  cfield_descriptor->descriptor_field = NULL;
+
+  return reinterpret_cast<PyObject*>(cfield_descriptor);
+}
+
+PyObject* FindFieldByName(CDescriptorPool* self, PyObject* name) {
+  const char* full_field_name = PyString_AsString(name);
+  if (full_field_name == NULL) {
+    return NULL;
+  }
+
+  const google::protobuf::FieldDescriptor* field_descriptor = NULL;
+
+  field_descriptor = self->pool->FindFieldByName(full_field_name);
+
+  if (field_descriptor == NULL) {
+    PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s",
+                 full_field_name);
+    return NULL;
+  }
+
+  return NewCDescriptor(field_descriptor);
+}
+
+PyObject* FindExtensionByName(CDescriptorPool* self, PyObject* arg) {
+  const char* full_field_name = PyString_AsString(arg);
+  if (full_field_name == NULL) {
+    return NULL;
+  }
+
+  const google::protobuf::FieldDescriptor* field_descriptor =
+      self->pool->FindExtensionByName(full_field_name);
+  if (field_descriptor == NULL) {
+    PyErr_Format(PyExc_TypeError, "Couldn't find field %.200s",
+                 full_field_name);
+    return NULL;
+  }
+
+  return NewCDescriptor(field_descriptor);
+}
+
+static PyMethodDef Methods[] = {
+  { C("FindFieldByName"),
+    (PyCFunction)FindFieldByName,
+    METH_O,
+    C("Searches for a field descriptor by full name.") },
+  { C("FindExtensionByName"),
+    (PyCFunction)FindExtensionByName,
+    METH_O,
+    C("Searches for extension descriptor by full name.") },
+  {NULL}
+};
+
+}  // namespace cdescriptor_pool
+
+PyTypeObject CDescriptorPool_Type = {
+  PyVarObject_HEAD_INIT(&PyType_Type, 0)
+  C("google.protobuf.internal."
+    "_net_proto2___python."
+    "CFieldDescriptor"),               // tp_name
+  sizeof(CDescriptorPool),             // tp_basicsize
+  0,                                   // tp_itemsize
+  (destructor)cdescriptor_pool::Dealloc,  // tp_dealloc
+  0,                                   // tp_print
+  0,                                   // tp_getattr
+  0,                                   // tp_setattr
+  0,                                   // tp_compare
+  0,                                   // tp_repr
+  0,                                   // tp_as_number
+  0,                                   // tp_as_sequence
+  0,                                   // tp_as_mapping
+  0,                                   // tp_hash
+  0,                                   // tp_call
+  0,                                   // tp_str
+  0,                                   // tp_getattro
+  0,                                   // tp_setattro
+  0,                                   // tp_as_buffer
+  Py_TPFLAGS_DEFAULT,                  // tp_flags
+  C("A Descriptor Pool"),              // tp_doc
+  0,                                   // tp_traverse
+  0,                                   // tp_clear
+  0,                                   // tp_richcompare
+  0,                                   // tp_weaklistoffset
+  0,                                   // tp_iter
+  0,                                   // tp_iternext
+  cdescriptor_pool::Methods,           // tp_methods
+  0,                                   // tp_members
+  0,                                   // tp_getset
+  0,                                   // tp_base
+  0,                                   // tp_dict
+  0,                                   // tp_descr_get
+  0,                                   // tp_descr_set
+  0,                                   // tp_dictoffset
+  0,                                   // tp_init
+  PyType_GenericAlloc,                 // tp_alloc
+  PyType_GenericNew,                   // tp_new
+  PyObject_Del,                        // tp_free
+};
+
+google::protobuf::DescriptorPool* GetDescriptorPool() {
+  if (g_descriptor_pool == NULL) {
+    g_descriptor_pool = new google::protobuf::DescriptorPool(
+        google::protobuf::DescriptorPool::generated_pool());
+  }
+  return g_descriptor_pool;
+}
+
+PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args) {
+  CDescriptorPool* cdescriptor_pool = PyObject_New(
+      CDescriptorPool, &CDescriptorPool_Type);
+  if (cdescriptor_pool == NULL) {
+    return NULL;
+  }
+  cdescriptor_pool->pool = GetDescriptorPool();
+  return reinterpret_cast<PyObject*>(cdescriptor_pool);
+}
+
+
+// Collects errors that occur during proto file building to allow them to be
+// propagated in the python exception instead of only living in ERROR logs.
+class BuildFileErrorCollector : public google::protobuf::DescriptorPool::ErrorCollector {
+ public:
+  BuildFileErrorCollector() : error_message(""), had_errors(false) {}
+
+  void AddError(const string& filename, const string& element_name,
+                const Message* descriptor, ErrorLocation location,
+                const string& message) {
+    // Replicates the logging behavior that happens in the C++ implementation
+    // when an error collector is not passed in.
+    if (!had_errors) {
+      error_message +=
+          ("Invalid proto descriptor for file \"" + filename + "\":\n");
+    }
+    // As this only happens on failure and will result in the program not
+    // running at all, no effort is made to optimize this string manipulation.
+    error_message += ("  " + element_name + ": " + message + "\n");
+  }
+
+  string error_message;
+  bool had_errors;
+};
+
+PyObject* Python_BuildFile(PyObject* ignored, PyObject* arg) {
+  char* message_type;
+  Py_ssize_t message_len;
+
+  if (PyBytes_AsStringAndSize(arg, &message_type, &message_len) < 0) {
+    return NULL;
+  }
+
+  google::protobuf::FileDescriptorProto file_proto;
+  if (!file_proto.ParseFromArray(message_type, message_len)) {
+    PyErr_SetString(PyExc_TypeError, "Couldn't parse file content!");
+    return NULL;
+  }
+
+  if (google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+          file_proto.name()) != NULL) {
+    Py_RETURN_NONE;
+  }
+
+  BuildFileErrorCollector error_collector;
+  const google::protobuf::FileDescriptor* descriptor =
+      GetDescriptorPool()->BuildFileCollectingErrors(file_proto,
+                                                     &error_collector);
+  if (descriptor == NULL) {
+    PyErr_Format(PyExc_TypeError,
+                 "Couldn't build proto file into descriptor pool!\n%s",
+                 error_collector.error_message.c_str());
+    return NULL;
+  }
+
+  Py_RETURN_NONE;
+}
+
+bool InitDescriptor() {
+  CFieldDescriptor_Type.tp_new = PyType_GenericNew;
+  if (PyType_Ready(&CFieldDescriptor_Type) < 0)
+    return false;
+
+  CDescriptorPool_Type.tp_new = PyType_GenericNew;
+  if (PyType_Ready(&CDescriptorPool_Type) < 0)
+    return false;
+
+  return true;
+}
+
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/python/google/protobuf/pyext/descriptor.h b/protobuf/python/google/protobuf/pyext/descriptor.h
new file mode 100644
index 0000000..ae7a1b9
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/descriptor.h
@@ -0,0 +1,96 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: petar@google.com (Petar Petrov)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__
+
+#include <Python.h>
+#include <structmember.h>
+
+#include <google/protobuf/descriptor.h>
+
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+typedef struct CFieldDescriptor {
+  PyObject_HEAD
+
+  // The proto2 descriptor that this object represents.
+  const google::protobuf::FieldDescriptor* descriptor;
+
+  // Reference to the original field object in the Python DESCRIPTOR.
+  PyObject* descriptor_field;
+} CFieldDescriptor;
+
+typedef struct {
+  PyObject_HEAD
+
+  const google::protobuf::DescriptorPool* pool;
+} CDescriptorPool;
+
+extern PyTypeObject CFieldDescriptor_Type;
+
+extern PyTypeObject CDescriptorPool_Type;
+
+namespace cdescriptor_pool {
+
+// Looks up a field by name. Returns a CDescriptor corresponding to
+// the field on success, or NULL on failure.
+//
+// Returns a new reference.
+PyObject* FindFieldByName(CDescriptorPool* self, PyObject* name);
+
+// Looks up an extension by name. Returns a CDescriptor corresponding
+// to the field on success, or NULL on failure.
+//
+// Returns a new reference.
+PyObject* FindExtensionByName(CDescriptorPool* self, PyObject* arg);
+
+}  // namespace cdescriptor_pool
+
+PyObject* Python_NewCDescriptorPool(PyObject* ignored, PyObject* args);
+PyObject* Python_BuildFile(PyObject* ignored, PyObject* args);
+bool InitDescriptor();
+google::protobuf::DescriptorPool* GetDescriptorPool();
+
+}  // namespace python
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_PYTHON_CPP_DESCRIPTOR_H__
diff --git a/protobuf/python/google/protobuf/pyext/descriptor_cpp2_test.py b/protobuf/python/google/protobuf/pyext/descriptor_cpp2_test.py
new file mode 100644
index 0000000..3cf45a2
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/descriptor_cpp2_test.py
@@ -0,0 +1,58 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.pyext behavior."""
+
+__author__ = 'anuraag@google.com (Anuraag Agrawal)'
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION'] = '2'
+
+# We must set the implementation version above before the google3 imports.
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+# Run all tests from the original module by putting them in our namespace.
+# pylint: disable=wildcard-import
+from google.protobuf.internal.descriptor_test import *
+
+
+class ConfirmCppApi2Test(basetest.TestCase):
+
+  def testImplementationSetting(self):
+    self.assertEqual('cpp', api_implementation.Type())
+    self.assertEqual(2, api_implementation.Version())
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/pyext/extension_dict.cc b/protobuf/python/google/protobuf/pyext/extension_dict.cc
new file mode 100644
index 0000000..3861c79
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/extension_dict.cc
@@ -0,0 +1,338 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#include <google/protobuf/pyext/extension_dict.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/pyext/descriptor.h>
+#include <google/protobuf/pyext/message.h>
+#include <google/protobuf/pyext/repeated_composite_container.h>
+#include <google/protobuf/pyext/repeated_scalar_container.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+#include <google/protobuf/stubs/shared_ptr.h>
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+extern google::protobuf::DynamicMessageFactory* global_message_factory;
+
+namespace extension_dict {
+
+// TODO(tibell): Always use self->message for clarity, just like in
+// RepeatedCompositeContainer.
+static google::protobuf::Message* GetMessage(ExtensionDict* self) {
+  if (self->parent != NULL) {
+    return self->parent->message;
+  } else {
+    return self->message;
+  }
+}
+
+CFieldDescriptor* InternalGetCDescriptorFromExtension(PyObject* extension) {
+  PyObject* cdescriptor = PyObject_GetAttrString(extension, "_cdescriptor");
+  if (cdescriptor == NULL) {
+    PyErr_SetString(PyExc_KeyError, "Unregistered extension.");
+    return NULL;
+  }
+  if (!PyObject_TypeCheck(cdescriptor, &CFieldDescriptor_Type)) {
+    PyErr_SetString(PyExc_TypeError, "Not a CFieldDescriptor");
+    Py_DECREF(cdescriptor);
+    return NULL;
+  }
+  CFieldDescriptor* descriptor =
+      reinterpret_cast<CFieldDescriptor*>(cdescriptor);
+  return descriptor;
+}
+
+PyObject* len(ExtensionDict* self) {
+#if PY_MAJOR_VERSION >= 3
+  return PyLong_FromLong(PyDict_Size(self->values));
+#else
+  return PyInt_FromLong(PyDict_Size(self->values));
+#endif
+}
+
+// TODO(tibell): Use VisitCompositeField.
+int ReleaseExtension(ExtensionDict* self,
+                     PyObject* extension,
+                     const google::protobuf::FieldDescriptor* descriptor) {
+  if (descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+    if (descriptor->cpp_type() ==
+        google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (repeated_composite_container::Release(
+              reinterpret_cast<RepeatedCompositeContainer*>(
+                  extension)) < 0) {
+        return -1;
+      }
+    } else {
+      if (repeated_scalar_container::Release(
+              reinterpret_cast<RepeatedScalarContainer*>(
+                  extension)) < 0) {
+        return -1;
+      }
+    }
+  } else if (descriptor->cpp_type() ==
+             google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+    if (cmessage::ReleaseSubMessage(
+            GetMessage(self), descriptor,
+            reinterpret_cast<CMessage*>(extension)) < 0) {
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+PyObject* subscript(ExtensionDict* self, PyObject* key) {
+  CFieldDescriptor* cdescriptor = InternalGetCDescriptorFromExtension(
+      key);
+  if (cdescriptor == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor));
+  const google::protobuf::FieldDescriptor* descriptor = cdescriptor->descriptor;
+  if (descriptor == NULL) {
+    return NULL;
+  }
+  if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
+      descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+    return cmessage::InternalGetScalar(self->parent, descriptor);
+  }
+
+  PyObject* value = PyDict_GetItem(self->values, key);
+  if (value != NULL) {
+    Py_INCREF(value);
+    return value;
+  }
+
+  if (descriptor->label() != FieldDescriptor::LABEL_REPEATED &&
+      descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+    PyObject* sub_message = cmessage::InternalGetSubMessage(
+        self->parent, cdescriptor);
+    if (sub_message == NULL) {
+      return NULL;
+    }
+    PyDict_SetItem(self->values, key, sub_message);
+    return sub_message;
+  }
+
+  if (descriptor->label() == FieldDescriptor::LABEL_REPEATED) {
+    if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      // COPIED
+      PyObject* py_container = PyObject_CallObject(
+          reinterpret_cast<PyObject*>(&RepeatedCompositeContainer_Type),
+          NULL);
+      if (py_container == NULL) {
+        return NULL;
+      }
+      RepeatedCompositeContainer* container =
+          reinterpret_cast<RepeatedCompositeContainer*>(py_container);
+      PyObject* field = cdescriptor->descriptor_field;
+      PyObject* message_type = PyObject_GetAttrString(field, "message_type");
+      PyObject* concrete_class = PyObject_GetAttrString(message_type,
+                                                        "_concrete_class");
+      container->owner = self->owner;
+      container->parent = self->parent;
+      container->message = self->parent->message;
+      container->parent_field = cdescriptor;
+      container->subclass_init = concrete_class;
+      Py_DECREF(message_type);
+      PyDict_SetItem(self->values, key, py_container);
+      return py_container;
+    } else {
+      // COPIED
+      ScopedPyObjectPtr init_args(PyTuple_Pack(2, self->parent, cdescriptor));
+      PyObject* py_container = PyObject_CallObject(
+          reinterpret_cast<PyObject*>(&RepeatedScalarContainer_Type),
+          init_args);
+      if (py_container == NULL) {
+        return NULL;
+      }
+      PyDict_SetItem(self->values, key, py_container);
+      return py_container;
+    }
+  }
+  PyErr_SetString(PyExc_ValueError, "control reached unexpected line");
+  return NULL;
+}
+
+int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value) {
+  CFieldDescriptor* cdescriptor = InternalGetCDescriptorFromExtension(
+      key);
+  if (cdescriptor == NULL) {
+    return -1;
+  }
+  ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor));
+  const google::protobuf::FieldDescriptor* descriptor = cdescriptor->descriptor;
+  if (descriptor->label() != FieldDescriptor::LABEL_OPTIONAL ||
+      descriptor->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+    PyErr_SetString(PyExc_TypeError, "Extension is repeated and/or composite "
+                    "type");
+    return -1;
+  }
+  cmessage::AssureWritable(self->parent);
+  if (cmessage::InternalSetScalar(self->parent, descriptor, value) < 0) {
+    return -1;
+  }
+  // TODO(tibell): We shouldn't write scalars to the cache.
+  PyDict_SetItem(self->values, key, value);
+  return 0;
+}
+
+PyObject* ClearExtension(ExtensionDict* self, PyObject* extension) {
+  CFieldDescriptor* cdescriptor = InternalGetCDescriptorFromExtension(
+      extension);
+  if (cdescriptor == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor));
+  PyObject* value = PyDict_GetItem(self->values, extension);
+  if (value != NULL) {
+    if (ReleaseExtension(self, value, cdescriptor->descriptor) < 0) {
+      return NULL;
+    }
+  }
+  if (cmessage::ClearFieldByDescriptor(self->parent,
+                                       cdescriptor->descriptor) == NULL) {
+    return NULL;
+  }
+  if (PyDict_DelItem(self->values, extension) < 0) {
+    PyErr_Clear();
+  }
+  Py_RETURN_NONE;
+}
+
+PyObject* HasExtension(ExtensionDict* self, PyObject* extension) {
+  CFieldDescriptor* cdescriptor = InternalGetCDescriptorFromExtension(
+      extension);
+  if (cdescriptor == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor));
+  PyObject* result = cmessage::HasFieldByDescriptor(
+      self->parent, cdescriptor->descriptor);
+  return result;
+}
+
+PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name) {
+  ScopedPyObjectPtr extensions_by_name(PyObject_GetAttrString(
+      reinterpret_cast<PyObject*>(self->parent), "_extensions_by_name"));
+  if (extensions_by_name == NULL) {
+    return NULL;
+  }
+  PyObject* result = PyDict_GetItem(extensions_by_name, name);
+  if (result == NULL) {
+    Py_RETURN_NONE;
+  } else {
+    Py_INCREF(result);
+    return result;
+  }
+}
+
+int init(ExtensionDict* self, PyObject* args, PyObject* kwargs) {
+  self->parent = NULL;
+  self->message = NULL;
+  self->values = PyDict_New();
+  return 0;
+}
+
+void dealloc(ExtensionDict* self) {
+  Py_CLEAR(self->values);
+  self->owner.reset();
+  Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+static PyMappingMethods MpMethods = {
+  (lenfunc)len,               /* mp_length */
+  (binaryfunc)subscript,      /* mp_subscript */
+  (objobjargproc)ass_subscript,/* mp_ass_subscript */
+};
+
+#define EDMETHOD(name, args, doc) { #name, (PyCFunction)name, args, doc }
+static PyMethodDef Methods[] = {
+  EDMETHOD(ClearExtension, METH_O, "Clears an extension from the object."),
+  EDMETHOD(HasExtension, METH_O, "Checks if the object has an extension."),
+  EDMETHOD(_FindExtensionByName, METH_O,
+           "Finds an extension by name."),
+  { NULL, NULL }
+};
+
+}  // namespace extension_dict
+
+PyTypeObject ExtensionDict_Type = {
+  PyVarObject_HEAD_INIT(&PyType_Type, 0)
+  "google.protobuf.internal."
+  "cpp._message.ExtensionDict",        // tp_name
+  sizeof(ExtensionDict),               // tp_basicsize
+  0,                                   //  tp_itemsize
+  (destructor)extension_dict::dealloc,  //  tp_dealloc
+  0,                                   //  tp_print
+  0,                                   //  tp_getattr
+  0,                                   //  tp_setattr
+  0,                                   //  tp_compare
+  0,                                   //  tp_repr
+  0,                                   //  tp_as_number
+  0,                                   //  tp_as_sequence
+  &extension_dict::MpMethods,          //  tp_as_mapping
+  0,                                   //  tp_hash
+  0,                                   //  tp_call
+  0,                                   //  tp_str
+  0,                                   //  tp_getattro
+  0,                                   //  tp_setattro
+  0,                                   //  tp_as_buffer
+  Py_TPFLAGS_DEFAULT,                  //  tp_flags
+  "An extension dict",                 //  tp_doc
+  0,                                   //  tp_traverse
+  0,                                   //  tp_clear
+  0,                                   //  tp_richcompare
+  0,                                   //  tp_weaklistoffset
+  0,                                   //  tp_iter
+  0,                                   //  tp_iternext
+  extension_dict::Methods,             //  tp_methods
+  0,                                   //  tp_members
+  0,                                   //  tp_getset
+  0,                                   //  tp_base
+  0,                                   //  tp_dict
+  0,                                   //  tp_descr_get
+  0,                                   //  tp_descr_set
+  0,                                   //  tp_dictoffset
+  (initproc)extension_dict::init,      //  tp_init
+};
+
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/python/google/protobuf/pyext/extension_dict.h b/protobuf/python/google/protobuf/pyext/extension_dict.h
new file mode 100644
index 0000000..13c874a
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/extension_dict.h
@@ -0,0 +1,123 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__
+
+#include <Python.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+
+namespace google {
+namespace protobuf {
+
+class Message;
+class FieldDescriptor;
+
+using internal::shared_ptr;
+
+namespace python {
+
+struct CMessage;
+struct CFieldDescriptor;
+
+typedef struct ExtensionDict {
+  PyObject_HEAD;
+  shared_ptr<Message> owner;
+  CMessage* parent;
+  Message* message;
+  PyObject* values;
+} ExtensionDict;
+
+extern PyTypeObject ExtensionDict_Type;
+
+namespace extension_dict {
+
+// Gets the _cdescriptor reference to a CFieldDescriptor object given a
+// python descriptor object.
+//
+// Returns a new reference.
+CFieldDescriptor* InternalGetCDescriptorFromExtension(PyObject* extension);
+
+// Gets the number of extension values in this ExtensionDict as a python object.
+//
+// Returns a new reference.
+PyObject* len(ExtensionDict* self);
+
+// Releases extensions referenced outside this dictionary to keep outside
+// references alive.
+//
+// Returns 0 on success, -1 on failure.
+int ReleaseExtension(ExtensionDict* self,
+                     PyObject* extension,
+                     const google::protobuf::FieldDescriptor* descriptor);
+
+// Gets an extension from the dict for the given extension descriptor.
+//
+// Returns a new reference.
+PyObject* subscript(ExtensionDict* self, PyObject* key);
+
+// Assigns a value to an extension in the dict. Can only be used for singular
+// simple types.
+//
+// Returns 0 on success, -1 on failure.
+int ass_subscript(ExtensionDict* self, PyObject* key, PyObject* value);
+
+// Clears an extension from the dict. Will release the extension if there
+// is still an external reference left to it.
+//
+// Returns None on success.
+PyObject* ClearExtension(ExtensionDict* self,
+                                       PyObject* extension);
+
+// Checks if the dict has an extension.
+//
+// Returns a new python boolean reference.
+PyObject* HasExtension(ExtensionDict* self, PyObject* extension);
+
+// Gets an extension from the dict given the extension name as opposed to
+// descriptor.
+//
+// Returns a new reference.
+PyObject* _FindExtensionByName(ExtensionDict* self, PyObject* name);
+
+}  // namespace extension_dict
+}  // namespace python
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_PYTHON_CPP_EXTENSION_DICT_H__
diff --git a/protobuf/python/google/protobuf/pyext/message.cc b/protobuf/python/google/protobuf/pyext/message.cc
new file mode 100644
index 0000000..9fb7083
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/message.cc
@@ -0,0 +1,2561 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#include <google/protobuf/pyext/message.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+#include <string>
+#include <vector>
+
+#ifndef PyVarObject_HEAD_INIT
+#define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
+#endif
+#ifndef Py_TYPE
+#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+#endif
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/pyext/descriptor.h>
+#include <google/protobuf/pyext/extension_dict.h>
+#include <google/protobuf/pyext/repeated_composite_container.h>
+#include <google/protobuf/pyext/repeated_scalar_container.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyInt_Check PyLong_Check
+  #define PyInt_AsLong PyLong_AsLong
+  #define PyInt_FromLong PyLong_FromLong
+  #define PyInt_FromSize_t PyLong_FromSize_t
+  #define PyString_Check PyUnicode_Check
+  #define PyString_FromString PyUnicode_FromString
+  #define PyString_FromStringAndSize PyUnicode_FromStringAndSize
+  #if PY_VERSION_HEX < 0x03030000
+    #error "Python 3.0 - 3.2 are not supported."
+  #else
+  #define PyString_AsString(ob) \
+    (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AS_STRING(ob))
+  #endif
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+// Forward declarations
+namespace cmessage {
+static PyObject* GetDescriptor(CMessage* self, PyObject* name);
+static string GetMessageName(CMessage* self);
+int InternalReleaseFieldByDescriptor(
+    const google::protobuf::FieldDescriptor* field_descriptor,
+    PyObject* composite_field,
+    google::protobuf::Message* parent_message);
+}  // namespace cmessage
+
+// ---------------------------------------------------------------------
+// Visiting the composite children of a CMessage
+
+struct ChildVisitor {
+  // Returns 0 on success, -1 on failure.
+  int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
+    return 0;
+  }
+
+  // Returns 0 on success, -1 on failure.
+  int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
+    return 0;
+  }
+
+  // Returns 0 on success, -1 on failure.
+  int VisitCMessage(CMessage* cmessage,
+                    const google::protobuf::FieldDescriptor* field_descriptor) {
+    return 0;
+  }
+};
+
+// Apply a function to a composite field.  Does nothing if child is of
+// non-composite type.
+template<class Visitor>
+static int VisitCompositeField(const FieldDescriptor* descriptor,
+                               PyObject* child,
+                               Visitor visitor) {
+  if (descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+    if (descriptor->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+      RepeatedCompositeContainer* container =
+        reinterpret_cast<RepeatedCompositeContainer*>(child);
+      if (visitor.VisitRepeatedCompositeContainer(container) == -1)
+        return -1;
+    } else {
+      RepeatedScalarContainer* container =
+        reinterpret_cast<RepeatedScalarContainer*>(child);
+      if (visitor.VisitRepeatedScalarContainer(container) == -1)
+        return -1;
+    }
+  } else if (descriptor->cpp_type() ==
+             google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+    CMessage* cmsg = reinterpret_cast<CMessage*>(child);
+    if (visitor.VisitCMessage(cmsg, descriptor) == -1)
+      return -1;
+  }
+  // The ExtensionDict might contain non-composite fields, which we
+  // skip here.
+  return 0;
+}
+
+// Visit each composite field and extension field of this CMessage.
+// Returns -1 on error and 0 on success.
+template<class Visitor>
+int ForEachCompositeField(CMessage* self, Visitor visitor) {
+  Py_ssize_t pos = 0;
+  PyObject* key;
+  PyObject* field;
+
+  // Visit normal fields.
+  while (PyDict_Next(self->composite_fields, &pos, &key, &field)) {
+    PyObject* cdescriptor = cmessage::GetDescriptor(self, key);
+    if (cdescriptor != NULL) {
+      const google::protobuf::FieldDescriptor* descriptor =
+          reinterpret_cast<CFieldDescriptor*>(cdescriptor)->descriptor;
+      if (VisitCompositeField(descriptor, field, visitor) == -1)
+        return -1;
+    }
+  }
+
+  // Visit extension fields.
+  if (self->extensions != NULL) {
+    while (PyDict_Next(self->extensions->values, &pos, &key, &field)) {
+      CFieldDescriptor* cdescriptor =
+          extension_dict::InternalGetCDescriptorFromExtension(key);
+      if (cdescriptor == NULL)
+        return -1;
+      if (VisitCompositeField(cdescriptor->descriptor, field, visitor) == -1)
+        return -1;
+    }
+  }
+
+  return 0;
+}
+
+// ---------------------------------------------------------------------
+
+// Constants used for integer type range checking.
+PyObject* kPythonZero;
+PyObject* kint32min_py;
+PyObject* kint32max_py;
+PyObject* kuint32max_py;
+PyObject* kint64min_py;
+PyObject* kint64max_py;
+PyObject* kuint64max_py;
+
+PyObject* EnumTypeWrapper_class;
+PyObject* EncodeError_class;
+PyObject* DecodeError_class;
+PyObject* PickleError_class;
+
+// Constant PyString values used for GetAttr/GetItem.
+static PyObject* kDESCRIPTOR;
+static PyObject* k__descriptors;
+static PyObject* kfull_name;
+static PyObject* kname;
+static PyObject* kmessage_type;
+static PyObject* kis_extendable;
+static PyObject* kextensions_by_name;
+static PyObject* k_extensions_by_name;
+static PyObject* k_extensions_by_number;
+static PyObject* k_concrete_class;
+static PyObject* kfields_by_name;
+
+static CDescriptorPool* descriptor_pool;
+
+/* Is 64bit */
+void FormatTypeError(PyObject* arg, char* expected_types) {
+  PyObject* repr = PyObject_Repr(arg);
+  if (repr) {
+    PyErr_Format(PyExc_TypeError,
+                 "%.100s has type %.100s, but expected one of: %s",
+                 PyString_AsString(repr),
+                 Py_TYPE(arg)->tp_name,
+                 expected_types);
+    Py_DECREF(repr);
+  }
+}
+
+template<class T>
+bool CheckAndGetInteger(
+    PyObject* arg, T* value, PyObject* min, PyObject* max) {
+  bool is_long = PyLong_Check(arg);
+#if PY_MAJOR_VERSION < 3
+  if (!PyInt_Check(arg) && !is_long) {
+    FormatTypeError(arg, "int, long");
+    return false;
+  }
+  if (PyObject_Compare(min, arg) > 0 || PyObject_Compare(max, arg) < 0) {
+#else
+  if (!is_long) {
+    FormatTypeError(arg, "int");
+    return false;
+  }
+  if (PyObject_RichCompareBool(min, arg, Py_LE) != 1 ||
+      PyObject_RichCompareBool(max, arg, Py_GE) != 1) {
+#endif
+    PyObject *s = PyObject_Str(arg);
+    if (s) {
+      PyErr_Format(PyExc_ValueError,
+                   "Value out of range: %s",
+                   PyString_AsString(s));
+      Py_DECREF(s);
+    }
+    return false;
+  }
+#if PY_MAJOR_VERSION < 3
+  if (!is_long) {
+    *value = static_cast<T>(PyInt_AsLong(arg));
+  } else  // NOLINT
+#endif
+  {
+    if (min == kPythonZero) {
+      *value = static_cast<T>(PyLong_AsUnsignedLongLong(arg));
+    } else {
+      *value = static_cast<T>(PyLong_AsLongLong(arg));
+    }
+  }
+  return true;
+}
+
+// These are referenced by repeated_scalar_container, and must
+// be explicitly instantiated.
+template bool CheckAndGetInteger<int32>(
+    PyObject*, int32*, PyObject*, PyObject*);
+template bool CheckAndGetInteger<int64>(
+    PyObject*, int64*, PyObject*, PyObject*);
+template bool CheckAndGetInteger<uint32>(
+    PyObject*, uint32*, PyObject*, PyObject*);
+template bool CheckAndGetInteger<uint64>(
+    PyObject*, uint64*, PyObject*, PyObject*);
+
+bool CheckAndGetDouble(PyObject* arg, double* value) {
+  if (!PyInt_Check(arg) && !PyLong_Check(arg) &&
+      !PyFloat_Check(arg)) {
+    FormatTypeError(arg, "int, long, float");
+    return false;
+  }
+  *value = PyFloat_AsDouble(arg);
+  return true;
+}
+
+bool CheckAndGetFloat(PyObject* arg, float* value) {
+  double double_value;
+  if (!CheckAndGetDouble(arg, &double_value)) {
+    return false;
+  }
+  *value = static_cast<float>(double_value);
+  return true;
+}
+
+bool CheckAndGetBool(PyObject* arg, bool* value) {
+  if (!PyInt_Check(arg) && !PyBool_Check(arg) && !PyLong_Check(arg)) {
+    FormatTypeError(arg, "int, long, bool");
+    return false;
+  }
+  *value = static_cast<bool>(PyInt_AsLong(arg));
+  return true;
+}
+
+bool CheckAndSetString(
+    PyObject* arg, google::protobuf::Message* message,
+    const google::protobuf::FieldDescriptor* descriptor,
+    const google::protobuf::Reflection* reflection,
+    bool append,
+    int index) {
+  GOOGLE_DCHECK(descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING ||
+         descriptor->type() == google::protobuf::FieldDescriptor::TYPE_BYTES);
+  if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) {
+    if (!PyBytes_Check(arg) && !PyUnicode_Check(arg)) {
+      FormatTypeError(arg, "bytes, unicode");
+      return false;
+    }
+
+    if (PyBytes_Check(arg)) {
+      PyObject* unicode = PyUnicode_FromEncodedObject(arg, "ascii", NULL);
+      if (unicode == NULL) {
+        PyObject* repr = PyObject_Repr(arg);
+        PyErr_Format(PyExc_ValueError,
+                     "%s has type str, but isn't in 7-bit ASCII "
+                     "encoding. Non-ASCII strings must be converted to "
+                     "unicode objects before being added.",
+                     PyString_AsString(repr));
+        Py_DECREF(repr);
+        return false;
+      } else {
+        Py_DECREF(unicode);
+      }
+    }
+  } else if (!PyBytes_Check(arg)) {
+    FormatTypeError(arg, "bytes");
+    return false;
+  }
+
+  PyObject* encoded_string = NULL;
+  if (descriptor->type() == google::protobuf::FieldDescriptor::TYPE_STRING) {
+    if (PyBytes_Check(arg)) {
+#if PY_MAJOR_VERSION < 3
+      encoded_string = PyString_AsEncodedObject(arg, "utf-8", NULL);
+#else
+      encoded_string = arg;  // Already encoded.
+      Py_INCREF(encoded_string);
+#endif
+    } else {
+      encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL);
+    }
+  } else {
+    // In this case field type is "bytes".
+    encoded_string = arg;
+    Py_INCREF(encoded_string);
+  }
+
+  if (encoded_string == NULL) {
+    return false;
+  }
+
+  char* value;
+  Py_ssize_t value_len;
+  if (PyBytes_AsStringAndSize(encoded_string, &value, &value_len) < 0) {
+    Py_DECREF(encoded_string);
+    return false;
+  }
+
+  string value_string(value, value_len);
+  if (append) {
+    reflection->AddString(message, descriptor, value_string);
+  } else if (index < 0) {
+    reflection->SetString(message, descriptor, value_string);
+  } else {
+    reflection->SetRepeatedString(message, descriptor, index, value_string);
+  }
+  Py_DECREF(encoded_string);
+  return true;
+}
+
+PyObject* ToStringObject(
+    const google::protobuf::FieldDescriptor* descriptor, string value) {
+  if (descriptor->type() != google::protobuf::FieldDescriptor::TYPE_STRING) {
+    return PyBytes_FromStringAndSize(value.c_str(), value.length());
+  }
+
+  PyObject* result = PyUnicode_DecodeUTF8(value.c_str(), value.length(), NULL);
+  // If the string can't be decoded in UTF-8, just return a string object that
+  // contains the raw bytes. This can't happen if the value was assigned using
+  // the members of the Python message object, but can happen if the values were
+  // parsed from the wire (binary).
+  if (result == NULL) {
+    PyErr_Clear();
+    result = PyBytes_FromStringAndSize(value.c_str(), value.length());
+  }
+  return result;
+}
+
+google::protobuf::DynamicMessageFactory* global_message_factory;
+
+namespace cmessage {
+
+static int MaybeReleaseOverlappingOneofField(
+    CMessage* cmessage,
+    const google::protobuf::FieldDescriptor* field) {
+#ifdef GOOGLE_PROTOBUF_HAS_ONEOF
+  google::protobuf::Message* message = cmessage->message;
+  const google::protobuf::Reflection* reflection = message->GetReflection();
+  if (!field->containing_oneof() ||
+      !reflection->HasOneof(*message, field->containing_oneof()) ||
+      reflection->HasField(*message, field)) {
+    // No other field in this oneof, no need to release.
+    return 0;
+  }
+
+  const OneofDescriptor* oneof = field->containing_oneof();
+  const FieldDescriptor* existing_field =
+      reflection->GetOneofFieldDescriptor(*message, oneof);
+  if (existing_field->cpp_type() != google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+    // Non-message fields don't need to be released.
+    return 0;
+  }
+  const char* field_name = existing_field->name().c_str();
+  PyObject* child_message = PyDict_GetItemString(
+      cmessage->composite_fields, field_name);
+  if (child_message == NULL) {
+    // No python reference to this field so no need to release.
+    return 0;
+  }
+
+  if (InternalReleaseFieldByDescriptor(
+          existing_field, child_message, message) < 0) {
+    return -1;
+  }
+  return PyDict_DelItemString(cmessage->composite_fields, field_name);
+#else
+  return 0;
+#endif
+}
+
+// ---------------------------------------------------------------------
+// Making a message writable
+
+static google::protobuf::Message* GetMutableMessage(
+    CMessage* parent,
+    const google::protobuf::FieldDescriptor* parent_field) {
+  google::protobuf::Message* parent_message = parent->message;
+  const google::protobuf::Reflection* reflection = parent_message->GetReflection();
+  if (MaybeReleaseOverlappingOneofField(parent, parent_field) < 0) {
+    return NULL;
+  }
+  return reflection->MutableMessage(
+      parent_message, parent_field, global_message_factory);
+}
+
+struct FixupMessageReference : public ChildVisitor {
+  // message must outlive this object.
+  explicit FixupMessageReference(google::protobuf::Message* message) :
+      message_(message) {}
+
+  int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
+    container->message = message_;
+    return 0;
+  }
+
+  int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
+    container->message = message_;
+    return 0;
+  }
+
+ private:
+  google::protobuf::Message* message_;
+};
+
+int AssureWritable(CMessage* self) {
+  if (self == NULL || !self->read_only) {
+    return 0;
+  }
+
+  if (self->parent == NULL) {
+    // If parent is NULL but we are trying to modify a read-only message, this
+    // is a reference to a constant default instance that needs to be replaced
+    // with a mutable top-level message.
+    const Message* prototype = global_message_factory->GetPrototype(
+        self->message->GetDescriptor());
+    self->message = prototype->New();
+    self->owner.reset(self->message);
+  } else {
+    // Otherwise, we need a mutable child message.
+    if (AssureWritable(self->parent) == -1)
+      return -1;
+
+    // Make self->message writable.
+    google::protobuf::Message* parent_message = self->parent->message;
+    google::protobuf::Message* mutable_message = GetMutableMessage(
+        self->parent,
+        self->parent_field->descriptor);
+    if (mutable_message == NULL) {
+      return -1;
+    }
+    self->message = mutable_message;
+  }
+  self->read_only = false;
+
+  // When a CMessage is made writable its Message pointer is updated
+  // to point to a new mutable Message.  When that happens we need to
+  // update any references to the old, read-only CMessage.  There are
+  // three places such references occur: RepeatedScalarContainer,
+  // RepeatedCompositeContainer, and ExtensionDict.
+  if (self->extensions != NULL)
+    self->extensions->message = self->message;
+  if (ForEachCompositeField(self, FixupMessageReference(self->message)) == -1)
+    return -1;
+
+  return 0;
+}
+
+// --- Globals:
+
+static PyObject* GetDescriptor(CMessage* self, PyObject* name) {
+  PyObject* descriptors =
+      PyDict_GetItem(Py_TYPE(self)->tp_dict, k__descriptors);
+  if (descriptors == NULL) {
+    PyErr_SetString(PyExc_TypeError, "No __descriptors");
+    return NULL;
+  }
+
+  return PyDict_GetItem(descriptors, name);
+}
+
+static const google::protobuf::Message* CreateMessage(const char* message_type) {
+  string message_name(message_type);
+  const google::protobuf::Descriptor* descriptor =
+      GetDescriptorPool()->FindMessageTypeByName(message_name);
+  if (descriptor == NULL) {
+    PyErr_SetString(PyExc_TypeError, message_type);
+    return NULL;
+  }
+  return global_message_factory->GetPrototype(descriptor);
+}
+
+// If cmessage_list is not NULL, this function releases values into the
+// container CMessages instead of just removing. Repeated composite container
+// needs to do this to make sure CMessages stay alive if they're still
+// referenced after deletion. Repeated scalar container doesn't need to worry.
+int InternalDeleteRepeatedField(
+    google::protobuf::Message* message,
+    const google::protobuf::FieldDescriptor* field_descriptor,
+    PyObject* slice,
+    PyObject* cmessage_list) {
+  Py_ssize_t length, from, to, step, slice_length;
+  const google::protobuf::Reflection* reflection = message->GetReflection();
+  int min, max;
+  length = reflection->FieldSize(*message, field_descriptor);
+
+  if (PyInt_Check(slice) || PyLong_Check(slice)) {
+    from = to = PyLong_AsLong(slice);
+    if (from < 0) {
+      from = to = length + from;
+    }
+    step = 1;
+    min = max = from;
+
+    // Range check.
+    if (from < 0 || from >= length) {
+      PyErr_Format(PyExc_IndexError, "list assignment index out of range");
+      return -1;
+    }
+  } else if (PySlice_Check(slice)) {
+    from = to = step = slice_length = 0;
+    PySlice_GetIndicesEx(
+#if PY_MAJOR_VERSION < 3
+        reinterpret_cast<PySliceObject*>(slice),
+#else
+        slice,
+#endif
+        length, &from, &to, &step, &slice_length);
+    if (from < to) {
+      min = from;
+      max = to - 1;
+    } else {
+      min = to + 1;
+      max = from;
+    }
+  } else {
+    PyErr_SetString(PyExc_TypeError, "list indices must be integers");
+    return -1;
+  }
+
+  Py_ssize_t i = from;
+  std::vector<bool> to_delete(length, false);
+  while (i >= min && i <= max) {
+    to_delete[i] = true;
+    i += step;
+  }
+
+  to = 0;
+  for (i = 0; i < length; ++i) {
+    if (!to_delete[i]) {
+      if (i != to) {
+        reflection->SwapElements(message, field_descriptor, i, to);
+        if (cmessage_list != NULL) {
+          // If a list of cmessages is passed in (i.e. from a repeated
+          // composite container), swap those as well to correspond to the
+          // swaps in the underlying message so they're in the right order
+          // when we start releasing.
+          PyObject* tmp = PyList_GET_ITEM(cmessage_list, i);
+          PyList_SET_ITEM(cmessage_list, i,
+                          PyList_GET_ITEM(cmessage_list, to));
+          PyList_SET_ITEM(cmessage_list, to, tmp);
+        }
+      }
+      ++to;
+    }
+  }
+
+  while (i > to) {
+    if (cmessage_list == NULL) {
+      reflection->RemoveLast(message, field_descriptor);
+    } else {
+      CMessage* last_cmessage = reinterpret_cast<CMessage*>(
+          PyList_GET_ITEM(cmessage_list, PyList_GET_SIZE(cmessage_list) - 1));
+      repeated_composite_container::ReleaseLastTo(
+          field_descriptor, message, last_cmessage);
+      if (PySequence_DelItem(cmessage_list, -1) < 0) {
+        return -1;
+      }
+    }
+    --i;
+  }
+
+  return 0;
+}
+
+int InitAttributes(CMessage* self, PyObject* arg, PyObject* kwargs) {
+  ScopedPyObjectPtr descriptor;
+  if (arg == NULL) {
+    descriptor.reset(
+        PyObject_GetAttr(reinterpret_cast<PyObject*>(self), kDESCRIPTOR));
+    if (descriptor == NULL) {
+      return NULL;
+    }
+  } else {
+    descriptor.reset(arg);
+    descriptor.inc();
+  }
+  ScopedPyObjectPtr is_extendable(PyObject_GetAttr(descriptor, kis_extendable));
+  if (is_extendable == NULL) {
+    return NULL;
+  }
+  int retcode = PyObject_IsTrue(is_extendable);
+  if (retcode == -1) {
+    return NULL;
+  }
+  if (retcode) {
+    PyObject* py_extension_dict = PyObject_CallObject(
+        reinterpret_cast<PyObject*>(&ExtensionDict_Type), NULL);
+    if (py_extension_dict == NULL) {
+      return NULL;
+    }
+    ExtensionDict* extension_dict = reinterpret_cast<ExtensionDict*>(
+        py_extension_dict);
+    extension_dict->parent = self;
+    extension_dict->message = self->message;
+    self->extensions = extension_dict;
+  }
+
+  if (kwargs == NULL) {
+    return 0;
+  }
+
+  Py_ssize_t pos = 0;
+  PyObject* name;
+  PyObject* value;
+  while (PyDict_Next(kwargs, &pos, &name, &value)) {
+    if (!PyString_Check(name)) {
+      PyErr_SetString(PyExc_ValueError, "Field name must be a string");
+      return -1;
+    }
+    PyObject* py_cdescriptor = GetDescriptor(self, name);
+    if (py_cdescriptor == NULL) {
+      PyErr_Format(PyExc_ValueError, "Protocol message has no \"%s\" field.",
+                   PyString_AsString(name));
+      return -1;
+    }
+    const google::protobuf::FieldDescriptor* descriptor =
+        reinterpret_cast<CFieldDescriptor*>(py_cdescriptor)->descriptor;
+    if (descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+      ScopedPyObjectPtr container(GetAttr(self, name));
+      if (container == NULL) {
+        return -1;
+      }
+      if (descriptor->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+        if (repeated_composite_container::Extend(
+                reinterpret_cast<RepeatedCompositeContainer*>(container.get()),
+                value)
+            == NULL) {
+          return -1;
+        }
+      } else {
+        if (repeated_scalar_container::Extend(
+                reinterpret_cast<RepeatedScalarContainer*>(container.get()),
+                value) ==
+            NULL) {
+          return -1;
+        }
+      }
+    } else if (descriptor->cpp_type() ==
+               google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+      ScopedPyObjectPtr message(GetAttr(self, name));
+      if (message == NULL) {
+        return -1;
+      }
+      if (MergeFrom(reinterpret_cast<CMessage*>(message.get()),
+                             value) == NULL) {
+        return -1;
+      }
+    } else {
+      if (SetAttr(self, name, value) < 0) {
+        return -1;
+      }
+    }
+  }
+  return 0;
+}
+
+static PyObject* New(PyTypeObject* type, PyObject* args, PyObject* kwargs) {
+  CMessage* self = reinterpret_cast<CMessage*>(type->tp_alloc(type, 0));
+  if (self == NULL) {
+    return NULL;
+  }
+
+  self->message = NULL;
+  self->parent = NULL;
+  self->parent_field = NULL;
+  self->read_only = false;
+  self->extensions = NULL;
+
+  self->composite_fields = PyDict_New();
+  if (self->composite_fields == NULL) {
+    return NULL;
+  }
+  return reinterpret_cast<PyObject*>(self);
+}
+
+PyObject* NewEmpty(PyObject* type) {
+  return New(reinterpret_cast<PyTypeObject*>(type), NULL, NULL);
+}
+
+static int Init(CMessage* self, PyObject* args, PyObject* kwargs) {
+  if (kwargs == NULL) {
+    // TODO(anuraag): Set error
+    return -1;
+  }
+
+  PyObject* descriptor = PyTuple_GetItem(args, 0);
+  if (descriptor == NULL || PyTuple_Size(args) != 1) {
+    PyErr_SetString(PyExc_ValueError, "args must contain one arg: descriptor");
+    return -1;
+  }
+
+  ScopedPyObjectPtr py_message_type(PyObject_GetAttr(descriptor, kfull_name));
+  if (py_message_type == NULL) {
+    return -1;
+  }
+
+  const char* message_type = PyString_AsString(py_message_type.get());
+  const google::protobuf::Message* message = CreateMessage(message_type);
+  if (message == NULL) {
+    return -1;
+  }
+
+  self->message = message->New();
+  self->owner.reset(self->message);
+
+  if (InitAttributes(self, descriptor, kwargs) < 0) {
+    return -1;
+  }
+  return 0;
+}
+
+// ---------------------------------------------------------------------
+// Deallocating a CMessage
+//
+// Deallocating a CMessage requires that we clear any weak references
+// from children to the message being deallocated.
+
+// Clear the weak reference from the child to the parent.
+struct ClearWeakReferences : public ChildVisitor {
+  int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
+    container->parent = NULL;
+    // The elements in the container have the same parent as the
+    // container itself, so NULL out that pointer as well.
+    const Py_ssize_t n = PyList_GET_SIZE(container->child_messages);
+    for (Py_ssize_t i = 0; i < n; ++i) {
+      CMessage* child_cmessage = reinterpret_cast<CMessage*>(
+          PyList_GET_ITEM(container->child_messages, i));
+      child_cmessage->parent = NULL;
+    }
+    return 0;
+  }
+
+  int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
+    container->parent = NULL;
+    return 0;
+  }
+
+  int VisitCMessage(CMessage* cmessage,
+                    const google::protobuf::FieldDescriptor* field_descriptor) {
+    cmessage->parent = NULL;
+    return 0;
+  }
+};
+
+static void Dealloc(CMessage* self) {
+  // Null out all weak references from children to this message.
+  GOOGLE_CHECK_EQ(0, ForEachCompositeField(self, ClearWeakReferences()));
+
+  Py_CLEAR(self->extensions);
+  Py_CLEAR(self->composite_fields);
+  self->owner.reset();
+  Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+// ---------------------------------------------------------------------
+
+
+PyObject* IsInitialized(CMessage* self, PyObject* args) {
+  PyObject* errors = NULL;
+  if (PyArg_ParseTuple(args, "|O", &errors) < 0) {
+    return NULL;
+  }
+  if (self->message->IsInitialized()) {
+    Py_RETURN_TRUE;
+  }
+  if (errors != NULL) {
+    ScopedPyObjectPtr initialization_errors(
+        FindInitializationErrors(self));
+    if (initialization_errors == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr extend_name(PyString_FromString("extend"));
+    if (extend_name == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr result(PyObject_CallMethodObjArgs(
+        errors,
+        extend_name.get(),
+        initialization_errors.get(),
+        NULL));
+    if (result == NULL) {
+      return NULL;
+    }
+  }
+  Py_RETURN_FALSE;
+}
+
+PyObject* HasFieldByDescriptor(
+    CMessage* self, const google::protobuf::FieldDescriptor* field_descriptor) {
+  google::protobuf::Message* message = self->message;
+  if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+    PyErr_SetString(PyExc_KeyError,
+                    "Field does not belong to message!");
+    return NULL;
+  }
+  if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+    PyErr_SetString(PyExc_KeyError,
+                    "Field is repeated. A singular method is required.");
+    return NULL;
+  }
+  bool has_field =
+      message->GetReflection()->HasField(*message, field_descriptor);
+  return PyBool_FromLong(has_field ? 1 : 0);
+}
+
+const google::protobuf::FieldDescriptor* FindFieldWithOneofs(
+    const google::protobuf::Message* message, const char* field_name, bool* in_oneof) {
+  const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
+  const google::protobuf::FieldDescriptor* field_descriptor =
+      descriptor->FindFieldByName(field_name);
+  if (field_descriptor == NULL) {
+    const google::protobuf::OneofDescriptor* oneof_desc =
+      message->GetDescriptor()->FindOneofByName(field_name);
+    if (oneof_desc == NULL) {
+      *in_oneof = false;
+      return NULL;
+    } else {
+      *in_oneof = true;
+      return message->GetReflection()->GetOneofFieldDescriptor(
+          *message, oneof_desc);
+    }
+  }
+  return field_descriptor;
+}
+
+PyObject* HasField(CMessage* self, PyObject* arg) {
+#if PY_MAJOR_VERSION < 3
+  char* field_name;
+  if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) {
+#else
+  char* field_name = PyUnicode_AsUTF8(arg);
+  if (!field_name) {
+#endif
+    return NULL;
+  }
+
+  google::protobuf::Message* message = self->message;
+  const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
+  bool is_in_oneof;
+  const google::protobuf::FieldDescriptor* field_descriptor =
+      FindFieldWithOneofs(message, field_name, &is_in_oneof);
+  if (field_descriptor == NULL) {
+    if (!is_in_oneof) {
+      PyErr_Format(PyExc_ValueError, "Unknown field %s.", field_name);
+      return NULL;
+    } else {
+      Py_RETURN_FALSE;
+    }
+  }
+
+  if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+    PyErr_Format(PyExc_ValueError,
+                 "Protocol message has no singular \"%s\" field.", field_name);
+    return NULL;
+  }
+
+  bool has_field =
+      message->GetReflection()->HasField(*message, field_descriptor);
+  if (!has_field && field_descriptor->cpp_type() ==
+      google::protobuf::FieldDescriptor::CPPTYPE_ENUM) {
+    // We may have an invalid enum value stored in the UnknownFieldSet and need
+    // to check presence in there as well.
+    const google::protobuf::UnknownFieldSet& unknown_field_set =
+        message->GetReflection()->GetUnknownFields(*message);
+    for (int i = 0; i < unknown_field_set.field_count(); ++i) {
+      if (unknown_field_set.field(i).number() == field_descriptor->number()) {
+        Py_RETURN_TRUE;
+      }
+    }
+    Py_RETURN_FALSE;
+  }
+  return PyBool_FromLong(has_field ? 1 : 0);
+}
+
+PyObject* ClearExtension(CMessage* self, PyObject* arg) {
+  if (self->extensions != NULL) {
+    return extension_dict::ClearExtension(self->extensions, arg);
+  }
+  PyErr_SetString(PyExc_TypeError, "Message is not extendable");
+  return NULL;
+}
+
+PyObject* HasExtension(CMessage* self, PyObject* arg) {
+  if (self->extensions != NULL) {
+    return extension_dict::HasExtension(self->extensions, arg);
+  }
+  PyErr_SetString(PyExc_TypeError, "Message is not extendable");
+  return NULL;
+}
+
+// ---------------------------------------------------------------------
+// Releasing messages
+//
+// The Python API's ClearField() and Clear() methods behave
+// differently than their C++ counterparts.  While the C++ versions
+// clears the children the Python versions detaches the children,
+// without touching their content.  This impedance mismatch causes
+// some complexity in the implementation, which is captured in this
+// section.
+//
+// When a CMessage field is cleared we need to:
+//
+// * Release the Message used as the backing store for the CMessage
+//   from its parent.
+//
+// * Change the owner field of the released CMessage and all of its
+//   children to point to the newly released Message.
+//
+// * Clear the weak references from the released CMessage to the
+//   parent.
+//
+// When a RepeatedCompositeContainer field is cleared we need to:
+//
+// * Release all the Message used as the backing store for the
+//   CMessages stored in the container.
+//
+// * Change the owner field of all the released CMessage and all of
+//   their children to point to the newly released Messages.
+//
+// * Clear the weak references from the released container to the
+//   parent.
+
+struct SetOwnerVisitor : public ChildVisitor {
+  // new_owner must outlive this object.
+  explicit SetOwnerVisitor(const shared_ptr<Message>& new_owner)
+      : new_owner_(new_owner) {}
+
+  int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
+    repeated_composite_container::SetOwner(container, new_owner_);
+    return 0;
+  }
+
+  int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
+    repeated_scalar_container::SetOwner(container, new_owner_);
+    return 0;
+  }
+
+  int VisitCMessage(CMessage* cmessage,
+                    const google::protobuf::FieldDescriptor* field_descriptor) {
+    return SetOwner(cmessage, new_owner_);
+  }
+
+ private:
+  const shared_ptr<Message>& new_owner_;
+};
+
+// Change the owner of this CMessage and all its children, recursively.
+int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner) {
+  self->owner = new_owner;
+  if (ForEachCompositeField(self, SetOwnerVisitor(new_owner)) == -1)
+    return -1;
+  return 0;
+}
+
+// Releases the message specified by 'field' and returns the
+// pointer. If the field does not exist a new message is created using
+// 'descriptor'. The caller takes ownership of the returned pointer.
+Message* ReleaseMessage(google::protobuf::Message* message,
+                        const google::protobuf::Descriptor* descriptor,
+                        const google::protobuf::FieldDescriptor* field_descriptor) {
+  Message* released_message = message->GetReflection()->ReleaseMessage(
+      message, field_descriptor, global_message_factory);
+  // ReleaseMessage will return NULL which differs from
+  // child_cmessage->message, if the field does not exist.  In this case,
+  // the latter points to the default instance via a const_cast<>, so we
+  // have to reset it to a new mutable object since we are taking ownership.
+  if (released_message == NULL) {
+    const Message* prototype = global_message_factory->GetPrototype(
+        descriptor);
+    GOOGLE_DCHECK(prototype != NULL);
+    released_message = prototype->New();
+  }
+
+  return released_message;
+}
+
+int ReleaseSubMessage(google::protobuf::Message* message,
+                      const google::protobuf::FieldDescriptor* field_descriptor,
+                      CMessage* child_cmessage) {
+  // Release the Message
+  shared_ptr<Message> released_message(ReleaseMessage(
+      message, child_cmessage->message->GetDescriptor(), field_descriptor));
+  child_cmessage->message = released_message.get();
+  child_cmessage->owner.swap(released_message);
+  child_cmessage->parent = NULL;
+  child_cmessage->parent_field = NULL;
+  child_cmessage->read_only = false;
+  return ForEachCompositeField(child_cmessage,
+                               SetOwnerVisitor(child_cmessage->owner));
+}
+
+struct ReleaseChild : public ChildVisitor {
+  // message must outlive this object.
+  explicit ReleaseChild(google::protobuf::Message* parent_message) :
+      parent_message_(parent_message) {}
+
+  int VisitRepeatedCompositeContainer(RepeatedCompositeContainer* container) {
+    return repeated_composite_container::Release(
+        reinterpret_cast<RepeatedCompositeContainer*>(container));
+  }
+
+  int VisitRepeatedScalarContainer(RepeatedScalarContainer* container) {
+    return repeated_scalar_container::Release(
+        reinterpret_cast<RepeatedScalarContainer*>(container));
+  }
+
+  int VisitCMessage(CMessage* cmessage,
+                    const google::protobuf::FieldDescriptor* field_descriptor) {
+    return ReleaseSubMessage(parent_message_, field_descriptor,
+        reinterpret_cast<CMessage*>(cmessage));
+  }
+
+  google::protobuf::Message* parent_message_;
+};
+
+int InternalReleaseFieldByDescriptor(
+    const google::protobuf::FieldDescriptor* field_descriptor,
+    PyObject* composite_field,
+    google::protobuf::Message* parent_message) {
+  return VisitCompositeField(
+      field_descriptor,
+      composite_field,
+      ReleaseChild(parent_message));
+}
+
+int InternalReleaseField(CMessage* self, PyObject* composite_field,
+                         PyObject* name) {
+  PyObject* cdescriptor = GetDescriptor(self, name);
+  if (cdescriptor != NULL) {
+    const google::protobuf::FieldDescriptor* descriptor =
+        reinterpret_cast<CFieldDescriptor*>(cdescriptor)->descriptor;
+    return InternalReleaseFieldByDescriptor(
+        descriptor, composite_field, self->message);
+  }
+
+  return 0;
+}
+
+PyObject* ClearFieldByDescriptor(
+    CMessage* self,
+    const google::protobuf::FieldDescriptor* descriptor) {
+  if (!FIELD_BELONGS_TO_MESSAGE(descriptor, self->message)) {
+    PyErr_SetString(PyExc_KeyError,
+                    "Field does not belong to message!");
+    return NULL;
+  }
+  AssureWritable(self);
+  self->message->GetReflection()->ClearField(self->message, descriptor);
+  Py_RETURN_NONE;
+}
+
+PyObject* ClearField(CMessage* self, PyObject* arg) {
+  char* field_name;
+  if (!PyString_Check(arg)) {
+    PyErr_SetString(PyExc_TypeError, "field name must be a string");
+    return NULL;
+  }
+#if PY_MAJOR_VERSION < 3
+  if (PyString_AsStringAndSize(arg, &field_name, NULL) < 0) {
+    return NULL;
+  }
+#else
+  field_name = PyUnicode_AsUTF8(arg);
+#endif
+  AssureWritable(self);
+  google::protobuf::Message* message = self->message;
+  const google::protobuf::Descriptor* descriptor = message->GetDescriptor();
+  ScopedPyObjectPtr arg_in_oneof;
+  bool is_in_oneof;
+  const google::protobuf::FieldDescriptor* field_descriptor =
+      FindFieldWithOneofs(message, field_name, &is_in_oneof);
+  if (field_descriptor == NULL) {
+    if (!is_in_oneof) {
+      PyErr_Format(PyExc_ValueError,
+                   "Protocol message has no \"%s\" field.", field_name);
+      return NULL;
+    } else {
+      Py_RETURN_NONE;
+    }
+  } else if (is_in_oneof) {
+    arg_in_oneof.reset(PyString_FromString(field_descriptor->name().c_str()));
+    arg = arg_in_oneof.get();
+  }
+
+  PyObject* composite_field = PyDict_GetItem(self->composite_fields,
+                                             arg);
+
+  // Only release the field if there's a possibility that there are
+  // references to it.
+  if (composite_field != NULL) {
+    if (InternalReleaseField(self, composite_field, arg) < 0) {
+      return NULL;
+    }
+    PyDict_DelItem(self->composite_fields, arg);
+  }
+  message->GetReflection()->ClearField(message, field_descriptor);
+  if (field_descriptor->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_ENUM) {
+    google::protobuf::UnknownFieldSet* unknown_field_set =
+        message->GetReflection()->MutableUnknownFields(message);
+    unknown_field_set->DeleteByNumber(field_descriptor->number());
+  }
+
+  Py_RETURN_NONE;
+}
+
+PyObject* Clear(CMessage* self) {
+  AssureWritable(self);
+  if (ForEachCompositeField(self, ReleaseChild(self->message)) == -1)
+    return NULL;
+
+  // The old ExtensionDict still aliases this CMessage, but all its
+  // fields have been released.
+  if (self->extensions != NULL) {
+    Py_CLEAR(self->extensions);
+    PyObject* py_extension_dict = PyObject_CallObject(
+        reinterpret_cast<PyObject*>(&ExtensionDict_Type), NULL);
+    if (py_extension_dict == NULL) {
+      return NULL;
+    }
+    ExtensionDict* extension_dict = reinterpret_cast<ExtensionDict*>(
+        py_extension_dict);
+    extension_dict->parent = self;
+    extension_dict->message = self->message;
+    self->extensions = extension_dict;
+  }
+  PyDict_Clear(self->composite_fields);
+  self->message->Clear();
+  Py_RETURN_NONE;
+}
+
+// ---------------------------------------------------------------------
+
+static string GetMessageName(CMessage* self) {
+  if (self->parent_field != NULL) {
+    return self->parent_field->descriptor->full_name();
+  } else {
+    return self->message->GetDescriptor()->full_name();
+  }
+}
+
+static PyObject* SerializeToString(CMessage* self, PyObject* args) {
+  if (!self->message->IsInitialized()) {
+    ScopedPyObjectPtr errors(FindInitializationErrors(self));
+    if (errors == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr comma(PyString_FromString(","));
+    if (comma == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr joined(
+        PyObject_CallMethod(comma.get(), "join", "O", errors.get()));
+    if (joined == NULL) {
+      return NULL;
+    }
+    PyErr_Format(EncodeError_class, "Message %s is missing required fields: %s",
+                 GetMessageName(self).c_str(), PyString_AsString(joined.get()));
+    return NULL;
+  }
+  int size = self->message->ByteSize();
+  if (size <= 0) {
+    return PyBytes_FromString("");
+  }
+  PyObject* result = PyBytes_FromStringAndSize(NULL, size);
+  if (result == NULL) {
+    return NULL;
+  }
+  char* buffer = PyBytes_AS_STRING(result);
+  self->message->SerializeWithCachedSizesToArray(
+      reinterpret_cast<uint8*>(buffer));
+  return result;
+}
+
+static PyObject* SerializePartialToString(CMessage* self) {
+  string contents;
+  self->message->SerializePartialToString(&contents);
+  return PyBytes_FromStringAndSize(contents.c_str(), contents.size());
+}
+
+// Formats proto fields for ascii dumps using python formatting functions where
+// appropriate.
+class PythonFieldValuePrinter : public google::protobuf::TextFormat::FieldValuePrinter {
+ public:
+  PythonFieldValuePrinter() : float_holder_(PyFloat_FromDouble(0)) {}
+
+  // Python has some differences from C++ when printing floating point numbers.
+  //
+  // 1) Trailing .0 is always printed.
+  // 2) Outputted is rounded to 12 digits.
+  //
+  // We override floating point printing with the C-API function for printing
+  // Python floats to ensure consistency.
+  string PrintFloat(float value) const { return PrintDouble(value); }
+  string PrintDouble(double value) const {
+    reinterpret_cast<PyFloatObject*>(float_holder_.get())->ob_fval = value;
+    ScopedPyObjectPtr s(PyObject_Str(float_holder_.get()));
+    if (s == NULL) return string();
+#if PY_MAJOR_VERSION < 3
+    char *cstr = PyBytes_AS_STRING(static_cast<PyObject*>(s));
+#else
+    char *cstr = PyUnicode_AsUTF8(s);
+#endif
+    return string(cstr);
+  }
+
+ private:
+  // Holder for a python float object which we use to allow us to use
+  // the Python API for printing doubles. We initialize once and then
+  // directly modify it for every float printed to save on allocations
+  // and refcounting.
+  ScopedPyObjectPtr float_holder_;
+};
+
+static PyObject* ToStr(CMessage* self) {
+  google::protobuf::TextFormat::Printer printer;
+  // Passes ownership
+  printer.SetDefaultFieldValuePrinter(new PythonFieldValuePrinter());
+  printer.SetHideUnknownFields(true);
+  string output;
+  if (!printer.PrintToString(*self->message, &output)) {
+    PyErr_SetString(PyExc_ValueError, "Unable to convert message to str");
+    return NULL;
+  }
+  return PyString_FromString(output.c_str());
+}
+
+PyObject* MergeFrom(CMessage* self, PyObject* arg) {
+  CMessage* other_message;
+  if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
+    PyErr_SetString(PyExc_TypeError, "Must be a message");
+    return NULL;
+  }
+
+  other_message = reinterpret_cast<CMessage*>(arg);
+  if (other_message->message->GetDescriptor() !=
+      self->message->GetDescriptor()) {
+    PyErr_Format(PyExc_TypeError,
+                 "Tried to merge from a message with a different type. "
+                 "to: %s, from: %s",
+                 self->message->GetDescriptor()->full_name().c_str(),
+                 other_message->message->GetDescriptor()->full_name().c_str());
+    return NULL;
+  }
+  AssureWritable(self);
+
+  // TODO(tibell): Message::MergeFrom might turn some child Messages
+  // into mutable messages, invalidating the message field in the
+  // corresponding CMessages.  We should run a FixupMessageReferences
+  // pass here.
+
+  self->message->MergeFrom(*other_message->message);
+  Py_RETURN_NONE;
+}
+
+static PyObject* CopyFrom(CMessage* self, PyObject* arg) {
+  CMessage* other_message;
+  if (!PyObject_TypeCheck(reinterpret_cast<PyObject *>(arg), &CMessage_Type)) {
+    PyErr_SetString(PyExc_TypeError, "Must be a message");
+    return NULL;
+  }
+
+  other_message = reinterpret_cast<CMessage*>(arg);
+
+  if (self == other_message) {
+    Py_RETURN_NONE;
+  }
+
+  if (other_message->message->GetDescriptor() !=
+      self->message->GetDescriptor()) {
+    PyErr_Format(PyExc_TypeError,
+                 "Tried to copy from a message with a different type. "
+                 "to: %s, from: %s",
+                 self->message->GetDescriptor()->full_name().c_str(),
+                 other_message->message->GetDescriptor()->full_name().c_str());
+    return NULL;
+  }
+
+  AssureWritable(self);
+
+  // CopyFrom on the message will not clean up self->composite_fields,
+  // which can leave us in an inconsistent state, so clear it out here.
+  Clear(self);
+
+  self->message->CopyFrom(*other_message->message);
+
+  Py_RETURN_NONE;
+}
+
+static PyObject* MergeFromString(CMessage* self, PyObject* arg) {
+  const void* data;
+  Py_ssize_t data_length;
+  if (PyObject_AsReadBuffer(arg, &data, &data_length) < 0) {
+    return NULL;
+  }
+
+  AssureWritable(self);
+  google::protobuf::io::CodedInputStream input(
+      reinterpret_cast<const uint8*>(data), data_length);
+  input.SetExtensionRegistry(GetDescriptorPool(), global_message_factory);
+  bool success = self->message->MergePartialFromCodedStream(&input);
+  if (success) {
+    return PyInt_FromLong(input.CurrentPosition());
+  } else {
+    PyErr_Format(DecodeError_class, "Error parsing message");
+    return NULL;
+  }
+}
+
+static PyObject* ParseFromString(CMessage* self, PyObject* arg) {
+  if (Clear(self) == NULL) {
+    return NULL;
+  }
+  return MergeFromString(self, arg);
+}
+
+static PyObject* ByteSize(CMessage* self, PyObject* args) {
+  return PyLong_FromLong(self->message->ByteSize());
+}
+
+static PyObject* RegisterExtension(PyObject* cls,
+                                   PyObject* extension_handle) {
+  ScopedPyObjectPtr message_descriptor(PyObject_GetAttr(cls, kDESCRIPTOR));
+  if (message_descriptor == NULL) {
+    return NULL;
+  }
+  if (PyObject_SetAttrString(extension_handle, "containing_type",
+                             message_descriptor) < 0) {
+    return NULL;
+  }
+  ScopedPyObjectPtr extensions_by_name(
+      PyObject_GetAttr(cls, k_extensions_by_name));
+  if (extensions_by_name == NULL) {
+    PyErr_SetString(PyExc_TypeError, "no extensions_by_name on class");
+    return NULL;
+  }
+  ScopedPyObjectPtr full_name(PyObject_GetAttr(extension_handle, kfull_name));
+  if (full_name == NULL) {
+    return NULL;
+  }
+  if (PyDict_SetItem(extensions_by_name, full_name, extension_handle) < 0) {
+    return NULL;
+  }
+
+  // Also store a mapping from extension number to implementing class.
+  ScopedPyObjectPtr extensions_by_number(
+      PyObject_GetAttr(cls, k_extensions_by_number));
+  if (extensions_by_number == NULL) {
+    PyErr_SetString(PyExc_TypeError, "no extensions_by_number on class");
+    return NULL;
+  }
+  ScopedPyObjectPtr number(PyObject_GetAttrString(extension_handle, "number"));
+  if (number == NULL) {
+    return NULL;
+  }
+  if (PyDict_SetItem(extensions_by_number, number, extension_handle) < 0) {
+    return NULL;
+  }
+
+  CFieldDescriptor* cdescriptor =
+      extension_dict::InternalGetCDescriptorFromExtension(extension_handle);
+  ScopedPyObjectPtr py_cdescriptor(reinterpret_cast<PyObject*>(cdescriptor));
+  if (cdescriptor == NULL) {
+    return NULL;
+  }
+  Py_INCREF(extension_handle);
+  cdescriptor->descriptor_field = extension_handle;
+  const google::protobuf::FieldDescriptor* descriptor = cdescriptor->descriptor;
+  // Check if it's a message set
+  if (descriptor->is_extension() &&
+      descriptor->containing_type()->options().message_set_wire_format() &&
+      descriptor->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE &&
+      descriptor->message_type() == descriptor->extension_scope() &&
+      descriptor->label() == google::protobuf::FieldDescriptor::LABEL_OPTIONAL) {
+    ScopedPyObjectPtr message_name(PyString_FromStringAndSize(
+        descriptor->message_type()->full_name().c_str(),
+        descriptor->message_type()->full_name().size()));
+    if (message_name == NULL) {
+      return NULL;
+    }
+    PyDict_SetItem(extensions_by_name, message_name, extension_handle);
+  }
+
+  Py_RETURN_NONE;
+}
+
+static PyObject* SetInParent(CMessage* self, PyObject* args) {
+  AssureWritable(self);
+  Py_RETURN_NONE;
+}
+
+static PyObject* WhichOneof(CMessage* self, PyObject* arg) {
+  char* oneof_name;
+  if (!PyString_Check(arg)) {
+    PyErr_SetString(PyExc_TypeError, "field name must be a string");
+    return NULL;
+  }
+  oneof_name = PyString_AsString(arg);
+  if (oneof_name == NULL) {
+    return NULL;
+  }
+  const google::protobuf::OneofDescriptor* oneof_desc =
+      self->message->GetDescriptor()->FindOneofByName(oneof_name);
+  if (oneof_desc == NULL) {
+    PyErr_Format(PyExc_ValueError,
+                 "Protocol message has no oneof \"%s\" field.", oneof_name);
+    return NULL;
+  }
+  const google::protobuf::FieldDescriptor* field_in_oneof =
+      self->message->GetReflection()->GetOneofFieldDescriptor(
+          *self->message, oneof_desc);
+  if (field_in_oneof == NULL) {
+    Py_RETURN_NONE;
+  } else {
+    return PyString_FromString(field_in_oneof->name().c_str());
+  }
+}
+
+static PyObject* ListFields(CMessage* self) {
+  vector<const google::protobuf::FieldDescriptor*> fields;
+  self->message->GetReflection()->ListFields(*self->message, &fields);
+
+  PyObject* descriptor = PyDict_GetItem(Py_TYPE(self)->tp_dict, kDESCRIPTOR);
+  if (descriptor == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr fields_by_name(
+      PyObject_GetAttr(descriptor, kfields_by_name));
+  if (fields_by_name == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr extensions_by_name(PyObject_GetAttr(
+      reinterpret_cast<PyObject*>(Py_TYPE(self)), k_extensions_by_name));
+  if (extensions_by_name == NULL) {
+    PyErr_SetString(PyExc_ValueError, "no extensionsbyname");
+    return NULL;
+  }
+  // Normally, the list will be exactly the size of the fields.
+  PyObject* all_fields = PyList_New(fields.size());
+  if (all_fields == NULL) {
+    return NULL;
+  }
+
+  // When there are unknown extensions, the py list will *not* contain
+  // the field information.  Thus the actual size of the py list will be
+  // smaller than the size of fields.  Set the actual size at the end.
+  Py_ssize_t actual_size = 0;
+  for (Py_ssize_t i = 0; i < fields.size(); ++i) {
+    ScopedPyObjectPtr t(PyTuple_New(2));
+    if (t == NULL) {
+      Py_DECREF(all_fields);
+      return NULL;
+    }
+
+    if (fields[i]->is_extension()) {
+      const string& field_name = fields[i]->full_name();
+      PyObject* extension_field = PyDict_GetItemString(extensions_by_name,
+                                                       field_name.c_str());
+      if (extension_field == NULL) {
+        // If we couldn't fetch extension_field, it means the module that
+        // defines this extension has not been explicitly imported in Python
+        // code, and the extension hasn't been registered. There's nothing much
+        // we can do about this, so just skip it in the output to match the
+        // behavior of the python implementation.
+        continue;
+      }
+      PyObject* extensions = reinterpret_cast<PyObject*>(self->extensions);
+      if (extensions == NULL) {
+        Py_DECREF(all_fields);
+        return NULL;
+      }
+      // 'extension' reference later stolen by PyTuple_SET_ITEM.
+      PyObject* extension = PyObject_GetItem(extensions, extension_field);
+      if (extension == NULL) {
+        Py_DECREF(all_fields);
+        return NULL;
+      }
+      Py_INCREF(extension_field);
+      PyTuple_SET_ITEM(t.get(), 0, extension_field);
+      // Steals reference to 'extension'
+      PyTuple_SET_ITEM(t.get(), 1, extension);
+    } else {
+      const string& field_name = fields[i]->name();
+      ScopedPyObjectPtr py_field_name(PyString_FromStringAndSize(
+          field_name.c_str(), field_name.length()));
+      if (py_field_name == NULL) {
+        PyErr_SetString(PyExc_ValueError, "bad string");
+        Py_DECREF(all_fields);
+        return NULL;
+      }
+      PyObject* field_descriptor =
+          PyDict_GetItem(fields_by_name, py_field_name);
+      if (field_descriptor == NULL) {
+        Py_DECREF(all_fields);
+        return NULL;
+      }
+
+      PyObject* field_value = GetAttr(self, py_field_name);
+      if (field_value == NULL) {
+        PyErr_SetObject(PyExc_ValueError, py_field_name);
+        Py_DECREF(all_fields);
+        return NULL;
+      }
+      Py_INCREF(field_descriptor);
+      PyTuple_SET_ITEM(t.get(), 0, field_descriptor);
+      PyTuple_SET_ITEM(t.get(), 1, field_value);
+    }
+    PyList_SET_ITEM(all_fields, actual_size, t.release());
+    ++actual_size;
+  }
+  Py_SIZE(all_fields) = actual_size;
+  return all_fields;
+}
+
+PyObject* FindInitializationErrors(CMessage* self) {
+  google::protobuf::Message* message = self->message;
+  vector<string> errors;
+  message->FindInitializationErrors(&errors);
+
+  PyObject* error_list = PyList_New(errors.size());
+  if (error_list == NULL) {
+    return NULL;
+  }
+  for (Py_ssize_t i = 0; i < errors.size(); ++i) {
+    const string& error = errors[i];
+    PyObject* error_string = PyString_FromStringAndSize(
+        error.c_str(), error.length());
+    if (error_string == NULL) {
+      Py_DECREF(error_list);
+      return NULL;
+    }
+    PyList_SET_ITEM(error_list, i, error_string);
+  }
+  return error_list;
+}
+
+static PyObject* RichCompare(CMessage* self, PyObject* other, int opid) {
+  if (!PyObject_TypeCheck(other, &CMessage_Type)) {
+    if (opid == Py_EQ) {
+      Py_RETURN_FALSE;
+    } else if (opid == Py_NE) {
+      Py_RETURN_TRUE;
+    }
+  }
+  if (opid == Py_EQ || opid == Py_NE) {
+    ScopedPyObjectPtr self_fields(ListFields(self));
+    ScopedPyObjectPtr other_fields(ListFields(
+        reinterpret_cast<CMessage*>(other)));
+    return PyObject_RichCompare(self_fields, other_fields, opid);
+  } else {
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+  }
+}
+
+PyObject* InternalGetScalar(
+    CMessage* self,
+    const google::protobuf::FieldDescriptor* field_descriptor) {
+  google::protobuf::Message* message = self->message;
+  const google::protobuf::Reflection* reflection = message->GetReflection();
+
+  if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+    PyErr_SetString(
+        PyExc_KeyError, "Field does not belong to message!");
+    return NULL;
+  }
+
+  PyObject* result = NULL;
+  switch (field_descriptor->cpp_type()) {
+    case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+      int32 value = reflection->GetInt32(*message, field_descriptor);
+      result = PyInt_FromLong(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+      int64 value = reflection->GetInt64(*message, field_descriptor);
+      result = PyLong_FromLongLong(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+      uint32 value = reflection->GetUInt32(*message, field_descriptor);
+      result = PyInt_FromSize_t(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+      uint64 value = reflection->GetUInt64(*message, field_descriptor);
+      result = PyLong_FromUnsignedLongLong(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+      float value = reflection->GetFloat(*message, field_descriptor);
+      result = PyFloat_FromDouble(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+      double value = reflection->GetDouble(*message, field_descriptor);
+      result = PyFloat_FromDouble(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+      bool value = reflection->GetBool(*message, field_descriptor);
+      result = PyBool_FromLong(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+      string value = reflection->GetString(*message, field_descriptor);
+      result = ToStringObject(field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+      if (!message->GetReflection()->HasField(*message, field_descriptor)) {
+        // Look for the value in the unknown fields.
+        google::protobuf::UnknownFieldSet* unknown_field_set =
+            message->GetReflection()->MutableUnknownFields(message);
+        for (int i = 0; i < unknown_field_set->field_count(); ++i) {
+          if (unknown_field_set->field(i).number() ==
+              field_descriptor->number()) {
+            result = PyInt_FromLong(unknown_field_set->field(i).varint());
+            break;
+          }
+        }
+      }
+
+      if (result == NULL) {
+        const google::protobuf::EnumValueDescriptor* enum_value =
+            message->GetReflection()->GetEnum(*message, field_descriptor);
+        result = PyInt_FromLong(enum_value->number());
+      }
+      break;
+    }
+    default:
+      PyErr_Format(
+          PyExc_SystemError, "Getting a value from a field of unknown type %d",
+          field_descriptor->cpp_type());
+  }
+
+  return result;
+}
+
+PyObject* InternalGetSubMessage(CMessage* self,
+                                CFieldDescriptor* cfield_descriptor) {
+  PyObject* field = cfield_descriptor->descriptor_field;
+  ScopedPyObjectPtr message_type(PyObject_GetAttr(field, kmessage_type));
+  if (message_type == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr concrete_class(
+      PyObject_GetAttr(message_type, k_concrete_class));
+  if (concrete_class == NULL) {
+    return NULL;
+  }
+  PyObject* py_cmsg = cmessage::NewEmpty(concrete_class);
+  if (py_cmsg == NULL) {
+    return NULL;
+  }
+  if (!PyObject_TypeCheck(py_cmsg, &CMessage_Type)) {
+    PyErr_SetString(PyExc_TypeError, "Not a CMessage!");
+  }
+  CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+
+  const google::protobuf::FieldDescriptor* field_descriptor =
+      cfield_descriptor->descriptor;
+  const google::protobuf::Reflection* reflection = self->message->GetReflection();
+  const google::protobuf::Message& sub_message = reflection->GetMessage(
+      *self->message, field_descriptor, global_message_factory);
+  cmsg->owner = self->owner;
+  cmsg->parent = self;
+  cmsg->parent_field = cfield_descriptor;
+  cmsg->read_only = !reflection->HasField(*self->message, field_descriptor);
+  cmsg->message = const_cast<google::protobuf::Message*>(&sub_message);
+
+  if (InitAttributes(cmsg, NULL, NULL) < 0) {
+    Py_DECREF(py_cmsg);
+    return NULL;
+  }
+  return py_cmsg;
+}
+
+int InternalSetScalar(
+    CMessage* self,
+    const google::protobuf::FieldDescriptor* field_descriptor,
+    PyObject* arg) {
+  google::protobuf::Message* message = self->message;
+  const google::protobuf::Reflection* reflection = message->GetReflection();
+
+  if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+    PyErr_SetString(
+        PyExc_KeyError, "Field does not belong to message!");
+    return -1;
+  }
+
+  if (MaybeReleaseOverlappingOneofField(self, field_descriptor) < 0) {
+    return -1;
+  }
+
+  switch (field_descriptor->cpp_type()) {
+    case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+      GOOGLE_CHECK_GET_INT32(arg, value, -1);
+      reflection->SetInt32(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+      GOOGLE_CHECK_GET_INT64(arg, value, -1);
+      reflection->SetInt64(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+      GOOGLE_CHECK_GET_UINT32(arg, value, -1);
+      reflection->SetUInt32(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+      GOOGLE_CHECK_GET_UINT64(arg, value, -1);
+      reflection->SetUInt64(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+      GOOGLE_CHECK_GET_FLOAT(arg, value, -1);
+      reflection->SetFloat(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+      GOOGLE_CHECK_GET_DOUBLE(arg, value, -1);
+      reflection->SetDouble(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+      GOOGLE_CHECK_GET_BOOL(arg, value, -1);
+      reflection->SetBool(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+      if (!CheckAndSetString(
+          arg, message, field_descriptor, reflection, false, -1)) {
+        return -1;
+      }
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+      GOOGLE_CHECK_GET_INT32(arg, value, -1);
+      const google::protobuf::EnumDescriptor* enum_descriptor =
+          field_descriptor->enum_type();
+      const google::protobuf::EnumValueDescriptor* enum_value =
+          enum_descriptor->FindValueByNumber(value);
+      if (enum_value != NULL) {
+        reflection->SetEnum(message, field_descriptor, enum_value);
+      } else {
+        PyErr_Format(PyExc_ValueError, "Unknown enum value: %d", value);
+        return -1;
+      }
+      break;
+    }
+    default:
+      PyErr_Format(
+          PyExc_SystemError, "Setting value to a field of unknown type %d",
+          field_descriptor->cpp_type());
+      return -1;
+  }
+
+  return 0;
+}
+
+PyObject* FromString(PyTypeObject* cls, PyObject* serialized) {
+  PyObject* py_cmsg = PyObject_CallObject(
+      reinterpret_cast<PyObject*>(cls), NULL);
+  if (py_cmsg == NULL) {
+    return NULL;
+  }
+  CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+
+  ScopedPyObjectPtr py_length(MergeFromString(cmsg, serialized));
+  if (py_length == NULL) {
+    Py_DECREF(py_cmsg);
+    return NULL;
+  }
+
+  if (InitAttributes(cmsg, NULL, NULL) < 0) {
+    Py_DECREF(py_cmsg);
+    return NULL;
+  }
+  return py_cmsg;
+}
+
+static PyObject* AddDescriptors(PyTypeObject* cls,
+                                PyObject* descriptor) {
+  if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+                       k_extensions_by_name, PyDict_New()) < 0) {
+    return NULL;
+  }
+  if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+                       k_extensions_by_number, PyDict_New()) < 0) {
+    return NULL;
+  }
+
+  ScopedPyObjectPtr field_descriptors(PyDict_New());
+
+  ScopedPyObjectPtr fields(PyObject_GetAttrString(descriptor, "fields"));
+  if (fields == NULL) {
+    return NULL;
+  }
+
+  ScopedPyObjectPtr _NUMBER_string(PyString_FromString("_FIELD_NUMBER"));
+  if (_NUMBER_string == NULL) {
+    return NULL;
+  }
+
+  const Py_ssize_t fields_size = PyList_GET_SIZE(fields.get());
+  for (int i = 0; i < fields_size; ++i) {
+    PyObject* field = PyList_GET_ITEM(fields.get(), i);
+    ScopedPyObjectPtr field_name(PyObject_GetAttr(field, kname));
+    ScopedPyObjectPtr full_field_name(PyObject_GetAttr(field, kfull_name));
+    if (field_name == NULL || full_field_name == NULL) {
+      PyErr_SetString(PyExc_TypeError, "Name is null");
+      return NULL;
+    }
+
+    PyObject* field_descriptor =
+        cdescriptor_pool::FindFieldByName(descriptor_pool, full_field_name);
+    if (field_descriptor == NULL) {
+      PyErr_SetString(PyExc_TypeError, "Couldn't find field");
+      return NULL;
+    }
+    Py_INCREF(field);
+    CFieldDescriptor* cfield_descriptor = reinterpret_cast<CFieldDescriptor*>(
+        field_descriptor);
+    cfield_descriptor->descriptor_field = field;
+    if (PyDict_SetItem(field_descriptors, field_name, field_descriptor) < 0) {
+      return NULL;
+    }
+
+    // The FieldDescriptor's name field might either be of type bytes or
+    // of type unicode, depending on whether the FieldDescriptor was
+    // parsed from a serialized message or read from the
+    // <message>_pb2.py module.
+    ScopedPyObjectPtr field_name_upcased(
+         PyObject_CallMethod(field_name, "upper", NULL));
+    if (field_name_upcased == NULL) {
+      return NULL;
+    }
+
+    ScopedPyObjectPtr field_number_name(PyObject_CallMethod(
+         field_name_upcased, "__add__", "(O)", _NUMBER_string.get()));
+    if (field_number_name == NULL) {
+      return NULL;
+    }
+
+    ScopedPyObjectPtr number(PyInt_FromLong(
+        cfield_descriptor->descriptor->number()));
+    if (number == NULL) {
+      return NULL;
+    }
+    if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+                         field_number_name, number) == -1) {
+      return NULL;
+    }
+  }
+
+  PyDict_SetItem(cls->tp_dict, k__descriptors, field_descriptors);
+
+  // Enum Values
+  ScopedPyObjectPtr enum_types(PyObject_GetAttrString(descriptor,
+                                                      "enum_types"));
+  if (enum_types == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr type_iter(PyObject_GetIter(enum_types));
+  if (type_iter == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr enum_type;
+  while ((enum_type.reset(PyIter_Next(type_iter))) != NULL) {
+    ScopedPyObjectPtr wrapped(PyObject_CallFunctionObjArgs(
+        EnumTypeWrapper_class, enum_type.get(), NULL));
+    if (wrapped == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr enum_name(PyObject_GetAttr(enum_type, kname));
+    if (enum_name == NULL) {
+      return NULL;
+    }
+    if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+                         enum_name, wrapped) == -1) {
+      return NULL;
+    }
+
+    ScopedPyObjectPtr enum_values(PyObject_GetAttrString(enum_type, "values"));
+    if (enum_values == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr values_iter(PyObject_GetIter(enum_values));
+    if (values_iter == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr enum_value;
+    while ((enum_value.reset(PyIter_Next(values_iter))) != NULL) {
+      ScopedPyObjectPtr value_name(PyObject_GetAttr(enum_value, kname));
+      if (value_name == NULL) {
+        return NULL;
+      }
+      ScopedPyObjectPtr value_number(PyObject_GetAttrString(enum_value,
+                                                            "number"));
+      if (value_number == NULL) {
+        return NULL;
+      }
+      if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+                           value_name, value_number) == -1) {
+        return NULL;
+      }
+    }
+    if (PyErr_Occurred()) {  // If PyIter_Next failed
+      return NULL;
+    }
+  }
+  if (PyErr_Occurred()) {  // If PyIter_Next failed
+    return NULL;
+  }
+
+  ScopedPyObjectPtr extension_dict(
+      PyObject_GetAttr(descriptor, kextensions_by_name));
+  if (extension_dict == NULL || !PyDict_Check(extension_dict)) {
+    PyErr_SetString(PyExc_TypeError, "extensions_by_name not a dict");
+    return NULL;
+  }
+  Py_ssize_t pos = 0;
+  PyObject* extension_name;
+  PyObject* extension_field;
+
+  while (PyDict_Next(extension_dict, &pos, &extension_name, &extension_field)) {
+    if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+                         extension_name, extension_field) == -1) {
+      return NULL;
+    }
+    ScopedPyObjectPtr py_cfield_descriptor(
+        PyObject_GetAttrString(extension_field, "_cdescriptor"));
+    if (py_cfield_descriptor == NULL) {
+      return NULL;
+    }
+    CFieldDescriptor* cfield_descriptor =
+        reinterpret_cast<CFieldDescriptor*>(py_cfield_descriptor.get());
+    Py_INCREF(extension_field);
+    cfield_descriptor->descriptor_field = extension_field;
+
+    ScopedPyObjectPtr field_name_upcased(
+        PyObject_CallMethod(extension_name, "upper", NULL));
+    if (field_name_upcased == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr field_number_name(PyObject_CallMethod(
+         field_name_upcased, "__add__", "(O)", _NUMBER_string.get()));
+    if (field_number_name == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr number(PyInt_FromLong(
+        cfield_descriptor->descriptor->number()));
+    if (number == NULL) {
+      return NULL;
+    }
+    if (PyObject_SetAttr(reinterpret_cast<PyObject*>(cls),
+                         field_number_name, PyInt_FromLong(
+            cfield_descriptor->descriptor->number())) == -1) {
+      return NULL;
+    }
+  }
+
+  Py_RETURN_NONE;
+}
+
+PyObject* DeepCopy(CMessage* self, PyObject* arg) {
+  PyObject* clone = PyObject_CallObject(
+      reinterpret_cast<PyObject*>(Py_TYPE(self)), NULL);
+  if (clone == NULL) {
+    return NULL;
+  }
+  if (!PyObject_TypeCheck(clone, &CMessage_Type)) {
+    Py_DECREF(clone);
+    return NULL;
+  }
+  if (InitAttributes(reinterpret_cast<CMessage*>(clone), NULL, NULL) < 0) {
+    Py_DECREF(clone);
+    return NULL;
+  }
+  if (MergeFrom(reinterpret_cast<CMessage*>(clone),
+                reinterpret_cast<PyObject*>(self)) == NULL) {
+    Py_DECREF(clone);
+    return NULL;
+  }
+  return clone;
+}
+
+PyObject* ToUnicode(CMessage* self) {
+  // Lazy import to prevent circular dependencies
+  ScopedPyObjectPtr text_format(
+      PyImport_ImportModule("google.protobuf.text_format"));
+  if (text_format == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr method_name(PyString_FromString("MessageToString"));
+  if (method_name == NULL) {
+    return NULL;
+  }
+  Py_INCREF(Py_True);
+  ScopedPyObjectPtr encoded(PyObject_CallMethodObjArgs(text_format, method_name,
+                                                       self, Py_True, NULL));
+  Py_DECREF(Py_True);
+  if (encoded == NULL) {
+    return NULL;
+  }
+#if PY_MAJOR_VERSION < 3
+  PyObject* decoded = PyString_AsDecodedObject(encoded, "utf-8", NULL);
+#else
+  PyObject* decoded = PyUnicode_FromEncodedObject(encoded, "utf-8", NULL);
+#endif
+  if (decoded == NULL) {
+    return NULL;
+  }
+  return decoded;
+}
+
+PyObject* Reduce(CMessage* self) {
+  ScopedPyObjectPtr constructor(reinterpret_cast<PyObject*>(Py_TYPE(self)));
+  constructor.inc();
+  ScopedPyObjectPtr args(PyTuple_New(0));
+  if (args == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr state(PyDict_New());
+  if (state == NULL) {
+    return  NULL;
+  }
+  ScopedPyObjectPtr serialized(SerializePartialToString(self));
+  if (serialized == NULL) {
+    return NULL;
+  }
+  if (PyDict_SetItemString(state, "serialized", serialized) < 0) {
+    return NULL;
+  }
+  return Py_BuildValue("OOO", constructor.get(), args.get(), state.get());
+}
+
+PyObject* SetState(CMessage* self, PyObject* state) {
+  if (!PyDict_Check(state)) {
+    PyErr_SetString(PyExc_TypeError, "state not a dict");
+    return NULL;
+  }
+  PyObject* serialized = PyDict_GetItemString(state, "serialized");
+  if (serialized == NULL) {
+    return NULL;
+  }
+  if (ParseFromString(self, serialized) == NULL) {
+    return NULL;
+  }
+  Py_RETURN_NONE;
+}
+
+// CMessage static methods:
+PyObject* _GetFieldDescriptor(PyObject* unused, PyObject* arg) {
+  return cdescriptor_pool::FindFieldByName(descriptor_pool, arg);
+}
+
+PyObject* _GetExtensionDescriptor(PyObject* unused, PyObject* arg) {
+  return cdescriptor_pool::FindExtensionByName(descriptor_pool, arg);
+}
+
+static PyMemberDef Members[] = {
+  {"Extensions", T_OBJECT_EX, offsetof(CMessage, extensions), 0,
+   "Extension dict"},
+  {NULL}
+};
+
+static PyMethodDef Methods[] = {
+  { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
+    "Makes a deep copy of the class." },
+  { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
+    "Outputs picklable representation of the message." },
+  { "__setstate__", (PyCFunction)SetState, METH_O,
+    "Inputs picklable representation of the message." },
+  { "__unicode__", (PyCFunction)ToUnicode, METH_NOARGS,
+    "Outputs a unicode representation of the message." },
+  { "AddDescriptors", (PyCFunction)AddDescriptors, METH_O | METH_CLASS,
+    "Adds field descriptors to the class" },
+  { "ByteSize", (PyCFunction)ByteSize, METH_NOARGS,
+    "Returns the size of the message in bytes." },
+  { "Clear", (PyCFunction)Clear, METH_NOARGS,
+    "Clears the message." },
+  { "ClearExtension", (PyCFunction)ClearExtension, METH_O,
+    "Clears a message field." },
+  { "ClearField", (PyCFunction)ClearField, METH_O,
+    "Clears a message field." },
+  { "CopyFrom", (PyCFunction)CopyFrom, METH_O,
+    "Copies a protocol message into the current message." },
+  { "FindInitializationErrors", (PyCFunction)FindInitializationErrors,
+    METH_NOARGS,
+    "Finds unset required fields." },
+  { "FromString", (PyCFunction)FromString, METH_O | METH_CLASS,
+    "Creates new method instance from given serialized data." },
+  { "HasExtension", (PyCFunction)HasExtension, METH_O,
+    "Checks if a message field is set." },
+  { "HasField", (PyCFunction)HasField, METH_O,
+    "Checks if a message field is set." },
+  { "IsInitialized", (PyCFunction)IsInitialized, METH_VARARGS,
+    "Checks if all required fields of a protocol message are set." },
+  { "ListFields", (PyCFunction)ListFields, METH_NOARGS,
+    "Lists all set fields of a message." },
+  { "MergeFrom", (PyCFunction)MergeFrom, METH_O,
+    "Merges a protocol message into the current message." },
+  { "MergeFromString", (PyCFunction)MergeFromString, METH_O,
+    "Merges a serialized message into the current message." },
+  { "ParseFromString", (PyCFunction)ParseFromString, METH_O,
+    "Parses a serialized message into the current message." },
+  { "RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS,
+    "Registers an extension with the current message." },
+  { "SerializePartialToString", (PyCFunction)SerializePartialToString,
+    METH_NOARGS,
+    "Serializes the message to a string, even if it isn't initialized." },
+  { "SerializeToString", (PyCFunction)SerializeToString, METH_NOARGS,
+    "Serializes the message to a string, only for initialized messages." },
+  { "SetInParent", (PyCFunction)SetInParent, METH_NOARGS,
+    "Sets the has bit of the given field in its parent message." },
+  { "WhichOneof", (PyCFunction)WhichOneof, METH_O,
+    "Returns the name of the field set inside a oneof, "
+    "or None if no field is set." },
+
+  // Static Methods.
+  { "_BuildFile", (PyCFunction)Python_BuildFile, METH_O | METH_STATIC,
+    "Registers a new protocol buffer file in the global C++ descriptor pool." },
+  { "_GetFieldDescriptor", (PyCFunction)_GetFieldDescriptor,
+    METH_O | METH_STATIC, "Finds a field descriptor in the message pool." },
+  { "_GetExtensionDescriptor", (PyCFunction)_GetExtensionDescriptor,
+    METH_O | METH_STATIC,
+    "Finds a extension descriptor in the message pool." },
+  { NULL, NULL}
+};
+
+PyObject* GetAttr(CMessage* self, PyObject* name) {
+  PyObject* value = PyDict_GetItem(self->composite_fields, name);
+  if (value != NULL) {
+    Py_INCREF(value);
+    return value;
+  }
+
+  PyObject* descriptor = GetDescriptor(self, name);
+  if (descriptor != NULL) {
+    CFieldDescriptor* cdescriptor =
+        reinterpret_cast<CFieldDescriptor*>(descriptor);
+    const google::protobuf::FieldDescriptor* field_descriptor = cdescriptor->descriptor;
+    if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+      if (field_descriptor->cpp_type() ==
+          google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+        PyObject* py_container = PyObject_CallObject(
+            reinterpret_cast<PyObject*>(&RepeatedCompositeContainer_Type),
+            NULL);
+        if (py_container == NULL) {
+          return NULL;
+        }
+        RepeatedCompositeContainer* container =
+            reinterpret_cast<RepeatedCompositeContainer*>(py_container);
+        PyObject* field = cdescriptor->descriptor_field;
+        PyObject* message_type = PyObject_GetAttr(field, kmessage_type);
+        if (message_type == NULL) {
+          return NULL;
+        }
+        PyObject* concrete_class =
+            PyObject_GetAttr(message_type, k_concrete_class);
+        if (concrete_class == NULL) {
+          return NULL;
+        }
+        container->parent = self;
+        container->parent_field = cdescriptor;
+        container->message = self->message;
+        container->owner = self->owner;
+        container->subclass_init = concrete_class;
+        Py_DECREF(message_type);
+        if (PyDict_SetItem(self->composite_fields, name, py_container) < 0) {
+          Py_DECREF(py_container);
+          return NULL;
+        }
+        return py_container;
+      } else {
+        ScopedPyObjectPtr init_args(PyTuple_Pack(2, self, cdescriptor));
+        PyObject* py_container = PyObject_CallObject(
+            reinterpret_cast<PyObject*>(&RepeatedScalarContainer_Type),
+            init_args);
+        if (py_container == NULL) {
+          return NULL;
+        }
+        if (PyDict_SetItem(self->composite_fields, name, py_container) < 0) {
+          Py_DECREF(py_container);
+          return NULL;
+        }
+        return py_container;
+      }
+    } else {
+      if (field_descriptor->cpp_type() ==
+          google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+        PyObject* sub_message = InternalGetSubMessage(self, cdescriptor);
+        if (PyDict_SetItem(self->composite_fields, name, sub_message) < 0) {
+          Py_DECREF(sub_message);
+          return NULL;
+        }
+        return sub_message;
+      } else {
+        return InternalGetScalar(self, field_descriptor);
+      }
+    }
+  }
+
+  return CMessage_Type.tp_base->tp_getattro(reinterpret_cast<PyObject*>(self),
+                                            name);
+}
+
+int SetAttr(CMessage* self, PyObject* name, PyObject* value) {
+  if (PyDict_Contains(self->composite_fields, name)) {
+    PyErr_SetString(PyExc_TypeError, "Can't set composite field");
+    return -1;
+  }
+
+  PyObject* descriptor = GetDescriptor(self, name);
+  if (descriptor != NULL) {
+    AssureWritable(self);
+    CFieldDescriptor* cdescriptor =
+        reinterpret_cast<CFieldDescriptor*>(descriptor);
+    const google::protobuf::FieldDescriptor* field_descriptor = cdescriptor->descriptor;
+    if (field_descriptor->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED) {
+      PyErr_Format(PyExc_AttributeError, "Assignment not allowed to repeated "
+                   "field \"%s\" in protocol message object.",
+                   field_descriptor->name().c_str());
+      return -1;
+    } else {
+      if (field_descriptor->cpp_type() ==
+          google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
+        PyErr_Format(PyExc_AttributeError, "Assignment not allowed to "
+                     "field \"%s\" in protocol message object.",
+                     field_descriptor->name().c_str());
+        return -1;
+      } else {
+        return InternalSetScalar(self, field_descriptor, value);
+      }
+    }
+  }
+
+  PyErr_Format(PyExc_AttributeError, "Assignment not allowed");
+  return -1;
+}
+
+}  // namespace cmessage
+
+PyTypeObject CMessage_Type = {
+  PyVarObject_HEAD_INIT(&PyType_Type, 0)
+  "google.protobuf.internal."
+  "cpp._message.CMessage",             // tp_name
+  sizeof(CMessage),                    // tp_basicsize
+  0,                                   //  tp_itemsize
+  (destructor)cmessage::Dealloc,       //  tp_dealloc
+  0,                                   //  tp_print
+  0,                                   //  tp_getattr
+  0,                                   //  tp_setattr
+  0,                                   //  tp_compare
+  0,                                   //  tp_repr
+  0,                                   //  tp_as_number
+  0,                                   //  tp_as_sequence
+  0,                                   //  tp_as_mapping
+  0,                                   //  tp_hash
+  0,                                   //  tp_call
+  (reprfunc)cmessage::ToStr,           //  tp_str
+  (getattrofunc)cmessage::GetAttr,     //  tp_getattro
+  (setattrofunc)cmessage::SetAttr,     //  tp_setattro
+  0,                                   //  tp_as_buffer
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  //  tp_flags
+  "A ProtocolMessage",                 //  tp_doc
+  0,                                   //  tp_traverse
+  0,                                   //  tp_clear
+  (richcmpfunc)cmessage::RichCompare,  //  tp_richcompare
+  0,                                   //  tp_weaklistoffset
+  0,                                   //  tp_iter
+  0,                                   //  tp_iternext
+  cmessage::Methods,                   //  tp_methods
+  cmessage::Members,                   //  tp_members
+  0,                                   //  tp_getset
+  0,                                   //  tp_base
+  0,                                   //  tp_dict
+  0,                                   //  tp_descr_get
+  0,                                   //  tp_descr_set
+  0,                                   //  tp_dictoffset
+  (initproc)cmessage::Init,            //  tp_init
+  0,                                   //  tp_alloc
+  cmessage::New,                       //  tp_new
+};
+
+// --- Exposing the C proto living inside Python proto to C code:
+
+const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg);
+Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg);
+
+static const google::protobuf::Message* GetCProtoInsidePyProtoImpl(PyObject* msg) {
+  if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
+    return NULL;
+  }
+  CMessage* cmsg = reinterpret_cast<CMessage*>(msg);
+  return cmsg->message;
+}
+
+static google::protobuf::Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) {
+  if (!PyObject_TypeCheck(msg, &CMessage_Type)) {
+    return NULL;
+  }
+  CMessage* cmsg = reinterpret_cast<CMessage*>(msg);
+  if (PyDict_Size(cmsg->composite_fields) != 0 ||
+      (cmsg->extensions != NULL &&
+       PyDict_Size(cmsg->extensions->values) != 0)) {
+    // There is currently no way of accurately syncing arbitrary changes to
+    // the underlying C++ message back to the CMessage (e.g. removed repeated
+    // composite containers). We only allow direct mutation of the underlying
+    // C++ message if there is no child data in the CMessage.
+    return NULL;
+  }
+  cmessage::AssureWritable(cmsg);
+  return cmsg->message;
+}
+
+static const char module_docstring[] =
+"python-proto2 is a module that can be used to enhance proto2 Python API\n"
+"performance.\n"
+"\n"
+"It provides access to the protocol buffers C++ reflection API that\n"
+"implements the basic protocol buffer functions.";
+
+void InitGlobals() {
+  // TODO(gps): Check all return values in this function for NULL and propagate
+  // the error (MemoryError) on up to result in an import failure.  These should
+  // also be freed and reset to NULL during finalization.
+  kPythonZero = PyInt_FromLong(0);
+  kint32min_py = PyInt_FromLong(kint32min);
+  kint32max_py = PyInt_FromLong(kint32max);
+  kuint32max_py = PyLong_FromLongLong(kuint32max);
+  kint64min_py = PyLong_FromLongLong(kint64min);
+  kint64max_py = PyLong_FromLongLong(kint64max);
+  kuint64max_py = PyLong_FromUnsignedLongLong(kuint64max);
+
+  kDESCRIPTOR = PyString_FromString("DESCRIPTOR");
+  k__descriptors = PyString_FromString("__descriptors");
+  kfull_name = PyString_FromString("full_name");
+  kis_extendable = PyString_FromString("is_extendable");
+  kextensions_by_name = PyString_FromString("extensions_by_name");
+  k_extensions_by_name = PyString_FromString("_extensions_by_name");
+  k_extensions_by_number = PyString_FromString("_extensions_by_number");
+  k_concrete_class = PyString_FromString("_concrete_class");
+  kmessage_type = PyString_FromString("message_type");
+  kname = PyString_FromString("name");
+  kfields_by_name = PyString_FromString("fields_by_name");
+
+  global_message_factory = new DynamicMessageFactory(GetDescriptorPool());
+  global_message_factory->SetDelegateToGeneratedFactory(true);
+
+  descriptor_pool = reinterpret_cast<google::protobuf::python::CDescriptorPool*>(
+      Python_NewCDescriptorPool(NULL, NULL));
+}
+
+bool InitProto2MessageModule(PyObject *m) {
+  InitGlobals();
+
+  google::protobuf::python::CMessage_Type.tp_hash = PyObject_HashNotImplemented;
+  if (PyType_Ready(&google::protobuf::python::CMessage_Type) < 0) {
+    return false;
+  }
+
+  // All three of these are actually set elsewhere, directly onto the child
+  // protocol buffer message class, but set them here as well to document that
+  // subclasses need to set these.
+  PyDict_SetItem(google::protobuf::python::CMessage_Type.tp_dict, kDESCRIPTOR, Py_None);
+  PyDict_SetItem(google::protobuf::python::CMessage_Type.tp_dict,
+                 k_extensions_by_name, Py_None);
+  PyDict_SetItem(google::protobuf::python::CMessage_Type.tp_dict,
+                 k_extensions_by_number, Py_None);
+
+  PyModule_AddObject(m, "Message", reinterpret_cast<PyObject*>(
+      &google::protobuf::python::CMessage_Type));
+
+  google::protobuf::python::RepeatedScalarContainer_Type.tp_new = PyType_GenericNew;
+  google::protobuf::python::RepeatedScalarContainer_Type.tp_hash =
+      PyObject_HashNotImplemented;
+  if (PyType_Ready(&google::protobuf::python::RepeatedScalarContainer_Type) < 0) {
+    return false;
+  }
+
+  PyModule_AddObject(m, "RepeatedScalarContainer",
+                     reinterpret_cast<PyObject*>(
+                         &google::protobuf::python::RepeatedScalarContainer_Type));
+
+  google::protobuf::python::RepeatedCompositeContainer_Type.tp_new = PyType_GenericNew;
+  google::protobuf::python::RepeatedCompositeContainer_Type.tp_hash =
+      PyObject_HashNotImplemented;
+  if (PyType_Ready(&google::protobuf::python::RepeatedCompositeContainer_Type) < 0) {
+    return false;
+  }
+
+  PyModule_AddObject(
+      m, "RepeatedCompositeContainer",
+      reinterpret_cast<PyObject*>(
+          &google::protobuf::python::RepeatedCompositeContainer_Type));
+
+  google::protobuf::python::ExtensionDict_Type.tp_new = PyType_GenericNew;
+  google::protobuf::python::ExtensionDict_Type.tp_hash = PyObject_HashNotImplemented;
+  if (PyType_Ready(&google::protobuf::python::ExtensionDict_Type) < 0) {
+    return false;
+  }
+
+  PyModule_AddObject(
+      m, "ExtensionDict",
+      reinterpret_cast<PyObject*>(&google::protobuf::python::ExtensionDict_Type));
+
+  if (!google::protobuf::python::InitDescriptor()) {
+    return false;
+  }
+
+  PyObject* enum_type_wrapper = PyImport_ImportModule(
+      "google.protobuf.internal.enum_type_wrapper");
+  if (enum_type_wrapper == NULL) {
+    return false;
+  }
+  google::protobuf::python::EnumTypeWrapper_class =
+      PyObject_GetAttrString(enum_type_wrapper, "EnumTypeWrapper");
+  Py_DECREF(enum_type_wrapper);
+
+  PyObject* message_module = PyImport_ImportModule(
+      "google.protobuf.message");
+  if (message_module == NULL) {
+    return false;
+  }
+  google::protobuf::python::EncodeError_class = PyObject_GetAttrString(message_module,
+                                                             "EncodeError");
+  google::protobuf::python::DecodeError_class = PyObject_GetAttrString(message_module,
+                                                             "DecodeError");
+  Py_DECREF(message_module);
+
+  PyObject* pickle_module = PyImport_ImportModule("pickle");
+  if (pickle_module == NULL) {
+    return false;
+  }
+  google::protobuf::python::PickleError_class = PyObject_GetAttrString(pickle_module,
+                                                             "PickleError");
+  Py_DECREF(pickle_module);
+
+  // Override {Get,Mutable}CProtoInsidePyProto.
+  google::protobuf::python::GetCProtoInsidePyProtoPtr =
+      google::protobuf::python::GetCProtoInsidePyProtoImpl;
+  google::protobuf::python::MutableCProtoInsidePyProtoPtr =
+      google::protobuf::python::MutableCProtoInsidePyProtoImpl;
+
+  return true;
+}
+
+}  // namespace python
+}  // namespace protobuf
+
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef _module = {
+  PyModuleDef_HEAD_INIT,
+  "_message",
+  google::protobuf::python::module_docstring,
+  -1,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL
+};
+#define INITFUNC PyInit__message
+#define INITFUNC_ERRORVAL NULL
+#else  // Python 2
+#define INITFUNC init_message
+#define INITFUNC_ERRORVAL
+#endif
+
+extern "C" {
+  PyMODINIT_FUNC INITFUNC(void) {
+    PyObject* m;
+#if PY_MAJOR_VERSION >= 3
+    m = PyModule_Create(&_module);
+#else
+    m = Py_InitModule3("_message", NULL, google::protobuf::python::module_docstring);
+#endif
+    if (m == NULL) {
+      return INITFUNC_ERRORVAL;
+    }
+
+    if (!google::protobuf::python::InitProto2MessageModule(m)) {
+      Py_DECREF(m);
+      return INITFUNC_ERRORVAL;
+    }
+
+#if PY_MAJOR_VERSION >= 3
+    return m;
+#endif
+  }
+}
+}  // namespace google
diff --git a/protobuf/python/google/protobuf/pyext/message.h b/protobuf/python/google/protobuf/pyext/message.h
new file mode 100644
index 0000000..9f4978f
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/message.h
@@ -0,0 +1,305 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__
+
+#include <Python.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+#include <string>
+
+
+namespace google {
+namespace protobuf {
+
+class Message;
+class Reflection;
+class FieldDescriptor;
+
+using internal::shared_ptr;
+
+namespace python {
+
+struct CFieldDescriptor;
+struct ExtensionDict;
+
+typedef struct CMessage {
+  PyObject_HEAD;
+
+  // This is the top-level C++ Message object that owns the whole
+  // proto tree.  Every Python CMessage holds a reference to it in
+  // order to keep it alive as long as there's a Python object that
+  // references any part of the tree.
+  shared_ptr<Message> owner;
+
+  // Weak reference to a parent CMessage object. This is NULL for any top-level
+  // message and is set for any child message (i.e. a child submessage or a
+  // part of a repeated composite field).
+  //
+  // Used to make sure all ancestors are also mutable when first modifying
+  // a child submessage (in other words, turning a default message instance
+  // into a mutable one).
+  //
+  // If a submessage is released (becomes a new top-level message), this field
+  // MUST be set to NULL. The parent may get deallocated and further attempts
+  // to use this pointer will result in a crash.
+  struct CMessage* parent;
+
+  // Weak reference to the parent's descriptor that describes this submessage.
+  // Used together with the parent's message when making a default message
+  // instance mutable.
+  // TODO(anuraag): With a bit of work on the Python/C++ layer, it should be
+  // possible to make this a direct pointer to a C++ FieldDescriptor, this would
+  // be easier if this implementation replaces upstream.
+  CFieldDescriptor* parent_field;
+
+  // Pointer to the C++ Message object for this CMessage.  The
+  // CMessage does not own this pointer.
+  Message* message;
+
+  // Indicates this submessage is pointing to a default instance of a message.
+  // Submessages are always first created as read only messages and are then
+  // made writable, at which point this field is set to false.
+  bool read_only;
+
+  // A reference to a Python dictionary containing CMessage,
+  // RepeatedCompositeContainer, and RepeatedScalarContainer
+  // objects. Used as a cache to make sure we don't have to make a
+  // Python wrapper for the C++ Message objects on every access, or
+  // deal with the synchronization nightmare that could create.
+  PyObject* composite_fields;
+
+  // A reference to the dictionary containing the message's extensions.
+  // Similar to composite_fields, acting as a cache, but also contains the
+  // required extension dict logic.
+  ExtensionDict* extensions;
+} CMessage;
+
+extern PyTypeObject CMessage_Type;
+
+namespace cmessage {
+
+// Create a new empty message that can be populated by the parent.
+PyObject* NewEmpty(PyObject* type);
+
+// Release a submessage from its proto tree, making it a new top-level messgae.
+// A new message will be created if this is a read-only default instance.
+//
+// Corresponds to reflection api method ReleaseMessage.
+int ReleaseSubMessage(google::protobuf::Message* message,
+                      const google::protobuf::FieldDescriptor* field_descriptor,
+                      CMessage* child_cmessage);
+
+// Initializes a new CMessage instance for a submessage. Only called once per
+// submessage as the result is cached in composite_fields.
+//
+// Corresponds to reflection api method GetMessage.
+PyObject* InternalGetSubMessage(CMessage* self,
+                                CFieldDescriptor* cfield_descriptor);
+
+// Deletes a range of C++ submessages in a repeated field (following a
+// removal in a RepeatedCompositeContainer).
+//
+// Releases messages to the provided cmessage_list if it is not NULL rather
+// than just removing them from the underlying proto. This cmessage_list must
+// have a CMessage for each underlying submessage. The CMessages refered to
+// by slice will be removed from cmessage_list by this function.
+//
+// Corresponds to reflection api method RemoveLast.
+int InternalDeleteRepeatedField(google::protobuf::Message* message,
+                                const google::protobuf::FieldDescriptor* field_descriptor,
+                                PyObject* slice, PyObject* cmessage_list);
+
+// Sets the specified scalar value to the message.
+int InternalSetScalar(CMessage* self,
+                      const google::protobuf::FieldDescriptor* field_descriptor,
+                      PyObject* value);
+
+// Retrieves the specified scalar value from the message.
+//
+// Returns a new python reference.
+PyObject* InternalGetScalar(CMessage* self,
+                            const google::protobuf::FieldDescriptor* field_descriptor);
+
+// Clears the message, removing all contained data. Extension dictionary and
+// submessages are released first if there are remaining external references.
+//
+// Corresponds to message api method Clear.
+PyObject* Clear(CMessage* self);
+
+// Clears the data described by the given descriptor. Used to clear extensions
+// (which don't have names). Extension release is handled by ExtensionDict
+// class, not this function.
+// TODO(anuraag): Try to make this discrepancy in release semantics with
+//                ClearField less confusing.
+//
+// Corresponds to reflection api method ClearField.
+PyObject* ClearFieldByDescriptor(
+    CMessage* self,
+    const google::protobuf::FieldDescriptor* descriptor);
+
+// Clears the data for the given field name. The message is released if there
+// are any external references.
+//
+// Corresponds to reflection api method ClearField.
+PyObject* ClearField(CMessage* self, PyObject* arg);
+
+// Checks if the message has the field described by the descriptor. Used for
+// extensions (which have no name).
+//
+// Corresponds to reflection api method HasField
+PyObject* HasFieldByDescriptor(
+    CMessage* self, const google::protobuf::FieldDescriptor* field_descriptor);
+
+// Checks if the message has the named field.
+//
+// Corresponds to reflection api method HasField.
+PyObject* HasField(CMessage* self, PyObject* arg);
+
+// Initializes constants/enum values on a message. This is called by
+// RepeatedCompositeContainer and ExtensionDict after calling the constructor.
+// TODO(anuraag): Make it always called from within the constructor since it can
+int InitAttributes(CMessage* self, PyObject* descriptor, PyObject* kwargs);
+
+PyObject* MergeFrom(CMessage* self, PyObject* arg);
+
+// Retrieves an attribute named 'name' from CMessage 'self'. Returns
+// the attribute value on success, or NULL on failure.
+//
+// Returns a new reference.
+PyObject* GetAttr(CMessage* self, PyObject* name);
+
+// Set the value of the attribute named 'name', for CMessage 'self',
+// to the value 'value'. Returns -1 on failure.
+int SetAttr(CMessage* self, PyObject* name, PyObject* value);
+
+PyObject* FindInitializationErrors(CMessage* self);
+
+// Set the owner field of self and any children of self, recursively.
+// Used when self is being released and thus has a new owner (the
+// released Message.)
+int SetOwner(CMessage* self, const shared_ptr<Message>& new_owner);
+
+int AssureWritable(CMessage* self);
+
+}  // namespace cmessage
+
+/* Is 64bit */
+#define IS_64BIT (SIZEOF_LONG == 8)
+
+#define FIELD_BELONGS_TO_MESSAGE(field_descriptor, message) \
+    ((message)->GetDescriptor() == (field_descriptor)->containing_type())
+
+#define FIELD_IS_REPEATED(field_descriptor)                 \
+    ((field_descriptor)->label() == google::protobuf::FieldDescriptor::LABEL_REPEATED)
+
+#define GOOGLE_CHECK_GET_INT32(arg, value, err)                        \
+    int32 value;                                            \
+    if (!CheckAndGetInteger(arg, &value, kint32min_py, kint32max_py)) { \
+      return err;                                          \
+    }
+
+#define GOOGLE_CHECK_GET_INT64(arg, value, err)                        \
+    int64 value;                                            \
+    if (!CheckAndGetInteger(arg, &value, kint64min_py, kint64max_py)) { \
+      return err;                                          \
+    }
+
+#define GOOGLE_CHECK_GET_UINT32(arg, value, err)                       \
+    uint32 value;                                           \
+    if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint32max_py)) { \
+      return err;                                          \
+    }
+
+#define GOOGLE_CHECK_GET_UINT64(arg, value, err)                       \
+    uint64 value;                                           \
+    if (!CheckAndGetInteger(arg, &value, kPythonZero, kuint64max_py)) { \
+      return err;                                          \
+    }
+
+#define GOOGLE_CHECK_GET_FLOAT(arg, value, err)                        \
+    float value;                                            \
+    if (!CheckAndGetFloat(arg, &value)) {                   \
+      return err;                                          \
+    }                                                       \
+
+#define GOOGLE_CHECK_GET_DOUBLE(arg, value, err)                       \
+    double value;                                           \
+    if (!CheckAndGetDouble(arg, &value)) {                  \
+      return err;                                          \
+    }
+
+#define GOOGLE_CHECK_GET_BOOL(arg, value, err)                         \
+    bool value;                                             \
+    if (!CheckAndGetBool(arg, &value)) {                    \
+      return err;                                          \
+    }
+
+
+extern PyObject* kPythonZero;
+extern PyObject* kint32min_py;
+extern PyObject* kint32max_py;
+extern PyObject* kuint32max_py;
+extern PyObject* kint64min_py;
+extern PyObject* kint64max_py;
+extern PyObject* kuint64max_py;
+
+#define C(str) const_cast<char*>(str)
+
+void FormatTypeError(PyObject* arg, char* expected_types);
+template<class T>
+bool CheckAndGetInteger(
+    PyObject* arg, T* value, PyObject* min, PyObject* max);
+bool CheckAndGetDouble(PyObject* arg, double* value);
+bool CheckAndGetFloat(PyObject* arg, float* value);
+bool CheckAndGetBool(PyObject* arg, bool* value);
+bool CheckAndSetString(
+    PyObject* arg, google::protobuf::Message* message,
+    const google::protobuf::FieldDescriptor* descriptor,
+    const google::protobuf::Reflection* reflection,
+    bool append,
+    int index);
+PyObject* ToStringObject(
+    const google::protobuf::FieldDescriptor* descriptor, string value);
+
+extern PyObject* PickleError_class;
+
+}  // namespace python
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_PYTHON_CPP_MESSAGE_H__
diff --git a/protobuf/python/google/protobuf/pyext/message_factory_cpp2_test.py b/protobuf/python/google/protobuf/pyext/message_factory_cpp2_test.py
new file mode 100644
index 0000000..32ab4f8
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/message_factory_cpp2_test.py
@@ -0,0 +1,56 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for google.protobuf.message_factory."""
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION'] = '2'
+
+# We must set the implementation version above before the google3 imports.
+# pylint: disable=g-import-not-at-top
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+# Run all tests from the original module by putting them in our namespace.
+# pylint: disable=wildcard-import
+from google.protobuf.internal.message_factory_test import *
+
+
+class ConfirmCppApi2Test(basetest.TestCase):
+
+  def testImplementationSetting(self):
+    self.assertEqual('cpp', api_implementation.Type())
+    self.assertEqual(2, api_implementation.Version())
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/pyext/proto2_api_test.proto b/protobuf/python/google/protobuf/pyext/proto2_api_test.proto
new file mode 100644
index 0000000..72c31b1
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/proto2_api_test.proto
@@ -0,0 +1,38 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import "google/protobuf/internal/cpp/proto1_api_test.proto";
+
+package google.protobuf.python.internal;
+
+message TestNestedProto1APIMessage {
+  optional int32 a = 1;
+  optional TestMessage.NestedMessage b = 2;
+}
diff --git a/protobuf/python/google/protobuf/pyext/python.proto b/protobuf/python/google/protobuf/pyext/python.proto
new file mode 100644
index 0000000..d47d402
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/python.proto
@@ -0,0 +1,66 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: tibell@google.com (Johan Tibell)
+//
+// These message definitions are used to exercises known corner cases
+// in the C++ implementation of the Python API.
+
+
+package google.protobuf.python.internal;
+
+// 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;
+
+message TestAllTypes {
+  message NestedMessage {
+    optional int32 bb = 1;
+    optional ForeignMessage cc = 2;
+  }
+
+  repeated NestedMessage repeated_nested_message = 1;
+  optional NestedMessage optional_nested_message = 2;
+  optional int32 optional_int32 = 3;
+}
+
+message ForeignMessage {
+  optional int32 c = 1;
+  repeated int32 d = 2;
+}
+
+message TestAllExtensions {
+  extensions 1 to max;
+}
+
+extend TestAllExtensions {
+  optional TestAllTypes.NestedMessage optional_nested_message_extension = 1;
+}
diff --git a/protobuf/python/google/protobuf/pyext/python_protobuf.h b/protobuf/python/google/protobuf/pyext/python_protobuf.h
new file mode 100644
index 0000000..beb6e46
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/python_protobuf.h
@@ -0,0 +1,57 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: qrczak@google.com (Marcin Kowalczyk)
+//
+// This module exposes the C proto inside the given Python proto, in
+// case the Python proto is implemented with a C proto.
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
+#define GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
+
+#include <Python.h>
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+namespace python {
+
+// Return the pointer to the C proto inside the given Python proto,
+// or NULL when this is not a Python proto implemented with a C proto.
+const Message* GetCProtoInsidePyProto(PyObject* msg);
+Message* MutableCProtoInsidePyProto(PyObject* msg);
+
+}  // namespace python
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__
diff --git a/protobuf/python/google/protobuf/pyext/reflection_cpp2_generated_test.py b/protobuf/python/google/protobuf/pyext/reflection_cpp2_generated_test.py
new file mode 100755
index 0000000..552efd4
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/reflection_cpp2_generated_test.py
@@ -0,0 +1,94 @@
+#! /usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Unittest for reflection.py, which tests the generated C++ implementation."""
+
+__author__ = 'jasonh@google.com (Jason Hsueh)'
+
+import os
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'
+os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION'] = '2'
+
+from google.apputils import basetest
+from google.protobuf.internal import api_implementation
+from google.protobuf.internal import more_extensions_dynamic_pb2
+from google.protobuf.internal import more_extensions_pb2
+from google.protobuf.internal.reflection_test import *
+
+
+class ReflectionCppTest(basetest.TestCase):
+  def testImplementationSetting(self):
+    self.assertEqual('cpp', api_implementation.Type())
+    self.assertEqual(2, api_implementation.Version())
+
+  def testExtensionOfGeneratedTypeInDynamicFile(self):
+    """Tests that a file built dynamically can extend a generated C++ type.
+
+    The C++ implementation uses a DescriptorPool that has the generated
+    DescriptorPool as an underlay. Typically, a type can only find
+    extensions in its own pool. With the python C-extension, the generated C++
+    extendee may be available, but not the extension. This tests that the
+    C-extension implements the correct special handling to make such extensions
+    available.
+    """
+    pb1 = more_extensions_pb2.ExtendedMessage()
+    # Test that basic accessors work.
+    self.assertFalse(
+        pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension))
+    self.assertFalse(
+        pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension))
+    pb1.Extensions[more_extensions_dynamic_pb2.dynamic_int32_extension] = 17
+    pb1.Extensions[more_extensions_dynamic_pb2.dynamic_message_extension].a = 24
+    self.assertTrue(
+        pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension))
+    self.assertTrue(
+        pb1.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension))
+
+    # Now serialize the data and parse to a new message.
+    pb2 = more_extensions_pb2.ExtendedMessage()
+    pb2.MergeFromString(pb1.SerializeToString())
+
+    self.assertTrue(
+        pb2.HasExtension(more_extensions_dynamic_pb2.dynamic_int32_extension))
+    self.assertTrue(
+        pb2.HasExtension(more_extensions_dynamic_pb2.dynamic_message_extension))
+    self.assertEqual(
+        17, pb2.Extensions[more_extensions_dynamic_pb2.dynamic_int32_extension])
+    self.assertEqual(
+        24,
+        pb2.Extensions[more_extensions_dynamic_pb2.dynamic_message_extension].a)
+
+
+
+if __name__ == '__main__':
+  basetest.main()
diff --git a/protobuf/python/google/protobuf/pyext/repeated_composite_container.cc b/protobuf/python/google/protobuf/pyext/repeated_composite_container.cc
new file mode 100644
index 0000000..5c05b3d
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/repeated_composite_container.cc
@@ -0,0 +1,763 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#include <google/protobuf/pyext/repeated_composite_container.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/pyext/descriptor.h>
+#include <google/protobuf/pyext/message.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyInt_Check PyLong_Check
+  #define PyInt_AsLong PyLong_AsLong
+  #define PyInt_FromLong PyLong_FromLong
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+extern google::protobuf::DynamicMessageFactory* global_message_factory;
+
+namespace repeated_composite_container {
+
+// TODO(tibell): We might also want to check:
+//   GOOGLE_CHECK_NOTNULL((self)->owner.get());
+#define GOOGLE_CHECK_ATTACHED(self)             \
+  do {                                   \
+    GOOGLE_CHECK_NOTNULL((self)->message);      \
+    GOOGLE_CHECK_NOTNULL((self)->parent_field); \
+  } while (0);
+
+#define GOOGLE_CHECK_RELEASED(self)             \
+  do {                                   \
+    GOOGLE_CHECK((self)->owner.get() == NULL);  \
+    GOOGLE_CHECK((self)->message == NULL);      \
+    GOOGLE_CHECK((self)->parent_field == NULL); \
+    GOOGLE_CHECK((self)->parent == NULL);       \
+  } while (0);
+
+// Returns a new reference.
+static PyObject* GetKey(PyObject* x) {
+  // Just the identity function.
+  Py_INCREF(x);
+  return x;
+}
+
+#define GET_KEY(keyfunc, value)                                         \
+  ((keyfunc) == NULL ?                                                  \
+  GetKey((value)) :                                                     \
+  PyObject_CallFunctionObjArgs((keyfunc), (value), NULL))
+
+// Converts a comparison function that returns -1, 0, or 1 into a
+// less-than predicate.
+//
+// Returns -1 on error, 1 if x < y, 0 if x >= y.
+static int islt(PyObject *x, PyObject *y, PyObject *compare) {
+  if (compare == NULL)
+    return PyObject_RichCompareBool(x, y, Py_LT);
+
+  ScopedPyObjectPtr res(PyObject_CallFunctionObjArgs(compare, x, y, NULL));
+  if (res == NULL)
+    return -1;
+  if (!PyInt_Check(res)) {
+    PyErr_Format(PyExc_TypeError,
+                 "comparison function must return int, not %.200s",
+                 Py_TYPE(res)->tp_name);
+    return -1;
+  }
+  return PyInt_AsLong(res) < 0;
+}
+
+// Copied from uarrsort.c but swaps memcpy swaps with protobuf/python swaps
+// TODO(anuraag): Is there a better way to do this then reinventing the wheel?
+static int InternalQuickSort(RepeatedCompositeContainer* self,
+                             Py_ssize_t start,
+                             Py_ssize_t limit,
+                             PyObject* cmp,
+                             PyObject* keyfunc) {
+  if (limit - start <= 1)
+    return 0;  // Nothing to sort.
+
+  GOOGLE_CHECK_ATTACHED(self);
+
+  google::protobuf::Message* message = self->message;
+  const google::protobuf::Reflection* reflection = message->GetReflection();
+  const google::protobuf::FieldDescriptor* descriptor = self->parent_field->descriptor;
+  Py_ssize_t left;
+  Py_ssize_t right;
+
+  PyObject* children = self->child_messages;
+
+  do {
+    left = start;
+    right = limit;
+    ScopedPyObjectPtr mid(
+        GET_KEY(keyfunc, PyList_GET_ITEM(children, (start + limit) / 2)));
+    do {
+      ScopedPyObjectPtr key(GET_KEY(keyfunc, PyList_GET_ITEM(children, left)));
+      int is_lt = islt(key, mid, cmp);
+      if (is_lt == -1)
+        return -1;
+      /* array[left]<x */
+      while (is_lt) {
+        ++left;
+        ScopedPyObjectPtr key(GET_KEY(keyfunc,
+                                      PyList_GET_ITEM(children, left)));
+        is_lt = islt(key, mid, cmp);
+        if (is_lt == -1)
+          return -1;
+      }
+      key.reset(GET_KEY(keyfunc, PyList_GET_ITEM(children, right - 1)));
+      is_lt = islt(mid, key, cmp);
+      if (is_lt == -1)
+        return -1;
+      while (is_lt) {
+        --right;
+        ScopedPyObjectPtr key(GET_KEY(keyfunc,
+                                      PyList_GET_ITEM(children, right - 1)));
+        is_lt = islt(mid, key, cmp);
+        if (is_lt == -1)
+          return -1;
+      }
+      if (left < right) {
+        --right;
+        if (left < right) {
+          reflection->SwapElements(message, descriptor, left, right);
+          PyObject* tmp = PyList_GET_ITEM(children, left);
+          PyList_SET_ITEM(children, left, PyList_GET_ITEM(children, right));
+          PyList_SET_ITEM(children, right, tmp);
+        }
+        ++left;
+      }
+    } while (left < right);
+
+    if ((right - start) < (limit - left)) {
+      /* sort [start..right[ */
+      if (start < (right - 1)) {
+        InternalQuickSort(self, start, right, cmp, keyfunc);
+      }
+
+      /* sort [left..limit[ */
+      start = left;
+    } else {
+      /* sort [left..limit[ */
+      if (left < (limit - 1)) {
+        InternalQuickSort(self, left, limit, cmp, keyfunc);
+      }
+
+      /* sort [start..right[ */
+      limit = right;
+    }
+  } while (start < (limit - 1));
+
+  return 0;
+}
+
+#undef GET_KEY
+
+// ---------------------------------------------------------------------
+// len()
+
+static Py_ssize_t Length(RepeatedCompositeContainer* self) {
+  google::protobuf::Message* message = self->message;
+  if (message != NULL) {
+    return message->GetReflection()->FieldSize(*message,
+                                               self->parent_field->descriptor);
+  } else {
+    // The container has been released (i.e. by a call to Clear() or
+    // ClearField() on the parent) and thus there's no message.
+    return PyList_GET_SIZE(self->child_messages);
+  }
+}
+
+// Returns 0 if successful; returns -1 and sets an exception if
+// unsuccessful.
+static int UpdateChildMessages(RepeatedCompositeContainer* self) {
+  if (self->message == NULL)
+    return 0;
+
+  // A MergeFrom on a parent message could have caused extra messages to be
+  // added in the underlying protobuf so add them to our list. They can never
+  // be removed in such a way so there's no need to worry about that.
+  Py_ssize_t message_length = Length(self);
+  Py_ssize_t child_length = PyList_GET_SIZE(self->child_messages);
+  google::protobuf::Message* message = self->message;
+  const google::protobuf::Reflection* reflection = message->GetReflection();
+  for (Py_ssize_t i = child_length; i < message_length; ++i) {
+    const Message& sub_message = reflection->GetRepeatedMessage(
+        *(self->message), self->parent_field->descriptor, i);
+    ScopedPyObjectPtr py_cmsg(cmessage::NewEmpty(self->subclass_init));
+    if (py_cmsg == NULL) {
+      return -1;
+    }
+    CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg.get());
+    cmsg->owner = self->owner;
+    cmsg->message = const_cast<google::protobuf::Message*>(&sub_message);
+    cmsg->parent = self->parent;
+    if (cmessage::InitAttributes(cmsg, NULL, NULL) < 0) {
+      return -1;
+    }
+    PyList_Append(self->child_messages, py_cmsg);
+  }
+  return 0;
+}
+
+// ---------------------------------------------------------------------
+// add()
+
+static PyObject* AddToAttached(RepeatedCompositeContainer* self,
+                               PyObject* args,
+                               PyObject* kwargs) {
+  GOOGLE_CHECK_ATTACHED(self);
+
+  if (UpdateChildMessages(self) < 0) {
+    return NULL;
+  }
+  if (cmessage::AssureWritable(self->parent) == -1)
+    return NULL;
+  google::protobuf::Message* message = self->message;
+  google::protobuf::Message* sub_message =
+      message->GetReflection()->AddMessage(message,
+                                           self->parent_field->descriptor);
+  PyObject* py_cmsg = cmessage::NewEmpty(self->subclass_init);
+  if (py_cmsg == NULL) {
+    return NULL;
+  }
+  CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+
+  cmsg->owner = self->owner;
+  cmsg->message = sub_message;
+  cmsg->parent = self->parent;
+  // cmessage::InitAttributes must be called after cmsg->message has
+  // been set.
+  if (cmessage::InitAttributes(cmsg, NULL, kwargs) < 0) {
+    Py_DECREF(py_cmsg);
+    return NULL;
+  }
+  PyList_Append(self->child_messages, py_cmsg);
+  return py_cmsg;
+}
+
+static PyObject* AddToReleased(RepeatedCompositeContainer* self,
+                               PyObject* args,
+                               PyObject* kwargs) {
+  GOOGLE_CHECK_RELEASED(self);
+
+  // Create the CMessage
+  PyObject* py_cmsg = PyObject_CallObject(self->subclass_init, NULL);
+  if (py_cmsg == NULL)
+    return NULL;
+  CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+  if (cmessage::InitAttributes(cmsg, NULL, kwargs) < 0) {
+    Py_DECREF(py_cmsg);
+    return NULL;
+  }
+
+  // The Message got created by the call to subclass_init above and
+  // it set self->owner to the newly allocated message.
+
+  PyList_Append(self->child_messages, py_cmsg);
+  return py_cmsg;
+}
+
+PyObject* Add(RepeatedCompositeContainer* self,
+              PyObject* args,
+              PyObject* kwargs) {
+  if (self->message == NULL)
+    return AddToReleased(self, args, kwargs);
+  else
+    return AddToAttached(self, args, kwargs);
+}
+
+// ---------------------------------------------------------------------
+// extend()
+
+PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value) {
+  cmessage::AssureWritable(self->parent);
+  if (UpdateChildMessages(self) < 0) {
+    return NULL;
+  }
+  ScopedPyObjectPtr iter(PyObject_GetIter(value));
+  if (iter == NULL) {
+    PyErr_SetString(PyExc_TypeError, "Value must be iterable");
+    return NULL;
+  }
+  ScopedPyObjectPtr next;
+  while ((next.reset(PyIter_Next(iter))) != NULL) {
+    if (!PyObject_TypeCheck(next, &CMessage_Type)) {
+      PyErr_SetString(PyExc_TypeError, "Not a cmessage");
+      return NULL;
+    }
+    ScopedPyObjectPtr new_message(Add(self, NULL, NULL));
+    if (new_message == NULL) {
+      return NULL;
+    }
+    CMessage* new_cmessage = reinterpret_cast<CMessage*>(new_message.get());
+    if (cmessage::MergeFrom(new_cmessage, next) == NULL) {
+      return NULL;
+    }
+  }
+  if (PyErr_Occurred()) {
+    return NULL;
+  }
+  Py_RETURN_NONE;
+}
+
+PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other) {
+  if (UpdateChildMessages(self) < 0) {
+    return NULL;
+  }
+  return Extend(self, other);
+}
+
+PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice) {
+  if (UpdateChildMessages(self) < 0) {
+    return NULL;
+  }
+  Py_ssize_t from;
+  Py_ssize_t to;
+  Py_ssize_t step;
+  Py_ssize_t length = Length(self);
+  Py_ssize_t slicelength;
+  if (PySlice_Check(slice)) {
+#if PY_MAJOR_VERSION >= 3
+    if (PySlice_GetIndicesEx(slice,
+#else
+    if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
+#endif
+                             length, &from, &to, &step, &slicelength) == -1) {
+      return NULL;
+    }
+    return PyList_GetSlice(self->child_messages, from, to);
+  } else if (PyInt_Check(slice) || PyLong_Check(slice)) {
+    from = to = PyLong_AsLong(slice);
+    if (from < 0) {
+      from = to = length + from;
+    }
+    PyObject* result = PyList_GetItem(self->child_messages, from);
+    if (result == NULL) {
+      return NULL;
+    }
+    Py_INCREF(result);
+    return result;
+  }
+  PyErr_SetString(PyExc_TypeError, "index must be an integer or slice");
+  return NULL;
+}
+
+int AssignSubscript(RepeatedCompositeContainer* self,
+                    PyObject* slice,
+                    PyObject* value) {
+  if (UpdateChildMessages(self) < 0) {
+    return -1;
+  }
+  if (value != NULL) {
+    PyErr_SetString(PyExc_TypeError, "does not support assignment");
+    return -1;
+  }
+
+  // Delete from the underlying Message, if any.
+  if (self->message != NULL) {
+    if (cmessage::InternalDeleteRepeatedField(self->message,
+                                              self->parent_field->descriptor,
+                                              slice,
+                                              self->child_messages) < 0) {
+      return -1;
+    }
+  } else {
+    Py_ssize_t from;
+    Py_ssize_t to;
+    Py_ssize_t step;
+    Py_ssize_t length = Length(self);
+    Py_ssize_t slicelength;
+    if (PySlice_Check(slice)) {
+#if PY_MAJOR_VERSION >= 3
+      if (PySlice_GetIndicesEx(slice,
+#else
+      if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
+#endif
+                               length, &from, &to, &step, &slicelength) == -1) {
+        return -1;
+      }
+      return PySequence_DelSlice(self->child_messages, from, to);
+    } else if (PyInt_Check(slice) || PyLong_Check(slice)) {
+      from = to = PyLong_AsLong(slice);
+      if (from < 0) {
+        from = to = length + from;
+      }
+      return PySequence_DelItem(self->child_messages, from);
+    }
+  }
+
+  return 0;
+}
+
+static PyObject* Remove(RepeatedCompositeContainer* self, PyObject* value) {
+  if (UpdateChildMessages(self) < 0) {
+    return NULL;
+  }
+  Py_ssize_t index = PySequence_Index(self->child_messages, value);
+  if (index == -1) {
+    return NULL;
+  }
+  ScopedPyObjectPtr py_index(PyLong_FromLong(index));
+  if (AssignSubscript(self, py_index, NULL) < 0) {
+    return NULL;
+  }
+  Py_RETURN_NONE;
+}
+
+static PyObject* RichCompare(RepeatedCompositeContainer* self,
+                             PyObject* other,
+                             int opid) {
+  if (UpdateChildMessages(self) < 0) {
+    return NULL;
+  }
+  if (!PyObject_TypeCheck(other, &RepeatedCompositeContainer_Type)) {
+    PyErr_SetString(PyExc_TypeError,
+                    "Can only compare repeated composite fields "
+                    "against other repeated composite fields.");
+    return NULL;
+  }
+  if (opid == Py_EQ || opid == Py_NE) {
+    // TODO(anuraag): Don't make new lists just for this...
+    ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+    if (full_slice == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr list(Subscript(self, full_slice));
+    if (list == NULL) {
+      return NULL;
+    }
+    ScopedPyObjectPtr other_list(
+        Subscript(
+            reinterpret_cast<RepeatedCompositeContainer*>(other), full_slice));
+    if (other_list == NULL) {
+      return NULL;
+    }
+    return PyObject_RichCompare(list, other_list, opid);
+  } else {
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+  }
+}
+
+// ---------------------------------------------------------------------
+// sort()
+
+static PyObject* SortAttached(RepeatedCompositeContainer* self,
+                              PyObject* args,
+                              PyObject* kwds) {
+  // Sort the underlying Message array.
+  PyObject *compare = NULL;
+  int reverse = 0;
+  PyObject *keyfunc = NULL;
+  static char *kwlist[] = {"cmp", "key", "reverse", 0};
+
+  if (args != NULL) {
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi:sort",
+                                     kwlist, &compare, &keyfunc, &reverse))
+      return NULL;
+  }
+  if (compare == Py_None)
+    compare = NULL;
+  if (keyfunc == Py_None)
+    keyfunc = NULL;
+
+  const Py_ssize_t length = Length(self);
+  if (InternalQuickSort(self, 0, length, compare, keyfunc) < 0)
+    return NULL;
+
+  // Finally reverse the result if requested.
+  if (reverse) {
+    google::protobuf::Message* message = self->message;
+    const google::protobuf::Reflection* reflection = message->GetReflection();
+    const google::protobuf::FieldDescriptor* descriptor = self->parent_field->descriptor;
+
+    // Reverse the Message array.
+    for (int i = 0; i < length / 2; ++i)
+      reflection->SwapElements(message, descriptor, i, length - i - 1);
+
+    // Reverse the Python list.
+    ScopedPyObjectPtr res(PyObject_CallMethod(self->child_messages,
+                                              "reverse", NULL));
+    if (res == NULL)
+      return NULL;
+  }
+
+  Py_RETURN_NONE;
+}
+
+static PyObject* SortReleased(RepeatedCompositeContainer* self,
+                              PyObject* args,
+                              PyObject* kwds) {
+  ScopedPyObjectPtr m(PyObject_GetAttrString(self->child_messages, "sort"));
+  if (m == NULL)
+    return NULL;
+  if (PyObject_Call(m, args, kwds) == NULL)
+    return NULL;
+  Py_RETURN_NONE;
+}
+
+static PyObject* Sort(RepeatedCompositeContainer* self,
+                      PyObject* args,
+                      PyObject* kwds) {
+  // Support the old sort_function argument for backwards
+  // compatibility.
+  if (kwds != NULL) {
+    PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function");
+    if (sort_func != NULL) {
+      // Must set before deleting as sort_func is a borrowed reference
+      // and kwds might be the only thing keeping it alive.
+      PyDict_SetItemString(kwds, "cmp", sort_func);
+      PyDict_DelItemString(kwds, "sort_function");
+    }
+  }
+
+  if (UpdateChildMessages(self) < 0)
+    return NULL;
+  if (self->message == NULL) {
+    return SortReleased(self, args, kwds);
+  } else {
+    return SortAttached(self, args, kwds);
+  }
+}
+
+// ---------------------------------------------------------------------
+
+static PyObject* Item(RepeatedCompositeContainer* self, Py_ssize_t index) {
+  if (UpdateChildMessages(self) < 0) {
+    return NULL;
+  }
+  Py_ssize_t length = Length(self);
+  if (index < 0) {
+    index = length + index;
+  }
+  PyObject* item = PyList_GetItem(self->child_messages, index);
+  if (item == NULL) {
+    return NULL;
+  }
+  Py_INCREF(item);
+  return item;
+}
+
+// The caller takes ownership of the returned Message.
+Message* ReleaseLast(const FieldDescriptor* field,
+                     const Descriptor* type,
+                     Message* message) {
+  GOOGLE_CHECK_NOTNULL(field);
+  GOOGLE_CHECK_NOTNULL(type);
+  GOOGLE_CHECK_NOTNULL(message);
+
+  Message* released_message = message->GetReflection()->ReleaseLast(
+      message, field);
+  // TODO(tibell): Deal with proto1.
+
+  // ReleaseMessage will return NULL which differs from
+  // child_cmessage->message, if the field does not exist.  In this case,
+  // the latter points to the default instance via a const_cast<>, so we
+  // have to reset it to a new mutable object since we are taking ownership.
+  if (released_message == NULL) {
+    const Message* prototype = global_message_factory->GetPrototype(type);
+    GOOGLE_CHECK_NOTNULL(prototype);
+    return prototype->New();
+  } else {
+    return released_message;
+  }
+}
+
+// Release field of message and transfer the ownership to cmessage.
+void ReleaseLastTo(const FieldDescriptor* field,
+                   Message* message,
+                   CMessage* cmessage) {
+  GOOGLE_CHECK_NOTNULL(field);
+  GOOGLE_CHECK_NOTNULL(message);
+  GOOGLE_CHECK_NOTNULL(cmessage);
+
+  shared_ptr<Message> released_message(
+      ReleaseLast(field, cmessage->message->GetDescriptor(), message));
+  cmessage->parent = NULL;
+  cmessage->parent_field = NULL;
+  cmessage->message = released_message.get();
+  cmessage->read_only = false;
+  cmessage::SetOwner(cmessage, released_message);
+}
+
+// Called to release a container using
+// ClearField('container_field_name') on the parent.
+int Release(RepeatedCompositeContainer* self) {
+  if (UpdateChildMessages(self) < 0) {
+    PyErr_WriteUnraisable(PyBytes_FromString("Failed to update released "
+                                             "messages"));
+    return -1;
+  }
+
+  Message* message = self->message;
+  const FieldDescriptor* field = self->parent_field->descriptor;
+
+  // The reflection API only lets us release the last message in a
+  // repeated field.  Therefore we iterate through the children
+  // starting with the last one.
+  const Py_ssize_t size = PyList_GET_SIZE(self->child_messages);
+  GOOGLE_DCHECK_EQ(size, message->GetReflection()->FieldSize(*message, field));
+  for (Py_ssize_t i = size - 1; i >= 0; --i) {
+    CMessage* child_cmessage = reinterpret_cast<CMessage*>(
+        PyList_GET_ITEM(self->child_messages, i));
+    ReleaseLastTo(field, message, child_cmessage);
+  }
+
+  // Detach from containing message.
+  self->parent = NULL;
+  self->parent_field = NULL;
+  self->message = NULL;
+  self->owner.reset();
+
+  return 0;
+}
+
+int SetOwner(RepeatedCompositeContainer* self,
+             const shared_ptr<Message>& new_owner) {
+  GOOGLE_CHECK_ATTACHED(self);
+
+  self->owner = new_owner;
+  const Py_ssize_t n = PyList_GET_SIZE(self->child_messages);
+  for (Py_ssize_t i = 0; i < n; ++i) {
+    PyObject* msg = PyList_GET_ITEM(self->child_messages, i);
+    if (cmessage::SetOwner(reinterpret_cast<CMessage*>(msg), new_owner) == -1) {
+      return -1;
+    }
+  }
+  return 0;
+}
+
+static int Init(RepeatedCompositeContainer* self,
+                PyObject* args,
+                PyObject* kwargs) {
+  self->message = NULL;
+  self->parent = NULL;
+  self->parent_field = NULL;
+  self->subclass_init = NULL;
+  self->child_messages = PyList_New(0);
+  return 0;
+}
+
+static void Dealloc(RepeatedCompositeContainer* self) {
+  Py_CLEAR(self->child_messages);
+  // TODO(tibell): Do we need to call delete on these objects to make
+  // sure their destructors are called?
+  self->owner.reset();
+  Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+static PySequenceMethods SqMethods = {
+  (lenfunc)Length,        /* sq_length */
+  0, /* sq_concat */
+  0, /* sq_repeat */
+  (ssizeargfunc)Item /* sq_item */
+};
+
+static PyMappingMethods MpMethods = {
+  (lenfunc)Length,               /* mp_length */
+  (binaryfunc)Subscript,      /* mp_subscript */
+  (objobjargproc)AssignSubscript,/* mp_ass_subscript */
+};
+
+static PyMethodDef Methods[] = {
+  { "add", (PyCFunction) Add, METH_VARARGS | METH_KEYWORDS,
+    "Adds an object to the repeated container." },
+  { "extend", (PyCFunction) Extend, METH_O,
+    "Adds objects to the repeated container." },
+  { "remove", (PyCFunction) Remove, METH_O,
+    "Removes an object from the repeated container." },
+  { "sort", (PyCFunction) Sort, METH_VARARGS | METH_KEYWORDS,
+    "Sorts the repeated container." },
+  { "MergeFrom", (PyCFunction) MergeFrom, METH_O,
+    "Adds objects to the repeated container." },
+  { NULL, NULL }
+};
+
+}  // namespace repeated_composite_container
+
+PyTypeObject RepeatedCompositeContainer_Type = {
+  PyVarObject_HEAD_INIT(&PyType_Type, 0)
+  "google.protobuf.internal."
+  "cpp._message.RepeatedCompositeContainer",  // tp_name
+  sizeof(RepeatedCompositeContainer),     // tp_basicsize
+  0,                                   //  tp_itemsize
+  (destructor)repeated_composite_container::Dealloc,  //  tp_dealloc
+  0,                                   //  tp_print
+  0,                                   //  tp_getattr
+  0,                                   //  tp_setattr
+  0,                                   //  tp_compare
+  0,                                   //  tp_repr
+  0,                                   //  tp_as_number
+  &repeated_composite_container::SqMethods,   //  tp_as_sequence
+  &repeated_composite_container::MpMethods,   //  tp_as_mapping
+  0,                                   //  tp_hash
+  0,                                   //  tp_call
+  0,                                   //  tp_str
+  0,                                   //  tp_getattro
+  0,                                   //  tp_setattro
+  0,                                   //  tp_as_buffer
+  Py_TPFLAGS_DEFAULT,                  //  tp_flags
+  "A Repeated scalar container",       //  tp_doc
+  0,                                   //  tp_traverse
+  0,                                   //  tp_clear
+  (richcmpfunc)repeated_composite_container::RichCompare,  //  tp_richcompare
+  0,                                   //  tp_weaklistoffset
+  0,                                   //  tp_iter
+  0,                                   //  tp_iternext
+  repeated_composite_container::Methods,   //  tp_methods
+  0,                                   //  tp_members
+  0,                                   //  tp_getset
+  0,                                   //  tp_base
+  0,                                   //  tp_dict
+  0,                                   //  tp_descr_get
+  0,                                   //  tp_descr_set
+  0,                                   //  tp_dictoffset
+  (initproc)repeated_composite_container::Init,  //  tp_init
+};
+
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/python/google/protobuf/pyext/repeated_composite_container.h b/protobuf/python/google/protobuf/pyext/repeated_composite_container.h
new file mode 100644
index 0000000..898ef5a
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/repeated_composite_container.h
@@ -0,0 +1,172 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
+
+#include <Python.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+#include <string>
+#include <vector>
+
+
+namespace google {
+namespace protobuf {
+
+class FieldDescriptor;
+class Message;
+
+using internal::shared_ptr;
+
+namespace python {
+
+struct CMessage;
+struct CFieldDescriptor;
+
+// A RepeatedCompositeContainer can be in one of two states: attached
+// or released.
+//
+// When in the attached state all modifications to the container are
+// done both on the 'message' and on the 'child_messages'
+// list.  In this state all Messages refered to by the children in
+// 'child_messages' are owner by the 'owner'.
+//
+// When in the released state 'message', 'owner', 'parent', and
+// 'parent_field' are NULL.
+typedef struct RepeatedCompositeContainer {
+  PyObject_HEAD;
+
+  // This is the top-level C++ Message object that owns the whole
+  // proto tree.  Every Python RepeatedCompositeContainer holds a
+  // reference to it in order to keep it alive as long as there's a
+  // Python object that references any part of the tree.
+  shared_ptr<Message> owner;
+
+  // Weak reference to parent object. May be NULL. Used to make sure
+  // the parent is writable before modifying the
+  // RepeatedCompositeContainer.
+  CMessage* parent;
+
+  // A descriptor used to modify the underlying 'message'.
+  CFieldDescriptor* parent_field;
+
+  // Pointer to the C++ Message that contains this container.  The
+  // RepeatedCompositeContainer does not own this pointer.
+  //
+  // If NULL, this message has been released from its parent (by
+  // calling Clear() or ClearField() on the parent.
+  Message* message;
+
+  // A callable that is used to create new child messages.
+  PyObject* subclass_init;
+
+  // A list of child messages.
+  PyObject* child_messages;
+} RepeatedCompositeContainer;
+
+extern PyTypeObject RepeatedCompositeContainer_Type;
+
+namespace repeated_composite_container {
+
+// Returns the number of items in this repeated composite container.
+static Py_ssize_t Length(RepeatedCompositeContainer* self);
+
+// Appends a new CMessage to the container and returns it.  The
+// CMessage is initialized using the content of kwargs.
+//
+// Returns a new reference if successful; returns NULL and sets an
+// exception if unsuccessful.
+PyObject* Add(RepeatedCompositeContainer* self,
+              PyObject* args,
+              PyObject* kwargs);
+
+// Appends all the CMessages in the input iterator to the container.
+//
+// Returns None if successful; returns NULL and sets an exception if
+// unsuccessful.
+PyObject* Extend(RepeatedCompositeContainer* self, PyObject* value);
+
+// Appends a new message to the container for each message in the
+// input iterator, merging each data element in. Equivalent to extend.
+//
+// Returns None if successful; returns NULL and sets an exception if
+// unsuccessful.
+PyObject* MergeFrom(RepeatedCompositeContainer* self, PyObject* other);
+
+// Accesses messages in the container.
+//
+// Returns a new reference to the message for an integer parameter.
+// Returns a new reference to a list of messages for a slice.
+PyObject* Subscript(RepeatedCompositeContainer* self, PyObject* slice);
+
+// Deletes items from the container (cannot be used for assignment).
+//
+// Returns 0 on success, -1 on failure.
+int AssignSubscript(RepeatedCompositeContainer* self,
+                    PyObject* slice,
+                    PyObject* value);
+
+// Releases the messages in the container to the given message.
+//
+// Returns 0 on success, -1 on failure.
+int ReleaseToMessage(RepeatedCompositeContainer* self,
+                     google::protobuf::Message* new_message);
+
+// Releases the messages in the container to a new message.
+//
+// Returns 0 on success, -1 on failure.
+int Release(RepeatedCompositeContainer* self);
+
+// Returns 0 on success, -1 on failure.
+int SetOwner(RepeatedCompositeContainer* self,
+             const shared_ptr<Message>& new_owner);
+
+// Removes the last element of the repeated message field 'field' on
+// the Message 'message', and transfers the ownership of the released
+// Message to 'cmessage'.
+//
+// Corresponds to reflection api method ReleaseMessage.
+void ReleaseLastTo(const FieldDescriptor* field,
+                   Message* message,
+                   CMessage* cmessage);
+
+}  // namespace repeated_composite_container
+}  // namespace python
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_COMPOSITE_CONTAINER_H__
diff --git a/protobuf/python/google/protobuf/pyext/repeated_scalar_container.cc b/protobuf/python/google/protobuf/pyext/repeated_scalar_container.cc
new file mode 100644
index 0000000..e627d37
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/repeated_scalar_container.cc
@@ -0,0 +1,825 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#include <google/protobuf/pyext/repeated_scalar_container.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/pyext/descriptor.h>
+#include <google/protobuf/pyext/message.h>
+#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
+
+#if PY_MAJOR_VERSION >= 3
+  #define PyInt_FromLong PyLong_FromLong
+  #if PY_VERSION_HEX < 0x03030000
+    #error "Python 3.0 - 3.2 are not supported."
+  #else
+  #define PyString_AsString(ob) \
+    (PyUnicode_Check(ob)? PyUnicode_AsUTF8(ob): PyBytes_AS_STRING(ob))
+  #endif
+#endif
+
+namespace google {
+namespace protobuf {
+namespace python {
+
+extern google::protobuf::DynamicMessageFactory* global_message_factory;
+
+namespace repeated_scalar_container {
+
+static int InternalAssignRepeatedField(
+    RepeatedScalarContainer* self, PyObject* list) {
+  self->message->GetReflection()->ClearField(self->message,
+                                             self->parent_field->descriptor);
+  for (Py_ssize_t i = 0; i < PyList_GET_SIZE(list); ++i) {
+    PyObject* value = PyList_GET_ITEM(list, i);
+    if (Append(self, value) == NULL) {
+      return -1;
+    }
+  }
+  return 0;
+}
+
+static Py_ssize_t Len(RepeatedScalarContainer* self) {
+  google::protobuf::Message* message = self->message;
+  return message->GetReflection()->FieldSize(*message,
+                                             self->parent_field->descriptor);
+}
+
+static int AssignItem(RepeatedScalarContainer* self,
+                      Py_ssize_t index,
+                      PyObject* arg) {
+  cmessage::AssureWritable(self->parent);
+  google::protobuf::Message* message = self->message;
+  const google::protobuf::FieldDescriptor* field_descriptor =
+      self->parent_field->descriptor;
+  if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+    PyErr_SetString(
+        PyExc_KeyError, "Field does not belong to message!");
+    return -1;
+  }
+
+  const google::protobuf::Reflection* reflection = message->GetReflection();
+  int field_size = reflection->FieldSize(*message, field_descriptor);
+  if (index < 0) {
+    index = field_size + index;
+  }
+  if (index < 0 || index >= field_size) {
+    PyErr_Format(PyExc_IndexError,
+                 "list assignment index (%d) out of range",
+                 static_cast<int>(index));
+    return -1;
+  }
+
+  if (arg == NULL) {
+    ScopedPyObjectPtr py_index(PyLong_FromLong(index));
+    return cmessage::InternalDeleteRepeatedField(message, field_descriptor,
+                                                 py_index, NULL);
+  }
+
+  if (PySequence_Check(arg) && !(PyBytes_Check(arg) || PyUnicode_Check(arg))) {
+    PyErr_SetString(PyExc_TypeError, "Value must be scalar");
+    return -1;
+  }
+
+  switch (field_descriptor->cpp_type()) {
+    case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+      GOOGLE_CHECK_GET_INT32(arg, value, -1);
+      reflection->SetRepeatedInt32(message, field_descriptor, index, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+      GOOGLE_CHECK_GET_INT64(arg, value, -1);
+      reflection->SetRepeatedInt64(message, field_descriptor, index, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+      GOOGLE_CHECK_GET_UINT32(arg, value, -1);
+      reflection->SetRepeatedUInt32(message, field_descriptor, index, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+      GOOGLE_CHECK_GET_UINT64(arg, value, -1);
+      reflection->SetRepeatedUInt64(message, field_descriptor, index, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+      GOOGLE_CHECK_GET_FLOAT(arg, value, -1);
+      reflection->SetRepeatedFloat(message, field_descriptor, index, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+      GOOGLE_CHECK_GET_DOUBLE(arg, value, -1);
+      reflection->SetRepeatedDouble(message, field_descriptor, index, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+      GOOGLE_CHECK_GET_BOOL(arg, value, -1);
+      reflection->SetRepeatedBool(message, field_descriptor, index, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+      if (!CheckAndSetString(
+          arg, message, field_descriptor, reflection, false, index)) {
+        return -1;
+      }
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+      GOOGLE_CHECK_GET_INT32(arg, value, -1);
+      const google::protobuf::EnumDescriptor* enum_descriptor =
+          field_descriptor->enum_type();
+      const google::protobuf::EnumValueDescriptor* enum_value =
+          enum_descriptor->FindValueByNumber(value);
+      if (enum_value != NULL) {
+        reflection->SetRepeatedEnum(message, field_descriptor, index,
+                                    enum_value);
+      } else {
+        ScopedPyObjectPtr s(PyObject_Str(arg));
+        if (s != NULL) {
+          PyErr_Format(PyExc_ValueError, "Unknown enum value: %s",
+                       PyString_AsString(s.get()));
+        }
+        return -1;
+      }
+      break;
+    }
+    default:
+      PyErr_Format(
+          PyExc_SystemError, "Adding value to a field of unknown type %d",
+          field_descriptor->cpp_type());
+      return -1;
+  }
+  return 0;
+}
+
+static PyObject* Item(RepeatedScalarContainer* self, Py_ssize_t index) {
+  google::protobuf::Message* message = self->message;
+  const google::protobuf::FieldDescriptor* field_descriptor =
+      self->parent_field->descriptor;
+  const google::protobuf::Reflection* reflection = message->GetReflection();
+
+  int field_size = reflection->FieldSize(*message, field_descriptor);
+  if (index < 0) {
+    index = field_size + index;
+  }
+  if (index < 0 || index >= field_size) {
+    PyErr_Format(PyExc_IndexError,
+                 "list assignment index (%d) out of range",
+                 static_cast<int>(index));
+    return NULL;
+  }
+
+  PyObject* result = NULL;
+  switch (field_descriptor->cpp_type()) {
+    case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+      int32 value = reflection->GetRepeatedInt32(
+          *message, field_descriptor, index);
+      result = PyInt_FromLong(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+      int64 value = reflection->GetRepeatedInt64(
+          *message, field_descriptor, index);
+      result = PyLong_FromLongLong(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+      uint32 value = reflection->GetRepeatedUInt32(
+          *message, field_descriptor, index);
+      result = PyLong_FromLongLong(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+      uint64 value = reflection->GetRepeatedUInt64(
+          *message, field_descriptor, index);
+      result = PyLong_FromUnsignedLongLong(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+      float value = reflection->GetRepeatedFloat(
+          *message, field_descriptor, index);
+      result = PyFloat_FromDouble(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+      double value = reflection->GetRepeatedDouble(
+          *message, field_descriptor, index);
+      result = PyFloat_FromDouble(value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+      bool value = reflection->GetRepeatedBool(
+          *message, field_descriptor, index);
+      result = PyBool_FromLong(value ? 1 : 0);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+      const google::protobuf::EnumValueDescriptor* enum_value =
+          message->GetReflection()->GetRepeatedEnum(
+              *message, field_descriptor, index);
+      result = PyInt_FromLong(enum_value->number());
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+      string value = reflection->GetRepeatedString(
+          *message, field_descriptor, index);
+      result = ToStringObject(field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+      PyObject* py_cmsg = PyObject_CallObject(reinterpret_cast<PyObject*>(
+          &CMessage_Type), NULL);
+      if (py_cmsg == NULL) {
+        return NULL;
+      }
+      CMessage* cmsg = reinterpret_cast<CMessage*>(py_cmsg);
+      const google::protobuf::Message& msg = reflection->GetRepeatedMessage(
+          *message, field_descriptor, index);
+      cmsg->owner = self->owner;
+      cmsg->parent = self->parent;
+      cmsg->message = const_cast<google::protobuf::Message*>(&msg);
+      cmsg->read_only = false;
+      result = reinterpret_cast<PyObject*>(py_cmsg);
+      break;
+    }
+    default:
+      PyErr_Format(
+          PyExc_SystemError,
+          "Getting value from a repeated field of unknown type %d",
+          field_descriptor->cpp_type());
+  }
+
+  return result;
+}
+
+static PyObject* Subscript(RepeatedScalarContainer* self, PyObject* slice) {
+  Py_ssize_t from;
+  Py_ssize_t to;
+  Py_ssize_t step;
+  Py_ssize_t length;
+  Py_ssize_t slicelength;
+  bool return_list = false;
+#if PY_MAJOR_VERSION < 3
+  if (PyInt_Check(slice)) {
+    from = to = PyInt_AsLong(slice);
+  } else  // NOLINT
+#endif
+  if (PyLong_Check(slice)) {
+    from = to = PyLong_AsLong(slice);
+  } else if (PySlice_Check(slice)) {
+    length = Len(self);
+#if PY_MAJOR_VERSION >= 3
+    if (PySlice_GetIndicesEx(slice,
+#else
+    if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
+#endif
+                             length, &from, &to, &step, &slicelength) == -1) {
+      return NULL;
+    }
+    return_list = true;
+  } else {
+    PyErr_SetString(PyExc_TypeError, "list indices must be integers");
+    return NULL;
+  }
+
+  if (!return_list) {
+    return Item(self, from);
+  }
+
+  PyObject* list = PyList_New(0);
+  if (list == NULL) {
+    return NULL;
+  }
+  if (from <= to) {
+    if (step < 0) {
+      return list;
+    }
+    for (Py_ssize_t index = from; index < to; index += step) {
+      if (index < 0 || index >= length) {
+        break;
+      }
+      ScopedPyObjectPtr s(Item(self, index));
+      PyList_Append(list, s);
+    }
+  } else {
+    if (step > 0) {
+      return list;
+    }
+    for (Py_ssize_t index = from; index > to; index += step) {
+      if (index < 0 || index >= length) {
+        break;
+      }
+      ScopedPyObjectPtr s(Item(self, index));
+      PyList_Append(list, s);
+    }
+  }
+  return list;
+}
+
+PyObject* Append(RepeatedScalarContainer* self, PyObject* item) {
+  cmessage::AssureWritable(self->parent);
+  google::protobuf::Message* message = self->message;
+  const google::protobuf::FieldDescriptor* field_descriptor =
+      self->parent_field->descriptor;
+
+  if (!FIELD_BELONGS_TO_MESSAGE(field_descriptor, message)) {
+    PyErr_SetString(
+        PyExc_KeyError, "Field does not belong to message!");
+    return NULL;
+  }
+
+  const google::protobuf::Reflection* reflection = message->GetReflection();
+  switch (field_descriptor->cpp_type()) {
+    case google::protobuf::FieldDescriptor::CPPTYPE_INT32: {
+      GOOGLE_CHECK_GET_INT32(item, value, NULL);
+      reflection->AddInt32(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {
+      GOOGLE_CHECK_GET_INT64(item, value, NULL);
+      reflection->AddInt64(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: {
+      GOOGLE_CHECK_GET_UINT32(item, value, NULL);
+      reflection->AddUInt32(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {
+      GOOGLE_CHECK_GET_UINT64(item, value, NULL);
+      reflection->AddUInt64(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: {
+      GOOGLE_CHECK_GET_FLOAT(item, value, NULL);
+      reflection->AddFloat(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: {
+      GOOGLE_CHECK_GET_DOUBLE(item, value, NULL);
+      reflection->AddDouble(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: {
+      GOOGLE_CHECK_GET_BOOL(item, value, NULL);
+      reflection->AddBool(message, field_descriptor, value);
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {
+      if (!CheckAndSetString(
+          item, message, field_descriptor, reflection, true, -1)) {
+        return NULL;
+      }
+      break;
+    }
+    case google::protobuf::FieldDescriptor::CPPTYPE_ENUM: {
+      GOOGLE_CHECK_GET_INT32(item, value, NULL);
+      const google::protobuf::EnumDescriptor* enum_descriptor =
+          field_descriptor->enum_type();
+      const google::protobuf::EnumValueDescriptor* enum_value =
+          enum_descriptor->FindValueByNumber(value);
+      if (enum_value != NULL) {
+        reflection->AddEnum(message, field_descriptor, enum_value);
+      } else {
+        ScopedPyObjectPtr s(PyObject_Str(item));
+        if (s != NULL) {
+          PyErr_Format(PyExc_ValueError, "Unknown enum value: %s",
+                       PyString_AsString(s.get()));
+        }
+        return NULL;
+      }
+      break;
+    }
+    default:
+      PyErr_Format(
+          PyExc_SystemError, "Adding value to a field of unknown type %d",
+          field_descriptor->cpp_type());
+      return NULL;
+  }
+
+  Py_RETURN_NONE;
+}
+
+static int AssSubscript(RepeatedScalarContainer* self,
+                        PyObject* slice,
+                        PyObject* value) {
+  Py_ssize_t from;
+  Py_ssize_t to;
+  Py_ssize_t step;
+  Py_ssize_t length;
+  Py_ssize_t slicelength;
+  bool create_list = false;
+
+  cmessage::AssureWritable(self->parent);
+  google::protobuf::Message* message = self->message;
+  const google::protobuf::FieldDescriptor* field_descriptor =
+      self->parent_field->descriptor;
+
+#if PY_MAJOR_VERSION < 3
+  if (PyInt_Check(slice)) {
+    from = to = PyInt_AsLong(slice);
+  } else
+#endif
+  if (PyLong_Check(slice)) {
+    from = to = PyLong_AsLong(slice);
+  } else if (PySlice_Check(slice)) {
+    const google::protobuf::Reflection* reflection = message->GetReflection();
+    length = reflection->FieldSize(*message, field_descriptor);
+#if PY_MAJOR_VERSION >= 3
+    if (PySlice_GetIndicesEx(slice,
+#else
+    if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(slice),
+#endif
+                             length, &from, &to, &step, &slicelength) == -1) {
+      return -1;
+    }
+    create_list = true;
+  } else {
+    PyErr_SetString(PyExc_TypeError, "list indices must be integers");
+    return -1;
+  }
+
+  if (value == NULL) {
+    return cmessage::InternalDeleteRepeatedField(
+        message, field_descriptor, slice, NULL);
+  }
+
+  if (!create_list) {
+    return AssignItem(self, from, value);
+  }
+
+  ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+  if (full_slice == NULL) {
+    return -1;
+  }
+  ScopedPyObjectPtr new_list(Subscript(self, full_slice));
+  if (new_list == NULL) {
+    return -1;
+  }
+  if (PySequence_SetSlice(new_list, from, to, value) < 0) {
+    return -1;
+  }
+
+  return InternalAssignRepeatedField(self, new_list);
+}
+
+PyObject* Extend(RepeatedScalarContainer* self, PyObject* value) {
+  cmessage::AssureWritable(self->parent);
+  if (PyObject_Not(value)) {
+    Py_RETURN_NONE;
+  }
+  ScopedPyObjectPtr iter(PyObject_GetIter(value));
+  if (iter == NULL) {
+    PyErr_SetString(PyExc_TypeError, "Value must be iterable");
+    return NULL;
+  }
+  ScopedPyObjectPtr next;
+  while ((next.reset(PyIter_Next(iter))) != NULL) {
+    if (Append(self, next) == NULL) {
+      return NULL;
+    }
+  }
+  if (PyErr_Occurred()) {
+    return NULL;
+  }
+  Py_RETURN_NONE;
+}
+
+static PyObject* Insert(RepeatedScalarContainer* self, PyObject* args) {
+  Py_ssize_t index;
+  PyObject* value;
+  if (!PyArg_ParseTuple(args, "lO", &index, &value)) {
+    return NULL;
+  }
+  ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+  ScopedPyObjectPtr new_list(Subscript(self, full_slice));
+  if (PyList_Insert(new_list, index, value) < 0) {
+    return NULL;
+  }
+  int ret = InternalAssignRepeatedField(self, new_list);
+  if (ret < 0) {
+    return NULL;
+  }
+  Py_RETURN_NONE;
+}
+
+static PyObject* Remove(RepeatedScalarContainer* self, PyObject* value) {
+  Py_ssize_t match_index = -1;
+  for (Py_ssize_t i = 0; i < Len(self); ++i) {
+    ScopedPyObjectPtr elem(Item(self, i));
+    if (PyObject_RichCompareBool(elem, value, Py_EQ)) {
+      match_index = i;
+      break;
+    }
+  }
+  if (match_index == -1) {
+    PyErr_SetString(PyExc_ValueError, "remove(x): x not in container");
+    return NULL;
+  }
+  if (AssignItem(self, match_index, NULL) < 0) {
+    return NULL;
+  }
+  Py_RETURN_NONE;
+}
+
+static PyObject* RichCompare(RepeatedScalarContainer* self,
+                             PyObject* other,
+                             int opid) {
+  if (opid != Py_EQ && opid != Py_NE) {
+    Py_INCREF(Py_NotImplemented);
+    return Py_NotImplemented;
+  }
+
+  // Copy the contents of this repeated scalar container, and other if it is
+  // also a repeated scalar container, into Python lists so we can delegate
+  // to the list's compare method.
+
+  ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+  if (full_slice == NULL) {
+    return NULL;
+  }
+
+  ScopedPyObjectPtr other_list_deleter;
+  if (PyObject_TypeCheck(other, &RepeatedScalarContainer_Type)) {
+    other_list_deleter.reset(Subscript(
+        reinterpret_cast<RepeatedScalarContainer*>(other), full_slice));
+    other = other_list_deleter.get();
+  }
+
+  ScopedPyObjectPtr list(Subscript(self, full_slice));
+  if (list == NULL) {
+    return NULL;
+  }
+  return PyObject_RichCompare(list, other, opid);
+}
+
+PyObject* Reduce(RepeatedScalarContainer* unused_self) {
+  PyErr_Format(
+      PickleError_class,
+      "can't pickle repeated message fields, convert to list first");
+  return NULL;
+}
+
+static PyObject* Sort(RepeatedScalarContainer* self,
+                      PyObject* args,
+                      PyObject* kwds) {
+  // Support the old sort_function argument for backwards
+  // compatibility.
+  if (kwds != NULL) {
+    PyObject* sort_func = PyDict_GetItemString(kwds, "sort_function");
+    if (sort_func != NULL) {
+      // Must set before deleting as sort_func is a borrowed reference
+      // and kwds might be the only thing keeping it alive.
+      if (PyDict_SetItemString(kwds, "cmp", sort_func) == -1)
+        return NULL;
+      if (PyDict_DelItemString(kwds, "sort_function") == -1)
+        return NULL;
+    }
+  }
+
+  ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+  if (full_slice == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr list(Subscript(self, full_slice));
+  if (list == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr m(PyObject_GetAttrString(list, "sort"));
+  if (m == NULL) {
+    return NULL;
+  }
+  ScopedPyObjectPtr res(PyObject_Call(m, args, kwds));
+  if (res == NULL) {
+    return NULL;
+  }
+  int ret = InternalAssignRepeatedField(self, list);
+  if (ret < 0) {
+    return NULL;
+  }
+  Py_RETURN_NONE;
+}
+
+static int Init(RepeatedScalarContainer* self,
+                PyObject* args,
+                PyObject* kwargs) {
+  PyObject* py_parent;
+  PyObject* py_parent_field;
+  if (!PyArg_UnpackTuple(args, "__init__()", 2, 2, &py_parent,
+                         &py_parent_field)) {
+    return -1;
+  }
+
+  if (!PyObject_TypeCheck(py_parent, &CMessage_Type)) {
+    PyErr_Format(PyExc_TypeError,
+                 "expect %s, but got %s",
+                 CMessage_Type.tp_name,
+                 Py_TYPE(py_parent)->tp_name);
+    return -1;
+  }
+
+  if (!PyObject_TypeCheck(py_parent_field, &CFieldDescriptor_Type)) {
+    PyErr_Format(PyExc_TypeError,
+                 "expect %s, but got %s",
+                 CFieldDescriptor_Type.tp_name,
+                 Py_TYPE(py_parent_field)->tp_name);
+    return -1;
+  }
+
+  CMessage* cmessage = reinterpret_cast<CMessage*>(py_parent);
+  CFieldDescriptor* cdescriptor = reinterpret_cast<CFieldDescriptor*>(
+      py_parent_field);
+
+  if (!FIELD_BELONGS_TO_MESSAGE(cdescriptor->descriptor, cmessage->message)) {
+    PyErr_SetString(
+        PyExc_KeyError, "Field does not belong to message!");
+    return -1;
+  }
+
+  self->message = cmessage->message;
+  self->parent = cmessage;
+  self->parent_field = cdescriptor;
+  self->owner = cmessage->owner;
+  return 0;
+}
+
+// Initializes the underlying Message object of "to" so it becomes a new parent
+// repeated scalar, and copies all the values from "from" to it. A child scalar
+// container can be released by passing it as both from and to (e.g. making it
+// the recipient of the new parent message and copying the values from itself).
+static int InitializeAndCopyToParentContainer(
+    RepeatedScalarContainer* from,
+    RepeatedScalarContainer* to) {
+  ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
+  if (full_slice == NULL) {
+    return -1;
+  }
+  ScopedPyObjectPtr values(Subscript(from, full_slice));
+  if (values == NULL) {
+    return -1;
+  }
+  google::protobuf::Message* new_message = global_message_factory->GetPrototype(
+      from->message->GetDescriptor())->New();
+  to->parent = NULL;
+  // TODO(anuraag): Document why it's OK to hang on to parent_field,
+  //     even though it's a weak reference. It ought to be enough to
+  //     hold on to the FieldDescriptor only.
+  to->parent_field = from->parent_field;
+  to->message = new_message;
+  to->owner.reset(new_message);
+  if (InternalAssignRepeatedField(to, values) < 0) {
+    return -1;
+  }
+  return 0;
+}
+
+int Release(RepeatedScalarContainer* self) {
+  return InitializeAndCopyToParentContainer(self, self);
+}
+
+PyObject* DeepCopy(RepeatedScalarContainer* self, PyObject* arg) {
+  ScopedPyObjectPtr init_args(
+      PyTuple_Pack(2, self->parent, self->parent_field));
+  PyObject* clone = PyObject_CallObject(
+      reinterpret_cast<PyObject*>(&RepeatedScalarContainer_Type), init_args);
+  if (clone == NULL) {
+    return NULL;
+  }
+  if (!PyObject_TypeCheck(clone, &RepeatedScalarContainer_Type)) {
+    Py_DECREF(clone);
+    return NULL;
+  }
+  if (InitializeAndCopyToParentContainer(
+          self, reinterpret_cast<RepeatedScalarContainer*>(clone)) < 0) {
+    Py_DECREF(clone);
+    return NULL;
+  }
+  return clone;
+}
+
+static void Dealloc(RepeatedScalarContainer* self) {
+  self->owner.reset();
+  Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self));
+}
+
+void SetOwner(RepeatedScalarContainer* self,
+              const shared_ptr<Message>& new_owner) {
+  self->owner = new_owner;
+}
+
+static PySequenceMethods SqMethods = {
+  (lenfunc)Len,           /* sq_length */
+  0, /* sq_concat */
+  0, /* sq_repeat */
+  (ssizeargfunc)Item, /* sq_item */
+  0, /* sq_slice */
+  (ssizeobjargproc)AssignItem /* sq_ass_item */
+};
+
+static PyMappingMethods MpMethods = {
+  (lenfunc)Len,               /* mp_length */
+  (binaryfunc)Subscript,      /* mp_subscript */
+  (objobjargproc)AssSubscript, /* mp_ass_subscript */
+};
+
+static PyMethodDef Methods[] = {
+  { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
+    "Makes a deep copy of the class." },
+  { "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
+    "Outputs picklable representation of the repeated field." },
+  { "append", (PyCFunction)Append, METH_O,
+    "Appends an object to the repeated container." },
+  { "extend", (PyCFunction)Extend, METH_O,
+    "Appends objects to the repeated container." },
+  { "insert", (PyCFunction)Insert, METH_VARARGS,
+    "Appends objects to the repeated container." },
+  { "remove", (PyCFunction)Remove, METH_O,
+    "Removes an object from the repeated container." },
+  { "sort", (PyCFunction)Sort, METH_VARARGS | METH_KEYWORDS,
+    "Sorts the repeated container."},
+  { NULL, NULL }
+};
+
+}  // namespace repeated_scalar_container
+
+PyTypeObject RepeatedScalarContainer_Type = {
+  PyVarObject_HEAD_INIT(&PyType_Type, 0)
+  "google.protobuf.internal."
+  "cpp._message.RepeatedScalarContainer",  // tp_name
+  sizeof(RepeatedScalarContainer),     // tp_basicsize
+  0,                                   //  tp_itemsize
+  (destructor)repeated_scalar_container::Dealloc,  //  tp_dealloc
+  0,                                   //  tp_print
+  0,                                   //  tp_getattr
+  0,                                   //  tp_setattr
+  0,                                   //  tp_compare
+  0,                                   //  tp_repr
+  0,                                   //  tp_as_number
+  &repeated_scalar_container::SqMethods,   //  tp_as_sequence
+  &repeated_scalar_container::MpMethods,   //  tp_as_mapping
+  0,                                   //  tp_hash
+  0,                                   //  tp_call
+  0,                                   //  tp_str
+  0,                                   //  tp_getattro
+  0,                                   //  tp_setattro
+  0,                                   //  tp_as_buffer
+  Py_TPFLAGS_DEFAULT,                  //  tp_flags
+  "A Repeated scalar container",       //  tp_doc
+  0,                                   //  tp_traverse
+  0,                                   //  tp_clear
+  (richcmpfunc)repeated_scalar_container::RichCompare,  //  tp_richcompare
+  0,                                   //  tp_weaklistoffset
+  0,                                   //  tp_iter
+  0,                                   //  tp_iternext
+  repeated_scalar_container::Methods,      //  tp_methods
+  0,                                   //  tp_members
+  0,                                   //  tp_getset
+  0,                                   //  tp_base
+  0,                                   //  tp_dict
+  0,                                   //  tp_descr_get
+  0,                                   //  tp_descr_set
+  0,                                   //  tp_dictoffset
+  (initproc)repeated_scalar_container::Init,  //  tp_init
+};
+
+}  // namespace python
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/python/google/protobuf/pyext/repeated_scalar_container.h b/protobuf/python/google/protobuf/pyext/repeated_scalar_container.h
new file mode 100644
index 0000000..69d15d5
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/repeated_scalar_container.h
@@ -0,0 +1,112 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: anuraag@google.com (Anuraag Agrawal)
+// Author: tibell@google.com (Johan Tibell)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__
+
+#include <Python.h>
+
+#include <memory>
+#ifndef _SHARED_PTR_H
+#include <google/protobuf/stubs/shared_ptr.h>
+#endif
+
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+using internal::shared_ptr;
+
+namespace python {
+
+struct CFieldDescriptor;
+struct CMessage;
+
+typedef struct RepeatedScalarContainer {
+  PyObject_HEAD;
+
+  // This is the top-level C++ Message object that owns the whole
+  // proto tree.  Every Python RepeatedScalarContainer holds a
+  // reference to it in order to keep it alive as long as there's a
+  // Python object that references any part of the tree.
+  shared_ptr<Message> owner;
+
+  // Pointer to the C++ Message that contains this container.  The
+  // RepeatedScalarContainer does not own this pointer.
+  Message* message;
+
+  // Weak reference to a parent CMessage object (i.e. may be NULL.)
+  //
+  // Used to make sure all ancestors are also mutable when first
+  // modifying the container.
+  CMessage* parent;
+
+  // Weak reference to the parent's descriptor that describes this
+  // field.  Used together with the parent's message when making a
+  // default message instance mutable.
+  CFieldDescriptor* parent_field;
+} RepeatedScalarContainer;
+
+extern PyTypeObject RepeatedScalarContainer_Type;
+
+namespace repeated_scalar_container {
+
+// Appends the scalar 'item' to the end of the container 'self'.
+//
+// Returns None if successful; returns NULL and sets an exception if
+// unsuccessful.
+PyObject* Append(RepeatedScalarContainer* self, PyObject* item);
+
+// Releases the messages in the container to a new message.
+//
+// Returns 0 on success, -1 on failure.
+int Release(RepeatedScalarContainer* self);
+
+// Appends all the elements in the input iterator to the container.
+//
+// Returns None if successful; returns NULL and sets an exception if
+// unsuccessful.
+PyObject* Extend(RepeatedScalarContainer* self, PyObject* value);
+
+// Set the owner field of self and any children of self.
+void SetOwner(RepeatedScalarContainer* self,
+              const shared_ptr<Message>& new_owner);
+
+}  // namespace repeated_scalar_container
+}  // namespace python
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_PYTHON_CPP_REPEATED_SCALAR_CONTAINER_H__
diff --git a/protobuf/python/google/protobuf/pyext/scoped_pyobject_ptr.h b/protobuf/python/google/protobuf/pyext/scoped_pyobject_ptr.h
new file mode 100644
index 0000000..9f337c3
--- /dev/null
+++ b/protobuf/python/google/protobuf/pyext/scoped_pyobject_ptr.h
@@ -0,0 +1,95 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: tibell@google.com (Johan Tibell)
+
+#ifndef GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__
+#define GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__
+
+#include <Python.h>
+
+namespace google {
+class ScopedPyObjectPtr {
+ public:
+  // Constructor.  Defaults to intializing with NULL.
+  // There is no way to create an uninitialized ScopedPyObjectPtr.
+  explicit ScopedPyObjectPtr(PyObject* p = NULL) : ptr_(p) { }
+
+  // Destructor.  If there is a PyObject object, delete it.
+  ~ScopedPyObjectPtr() {
+    Py_XDECREF(ptr_);
+  }
+
+  // Reset.  Deletes the current owned object, if any.
+  // Then takes ownership of a new object, if given.
+  // this->reset(this->get()) works.
+  PyObject* reset(PyObject* p = NULL) {
+    if (p != ptr_) {
+      Py_XDECREF(ptr_);
+      ptr_ = p;
+    }
+    return ptr_;
+  }
+
+  // Releases ownership of the object.
+  PyObject* release() {
+    PyObject* p = ptr_;
+    ptr_ = NULL;
+    return p;
+  }
+
+  operator PyObject*() { return ptr_; }
+
+  PyObject* operator->() const  {
+    assert(ptr_ != NULL);
+    return ptr_;
+  }
+
+  PyObject* get() const { return ptr_; }
+
+  Py_ssize_t refcnt() const { return Py_REFCNT(ptr_); }
+
+  void inc() const { Py_INCREF(ptr_); }
+
+  // Comparison operators.
+  // These return whether a ScopedPyObjectPtr and a raw pointer
+  // refer to the same object, not just to two different but equal
+  // objects.
+  bool operator==(const PyObject* p) const { return ptr_ == p; }
+  bool operator!=(const PyObject* p) const { return ptr_ != p; }
+
+ private:
+  PyObject* ptr_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedPyObjectPtr);
+};
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__
diff --git a/protobuf/python/google/protobuf/reflection.py b/protobuf/python/google/protobuf/reflection.py
new file mode 100755
index 0000000..1fc704a
--- /dev/null
+++ b/protobuf/python/google/protobuf/reflection.py
@@ -0,0 +1,205 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# This code is meant to work on Python 2.4 and above only.
+
+"""Contains a metaclass and helper functions used to create
+protocol message classes from Descriptor objects at runtime.
+
+Recall that a metaclass is the "type" of a class.
+(A class is to a metaclass what an instance is to a class.)
+
+In this case, we use the GeneratedProtocolMessageType metaclass
+to inject all the useful functionality into the classes
+output by the protocol compiler at compile-time.
+
+The upshot of all this is that the real implementation
+details for ALL pure-Python protocol buffers are *here in
+this file*.
+"""
+
+__author__ = 'robinson@google.com (Will Robinson)'
+
+
+from google.protobuf.internal import api_implementation
+from google.protobuf import descriptor as descriptor_mod
+from google.protobuf import message
+
+_FieldDescriptor = descriptor_mod.FieldDescriptor
+
+
+if api_implementation.Type() == 'cpp':
+  if api_implementation.Version() == 2:
+    from google.protobuf.pyext import cpp_message
+    _NewMessage = cpp_message.NewMessage
+    _InitMessage = cpp_message.InitMessage
+  else:
+    from google.protobuf.internal import cpp_message
+    _NewMessage = cpp_message.NewMessage
+    _InitMessage = cpp_message.InitMessage
+else:
+  from google.protobuf.internal import python_message
+  _NewMessage = python_message.NewMessage
+  _InitMessage = python_message.InitMessage
+
+
+class GeneratedProtocolMessageType(type):
+
+  """Metaclass for protocol message classes created at runtime from Descriptors.
+
+  We add implementations for all methods described in the Message class.  We
+  also create properties to allow getting/setting all fields in the protocol
+  message.  Finally, we create slots to prevent users from accidentally
+  "setting" nonexistent fields in the protocol message, which then wouldn't get
+  serialized / deserialized properly.
+
+  The protocol compiler currently uses this metaclass to create protocol
+  message classes at runtime.  Clients can also manually create their own
+  classes at runtime, as in this example:
+
+  mydescriptor = Descriptor(.....)
+  class MyProtoClass(Message):
+    __metaclass__ = GeneratedProtocolMessageType
+    DESCRIPTOR = mydescriptor
+  myproto_instance = MyProtoClass()
+  myproto.foo_field = 23
+  ...
+
+  The above example will not work for nested types. If you wish to include them,
+  use reflection.MakeClass() instead of manually instantiating the class in
+  order to create the appropriate class structure.
+  """
+
+  # Must be consistent with the protocol-compiler code in
+  # proto2/compiler/internal/generator.*.
+  _DESCRIPTOR_KEY = 'DESCRIPTOR'
+
+  def __new__(cls, name, bases, dictionary):
+    """Custom allocation for runtime-generated class types.
+
+    We override __new__ because this is apparently the only place
+    where we can meaningfully set __slots__ on the class we're creating(?).
+    (The interplay between metaclasses and slots is not very well-documented).
+
+    Args:
+      name: Name of the class (ignored, but required by the
+        metaclass protocol).
+      bases: Base classes of the class we're constructing.
+        (Should be message.Message).  We ignore this field, but
+        it's required by the metaclass protocol
+      dictionary: The class dictionary of the class we're
+        constructing.  dictionary[_DESCRIPTOR_KEY] must contain
+        a Descriptor object describing this protocol message
+        type.
+
+    Returns:
+      Newly-allocated class.
+    """
+    descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
+    bases = _NewMessage(bases, descriptor, dictionary)
+    superclass = super(GeneratedProtocolMessageType, cls)
+
+    new_class = superclass.__new__(cls, name, bases, dictionary)
+    setattr(descriptor, '_concrete_class', new_class)
+    return new_class
+
+  def __init__(cls, name, bases, dictionary):
+    """Here we perform the majority of our work on the class.
+    We add enum getters, an __init__ method, implementations
+    of all Message methods, and properties for all fields
+    in the protocol type.
+
+    Args:
+      name: Name of the class (ignored, but required by the
+        metaclass protocol).
+      bases: Base classes of the class we're constructing.
+        (Should be message.Message).  We ignore this field, but
+        it's required by the metaclass protocol
+      dictionary: The class dictionary of the class we're
+        constructing.  dictionary[_DESCRIPTOR_KEY] must contain
+        a Descriptor object describing this protocol message
+        type.
+    """
+    descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY]
+    _InitMessage(descriptor, cls)
+    superclass = super(GeneratedProtocolMessageType, cls)
+    superclass.__init__(name, bases, dictionary)
+
+
+def ParseMessage(descriptor, byte_str):
+  """Generate a new Message instance from this Descriptor and a byte string.
+
+  Args:
+    descriptor: Protobuf Descriptor object
+    byte_str: Serialized protocol buffer byte string
+
+  Returns:
+    Newly created protobuf Message object.
+  """
+  result_class = MakeClass(descriptor)
+  new_msg = result_class()
+  new_msg.ParseFromString(byte_str)
+  return new_msg
+
+
+def MakeClass(descriptor):
+  """Construct a class object for a protobuf described by descriptor.
+
+  Composite descriptors are handled by defining the new class as a member of the
+  parent class, recursing as deep as necessary.
+  This is the dynamic equivalent to:
+
+  class Parent(message.Message):
+    __metaclass__ = GeneratedProtocolMessageType
+    DESCRIPTOR = descriptor
+    class Child(message.Message):
+      __metaclass__ = GeneratedProtocolMessageType
+      DESCRIPTOR = descriptor.nested_types[0]
+
+  Sample usage:
+    file_descriptor = descriptor_pb2.FileDescriptorProto()
+    file_descriptor.ParseFromString(proto2_string)
+    msg_descriptor = descriptor.MakeDescriptor(file_descriptor.message_type[0])
+    msg_class = reflection.MakeClass(msg_descriptor)
+    msg = msg_class()
+
+  Args:
+    descriptor: A descriptor.Descriptor object describing the protobuf.
+  Returns:
+    The Message class object described by the descriptor.
+  """
+  attributes = {}
+  for name, nested_type in descriptor.nested_types_by_name.items():
+    attributes[name] = MakeClass(nested_type)
+
+  attributes[GeneratedProtocolMessageType._DESCRIPTOR_KEY] = descriptor
+
+  return GeneratedProtocolMessageType(str(descriptor.name), (message.Message,),
+                                      attributes)
diff --git a/protobuf/python/google/protobuf/service.py b/protobuf/python/google/protobuf/service.py
new file mode 100755
index 0000000..9e00de7
--- /dev/null
+++ b/protobuf/python/google/protobuf/service.py
@@ -0,0 +1,226 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""DEPRECATED:  Declares the RPC service interfaces.
+
+This module declares the abstract interfaces underlying proto2 RPC
+services.  These are intended to be independent of any particular RPC
+implementation, so that proto2 services can be used on top of a variety
+of implementations.  Starting with version 2.3.0, RPC implementations should
+not try to build on these, but should instead provide code generator plugins
+which generate code specific to the particular RPC implementation.  This way
+the generated code can be more appropriate for the implementation in use
+and can avoid unnecessary layers of indirection.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+
+class RpcException(Exception):
+  """Exception raised on failed blocking RPC method call."""
+  pass
+
+
+class Service(object):
+
+  """Abstract base interface for protocol-buffer-based RPC services.
+
+  Services themselves are abstract classes (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 the Message interface).
+  """
+
+  def GetDescriptor():
+    """Retrieves this service's descriptor."""
+    raise NotImplementedError
+
+  def CallMethod(self, method_descriptor, rpc_controller,
+                 request, done):
+    """Calls a method of the service specified by method_descriptor.
+
+    If "done" is None then the call is blocking and the response
+    message will be returned directly.  Otherwise the call is asynchronous
+    and "done" will later be called with the response value.
+
+    In the blocking case, RpcException will be raised on error.
+
+    Preconditions:
+    * method_descriptor.service == GetDescriptor
+    * request is of the exact same classes as returned by
+      GetRequestClass(method).
+    * After the call has started, the request must not be modified.
+    * "rpc_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.
+
+    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 failed, the response value passed to "done" will be None.
+      Further details about the failure can be found by querying the
+      RpcController.
+    """
+    raise NotImplementedError
+
+  def GetRequestClass(self, method_descriptor):
+    """Returns the class of the request message for the specified method.
+
+    CallMethod() requires that the request is of a particular subclass of
+    Message. GetRequestClass() gets the default instance of this required
+    type.
+
+    Example:
+      method = service.GetDescriptor().FindMethodByName("Foo")
+      request = stub.GetRequestClass(method)()
+      request.ParseFromString(input)
+      service.CallMethod(method, request, callback)
+    """
+    raise NotImplementedError
+
+  def GetResponseClass(self, method_descriptor):
+    """Returns the class of the response message for the specified method.
+
+    This method isn't really needed, as the RpcChannel's CallMethod constructs
+    the response protocol message. It's provided anyway in case it is useful
+    for the caller to know the response type in advance.
+    """
+    raise NotImplementedError
+
+
+class RpcController(object):
+
+  """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).
+  """
+
+  # Client-side methods below
+
+  def Reset(self):
+    """Resets the RpcController to its initial state.
+
+    After the RpcController has been reset, it may be reused in
+    a new call. Must not be called while an RPC is in progress.
+    """
+    raise NotImplementedError
+
+  def Failed(self):
+    """Returns true if the call failed.
+
+    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.
+    """
+    raise NotImplementedError
+
+  def ErrorText(self):
+    """If Failed is true, returns a human-readable description of the error."""
+    raise NotImplementedError
+
+  def StartCancel(self):
+    """Initiate cancellation.
+
+    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.
+    """
+    raise NotImplementedError
+
+  # Server-side methods below
+
+  def SetFailed(self, reason):
+    """Sets a failure reason.
+
+    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().
+    """
+    raise NotImplementedError
+
+  def IsCanceled(self):
+    """Checks if the client cancelled the RPC.
+
+    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.
+    """
+    raise NotImplementedError
+
+  def NotifyOnCancel(self, callback):
+    """Sets a callback to invoke on cancel.
+
+    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.
+    """
+    raise NotImplementedError
+
+
+class RpcChannel(object):
+
+  """Abstract interface for an RPC channel.
+
+  An RpcChannel represents a communication line to a service which can be used
+  to call that service's methods.  The service may be running on another
+  machine. Normally, you should not use an RpcChannel directly, but instead
+  construct a stub {@link Service} wrapping it.  Example:
+
+  Example:
+    RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234")
+    RpcController controller = rpcImpl.Controller()
+    MyService service = MyService_Stub(channel)
+    service.MyMethod(controller, request, callback)
+  """
+
+  def CallMethod(self, method_descriptor, rpc_controller,
+                 request, response_class, done):
+    """Calls the method identified by the descriptor.
+
+    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 object doesn't have to
+    be of any specific class as long as its descriptor is method.input_type.
+    """
+    raise NotImplementedError
diff --git a/protobuf/python/google/protobuf/service_reflection.py b/protobuf/python/google/protobuf/service_reflection.py
new file mode 100755
index 0000000..1c3636a
--- /dev/null
+++ b/protobuf/python/google/protobuf/service_reflection.py
@@ -0,0 +1,284 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Contains metaclasses used to create protocol service and service stub
+classes from ServiceDescriptor objects at runtime.
+
+The GeneratedServiceType and GeneratedServiceStubType metaclasses are used to
+inject all useful functionality into the classes output by the protocol
+compiler at compile-time.
+"""
+
+__author__ = 'petar@google.com (Petar Petrov)'
+
+
+class GeneratedServiceType(type):
+
+  """Metaclass for service classes created at runtime from ServiceDescriptors.
+
+  Implementations for all methods described in the Service class are added here
+  by this class. We also create properties to allow getting/setting all fields
+  in the protocol message.
+
+  The protocol compiler currently uses this metaclass to create protocol service
+  classes at runtime. Clients can also manually create their own classes at
+  runtime, as in this example:
+
+  mydescriptor = ServiceDescriptor(.....)
+  class MyProtoService(service.Service):
+    __metaclass__ = GeneratedServiceType
+    DESCRIPTOR = mydescriptor
+  myservice_instance = MyProtoService()
+  ...
+  """
+
+  _DESCRIPTOR_KEY = 'DESCRIPTOR'
+
+  def __init__(cls, name, bases, dictionary):
+    """Creates a message service class.
+
+    Args:
+      name: Name of the class (ignored, but required by the metaclass
+        protocol).
+      bases: Base classes of the class being constructed.
+      dictionary: The class dictionary of the class being constructed.
+        dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object
+        describing this protocol service type.
+    """
+    # Don't do anything if this class doesn't have a descriptor. This happens
+    # when a service class is subclassed.
+    if GeneratedServiceType._DESCRIPTOR_KEY not in dictionary:
+      return
+    descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY]
+    service_builder = _ServiceBuilder(descriptor)
+    service_builder.BuildService(cls)
+
+
+class GeneratedServiceStubType(GeneratedServiceType):
+
+  """Metaclass for service stubs created at runtime from ServiceDescriptors.
+
+  This class has similar responsibilities as GeneratedServiceType, except that
+  it creates the service stub classes.
+  """
+
+  _DESCRIPTOR_KEY = 'DESCRIPTOR'
+
+  def __init__(cls, name, bases, dictionary):
+    """Creates a message service stub class.
+
+    Args:
+      name: Name of the class (ignored, here).
+      bases: Base classes of the class being constructed.
+      dictionary: The class dictionary of the class being constructed.
+        dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object
+        describing this protocol service type.
+    """
+    super(GeneratedServiceStubType, cls).__init__(name, bases, dictionary)
+    # Don't do anything if this class doesn't have a descriptor. This happens
+    # when a service stub is subclassed.
+    if GeneratedServiceStubType._DESCRIPTOR_KEY not in dictionary:
+      return
+    descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY]
+    service_stub_builder = _ServiceStubBuilder(descriptor)
+    service_stub_builder.BuildServiceStub(cls)
+
+
+class _ServiceBuilder(object):
+
+  """This class constructs a protocol service class using a service descriptor.
+
+  Given a service descriptor, this class constructs a class that represents
+  the specified service descriptor. One service builder instance constructs
+  exactly one service class. That means all instances of that class share the
+  same builder.
+  """
+
+  def __init__(self, service_descriptor):
+    """Initializes an instance of the service class builder.
+
+    Args:
+      service_descriptor: ServiceDescriptor to use when constructing the
+        service class.
+    """
+    self.descriptor = service_descriptor
+
+  def BuildService(self, cls):
+    """Constructs the service class.
+
+    Args:
+      cls: The class that will be constructed.
+    """
+
+    # CallMethod needs to operate with an instance of the Service class. This
+    # internal wrapper function exists only to be able to pass the service
+    # instance to the method that does the real CallMethod work.
+    def _WrapCallMethod(srvc, method_descriptor,
+                        rpc_controller, request, callback):
+      return self._CallMethod(srvc, method_descriptor,
+                       rpc_controller, request, callback)
+    self.cls = cls
+    cls.CallMethod = _WrapCallMethod
+    cls.GetDescriptor = staticmethod(lambda: self.descriptor)
+    cls.GetDescriptor.__doc__ = "Returns the service descriptor."
+    cls.GetRequestClass = self._GetRequestClass
+    cls.GetResponseClass = self._GetResponseClass
+    for method in self.descriptor.methods:
+      setattr(cls, method.name, self._GenerateNonImplementedMethod(method))
+
+  def _CallMethod(self, srvc, method_descriptor,
+                  rpc_controller, request, callback):
+    """Calls the method described by a given method descriptor.
+
+    Args:
+      srvc: Instance of the service for which this method is called.
+      method_descriptor: Descriptor that represent the method to call.
+      rpc_controller: RPC controller to use for this method's execution.
+      request: Request protocol message.
+      callback: A callback to invoke after the method has completed.
+    """
+    if method_descriptor.containing_service != self.descriptor:
+      raise RuntimeError(
+          'CallMethod() given method descriptor for wrong service type.')
+    method = getattr(srvc, method_descriptor.name)
+    return method(rpc_controller, request, callback)
+
+  def _GetRequestClass(self, method_descriptor):
+    """Returns the class of the request protocol message.
+
+    Args:
+      method_descriptor: Descriptor of the method for which to return the
+        request protocol message class.
+
+    Returns:
+      A class that represents the input protocol message of the specified
+      method.
+    """
+    if method_descriptor.containing_service != self.descriptor:
+      raise RuntimeError(
+          'GetRequestClass() given method descriptor for wrong service type.')
+    return method_descriptor.input_type._concrete_class
+
+  def _GetResponseClass(self, method_descriptor):
+    """Returns the class of the response protocol message.
+
+    Args:
+      method_descriptor: Descriptor of the method for which to return the
+        response protocol message class.
+
+    Returns:
+      A class that represents the output protocol message of the specified
+      method.
+    """
+    if method_descriptor.containing_service != self.descriptor:
+      raise RuntimeError(
+          'GetResponseClass() given method descriptor for wrong service type.')
+    return method_descriptor.output_type._concrete_class
+
+  def _GenerateNonImplementedMethod(self, method):
+    """Generates and returns a method that can be set for a service methods.
+
+    Args:
+      method: Descriptor of the service method for which a method is to be
+        generated.
+
+    Returns:
+      A method that can be added to the service class.
+    """
+    return lambda inst, rpc_controller, request, callback: (
+        self._NonImplementedMethod(method.name, rpc_controller, callback))
+
+  def _NonImplementedMethod(self, method_name, rpc_controller, callback):
+    """The body of all methods in the generated service class.
+
+    Args:
+      method_name: Name of the method being executed.
+      rpc_controller: RPC controller used to execute this method.
+      callback: A callback which will be invoked when the method finishes.
+    """
+    rpc_controller.SetFailed('Method %s not implemented.' % method_name)
+    callback(None)
+
+
+class _ServiceStubBuilder(object):
+
+  """Constructs a protocol service stub class using a service descriptor.
+
+  Given a service descriptor, this class constructs a suitable stub class.
+  A stub is just a type-safe wrapper around an RpcChannel which emulates a
+  local implementation of the service.
+
+  One service stub builder instance constructs exactly one class. It means all
+  instances of that class share the same service stub builder.
+  """
+
+  def __init__(self, service_descriptor):
+    """Initializes an instance of the service stub class builder.
+
+    Args:
+      service_descriptor: ServiceDescriptor to use when constructing the
+        stub class.
+    """
+    self.descriptor = service_descriptor
+
+  def BuildServiceStub(self, cls):
+    """Constructs the stub class.
+
+    Args:
+      cls: The class that will be constructed.
+    """
+
+    def _ServiceStubInit(stub, rpc_channel):
+      stub.rpc_channel = rpc_channel
+    self.cls = cls
+    cls.__init__ = _ServiceStubInit
+    for method in self.descriptor.methods:
+      setattr(cls, method.name, self._GenerateStubMethod(method))
+
+  def _GenerateStubMethod(self, method):
+    return (lambda inst, rpc_controller, request, callback=None:
+        self._StubMethod(inst, method, rpc_controller, request, callback))
+
+  def _StubMethod(self, stub, method_descriptor,
+                  rpc_controller, request, callback):
+    """The body of all service methods in the generated stub class.
+
+    Args:
+      stub: Stub instance.
+      method_descriptor: Descriptor of the invoked method.
+      rpc_controller: Rpc controller to execute the method.
+      request: Request protocol message.
+      callback: A callback to execute when the method finishes.
+    Returns:
+      Response message (in case of blocking call).
+    """
+    return stub.rpc_channel.CallMethod(
+        method_descriptor, rpc_controller, request,
+        method_descriptor.output_type._concrete_class, callback)
diff --git a/protobuf/python/google/protobuf/symbol_database.py b/protobuf/python/google/protobuf/symbol_database.py
new file mode 100644
index 0000000..4c70b39
--- /dev/null
+++ b/protobuf/python/google/protobuf/symbol_database.py
@@ -0,0 +1,185 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""A database of Python protocol buffer generated symbols.
+
+SymbolDatabase makes it easy to create new instances of a registered type, given
+only the type's protocol buffer symbol name. Once all symbols are registered,
+they can be accessed using either the MessageFactory interface which
+SymbolDatabase exposes, or the DescriptorPool interface of the underlying
+pool.
+
+Example usage:
+
+  db = symbol_database.SymbolDatabase()
+
+  # Register symbols of interest, from one or multiple files.
+  db.RegisterFileDescriptor(my_proto_pb2.DESCRIPTOR)
+  db.RegisterMessage(my_proto_pb2.MyMessage)
+  db.RegisterEnumDescriptor(my_proto_pb2.MyEnum.DESCRIPTOR)
+
+  # The database can be used as a MessageFactory, to generate types based on
+  # their name:
+  types = db.GetMessages(['my_proto.proto'])
+  my_message_instance = types['MyMessage']()
+
+  # The database's underlying descriptor pool can be queried, so it's not
+  # necessary to know a type's filename to be able to generate it:
+  filename = db.pool.FindFileContainingSymbol('MyMessage')
+  my_message_instance = db.GetMessages([filename])['MyMessage']()
+
+  # This functionality is also provided directly via a convenience method:
+  my_message_instance = db.GetSymbol('MyMessage')()
+"""
+
+
+from google.protobuf import descriptor_pool
+
+
+class SymbolDatabase(object):
+  """A database of Python generated symbols.
+
+  SymbolDatabase also models message_factory.MessageFactory.
+
+  The symbol database can be used to keep a global registry of all protocol
+  buffer types used within a program.
+  """
+
+  def __init__(self):
+    """Constructor."""
+
+    self._symbols = {}
+    self._symbols_by_file = {}
+    self.pool = descriptor_pool.DescriptorPool()
+
+  def RegisterMessage(self, message):
+    """Registers the given message type in the local database.
+
+    Args:
+      message: a message.Message, to be registered.
+
+    Returns:
+      The provided message.
+    """
+
+    desc = message.DESCRIPTOR
+    self._symbols[desc.full_name] = message
+    if desc.file.name not in self._symbols_by_file:
+      self._symbols_by_file[desc.file.name] = {}
+    self._symbols_by_file[desc.file.name][desc.full_name] = message
+    self.pool.AddDescriptor(desc)
+    return message
+
+  def RegisterEnumDescriptor(self, enum_descriptor):
+    """Registers the given enum descriptor in the local database.
+
+    Args:
+      enum_descriptor: a descriptor.EnumDescriptor.
+
+    Returns:
+      The provided descriptor.
+    """
+    self.pool.AddEnumDescriptor(enum_descriptor)
+    return enum_descriptor
+
+  def RegisterFileDescriptor(self, file_descriptor):
+    """Registers the given file descriptor in the local database.
+
+    Args:
+      file_descriptor: a descriptor.FileDescriptor.
+
+    Returns:
+      The provided descriptor.
+    """
+    self.pool.AddFileDescriptor(file_descriptor)
+
+  def GetSymbol(self, symbol):
+    """Tries to find a symbol in the local database.
+
+    Currently, this method only returns message.Message instances, however, if
+    may be extended in future to support other symbol types.
+
+    Args:
+      symbol: A str, a protocol buffer symbol.
+
+    Returns:
+      A Python class corresponding to the symbol.
+
+    Raises:
+      KeyError: if the symbol could not be found.
+    """
+
+    return self._symbols[symbol]
+
+  def GetPrototype(self, descriptor):
+    """Builds a proto2 message class based on the passed in descriptor.
+
+    Passing a descriptor with a fully qualified name matching a previous
+    invocation will cause the same class to be returned.
+
+    Args:
+      descriptor: The descriptor to build from.
+
+    Returns:
+      A class describing the passed in descriptor.
+    """
+
+    return self.GetSymbol(descriptor.full_name)
+
+  def GetMessages(self, files):
+    """Gets all the messages from a specified file.
+
+    This will find and resolve dependencies, failing if they are not registered
+    in the symbol database.
+
+
+    Args:
+      files: The file names to extract messages from.
+
+    Returns:
+      A dictionary mapping proto names to the message classes. This will include
+      any dependent messages as well as any messages defined in the same file as
+      a specified message.
+
+    Raises:
+      KeyError: if a file could not be found.
+    """
+
+    result = {}
+    for f in files:
+      result.update(self._symbols_by_file[f])
+    return result
+
+_DEFAULT = SymbolDatabase()
+
+
+def Default():
+  """Returns the default SymbolDatabase."""
+  return _DEFAULT
diff --git a/protobuf/python/google/protobuf/text_encoding.py b/protobuf/python/google/protobuf/text_encoding.py
new file mode 100644
index 0000000..2d86a67
--- /dev/null
+++ b/protobuf/python/google/protobuf/text_encoding.py
@@ -0,0 +1,110 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#PY25 compatible for GAE.
+#
+"""Encoding related utilities."""
+
+import re
+import sys  ##PY25
+
+# Lookup table for utf8
+_cescape_utf8_to_str = [chr(i) for i in xrange(0, 256)]
+_cescape_utf8_to_str[9] = r'\t'  # optional escape
+_cescape_utf8_to_str[10] = r'\n'  # optional escape
+_cescape_utf8_to_str[13] = r'\r'  # optional escape
+_cescape_utf8_to_str[39] = r"\'"  # optional escape
+
+_cescape_utf8_to_str[34] = r'\"'  # necessary escape
+_cescape_utf8_to_str[92] = r'\\'  # necessary escape
+
+# Lookup table for non-utf8, with necessary escapes at (o >= 127 or o < 32)
+_cescape_byte_to_str = ([r'\%03o' % i for i in xrange(0, 32)] +
+                        [chr(i) for i in xrange(32, 127)] +
+                        [r'\%03o' % i for i in xrange(127, 256)])
+_cescape_byte_to_str[9] = r'\t'  # optional escape
+_cescape_byte_to_str[10] = r'\n'  # optional escape
+_cescape_byte_to_str[13] = r'\r'  # optional escape
+_cescape_byte_to_str[39] = r"\'"  # optional escape
+
+_cescape_byte_to_str[34] = r'\"'  # necessary escape
+_cescape_byte_to_str[92] = r'\\'  # necessary escape
+
+
+def CEscape(text, as_utf8):
+  """Escape a bytes string for use in an ascii protocol buffer.
+
+  text.encode('string_escape') does not seem to satisfy our needs as it
+  encodes unprintable characters using two-digit hex escapes whereas our
+  C++ unescaping function allows hex escapes to be any length.  So,
+  "\0011".encode('string_escape') ends up being "\\x011", which will be
+  decoded in C++ as a single-character string with char code 0x11.
+
+  Args:
+    text: A byte string to be escaped
+    as_utf8: Specifies if result should be returned in UTF-8 encoding
+  Returns:
+    Escaped string
+  """
+  # PY3 hack: make Ord work for str and bytes:
+  # //platforms/networking/data uses unicode here, hence basestring.
+  Ord = ord if isinstance(text, basestring) else lambda x: x
+  if as_utf8:
+    return ''.join(_cescape_utf8_to_str[Ord(c)] for c in text)
+  return ''.join(_cescape_byte_to_str[Ord(c)] for c in text)
+
+
+_CUNESCAPE_HEX = re.compile(r'(\\+)x([0-9a-fA-F])(?![0-9a-fA-F])')
+_cescape_highbit_to_str = ([chr(i) for i in range(0, 127)] +
+                           [r'\%03o' % i for i in range(127, 256)])
+
+
+def CUnescape(text):
+  """Unescape a text string with C-style escape sequences to UTF-8 bytes."""
+
+  def ReplaceHex(m):
+    # Only replace the match if the number of leading back slashes is odd. i.e.
+    # the slash itself is not escaped.
+    if len(m.group(1)) & 1:
+      return m.group(1) + 'x0' + m.group(2)
+    return m.group(0)
+
+  # This is required because the 'string_escape' encoding doesn't
+  # allow single-digit hex escapes (like '\xf').
+  result = _CUNESCAPE_HEX.sub(ReplaceHex, text)
+
+  if sys.version_info[0] < 3:  ##PY25
+##!PY25  if str is bytes:  # PY2
+    return result.decode('string_escape')
+  result = ''.join(_cescape_highbit_to_str[ord(c)] for c in result)
+  return (result.encode('ascii')  # Make it bytes to allow decode.
+          .decode('unicode_escape')
+          # Make it bytes again to return the proper type.
+          .encode('raw_unicode_escape'))
diff --git a/protobuf/python/google/protobuf/text_format.py b/protobuf/python/google/protobuf/text_format.py
new file mode 100755
index 0000000..2429fa5
--- /dev/null
+++ b/protobuf/python/google/protobuf/text_format.py
@@ -0,0 +1,873 @@
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#PY25 compatible for GAE.
+#
+# Copyright 2007 Google Inc. All Rights Reserved.
+
+"""Contains routines for printing protocol messages in text format."""
+
+__author__ = 'kenton@google.com (Kenton Varda)'
+
+import cStringIO
+import re
+
+from google.protobuf.internal import type_checkers
+from google.protobuf import descriptor
+from google.protobuf import text_encoding
+
+__all__ = ['MessageToString', 'PrintMessage', 'PrintField',
+           'PrintFieldValue', 'Merge']
+
+
+_INTEGER_CHECKERS = (type_checkers.Uint32ValueChecker(),
+                     type_checkers.Int32ValueChecker(),
+                     type_checkers.Uint64ValueChecker(),
+                     type_checkers.Int64ValueChecker())
+_FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?', re.IGNORECASE)
+_FLOAT_NAN = re.compile('nanf?', re.IGNORECASE)
+_FLOAT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_FLOAT,
+                          descriptor.FieldDescriptor.CPPTYPE_DOUBLE])
+
+
+class Error(Exception):
+  """Top-level module error for text_format."""
+
+
+class ParseError(Error):
+  """Thrown in case of ASCII parsing error."""
+
+
+def MessageToString(message, as_utf8=False, as_one_line=False,
+                    pointy_brackets=False, use_index_order=False,
+                    float_format=None):
+  """Convert protobuf message to text format.
+
+  Floating point values can be formatted compactly with 15 digits of
+  precision (which is the most that IEEE 754 "double" can guarantee)
+  using float_format='.15g'.
+
+  Args:
+    message: The protocol buffers message.
+    as_utf8: Produce text output in UTF8 format.
+    as_one_line: Don't introduce newlines between fields.
+    pointy_brackets: If True, use angle brackets instead of curly braces for
+      nesting.
+    use_index_order: If True, print fields of a proto message using the order
+      defined in source code instead of the field number. By default, use the
+      field number order.
+    float_format: If set, use this to specify floating point number formatting
+      (per the "Format Specification Mini-Language"); otherwise, str() is used.
+
+  Returns:
+    A string of the text formatted protocol buffer message.
+  """
+  out = cStringIO.StringIO()
+  PrintMessage(message, out, as_utf8=as_utf8, as_one_line=as_one_line,
+               pointy_brackets=pointy_brackets,
+               use_index_order=use_index_order,
+               float_format=float_format)
+  result = out.getvalue()
+  out.close()
+  if as_one_line:
+    return result.rstrip()
+  return result
+
+
+def PrintMessage(message, out, indent=0, as_utf8=False, as_one_line=False,
+                 pointy_brackets=False, use_index_order=False,
+                 float_format=None):
+  fields = message.ListFields()
+  if use_index_order:
+    fields.sort(key=lambda x: x[0].index)
+  for field, value in fields:
+    if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+      for element in value:
+        PrintField(field, element, out, indent, as_utf8, as_one_line,
+                   pointy_brackets=pointy_brackets,
+                   float_format=float_format)
+    else:
+      PrintField(field, value, out, indent, as_utf8, as_one_line,
+                 pointy_brackets=pointy_brackets,
+                 float_format=float_format)
+
+
+def PrintField(field, value, out, indent=0, as_utf8=False, as_one_line=False,
+               pointy_brackets=False, float_format=None):
+  """Print a single field name/value pair.  For repeated fields, the value
+  should be a single element."""
+
+  out.write(' ' * indent)
+  if field.is_extension:
+    out.write('[')
+    if (field.containing_type.GetOptions().message_set_wire_format and
+        field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
+        field.message_type == field.extension_scope and
+        field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL):
+      out.write(field.message_type.full_name)
+    else:
+      out.write(field.full_name)
+    out.write(']')
+  elif field.type == descriptor.FieldDescriptor.TYPE_GROUP:
+    # For groups, use the capitalized name.
+    out.write(field.message_type.name)
+  else:
+    out.write(field.name)
+
+  if field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+    # The colon is optional in this case, but our cross-language golden files
+    # don't include it.
+    out.write(': ')
+
+  PrintFieldValue(field, value, out, indent, as_utf8, as_one_line,
+                  pointy_brackets=pointy_brackets,
+                  float_format=float_format)
+  if as_one_line:
+    out.write(' ')
+  else:
+    out.write('\n')
+
+
+def PrintFieldValue(field, value, out, indent=0, as_utf8=False,
+                    as_one_line=False, pointy_brackets=False,
+                    float_format=None):
+  """Print a single field value (not including name).  For repeated fields,
+  the value should be a single element."""
+
+  if pointy_brackets:
+    openb = '<'
+    closeb = '>'
+  else:
+    openb = '{'
+    closeb = '}'
+
+  if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+    if as_one_line:
+      out.write(' %s ' % openb)
+      PrintMessage(value, out, indent, as_utf8, as_one_line,
+                   pointy_brackets=pointy_brackets,
+                   float_format=float_format)
+      out.write(closeb)
+    else:
+      out.write(' %s\n' % openb)
+      PrintMessage(value, out, indent + 2, as_utf8, as_one_line,
+                   pointy_brackets=pointy_brackets,
+                   float_format=float_format)
+      out.write(' ' * indent + closeb)
+  elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM:
+    enum_value = field.enum_type.values_by_number.get(value, None)
+    if enum_value is not None:
+      out.write(enum_value.name)
+    else:
+      out.write(str(value))
+  elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING:
+    out.write('\"')
+    if isinstance(value, unicode):
+      out_value = value.encode('utf-8')
+    else:
+      out_value = value
+    if field.type == descriptor.FieldDescriptor.TYPE_BYTES:
+      # We need to escape non-UTF8 chars in TYPE_BYTES field.
+      out_as_utf8 = False
+    else:
+      out_as_utf8 = as_utf8
+    out.write(text_encoding.CEscape(out_value, out_as_utf8))
+    out.write('\"')
+  elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL:
+    if value:
+      out.write('true')
+    else:
+      out.write('false')
+  elif field.cpp_type in _FLOAT_TYPES and float_format is not None:
+    out.write('{1:{0}}'.format(float_format, value))
+  else:
+    out.write(str(value))
+
+
+def _ParseOrMerge(lines, message, allow_multiple_scalars):
+  """Converts an ASCII representation of a protocol message into a message.
+
+  Args:
+    lines: Lines of a message's ASCII representation.
+    message: A protocol buffer message to merge into.
+    allow_multiple_scalars: Determines if repeated values for a non-repeated
+      field are permitted, e.g., the string "foo: 1 foo: 2" for a
+      required/optional field named "foo".
+
+  Raises:
+    ParseError: On ASCII parsing problems.
+  """
+  tokenizer = _Tokenizer(lines)
+  while not tokenizer.AtEnd():
+    _MergeField(tokenizer, message, allow_multiple_scalars)
+
+
+def Parse(text, message):
+  """Parses an ASCII representation of a protocol message into a message.
+
+  Args:
+    text: Message ASCII representation.
+    message: A protocol buffer message to merge into.
+
+  Returns:
+    The same message passed as argument.
+
+  Raises:
+    ParseError: On ASCII parsing problems.
+  """
+  if not isinstance(text, str): text = text.decode('utf-8')
+  return ParseLines(text.split('\n'), message)
+
+
+def Merge(text, message):
+  """Parses an ASCII representation of a protocol message into a message.
+
+  Like Parse(), but allows repeated values for a non-repeated field, and uses
+  the last one.
+
+  Args:
+    text: Message ASCII representation.
+    message: A protocol buffer message to merge into.
+
+  Returns:
+    The same message passed as argument.
+
+  Raises:
+    ParseError: On ASCII parsing problems.
+  """
+  return MergeLines(text.split('\n'), message)
+
+
+def ParseLines(lines, message):
+  """Parses an ASCII representation of a protocol message into a message.
+
+  Args:
+    lines: An iterable of lines of a message's ASCII representation.
+    message: A protocol buffer message to merge into.
+
+  Returns:
+    The same message passed as argument.
+
+  Raises:
+    ParseError: On ASCII parsing problems.
+  """
+  _ParseOrMerge(lines, message, False)
+  return message
+
+
+def MergeLines(lines, message):
+  """Parses an ASCII representation of a protocol message into a message.
+
+  Args:
+    lines: An iterable of lines of a message's ASCII representation.
+    message: A protocol buffer message to merge into.
+
+  Returns:
+    The same message passed as argument.
+
+  Raises:
+    ParseError: On ASCII parsing problems.
+  """
+  _ParseOrMerge(lines, message, True)
+  return message
+
+
+def _MergeField(tokenizer, message, allow_multiple_scalars):
+  """Merges a single protocol message field into a message.
+
+  Args:
+    tokenizer: A tokenizer to parse the field name and values.
+    message: A protocol message to record the data.
+    allow_multiple_scalars: Determines if repeated values for a non-repeated
+      field are permitted, e.g., the string "foo: 1 foo: 2" for a
+      required/optional field named "foo".
+
+  Raises:
+    ParseError: In case of ASCII parsing problems.
+  """
+  message_descriptor = message.DESCRIPTOR
+  if tokenizer.TryConsume('['):
+    name = [tokenizer.ConsumeIdentifier()]
+    while tokenizer.TryConsume('.'):
+      name.append(tokenizer.ConsumeIdentifier())
+    name = '.'.join(name)
+
+    if not message_descriptor.is_extendable:
+      raise tokenizer.ParseErrorPreviousToken(
+          'Message type "%s" does not have extensions.' %
+          message_descriptor.full_name)
+    # pylint: disable=protected-access
+    field = message.Extensions._FindExtensionByName(name)
+    # pylint: enable=protected-access
+    if not field:
+      raise tokenizer.ParseErrorPreviousToken(
+          'Extension "%s" not registered.' % name)
+    elif message_descriptor != field.containing_type:
+      raise tokenizer.ParseErrorPreviousToken(
+          'Extension "%s" does not extend message type "%s".' % (
+              name, message_descriptor.full_name))
+    tokenizer.Consume(']')
+  else:
+    name = tokenizer.ConsumeIdentifier()
+    field = message_descriptor.fields_by_name.get(name, None)
+
+    # 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 not field:
+      field = message_descriptor.fields_by_name.get(name.lower(), None)
+      if field and field.type != descriptor.FieldDescriptor.TYPE_GROUP:
+        field = None
+
+    if (field and field.type == descriptor.FieldDescriptor.TYPE_GROUP and
+        field.message_type.name != name):
+      field = None
+
+    if not field:
+      raise tokenizer.ParseErrorPreviousToken(
+          'Message type "%s" has no field named "%s".' % (
+              message_descriptor.full_name, name))
+
+  if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
+    tokenizer.TryConsume(':')
+
+    if tokenizer.TryConsume('<'):
+      end_token = '>'
+    else:
+      tokenizer.Consume('{')
+      end_token = '}'
+
+    if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+      if field.is_extension:
+        sub_message = message.Extensions[field].add()
+      else:
+        sub_message = getattr(message, field.name).add()
+    else:
+      if field.is_extension:
+        sub_message = message.Extensions[field]
+      else:
+        sub_message = getattr(message, field.name)
+      sub_message.SetInParent()
+
+    while not tokenizer.TryConsume(end_token):
+      if tokenizer.AtEnd():
+        raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token))
+      _MergeField(tokenizer, sub_message, allow_multiple_scalars)
+  else:
+    _MergeScalarField(tokenizer, message, field, allow_multiple_scalars)
+
+  # For historical reasons, fields may optionally be separated by commas or
+  # semicolons.
+  if not tokenizer.TryConsume(','):
+    tokenizer.TryConsume(';')
+
+
+def _MergeScalarField(tokenizer, message, field, allow_multiple_scalars):
+  """Merges a single protocol message scalar field into a message.
+
+  Args:
+    tokenizer: A tokenizer to parse the field value.
+    message: A protocol message to record the data.
+    field: The descriptor of the field to be merged.
+    allow_multiple_scalars: Determines if repeated values for a non-repeated
+      field are permitted, e.g., the string "foo: 1 foo: 2" for a
+      required/optional field named "foo".
+
+  Raises:
+    ParseError: In case of ASCII parsing problems.
+    RuntimeError: On runtime errors.
+  """
+  tokenizer.Consume(':')
+  value = None
+
+  if field.type in (descriptor.FieldDescriptor.TYPE_INT32,
+                    descriptor.FieldDescriptor.TYPE_SINT32,
+                    descriptor.FieldDescriptor.TYPE_SFIXED32):
+    value = tokenizer.ConsumeInt32()
+  elif field.type in (descriptor.FieldDescriptor.TYPE_INT64,
+                      descriptor.FieldDescriptor.TYPE_SINT64,
+                      descriptor.FieldDescriptor.TYPE_SFIXED64):
+    value = tokenizer.ConsumeInt64()
+  elif field.type in (descriptor.FieldDescriptor.TYPE_UINT32,
+                      descriptor.FieldDescriptor.TYPE_FIXED32):
+    value = tokenizer.ConsumeUint32()
+  elif field.type in (descriptor.FieldDescriptor.TYPE_UINT64,
+                      descriptor.FieldDescriptor.TYPE_FIXED64):
+    value = tokenizer.ConsumeUint64()
+  elif field.type in (descriptor.FieldDescriptor.TYPE_FLOAT,
+                      descriptor.FieldDescriptor.TYPE_DOUBLE):
+    value = tokenizer.ConsumeFloat()
+  elif field.type == descriptor.FieldDescriptor.TYPE_BOOL:
+    value = tokenizer.ConsumeBool()
+  elif field.type == descriptor.FieldDescriptor.TYPE_STRING:
+    value = tokenizer.ConsumeString()
+  elif field.type == descriptor.FieldDescriptor.TYPE_BYTES:
+    value = tokenizer.ConsumeByteString()
+  elif field.type == descriptor.FieldDescriptor.TYPE_ENUM:
+    value = tokenizer.ConsumeEnum(field)
+  else:
+    raise RuntimeError('Unknown field type %d' % field.type)
+
+  if field.label == descriptor.FieldDescriptor.LABEL_REPEATED:
+    if field.is_extension:
+      message.Extensions[field].append(value)
+    else:
+      getattr(message, field.name).append(value)
+  else:
+    if field.is_extension:
+      if not allow_multiple_scalars and message.HasExtension(field):
+        raise tokenizer.ParseErrorPreviousToken(
+            'Message type "%s" should not have multiple "%s" extensions.' %
+            (message.DESCRIPTOR.full_name, field.full_name))
+      else:
+        message.Extensions[field] = value
+    else:
+      if not allow_multiple_scalars and message.HasField(field.name):
+        raise tokenizer.ParseErrorPreviousToken(
+            'Message type "%s" should not have multiple "%s" fields.' %
+            (message.DESCRIPTOR.full_name, field.name))
+      else:
+        setattr(message, field.name, value)
+
+
+class _Tokenizer(object):
+  """Protocol buffer ASCII representation tokenizer.
+
+  This class handles the lower level string parsing by splitting it into
+  meaningful tokens.
+
+  It was directly ported from the Java protocol buffer API.
+  """
+
+  _WHITESPACE = re.compile('(\\s|(#.*$))+', re.MULTILINE)
+  _TOKEN = re.compile(
+      '[a-zA-Z_][0-9a-zA-Z_+-]*|'           # an identifier
+      '[0-9+-][0-9a-zA-Z_.+-]*|'            # a number
+      '\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|'  # a double-quoted string
+      '\'([^\'\n\\\\]|\\\\.)*(\'|\\\\?$)')  # a single-quoted string
+  _IDENTIFIER = re.compile(r'\w+')
+
+  def __init__(self, lines):
+    self._position = 0
+    self._line = -1
+    self._column = 0
+    self._token_start = None
+    self.token = ''
+    self._lines = iter(lines)
+    self._current_line = ''
+    self._previous_line = 0
+    self._previous_column = 0
+    self._more_lines = True
+    self._SkipWhitespace()
+    self.NextToken()
+
+  def AtEnd(self):
+    """Checks the end of the text was reached.
+
+    Returns:
+      True iff the end was reached.
+    """
+    return not self.token
+
+  def _PopLine(self):
+    while len(self._current_line) <= self._column:
+      try:
+        self._current_line = self._lines.next()
+      except StopIteration:
+        self._current_line = ''
+        self._more_lines = False
+        return
+      else:
+        self._line += 1
+        self._column = 0
+
+  def _SkipWhitespace(self):
+    while True:
+      self._PopLine()
+      match = self._WHITESPACE.match(self._current_line, self._column)
+      if not match:
+        break
+      length = len(match.group(0))
+      self._column += length
+
+  def TryConsume(self, token):
+    """Tries to consume a given piece of text.
+
+    Args:
+      token: Text to consume.
+
+    Returns:
+      True iff the text was consumed.
+    """
+    if self.token == token:
+      self.NextToken()
+      return True
+    return False
+
+  def Consume(self, token):
+    """Consumes a piece of text.
+
+    Args:
+      token: Text to consume.
+
+    Raises:
+      ParseError: If the text couldn't be consumed.
+    """
+    if not self.TryConsume(token):
+      raise self._ParseError('Expected "%s".' % token)
+
+  def ConsumeIdentifier(self):
+    """Consumes protocol message field identifier.
+
+    Returns:
+      Identifier string.
+
+    Raises:
+      ParseError: If an identifier couldn't be consumed.
+    """
+    result = self.token
+    if not self._IDENTIFIER.match(result):
+      raise self._ParseError('Expected identifier.')
+    self.NextToken()
+    return result
+
+  def ConsumeInt32(self):
+    """Consumes a signed 32bit integer number.
+
+    Returns:
+      The integer parsed.
+
+    Raises:
+      ParseError: If a signed 32bit integer couldn't be consumed.
+    """
+    try:
+      result = ParseInteger(self.token, is_signed=True, is_long=False)
+    except ValueError, e:
+      raise self._ParseError(str(e))
+    self.NextToken()
+    return result
+
+  def ConsumeUint32(self):
+    """Consumes an unsigned 32bit integer number.
+
+    Returns:
+      The integer parsed.
+
+    Raises:
+      ParseError: If an unsigned 32bit integer couldn't be consumed.
+    """
+    try:
+      result = ParseInteger(self.token, is_signed=False, is_long=False)
+    except ValueError, e:
+      raise self._ParseError(str(e))
+    self.NextToken()
+    return result
+
+  def ConsumeInt64(self):
+    """Consumes a signed 64bit integer number.
+
+    Returns:
+      The integer parsed.
+
+    Raises:
+      ParseError: If a signed 64bit integer couldn't be consumed.
+    """
+    try:
+      result = ParseInteger(self.token, is_signed=True, is_long=True)
+    except ValueError, e:
+      raise self._ParseError(str(e))
+    self.NextToken()
+    return result
+
+  def ConsumeUint64(self):
+    """Consumes an unsigned 64bit integer number.
+
+    Returns:
+      The integer parsed.
+
+    Raises:
+      ParseError: If an unsigned 64bit integer couldn't be consumed.
+    """
+    try:
+      result = ParseInteger(self.token, is_signed=False, is_long=True)
+    except ValueError, e:
+      raise self._ParseError(str(e))
+    self.NextToken()
+    return result
+
+  def ConsumeFloat(self):
+    """Consumes an floating point number.
+
+    Returns:
+      The number parsed.
+
+    Raises:
+      ParseError: If a floating point number couldn't be consumed.
+    """
+    try:
+      result = ParseFloat(self.token)
+    except ValueError, e:
+      raise self._ParseError(str(e))
+    self.NextToken()
+    return result
+
+  def ConsumeBool(self):
+    """Consumes a boolean value.
+
+    Returns:
+      The bool parsed.
+
+    Raises:
+      ParseError: If a boolean value couldn't be consumed.
+    """
+    try:
+      result = ParseBool(self.token)
+    except ValueError, e:
+      raise self._ParseError(str(e))
+    self.NextToken()
+    return result
+
+  def ConsumeString(self):
+    """Consumes a string value.
+
+    Returns:
+      The string parsed.
+
+    Raises:
+      ParseError: If a string value couldn't be consumed.
+    """
+    the_bytes = self.ConsumeByteString()
+    try:
+      return unicode(the_bytes, 'utf-8')
+    except UnicodeDecodeError, e:
+      raise self._StringParseError(e)
+
+  def ConsumeByteString(self):
+    """Consumes a byte array value.
+
+    Returns:
+      The array parsed (as a string).
+
+    Raises:
+      ParseError: If a byte array value couldn't be consumed.
+    """
+    the_list = [self._ConsumeSingleByteString()]
+    while self.token and self.token[0] in ('\'', '"'):
+      the_list.append(self._ConsumeSingleByteString())
+    return ''.encode('latin1').join(the_list)  ##PY25
+##!PY25    return b''.join(the_list)
+
+  def _ConsumeSingleByteString(self):
+    """Consume one token of a string literal.
+
+    String literals (whether bytes or text) can come in multiple adjacent
+    tokens which are automatically concatenated, like in C or Python.  This
+    method only consumes one token.
+    """
+    text = self.token
+    if len(text) < 1 or text[0] not in ('\'', '"'):
+      raise self._ParseError('Expected string.')
+
+    if len(text) < 2 or text[-1] != text[0]:
+      raise self._ParseError('String missing ending quote.')
+
+    try:
+      result = text_encoding.CUnescape(text[1:-1])
+    except ValueError, e:
+      raise self._ParseError(str(e))
+    self.NextToken()
+    return result
+
+  def ConsumeEnum(self, field):
+    try:
+      result = ParseEnum(field, self.token)
+    except ValueError, e:
+      raise self._ParseError(str(e))
+    self.NextToken()
+    return result
+
+  def ParseErrorPreviousToken(self, message):
+    """Creates and *returns* a ParseError for the previously read token.
+
+    Args:
+      message: A message to set for the exception.
+
+    Returns:
+      A ParseError instance.
+    """
+    return ParseError('%d:%d : %s' % (
+        self._previous_line + 1, self._previous_column + 1, message))
+
+  def _ParseError(self, message):
+    """Creates and *returns* a ParseError for the current token."""
+    return ParseError('%d:%d : %s' % (
+        self._line + 1, self._column + 1, message))
+
+  def _StringParseError(self, e):
+    return self._ParseError('Couldn\'t parse string: ' + str(e))
+
+  def NextToken(self):
+    """Reads the next meaningful token."""
+    self._previous_line = self._line
+    self._previous_column = self._column
+
+    self._column += len(self.token)
+    self._SkipWhitespace()
+
+    if not self._more_lines:
+      self.token = ''
+      return
+
+    match = self._TOKEN.match(self._current_line, self._column)
+    if match:
+      token = match.group(0)
+      self.token = token
+    else:
+      self.token = self._current_line[self._column]
+
+
+def ParseInteger(text, is_signed=False, is_long=False):
+  """Parses an integer.
+
+  Args:
+    text: The text to parse.
+    is_signed: True if a signed integer must be parsed.
+    is_long: True if a long integer must be parsed.
+
+  Returns:
+    The integer value.
+
+  Raises:
+    ValueError: Thrown Iff the text is not a valid integer.
+  """
+  # Do the actual parsing. Exception handling is propagated to caller.
+  try:
+    # We force 32-bit values to int and 64-bit values to long to make
+    # alternate implementations where the distinction is more significant
+    # (e.g. the C++ implementation) simpler.
+    if is_long:
+      result = long(text, 0)
+    else:
+      result = int(text, 0)
+  except ValueError:
+    raise ValueError('Couldn\'t parse integer: %s' % text)
+
+  # Check if the integer is sane. Exceptions handled by callers.
+  checker = _INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)]
+  checker.CheckValue(result)
+  return result
+
+
+def ParseFloat(text):
+  """Parse a floating point number.
+
+  Args:
+    text: Text to parse.
+
+  Returns:
+    The number parsed.
+
+  Raises:
+    ValueError: If a floating point number couldn't be parsed.
+  """
+  try:
+    # Assume Python compatible syntax.
+    return float(text)
+  except ValueError:
+    # Check alternative spellings.
+    if _FLOAT_INFINITY.match(text):
+      if text[0] == '-':
+        return float('-inf')
+      else:
+        return float('inf')
+    elif _FLOAT_NAN.match(text):
+      return float('nan')
+    else:
+      # assume '1.0f' format
+      try:
+        return float(text.rstrip('f'))
+      except ValueError:
+        raise ValueError('Couldn\'t parse float: %s' % text)
+
+
+def ParseBool(text):
+  """Parse a boolean value.
+
+  Args:
+    text: Text to parse.
+
+  Returns:
+    Boolean values parsed
+
+  Raises:
+    ValueError: If text is not a valid boolean.
+  """
+  if text in ('true', 't', '1'):
+    return True
+  elif text in ('false', 'f', '0'):
+    return False
+  else:
+    raise ValueError('Expected "true" or "false".')
+
+
+def ParseEnum(field, value):
+  """Parse an enum value.
+
+  The value can be specified by a number (the enum value), or by
+  a string literal (the enum name).
+
+  Args:
+    field: Enum field descriptor.
+    value: String value.
+
+  Returns:
+    Enum value number.
+
+  Raises:
+    ValueError: If the enum value could not be parsed.
+  """
+  enum_descriptor = field.enum_type
+  try:
+    number = int(value, 0)
+  except ValueError:
+    # Identifier.
+    enum_value = enum_descriptor.values_by_name.get(value, None)
+    if enum_value is None:
+      raise ValueError(
+          'Enum type "%s" has no value named %s.' % (
+              enum_descriptor.full_name, value))
+  else:
+    # Numeric value.
+    enum_value = enum_descriptor.values_by_number.get(number, None)
+    if enum_value is None:
+      raise ValueError(
+          'Enum type "%s" has no value with number %d.' % (
+              enum_descriptor.full_name, number))
+  return enum_value.number
diff --git a/protobuf/python/mox.py b/protobuf/python/mox.py
new file mode 100755
index 0000000..ce80ba5
--- /dev/null
+++ b/protobuf/python/mox.py
@@ -0,0 +1,1401 @@
+#!/usr/bin/python2.4
+#
+# Copyright 2008 Google Inc.
+#
+# 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.
+
+# This file is used for testing.  The original is at:
+#   http://code.google.com/p/pymox/
+
+"""Mox, an object-mocking framework for Python.
+
+Mox works in the record-replay-verify paradigm.  When you first create
+a mock object, it is in record mode.  You then programmatically set
+the expected behavior of the mock object (what methods are to be
+called on it, with what parameters, what they should return, and in
+what order).
+
+Once you have set up the expected mock behavior, you put it in replay
+mode.  Now the mock responds to method calls just as you told it to.
+If an unexpected method (or an expected method with unexpected
+parameters) is called, then an exception will be raised.
+
+Once you are done interacting with the mock, you need to verify that
+all the expected interactions occured.  (Maybe your code exited
+prematurely without calling some cleanup method!)  The verify phase
+ensures that every expected method was called; otherwise, an exception
+will be raised.
+
+Suggested usage / workflow:
+
+  # Create Mox factory
+  my_mox = Mox()
+
+  # Create a mock data access object
+  mock_dao = my_mox.CreateMock(DAOClass)
+
+  # Set up expected behavior
+  mock_dao.RetrievePersonWithIdentifier('1').AndReturn(person)
+  mock_dao.DeletePerson(person)
+
+  # Put mocks in replay mode
+  my_mox.ReplayAll()
+
+  # Inject mock object and run test
+  controller.SetDao(mock_dao)
+  controller.DeletePersonById('1')
+
+  # Verify all methods were called as expected
+  my_mox.VerifyAll()
+"""
+
+from collections import deque
+import re
+import types
+import unittest
+
+import stubout
+
+class Error(AssertionError):
+  """Base exception for this module."""
+
+  pass
+
+
+class ExpectedMethodCallsError(Error):
+  """Raised when Verify() is called before all expected methods have been called
+  """
+
+  def __init__(self, expected_methods):
+    """Init exception.
+
+    Args:
+      # expected_methods: A sequence of MockMethod objects that should have been
+      #   called.
+      expected_methods: [MockMethod]
+
+    Raises:
+      ValueError: if expected_methods contains no methods.
+    """
+
+    if not expected_methods:
+      raise ValueError("There must be at least one expected method")
+    Error.__init__(self)
+    self._expected_methods = expected_methods
+
+  def __str__(self):
+    calls = "\n".join(["%3d.  %s" % (i, m)
+                       for i, m in enumerate(self._expected_methods)])
+    return "Verify: Expected methods never called:\n%s" % (calls,)
+
+
+class UnexpectedMethodCallError(Error):
+  """Raised when an unexpected method is called.
+
+  This can occur if a method is called with incorrect parameters, or out of the
+  specified order.
+  """
+
+  def __init__(self, unexpected_method, expected):
+    """Init exception.
+
+    Args:
+      # unexpected_method: MockMethod that was called but was not at the head of
+      #   the expected_method queue.
+      # expected: MockMethod or UnorderedGroup the method should have
+      #   been in.
+      unexpected_method: MockMethod
+      expected: MockMethod or UnorderedGroup
+    """
+
+    Error.__init__(self)
+    self._unexpected_method = unexpected_method
+    self._expected = expected
+
+  def __str__(self):
+    return "Unexpected method call: %s.  Expecting: %s" % \
+      (self._unexpected_method, self._expected)
+
+
+class UnknownMethodCallError(Error):
+  """Raised if an unknown method is requested of the mock object."""
+
+  def __init__(self, unknown_method_name):
+    """Init exception.
+
+    Args:
+      # unknown_method_name: Method call that is not part of the mocked class's
+      #   public interface.
+      unknown_method_name: str
+    """
+
+    Error.__init__(self)
+    self._unknown_method_name = unknown_method_name
+
+  def __str__(self):
+    return "Method called is not a member of the object: %s" % \
+      self._unknown_method_name
+
+
+class Mox(object):
+  """Mox: a factory for creating mock objects."""
+
+  # A list of types that should be stubbed out with MockObjects (as
+  # opposed to MockAnythings).
+  _USE_MOCK_OBJECT = [types.ClassType, types.InstanceType, types.ModuleType,
+                      types.ObjectType, types.TypeType]
+
+  def __init__(self):
+    """Initialize a new Mox."""
+
+    self._mock_objects = []
+    self.stubs = stubout.StubOutForTesting()
+
+  def CreateMock(self, class_to_mock):
+    """Create a new mock object.
+
+    Args:
+      # class_to_mock: the class to be mocked
+      class_to_mock: class
+
+    Returns:
+      MockObject that can be used as the class_to_mock would be.
+    """
+
+    new_mock = MockObject(class_to_mock)
+    self._mock_objects.append(new_mock)
+    return new_mock
+
+  def CreateMockAnything(self):
+    """Create a mock that will accept any method calls.
+
+    This does not enforce an interface.
+    """
+
+    new_mock = MockAnything()
+    self._mock_objects.append(new_mock)
+    return new_mock
+
+  def ReplayAll(self):
+    """Set all mock objects to replay mode."""
+
+    for mock_obj in self._mock_objects:
+      mock_obj._Replay()
+
+
+  def VerifyAll(self):
+    """Call verify on all mock objects created."""
+
+    for mock_obj in self._mock_objects:
+      mock_obj._Verify()
+
+  def ResetAll(self):
+    """Call reset on all mock objects.  This does not unset stubs."""
+
+    for mock_obj in self._mock_objects:
+      mock_obj._Reset()
+
+  def StubOutWithMock(self, obj, attr_name, use_mock_anything=False):
+    """Replace a method, attribute, etc. with a Mock.
+
+    This will replace a class or module with a MockObject, and everything else
+    (method, function, etc) with a MockAnything.  This can be overridden to
+    always use a MockAnything by setting use_mock_anything to True.
+
+    Args:
+      obj: A Python object (class, module, instance, callable).
+      attr_name: str.  The name of the attribute to replace with a mock.
+      use_mock_anything: bool. True if a MockAnything should be used regardless
+        of the type of attribute.
+    """
+
+    attr_to_replace = getattr(obj, attr_name)
+    if type(attr_to_replace) in self._USE_MOCK_OBJECT and not use_mock_anything:
+      stub = self.CreateMock(attr_to_replace)
+    else:
+      stub = self.CreateMockAnything()
+
+    self.stubs.Set(obj, attr_name, stub)
+
+  def UnsetStubs(self):
+    """Restore stubs to their original state."""
+
+    self.stubs.UnsetAll()
+
+def Replay(*args):
+  """Put mocks into Replay mode.
+
+  Args:
+    # args is any number of mocks to put into replay mode.
+  """
+
+  for mock in args:
+    mock._Replay()
+
+
+def Verify(*args):
+  """Verify mocks.
+
+  Args:
+    # args is any number of mocks to be verified.
+  """
+
+  for mock in args:
+    mock._Verify()
+
+
+def Reset(*args):
+  """Reset mocks.
+
+  Args:
+    # args is any number of mocks to be reset.
+  """
+
+  for mock in args:
+    mock._Reset()
+
+
+class MockAnything:
+  """A mock that can be used to mock anything.
+
+  This is helpful for mocking classes that do not provide a public interface.
+  """
+
+  def __init__(self):
+    """ """
+    self._Reset()
+
+  def __getattr__(self, method_name):
+    """Intercept method calls on this object.
+
+     A new MockMethod is returned that is aware of the MockAnything's
+     state (record or replay).  The call will be recorded or replayed
+     by the MockMethod's __call__.
+
+    Args:
+      # method name: the name of the method being called.
+      method_name: str
+
+    Returns:
+      A new MockMethod aware of MockAnything's state (record or replay).
+    """
+
+    return self._CreateMockMethod(method_name)
+
+  def _CreateMockMethod(self, method_name):
+    """Create a new mock method call and return it.
+
+    Args:
+      # method name: the name of the method being called.
+      method_name: str
+
+    Returns:
+      A new MockMethod aware of MockAnything's state (record or replay).
+    """
+
+    return MockMethod(method_name, self._expected_calls_queue,
+                      self._replay_mode)
+
+  def __nonzero__(self):
+    """Return 1 for nonzero so the mock can be used as a conditional."""
+
+    return 1
+
+  def __eq__(self, rhs):
+    """Provide custom logic to compare objects."""
+
+    return (isinstance(rhs, MockAnything) and
+            self._replay_mode == rhs._replay_mode and
+            self._expected_calls_queue == rhs._expected_calls_queue)
+
+  def __ne__(self, rhs):
+    """Provide custom logic to compare objects."""
+
+    return not self == rhs
+
+  def _Replay(self):
+    """Start replaying expected method calls."""
+
+    self._replay_mode = True
+
+  def _Verify(self):
+    """Verify that all of the expected calls have been made.
+
+    Raises:
+      ExpectedMethodCallsError: if there are still more method calls in the
+        expected queue.
+    """
+
+    # If the list of expected calls is not empty, raise an exception
+    if self._expected_calls_queue:
+      # The last MultipleTimesGroup is not popped from the queue.
+      if (len(self._expected_calls_queue) == 1 and
+          isinstance(self._expected_calls_queue[0], MultipleTimesGroup) and
+          self._expected_calls_queue[0].IsSatisfied()):
+        pass
+      else:
+        raise ExpectedMethodCallsError(self._expected_calls_queue)
+
+  def _Reset(self):
+    """Reset the state of this mock to record mode with an empty queue."""
+
+    # Maintain a list of method calls we are expecting
+    self._expected_calls_queue = deque()
+
+    # Make sure we are in setup mode, not replay mode
+    self._replay_mode = False
+
+
+class MockObject(MockAnything, object):
+  """A mock object that simulates the public/protected interface of a class."""
+
+  def __init__(self, class_to_mock):
+    """Initialize a mock object.
+
+    This determines the methods and properties of the class and stores them.
+
+    Args:
+      # class_to_mock: class to be mocked
+      class_to_mock: class
+    """
+
+    # This is used to hack around the mixin/inheritance of MockAnything, which
+    # is not a proper object (it can be anything. :-)
+    MockAnything.__dict__['__init__'](self)
+
+    # Get a list of all the public and special methods we should mock.
+    self._known_methods = set()
+    self._known_vars = set()
+    self._class_to_mock = class_to_mock
+    for method in dir(class_to_mock):
+      if callable(getattr(class_to_mock, method)):
+        self._known_methods.add(method)
+      else:
+        self._known_vars.add(method)
+
+  def __getattr__(self, name):
+    """Intercept attribute request on this object.
+
+    If the attribute is a public class variable, it will be returned and not
+    recorded as a call.
+
+    If the attribute is not a variable, it is handled like a method
+    call. The method name is checked against the set of mockable
+    methods, and a new MockMethod is returned that is aware of the
+    MockObject's state (record or replay).  The call will be recorded
+    or replayed by the MockMethod's __call__.
+
+    Args:
+      # name: the name of the attribute being requested.
+      name: str
+
+    Returns:
+      Either a class variable or a new MockMethod that is aware of the state
+      of the mock (record or replay).
+
+    Raises:
+      UnknownMethodCallError if the MockObject does not mock the requested
+          method.
+    """
+
+    if name in self._known_vars:
+      return getattr(self._class_to_mock, name)
+
+    if name in self._known_methods:
+      return self._CreateMockMethod(name)
+
+    raise UnknownMethodCallError(name)
+
+  def __eq__(self, rhs):
+    """Provide custom logic to compare objects."""
+
+    return (isinstance(rhs, MockObject) and
+            self._class_to_mock == rhs._class_to_mock and
+            self._replay_mode == rhs._replay_mode and
+            self._expected_calls_queue == rhs._expected_calls_queue)
+
+  def __setitem__(self, key, value):
+    """Provide custom logic for mocking classes that support item assignment.
+
+    Args:
+      key: Key to set the value for.
+      value: Value to set.
+
+    Returns:
+      Expected return value in replay mode.  A MockMethod object for the
+      __setitem__ method that has already been called if not in replay mode.
+
+    Raises:
+      TypeError if the underlying class does not support item assignment.
+      UnexpectedMethodCallError if the object does not expect the call to
+        __setitem__.
+
+    """
+    setitem = self._class_to_mock.__dict__.get('__setitem__', None)
+
+    # Verify the class supports item assignment.
+    if setitem is None:
+      raise TypeError('object does not support item assignment')
+
+    # If we are in replay mode then simply call the mock __setitem__ method.
+    if self._replay_mode:
+      return MockMethod('__setitem__', self._expected_calls_queue,
+                        self._replay_mode)(key, value)
+
+
+    # Otherwise, create a mock method __setitem__.
+    return self._CreateMockMethod('__setitem__')(key, value)
+
+  def __getitem__(self, key):
+    """Provide custom logic for mocking classes that are subscriptable.
+
+    Args:
+      key: Key to return the value for.
+
+    Returns:
+      Expected return value in replay mode.  A MockMethod object for the
+      __getitem__ method that has already been called if not in replay mode.
+
+    Raises:
+      TypeError if the underlying class is not subscriptable.
+      UnexpectedMethodCallError if the object does not expect the call to
+        __setitem__.
+
+    """
+    getitem = self._class_to_mock.__dict__.get('__getitem__', None)
+
+    # Verify the class supports item assignment.
+    if getitem is None:
+      raise TypeError('unsubscriptable object')
+
+    # If we are in replay mode then simply call the mock __getitem__ method.
+    if self._replay_mode:
+      return MockMethod('__getitem__', self._expected_calls_queue,
+                        self._replay_mode)(key)
+
+
+    # Otherwise, create a mock method __getitem__.
+    return self._CreateMockMethod('__getitem__')(key)
+
+  def __call__(self, *params, **named_params):
+    """Provide custom logic for mocking classes that are callable."""
+
+    # Verify the class we are mocking is callable
+    callable = self._class_to_mock.__dict__.get('__call__', None)
+    if callable is None:
+      raise TypeError('Not callable')
+
+    # Because the call is happening directly on this object instead of a method,
+    # the call on the mock method is made right here
+    mock_method = self._CreateMockMethod('__call__')
+    return mock_method(*params, **named_params)
+
+  @property
+  def __class__(self):
+    """Return the class that is being mocked."""
+
+    return self._class_to_mock
+
+
+class MockMethod(object):
+  """Callable mock method.
+
+  A MockMethod should act exactly like the method it mocks, accepting parameters
+  and returning a value, or throwing an exception (as specified).  When this
+  method is called, it can optionally verify whether the called method (name and
+  signature) matches the expected method.
+  """
+
+  def __init__(self, method_name, call_queue, replay_mode):
+    """Construct a new mock method.
+
+    Args:
+      # method_name: the name of the method
+      # call_queue: deque of calls, verify this call against the head, or add
+      #     this call to the queue.
+      # replay_mode: False if we are recording, True if we are verifying calls
+      #     against the call queue.
+      method_name: str
+      call_queue: list or deque
+      replay_mode: bool
+    """
+
+    self._name = method_name
+    self._call_queue = call_queue
+    if not isinstance(call_queue, deque):
+      self._call_queue = deque(self._call_queue)
+    self._replay_mode = replay_mode
+
+    self._params = None
+    self._named_params = None
+    self._return_value = None
+    self._exception = None
+    self._side_effects = None
+
+  def __call__(self, *params, **named_params):
+    """Log parameters and return the specified return value.
+
+    If the Mock(Anything/Object) associated with this call is in record mode,
+    this MockMethod will be pushed onto the expected call queue.  If the mock
+    is in replay mode, this will pop a MockMethod off the top of the queue and
+    verify this call is equal to the expected call.
+
+    Raises:
+      UnexpectedMethodCall if this call is supposed to match an expected method
+        call and it does not.
+    """
+
+    self._params = params
+    self._named_params = named_params
+
+    if not self._replay_mode:
+      self._call_queue.append(self)
+      return self
+
+    expected_method = self._VerifyMethodCall()
+
+    if expected_method._side_effects:
+      expected_method._side_effects(*params, **named_params)
+
+    if expected_method._exception:
+      raise expected_method._exception
+
+    return expected_method._return_value
+
+  def __getattr__(self, name):
+    """Raise an AttributeError with a helpful message."""
+
+    raise AttributeError('MockMethod has no attribute "%s". '
+        'Did you remember to put your mocks in replay mode?' % name)
+
+  def _PopNextMethod(self):
+    """Pop the next method from our call queue."""
+    try:
+      return self._call_queue.popleft()
+    except IndexError:
+      raise UnexpectedMethodCallError(self, None)
+
+  def _VerifyMethodCall(self):
+    """Verify the called method is expected.
+
+    This can be an ordered method, or part of an unordered set.
+
+    Returns:
+      The expected mock method.
+
+    Raises:
+      UnexpectedMethodCall if the method called was not expected.
+    """
+
+    expected = self._PopNextMethod()
+
+    # Loop here, because we might have a MethodGroup followed by another
+    # group.
+    while isinstance(expected, MethodGroup):
+      expected, method = expected.MethodCalled(self)
+      if method is not None:
+        return method
+
+    # This is a mock method, so just check equality.
+    if expected != self:
+      raise UnexpectedMethodCallError(self, expected)
+
+    return expected
+
+  def __str__(self):
+    params = ', '.join(
+        [repr(p) for p in self._params or []] +
+        ['%s=%r' % x for x in sorted((self._named_params or {}).items())])
+    desc = "%s(%s) -> %r" % (self._name, params, self._return_value)
+    return desc
+
+  def __eq__(self, rhs):
+    """Test whether this MockMethod is equivalent to another MockMethod.
+
+    Args:
+      # rhs: the right hand side of the test
+      rhs: MockMethod
+    """
+
+    return (isinstance(rhs, MockMethod) and
+            self._name == rhs._name and
+            self._params == rhs._params and
+            self._named_params == rhs._named_params)
+
+  def __ne__(self, rhs):
+    """Test whether this MockMethod is not equivalent to another MockMethod.
+
+    Args:
+      # rhs: the right hand side of the test
+      rhs: MockMethod
+    """
+
+    return not self == rhs
+
+  def GetPossibleGroup(self):
+    """Returns a possible group from the end of the call queue or None if no
+    other methods are on the stack.
+    """
+
+    # Remove this method from the tail of the queue so we can add it to a group.
+    this_method = self._call_queue.pop()
+    assert this_method == self
+
+    # Determine if the tail of the queue is a group, or just a regular ordered
+    # mock method.
+    group = None
+    try:
+      group = self._call_queue[-1]
+    except IndexError:
+      pass
+
+    return group
+
+  def _CheckAndCreateNewGroup(self, group_name, group_class):
+    """Checks if the last method (a possible group) is an instance of our
+    group_class. Adds the current method to this group or creates a new one.
+
+    Args:
+
+      group_name: the name of the group.
+      group_class: the class used to create instance of this new group
+    """
+    group = self.GetPossibleGroup()
+
+    # If this is a group, and it is the correct group, add the method.
+    if isinstance(group, group_class) and group.group_name() == group_name:
+      group.AddMethod(self)
+      return self
+
+    # Create a new group and add the method.
+    new_group = group_class(group_name)
+    new_group.AddMethod(self)
+    self._call_queue.append(new_group)
+    return self
+
+  def InAnyOrder(self, group_name="default"):
+    """Move this method into a group of unordered calls.
+
+    A group of unordered calls must be defined together, and must be executed
+    in full before the next expected method can be called.  There can be
+    multiple groups that are expected serially, if they are given
+    different group names.  The same group name can be reused if there is a
+    standard method call, or a group with a different name, spliced between
+    usages.
+
+    Args:
+      group_name: the name of the unordered group.
+
+    Returns:
+      self
+    """
+    return self._CheckAndCreateNewGroup(group_name, UnorderedGroup)
+
+  def MultipleTimes(self, group_name="default"):
+    """Move this method into group of calls which may be called multiple times.
+
+    A group of repeating calls must be defined together, and must be executed in
+    full before the next expected mehtod can be called.
+
+    Args:
+      group_name: the name of the unordered group.
+
+    Returns:
+      self
+    """
+    return self._CheckAndCreateNewGroup(group_name, MultipleTimesGroup)
+
+  def AndReturn(self, return_value):
+    """Set the value to return when this method is called.
+
+    Args:
+      # return_value can be anything.
+    """
+
+    self._return_value = return_value
+    return return_value
+
+  def AndRaise(self, exception):
+    """Set the exception to raise when this method is called.
+
+    Args:
+      # exception: the exception to raise when this method is called.
+      exception: Exception
+    """
+
+    self._exception = exception
+
+  def WithSideEffects(self, side_effects):
+    """Set the side effects that are simulated when this method is called.
+
+    Args:
+      side_effects: A callable which modifies the parameters or other relevant
+        state which a given test case depends on.
+
+    Returns:
+      Self for chaining with AndReturn and AndRaise.
+    """
+    self._side_effects = side_effects
+    return self
+
+class Comparator:
+  """Base class for all Mox comparators.
+
+  A Comparator can be used as a parameter to a mocked method when the exact
+  value is not known.  For example, the code you are testing might build up a
+  long SQL string that is passed to your mock DAO. You're only interested that
+  the IN clause contains the proper primary keys, so you can set your mock
+  up as follows:
+
+  mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result)
+
+  Now whatever query is passed in must contain the string 'IN (1, 2, 4, 5)'.
+
+  A Comparator may replace one or more parameters, for example:
+  # return at most 10 rows
+  mock_dao.RunQuery(StrContains('SELECT'), 10)
+
+  or
+
+  # Return some non-deterministic number of rows
+  mock_dao.RunQuery(StrContains('SELECT'), IsA(int))
+  """
+
+  def equals(self, rhs):
+    """Special equals method that all comparators must implement.
+
+    Args:
+      rhs: any python object
+    """
+
+    raise NotImplementedError, 'method must be implemented by a subclass.'
+
+  def __eq__(self, rhs):
+    return self.equals(rhs)
+
+  def __ne__(self, rhs):
+    return not self.equals(rhs)
+
+
+class IsA(Comparator):
+  """This class wraps a basic Python type or class.  It is used to verify
+  that a parameter is of the given type or class.
+
+  Example:
+  mock_dao.Connect(IsA(DbConnectInfo))
+  """
+
+  def __init__(self, class_name):
+    """Initialize IsA
+
+    Args:
+      class_name: basic python type or a class
+    """
+
+    self._class_name = class_name
+
+  def equals(self, rhs):
+    """Check to see if the RHS is an instance of class_name.
+
+    Args:
+      # rhs: the right hand side of the test
+      rhs: object
+
+    Returns:
+      bool
+    """
+
+    try:
+      return isinstance(rhs, self._class_name)
+    except TypeError:
+      # Check raw types if there was a type error.  This is helpful for
+      # things like cStringIO.StringIO.
+      return type(rhs) == type(self._class_name)
+
+  def __repr__(self):
+    return str(self._class_name)
+
+class IsAlmost(Comparator):
+  """Comparison class used to check whether a parameter is nearly equal
+  to a given value.  Generally useful for floating point numbers.
+
+  Example mock_dao.SetTimeout((IsAlmost(3.9)))
+  """
+
+  def __init__(self, float_value, places=7):
+    """Initialize IsAlmost.
+
+    Args:
+      float_value: The value for making the comparison.
+      places: The number of decimal places to round to.
+    """
+
+    self._float_value = float_value
+    self._places = places
+
+  def equals(self, rhs):
+    """Check to see if RHS is almost equal to float_value
+
+    Args:
+      rhs: the value to compare to float_value
+
+    Returns:
+      bool
+    """
+
+    try:
+      return round(rhs-self._float_value, self._places) == 0
+    except TypeError:
+      # This is probably because either float_value or rhs is not a number.
+      return False
+
+  def __repr__(self):
+    return str(self._float_value)
+
+class StrContains(Comparator):
+  """Comparison class used to check whether a substring exists in a
+  string parameter.  This can be useful in mocking a database with SQL
+  passed in as a string parameter, for example.
+
+  Example:
+  mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result)
+  """
+
+  def __init__(self, search_string):
+    """Initialize.
+
+    Args:
+      # search_string: the string you are searching for
+      search_string: str
+    """
+
+    self._search_string = search_string
+
+  def equals(self, rhs):
+    """Check to see if the search_string is contained in the rhs string.
+
+    Args:
+      # rhs: the right hand side of the test
+      rhs: object
+
+    Returns:
+      bool
+    """
+
+    try:
+      return rhs.find(self._search_string) > -1
+    except Exception:
+      return False
+
+  def __repr__(self):
+    return '<str containing \'%s\'>' % self._search_string
+
+
+class Regex(Comparator):
+  """Checks if a string matches a regular expression.
+
+  This uses a given regular expression to determine equality.
+  """
+
+  def __init__(self, pattern, flags=0):
+    """Initialize.
+
+    Args:
+      # pattern is the regular expression to search for
+      pattern: str
+      # flags passed to re.compile function as the second argument
+      flags: int
+    """
+
+    self.regex = re.compile(pattern, flags=flags)
+
+  def equals(self, rhs):
+    """Check to see if rhs matches regular expression pattern.
+
+    Returns:
+      bool
+    """
+
+    return self.regex.search(rhs) is not None
+
+  def __repr__(self):
+    s = '<regular expression \'%s\'' % self.regex.pattern
+    if self.regex.flags:
+      s += ', flags=%d' % self.regex.flags
+    s += '>'
+    return s
+
+
+class In(Comparator):
+  """Checks whether an item (or key) is in a list (or dict) parameter.
+
+  Example:
+  mock_dao.GetUsersInfo(In('expectedUserName')).AndReturn(mock_result)
+  """
+
+  def __init__(self, key):
+    """Initialize.
+
+    Args:
+      # key is any thing that could be in a list or a key in a dict
+    """
+
+    self._key = key
+
+  def equals(self, rhs):
+    """Check to see whether key is in rhs.
+
+    Args:
+      rhs: dict
+
+    Returns:
+      bool
+    """
+
+    return self._key in rhs
+
+  def __repr__(self):
+    return '<sequence or map containing \'%s\'>' % self._key
+
+
+class ContainsKeyValue(Comparator):
+  """Checks whether a key/value pair is in a dict parameter.
+
+  Example:
+  mock_dao.UpdateUsers(ContainsKeyValue('stevepm', stevepm_user_info))
+  """
+
+  def __init__(self, key, value):
+    """Initialize.
+
+    Args:
+      # key: a key in a dict
+      # value: the corresponding value
+    """
+
+    self._key = key
+    self._value = value
+
+  def equals(self, rhs):
+    """Check whether the given key/value pair is in the rhs dict.
+
+    Returns:
+      bool
+    """
+
+    try:
+      return rhs[self._key] == self._value
+    except Exception:
+      return False
+
+  def __repr__(self):
+    return '<map containing the entry \'%s: %s\'>' % (self._key, self._value)
+
+
+class SameElementsAs(Comparator):
+  """Checks whether iterables contain the same elements (ignoring order).
+
+  Example:
+  mock_dao.ProcessUsers(SameElementsAs('stevepm', 'salomaki'))
+  """
+
+  def __init__(self, expected_seq):
+    """Initialize.
+
+    Args:
+      expected_seq: a sequence
+    """
+
+    self._expected_seq = expected_seq
+
+  def equals(self, actual_seq):
+    """Check to see whether actual_seq has same elements as expected_seq.
+
+    Args:
+      actual_seq: sequence
+
+    Returns:
+      bool
+    """
+
+    try:
+      expected = dict([(element, None) for element in self._expected_seq])
+      actual = dict([(element, None) for element in actual_seq])
+    except TypeError:
+      # Fall back to slower list-compare if any of the objects are unhashable.
+      expected = list(self._expected_seq)
+      actual = list(actual_seq)
+      expected.sort()
+      actual.sort()
+    return expected == actual
+
+  def __repr__(self):
+    return '<sequence with same elements as \'%s\'>' % self._expected_seq
+
+
+class And(Comparator):
+  """Evaluates one or more Comparators on RHS and returns an AND of the results.
+  """
+
+  def __init__(self, *args):
+    """Initialize.
+
+    Args:
+      *args: One or more Comparator
+    """
+
+    self._comparators = args
+
+  def equals(self, rhs):
+    """Checks whether all Comparators are equal to rhs.
+
+    Args:
+      # rhs: can be anything
+
+    Returns:
+      bool
+    """
+
+    for comparator in self._comparators:
+      if not comparator.equals(rhs):
+        return False
+
+    return True
+
+  def __repr__(self):
+    return '<AND %s>' % str(self._comparators)
+
+
+class Or(Comparator):
+  """Evaluates one or more Comparators on RHS and returns an OR of the results.
+  """
+
+  def __init__(self, *args):
+    """Initialize.
+
+    Args:
+      *args: One or more Mox comparators
+    """
+
+    self._comparators = args
+
+  def equals(self, rhs):
+    """Checks whether any Comparator is equal to rhs.
+
+    Args:
+      # rhs: can be anything
+
+    Returns:
+      bool
+    """
+
+    for comparator in self._comparators:
+      if comparator.equals(rhs):
+        return True
+
+    return False
+
+  def __repr__(self):
+    return '<OR %s>' % str(self._comparators)
+
+
+class Func(Comparator):
+  """Call a function that should verify the parameter passed in is correct.
+
+  You may need the ability to perform more advanced operations on the parameter
+  in order to validate it.  You can use this to have a callable validate any
+  parameter. The callable should return either True or False.
+
+
+  Example:
+
+  def myParamValidator(param):
+    # Advanced logic here
+    return True
+
+  mock_dao.DoSomething(Func(myParamValidator), true)
+  """
+
+  def __init__(self, func):
+    """Initialize.
+
+    Args:
+      func: callable that takes one parameter and returns a bool
+    """
+
+    self._func = func
+
+  def equals(self, rhs):
+    """Test whether rhs passes the function test.
+
+    rhs is passed into func.
+
+    Args:
+      rhs: any python object
+
+    Returns:
+      the result of func(rhs)
+    """
+
+    return self._func(rhs)
+
+  def __repr__(self):
+    return str(self._func)
+
+
+class IgnoreArg(Comparator):
+  """Ignore an argument.
+
+  This can be used when we don't care about an argument of a method call.
+
+  Example:
+  # Check if CastMagic is called with 3 as first arg and 'disappear' as third.
+  mymock.CastMagic(3, IgnoreArg(), 'disappear')
+  """
+
+  def equals(self, unused_rhs):
+    """Ignores arguments and returns True.
+
+    Args:
+      unused_rhs: any python object
+
+    Returns:
+      always returns True
+    """
+
+    return True
+
+  def __repr__(self):
+    return '<IgnoreArg>'
+
+
+class MethodGroup(object):
+  """Base class containing common behaviour for MethodGroups."""
+
+  def __init__(self, group_name):
+    self._group_name = group_name
+
+  def group_name(self):
+    return self._group_name
+
+  def __str__(self):
+    return '<%s "%s">' % (self.__class__.__name__, self._group_name)
+
+  def AddMethod(self, mock_method):
+    raise NotImplementedError
+
+  def MethodCalled(self, mock_method):
+    raise NotImplementedError
+
+  def IsSatisfied(self):
+    raise NotImplementedError
+
+class UnorderedGroup(MethodGroup):
+  """UnorderedGroup holds a set of method calls that may occur in any order.
+
+  This construct is helpful for non-deterministic events, such as iterating
+  over the keys of a dict.
+  """
+
+  def __init__(self, group_name):
+    super(UnorderedGroup, self).__init__(group_name)
+    self._methods = []
+
+  def AddMethod(self, mock_method):
+    """Add a method to this group.
+
+    Args:
+      mock_method: A mock method to be added to this group.
+    """
+
+    self._methods.append(mock_method)
+
+  def MethodCalled(self, mock_method):
+    """Remove a method call from the group.
+
+    If the method is not in the set, an UnexpectedMethodCallError will be
+    raised.
+
+    Args:
+      mock_method: a mock method that should be equal to a method in the group.
+
+    Returns:
+      The mock method from the group
+
+    Raises:
+      UnexpectedMethodCallError if the mock_method was not in the group.
+    """
+
+    # Check to see if this method exists, and if so, remove it from the set
+    # and return it.
+    for method in self._methods:
+      if method == mock_method:
+        # Remove the called mock_method instead of the method in the group.
+        # The called method will match any comparators when equality is checked
+        # during removal.  The method in the group could pass a comparator to
+        # another comparator during the equality check.
+        self._methods.remove(mock_method)
+
+        # If this group is not empty, put it back at the head of the queue.
+        if not self.IsSatisfied():
+          mock_method._call_queue.appendleft(self)
+
+        return self, method
+
+    raise UnexpectedMethodCallError(mock_method, self)
+
+  def IsSatisfied(self):
+    """Return True if there are not any methods in this group."""
+
+    return len(self._methods) == 0
+
+
+class MultipleTimesGroup(MethodGroup):
+  """MultipleTimesGroup holds methods that may be called any number of times.
+
+  Note: Each method must be called at least once.
+
+  This is helpful, if you don't know or care how many times a method is called.
+  """
+
+  def __init__(self, group_name):
+    super(MultipleTimesGroup, self).__init__(group_name)
+    self._methods = set()
+    self._methods_called = set()
+
+  def AddMethod(self, mock_method):
+    """Add a method to this group.
+
+    Args:
+      mock_method: A mock method to be added to this group.
+    """
+
+    self._methods.add(mock_method)
+
+  def MethodCalled(self, mock_method):
+    """Remove a method call from the group.
+
+    If the method is not in the set, an UnexpectedMethodCallError will be
+    raised.
+
+    Args:
+      mock_method: a mock method that should be equal to a method in the group.
+
+    Returns:
+      The mock method from the group
+
+    Raises:
+      UnexpectedMethodCallError if the mock_method was not in the group.
+    """
+
+    # Check to see if this method exists, and if so add it to the set of
+    # called methods.
+
+    for method in self._methods:
+      if method == mock_method:
+        self._methods_called.add(mock_method)
+        # Always put this group back on top of the queue, because we don't know
+        # when we are done.
+        mock_method._call_queue.appendleft(self)
+        return self, method
+
+    if self.IsSatisfied():
+      next_method = mock_method._PopNextMethod();
+      return next_method, None
+    else:
+      raise UnexpectedMethodCallError(mock_method, self)
+
+  def IsSatisfied(self):
+    """Return True if all methods in this group are called at least once."""
+    # NOTE(psycho): We can't use the simple set difference here because we want
+    # to match different parameters which are considered the same e.g. IsA(str)
+    # and some string. This solution is O(n^2) but n should be small.
+    tmp = self._methods.copy()
+    for called in self._methods_called:
+      for expected in tmp:
+        if called == expected:
+          tmp.remove(expected)
+          if not tmp:
+            return True
+          break
+    return False
+
+
+class MoxMetaTestBase(type):
+  """Metaclass to add mox cleanup and verification to every test.
+
+  As the mox unit testing class is being constructed (MoxTestBase or a
+  subclass), this metaclass will modify all test functions to call the
+  CleanUpMox method of the test class after they finish. This means that
+  unstubbing and verifying will happen for every test with no additional code,
+  and any failures will result in test failures as opposed to errors.
+  """
+
+  def __init__(cls, name, bases, d):
+    type.__init__(cls, name, bases, d)
+
+    # also get all the attributes from the base classes to account
+    # for a case when test class is not the immediate child of MoxTestBase
+    for base in bases:
+      for attr_name in dir(base):
+        d[attr_name] = getattr(base, attr_name)
+
+    for func_name, func in d.items():
+      if func_name.startswith('test') and callable(func):
+        setattr(cls, func_name, MoxMetaTestBase.CleanUpTest(cls, func))
+
+  @staticmethod
+  def CleanUpTest(cls, func):
+    """Adds Mox cleanup code to any MoxTestBase method.
+
+    Always unsets stubs after a test. Will verify all mocks for tests that
+    otherwise pass.
+
+    Args:
+      cls: MoxTestBase or subclass; the class whose test method we are altering.
+      func: method; the method of the MoxTestBase test class we wish to alter.
+
+    Returns:
+      The modified method.
+    """
+    def new_method(self, *args, **kwargs):
+      mox_obj = getattr(self, 'mox', None)
+      cleanup_mox = False
+      if mox_obj and isinstance(mox_obj, Mox):
+        cleanup_mox = True
+      try:
+        func(self, *args, **kwargs)
+      finally:
+        if cleanup_mox:
+          mox_obj.UnsetStubs()
+      if cleanup_mox:
+        mox_obj.VerifyAll()
+    new_method.__name__ = func.__name__
+    new_method.__doc__ = func.__doc__
+    new_method.__module__ = func.__module__
+    return new_method
+
+
+class MoxTestBase(unittest.TestCase):
+  """Convenience test class to make stubbing easier.
+
+  Sets up a "mox" attribute which is an instance of Mox - any mox tests will
+  want this. Also automatically unsets any stubs and verifies that all mock
+  methods have been called at the end of each test, eliminating boilerplate
+  code.
+  """
+
+  __metaclass__ = MoxMetaTestBase
+
+  def setUp(self):
+    self.mox = Mox()
diff --git a/protobuf/python/setup.py b/protobuf/python/setup.py
new file mode 100755
index 0000000..2450a77
--- /dev/null
+++ b/protobuf/python/setup.py
@@ -0,0 +1,201 @@
+#! /usr/bin/python
+#
+# See README for usage instructions.
+import sys
+import os
+import subprocess
+
+# We must use setuptools, not distutils, because we need to use the
+# namespace_packages option for the "google" package.
+try:
+  from setuptools import setup, Extension
+except ImportError:
+  try:
+    from ez_setup import use_setuptools
+    use_setuptools()
+    from setuptools import setup, Extension
+  except ImportError:
+    sys.stderr.write(
+        "Could not import setuptools; make sure you have setuptools or "
+        "ez_setup installed.\n")
+    raise
+from distutils.command.clean import clean as _clean
+from distutils.command.build_py import build_py as _build_py
+from distutils.spawn import find_executable
+
+maintainer_email = "protobuf@googlegroups.com"
+
+# Find the Protocol Compiler.
+if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']):
+  protoc = os.environ['PROTOC']
+elif os.path.exists("../src/protoc"):
+  protoc = "../src/protoc"
+elif os.path.exists("../src/protoc.exe"):
+  protoc = "../src/protoc.exe"
+elif os.path.exists("../vsprojects/Debug/protoc.exe"):
+  protoc = "../vsprojects/Debug/protoc.exe"
+elif os.path.exists("../vsprojects/Release/protoc.exe"):
+  protoc = "../vsprojects/Release/protoc.exe"
+else:
+  protoc = find_executable("protoc")
+
+def generate_proto(source):
+  """Invokes the Protocol Compiler to generate a _pb2.py from the given
+  .proto file.  Does nothing if the output already exists and is newer than
+  the input."""
+
+  output = source.replace(".proto", "_pb2.py").replace("../src/", "")
+
+  if (not os.path.exists(output) or
+      (os.path.exists(source) and
+       os.path.getmtime(source) > os.path.getmtime(output))):
+    print ("Generating %s..." % output)
+
+    if not os.path.exists(source):
+      sys.stderr.write("Can't find required file: %s\n" % source)
+      sys.exit(-1)
+
+    if protoc == None:
+      sys.stderr.write(
+          "protoc is not installed nor found in ../src.  Please compile it "
+          "or install the binary package.\n")
+      sys.exit(-1)
+
+    protoc_command = [ protoc, "-I../src", "-I.", "--python_out=.", source ]
+    if subprocess.call(protoc_command) != 0:
+      sys.exit(-1)
+
+def GenerateUnittestProtos():
+  generate_proto("../src/google/protobuf/unittest.proto")
+  generate_proto("../src/google/protobuf/unittest_custom_options.proto")
+  generate_proto("../src/google/protobuf/unittest_import.proto")
+  generate_proto("../src/google/protobuf/unittest_import_public.proto")
+  generate_proto("../src/google/protobuf/unittest_mset.proto")
+  generate_proto("../src/google/protobuf/unittest_no_generic_services.proto")
+  generate_proto("google/protobuf/internal/descriptor_pool_test1.proto")
+  generate_proto("google/protobuf/internal/descriptor_pool_test2.proto")
+  generate_proto("google/protobuf/internal/test_bad_identifiers.proto")
+  generate_proto("google/protobuf/internal/missing_enum_values.proto")
+  generate_proto("google/protobuf/internal/more_extensions.proto")
+  generate_proto("google/protobuf/internal/more_extensions_dynamic.proto")
+  generate_proto("google/protobuf/internal/more_messages.proto")
+  generate_proto("google/protobuf/internal/factory_test1.proto")
+  generate_proto("google/protobuf/internal/factory_test2.proto")
+  generate_proto("google/protobuf/pyext/python.proto")
+
+def MakeTestSuite():
+  # Test C++ implementation
+  import unittest
+  import google.protobuf.pyext.descriptor_cpp2_test as descriptor_cpp2_test
+  import google.protobuf.pyext.message_factory_cpp2_test \
+      as message_factory_cpp2_test
+  import google.protobuf.pyext.reflection_cpp2_generated_test \
+      as reflection_cpp2_generated_test
+
+  loader = unittest.defaultTestLoader
+  suite = unittest.TestSuite()
+  for test in [  descriptor_cpp2_test,
+                 message_factory_cpp2_test,
+                 reflection_cpp2_generated_test]:
+    suite.addTest(loader.loadTestsFromModule(test))
+  return suite
+
+class clean(_clean):
+  def run(self):
+    # Delete generated files in the code tree.
+    for (dirpath, dirnames, filenames) in os.walk("."):
+      for filename in filenames:
+        filepath = os.path.join(dirpath, filename)
+        if filepath.endswith("_pb2.py") or filepath.endswith(".pyc") or \
+          filepath.endswith(".so") or filepath.endswith(".o") or \
+          filepath.endswith('google/protobuf/compiler/__init__.py'):
+          os.remove(filepath)
+    # _clean is an old-style class, so super() doesn't work.
+    _clean.run(self)
+
+class build_py(_build_py):
+  def run(self):
+    # Generate necessary .proto file if it doesn't exist.
+    generate_proto("../src/google/protobuf/descriptor.proto")
+    generate_proto("../src/google/protobuf/compiler/plugin.proto")
+    GenerateUnittestProtos()
+
+    # Make sure google.protobuf/** are valid packages.
+    for path in ['', 'internal/', 'compiler/', 'pyext/']:
+      try:
+        open('google/protobuf/%s__init__.py' % path, 'a').close()
+      except EnvironmentError:
+        pass
+    # _build_py is an old-style class, so super() doesn't work.
+    _build_py.run(self)
+  # TODO(mrovner): Subclass to run 2to3 on some files only.
+  # Tracing what https://wiki.python.org/moin/PortingPythonToPy3k's "Approach 2"
+  # section on how to get 2to3 to run on source files during install under
+  # Python 3.  This class seems like a good place to put logic that calls
+  # python3's distutils.util.run_2to3 on the subset of the files we have in our
+  # release that are subject to conversion.
+  # See code reference in previous code review.
+
+if __name__ == '__main__':
+  ext_module_list = []
+  cpp_impl = '--cpp_implementation'
+  if cpp_impl in sys.argv:
+    sys.argv.remove(cpp_impl)
+    # C++ implementation extension
+    ext_module_list.append(Extension(
+        "google.protobuf.pyext._message",
+        [ "google/protobuf/pyext/descriptor.cc",
+          "google/protobuf/pyext/message.cc",
+          "google/protobuf/pyext/extension_dict.cc",
+          "google/protobuf/pyext/repeated_scalar_container.cc",
+          "google/protobuf/pyext/repeated_composite_container.cc" ],
+        define_macros=[('GOOGLE_PROTOBUF_HAS_ONEOF', '1')],
+        include_dirs = [ ".", "../src"],
+        libraries = [ "protobuf" ],
+        library_dirs = [ '../src/.libs' ],
+        ))
+
+  setup(name = 'protobuf',
+        version = '2.6.1',
+        packages = [ 'google' ],
+        namespace_packages = [ 'google' ],
+        test_suite = 'setup.MakeTestSuite',
+        google_test_dir = "google/protobuf/internal",
+        # Must list modules explicitly so that we don't install tests.
+        py_modules = [
+          'google.protobuf.internal.api_implementation',
+          'google.protobuf.internal.containers',
+          'google.protobuf.internal.cpp_message',
+          'google.protobuf.internal.decoder',
+          'google.protobuf.internal.encoder',
+          'google.protobuf.internal.enum_type_wrapper',
+          'google.protobuf.internal.message_listener',
+          'google.protobuf.internal.python_message',
+          'google.protobuf.internal.type_checkers',
+          'google.protobuf.internal.wire_format',
+          'google.protobuf.descriptor',
+          'google.protobuf.descriptor_pb2',
+          'google.protobuf.compiler.plugin_pb2',
+          'google.protobuf.message',
+          'google.protobuf.descriptor_database',
+          'google.protobuf.descriptor_pool',
+          'google.protobuf.message_factory',
+          'google.protobuf.pyext.cpp_message',
+          'google.protobuf.reflection',
+          'google.protobuf.service',
+          'google.protobuf.service_reflection',
+          'google.protobuf.symbol_database',
+          'google.protobuf.text_encoding',
+          'google.protobuf.text_format'],
+        cmdclass = { 'clean': clean, 'build_py': build_py },
+        install_requires = ['setuptools'],
+        setup_requires = ['google-apputils'],
+        ext_modules = ext_module_list,
+        url = 'https://developers.google.com/protocol-buffers/',
+        maintainer = maintainer_email,
+        maintainer_email = 'protobuf@googlegroups.com',
+        license = 'New BSD License',
+        description = 'Protocol Buffers',
+        long_description =
+          "Protocol Buffers are Google's data interchange format.",
+        )
diff --git a/protobuf/python/stubout.py b/protobuf/python/stubout.py
new file mode 100755
index 0000000..aee4f2d
--- /dev/null
+++ b/protobuf/python/stubout.py
@@ -0,0 +1,140 @@
+#!/usr/bin/python2.4
+#
+# Copyright 2008 Google Inc.
+#
+# 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.
+
+# This file is used for testing.  The original is at:
+#   http://code.google.com/p/pymox/
+
+class StubOutForTesting:
+  """Sample Usage:
+     You want os.path.exists() to always return true during testing.
+
+     stubs = StubOutForTesting()
+     stubs.Set(os.path, 'exists', lambda x: 1)
+       ...
+     stubs.UnsetAll()
+
+     The above changes os.path.exists into a lambda that returns 1.  Once
+     the ... part of the code finishes, the UnsetAll() looks up the old value
+     of os.path.exists and restores it.
+
+  """
+  def __init__(self):
+    self.cache = []
+    self.stubs = []
+
+  def __del__(self):
+    self.SmartUnsetAll()
+    self.UnsetAll()
+
+  def SmartSet(self, obj, attr_name, new_attr):
+    """Replace obj.attr_name with new_attr. This method is smart and works
+       at the module, class, and instance level while preserving proper
+       inheritance. It will not stub out C types however unless that has been
+       explicitly allowed by the type.
+
+       This method supports the case where attr_name is a staticmethod or a
+       classmethod of obj.
+
+       Notes:
+      - If obj is an instance, then it is its class that will actually be
+        stubbed. Note that the method Set() does not do that: if obj is
+        an instance, it (and not its class) will be stubbed.
+      - The stubbing is using the builtin getattr and setattr. So, the __get__
+        and __set__ will be called when stubbing (TODO: A better idea would
+        probably be to manipulate obj.__dict__ instead of getattr() and
+        setattr()).
+
+       Raises AttributeError if the attribute cannot be found.
+    """
+    if (inspect.ismodule(obj) or
+        (not inspect.isclass(obj) and obj.__dict__.has_key(attr_name))):
+      orig_obj = obj
+      orig_attr = getattr(obj, attr_name)
+
+    else:
+      if not inspect.isclass(obj):
+        mro = list(inspect.getmro(obj.__class__))
+      else:
+        mro = list(inspect.getmro(obj))
+
+      mro.reverse()
+
+      orig_attr = None
+
+      for cls in mro:
+        try:
+          orig_obj = cls
+          orig_attr = getattr(obj, attr_name)
+        except AttributeError:
+          continue
+
+    if orig_attr is None:
+      raise AttributeError("Attribute not found.")
+
+    # Calling getattr() on a staticmethod transforms it to a 'normal' function.
+    # We need to ensure that we put it back as a staticmethod.
+    old_attribute = obj.__dict__.get(attr_name)
+    if old_attribute is not None and isinstance(old_attribute, staticmethod):
+      orig_attr = staticmethod(orig_attr)
+
+    self.stubs.append((orig_obj, attr_name, orig_attr))
+    setattr(orig_obj, attr_name, new_attr)
+
+  def SmartUnsetAll(self):
+    """Reverses all the SmartSet() calls, restoring things to their original
+    definition.  Its okay to call SmartUnsetAll() repeatedly, as later calls
+    have no effect if no SmartSet() calls have been made.
+
+    """
+    self.stubs.reverse()
+
+    for args in self.stubs:
+      setattr(*args)
+
+    self.stubs = []
+
+  def Set(self, parent, child_name, new_child):
+    """Replace child_name's old definition with new_child, in the context
+    of the given parent.  The parent could be a module when the child is a
+    function at module scope.  Or the parent could be a class when a class'
+    method is being replaced.  The named child is set to new_child, while
+    the prior definition is saved away for later, when UnsetAll() is called.
+
+    This method supports the case where child_name is a staticmethod or a
+    classmethod of parent.
+    """
+    old_child = getattr(parent, child_name)
+
+    old_attribute = parent.__dict__.get(child_name)
+    if old_attribute is not None and isinstance(old_attribute, staticmethod):
+      old_child = staticmethod(old_child)
+
+    self.cache.append((parent, old_child, child_name))
+    setattr(parent, child_name, new_child)
+
+  def UnsetAll(self):
+    """Reverses all the Set() calls, restoring things to their original
+    definition.  Its okay to call UnsetAll() repeatedly, as later calls have
+    no effect if no Set() calls have been made.
+
+    """
+    # Undo calls to Set() in reverse order, in case Set() was called on the
+    # same arguments repeatedly (want the original call to be last one undone)
+    self.cache.reverse()
+
+    for (parent, old_child, child_name) in self.cache:
+      setattr(parent, child_name, old_child)
+    self.cache = []
diff --git a/protobuf/src/Makefile.am b/protobuf/src/Makefile.am
new file mode 100644
index 0000000..7baabbd
--- /dev/null
+++ b/protobuf/src/Makefile.am
@@ -0,0 +1,456 @@
+## Process this file with automake to produce Makefile.in
+
+if HAVE_ZLIB
+GZCHECKPROGRAMS = zcgzip zcgunzip
+GZHEADERS = google/protobuf/io/gzip_stream.h
+GZTESTS = google/protobuf/io/gzip_stream_unittest.sh
+else
+GZCHECKPROGRAMS =
+GZHEADERS =
+GZTESTS =
+endif
+
+if GCC
+# These are good warnings to turn on by default
+NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+else
+NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS)
+endif
+
+AM_CXXFLAGS = $(NO_OPT_CXXFLAGS) $(PROTOBUF_OPT_FLAG)
+
+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 \
+                         google/protobuf/compiler/plugin.proto
+
+# Not sure why these don't get cleaned automatically.
+clean-local:
+	rm -f *.loT
+
+CLEANFILES = $(protoc_outputs) unittest_proto_middleman \
+             testzip.jar testzip.list testzip.proto testzip.zip
+
+MAINTAINERCLEANFILES =   \
+  Makefile.in
+
+nobase_include_HEADERS =                                        \
+  google/protobuf/stubs/atomicops.h                             \
+  google/protobuf/stubs/atomicops_internals_arm_gcc.h           \
+  google/protobuf/stubs/atomicops_internals_arm64_gcc.h         \
+  google/protobuf/stubs/atomicops_internals_arm_qnx.h           \
+  google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
+  google/protobuf/stubs/atomicops_internals_generic_gcc.h       \
+  google/protobuf/stubs/atomicops_internals_macosx.h            \
+  google/protobuf/stubs/atomicops_internals_mips_gcc.h          \
+  google/protobuf/stubs/atomicops_internals_pnacl.h             \
+  google/protobuf/stubs/atomicops_internals_tsan.h              \
+  google/protobuf/stubs/atomicops_internals_x86_gcc.h           \
+  google/protobuf/stubs/atomicops_internals_x86_msvc.h          \
+  google/protobuf/stubs/common.h                                \
+  google/protobuf/stubs/platform_macros.h                       \
+  google/protobuf/stubs/once.h                                  \
+  google/protobuf/stubs/stl_util.h                              \
+  google/protobuf/stubs/template_util.h                         \
+  google/protobuf/stubs/type_traits.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_enum_reflection.h                   \
+  google/protobuf/generated_message_util.h                      \
+  google/protobuf/generated_message_reflection.h                \
+  google/protobuf/message.h                                     \
+  google/protobuf/message_lite.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_lite.h                            \
+  google/protobuf/wire_format_lite_inl.h                        \
+  google/protobuf/io/coded_stream.h                             \
+  $(GZHEADERS)                                                  \
+  google/protobuf/io/printer.h                                  \
+  google/protobuf/io/strtod.h                                   \
+  google/protobuf/io/tokenizer.h                                \
+  google/protobuf/io/zero_copy_stream.h                         \
+  google/protobuf/io/zero_copy_stream_impl.h                    \
+  google/protobuf/io/zero_copy_stream_impl_lite.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/plugin.h                             \
+  google/protobuf/compiler/plugin.pb.h                          \
+  google/protobuf/compiler/cpp/cpp_generator.h                  \
+  google/protobuf/compiler/java/java_generator.h                \
+  google/protobuf/compiler/javamicro/javamicro_generator.h      \
+  google/protobuf/compiler/javanano/javanano_generator.h        \
+  google/protobuf/compiler/python/python_generator.h
+
+lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
+
+libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS)
+libprotobuf_lite_la_LDFLAGS = -version-info 9:1:0 -export-dynamic -no-undefined
+libprotobuf_lite_la_SOURCES =                                  \
+  google/protobuf/stubs/atomicops_internals_x86_gcc.cc         \
+  google/protobuf/stubs/atomicops_internals_x86_msvc.cc        \
+  google/protobuf/stubs/common.cc                              \
+  google/protobuf/stubs/once.cc                                \
+  google/protobuf/stubs/hash.h                                 \
+  google/protobuf/stubs/map_util.h                             \
+  google/protobuf/stubs/shared_ptr.h                           \
+  google/protobuf/stubs/stringprintf.cc                        \
+  google/protobuf/stubs/stringprintf.h                         \
+  google/protobuf/extension_set.cc                             \
+  google/protobuf/generated_message_util.cc                    \
+  google/protobuf/message_lite.cc                              \
+  google/protobuf/repeated_field.cc                            \
+  google/protobuf/wire_format_lite.cc                          \
+  google/protobuf/io/coded_stream.cc                           \
+  google/protobuf/io/coded_stream_inl.h                        \
+  google/protobuf/io/zero_copy_stream.cc                       \
+  google/protobuf/io/zero_copy_stream_impl_lite.cc
+
+libprotobuf_la_LIBADD = $(PTHREAD_LIBS)
+libprotobuf_la_LDFLAGS = -version-info 9:1:0 -export-dynamic -no-undefined
+libprotobuf_la_SOURCES =                                       \
+  $(libprotobuf_lite_la_SOURCES)                               \
+  google/protobuf/stubs/strutil.cc                             \
+  google/protobuf/stubs/strutil.h                              \
+  google/protobuf/stubs/substitute.cc                          \
+  google/protobuf/stubs/substitute.h                           \
+  google/protobuf/stubs/structurally_valid.cc                  \
+  google/protobuf/descriptor.cc                                \
+  google/protobuf/descriptor.pb.cc                             \
+  google/protobuf/descriptor_database.cc                       \
+  google/protobuf/dynamic_message.cc                           \
+  google/protobuf/extension_set_heavy.cc                       \
+  google/protobuf/generated_message_reflection.cc              \
+  google/protobuf/message.cc                                   \
+  google/protobuf/reflection_ops.cc                            \
+  google/protobuf/service.cc                                   \
+  google/protobuf/text_format.cc                               \
+  google/protobuf/unknown_field_set.cc                         \
+  google/protobuf/wire_format.cc                               \
+  google/protobuf/io/gzip_stream.cc                            \
+  google/protobuf/io/printer.cc                                \
+  google/protobuf/io/strtod.cc                                 \
+  google/protobuf/io/tokenizer.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 9:1:0 -export-dynamic -no-undefined
+libprotoc_la_SOURCES =                                         \
+  google/protobuf/compiler/code_generator.cc                   \
+  google/protobuf/compiler/command_line_interface.cc           \
+  google/protobuf/compiler/plugin.cc                           \
+  google/protobuf/compiler/plugin.pb.cc                        \
+  google/protobuf/compiler/subprocess.cc                       \
+  google/protobuf/compiler/subprocess.h                        \
+  google/protobuf/compiler/zip_writer.cc                       \
+  google/protobuf/compiler/zip_writer.h                        \
+  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_options.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_context.cc                \
+  google/protobuf/compiler/java/java_context.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_generator_factory.cc      \
+  google/protobuf/compiler/java/java_generator_factory.h       \
+  google/protobuf/compiler/java/java_helpers.cc                \
+  google/protobuf/compiler/java/java_helpers.h                 \
+  google/protobuf/compiler/java/java_lazy_message_field.cc     \
+  google/protobuf/compiler/java/java_lazy_message_field.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_name_resolver.cc          \
+  google/protobuf/compiler/java/java_name_resolver.h           \
+  google/protobuf/compiler/java/java_primitive_field.cc        \
+  google/protobuf/compiler/java/java_primitive_field.h         \
+  google/protobuf/compiler/java/java_shared_code_generator.cc  \
+  google/protobuf/compiler/java/java_shared_code_generator.h   \
+  google/protobuf/compiler/java/java_service.cc                \
+  google/protobuf/compiler/java/java_service.h                 \
+  google/protobuf/compiler/java/java_string_field.cc           \
+  google/protobuf/compiler/java/java_string_field.h            \
+  google/protobuf/compiler/java/java_doc_comment.cc            \
+  google/protobuf/compiler/java/java_doc_comment.h             \
+  google/protobuf/compiler/javamicro/javamicro_enum.cc         \
+  google/protobuf/compiler/javamicro/javamicro_enum.h          \
+  google/protobuf/compiler/javamicro/javamicro_enum_field.cc   \
+  google/protobuf/compiler/javamicro/javamicro_enum_field.h    \
+  google/protobuf/compiler/javamicro/javamicro_field.cc        \
+  google/protobuf/compiler/javamicro/javamicro_field.h         \
+  google/protobuf/compiler/javamicro/javamicro_file.cc         \
+  google/protobuf/compiler/javamicro/javamicro_file.h          \
+  google/protobuf/compiler/javamicro/javamicro_generator.cc    \
+  google/protobuf/compiler/javamicro/javamicro_helpers.cc      \
+  google/protobuf/compiler/javamicro/javamicro_helpers.h       \
+  google/protobuf/compiler/javamicro/javamicro_message.cc      \
+  google/protobuf/compiler/javamicro/javamicro_message.h       \
+  google/protobuf/compiler/javamicro/javamicro_message_field.cc\
+  google/protobuf/compiler/javamicro/javamicro_message_field.h \
+  google/protobuf/compiler/javamicro/javamicro_primitive_field.cc\
+  google/protobuf/compiler/javamicro/javamicro_primitive_field.h\
+  google/protobuf/compiler/javanano/javanano_enum.cc         \
+  google/protobuf/compiler/javanano/javanano_enum.h          \
+  google/protobuf/compiler/javanano/javanano_enum_field.cc   \
+  google/protobuf/compiler/javanano/javanano_enum_field.h    \
+  google/protobuf/compiler/javanano/javanano_extension.cc    \
+  google/protobuf/compiler/javanano/javanano_extension.h     \
+  google/protobuf/compiler/javanano/javanano_field.cc        \
+  google/protobuf/compiler/javanano/javanano_field.h         \
+  google/protobuf/compiler/javanano/javanano_file.cc         \
+  google/protobuf/compiler/javanano/javanano_file.h          \
+  google/protobuf/compiler/javanano/javanano_generator.cc    \
+  google/protobuf/compiler/javanano/javanano_helpers.cc      \
+  google/protobuf/compiler/javanano/javanano_helpers.h       \
+  google/protobuf/compiler/javanano/javanano_message.cc      \
+  google/protobuf/compiler/javanano/javanano_message.h       \
+  google/protobuf/compiler/javanano/javanano_message_field.cc\
+  google/protobuf/compiler/javanano/javanano_message_field.h \
+  google/protobuf/compiler/javanano/javanano_primitive_field.cc\
+  google/protobuf/compiler/javanano/javanano_primitive_field.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_empty.proto                         \
+  google/protobuf/unittest_import.proto                        \
+  google/protobuf/unittest_import_public.proto                 \
+  google/protobuf/unittest_mset.proto                          \
+  google/protobuf/unittest_optimize_for.proto                  \
+  google/protobuf/unittest_embed_optimize_for.proto            \
+  google/protobuf/unittest_custom_options.proto                \
+  google/protobuf/unittest_lite.proto                          \
+  google/protobuf/unittest_import_lite.proto                   \
+  google/protobuf/unittest_import_public_lite.proto            \
+  google/protobuf/unittest_lite_imports_nonlite.proto          \
+  google/protobuf/unittest_no_generic_services.proto           \
+  google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
+
+EXTRA_DIST =                                                   \
+  $(protoc_inputs)                                             \
+  solaris/libstdc++.la                                         \
+  google/protobuf/io/gzip_stream.h                             \
+  google/protobuf/io/gzip_stream_unittest.sh                   \
+  google/protobuf/testdata/golden_message                      \
+  google/protobuf/testdata/golden_message_oneof_implemented    \
+  google/protobuf/testdata/golden_packed_fields_message        \
+  google/protobuf/testdata/bad_utf8_string                     \
+  google/protobuf/testdata/text_format_unittest_data.txt       \
+  google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt  \
+  google/protobuf/testdata/text_format_unittest_data_pointy.txt             \
+  google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt       \
+  google/protobuf/testdata/text_format_unittest_extensions_data.txt         \
+  google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt  \
+  google/protobuf/package_info.h                               \
+  google/protobuf/io/package_info.h                            \
+  google/protobuf/compiler/package_info.h                      \
+  google/protobuf/compiler/zip_output_unittest.sh              \
+  google/protobuf/unittest_enormous_descriptor.proto
+
+protoc_lite_outputs =                                          \
+  google/protobuf/unittest_lite.pb.cc                          \
+  google/protobuf/unittest_lite.pb.h                           \
+  google/protobuf/unittest_import_lite.pb.cc                   \
+  google/protobuf/unittest_import_lite.pb.h                    \
+  google/protobuf/unittest_import_public_lite.pb.cc            \
+  google/protobuf/unittest_import_public_lite.pb.h
+
+protoc_outputs =                                               \
+  $(protoc_lite_outputs)                                       \
+  google/protobuf/unittest.pb.cc                               \
+  google/protobuf/unittest.pb.h                                \
+  google/protobuf/unittest_empty.pb.cc                         \
+  google/protobuf/unittest_empty.pb.h                          \
+  google/protobuf/unittest_import.pb.cc                        \
+  google/protobuf/unittest_import.pb.h                         \
+  google/protobuf/unittest_import_public.pb.cc                 \
+  google/protobuf/unittest_import_public.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/unittest_custom_options.pb.cc                \
+  google/protobuf/unittest_custom_options.pb.h                 \
+  google/protobuf/unittest_lite_imports_nonlite.pb.cc          \
+  google/protobuf/unittest_lite_imports_nonlite.pb.h           \
+  google/protobuf/unittest_no_generic_services.pb.cc           \
+  google/protobuf/unittest_no_generic_services.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)
+
+if USE_EXTERNAL_PROTOC
+
+unittest_proto_middleman: $(protoc_inputs)
+	$(PROTOC) -I$(srcdir) --cpp_out=. $^
+	touch unittest_proto_middleman
+
+else
+
+# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
+# relative to srcdir, which may not be the same as the current directory when
+# building out-of-tree.
+unittest_proto_middleman: protoc$(EXEEXT) $(protoc_inputs)
+	oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) )
+	touch unittest_proto_middleman
+
+endif
+
+$(protoc_outputs): unittest_proto_middleman
+
+COMMON_TEST_SOURCES =                                          \
+  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
+
+check_PROGRAMS = protoc protobuf-test protobuf-lazy-descriptor-test \
+                 protobuf-lite-test test_plugin $(GZCHECKPROGRAMS)
+protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \
+                      $(top_builddir)/gtest/lib/libgtest.la       \
+                      $(top_builddir)/gtest/lib/libgtest_main.la
+protobuf_test_CPPFLAGS = -I$(top_srcdir)/gtest/include         \
+                         -I$(top_builddir)/gtest/include
+# Disable optimization for tests unless the user explicitly asked for it,
+# since test_util.cc takes forever to compile with optimization (with GCC).
+# See configure.ac for more info.
+protobuf_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_test_SOURCES =                                        \
+  google/protobuf/stubs/common_unittest.cc                     \
+  google/protobuf/stubs/once_unittest.cc                       \
+  google/protobuf/stubs/strutil_unittest.cc                    \
+  google/protobuf/stubs/structurally_valid_unittest.cc         \
+  google/protobuf/stubs/stringprintf_unittest.cc               \
+  google/protobuf/stubs/template_util_unittest.cc              \
+  google/protobuf/stubs/type_traits_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/repeated_field_reflection_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/mock_code_generator.cc              \
+  google/protobuf/compiler/mock_code_generator.h               \
+  google/protobuf/compiler/parser_unittest.cc                  \
+  google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc       \
+  google/protobuf/compiler/cpp/cpp_unittest.h                  \
+  google/protobuf/compiler/cpp/cpp_unittest.cc                 \
+  google/protobuf/compiler/cpp/cpp_plugin_unittest.cc          \
+  google/protobuf/compiler/java/java_plugin_unittest.cc        \
+  google/protobuf/compiler/java/java_doc_comment_unittest.cc   \
+  google/protobuf/compiler/python/python_plugin_unittest.cc    \
+  $(COMMON_TEST_SOURCES)
+nodist_protobuf_test_SOURCES = $(protoc_outputs)
+
+# Run cpp_unittest again with PROTOBUF_TEST_NO_DESCRIPTORS defined.
+protobuf_lazy_descriptor_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la \
+                      libprotoc.la                                   \
+                      $(top_builddir)/gtest/lib/libgtest.la          \
+                      $(top_builddir)/gtest/lib/libgtest_main.la
+protobuf_lazy_descriptor_test_CPPFLAGS = -I$(top_srcdir)/gtest/include    \
+                                         -I$(top_builddir)/gtest/include  \
+                                         -DPROTOBUF_TEST_NO_DESCRIPTORS
+protobuf_lazy_descriptor_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_lazy_descriptor_test_SOURCES =                        \
+  google/protobuf/compiler/cpp/cpp_unittest.cc                 \
+  $(COMMON_TEST_SOURCES)
+nodist_protobuf_lazy_descriptor_test_SOURCES = $(protoc_outputs)
+
+# Build lite_unittest separately, since it doesn't use gtest.
+protobuf_lite_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la
+protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_lite_test_SOURCES =                                           \
+  google/protobuf/lite_unittest.cc                                     \
+  google/protobuf/test_util_lite.cc                                    \
+  google/protobuf/test_util_lite.h
+nodist_protobuf_lite_test_SOURCES = $(protoc_lite_outputs)
+
+# Test plugin binary.
+test_plugin_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \
+                    $(top_builddir)/gtest/lib/libgtest.la
+test_plugin_CPPFLAGS = -I$(top_srcdir)/gtest/include         \
+                       -I$(top_builddir)/gtest/include
+test_plugin_SOURCES =                                          \
+  google/protobuf/compiler/mock_code_generator.cc              \
+  google/protobuf/testing/file.cc                              \
+  google/protobuf/testing/file.h                               \
+  google/protobuf/compiler/test_plugin.cc
+
+if HAVE_ZLIB
+zcgzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la
+zcgzip_SOURCES = google/protobuf/testing/zcgzip.cc
+
+zcgunzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la
+zcgunzip_SOURCES = google/protobuf/testing/zcgunzip.cc
+endif
+
+TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test \
+        google/protobuf/compiler/zip_output_unittest.sh $(GZTESTS)
diff --git a/protobuf/src/Makefile.in b/protobuf/src/Makefile.in
new file mode 100644
index 0000000..c6703bb
--- /dev/null
+++ b/protobuf/src/Makefile.in
@@ -0,0 +1,3796 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+bin_PROGRAMS = protoc$(EXEEXT)
+check_PROGRAMS = protoc$(EXEEXT) protobuf-test$(EXEEXT) \
+	protobuf-lazy-descriptor-test$(EXEEXT) \
+	protobuf-lite-test$(EXEEXT) test_plugin$(EXEEXT) \
+	$(am__EXEEXT_1)
+TESTS = protobuf-test$(EXEEXT) protobuf-lazy-descriptor-test$(EXEEXT) \
+	protobuf-lite-test$(EXEEXT) \
+	google/protobuf/compiler/zip_output_unittest.sh \
+	$(am__EXEEXT_2)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp $(nobase_dist_proto_DATA) \
+	$(am__nobase_include_HEADERS_DIST) $(top_srcdir)/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_system_extensions.m4 \
+	$(top_srcdir)/m4/acx_check_suncc.m4 \
+	$(top_srcdir)/m4/acx_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
+	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+	$(top_srcdir)/m4/stl_hash.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+	"$(DESTDIR)$(protodir)" "$(DESTDIR)$(includedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libprotobuf_lite_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_libprotobuf_lite_la_OBJECTS =  \
+	google/protobuf/stubs/atomicops_internals_x86_gcc.lo \
+	google/protobuf/stubs/atomicops_internals_x86_msvc.lo \
+	google/protobuf/stubs/common.lo google/protobuf/stubs/once.lo \
+	google/protobuf/stubs/stringprintf.lo \
+	google/protobuf/extension_set.lo \
+	google/protobuf/generated_message_util.lo \
+	google/protobuf/message_lite.lo \
+	google/protobuf/repeated_field.lo \
+	google/protobuf/wire_format_lite.lo \
+	google/protobuf/io/coded_stream.lo \
+	google/protobuf/io/zero_copy_stream.lo \
+	google/protobuf/io/zero_copy_stream_impl_lite.lo
+libprotobuf_lite_la_OBJECTS = $(am_libprotobuf_lite_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+libprotobuf_lite_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(libprotobuf_lite_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+libprotobuf_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am__objects_1 = google/protobuf/stubs/atomicops_internals_x86_gcc.lo \
+	google/protobuf/stubs/atomicops_internals_x86_msvc.lo \
+	google/protobuf/stubs/common.lo google/protobuf/stubs/once.lo \
+	google/protobuf/stubs/stringprintf.lo \
+	google/protobuf/extension_set.lo \
+	google/protobuf/generated_message_util.lo \
+	google/protobuf/message_lite.lo \
+	google/protobuf/repeated_field.lo \
+	google/protobuf/wire_format_lite.lo \
+	google/protobuf/io/coded_stream.lo \
+	google/protobuf/io/zero_copy_stream.lo \
+	google/protobuf/io/zero_copy_stream_impl_lite.lo
+am_libprotobuf_la_OBJECTS = $(am__objects_1) \
+	google/protobuf/stubs/strutil.lo \
+	google/protobuf/stubs/substitute.lo \
+	google/protobuf/stubs/structurally_valid.lo \
+	google/protobuf/descriptor.lo google/protobuf/descriptor.pb.lo \
+	google/protobuf/descriptor_database.lo \
+	google/protobuf/dynamic_message.lo \
+	google/protobuf/extension_set_heavy.lo \
+	google/protobuf/generated_message_reflection.lo \
+	google/protobuf/message.lo google/protobuf/reflection_ops.lo \
+	google/protobuf/service.lo google/protobuf/text_format.lo \
+	google/protobuf/unknown_field_set.lo \
+	google/protobuf/wire_format.lo \
+	google/protobuf/io/gzip_stream.lo \
+	google/protobuf/io/printer.lo google/protobuf/io/strtod.lo \
+	google/protobuf/io/tokenizer.lo \
+	google/protobuf/io/zero_copy_stream_impl.lo \
+	google/protobuf/compiler/importer.lo \
+	google/protobuf/compiler/parser.lo
+libprotobuf_la_OBJECTS = $(am_libprotobuf_la_OBJECTS)
+libprotobuf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(AM_CXXFLAGS) $(CXXFLAGS) $(libprotobuf_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+libprotoc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la
+am_libprotoc_la_OBJECTS = google/protobuf/compiler/code_generator.lo \
+	google/protobuf/compiler/command_line_interface.lo \
+	google/protobuf/compiler/plugin.lo \
+	google/protobuf/compiler/plugin.pb.lo \
+	google/protobuf/compiler/subprocess.lo \
+	google/protobuf/compiler/zip_writer.lo \
+	google/protobuf/compiler/cpp/cpp_enum.lo \
+	google/protobuf/compiler/cpp/cpp_enum_field.lo \
+	google/protobuf/compiler/cpp/cpp_extension.lo \
+	google/protobuf/compiler/cpp/cpp_field.lo \
+	google/protobuf/compiler/cpp/cpp_file.lo \
+	google/protobuf/compiler/cpp/cpp_generator.lo \
+	google/protobuf/compiler/cpp/cpp_helpers.lo \
+	google/protobuf/compiler/cpp/cpp_message.lo \
+	google/protobuf/compiler/cpp/cpp_message_field.lo \
+	google/protobuf/compiler/cpp/cpp_primitive_field.lo \
+	google/protobuf/compiler/cpp/cpp_service.lo \
+	google/protobuf/compiler/cpp/cpp_string_field.lo \
+	google/protobuf/compiler/java/java_context.lo \
+	google/protobuf/compiler/java/java_enum.lo \
+	google/protobuf/compiler/java/java_enum_field.lo \
+	google/protobuf/compiler/java/java_extension.lo \
+	google/protobuf/compiler/java/java_field.lo \
+	google/protobuf/compiler/java/java_file.lo \
+	google/protobuf/compiler/java/java_generator.lo \
+	google/protobuf/compiler/java/java_generator_factory.lo \
+	google/protobuf/compiler/java/java_helpers.lo \
+	google/protobuf/compiler/java/java_lazy_message_field.lo \
+	google/protobuf/compiler/java/java_message.lo \
+	google/protobuf/compiler/java/java_message_field.lo \
+	google/protobuf/compiler/java/java_name_resolver.lo \
+	google/protobuf/compiler/java/java_primitive_field.lo \
+	google/protobuf/compiler/java/java_shared_code_generator.lo \
+	google/protobuf/compiler/java/java_service.lo \
+	google/protobuf/compiler/java/java_string_field.lo \
+	google/protobuf/compiler/java/java_doc_comment.lo \
+	google/protobuf/compiler/javamicro/javamicro_enum.lo \
+	google/protobuf/compiler/javamicro/javamicro_enum_field.lo \
+	google/protobuf/compiler/javamicro/javamicro_field.lo \
+	google/protobuf/compiler/javamicro/javamicro_file.lo \
+	google/protobuf/compiler/javamicro/javamicro_generator.lo \
+	google/protobuf/compiler/javamicro/javamicro_helpers.lo \
+	google/protobuf/compiler/javamicro/javamicro_message.lo \
+	google/protobuf/compiler/javamicro/javamicro_message_field.lo \
+	google/protobuf/compiler/javamicro/javamicro_primitive_field.lo \
+	google/protobuf/compiler/javanano/javanano_enum.lo \
+	google/protobuf/compiler/javanano/javanano_enum_field.lo \
+	google/protobuf/compiler/javanano/javanano_extension.lo \
+	google/protobuf/compiler/javanano/javanano_field.lo \
+	google/protobuf/compiler/javanano/javanano_file.lo \
+	google/protobuf/compiler/javanano/javanano_generator.lo \
+	google/protobuf/compiler/javanano/javanano_helpers.lo \
+	google/protobuf/compiler/javanano/javanano_message.lo \
+	google/protobuf/compiler/javanano/javanano_message_field.lo \
+	google/protobuf/compiler/javanano/javanano_primitive_field.lo \
+	google/protobuf/compiler/python/python_generator.lo
+libprotoc_la_OBJECTS = $(am_libprotoc_la_OBJECTS)
+libprotoc_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(libprotoc_la_LDFLAGS) $(LDFLAGS) -o $@
+@HAVE_ZLIB_TRUE@am__EXEEXT_1 = zcgzip$(EXEEXT) zcgunzip$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS)
+am__objects_2 = google/protobuf/protobuf_lazy_descriptor_test-test_util.$(OBJEXT) \
+	google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.$(OBJEXT) \
+	google/protobuf/testing/protobuf_lazy_descriptor_test-file.$(OBJEXT)
+am_protobuf_lazy_descriptor_test_OBJECTS = google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.$(OBJEXT) \
+	$(am__objects_2)
+am__objects_3 = google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.$(OBJEXT)
+am__objects_4 = $(am__objects_3) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.$(OBJEXT) \
+	google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.$(OBJEXT)
+nodist_protobuf_lazy_descriptor_test_OBJECTS = $(am__objects_4)
+protobuf_lazy_descriptor_test_OBJECTS =  \
+	$(am_protobuf_lazy_descriptor_test_OBJECTS) \
+	$(nodist_protobuf_lazy_descriptor_test_OBJECTS)
+protobuf_lazy_descriptor_test_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	libprotobuf.la libprotoc.la \
+	$(top_builddir)/gtest/lib/libgtest.la \
+	$(top_builddir)/gtest/lib/libgtest_main.la
+protobuf_lazy_descriptor_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_protobuf_lite_test_OBJECTS =  \
+	google/protobuf/protobuf_lite_test-lite_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_lite_test-test_util_lite.$(OBJEXT)
+am__objects_5 =  \
+	google/protobuf/protobuf_lite_test-unittest_lite.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lite_test-unittest_import_lite.pb.$(OBJEXT) \
+	google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.$(OBJEXT)
+nodist_protobuf_lite_test_OBJECTS = $(am__objects_5)
+protobuf_lite_test_OBJECTS = $(am_protobuf_lite_test_OBJECTS) \
+	$(nodist_protobuf_lite_test_OBJECTS)
+protobuf_lite_test_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	libprotobuf-lite.la
+protobuf_lite_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am__objects_6 = google/protobuf/protobuf_test-test_util.$(OBJEXT) \
+	google/protobuf/testing/protobuf_test-googletest.$(OBJEXT) \
+	google/protobuf/testing/protobuf_test-file.$(OBJEXT)
+am_protobuf_test_OBJECTS =  \
+	google/protobuf/stubs/protobuf_test-common_unittest.$(OBJEXT) \
+	google/protobuf/stubs/protobuf_test-once_unittest.$(OBJEXT) \
+	google/protobuf/stubs/protobuf_test-strutil_unittest.$(OBJEXT) \
+	google/protobuf/stubs/protobuf_test-structurally_valid_unittest.$(OBJEXT) \
+	google/protobuf/stubs/protobuf_test-stringprintf_unittest.$(OBJEXT) \
+	google/protobuf/stubs/protobuf_test-template_util_unittest.$(OBJEXT) \
+	google/protobuf/stubs/protobuf_test-type_traits_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-descriptor_database_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-descriptor_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-dynamic_message_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-extension_set_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-generated_message_reflection_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-message_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-reflection_ops_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-repeated_field_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-repeated_field_reflection_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-text_format_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-unknown_field_set_unittest.$(OBJEXT) \
+	google/protobuf/protobuf_test-wire_format_unittest.$(OBJEXT) \
+	google/protobuf/io/protobuf_test-coded_stream_unittest.$(OBJEXT) \
+	google/protobuf/io/protobuf_test-printer_unittest.$(OBJEXT) \
+	google/protobuf/io/protobuf_test-tokenizer_unittest.$(OBJEXT) \
+	google/protobuf/io/protobuf_test-zero_copy_stream_unittest.$(OBJEXT) \
+	google/protobuf/compiler/protobuf_test-command_line_interface_unittest.$(OBJEXT) \
+	google/protobuf/compiler/protobuf_test-importer_unittest.$(OBJEXT) \
+	google/protobuf/compiler/protobuf_test-mock_code_generator.$(OBJEXT) \
+	google/protobuf/compiler/protobuf_test-parser_unittest.$(OBJEXT) \
+	google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.$(OBJEXT) \
+	google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.$(OBJEXT) \
+	google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.$(OBJEXT) \
+	google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.$(OBJEXT) \
+	google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.$(OBJEXT) \
+	google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.$(OBJEXT) \
+	$(am__objects_6)
+am__objects_7 =  \
+	google/protobuf/protobuf_test-unittest_lite.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_import_lite.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_import_public_lite.pb.$(OBJEXT)
+am__objects_8 = $(am__objects_7) \
+	google/protobuf/protobuf_test-unittest.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_empty.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_import.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_import_public.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_mset.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_optimize_for.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_custom_options.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.$(OBJEXT) \
+	google/protobuf/protobuf_test-unittest_no_generic_services.pb.$(OBJEXT) \
+	google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.$(OBJEXT)
+nodist_protobuf_test_OBJECTS = $(am__objects_8)
+protobuf_test_OBJECTS = $(am_protobuf_test_OBJECTS) \
+	$(nodist_protobuf_test_OBJECTS)
+protobuf_test_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \
+	libprotoc.la $(top_builddir)/gtest/lib/libgtest.la \
+	$(top_builddir)/gtest/lib/libgtest_main.la
+protobuf_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+	$(protobuf_test_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
+am_protoc_OBJECTS = google/protobuf/compiler/main.$(OBJEXT)
+protoc_OBJECTS = $(am_protoc_OBJECTS)
+protoc_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \
+	libprotoc.la
+am_test_plugin_OBJECTS = google/protobuf/compiler/test_plugin-mock_code_generator.$(OBJEXT) \
+	google/protobuf/testing/test_plugin-file.$(OBJEXT) \
+	google/protobuf/compiler/test_plugin-test_plugin.$(OBJEXT)
+test_plugin_OBJECTS = $(am_test_plugin_OBJECTS)
+test_plugin_DEPENDENCIES = $(am__DEPENDENCIES_1) libprotobuf.la \
+	libprotoc.la $(top_builddir)/gtest/lib/libgtest.la
+am__zcgunzip_SOURCES_DIST = google/protobuf/testing/zcgunzip.cc
+@HAVE_ZLIB_TRUE@am_zcgunzip_OBJECTS =  \
+@HAVE_ZLIB_TRUE@	google/protobuf/testing/zcgunzip.$(OBJEXT)
+zcgunzip_OBJECTS = $(am_zcgunzip_OBJECTS)
+@HAVE_ZLIB_TRUE@zcgunzip_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+@HAVE_ZLIB_TRUE@	libprotobuf.la
+am__zcgzip_SOURCES_DIST = google/protobuf/testing/zcgzip.cc
+@HAVE_ZLIB_TRUE@am_zcgzip_OBJECTS =  \
+@HAVE_ZLIB_TRUE@	google/protobuf/testing/zcgzip.$(OBJEXT)
+zcgzip_OBJECTS = $(am_zcgzip_OBJECTS)
+@HAVE_ZLIB_TRUE@zcgzip_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+@HAVE_ZLIB_TRUE@	libprotobuf.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(libprotobuf_lite_la_SOURCES) $(libprotobuf_la_SOURCES) \
+	$(libprotoc_la_SOURCES) \
+	$(protobuf_lazy_descriptor_test_SOURCES) \
+	$(nodist_protobuf_lazy_descriptor_test_SOURCES) \
+	$(protobuf_lite_test_SOURCES) \
+	$(nodist_protobuf_lite_test_SOURCES) $(protobuf_test_SOURCES) \
+	$(nodist_protobuf_test_SOURCES) $(protoc_SOURCES) \
+	$(test_plugin_SOURCES) $(zcgunzip_SOURCES) $(zcgzip_SOURCES)
+DIST_SOURCES = $(libprotobuf_lite_la_SOURCES) \
+	$(libprotobuf_la_SOURCES) $(libprotoc_la_SOURCES) \
+	$(protobuf_lazy_descriptor_test_SOURCES) \
+	$(protobuf_lite_test_SOURCES) $(protobuf_test_SOURCES) \
+	$(protoc_SOURCES) $(test_plugin_SOURCES) \
+	$(am__zcgunzip_SOURCES_DIST) $(am__zcgzip_SOURCES_DIST)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+DATA = $(nobase_dist_proto_DATA)
+am__nobase_include_HEADERS_DIST = google/protobuf/stubs/atomicops.h \
+	google/protobuf/stubs/atomicops_internals_arm_gcc.h \
+	google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
+	google/protobuf/stubs/atomicops_internals_arm_qnx.h \
+	google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
+	google/protobuf/stubs/atomicops_internals_generic_gcc.h \
+	google/protobuf/stubs/atomicops_internals_macosx.h \
+	google/protobuf/stubs/atomicops_internals_mips_gcc.h \
+	google/protobuf/stubs/atomicops_internals_pnacl.h \
+	google/protobuf/stubs/atomicops_internals_tsan.h \
+	google/protobuf/stubs/atomicops_internals_x86_gcc.h \
+	google/protobuf/stubs/atomicops_internals_x86_msvc.h \
+	google/protobuf/stubs/common.h \
+	google/protobuf/stubs/platform_macros.h \
+	google/protobuf/stubs/once.h google/protobuf/stubs/stl_util.h \
+	google/protobuf/stubs/template_util.h \
+	google/protobuf/stubs/type_traits.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_enum_reflection.h \
+	google/protobuf/generated_message_util.h \
+	google/protobuf/generated_message_reflection.h \
+	google/protobuf/message.h google/protobuf/message_lite.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_lite.h \
+	google/protobuf/wire_format_lite_inl.h \
+	google/protobuf/io/coded_stream.h \
+	google/protobuf/io/gzip_stream.h google/protobuf/io/printer.h \
+	google/protobuf/io/strtod.h google/protobuf/io/tokenizer.h \
+	google/protobuf/io/zero_copy_stream.h \
+	google/protobuf/io/zero_copy_stream_impl.h \
+	google/protobuf/io/zero_copy_stream_impl_lite.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/plugin.h \
+	google/protobuf/compiler/plugin.pb.h \
+	google/protobuf/compiler/cpp/cpp_generator.h \
+	google/protobuf/compiler/java/java_generator.h \
+	google/protobuf/compiler/javamicro/javamicro_generator.h \
+	google/protobuf/compiler/javanano/javanano_generator.h \
+	google/protobuf/compiler/python/python_generator.h
+HEADERS = $(nobase_include_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+@HAVE_ZLIB_TRUE@am__EXEEXT_2 =  \
+@HAVE_ZLIB_TRUE@	google/protobuf/io/gzip_stream_unittest.sh
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ISAINFO = @ISAINFO@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POW_LIB = @POW_LIB@
+PROTOBUF_OPT_FLAG = @PROTOBUF_OPT_FLAG@
+PROTOC = @PROTOC@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+acx_pthread_config = @acx_pthread_config@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+@HAVE_ZLIB_FALSE@GZCHECKPROGRAMS = 
+@HAVE_ZLIB_TRUE@GZCHECKPROGRAMS = zcgzip zcgunzip
+@HAVE_ZLIB_FALSE@GZHEADERS = 
+@HAVE_ZLIB_TRUE@GZHEADERS = google/protobuf/io/gzip_stream.h
+@HAVE_ZLIB_FALSE@GZTESTS = 
+@HAVE_ZLIB_TRUE@GZTESTS = google/protobuf/io/gzip_stream_unittest.sh
+@GCC_FALSE@NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS)
+
+# These are good warnings to turn on by default
+@GCC_TRUE@NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+AM_CXXFLAGS = $(NO_OPT_CXXFLAGS) $(PROTOBUF_OPT_FLAG)
+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 \
+                         google/protobuf/compiler/plugin.proto
+
+CLEANFILES = $(protoc_outputs) unittest_proto_middleman \
+             testzip.jar testzip.list testzip.proto testzip.zip
+
+MAINTAINERCLEANFILES = \
+  Makefile.in
+
+nobase_include_HEADERS = \
+  google/protobuf/stubs/atomicops.h                             \
+  google/protobuf/stubs/atomicops_internals_arm_gcc.h           \
+  google/protobuf/stubs/atomicops_internals_arm64_gcc.h         \
+  google/protobuf/stubs/atomicops_internals_arm_qnx.h           \
+  google/protobuf/stubs/atomicops_internals_atomicword_compat.h \
+  google/protobuf/stubs/atomicops_internals_generic_gcc.h       \
+  google/protobuf/stubs/atomicops_internals_macosx.h            \
+  google/protobuf/stubs/atomicops_internals_mips_gcc.h          \
+  google/protobuf/stubs/atomicops_internals_pnacl.h             \
+  google/protobuf/stubs/atomicops_internals_tsan.h              \
+  google/protobuf/stubs/atomicops_internals_x86_gcc.h           \
+  google/protobuf/stubs/atomicops_internals_x86_msvc.h          \
+  google/protobuf/stubs/common.h                                \
+  google/protobuf/stubs/platform_macros.h                       \
+  google/protobuf/stubs/once.h                                  \
+  google/protobuf/stubs/stl_util.h                              \
+  google/protobuf/stubs/template_util.h                         \
+  google/protobuf/stubs/type_traits.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_enum_reflection.h                   \
+  google/protobuf/generated_message_util.h                      \
+  google/protobuf/generated_message_reflection.h                \
+  google/protobuf/message.h                                     \
+  google/protobuf/message_lite.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_lite.h                            \
+  google/protobuf/wire_format_lite_inl.h                        \
+  google/protobuf/io/coded_stream.h                             \
+  $(GZHEADERS)                                                  \
+  google/protobuf/io/printer.h                                  \
+  google/protobuf/io/strtod.h                                   \
+  google/protobuf/io/tokenizer.h                                \
+  google/protobuf/io/zero_copy_stream.h                         \
+  google/protobuf/io/zero_copy_stream_impl.h                    \
+  google/protobuf/io/zero_copy_stream_impl_lite.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/plugin.h                             \
+  google/protobuf/compiler/plugin.pb.h                          \
+  google/protobuf/compiler/cpp/cpp_generator.h                  \
+  google/protobuf/compiler/java/java_generator.h                \
+  google/protobuf/compiler/javamicro/javamicro_generator.h      \
+  google/protobuf/compiler/javanano/javanano_generator.h        \
+  google/protobuf/compiler/python/python_generator.h
+
+lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
+libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS)
+libprotobuf_lite_la_LDFLAGS = -version-info 9:1:0 -export-dynamic -no-undefined
+libprotobuf_lite_la_SOURCES = \
+  google/protobuf/stubs/atomicops_internals_x86_gcc.cc         \
+  google/protobuf/stubs/atomicops_internals_x86_msvc.cc        \
+  google/protobuf/stubs/common.cc                              \
+  google/protobuf/stubs/once.cc                                \
+  google/protobuf/stubs/hash.h                                 \
+  google/protobuf/stubs/map_util.h                             \
+  google/protobuf/stubs/shared_ptr.h                           \
+  google/protobuf/stubs/stringprintf.cc                        \
+  google/protobuf/stubs/stringprintf.h                         \
+  google/protobuf/extension_set.cc                             \
+  google/protobuf/generated_message_util.cc                    \
+  google/protobuf/message_lite.cc                              \
+  google/protobuf/repeated_field.cc                            \
+  google/protobuf/wire_format_lite.cc                          \
+  google/protobuf/io/coded_stream.cc                           \
+  google/protobuf/io/coded_stream_inl.h                        \
+  google/protobuf/io/zero_copy_stream.cc                       \
+  google/protobuf/io/zero_copy_stream_impl_lite.cc
+
+libprotobuf_la_LIBADD = $(PTHREAD_LIBS)
+libprotobuf_la_LDFLAGS = -version-info 9:1:0 -export-dynamic -no-undefined
+libprotobuf_la_SOURCES = \
+  $(libprotobuf_lite_la_SOURCES)                               \
+  google/protobuf/stubs/strutil.cc                             \
+  google/protobuf/stubs/strutil.h                              \
+  google/protobuf/stubs/substitute.cc                          \
+  google/protobuf/stubs/substitute.h                           \
+  google/protobuf/stubs/structurally_valid.cc                  \
+  google/protobuf/descriptor.cc                                \
+  google/protobuf/descriptor.pb.cc                             \
+  google/protobuf/descriptor_database.cc                       \
+  google/protobuf/dynamic_message.cc                           \
+  google/protobuf/extension_set_heavy.cc                       \
+  google/protobuf/generated_message_reflection.cc              \
+  google/protobuf/message.cc                                   \
+  google/protobuf/reflection_ops.cc                            \
+  google/protobuf/service.cc                                   \
+  google/protobuf/text_format.cc                               \
+  google/protobuf/unknown_field_set.cc                         \
+  google/protobuf/wire_format.cc                               \
+  google/protobuf/io/gzip_stream.cc                            \
+  google/protobuf/io/printer.cc                                \
+  google/protobuf/io/strtod.cc                                 \
+  google/protobuf/io/tokenizer.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 9:1:0 -export-dynamic -no-undefined
+libprotoc_la_SOURCES = \
+  google/protobuf/compiler/code_generator.cc                   \
+  google/protobuf/compiler/command_line_interface.cc           \
+  google/protobuf/compiler/plugin.cc                           \
+  google/protobuf/compiler/plugin.pb.cc                        \
+  google/protobuf/compiler/subprocess.cc                       \
+  google/protobuf/compiler/subprocess.h                        \
+  google/protobuf/compiler/zip_writer.cc                       \
+  google/protobuf/compiler/zip_writer.h                        \
+  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_options.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_context.cc                \
+  google/protobuf/compiler/java/java_context.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_generator_factory.cc      \
+  google/protobuf/compiler/java/java_generator_factory.h       \
+  google/protobuf/compiler/java/java_helpers.cc                \
+  google/protobuf/compiler/java/java_helpers.h                 \
+  google/protobuf/compiler/java/java_lazy_message_field.cc     \
+  google/protobuf/compiler/java/java_lazy_message_field.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_name_resolver.cc          \
+  google/protobuf/compiler/java/java_name_resolver.h           \
+  google/protobuf/compiler/java/java_primitive_field.cc        \
+  google/protobuf/compiler/java/java_primitive_field.h         \
+  google/protobuf/compiler/java/java_shared_code_generator.cc  \
+  google/protobuf/compiler/java/java_shared_code_generator.h   \
+  google/protobuf/compiler/java/java_service.cc                \
+  google/protobuf/compiler/java/java_service.h                 \
+  google/protobuf/compiler/java/java_string_field.cc           \
+  google/protobuf/compiler/java/java_string_field.h            \
+  google/protobuf/compiler/java/java_doc_comment.cc            \
+  google/protobuf/compiler/java/java_doc_comment.h             \
+  google/protobuf/compiler/javamicro/javamicro_enum.cc         \
+  google/protobuf/compiler/javamicro/javamicro_enum.h          \
+  google/protobuf/compiler/javamicro/javamicro_enum_field.cc   \
+  google/protobuf/compiler/javamicro/javamicro_enum_field.h    \
+  google/protobuf/compiler/javamicro/javamicro_field.cc        \
+  google/protobuf/compiler/javamicro/javamicro_field.h         \
+  google/protobuf/compiler/javamicro/javamicro_file.cc         \
+  google/protobuf/compiler/javamicro/javamicro_file.h          \
+  google/protobuf/compiler/javamicro/javamicro_generator.cc    \
+  google/protobuf/compiler/javamicro/javamicro_helpers.cc      \
+  google/protobuf/compiler/javamicro/javamicro_helpers.h       \
+  google/protobuf/compiler/javamicro/javamicro_message.cc      \
+  google/protobuf/compiler/javamicro/javamicro_message.h       \
+  google/protobuf/compiler/javamicro/javamicro_message_field.cc\
+  google/protobuf/compiler/javamicro/javamicro_message_field.h \
+  google/protobuf/compiler/javamicro/javamicro_primitive_field.cc\
+  google/protobuf/compiler/javamicro/javamicro_primitive_field.h\
+  google/protobuf/compiler/javanano/javanano_enum.cc         \
+  google/protobuf/compiler/javanano/javanano_enum.h          \
+  google/protobuf/compiler/javanano/javanano_enum_field.cc   \
+  google/protobuf/compiler/javanano/javanano_enum_field.h    \
+  google/protobuf/compiler/javanano/javanano_extension.cc    \
+  google/protobuf/compiler/javanano/javanano_extension.h     \
+  google/protobuf/compiler/javanano/javanano_field.cc        \
+  google/protobuf/compiler/javanano/javanano_field.h         \
+  google/protobuf/compiler/javanano/javanano_file.cc         \
+  google/protobuf/compiler/javanano/javanano_file.h          \
+  google/protobuf/compiler/javanano/javanano_generator.cc    \
+  google/protobuf/compiler/javanano/javanano_helpers.cc      \
+  google/protobuf/compiler/javanano/javanano_helpers.h       \
+  google/protobuf/compiler/javanano/javanano_message.cc      \
+  google/protobuf/compiler/javanano/javanano_message.h       \
+  google/protobuf/compiler/javanano/javanano_message_field.cc\
+  google/protobuf/compiler/javanano/javanano_message_field.h \
+  google/protobuf/compiler/javanano/javanano_primitive_field.cc\
+  google/protobuf/compiler/javanano/javanano_primitive_field.h\
+  google/protobuf/compiler/python/python_generator.cc
+
+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_empty.proto                         \
+  google/protobuf/unittest_import.proto                        \
+  google/protobuf/unittest_import_public.proto                 \
+  google/protobuf/unittest_mset.proto                          \
+  google/protobuf/unittest_optimize_for.proto                  \
+  google/protobuf/unittest_embed_optimize_for.proto            \
+  google/protobuf/unittest_custom_options.proto                \
+  google/protobuf/unittest_lite.proto                          \
+  google/protobuf/unittest_import_lite.proto                   \
+  google/protobuf/unittest_import_public_lite.proto            \
+  google/protobuf/unittest_lite_imports_nonlite.proto          \
+  google/protobuf/unittest_no_generic_services.proto           \
+  google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
+
+EXTRA_DIST = \
+  $(protoc_inputs)                                             \
+  solaris/libstdc++.la                                         \
+  google/protobuf/io/gzip_stream.h                             \
+  google/protobuf/io/gzip_stream_unittest.sh                   \
+  google/protobuf/testdata/golden_message                      \
+  google/protobuf/testdata/golden_message_oneof_implemented    \
+  google/protobuf/testdata/golden_packed_fields_message        \
+  google/protobuf/testdata/bad_utf8_string                     \
+  google/protobuf/testdata/text_format_unittest_data.txt       \
+  google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt  \
+  google/protobuf/testdata/text_format_unittest_data_pointy.txt             \
+  google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt       \
+  google/protobuf/testdata/text_format_unittest_extensions_data.txt         \
+  google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt  \
+  google/protobuf/package_info.h                               \
+  google/protobuf/io/package_info.h                            \
+  google/protobuf/compiler/package_info.h                      \
+  google/protobuf/compiler/zip_output_unittest.sh              \
+  google/protobuf/unittest_enormous_descriptor.proto
+
+protoc_lite_outputs = \
+  google/protobuf/unittest_lite.pb.cc                          \
+  google/protobuf/unittest_lite.pb.h                           \
+  google/protobuf/unittest_import_lite.pb.cc                   \
+  google/protobuf/unittest_import_lite.pb.h                    \
+  google/protobuf/unittest_import_public_lite.pb.cc            \
+  google/protobuf/unittest_import_public_lite.pb.h
+
+protoc_outputs = \
+  $(protoc_lite_outputs)                                       \
+  google/protobuf/unittest.pb.cc                               \
+  google/protobuf/unittest.pb.h                                \
+  google/protobuf/unittest_empty.pb.cc                         \
+  google/protobuf/unittest_empty.pb.h                          \
+  google/protobuf/unittest_import.pb.cc                        \
+  google/protobuf/unittest_import.pb.h                         \
+  google/protobuf/unittest_import_public.pb.cc                 \
+  google/protobuf/unittest_import_public.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/unittest_custom_options.pb.cc                \
+  google/protobuf/unittest_custom_options.pb.h                 \
+  google/protobuf/unittest_lite_imports_nonlite.pb.cc          \
+  google/protobuf/unittest_lite_imports_nonlite.pb.h           \
+  google/protobuf/unittest_no_generic_services.pb.cc           \
+  google/protobuf/unittest_no_generic_services.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)
+COMMON_TEST_SOURCES = \
+  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
+
+protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \
+                      $(top_builddir)/gtest/lib/libgtest.la       \
+                      $(top_builddir)/gtest/lib/libgtest_main.la
+
+protobuf_test_CPPFLAGS = -I$(top_srcdir)/gtest/include         \
+                         -I$(top_builddir)/gtest/include
+
+# Disable optimization for tests unless the user explicitly asked for it,
+# since test_util.cc takes forever to compile with optimization (with GCC).
+# See configure.ac for more info.
+protobuf_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_test_SOURCES = \
+  google/protobuf/stubs/common_unittest.cc                     \
+  google/protobuf/stubs/once_unittest.cc                       \
+  google/protobuf/stubs/strutil_unittest.cc                    \
+  google/protobuf/stubs/structurally_valid_unittest.cc         \
+  google/protobuf/stubs/stringprintf_unittest.cc               \
+  google/protobuf/stubs/template_util_unittest.cc              \
+  google/protobuf/stubs/type_traits_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/repeated_field_reflection_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/mock_code_generator.cc              \
+  google/protobuf/compiler/mock_code_generator.h               \
+  google/protobuf/compiler/parser_unittest.cc                  \
+  google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc       \
+  google/protobuf/compiler/cpp/cpp_unittest.h                  \
+  google/protobuf/compiler/cpp/cpp_unittest.cc                 \
+  google/protobuf/compiler/cpp/cpp_plugin_unittest.cc          \
+  google/protobuf/compiler/java/java_plugin_unittest.cc        \
+  google/protobuf/compiler/java/java_doc_comment_unittest.cc   \
+  google/protobuf/compiler/python/python_plugin_unittest.cc    \
+  $(COMMON_TEST_SOURCES)
+
+nodist_protobuf_test_SOURCES = $(protoc_outputs)
+
+# Run cpp_unittest again with PROTOBUF_TEST_NO_DESCRIPTORS defined.
+protobuf_lazy_descriptor_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la \
+                      libprotoc.la                                   \
+                      $(top_builddir)/gtest/lib/libgtest.la          \
+                      $(top_builddir)/gtest/lib/libgtest_main.la
+
+protobuf_lazy_descriptor_test_CPPFLAGS = -I$(top_srcdir)/gtest/include    \
+                                         -I$(top_builddir)/gtest/include  \
+                                         -DPROTOBUF_TEST_NO_DESCRIPTORS
+
+protobuf_lazy_descriptor_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_lazy_descriptor_test_SOURCES = \
+  google/protobuf/compiler/cpp/cpp_unittest.cc                 \
+  $(COMMON_TEST_SOURCES)
+
+nodist_protobuf_lazy_descriptor_test_SOURCES = $(protoc_outputs)
+
+# Build lite_unittest separately, since it doesn't use gtest.
+protobuf_lite_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la
+protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_lite_test_SOURCES = \
+  google/protobuf/lite_unittest.cc                                     \
+  google/protobuf/test_util_lite.cc                                    \
+  google/protobuf/test_util_lite.h
+
+nodist_protobuf_lite_test_SOURCES = $(protoc_lite_outputs)
+
+# Test plugin binary.
+test_plugin_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \
+                    $(top_builddir)/gtest/lib/libgtest.la
+
+test_plugin_CPPFLAGS = -I$(top_srcdir)/gtest/include         \
+                       -I$(top_builddir)/gtest/include
+
+test_plugin_SOURCES = \
+  google/protobuf/compiler/mock_code_generator.cc              \
+  google/protobuf/testing/file.cc                              \
+  google/protobuf/testing/file.h                               \
+  google/protobuf/compiler/test_plugin.cc
+
+@HAVE_ZLIB_TRUE@zcgzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la
+@HAVE_ZLIB_TRUE@zcgzip_SOURCES = google/protobuf/testing/zcgzip.cc
+@HAVE_ZLIB_TRUE@zcgunzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la
+@HAVE_ZLIB_TRUE@zcgunzip_SOURCES = google/protobuf/testing/zcgunzip.cc
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+	}
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+	done
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+	@list='$(lib_LTLIBRARIES)'; \
+	locs=`for p in $$list; do echo $$p; done | \
+	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+	      sort -u`; \
+	test -z "$$locs" || { \
+	  echo rm -f $${locs}; \
+	  rm -f $${locs}; \
+	}
+google/protobuf/stubs/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/stubs
+	@: > google/protobuf/stubs/$(am__dirstamp)
+google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/stubs/$(DEPDIR)
+	@: > google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/atomicops_internals_x86_gcc.lo:  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/atomicops_internals_x86_msvc.lo:  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/common.lo:  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/once.lo: google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/stringprintf.lo:  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf
+	@: > google/protobuf/$(am__dirstamp)
+google/protobuf/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/$(DEPDIR)
+	@: > google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/extension_set.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/generated_message_util.lo:  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/message_lite.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/repeated_field.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/wire_format_lite.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/io
+	@: > google/protobuf/io/$(am__dirstamp)
+google/protobuf/io/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/io/$(DEPDIR)
+	@: > google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/coded_stream.lo:  \
+	google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/zero_copy_stream.lo:  \
+	google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/zero_copy_stream_impl_lite.lo:  \
+	google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+
+libprotobuf-lite.la: $(libprotobuf_lite_la_OBJECTS) $(libprotobuf_lite_la_DEPENDENCIES) $(EXTRA_libprotobuf_lite_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(libprotobuf_lite_la_LINK) -rpath $(libdir) $(libprotobuf_lite_la_OBJECTS) $(libprotobuf_lite_la_LIBADD) $(LIBS)
+google/protobuf/stubs/strutil.lo:  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/substitute.lo:  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/structurally_valid.lo:  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/descriptor.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/descriptor.pb.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/descriptor_database.lo:  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/dynamic_message.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/extension_set_heavy.lo:  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/generated_message_reflection.lo:  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/message.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/reflection_ops.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/service.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/text_format.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/unknown_field_set.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/wire_format.lo: google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/gzip_stream.lo: google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/printer.lo: google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/strtod.lo: google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/tokenizer.lo: google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/zero_copy_stream_impl.lo:  \
+	google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler
+	@: > google/protobuf/compiler/$(am__dirstamp)
+google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/$(DEPDIR)
+	@: > google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/importer.lo:  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/parser.lo:  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+
+libprotobuf.la: $(libprotobuf_la_OBJECTS) $(libprotobuf_la_DEPENDENCIES) $(EXTRA_libprotobuf_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(libprotobuf_la_LINK) -rpath $(libdir) $(libprotobuf_la_OBJECTS) $(libprotobuf_la_LIBADD) $(LIBS)
+google/protobuf/compiler/code_generator.lo:  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/command_line_interface.lo:  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/plugin.lo:  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/plugin.pb.lo:  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/subprocess.lo:  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/zip_writer.lo:  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/cpp
+	@: > google/protobuf/compiler/cpp/$(am__dirstamp)
+google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/cpp/$(DEPDIR)
+	@: > google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_enum.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_enum_field.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_extension.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_field.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_file.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_generator.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_helpers.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_message.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_message_field.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_primitive_field.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_service.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/cpp_string_field.lo:  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/java
+	@: > google/protobuf/compiler/java/$(am__dirstamp)
+google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/java/$(DEPDIR)
+	@: > google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_context.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_enum.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_enum_field.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_extension.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_field.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_file.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_generator.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_generator_factory.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_helpers.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_lazy_message_field.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_message.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_message_field.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_name_resolver.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_primitive_field.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_shared_code_generator.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_service.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_string_field.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/java_doc_comment.lo:  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/javamicro
+	@: > google/protobuf/compiler/javamicro/$(am__dirstamp)
+google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/javamicro/$(DEPDIR)
+	@: > google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_enum.lo:  \
+	google/protobuf/compiler/javamicro/$(am__dirstamp) \
+	google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_enum_field.lo:  \
+	google/protobuf/compiler/javamicro/$(am__dirstamp) \
+	google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_field.lo:  \
+	google/protobuf/compiler/javamicro/$(am__dirstamp) \
+	google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_file.lo:  \
+	google/protobuf/compiler/javamicro/$(am__dirstamp) \
+	google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_generator.lo:  \
+	google/protobuf/compiler/javamicro/$(am__dirstamp) \
+	google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_helpers.lo:  \
+	google/protobuf/compiler/javamicro/$(am__dirstamp) \
+	google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_message.lo:  \
+	google/protobuf/compiler/javamicro/$(am__dirstamp) \
+	google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_message_field.lo:  \
+	google/protobuf/compiler/javamicro/$(am__dirstamp) \
+	google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javamicro/javamicro_primitive_field.lo:  \
+	google/protobuf/compiler/javamicro/$(am__dirstamp) \
+	google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/javanano
+	@: > google/protobuf/compiler/javanano/$(am__dirstamp)
+google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/javanano/$(DEPDIR)
+	@: > google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_enum.lo:  \
+	google/protobuf/compiler/javanano/$(am__dirstamp) \
+	google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_enum_field.lo:  \
+	google/protobuf/compiler/javanano/$(am__dirstamp) \
+	google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_extension.lo:  \
+	google/protobuf/compiler/javanano/$(am__dirstamp) \
+	google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_field.lo:  \
+	google/protobuf/compiler/javanano/$(am__dirstamp) \
+	google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_file.lo:  \
+	google/protobuf/compiler/javanano/$(am__dirstamp) \
+	google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_generator.lo:  \
+	google/protobuf/compiler/javanano/$(am__dirstamp) \
+	google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_helpers.lo:  \
+	google/protobuf/compiler/javanano/$(am__dirstamp) \
+	google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_message.lo:  \
+	google/protobuf/compiler/javanano/$(am__dirstamp) \
+	google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_message_field.lo:  \
+	google/protobuf/compiler/javanano/$(am__dirstamp) \
+	google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/javanano/javanano_primitive_field.lo:  \
+	google/protobuf/compiler/javanano/$(am__dirstamp) \
+	google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/python/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/python
+	@: > google/protobuf/compiler/python/$(am__dirstamp)
+google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/compiler/python/$(DEPDIR)
+	@: > google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/python/python_generator.lo:  \
+	google/protobuf/compiler/python/$(am__dirstamp) \
+	google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp)
+
+libprotoc.la: $(libprotoc_la_OBJECTS) $(libprotoc_la_DEPENDENCIES) $(EXTRA_libprotoc_la_DEPENDENCIES) 
+	$(AM_V_CXXLD)$(libprotoc_la_LINK) -rpath $(libdir) $(libprotoc_la_OBJECTS) $(libprotoc_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p \
+	 || test -f $$p1 \
+	  ; then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' \
+	    -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' \
+	`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.$(OBJEXT):  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-test_util.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/testing
+	@: > google/protobuf/testing/$(am__dirstamp)
+google/protobuf/testing/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) google/protobuf/testing/$(DEPDIR)
+	@: > google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.$(OBJEXT):  \
+	google/protobuf/testing/$(am__dirstamp) \
+	google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/protobuf_lazy_descriptor_test-file.$(OBJEXT):  \
+	google/protobuf/testing/$(am__dirstamp) \
+	google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.$(OBJEXT):  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+
+protobuf-lazy-descriptor-test$(EXEEXT): $(protobuf_lazy_descriptor_test_OBJECTS) $(protobuf_lazy_descriptor_test_DEPENDENCIES) $(EXTRA_protobuf_lazy_descriptor_test_DEPENDENCIES) 
+	@rm -f protobuf-lazy-descriptor-test$(EXEEXT)
+	$(AM_V_CXXLD)$(protobuf_lazy_descriptor_test_LINK) $(protobuf_lazy_descriptor_test_OBJECTS) $(protobuf_lazy_descriptor_test_LDADD) $(LIBS)
+google/protobuf/protobuf_lite_test-lite_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lite_test-test_util_lite.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lite_test-unittest_lite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lite_test-unittest_import_lite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+
+protobuf-lite-test$(EXEEXT): $(protobuf_lite_test_OBJECTS) $(protobuf_lite_test_DEPENDENCIES) $(EXTRA_protobuf_lite_test_DEPENDENCIES) 
+	@rm -f protobuf-lite-test$(EXEEXT)
+	$(AM_V_CXXLD)$(protobuf_lite_test_LINK) $(protobuf_lite_test_OBJECTS) $(protobuf_lite_test_LDADD) $(LIBS)
+google/protobuf/stubs/protobuf_test-common_unittest.$(OBJEXT):  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-once_unittest.$(OBJEXT):  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-strutil_unittest.$(OBJEXT):  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-structurally_valid_unittest.$(OBJEXT):  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-stringprintf_unittest.$(OBJEXT):  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-template_util_unittest.$(OBJEXT):  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/stubs/protobuf_test-type_traits_unittest.$(OBJEXT):  \
+	google/protobuf/stubs/$(am__dirstamp) \
+	google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-descriptor_database_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-descriptor_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-dynamic_message_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-extension_set_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-generated_message_reflection_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-message_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-reflection_ops_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-repeated_field_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-repeated_field_reflection_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-text_format_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unknown_field_set_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-wire_format_unittest.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/protobuf_test-coded_stream_unittest.$(OBJEXT):  \
+	google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/protobuf_test-printer_unittest.$(OBJEXT):  \
+	google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/protobuf_test-tokenizer_unittest.$(OBJEXT):  \
+	google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/io/protobuf_test-zero_copy_stream_unittest.$(OBJEXT):  \
+	google/protobuf/io/$(am__dirstamp) \
+	google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/protobuf_test-command_line_interface_unittest.$(OBJEXT):  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/protobuf_test-importer_unittest.$(OBJEXT):  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/protobuf_test-mock_code_generator.$(OBJEXT):  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/protobuf_test-parser_unittest.$(OBJEXT):  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.$(OBJEXT):  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.$(OBJEXT):  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.$(OBJEXT):  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.$(OBJEXT):  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.$(OBJEXT):  \
+	google/protobuf/compiler/java/$(am__dirstamp) \
+	google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.$(OBJEXT):  \
+	google/protobuf/compiler/python/$(am__dirstamp) \
+	google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-test_util.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/protobuf_test-googletest.$(OBJEXT):  \
+	google/protobuf/testing/$(am__dirstamp) \
+	google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/protobuf_test-file.$(OBJEXT):  \
+	google/protobuf/testing/$(am__dirstamp) \
+	google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_lite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_import_lite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_import_public_lite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_empty.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_import.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_import_public.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_mset.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_optimize_for.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_custom_options.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/protobuf_test-unittest_no_generic_services.pb.$(OBJEXT):  \
+	google/protobuf/$(am__dirstamp) \
+	google/protobuf/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.$(OBJEXT):  \
+	google/protobuf/compiler/cpp/$(am__dirstamp) \
+	google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+
+protobuf-test$(EXEEXT): $(protobuf_test_OBJECTS) $(protobuf_test_DEPENDENCIES) $(EXTRA_protobuf_test_DEPENDENCIES) 
+	@rm -f protobuf-test$(EXEEXT)
+	$(AM_V_CXXLD)$(protobuf_test_LINK) $(protobuf_test_OBJECTS) $(protobuf_test_LDADD) $(LIBS)
+google/protobuf/compiler/main.$(OBJEXT):  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+
+protoc$(EXEEXT): $(protoc_OBJECTS) $(protoc_DEPENDENCIES) $(EXTRA_protoc_DEPENDENCIES) 
+	@rm -f protoc$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(protoc_OBJECTS) $(protoc_LDADD) $(LIBS)
+google/protobuf/compiler/test_plugin-mock_code_generator.$(OBJEXT):  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/testing/test_plugin-file.$(OBJEXT):  \
+	google/protobuf/testing/$(am__dirstamp) \
+	google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+google/protobuf/compiler/test_plugin-test_plugin.$(OBJEXT):  \
+	google/protobuf/compiler/$(am__dirstamp) \
+	google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+
+test_plugin$(EXEEXT): $(test_plugin_OBJECTS) $(test_plugin_DEPENDENCIES) $(EXTRA_test_plugin_DEPENDENCIES) 
+	@rm -f test_plugin$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(test_plugin_OBJECTS) $(test_plugin_LDADD) $(LIBS)
+google/protobuf/testing/zcgunzip.$(OBJEXT):  \
+	google/protobuf/testing/$(am__dirstamp) \
+	google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+
+zcgunzip$(EXEEXT): $(zcgunzip_OBJECTS) $(zcgunzip_DEPENDENCIES) $(EXTRA_zcgunzip_DEPENDENCIES) 
+	@rm -f zcgunzip$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(zcgunzip_OBJECTS) $(zcgunzip_LDADD) $(LIBS)
+google/protobuf/testing/zcgzip.$(OBJEXT):  \
+	google/protobuf/testing/$(am__dirstamp) \
+	google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+
+zcgzip$(EXEEXT): $(zcgzip_OBJECTS) $(zcgzip_DEPENDENCIES) $(EXTRA_zcgzip_DEPENDENCIES) 
+	@rm -f zcgzip$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(zcgzip_OBJECTS) $(zcgzip_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+	-rm -f google/protobuf/*.$(OBJEXT)
+	-rm -f google/protobuf/*.lo
+	-rm -f google/protobuf/compiler/*.$(OBJEXT)
+	-rm -f google/protobuf/compiler/*.lo
+	-rm -f google/protobuf/compiler/cpp/*.$(OBJEXT)
+	-rm -f google/protobuf/compiler/cpp/*.lo
+	-rm -f google/protobuf/compiler/java/*.$(OBJEXT)
+	-rm -f google/protobuf/compiler/java/*.lo
+	-rm -f google/protobuf/compiler/javamicro/*.$(OBJEXT)
+	-rm -f google/protobuf/compiler/javamicro/*.lo
+	-rm -f google/protobuf/compiler/javanano/*.$(OBJEXT)
+	-rm -f google/protobuf/compiler/javanano/*.lo
+	-rm -f google/protobuf/compiler/python/*.$(OBJEXT)
+	-rm -f google/protobuf/compiler/python/*.lo
+	-rm -f google/protobuf/io/*.$(OBJEXT)
+	-rm -f google/protobuf/io/*.lo
+	-rm -f google/protobuf/stubs/*.$(OBJEXT)
+	-rm -f google/protobuf/stubs/*.lo
+	-rm -f google/protobuf/testing/*.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/descriptor.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/descriptor.pb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/descriptor_database.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/dynamic_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/extension_set.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/extension_set_heavy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_reflection.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/generated_message_util.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/message_lite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-test_util.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/reflection_ops.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/repeated_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/service.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/text_format.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/unknown_field_set.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/wire_format.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/$(DEPDIR)/wire_format_lite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/code_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/command_line_interface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/importer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/plugin.pb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/subprocess.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/$(DEPDIR)/zip_writer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_enum_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_extension.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_helpers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_message_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_primitive_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_service.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/cpp_string_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_context.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_doc_comment.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_enum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_enum_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_extension.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_generator_factory.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_helpers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_lazy_message_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_message_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_name_resolver.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_primitive_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_service.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_shared_code_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/java_string_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_enum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_enum_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_helpers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_message_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javamicro/$(DEPDIR)/javamicro_primitive_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_enum.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_enum_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_extension.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_file.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_helpers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_message_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/javanano/$(DEPDIR)/javanano_primitive_field.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/compiler/python/$(DEPDIR)/python_generator.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/coded_stream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/gzip_stream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/printer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/strtod.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/tokenizer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/zero_copy_stream.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/zero_copy_stream_impl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/io/$(DEPDIR)/zero_copy_stream_impl_lite.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/atomicops_internals_x86_gcc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/atomicops_internals_x86_msvc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/once.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/stringprintf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/structurally_valid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/strutil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/stubs/$(DEPDIR)/substitute.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/test_plugin-file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/zcgunzip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@google/protobuf/testing/$(DEPDIR)/zcgzip.Po@am__quote@
+
+.cc.o:
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
+
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o: google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
+
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-test_util.o: google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-test_util.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/test_util.cc' object='google/protobuf/protobuf_lazy_descriptor_test-test_util.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-test_util.obj: google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-test_util.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-test_util.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/test_util.cc' object='google/protobuf/protobuf_lazy_descriptor_test-test_util.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
+
+google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.o: google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.o -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/testing/googletest.cc' object='google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
+
+google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.obj: google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.obj -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-googletest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/testing/googletest.cc' object='google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
+
+google/protobuf/testing/protobuf_lazy_descriptor_test-file.o: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_lazy_descriptor_test-file.o -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/protobuf_lazy_descriptor_test-file.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+
+google/protobuf/testing/protobuf_lazy_descriptor_test-file.obj: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_lazy_descriptor_test-file.obj -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_lazy_descriptor_test-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/protobuf_lazy_descriptor_test-file.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_lazy_descriptor_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.o: google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.obj: google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.o: google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_empty.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.obj: google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_empty.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_empty.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.o: google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.obj: google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.o: google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_public.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.obj: google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_import_public.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_public.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.o: google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_mset.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.obj: google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_mset.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_mset.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o: google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_optimize_for.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj: google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_optimize_for.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o: google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj: google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.o: google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_custom_options.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj: google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_custom_options.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_custom_options.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o: google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj: google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o: google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_no_generic_services.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
+
+google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj: google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_no_generic_services.pb.cc' object='google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lazy_descriptor_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
+
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+
+google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_lazy_descriptor_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_lazy_descriptor_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_lazy_descriptor_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
+
+google/protobuf/protobuf_lite_test-lite_unittest.o: google/protobuf/lite_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-lite_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo -c -o google/protobuf/protobuf_lite_test-lite_unittest.o `test -f 'google/protobuf/lite_unittest.cc' || echo '$(srcdir)/'`google/protobuf/lite_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/lite_unittest.cc' object='google/protobuf/protobuf_lite_test-lite_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-lite_unittest.o `test -f 'google/protobuf/lite_unittest.cc' || echo '$(srcdir)/'`google/protobuf/lite_unittest.cc
+
+google/protobuf/protobuf_lite_test-lite_unittest.obj: google/protobuf/lite_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-lite_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo -c -o google/protobuf/protobuf_lite_test-lite_unittest.obj `if test -f 'google/protobuf/lite_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/lite_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/lite_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-lite_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/lite_unittest.cc' object='google/protobuf/protobuf_lite_test-lite_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-lite_unittest.obj `if test -f 'google/protobuf/lite_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/lite_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/lite_unittest.cc'; fi`
+
+google/protobuf/protobuf_lite_test-test_util_lite.o: google/protobuf/test_util_lite.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-test_util_lite.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo -c -o google/protobuf/protobuf_lite_test-test_util_lite.o `test -f 'google/protobuf/test_util_lite.cc' || echo '$(srcdir)/'`google/protobuf/test_util_lite.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/test_util_lite.cc' object='google/protobuf/protobuf_lite_test-test_util_lite.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-test_util_lite.o `test -f 'google/protobuf/test_util_lite.cc' || echo '$(srcdir)/'`google/protobuf/test_util_lite.cc
+
+google/protobuf/protobuf_lite_test-test_util_lite.obj: google/protobuf/test_util_lite.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-test_util_lite.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo -c -o google/protobuf/protobuf_lite_test-test_util_lite.obj `if test -f 'google/protobuf/test_util_lite.cc'; then $(CYGPATH_W) 'google/protobuf/test_util_lite.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util_lite.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-test_util_lite.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/test_util_lite.cc' object='google/protobuf/protobuf_lite_test-test_util_lite.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-test_util_lite.obj `if test -f 'google/protobuf/test_util_lite.cc'; then $(CYGPATH_W) 'google/protobuf/test_util_lite.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util_lite.cc'; fi`
+
+google/protobuf/protobuf_lite_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+
+google/protobuf/protobuf_lite_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+
+google/protobuf/protobuf_lite_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_import_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+
+google/protobuf/protobuf_lite_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_import_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+
+google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
+
+google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_lite_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(protobuf_lite_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_lite_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
+
+google/protobuf/stubs/protobuf_test-common_unittest.o: google/protobuf/stubs/common_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-common_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-common_unittest.o `test -f 'google/protobuf/stubs/common_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/common_unittest.cc' object='google/protobuf/stubs/protobuf_test-common_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-common_unittest.o `test -f 'google/protobuf/stubs/common_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/common_unittest.cc
+
+google/protobuf/stubs/protobuf_test-common_unittest.obj: google/protobuf/stubs/common_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-common_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-common_unittest.obj `if test -f 'google/protobuf/stubs/common_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/common_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/common_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-common_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/common_unittest.cc' object='google/protobuf/stubs/protobuf_test-common_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-common_unittest.obj `if test -f 'google/protobuf/stubs/common_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/common_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/common_unittest.cc'; fi`
+
+google/protobuf/stubs/protobuf_test-once_unittest.o: google/protobuf/stubs/once_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-once_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-once_unittest.o `test -f 'google/protobuf/stubs/once_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/once_unittest.cc' object='google/protobuf/stubs/protobuf_test-once_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-once_unittest.o `test -f 'google/protobuf/stubs/once_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/once_unittest.cc
+
+google/protobuf/stubs/protobuf_test-once_unittest.obj: google/protobuf/stubs/once_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-once_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-once_unittest.obj `if test -f 'google/protobuf/stubs/once_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/once_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/once_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-once_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/once_unittest.cc' object='google/protobuf/stubs/protobuf_test-once_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-once_unittest.obj `if test -f 'google/protobuf/stubs/once_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/once_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/once_unittest.cc'; fi`
+
+google/protobuf/stubs/protobuf_test-strutil_unittest.o: google/protobuf/stubs/strutil_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-strutil_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-strutil_unittest.o `test -f 'google/protobuf/stubs/strutil_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/strutil_unittest.cc' object='google/protobuf/stubs/protobuf_test-strutil_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-strutil_unittest.o `test -f 'google/protobuf/stubs/strutil_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/strutil_unittest.cc
+
+google/protobuf/stubs/protobuf_test-strutil_unittest.obj: google/protobuf/stubs/strutil_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-strutil_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-strutil_unittest.obj `if test -f 'google/protobuf/stubs/strutil_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/strutil_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/strutil_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-strutil_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/strutil_unittest.cc' object='google/protobuf/stubs/protobuf_test-strutil_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-strutil_unittest.obj `if test -f 'google/protobuf/stubs/strutil_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/strutil_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/strutil_unittest.cc'; fi`
+
+google/protobuf/stubs/protobuf_test-structurally_valid_unittest.o: google/protobuf/stubs/structurally_valid_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-structurally_valid_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-structurally_valid_unittest.o `test -f 'google/protobuf/stubs/structurally_valid_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/structurally_valid_unittest.cc' object='google/protobuf/stubs/protobuf_test-structurally_valid_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-structurally_valid_unittest.o `test -f 'google/protobuf/stubs/structurally_valid_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/structurally_valid_unittest.cc
+
+google/protobuf/stubs/protobuf_test-structurally_valid_unittest.obj: google/protobuf/stubs/structurally_valid_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-structurally_valid_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-structurally_valid_unittest.obj `if test -f 'google/protobuf/stubs/structurally_valid_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/structurally_valid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/structurally_valid_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-structurally_valid_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/structurally_valid_unittest.cc' object='google/protobuf/stubs/protobuf_test-structurally_valid_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-structurally_valid_unittest.obj `if test -f 'google/protobuf/stubs/structurally_valid_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/structurally_valid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/structurally_valid_unittest.cc'; fi`
+
+google/protobuf/stubs/protobuf_test-stringprintf_unittest.o: google/protobuf/stubs/stringprintf_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-stringprintf_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-stringprintf_unittest.o `test -f 'google/protobuf/stubs/stringprintf_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/stringprintf_unittest.cc' object='google/protobuf/stubs/protobuf_test-stringprintf_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-stringprintf_unittest.o `test -f 'google/protobuf/stubs/stringprintf_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/stringprintf_unittest.cc
+
+google/protobuf/stubs/protobuf_test-stringprintf_unittest.obj: google/protobuf/stubs/stringprintf_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-stringprintf_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-stringprintf_unittest.obj `if test -f 'google/protobuf/stubs/stringprintf_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/stringprintf_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/stringprintf_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-stringprintf_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/stringprintf_unittest.cc' object='google/protobuf/stubs/protobuf_test-stringprintf_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-stringprintf_unittest.obj `if test -f 'google/protobuf/stubs/stringprintf_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/stringprintf_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/stringprintf_unittest.cc'; fi`
+
+google/protobuf/stubs/protobuf_test-template_util_unittest.o: google/protobuf/stubs/template_util_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-template_util_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-template_util_unittest.o `test -f 'google/protobuf/stubs/template_util_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/template_util_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/template_util_unittest.cc' object='google/protobuf/stubs/protobuf_test-template_util_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-template_util_unittest.o `test -f 'google/protobuf/stubs/template_util_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/template_util_unittest.cc
+
+google/protobuf/stubs/protobuf_test-template_util_unittest.obj: google/protobuf/stubs/template_util_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-template_util_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-template_util_unittest.obj `if test -f 'google/protobuf/stubs/template_util_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/template_util_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/template_util_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-template_util_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/template_util_unittest.cc' object='google/protobuf/stubs/protobuf_test-template_util_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-template_util_unittest.obj `if test -f 'google/protobuf/stubs/template_util_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/template_util_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/template_util_unittest.cc'; fi`
+
+google/protobuf/stubs/protobuf_test-type_traits_unittest.o: google/protobuf/stubs/type_traits_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-type_traits_unittest.o -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-type_traits_unittest.o `test -f 'google/protobuf/stubs/type_traits_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/type_traits_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/type_traits_unittest.cc' object='google/protobuf/stubs/protobuf_test-type_traits_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-type_traits_unittest.o `test -f 'google/protobuf/stubs/type_traits_unittest.cc' || echo '$(srcdir)/'`google/protobuf/stubs/type_traits_unittest.cc
+
+google/protobuf/stubs/protobuf_test-type_traits_unittest.obj: google/protobuf/stubs/type_traits_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/stubs/protobuf_test-type_traits_unittest.obj -MD -MP -MF google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Tpo -c -o google/protobuf/stubs/protobuf_test-type_traits_unittest.obj `if test -f 'google/protobuf/stubs/type_traits_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/type_traits_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/type_traits_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Tpo google/protobuf/stubs/$(DEPDIR)/protobuf_test-type_traits_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/stubs/type_traits_unittest.cc' object='google/protobuf/stubs/protobuf_test-type_traits_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/stubs/protobuf_test-type_traits_unittest.obj `if test -f 'google/protobuf/stubs/type_traits_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/stubs/type_traits_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/stubs/type_traits_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-descriptor_database_unittest.o: google/protobuf/descriptor_database_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-descriptor_database_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo -c -o google/protobuf/protobuf_test-descriptor_database_unittest.o `test -f 'google/protobuf/descriptor_database_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/descriptor_database_unittest.cc' object='google/protobuf/protobuf_test-descriptor_database_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-descriptor_database_unittest.o `test -f 'google/protobuf/descriptor_database_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_database_unittest.cc
+
+google/protobuf/protobuf_test-descriptor_database_unittest.obj: google/protobuf/descriptor_database_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-descriptor_database_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo -c -o google/protobuf/protobuf_test-descriptor_database_unittest.obj `if test -f 'google/protobuf/descriptor_database_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_database_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_database_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-descriptor_database_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/descriptor_database_unittest.cc' object='google/protobuf/protobuf_test-descriptor_database_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-descriptor_database_unittest.obj `if test -f 'google/protobuf/descriptor_database_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_database_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_database_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-descriptor_unittest.o: google/protobuf/descriptor_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-descriptor_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Tpo -c -o google/protobuf/protobuf_test-descriptor_unittest.o `test -f 'google/protobuf/descriptor_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/descriptor_unittest.cc' object='google/protobuf/protobuf_test-descriptor_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-descriptor_unittest.o `test -f 'google/protobuf/descriptor_unittest.cc' || echo '$(srcdir)/'`google/protobuf/descriptor_unittest.cc
+
+google/protobuf/protobuf_test-descriptor_unittest.obj: google/protobuf/descriptor_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-descriptor_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Tpo -c -o google/protobuf/protobuf_test-descriptor_unittest.obj `if test -f 'google/protobuf/descriptor_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-descriptor_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/descriptor_unittest.cc' object='google/protobuf/protobuf_test-descriptor_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-descriptor_unittest.obj `if test -f 'google/protobuf/descriptor_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/descriptor_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/descriptor_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-dynamic_message_unittest.o: google/protobuf/dynamic_message_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-dynamic_message_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo -c -o google/protobuf/protobuf_test-dynamic_message_unittest.o `test -f 'google/protobuf/dynamic_message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/dynamic_message_unittest.cc' object='google/protobuf/protobuf_test-dynamic_message_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-dynamic_message_unittest.o `test -f 'google/protobuf/dynamic_message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/dynamic_message_unittest.cc
+
+google/protobuf/protobuf_test-dynamic_message_unittest.obj: google/protobuf/dynamic_message_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-dynamic_message_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo -c -o google/protobuf/protobuf_test-dynamic_message_unittest.obj `if test -f 'google/protobuf/dynamic_message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/dynamic_message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/dynamic_message_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-dynamic_message_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/dynamic_message_unittest.cc' object='google/protobuf/protobuf_test-dynamic_message_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-dynamic_message_unittest.obj `if test -f 'google/protobuf/dynamic_message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/dynamic_message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/dynamic_message_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-extension_set_unittest.o: google/protobuf/extension_set_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-extension_set_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Tpo -c -o google/protobuf/protobuf_test-extension_set_unittest.o `test -f 'google/protobuf/extension_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/extension_set_unittest.cc' object='google/protobuf/protobuf_test-extension_set_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-extension_set_unittest.o `test -f 'google/protobuf/extension_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/extension_set_unittest.cc
+
+google/protobuf/protobuf_test-extension_set_unittest.obj: google/protobuf/extension_set_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-extension_set_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Tpo -c -o google/protobuf/protobuf_test-extension_set_unittest.obj `if test -f 'google/protobuf/extension_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/extension_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/extension_set_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-extension_set_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/extension_set_unittest.cc' object='google/protobuf/protobuf_test-extension_set_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-extension_set_unittest.obj `if test -f 'google/protobuf/extension_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/extension_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/extension_set_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-generated_message_reflection_unittest.o: google/protobuf/generated_message_reflection_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-generated_message_reflection_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo -c -o google/protobuf/protobuf_test-generated_message_reflection_unittest.o `test -f 'google/protobuf/generated_message_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/generated_message_reflection_unittest.cc' object='google/protobuf/protobuf_test-generated_message_reflection_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-generated_message_reflection_unittest.o `test -f 'google/protobuf/generated_message_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/generated_message_reflection_unittest.cc
+
+google/protobuf/protobuf_test-generated_message_reflection_unittest.obj: google/protobuf/generated_message_reflection_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-generated_message_reflection_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo -c -o google/protobuf/protobuf_test-generated_message_reflection_unittest.obj `if test -f 'google/protobuf/generated_message_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_reflection_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-generated_message_reflection_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/generated_message_reflection_unittest.cc' object='google/protobuf/protobuf_test-generated_message_reflection_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-generated_message_reflection_unittest.obj `if test -f 'google/protobuf/generated_message_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/generated_message_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/generated_message_reflection_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-message_unittest.o: google/protobuf/message_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-message_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Tpo -c -o google/protobuf/protobuf_test-message_unittest.o `test -f 'google/protobuf/message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/message_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/message_unittest.cc' object='google/protobuf/protobuf_test-message_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-message_unittest.o `test -f 'google/protobuf/message_unittest.cc' || echo '$(srcdir)/'`google/protobuf/message_unittest.cc
+
+google/protobuf/protobuf_test-message_unittest.obj: google/protobuf/message_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-message_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Tpo -c -o google/protobuf/protobuf_test-message_unittest.obj `if test -f 'google/protobuf/message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/message_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-message_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/message_unittest.cc' object='google/protobuf/protobuf_test-message_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-message_unittest.obj `if test -f 'google/protobuf/message_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/message_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-reflection_ops_unittest.o: google/protobuf/reflection_ops_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-reflection_ops_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo -c -o google/protobuf/protobuf_test-reflection_ops_unittest.o `test -f 'google/protobuf/reflection_ops_unittest.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/reflection_ops_unittest.cc' object='google/protobuf/protobuf_test-reflection_ops_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-reflection_ops_unittest.o `test -f 'google/protobuf/reflection_ops_unittest.cc' || echo '$(srcdir)/'`google/protobuf/reflection_ops_unittest.cc
+
+google/protobuf/protobuf_test-reflection_ops_unittest.obj: google/protobuf/reflection_ops_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-reflection_ops_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo -c -o google/protobuf/protobuf_test-reflection_ops_unittest.obj `if test -f 'google/protobuf/reflection_ops_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/reflection_ops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/reflection_ops_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-reflection_ops_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/reflection_ops_unittest.cc' object='google/protobuf/protobuf_test-reflection_ops_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-reflection_ops_unittest.obj `if test -f 'google/protobuf/reflection_ops_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/reflection_ops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/reflection_ops_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-repeated_field_unittest.o: google/protobuf/repeated_field_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-repeated_field_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo -c -o google/protobuf/protobuf_test-repeated_field_unittest.o `test -f 'google/protobuf/repeated_field_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/repeated_field_unittest.cc' object='google/protobuf/protobuf_test-repeated_field_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-repeated_field_unittest.o `test -f 'google/protobuf/repeated_field_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_unittest.cc
+
+google/protobuf/protobuf_test-repeated_field_unittest.obj: google/protobuf/repeated_field_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-repeated_field_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo -c -o google/protobuf/protobuf_test-repeated_field_unittest.obj `if test -f 'google/protobuf/repeated_field_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/repeated_field_unittest.cc' object='google/protobuf/protobuf_test-repeated_field_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-repeated_field_unittest.obj `if test -f 'google/protobuf/repeated_field_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-repeated_field_reflection_unittest.o: google/protobuf/repeated_field_reflection_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-repeated_field_reflection_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo -c -o google/protobuf/protobuf_test-repeated_field_reflection_unittest.o `test -f 'google/protobuf/repeated_field_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_reflection_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/repeated_field_reflection_unittest.cc' object='google/protobuf/protobuf_test-repeated_field_reflection_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-repeated_field_reflection_unittest.o `test -f 'google/protobuf/repeated_field_reflection_unittest.cc' || echo '$(srcdir)/'`google/protobuf/repeated_field_reflection_unittest.cc
+
+google/protobuf/protobuf_test-repeated_field_reflection_unittest.obj: google/protobuf/repeated_field_reflection_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-repeated_field_reflection_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo -c -o google/protobuf/protobuf_test-repeated_field_reflection_unittest.obj `if test -f 'google/protobuf/repeated_field_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_reflection_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-repeated_field_reflection_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/repeated_field_reflection_unittest.cc' object='google/protobuf/protobuf_test-repeated_field_reflection_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-repeated_field_reflection_unittest.obj `if test -f 'google/protobuf/repeated_field_reflection_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/repeated_field_reflection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/repeated_field_reflection_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-text_format_unittest.o: google/protobuf/text_format_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-text_format_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Tpo -c -o google/protobuf/protobuf_test-text_format_unittest.o `test -f 'google/protobuf/text_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/text_format_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/text_format_unittest.cc' object='google/protobuf/protobuf_test-text_format_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-text_format_unittest.o `test -f 'google/protobuf/text_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/text_format_unittest.cc
+
+google/protobuf/protobuf_test-text_format_unittest.obj: google/protobuf/text_format_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-text_format_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Tpo -c -o google/protobuf/protobuf_test-text_format_unittest.obj `if test -f 'google/protobuf/text_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/text_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/text_format_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-text_format_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/text_format_unittest.cc' object='google/protobuf/protobuf_test-text_format_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-text_format_unittest.obj `if test -f 'google/protobuf/text_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/text_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/text_format_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-unknown_field_set_unittest.o: google/protobuf/unknown_field_set_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unknown_field_set_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo -c -o google/protobuf/protobuf_test-unknown_field_set_unittest.o `test -f 'google/protobuf/unknown_field_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unknown_field_set_unittest.cc' object='google/protobuf/protobuf_test-unknown_field_set_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unknown_field_set_unittest.o `test -f 'google/protobuf/unknown_field_set_unittest.cc' || echo '$(srcdir)/'`google/protobuf/unknown_field_set_unittest.cc
+
+google/protobuf/protobuf_test-unknown_field_set_unittest.obj: google/protobuf/unknown_field_set_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unknown_field_set_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo -c -o google/protobuf/protobuf_test-unknown_field_set_unittest.obj `if test -f 'google/protobuf/unknown_field_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/unknown_field_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unknown_field_set_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unknown_field_set_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unknown_field_set_unittest.cc' object='google/protobuf/protobuf_test-unknown_field_set_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unknown_field_set_unittest.obj `if test -f 'google/protobuf/unknown_field_set_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/unknown_field_set_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unknown_field_set_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-wire_format_unittest.o: google/protobuf/wire_format_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-wire_format_unittest.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Tpo -c -o google/protobuf/protobuf_test-wire_format_unittest.o `test -f 'google/protobuf/wire_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/wire_format_unittest.cc' object='google/protobuf/protobuf_test-wire_format_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-wire_format_unittest.o `test -f 'google/protobuf/wire_format_unittest.cc' || echo '$(srcdir)/'`google/protobuf/wire_format_unittest.cc
+
+google/protobuf/protobuf_test-wire_format_unittest.obj: google/protobuf/wire_format_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-wire_format_unittest.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Tpo -c -o google/protobuf/protobuf_test-wire_format_unittest.obj `if test -f 'google/protobuf/wire_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/wire_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/wire_format_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Tpo google/protobuf/$(DEPDIR)/protobuf_test-wire_format_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/wire_format_unittest.cc' object='google/protobuf/protobuf_test-wire_format_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-wire_format_unittest.obj `if test -f 'google/protobuf/wire_format_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/wire_format_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/wire_format_unittest.cc'; fi`
+
+google/protobuf/io/protobuf_test-coded_stream_unittest.o: google/protobuf/io/coded_stream_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-coded_stream_unittest.o -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo -c -o google/protobuf/io/protobuf_test-coded_stream_unittest.o `test -f 'google/protobuf/io/coded_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/io/coded_stream_unittest.cc' object='google/protobuf/io/protobuf_test-coded_stream_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-coded_stream_unittest.o `test -f 'google/protobuf/io/coded_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/coded_stream_unittest.cc
+
+google/protobuf/io/protobuf_test-coded_stream_unittest.obj: google/protobuf/io/coded_stream_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-coded_stream_unittest.obj -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo -c -o google/protobuf/io/protobuf_test-coded_stream_unittest.obj `if test -f 'google/protobuf/io/coded_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/coded_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/coded_stream_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-coded_stream_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/io/coded_stream_unittest.cc' object='google/protobuf/io/protobuf_test-coded_stream_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-coded_stream_unittest.obj `if test -f 'google/protobuf/io/coded_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/coded_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/coded_stream_unittest.cc'; fi`
+
+google/protobuf/io/protobuf_test-printer_unittest.o: google/protobuf/io/printer_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-printer_unittest.o -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Tpo -c -o google/protobuf/io/protobuf_test-printer_unittest.o `test -f 'google/protobuf/io/printer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/printer_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/io/printer_unittest.cc' object='google/protobuf/io/protobuf_test-printer_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-printer_unittest.o `test -f 'google/protobuf/io/printer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/printer_unittest.cc
+
+google/protobuf/io/protobuf_test-printer_unittest.obj: google/protobuf/io/printer_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-printer_unittest.obj -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Tpo -c -o google/protobuf/io/protobuf_test-printer_unittest.obj `if test -f 'google/protobuf/io/printer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/printer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/printer_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-printer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/io/printer_unittest.cc' object='google/protobuf/io/protobuf_test-printer_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-printer_unittest.obj `if test -f 'google/protobuf/io/printer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/printer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/printer_unittest.cc'; fi`
+
+google/protobuf/io/protobuf_test-tokenizer_unittest.o: google/protobuf/io/tokenizer_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-tokenizer_unittest.o -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo -c -o google/protobuf/io/protobuf_test-tokenizer_unittest.o `test -f 'google/protobuf/io/tokenizer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/io/tokenizer_unittest.cc' object='google/protobuf/io/protobuf_test-tokenizer_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-tokenizer_unittest.o `test -f 'google/protobuf/io/tokenizer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/tokenizer_unittest.cc
+
+google/protobuf/io/protobuf_test-tokenizer_unittest.obj: google/protobuf/io/tokenizer_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-tokenizer_unittest.obj -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo -c -o google/protobuf/io/protobuf_test-tokenizer_unittest.obj `if test -f 'google/protobuf/io/tokenizer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/tokenizer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/tokenizer_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-tokenizer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/io/tokenizer_unittest.cc' object='google/protobuf/io/protobuf_test-tokenizer_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-tokenizer_unittest.obj `if test -f 'google/protobuf/io/tokenizer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/tokenizer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/tokenizer_unittest.cc'; fi`
+
+google/protobuf/io/protobuf_test-zero_copy_stream_unittest.o: google/protobuf/io/zero_copy_stream_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-zero_copy_stream_unittest.o -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo -c -o google/protobuf/io/protobuf_test-zero_copy_stream_unittest.o `test -f 'google/protobuf/io/zero_copy_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/io/zero_copy_stream_unittest.cc' object='google/protobuf/io/protobuf_test-zero_copy_stream_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-zero_copy_stream_unittest.o `test -f 'google/protobuf/io/zero_copy_stream_unittest.cc' || echo '$(srcdir)/'`google/protobuf/io/zero_copy_stream_unittest.cc
+
+google/protobuf/io/protobuf_test-zero_copy_stream_unittest.obj: google/protobuf/io/zero_copy_stream_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/io/protobuf_test-zero_copy_stream_unittest.obj -MD -MP -MF google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo -c -o google/protobuf/io/protobuf_test-zero_copy_stream_unittest.obj `if test -f 'google/protobuf/io/zero_copy_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/zero_copy_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/zero_copy_stream_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Tpo google/protobuf/io/$(DEPDIR)/protobuf_test-zero_copy_stream_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/io/zero_copy_stream_unittest.cc' object='google/protobuf/io/protobuf_test-zero_copy_stream_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/io/protobuf_test-zero_copy_stream_unittest.obj `if test -f 'google/protobuf/io/zero_copy_stream_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/io/zero_copy_stream_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/io/zero_copy_stream_unittest.cc'; fi`
+
+google/protobuf/compiler/protobuf_test-command_line_interface_unittest.o: google/protobuf/compiler/command_line_interface_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-command_line_interface_unittest.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-command_line_interface_unittest.o `test -f 'google/protobuf/compiler/command_line_interface_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/command_line_interface_unittest.cc' object='google/protobuf/compiler/protobuf_test-command_line_interface_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-command_line_interface_unittest.o `test -f 'google/protobuf/compiler/command_line_interface_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/command_line_interface_unittest.cc
+
+google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj: google/protobuf/compiler/command_line_interface_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj `if test -f 'google/protobuf/compiler/command_line_interface_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/command_line_interface_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/command_line_interface_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-command_line_interface_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/command_line_interface_unittest.cc' object='google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-command_line_interface_unittest.obj `if test -f 'google/protobuf/compiler/command_line_interface_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/command_line_interface_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/command_line_interface_unittest.cc'; fi`
+
+google/protobuf/compiler/protobuf_test-importer_unittest.o: google/protobuf/compiler/importer_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-importer_unittest.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-importer_unittest.o `test -f 'google/protobuf/compiler/importer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/importer_unittest.cc' object='google/protobuf/compiler/protobuf_test-importer_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-importer_unittest.o `test -f 'google/protobuf/compiler/importer_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/importer_unittest.cc
+
+google/protobuf/compiler/protobuf_test-importer_unittest.obj: google/protobuf/compiler/importer_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-importer_unittest.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-importer_unittest.obj `if test -f 'google/protobuf/compiler/importer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/importer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/importer_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-importer_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/importer_unittest.cc' object='google/protobuf/compiler/protobuf_test-importer_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-importer_unittest.obj `if test -f 'google/protobuf/compiler/importer_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/importer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/importer_unittest.cc'; fi`
+
+google/protobuf/compiler/protobuf_test-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-mock_code_generator.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o google/protobuf/compiler/protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/mock_code_generator.cc' object='google/protobuf/compiler/protobuf_test-mock_code_generator.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
+
+google/protobuf/compiler/protobuf_test-mock_code_generator.obj: google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-mock_code_generator.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Tpo -c -o google/protobuf/compiler/protobuf_test-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-mock_code_generator.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/mock_code_generator.cc' object='google/protobuf/compiler/protobuf_test-mock_code_generator.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
+
+google/protobuf/compiler/protobuf_test-parser_unittest.o: google/protobuf/compiler/parser_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-parser_unittest.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-parser_unittest.o `test -f 'google/protobuf/compiler/parser_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/parser_unittest.cc' object='google/protobuf/compiler/protobuf_test-parser_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-parser_unittest.o `test -f 'google/protobuf/compiler/parser_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/parser_unittest.cc
+
+google/protobuf/compiler/protobuf_test-parser_unittest.obj: google/protobuf/compiler/parser_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/protobuf_test-parser_unittest.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Tpo -c -o google/protobuf/compiler/protobuf_test-parser_unittest.obj `if test -f 'google/protobuf/compiler/parser_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/parser_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/parser_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Tpo google/protobuf/compiler/$(DEPDIR)/protobuf_test-parser_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/parser_unittest.cc' object='google/protobuf/compiler/protobuf_test-parser_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/protobuf_test-parser_unittest.obj `if test -f 'google/protobuf/compiler/parser_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/parser_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/parser_unittest.cc'; fi`
+
+google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o: google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+
+google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj: google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_bootstrap_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_bootstrap_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc'; fi`
+
+google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o: google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_unittest.cc
+
+google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj: google/protobuf/compiler/cpp/cpp_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_unittest.cc'; fi`
+
+google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.o `test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+
+google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj: google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_plugin_unittest.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_plugin_unittest.obj `if test -f 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc'; fi`
+
+google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o: google/protobuf/compiler/java/java_plugin_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.o `test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_plugin_unittest.cc
+
+google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj: google/protobuf/compiler/java/java_plugin_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/java/java_plugin_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_plugin_unittest.obj `if test -f 'google/protobuf/compiler/java/java_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_plugin_unittest.cc'; fi`
+
+google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o: google/protobuf/compiler/java/java_doc_comment_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/java/java_doc_comment_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.o `test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/java/java_doc_comment_unittest.cc
+
+google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj: google/protobuf/compiler/java/java_doc_comment_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj -MD -MP -MF google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_doc_comment_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Tpo google/protobuf/compiler/java/$(DEPDIR)/protobuf_test-java_doc_comment_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/java/java_doc_comment_unittest.cc' object='google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/java/protobuf_test-java_doc_comment_unittest.obj `if test -f 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/java/java_doc_comment_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/java/java_doc_comment_unittest.cc'; fi`
+
+google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o: google/protobuf/compiler/python/python_plugin_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o -MD -MP -MF google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.o `test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc' || echo '$(srcdir)/'`google/protobuf/compiler/python/python_plugin_unittest.cc
+
+google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj: google/protobuf/compiler/python/python_plugin_unittest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj -MD -MP -MF google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Tpo google/protobuf/compiler/python/$(DEPDIR)/protobuf_test-python_plugin_unittest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/python/python_plugin_unittest.cc' object='google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/python/protobuf_test-python_plugin_unittest.obj `if test -f 'google/protobuf/compiler/python/python_plugin_unittest.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/python/python_plugin_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/python/python_plugin_unittest.cc'; fi`
+
+google/protobuf/protobuf_test-test_util.o: google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-test_util.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-test_util.Tpo -c -o google/protobuf/protobuf_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-test_util.Tpo google/protobuf/$(DEPDIR)/protobuf_test-test_util.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/test_util.cc' object='google/protobuf/protobuf_test-test_util.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-test_util.o `test -f 'google/protobuf/test_util.cc' || echo '$(srcdir)/'`google/protobuf/test_util.cc
+
+google/protobuf/protobuf_test-test_util.obj: google/protobuf/test_util.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-test_util.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-test_util.Tpo -c -o google/protobuf/protobuf_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-test_util.Tpo google/protobuf/$(DEPDIR)/protobuf_test-test_util.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/test_util.cc' object='google/protobuf/protobuf_test-test_util.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-test_util.obj `if test -f 'google/protobuf/test_util.cc'; then $(CYGPATH_W) 'google/protobuf/test_util.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/test_util.cc'; fi`
+
+google/protobuf/testing/protobuf_test-googletest.o: google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_test-googletest.o -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Tpo -c -o google/protobuf/testing/protobuf_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/testing/googletest.cc' object='google/protobuf/testing/protobuf_test-googletest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_test-googletest.o `test -f 'google/protobuf/testing/googletest.cc' || echo '$(srcdir)/'`google/protobuf/testing/googletest.cc
+
+google/protobuf/testing/protobuf_test-googletest.obj: google/protobuf/testing/googletest.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_test-googletest.obj -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Tpo -c -o google/protobuf/testing/protobuf_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_test-googletest.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/testing/googletest.cc' object='google/protobuf/testing/protobuf_test-googletest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_test-googletest.obj `if test -f 'google/protobuf/testing/googletest.cc'; then $(CYGPATH_W) 'google/protobuf/testing/googletest.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/googletest.cc'; fi`
+
+google/protobuf/testing/protobuf_test-file.o: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_test-file.o -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Tpo -c -o google/protobuf/testing/protobuf_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/protobuf_test-file.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_test-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+
+google/protobuf/testing/protobuf_test-file.obj: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/protobuf_test-file.obj -MD -MP -MF google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Tpo -c -o google/protobuf/testing/protobuf_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Tpo google/protobuf/testing/$(DEPDIR)/protobuf_test-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/protobuf_test-file.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/protobuf_test-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_lite.pb.o: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_lite.pb.o `test -f 'google/protobuf/unittest_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite.pb.cc
+
+google/protobuf/protobuf_test-unittest_lite.pb.obj: google/protobuf/unittest_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_lite.pb.obj `if test -f 'google/protobuf/unittest_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_import_lite.pb.o: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_import_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_lite.pb.o `test -f 'google/protobuf/unittest_import_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_lite.pb.cc
+
+google/protobuf/protobuf_test-unittest_import_lite.pb.obj: google/protobuf/unittest_import_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_import_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_lite.pb.obj `if test -f 'google/protobuf/unittest_import_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_lite.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_import_public_lite.pb.o: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_public_lite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_import_public_lite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_public_lite.pb.o `test -f 'google/protobuf/unittest_import_public_lite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public_lite.pb.cc
+
+google/protobuf/protobuf_test-unittest_import_public_lite.pb.obj: google/protobuf/unittest_import_public_lite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_public_lite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public_lite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_public_lite.pb.cc' object='google/protobuf/protobuf_test-unittest_import_public_lite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_public_lite.pb.obj `if test -f 'google/protobuf/unittest_import_public_lite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public_lite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public_lite.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest.pb.o: google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Tpo -c -o google/protobuf/protobuf_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest.pb.cc' object='google/protobuf/protobuf_test-unittest.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest.pb.o `test -f 'google/protobuf/unittest.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest.pb.cc
+
+google/protobuf/protobuf_test-unittest.pb.obj: google/protobuf/unittest.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Tpo -c -o google/protobuf/protobuf_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest.pb.cc' object='google/protobuf/protobuf_test-unittest.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest.pb.obj `if test -f 'google/protobuf/unittest.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_empty.pb.o: google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_empty.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_empty.pb.cc' object='google/protobuf/protobuf_test-unittest_empty.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_empty.pb.o `test -f 'google/protobuf/unittest_empty.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_empty.pb.cc
+
+google/protobuf/protobuf_test-unittest_empty.pb.obj: google/protobuf/unittest_empty.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_empty.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_empty.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_empty.pb.cc' object='google/protobuf/protobuf_test-unittest_empty.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_empty.pb.obj `if test -f 'google/protobuf/unittest_empty.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_empty.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_empty.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_import.pb.o: google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import.pb.cc' object='google/protobuf/protobuf_test-unittest_import.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import.pb.o `test -f 'google/protobuf/unittest_import.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import.pb.cc
+
+google/protobuf/protobuf_test-unittest_import.pb.obj: google/protobuf/unittest_import.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import.pb.cc' object='google/protobuf/protobuf_test-unittest_import.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import.pb.obj `if test -f 'google/protobuf/unittest_import.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_import_public.pb.o: google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_public.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_public.pb.cc' object='google/protobuf/protobuf_test-unittest_import_public.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_public.pb.o `test -f 'google/protobuf/unittest_import_public.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_import_public.pb.cc
+
+google/protobuf/protobuf_test-unittest_import_public.pb.obj: google/protobuf/unittest_import_public.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_import_public.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_import_public.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_import_public.pb.cc' object='google/protobuf/protobuf_test-unittest_import_public.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_import_public.pb.obj `if test -f 'google/protobuf/unittest_import_public.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_import_public.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_import_public.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_mset.pb.o: google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_mset.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_mset.pb.cc' object='google/protobuf/protobuf_test-unittest_mset.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_mset.pb.o `test -f 'google/protobuf/unittest_mset.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_mset.pb.cc
+
+google/protobuf/protobuf_test-unittest_mset.pb.obj: google/protobuf/unittest_mset.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_mset.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_mset.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_mset.pb.cc' object='google/protobuf/protobuf_test-unittest_mset.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_mset.pb.obj `if test -f 'google/protobuf/unittest_mset.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_mset.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_mset.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_optimize_for.pb.o: google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_optimize_for.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_optimize_for.pb.cc' object='google/protobuf/protobuf_test-unittest_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_optimize_for.pb.o `test -f 'google/protobuf/unittest_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_optimize_for.pb.cc
+
+google/protobuf/protobuf_test-unittest_optimize_for.pb.obj: google/protobuf/unittest_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_optimize_for.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_optimize_for.pb.cc' object='google/protobuf/protobuf_test-unittest_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_optimize_for.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.o: google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.o `test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_embed_optimize_for.pb.cc
+
+google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.obj: google/protobuf/unittest_embed_optimize_for.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_embed_optimize_for.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_embed_optimize_for.pb.cc' object='google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_embed_optimize_for.pb.obj `if test -f 'google/protobuf/unittest_embed_optimize_for.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_embed_optimize_for.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_embed_optimize_for.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_custom_options.pb.o: google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_custom_options.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_custom_options.pb.cc' object='google/protobuf/protobuf_test-unittest_custom_options.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_custom_options.pb.o `test -f 'google/protobuf/unittest_custom_options.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_custom_options.pb.cc
+
+google/protobuf/protobuf_test-unittest_custom_options.pb.obj: google/protobuf/unittest_custom_options.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_custom_options.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_custom_options.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_custom_options.pb.cc' object='google/protobuf/protobuf_test-unittest_custom_options.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_custom_options.pb.obj `if test -f 'google/protobuf/unittest_custom_options.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_custom_options.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_custom_options.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.o: google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.o `test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_lite_imports_nonlite.pb.cc
+
+google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.obj: google/protobuf/unittest_lite_imports_nonlite.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_lite_imports_nonlite.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_lite_imports_nonlite.pb.cc' object='google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_lite_imports_nonlite.pb.obj `if test -f 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_lite_imports_nonlite.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_lite_imports_nonlite.pb.cc'; fi`
+
+google/protobuf/protobuf_test-unittest_no_generic_services.pb.o: google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_no_generic_services.pb.o -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_no_generic_services.pb.cc' object='google/protobuf/protobuf_test-unittest_no_generic_services.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_no_generic_services.pb.o `test -f 'google/protobuf/unittest_no_generic_services.pb.cc' || echo '$(srcdir)/'`google/protobuf/unittest_no_generic_services.pb.cc
+
+google/protobuf/protobuf_test-unittest_no_generic_services.pb.obj: google/protobuf/unittest_no_generic_services.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/protobuf_test-unittest_no_generic_services.pb.obj -MD -MP -MF google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo -c -o google/protobuf/protobuf_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Tpo google/protobuf/$(DEPDIR)/protobuf_test-unittest_no_generic_services.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/unittest_no_generic_services.pb.cc' object='google/protobuf/protobuf_test-unittest_no_generic_services.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/protobuf_test-unittest_no_generic_services.pb.obj `if test -f 'google/protobuf/unittest_no_generic_services.pb.cc'; then $(CYGPATH_W) 'google/protobuf/unittest_no_generic_services.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/unittest_no_generic_services.pb.cc'; fi`
+
+google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.o `test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' || echo '$(srcdir)/'`google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+
+google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj: google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj -MD -MP -MF google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Tpo google/protobuf/compiler/cpp/$(DEPDIR)/protobuf_test-cpp_test_bad_identifiers.pb.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc' object='google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(protobuf_test_CPPFLAGS) $(CPPFLAGS) $(protobuf_test_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/cpp/protobuf_test-cpp_test_bad_identifiers.pb.obj `if test -f 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc'; fi`
+
+google/protobuf/compiler/test_plugin-mock_code_generator.o: google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/test_plugin-mock_code_generator.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Tpo -c -o google/protobuf/compiler/test_plugin-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Tpo google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/mock_code_generator.cc' object='google/protobuf/compiler/test_plugin-mock_code_generator.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/test_plugin-mock_code_generator.o `test -f 'google/protobuf/compiler/mock_code_generator.cc' || echo '$(srcdir)/'`google/protobuf/compiler/mock_code_generator.cc
+
+google/protobuf/compiler/test_plugin-mock_code_generator.obj: google/protobuf/compiler/mock_code_generator.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/test_plugin-mock_code_generator.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Tpo -c -o google/protobuf/compiler/test_plugin-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Tpo google/protobuf/compiler/$(DEPDIR)/test_plugin-mock_code_generator.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/mock_code_generator.cc' object='google/protobuf/compiler/test_plugin-mock_code_generator.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/test_plugin-mock_code_generator.obj `if test -f 'google/protobuf/compiler/mock_code_generator.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/mock_code_generator.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/mock_code_generator.cc'; fi`
+
+google/protobuf/testing/test_plugin-file.o: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/test_plugin-file.o -MD -MP -MF google/protobuf/testing/$(DEPDIR)/test_plugin-file.Tpo -c -o google/protobuf/testing/test_plugin-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/test_plugin-file.Tpo google/protobuf/testing/$(DEPDIR)/test_plugin-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/test_plugin-file.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/test_plugin-file.o `test -f 'google/protobuf/testing/file.cc' || echo '$(srcdir)/'`google/protobuf/testing/file.cc
+
+google/protobuf/testing/test_plugin-file.obj: google/protobuf/testing/file.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/testing/test_plugin-file.obj -MD -MP -MF google/protobuf/testing/$(DEPDIR)/test_plugin-file.Tpo -c -o google/protobuf/testing/test_plugin-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/testing/$(DEPDIR)/test_plugin-file.Tpo google/protobuf/testing/$(DEPDIR)/test_plugin-file.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/testing/file.cc' object='google/protobuf/testing/test_plugin-file.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/testing/test_plugin-file.obj `if test -f 'google/protobuf/testing/file.cc'; then $(CYGPATH_W) 'google/protobuf/testing/file.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/testing/file.cc'; fi`
+
+google/protobuf/compiler/test_plugin-test_plugin.o: google/protobuf/compiler/test_plugin.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/test_plugin-test_plugin.o -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Tpo -c -o google/protobuf/compiler/test_plugin-test_plugin.o `test -f 'google/protobuf/compiler/test_plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/test_plugin.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Tpo google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/test_plugin.cc' object='google/protobuf/compiler/test_plugin-test_plugin.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/test_plugin-test_plugin.o `test -f 'google/protobuf/compiler/test_plugin.cc' || echo '$(srcdir)/'`google/protobuf/compiler/test_plugin.cc
+
+google/protobuf/compiler/test_plugin-test_plugin.obj: google/protobuf/compiler/test_plugin.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT google/protobuf/compiler/test_plugin-test_plugin.obj -MD -MP -MF google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Tpo -c -o google/protobuf/compiler/test_plugin-test_plugin.obj `if test -f 'google/protobuf/compiler/test_plugin.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/test_plugin.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/test_plugin.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Tpo google/protobuf/compiler/$(DEPDIR)/test_plugin-test_plugin.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='google/protobuf/compiler/test_plugin.cc' object='google/protobuf/compiler/test_plugin-test_plugin.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_plugin_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o google/protobuf/compiler/test_plugin-test_plugin.obj `if test -f 'google/protobuf/compiler/test_plugin.cc'; then $(CYGPATH_W) 'google/protobuf/compiler/test_plugin.cc'; else $(CYGPATH_W) '$(srcdir)/google/protobuf/compiler/test_plugin.cc'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+	-rm -rf google/protobuf/.libs google/protobuf/_libs
+	-rm -rf google/protobuf/compiler/.libs google/protobuf/compiler/_libs
+	-rm -rf google/protobuf/compiler/cpp/.libs google/protobuf/compiler/cpp/_libs
+	-rm -rf google/protobuf/compiler/java/.libs google/protobuf/compiler/java/_libs
+	-rm -rf google/protobuf/compiler/javamicro/.libs google/protobuf/compiler/javamicro/_libs
+	-rm -rf google/protobuf/compiler/javanano/.libs google/protobuf/compiler/javanano/_libs
+	-rm -rf google/protobuf/compiler/python/.libs google/protobuf/compiler/python/_libs
+	-rm -rf google/protobuf/io/.libs google/protobuf/io/_libs
+	-rm -rf google/protobuf/stubs/.libs google/protobuf/stubs/_libs
+install-nobase_dist_protoDATA: $(nobase_dist_proto_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(nobase_dist_proto_DATA)'; test -n "$(protodir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(protodir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(protodir)" || exit 1; \
+	fi; \
+	$(am__nobase_list) | while read dir files; do \
+	  xfiles=; for file in $$files; do \
+	    if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+	    else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+	  test -z "$$xfiles" || { \
+	    test "x$$dir" = x. || { \
+	      echo " $(MKDIR_P) '$(DESTDIR)$(protodir)/$$dir'"; \
+	      $(MKDIR_P) "$(DESTDIR)$(protodir)/$$dir"; }; \
+	    echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(protodir)/$$dir'"; \
+	    $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(protodir)/$$dir" || exit $$?; }; \
+	done
+
+uninstall-nobase_dist_protoDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nobase_dist_proto_DATA)'; test -n "$(protodir)" || list=; \
+	$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+	dir='$(DESTDIR)$(protodir)'; $(am__uninstall_files_from_dir)
+install-nobase_includeHEADERS: $(nobase_include_HEADERS)
+	@$(NORMAL_INSTALL)
+	@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+	fi; \
+	$(am__nobase_list) | while read dir files; do \
+	  xfiles=; for file in $$files; do \
+	    if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+	    else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+	  test -z "$$xfiles" || { \
+	    test "x$$dir" = x. || { \
+	      echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
+	      $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \
+	    echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \
+	    $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \
+	done
+
+uninstall-nobase_includeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
+	$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+	dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+protobuf-test.log: protobuf-test$(EXEEXT)
+	@p='protobuf-test$(EXEEXT)'; \
+	b='protobuf-test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+protobuf-lazy-descriptor-test.log: protobuf-lazy-descriptor-test$(EXEEXT)
+	@p='protobuf-lazy-descriptor-test$(EXEEXT)'; \
+	b='protobuf-lazy-descriptor-test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+protobuf-lite-test.log: protobuf-lite-test$(EXEEXT)
+	@p='protobuf-lite-test$(EXEEXT)'; \
+	b='protobuf-lite-test'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+google/protobuf/compiler/zip_output_unittest.sh.log: google/protobuf/compiler/zip_output_unittest.sh
+	@p='google/protobuf/compiler/zip_output_unittest.sh'; \
+	b='google/protobuf/compiler/zip_output_unittest.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+google/protobuf/io/gzip_stream_unittest.sh.log: google/protobuf/io/gzip_stream_unittest.sh
+	@p='google/protobuf/io/gzip_stream_unittest.sh'; \
+	b='google/protobuf/io/gzip_stream_unittest.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@	@p='$<'; \
+@am__EXEEXT_TRUE@	$(am__set_b); \
+@am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS)
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(protodir)" "$(DESTDIR)$(includedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-rm -f google/protobuf/$(DEPDIR)/$(am__dirstamp)
+	-rm -f google/protobuf/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/$(DEPDIR)/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/cpp/$(DEPDIR)/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/cpp/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/java/$(DEPDIR)/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/java/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/javamicro/$(DEPDIR)/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/javamicro/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/javanano/$(DEPDIR)/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/javanano/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/python/$(DEPDIR)/$(am__dirstamp)
+	-rm -f google/protobuf/compiler/python/$(am__dirstamp)
+	-rm -f google/protobuf/io/$(DEPDIR)/$(am__dirstamp)
+	-rm -f google/protobuf/io/$(am__dirstamp)
+	-rm -f google/protobuf/stubs/$(DEPDIR)/$(am__dirstamp)
+	-rm -f google/protobuf/stubs/$(am__dirstamp)
+	-rm -f google/protobuf/testing/$(DEPDIR)/$(am__dirstamp)
+	-rm -f google/protobuf/testing/$(am__dirstamp)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+	clean-libLTLIBRARIES clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf google/protobuf/$(DEPDIR) google/protobuf/compiler/$(DEPDIR) google/protobuf/compiler/cpp/$(DEPDIR) google/protobuf/compiler/java/$(DEPDIR) google/protobuf/compiler/javamicro/$(DEPDIR) google/protobuf/compiler/javanano/$(DEPDIR) google/protobuf/compiler/python/$(DEPDIR) google/protobuf/io/$(DEPDIR) google/protobuf/stubs/$(DEPDIR) google/protobuf/testing/$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-nobase_dist_protoDATA \
+	install-nobase_includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf google/protobuf/$(DEPDIR) google/protobuf/compiler/$(DEPDIR) google/protobuf/compiler/cpp/$(DEPDIR) google/protobuf/compiler/java/$(DEPDIR) google/protobuf/compiler/javamicro/$(DEPDIR) google/protobuf/compiler/javanano/$(DEPDIR) google/protobuf/compiler/python/$(DEPDIR) google/protobuf/io/$(DEPDIR) google/protobuf/stubs/$(DEPDIR) google/protobuf/testing/$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
+	uninstall-nobase_dist_protoDATA \
+	uninstall-nobase_includeHEADERS
+
+.MAKE: all check check-am install install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+	clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+	clean-libLTLIBRARIES clean-libtool clean-local cscopelist-am \
+	ctags ctags-am distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-binPROGRAMS \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-libLTLIBRARIES \
+	install-man install-nobase_dist_protoDATA \
+	install-nobase_includeHEADERS install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
+	uninstall-nobase_dist_protoDATA \
+	uninstall-nobase_includeHEADERS
+
+
+# Not sure why these don't get cleaned automatically.
+clean-local:
+	rm -f *.loT
+
+@USE_EXTERNAL_PROTOC_TRUE@unittest_proto_middleman: $(protoc_inputs)
+@USE_EXTERNAL_PROTOC_TRUE@	$(PROTOC) -I$(srcdir) --cpp_out=. $^
+@USE_EXTERNAL_PROTOC_TRUE@	touch unittest_proto_middleman
+
+# We have to cd to $(srcdir) before executing protoc because $(protoc_inputs) is
+# relative to srcdir, which may not be the same as the current directory when
+# building out-of-tree.
+@USE_EXTERNAL_PROTOC_FALSE@unittest_proto_middleman: protoc$(EXEEXT) $(protoc_inputs)
+@USE_EXTERNAL_PROTOC_FALSE@	oldpwd=`pwd` && ( cd $(srcdir) && $$oldpwd/protoc$(EXEEXT) -I. --cpp_out=$$oldpwd $(protoc_inputs) )
+@USE_EXTERNAL_PROTOC_FALSE@	touch unittest_proto_middleman
+
+$(protoc_outputs): unittest_proto_middleman
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/protobuf/src/google/protobuf/SEBS b/protobuf/src/google/protobuf/SEBS
new file mode 100644
index 0000000..ba33c73
--- /dev/null
+++ b/protobuf/src/google/protobuf/SEBS
@@ -0,0 +1,240 @@
+# **EXPERIMENTAL**
+#
+# See http://sebs.googlecode.com
+#
+# This is an experimental build definition file using the SEBS build system.
+# I (Kenton Varda, maintainer of Protocol Buffers) happen to be the author of
+# SEBS, though SEBS is not a Google project.  I'm sticking this file in
+# protobuf's SVN because that's the easiest place for me to put it, and it
+# shouldn't harm anyone.  This file is not included in the distribution.
+#
+# Currently, to use this file, you must generate config.h and put it at the
+# top level of the source tree.
+
+_cpp = sebs.import_("//sebs/cpp.sebs")
+
+# ====================================================================
+# Public targets
+
+protobuf_lite = _cpp.Library(
+  name = "protobuf-lite",
+  srcs = [ "stubs/common.cc",
+           "stubs/once.cc",
+           "stubs/hash.cc",
+           "stubs/hash.h",
+           "stubs/map-util.h",
+           "stubs/stl_util-inl.h",
+           "extension_set.cc",
+           "generated_message_util.cc",
+           "message_lite.cc",
+           "repeated_field.cc",
+           "wire_format_lite.cc",
+           "io/coded_stream.cc",
+           "io/zero_copy_stream.cc",
+           "io/zero_copy_stream_impl_lite.cc" ],
+  deps = [ _cpp.SystemLibrary(name = "pthread") ])
+
+protobuf = _cpp.Library(
+  name = "protobuf",
+  srcs = [ "stubs/strutil.cc",
+           "stubs/strutil.h",
+           "stubs/substitute.cc",
+           "stubs/substitute.h",
+           "stubs/structurally_valid.cc",
+           "descriptor.cc",
+           "descriptor.pb.cc",
+           "descriptor_database.cc",
+           "dynamic_message.cc",
+           "extension_set_heavy.cc",
+           "generated_message_reflection.cc",
+           "message.cc",
+           "reflection_ops.cc",
+           "service.cc",
+           "text_format.cc",
+           "unknown_field_set.cc",
+           "wire_format.cc",
+           "io/gzip_stream.cc",
+           "io/printer.cc",
+           "io/tokenizer.cc",
+           "io/zero_copy_stream_impl.cc",
+           "compiler/importer.cc",
+           "compiler/parser.cc" ],
+  deps = [ protobuf_lite,
+           _cpp.SystemLibrary(name = "z") ])
+
+libprotoc = _cpp.Library(
+  name = "protoc",
+  srcs = [ "compiler/code_generator.cc",
+           "compiler/command_line_interface.cc",
+           "compiler/cpp/cpp_enum.cc",
+           "compiler/cpp/cpp_enum.h",
+           "compiler/cpp/cpp_enum_field.cc",
+           "compiler/cpp/cpp_enum_field.h",
+           "compiler/cpp/cpp_extension.cc",
+           "compiler/cpp/cpp_extension.h",
+           "compiler/cpp/cpp_field.cc",
+           "compiler/cpp/cpp_field.h",
+           "compiler/cpp/cpp_file.cc",
+           "compiler/cpp/cpp_file.h",
+           "compiler/cpp/cpp_generator.cc",
+           "compiler/cpp/cpp_helpers.cc",
+           "compiler/cpp/cpp_helpers.h",
+           "compiler/cpp/cpp_message.cc",
+           "compiler/cpp/cpp_message.h",
+           "compiler/cpp/cpp_message_field.cc",
+           "compiler/cpp/cpp_message_field.h",
+           "compiler/cpp/cpp_primitive_field.cc",
+           "compiler/cpp/cpp_primitive_field.h",
+           "compiler/cpp/cpp_service.cc",
+           "compiler/cpp/cpp_service.h",
+           "compiler/cpp/cpp_string_field.cc",
+           "compiler/cpp/cpp_string_field.h",
+           "compiler/java/java_enum.cc",
+           "compiler/java/java_enum.h",
+           "compiler/java/java_enum_field.cc",
+           "compiler/java/java_enum_field.h",
+           "compiler/java/java_extension.cc",
+           "compiler/java/java_extension.h",
+           "compiler/java/java_field.cc",
+           "compiler/java/java_field.h",
+           "compiler/java/java_file.cc",
+           "compiler/java/java_file.h",
+           "compiler/java/java_generator.cc",
+           "compiler/java/java_helpers.cc",
+           "compiler/java/java_helpers.h",
+           "compiler/java/java_message.cc",
+           "compiler/java/java_message.h",
+           "compiler/java/java_message_field.cc",
+           "compiler/java/java_message_field.h",
+           "compiler/java/java_primitive_field.cc",
+           "compiler/java/java_primitive_field.h",
+           "compiler/java/java_service.cc",
+           "compiler/java/java_service.h",
+           "compiler/python/python_generator.cc" ],
+  deps = [ protobuf ])
+
+protoc = _cpp.Binary(
+  name = "protoc",
+  srcs = [ "compiler/main.cc" ],
+  deps = [ libprotoc ])
+
+# ====================================================================
+# ProtobufLibrary rule class
+
+class ProtobufLibrary(sebs.Rule):
+  argument_spec = sebs.ArgumentSpec(srcs = [sebs.Artifact],
+                                    deps = ([sebs.Rule], []),
+                                    lite = (bool, False))
+
+  def _expand(self, args):
+    for dep in args.deps:
+      if not isinstance(dep, ProtobufLibrary):
+        raise sebs.DefinitionError(
+          "Dependency of ProtobufLibrary is not a ProtobufLibrary: %s" % dep)
+
+    protoc.expand_once()
+
+    # We must build protoc for the host configuration to allow cross-compiling.
+    host_protoc = self.context.configured_artifact(protoc.binary, "host")
+
+    protoc_action = self.context.action(self, "protobuf")
+    protoc_args = [host_protoc, "-Isrc", "-Itmp", "-Iinclude","--cpp_out=tmp"]
+
+    cpp_srcs = []
+    for src in args.srcs:
+      protoc_args.append(src)
+
+      # We cannot build .proto files from other packages because the .pb.cc
+      # and .pb.h files would be written to that package, and we aren't allowed
+      # to write to other packages.
+      if self.context.local_filename(src) is None:
+        raise sebs.DefinitionError(
+          "Source file is not in this package: %s" % src)
+
+      cc_artifact = self.context.derived_artifact(src, ".pb.cc", protoc_action)
+      header_artifact = self.context.derived_artifact(
+          src, ".pb.h", protoc_action)
+
+      cpp_srcs.append(cc_artifact)
+      cpp_srcs.append(header_artifact)
+
+    protoc_action.set_command(
+      sebs.SubprocessCommand(protoc_action, protoc_args, implicit = cpp_srcs))
+
+    deps = list(args.deps)
+    if args.lite:
+      deps.append(protobuf_lite)
+    else:
+      deps.append(protobuf)
+
+    self.__cpp_library = _cpp.Library(srcs = cpp_srcs, deps = deps,
+                                      context = self.context)
+    self.__cpp_library.label = self.label
+    self.outputs = []
+
+  def as_cpp_library(self):
+    self.expand_once()
+    return self.__cpp_library
+
+# ====================================================================
+# Tests
+
+_lite_test_protos = ProtobufLibrary(
+  srcs = [ "unittest_lite.proto",
+           "unittest_import_lite.proto" ],
+  lite = True)
+_test_protos = ProtobufLibrary(
+  srcs = [ "unittest.proto",
+           "unittest_empty.proto",
+           "unittest_import.proto",
+           "unittest_mset.proto",
+           "unittest_optimize_for.proto",
+           "unittest_embed_optimize_for.proto",
+           "unittest_custom_options.proto",
+           "unittest_lite_imports_nonlite.proto",
+           "compiler/cpp/cpp_test_bad_identifiers.proto" ],
+  deps = [ _lite_test_protos ])
+
+_test_util = _cpp.Library(
+  name = "test_util",
+  srcs = [ "test_util.cc",
+           "test_util.h",
+           "testing/googletest.cc",
+           "testing/googletest.h",
+           "testing/file.cc",
+           "testing/file.h" ],
+  deps = [ protobuf, _test_protos, _cpp.SystemLibrary(name = "gtest")] )
+
+protobuf_lite_test = _cpp.Test(
+  srcs = [ "lite_unittest.cc",
+           "test_util_lite.cc",
+           "test_util_lite.h" ],
+  deps = [ _lite_test_protos ])
+
+protobuf_test = _cpp.Test(
+  srcs = [ "stubs/common_unittest.cc",
+           "stubs/once_unittest.cc",
+           "stubs/strutil_unittest.cc",
+           "stubs/structurally_valid_unittest.cc",
+           "descriptor_database_unittest.cc",
+           "descriptor_unittest.cc",
+           "dynamic_message_unittest.cc",
+           "extension_set_unittest.cc",
+           "generated_message_reflection_unittest.cc",
+           "message_unittest.cc",
+           "reflection_ops_unittest.cc",
+           "repeated_field_unittest.cc",
+           "text_format_unittest.cc",
+           "unknown_field_set_unittest.cc",
+           "wire_format_unittest.cc",
+           "io/coded_stream_unittest.cc",
+           "io/printer_unittest.cc",
+           "io/tokenizer_unittest.cc",
+           "io/zero_copy_stream_unittest.cc",
+           "compiler/command_line_interface_unittest.cc",
+           "compiler/importer_unittest.cc",
+           "compiler/parser_unittest.cc",
+           "compiler/cpp/cpp_bootstrap_unittest.cc",
+           "compiler/cpp/cpp_unittest.cc" ],
+  deps = [ protobuf, libprotoc, _test_util,
+           _cpp.SystemLibrary(name = "gtest_main") ])
diff --git a/protobuf/src/google/protobuf/compiler/code_generator.cc b/protobuf/src/google/protobuf/compiler/code_generator.cc
new file mode 100644
index 0000000..0039b00
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/code_generator.cc
@@ -0,0 +1,84 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+CodeGenerator::~CodeGenerator() {}
+GeneratorContext::~GeneratorContext() {}
+
+io::ZeroCopyOutputStream*
+GeneratorContext::OpenForAppend(const string& filename) {
+  return NULL;
+}
+
+io::ZeroCopyOutputStream* GeneratorContext::OpenForInsert(
+    const string& filename, const string& insertion_point) {
+  GOOGLE_LOG(FATAL) << "This GeneratorContext does not support insertion.";
+  return NULL;  // make compiler happy
+}
+
+void GeneratorContext::ListParsedFiles(
+    vector<const FileDescriptor*>* output) {
+  GOOGLE_LOG(FATAL) << "This GeneratorContext does not support ListParsedFiles";
+}
+
+// Parses a set of comma-delimited name/value pairs.
+void ParseGeneratorParameter(const string& text,
+                             vector<pair<string, string> >* output) {
+  vector<string> parts = Split(text, ",", true);
+
+  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 compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/code_generator.h b/protobuf/src/google/protobuf/compiler/code_generator.h
new file mode 100644
index 0000000..321a8cc
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/code_generator.h
@@ -0,0 +1,145 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+#include <vector>
+#include <utility>
+
+namespace google {
+namespace protobuf {
+
+namespace io { class ZeroCopyOutputStream; }
+class FileDescriptor;
+
+namespace compiler {
+
+// Defined in this file.
+class CodeGenerator;
+class GeneratorContext;
+
+// 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,
+                        GeneratorContext* generator_context,
+                        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 and other information about the context in which the Generator
+// runs.
+class LIBPROTOC_EXPORT GeneratorContext {
+ public:
+  inline GeneratorContext() {}
+  virtual ~GeneratorContext();
+
+  // 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.pb.h" and "foo/bar.pb.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;
+
+  // Similar to Open() but the output will be appended to the file if exists
+  virtual io::ZeroCopyOutputStream* OpenForAppend(const string& filename);
+
+  // Creates a ZeroCopyOutputStream which will insert code into the given file
+  // at the given insertion point.  See plugin.proto (plugin.pb.h) for more
+  // information on insertion points.  The default implementation
+  // assert-fails -- it exists only for backwards-compatibility.
+  //
+  // WARNING:  This feature is currently EXPERIMENTAL and is subject to change.
+  virtual io::ZeroCopyOutputStream* OpenForInsert(
+      const string& filename, const string& insertion_point);
+
+  // Returns a vector of FileDescriptors for all the files being compiled
+  // in this run.  Useful for languages, such as Go, that treat files
+  // differently when compiled as a set rather than individually.
+  virtual void ListParsedFiles(vector<const FileDescriptor*>* output);
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorContext);
+};
+
+// The type GeneratorContext was once called OutputDirectory. This typedef
+// provides backward compatibility.
+typedef GeneratorContext OutputDirectory;
+
+// Several code generators treat the parameter argument as holding a
+// list of options separated by commas.  This helper function 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")
+extern void ParseGeneratorParameter(const string&,
+            vector<pair<string, string> >*);
+
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CODE_GENERATOR_H__
diff --git a/protobuf/src/google/protobuf/compiler/command_line_interface.cc b/protobuf/src/google/protobuf/compiler/command_line_interface.cc
new file mode 100644
index 0000000..f9f27bd
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/command_line_interface.cc
@@ -0,0 +1,1603 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/command_line_interface.h>
+
+#include <stdio.h>
+#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 <ctype.h>
+
+#include <google/protobuf/stubs/hash.h>
+#include <memory>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/plugin.pb.h>
+#include <google/protobuf/compiler/subprocess.h>
+#include <google/protobuf/compiler/zip_writer.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/io/printer.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.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
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#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
+
+// Returns true if the text looks like a Windows-style absolute path, starting
+// with a drive letter.  Example:  "C:\foo".  TODO(kenton):  Share this with
+// copy in importer.cc?
+static bool IsWindowsAbsolutePath(const string& text) {
+#if defined(_WIN32) || defined(__CYGWIN__)
+  return text.size() >= 3 && text[1] == ':' &&
+         isalpha(text[0]) &&
+         (text[2] == '/' || text[2] == '\\') &&
+         text.find_last_of(':') == 1;
+#else
+  return false;
+#endif
+}
+
+void SetFdToTextMode(int fd) {
+#ifdef _WIN32
+  if (_setmode(fd, _O_TEXT) == -1) {
+    // This should never happen, I think.
+    GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_TEXT): " << strerror(errno);
+  }
+#endif
+  // (Text and binary are the same on non-Windows platforms.)
+}
+
+void SetFdToBinaryMode(int fd) {
+#ifdef _WIN32
+  if (_setmode(fd, _O_BINARY) == -1) {
+    // This should never happen, I think.
+    GOOGLE_LOG(WARNING) << "_setmode(" << fd << ", _O_BINARY): " << strerror(errno);
+  }
+#endif
+  // (Text and binary are the same on non-Windows platforms.)
+}
+
+void AddTrailingSlash(string* path) {
+  if (!path->empty() && path->at(path->size() - 1) != '/') {
+    path->push_back('/');
+  }
+}
+
+bool VerifyDirectoryExists(const string& path) {
+  if (path.empty()) return true;
+
+  if (access(path.c_str(), F_OK) == -1) {
+    cerr << path << ": " << strerror(errno) << endl;
+    return false;
+  } else {
+    return true;
+  }
+}
+
+// Try to create the parent directory of the given file, creating the parent's
+// parent if necessary, and so on.  The full file name is actually
+// (prefix + filename), but we assume |prefix| already exists and only create
+// directories listed in |filename|.
+bool TryCreateParentDirectory(const string& prefix, const string& filename) {
+  // Recursively create parent directories to the output file.
+  vector<string> parts = Split(filename, "/", true);
+  string path_so_far = prefix;
+  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;
+        return false;
+      }
+    }
+    path_so_far += '/';
+  }
+
+  return true;
+}
+
+}  // namespace
+
+// A MultiFileErrorCollector that prints errors to stderr.
+class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
+                                           public io::ErrorCollector {
+ public:
+  ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL)
+    : format_(format), tree_(tree) {}
+  ~ErrorPrinter() {}
+
+  // implements MultiFileErrorCollector ------------------------------
+  void AddError(const string& filename, int line, int column,
+                const string& message) {
+
+    // Print full path when running under MSVS
+    string dfile;
+    if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS &&
+        tree_ != NULL &&
+        tree_->VirtualFileToDiskFile(filename, &dfile)) {
+      cerr << dfile;
+    } else {
+      cerr << filename;
+    }
+
+    // Users typically expect 1-based line/column numbers, so we add 1
+    // to each here.
+    if (line != -1) {
+      // Allow for both GCC- and Visual-Studio-compatible output.
+      switch (format_) {
+        case CommandLineInterface::ERROR_FORMAT_GCC:
+          cerr << ":" << (line + 1) << ":" << (column + 1);
+          break;
+        case CommandLineInterface::ERROR_FORMAT_MSVS:
+          cerr << "(" << (line + 1) << ") : error in column=" << (column + 1);
+          break;
+      }
+    }
+
+    cerr << ": " << message << endl;
+  }
+
+  // implements io::ErrorCollector -----------------------------------
+  void AddError(int line, int column, const string& message) {
+    AddError("input", line, column, message);
+  }
+
+ private:
+  const ErrorFormat format_;
+  DiskSourceTree *tree_;
+};
+
+// -------------------------------------------------------------------
+
+// A GeneratorContext implementation that buffers files in memory, then dumps
+// them all to disk on demand.
+class CommandLineInterface::GeneratorContextImpl : public GeneratorContext {
+ public:
+  GeneratorContextImpl(const vector<const FileDescriptor*>& parsed_files);
+  ~GeneratorContextImpl();
+
+  // Write all files in the directory to disk at the given output location,
+  // which must end in a '/'.
+  bool WriteAllToDisk(const string& prefix);
+
+  // Write the contents of this directory to a ZIP-format archive with the
+  // given name.
+  bool WriteAllToZip(const string& filename);
+
+  // Add a boilerplate META-INF/MANIFEST.MF file as required by the Java JAR
+  // format, unless one has already been written.
+  void AddJarManifest();
+
+  // implements GeneratorContext --------------------------------------
+  io::ZeroCopyOutputStream* Open(const string& filename);
+  io::ZeroCopyOutputStream* OpenForAppend(const string& filename);
+  io::ZeroCopyOutputStream* OpenForInsert(
+      const string& filename, const string& insertion_point);
+  void ListParsedFiles(vector<const FileDescriptor*>* output) {
+    *output = parsed_files_;
+  }
+
+ private:
+  friend class MemoryOutputStream;
+
+  // map instead of hash_map so that files are written in order (good when
+  // writing zips).
+  map<string, string*> files_;
+  const vector<const FileDescriptor*>& parsed_files_;
+  bool had_error_;
+};
+
+class CommandLineInterface::MemoryOutputStream
+    : public io::ZeroCopyOutputStream {
+ public:
+  MemoryOutputStream(GeneratorContextImpl* directory, const string& filename,
+                     bool append_mode);
+  MemoryOutputStream(GeneratorContextImpl* directory, const string& filename,
+                     const string& insertion_point);
+  virtual ~MemoryOutputStream();
+
+  // implements ZeroCopyOutputStream ---------------------------------
+  virtual bool Next(void** data, int* size) { return inner_->Next(data, size); }
+  virtual void BackUp(int count)            {        inner_->BackUp(count);    }
+  virtual int64 ByteCount() const           { return inner_->ByteCount();      }
+
+ private:
+  // Where to insert the string when it's done.
+  GeneratorContextImpl* directory_;
+  string filename_;
+  string insertion_point_;
+
+  // The string we're building.
+  string data_;
+
+  // Whether we should append the output stream to the existing file.
+  bool append_mode_;
+
+  // StringOutputStream writing to data_.
+  scoped_ptr<io::StringOutputStream> inner_;
+};
+
+// -------------------------------------------------------------------
+
+CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl(
+    const vector<const FileDescriptor*>& parsed_files)
+    : parsed_files_(parsed_files),
+      had_error_(false) {
+}
+
+CommandLineInterface::GeneratorContextImpl::~GeneratorContextImpl() {
+  STLDeleteValues(&files_);
+}
+
+bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk(
+    const string& prefix) {
+  if (had_error_) {
+    return false;
+  }
+
+  if (!VerifyDirectoryExists(prefix)) {
+    return false;
+  }
+
+  for (map<string, string*>::const_iterator iter = files_.begin();
+       iter != files_.end(); ++iter) {
+    const string& relative_filename = iter->first;
+    const char* data = iter->second->data();
+    int size = iter->second->size();
+
+    if (!TryCreateParentDirectory(prefix, relative_filename)) {
+      return false;
+    }
+    string filename = prefix + relative_filename;
+
+    // Create the output file.
+    int file_descriptor;
+    do {
+      file_descriptor =
+        open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+    } while (file_descriptor < 0 && errno == EINTR);
+
+    if (file_descriptor < 0) {
+      int error = errno;
+      cerr << filename << ": " << strerror(error);
+      return false;
+    }
+
+    // Write the file.
+    while (size > 0) {
+      int write_result;
+      do {
+        write_result = write(file_descriptor, data, size);
+      } while (write_result < 0 && errno == EINTR);
+
+      if (write_result <= 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 (write_result < 0) {
+          int error = errno;
+          cerr << filename << ": write: " << strerror(error);
+        } else {
+          cerr << filename << ": write() returned zero?" << endl;
+        }
+        return false;
+      }
+
+      data += write_result;
+      size -= write_result;
+    }
+
+    if (close(file_descriptor) != 0) {
+      int error = errno;
+      cerr << filename << ": close: " << strerror(error);
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip(
+    const string& filename) {
+  if (had_error_) {
+    return false;
+  }
+
+  // Create the output file.
+  int file_descriptor;
+  do {
+    file_descriptor =
+      open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+  } while (file_descriptor < 0 && errno == EINTR);
+
+  if (file_descriptor < 0) {
+    int error = errno;
+    cerr << filename << ": " << strerror(error);
+    return false;
+  }
+
+  // Create the ZipWriter
+  io::FileOutputStream stream(file_descriptor);
+  ZipWriter zip_writer(&stream);
+
+  for (map<string, string*>::const_iterator iter = files_.begin();
+       iter != files_.end(); ++iter) {
+    zip_writer.Write(iter->first, *iter->second);
+  }
+
+  zip_writer.WriteDirectory();
+
+  if (stream.GetErrno() != 0) {
+    cerr << filename << ": " << strerror(stream.GetErrno()) << endl;
+  }
+
+  if (!stream.Close()) {
+    cerr << filename << ": " << strerror(stream.GetErrno()) << endl;
+  }
+
+  return true;
+}
+
+void CommandLineInterface::GeneratorContextImpl::AddJarManifest() {
+  string** map_slot = &files_["META-INF/MANIFEST.MF"];
+  if (*map_slot == NULL) {
+    *map_slot = new string(
+        "Manifest-Version: 1.0\n"
+        "Created-By: 1.6.0 (protoc)\n"
+        "\n");
+  }
+}
+
+io::ZeroCopyOutputStream* CommandLineInterface::GeneratorContextImpl::Open(
+    const string& filename) {
+  return new MemoryOutputStream(this, filename, false);
+}
+
+io::ZeroCopyOutputStream*
+CommandLineInterface::GeneratorContextImpl::OpenForAppend(
+    const string& filename) {
+  return new MemoryOutputStream(this, filename, true);
+}
+
+io::ZeroCopyOutputStream*
+CommandLineInterface::GeneratorContextImpl::OpenForInsert(
+    const string& filename, const string& insertion_point) {
+  return new MemoryOutputStream(this, filename, insertion_point);
+}
+
+// -------------------------------------------------------------------
+
+CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
+    GeneratorContextImpl* directory, const string& filename, bool append_mode)
+    : directory_(directory),
+      filename_(filename),
+      append_mode_(append_mode),
+      inner_(new io::StringOutputStream(&data_)) {
+}
+
+CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
+    GeneratorContextImpl* directory, const string& filename,
+    const string& insertion_point)
+    : directory_(directory),
+      filename_(filename),
+      insertion_point_(insertion_point),
+      inner_(new io::StringOutputStream(&data_)) {
+}
+
+CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
+  // Make sure all data has been written.
+  inner_.reset();
+
+  // Insert into the directory.
+  string** map_slot = &directory_->files_[filename_];
+
+  if (insertion_point_.empty()) {
+    // This was just a regular Open().
+    if (*map_slot != NULL) {
+      if (append_mode_) {
+        (*map_slot)->append(data_);
+      } else {
+        cerr << filename_ << ": Tried to write the same file twice." << endl;
+        directory_->had_error_ = true;
+      }
+      return;
+    }
+
+    *map_slot = new string;
+    (*map_slot)->swap(data_);
+  } else {
+    // This was an OpenForInsert().
+
+    // If the data doens't end with a clean line break, add one.
+    if (!data_.empty() && data_[data_.size() - 1] != '\n') {
+      data_.push_back('\n');
+    }
+
+    // Find the file we are going to insert into.
+    if (*map_slot == NULL) {
+      cerr << filename_ << ": Tried to insert into file that doesn't exist."
+           << endl;
+      directory_->had_error_ = true;
+      return;
+    }
+    string* target = *map_slot;
+
+    // Find the insertion point.
+    string magic_string = strings::Substitute(
+        "@@protoc_insertion_point($0)", insertion_point_);
+    string::size_type pos = target->find(magic_string);
+
+    if (pos == string::npos) {
+      cerr << filename_ << ": insertion point \"" << insertion_point_
+           << "\" not found." << endl;
+      directory_->had_error_ = true;
+      return;
+    }
+
+    // Seek backwards to the beginning of the line, which is where we will
+    // insert the data.  Note that this has the effect of pushing the insertion
+    // point down, so the data is inserted before it.  This is intentional
+    // because it means that multiple insertions at the same point will end
+    // up in the expected order in the final output.
+    pos = target->find_last_of('\n', pos);
+    if (pos == string::npos) {
+      // Insertion point is on the first line.
+      pos = 0;
+    } else {
+      // Advance to character after '\n'.
+      ++pos;
+    }
+
+    // Extract indent.
+    string indent_(*target, pos, target->find_first_not_of(" \t", pos) - pos);
+
+    if (indent_.empty()) {
+      // No indent.  This makes things easier.
+      target->insert(pos, data_);
+    } else {
+      // Calculate how much space we need.
+      int indent_size = 0;
+      for (int i = 0; i < data_.size(); i++) {
+        if (data_[i] == '\n') indent_size += indent_.size();
+      }
+
+      // Make a hole for it.
+      target->insert(pos, data_.size() + indent_size, '\0');
+
+      // Now copy in the data.
+      string::size_type data_pos = 0;
+      char* target_ptr = string_as_array(target) + pos;
+      while (data_pos < data_.size()) {
+        // Copy indent.
+        memcpy(target_ptr, indent_.data(), indent_.size());
+        target_ptr += indent_.size();
+
+        // Copy line from data_.
+        // We already guaranteed that data_ ends with a newline (above), so this
+        // search can't fail.
+        string::size_type line_length =
+            data_.find_first_of('\n', data_pos) + 1 - data_pos;
+        memcpy(target_ptr, data_.data() + data_pos, line_length);
+        target_ptr += line_length;
+        data_pos += line_length;
+      }
+
+      GOOGLE_CHECK_EQ(target_ptr,
+          string_as_array(target) + pos + data_.size() + indent_size);
+    }
+  }
+}
+
+// ===================================================================
+
+CommandLineInterface::CommandLineInterface()
+  : mode_(MODE_COMPILE),
+    print_mode_(PRINT_NONE),
+    error_format_(ERROR_FORMAT_GCC),
+    imports_in_descriptor_set_(false),
+    source_info_in_descriptor_set_(false),
+    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.flag_name = flag_name;
+  info.generator = generator;
+  info.help_text = help_text;
+  generators_by_flag_name_[flag_name] = info;
+}
+
+void CommandLineInterface::RegisterGenerator(const string& flag_name,
+                                             const string& option_flag_name,
+                                             CodeGenerator* generator,
+                                             const string& help_text) {
+  GeneratorInfo info;
+  info.flag_name = flag_name;
+  info.option_flag_name = option_flag_name;
+  info.generator = generator;
+  info.help_text = help_text;
+  generators_by_flag_name_[flag_name] = info;
+  generators_by_option_name_[option_flag_name] = info;
+}
+
+void CommandLineInterface::AllowPlugins(const string& exe_name_prefix) {
+  plugin_prefix_ = exe_name_prefix;
+}
+
+int CommandLineInterface::Run(int argc, const char* const argv[]) {
+  Clear();
+  switch (ParseArguments(argc, argv)) {
+    case PARSE_ARGUMENT_DONE_AND_EXIT:
+      return 0;
+    case PARSE_ARGUMENT_FAIL:
+      return 1;
+    case PARSE_ARGUMENT_DONE_AND_CONTINUE:
+      break;
+  }
+
+  // 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(error_format_, &source_tree);
+  Importer importer(&source_tree, &error_collector);
+
+  vector<const FileDescriptor*> parsed_files;
+
+  // Parse each file.
+  for (int i = 0; i < input_files_.size(); i++) {
+    // Import the file.
+    importer.AddUnusedImportTrackFile(input_files_[i]);
+    const FileDescriptor* parsed_file = importer.Import(input_files_[i]);
+    importer.ClearUnusedImportTrackFiles();
+    if (parsed_file == NULL) return 1;
+    parsed_files.push_back(parsed_file);
+
+    // Enforce --disallow_services.
+    if (disallow_services_ && parsed_file->service_count() > 0) {
+      cerr << parsed_file->name() << ": This file contains services, but "
+              "--disallow_services was used." << endl;
+      return 1;
+    }
+  }
+
+  // We construct a separate GeneratorContext for each output location.  Note
+  // that two code generators may output to the same location, in which case
+  // they should share a single GeneratorContext so that OpenForInsert() works.
+  typedef hash_map<string, GeneratorContextImpl*> GeneratorContextMap;
+  GeneratorContextMap output_directories;
+
+  // Generate output.
+  if (mode_ == MODE_COMPILE) {
+    for (int i = 0; i < output_directives_.size(); i++) {
+      string output_location = output_directives_[i].output_location;
+      if (!HasSuffixString(output_location, ".zip") &&
+          !HasSuffixString(output_location, ".jar")) {
+        AddTrailingSlash(&output_location);
+      }
+      GeneratorContextImpl** map_slot = &output_directories[output_location];
+
+      if (*map_slot == NULL) {
+        // First time we've seen this output location.
+        *map_slot = new GeneratorContextImpl(parsed_files);
+      }
+
+      if (!GenerateOutput(parsed_files, output_directives_[i], *map_slot)) {
+        STLDeleteValues(&output_directories);
+        return 1;
+      }
+    }
+  }
+
+  // Write all output to disk.
+  for (GeneratorContextMap::iterator iter = output_directories.begin();
+       iter != output_directories.end(); ++iter) {
+    const string& location = iter->first;
+    GeneratorContextImpl* directory = iter->second;
+    if (HasSuffixString(location, "/")) {
+      if (!directory->WriteAllToDisk(location)) {
+        STLDeleteValues(&output_directories);
+        return 1;
+      }
+    } else {
+      if (HasSuffixString(location, ".jar")) {
+        directory->AddJarManifest();
+      }
+
+      if (!directory->WriteAllToZip(location)) {
+        STLDeleteValues(&output_directories);
+        return 1;
+      }
+    }
+  }
+
+  STLDeleteValues(&output_directories);
+
+  if (!descriptor_set_name_.empty()) {
+    if (!WriteDescriptorSet(parsed_files)) {
+      return 1;
+    }
+  }
+
+  if (mode_ == MODE_ENCODE || mode_ == MODE_DECODE) {
+    if (codec_type_.empty()) {
+      // HACK:  Define an EmptyMessage type to use for decoding.
+      DescriptorPool pool;
+      FileDescriptorProto file;
+      file.set_name("empty_message.proto");
+      file.add_message_type()->set_name("EmptyMessage");
+      GOOGLE_CHECK(pool.BuildFile(file) != NULL);
+      codec_type_ = "EmptyMessage";
+      if (!EncodeOrDecode(&pool)) {
+        return 1;
+      }
+    } else {
+      if (!EncodeOrDecode(importer.pool())) {
+        return 1;
+      }
+    }
+  }
+
+  if (mode_ == MODE_PRINT) {
+    switch (print_mode_) {
+      case PRINT_FREE_FIELDS:
+        for (int i = 0; i < parsed_files.size(); ++i) {
+          const FileDescriptor* fd = parsed_files[i];
+          for (int j = 0; j < fd->message_type_count(); ++j) {
+            PrintFreeFieldNumbers(fd->message_type(j));
+          }
+        }
+        break;
+      case PRINT_NONE:
+        GOOGLE_LOG(ERROR) << "If the code reaches here, it usually means a bug of "
+                     "flag parsing in the CommonadLineInterface.";
+        return 1;
+
+      // Do not add a default case.
+    }
+  }
+
+  return 0;
+}
+
+void CommandLineInterface::Clear() {
+  // Clear all members that are set by Run().  Note that we must not clear
+  // members which are set by other methods before Run() is called.
+  executable_name_.clear();
+  proto_path_.clear();
+  input_files_.clear();
+  output_directives_.clear();
+  codec_type_.clear();
+  descriptor_set_name_.clear();
+
+  mode_ = MODE_COMPILE;
+  print_mode_ = PRINT_NONE;
+  imports_in_descriptor_set_ = false;
+  source_info_in_descriptor_set_ = false;
+  disallow_services_ = false;
+}
+
+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.  Note that the "
+                  "proto_path must be an exact prefix of the .proto file "
+                  "names -- protoc is too dumb to figure out when two paths "
+                  "(e.g. absolute and relative) are equivalent (it's harder "
+                  "than you think)." << endl;
+        }
+        return false;
+    }
+  }
+
+  return true;
+}
+
+CommandLineInterface::ParseArgumentStatus
+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)) {
+      // Returned true => Use the next argument as the flag value.
+      if (i + 1 == argc || argv[i+1][0] == '-') {
+        cerr << "Missing value for flag: " << name << endl;
+        if (name == "--decode") {
+          cerr << "To decode an unknown message, use --decode_raw." << endl;
+        }
+        return PARSE_ARGUMENT_FAIL;
+      } else {
+        ++i;
+        value = argv[i];
+      }
+    }
+
+    ParseArgumentStatus status = InterpretArgument(name, value);
+    if (status != PARSE_ARGUMENT_DONE_AND_CONTINUE)
+      return status;
+  }
+
+  // If no --proto_path was given, use the current working directory.
+  if (proto_path_.empty()) {
+    // Don't use make_pair as the old/default standard library on Solaris
+    // doesn't support it without explicit template parameters, which are
+    // incompatible with C++0x's make_pair.
+    proto_path_.push_back(pair<string, string>("", "."));
+  }
+
+  // Check some errror cases.
+  bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty();
+  if (decoding_raw && !input_files_.empty()) {
+    cerr << "When using --decode_raw, no input files should be given." << endl;
+    return PARSE_ARGUMENT_FAIL;
+  } else if (!decoding_raw && input_files_.empty()) {
+    cerr << "Missing input file." << endl;
+    return PARSE_ARGUMENT_FAIL;
+  }
+  if (mode_ == MODE_COMPILE && output_directives_.empty() &&
+      descriptor_set_name_.empty()) {
+    cerr << "Missing output directives." << endl;
+    return PARSE_ARGUMENT_FAIL;
+  }
+  if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) {
+    cerr << "--include_imports only makes sense when combined with "
+            "--descriptor_set_out." << endl;
+  }
+  if (source_info_in_descriptor_set_ && descriptor_set_name_.empty()) {
+    cerr << "--include_source_info only makes sense when combined with "
+            "--descriptor_set_out." << endl;
+  }
+
+  return PARSE_ARGUMENT_DONE_AND_CONTINUE;
+}
+
+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 == "--include_imports" ||
+      *name == "--include_source_info" ||
+      *name == "--version" ||
+      *name == "--decode_raw" ||
+      *name == "--print_free_field_numbers") {
+    // 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;
+}
+
+CommandLineInterface::ParseArgumentStatus
+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 PARSE_ARGUMENT_FAIL;
+    }
+
+    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 = Split(
+        value, kPathSeparator, true);
+
+    for (int i = 0; i < parts.size(); i++) {
+      string virtual_path;
+      string disk_path;
+
+      string::size_type 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 PARSE_ARGUMENT_FAIL;
+      }
+
+      // 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;
+      }
+
+      // Don't use make_pair as the old/default standard library on Solaris
+      // doesn't support it without explicit template parameters, which are
+      // incompatible with C++0x's make_pair.
+      proto_path_.push_back(pair<string, string>(virtual_path, disk_path));
+    }
+
+  } else if (name == "-o" || name == "--descriptor_set_out") {
+    if (!descriptor_set_name_.empty()) {
+      cerr << name << " may only be passed once." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+    if (value.empty()) {
+      cerr << name << " requires a non-empty value." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+    if (mode_ != MODE_COMPILE) {
+      cerr << "Cannot use --encode or --decode and generate descriptors at the "
+              "same time." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+    descriptor_set_name_ = value;
+
+  } else if (name == "--include_imports") {
+    if (imports_in_descriptor_set_) {
+      cerr << name << " may only be passed once." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+    imports_in_descriptor_set_ = true;
+
+  } else if (name == "--include_source_info") {
+    if (source_info_in_descriptor_set_) {
+      cerr << name << " may only be passed once." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+    source_info_in_descriptor_set_ = true;
+
+  } else if (name == "-h" || name == "--help") {
+    PrintHelpText();
+    return PARSE_ARGUMENT_DONE_AND_EXIT;  // 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 PARSE_ARGUMENT_DONE_AND_EXIT;  // Exit without running compiler.
+
+  } else if (name == "--disallow_services") {
+    disallow_services_ = true;
+
+  } else if (name == "--encode" || name == "--decode" ||
+             name == "--decode_raw") {
+    if (mode_ != MODE_COMPILE) {
+      cerr << "Only one of --encode and --decode can be specified." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+    if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
+      cerr << "Cannot use " << name
+           << " and generate code or descriptors at the same time." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+
+    mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE;
+
+    if (value.empty() && name != "--decode_raw") {
+      cerr << "Type name for " << name << " cannot be blank." << endl;
+      if (name == "--decode") {
+        cerr << "To decode an unknown message, use --decode_raw." << endl;
+      }
+      return PARSE_ARGUMENT_FAIL;
+    } else if (!value.empty() && name == "--decode_raw") {
+      cerr << "--decode_raw does not take a parameter." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+
+    codec_type_ = value;
+
+  } else if (name == "--error_format") {
+    if (value == "gcc") {
+      error_format_ = ERROR_FORMAT_GCC;
+    } else if (value == "msvs") {
+      error_format_ = ERROR_FORMAT_MSVS;
+    } else {
+      cerr << "Unknown error format: " << value << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+
+  } else if (name == "--plugin") {
+    if (plugin_prefix_.empty()) {
+      cerr << "This compiler does not support plugins." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+
+    string plugin_name;
+    string path;
+
+    string::size_type equals_pos = value.find_first_of('=');
+    if (equals_pos == string::npos) {
+      // Use the basename of the file.
+      string::size_type slash_pos = value.find_last_of('/');
+      if (slash_pos == string::npos) {
+        plugin_name = value;
+      } else {
+        plugin_name = value.substr(slash_pos + 1);
+      }
+      path = value;
+    } else {
+      plugin_name = value.substr(0, equals_pos);
+      path = value.substr(equals_pos + 1);
+    }
+
+    plugins_[plugin_name] = path;
+
+  } else if (name == "--print_free_field_numbers") {
+    if (mode_ != MODE_COMPILE) {
+      cerr << "Cannot use " << name << " and use --encode, --decode or print "
+           << "other info at the same time." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+    if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
+      cerr << "Cannot use " << name
+           << " and generate code or descriptors at the same time." << endl;
+      return PARSE_ARGUMENT_FAIL;
+    }
+    mode_ = MODE_PRINT;
+    print_mode_ = PRINT_FREE_FIELDS;
+  } else {
+    // Some other flag.  Look it up in the generators list.
+    const GeneratorInfo* generator_info =
+        FindOrNull(generators_by_flag_name_, name);
+    if (generator_info == NULL &&
+        (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) {
+      // Check if it's a generator option flag.
+      generator_info = FindOrNull(generators_by_option_name_, name);
+      if (generator_info == NULL) {
+        cerr << "Unknown flag: " << name << endl;
+        return PARSE_ARGUMENT_FAIL;
+      } else {
+        string* parameters = &generator_parameters_[generator_info->flag_name];
+        if (!parameters->empty()) {
+          parameters->append(",");
+        }
+        parameters->append(value);
+      }
+    } else {
+      // It's an output flag.  Add it to the output directives.
+      if (mode_ != MODE_COMPILE) {
+        cerr << "Cannot use --encode, --decode or print .proto info and "
+                "generate code at the same time." << endl;
+        return PARSE_ARGUMENT_FAIL;
+      }
+
+      OutputDirective directive;
+      directive.name = name;
+      if (generator_info == NULL) {
+        directive.generator = NULL;
+      } else {
+        directive.generator = generator_info->generator;
+      }
+
+      // Split value at ':' to separate the generator parameter from the
+      // filename.  However, avoid doing this if the colon is part of a valid
+      // Windows-style absolute path.
+      string::size_type colon_pos = value.find_first_of(':');
+      if (colon_pos == string::npos || IsWindowsAbsolutePath(value)) {
+        directive.output_location = value;
+      } else {
+        directive.parameter = value.substr(0, colon_pos);
+        directive.output_location = value.substr(colon_pos + 1);
+      }
+
+      output_directives_.push_back(directive);
+    }
+  }
+
+  return PARSE_ARGUMENT_DONE_AND_CONTINUE;
+}
+
+void CommandLineInterface::PrintHelpText() {
+  // Sorry for indentation here; line wrapping would be uglier.
+  cerr <<
+"Usage: " << executable_name_ << " [OPTION] PROTO_FILES\n"
+"Parse PROTO_FILES and generate output based on the options given:\n"
+"  -IPATH, --proto_path=PATH   Specify the directory in which to search for\n"
+"                              imports.  May be specified multiple times;\n"
+"                              directories will be searched in order.  If not\n"
+"                              given, the current working directory is used.\n"
+"  --version                   Show version info and exit.\n"
+"  -h, --help                  Show this text and exit.\n"
+"  --encode=MESSAGE_TYPE       Read a text-format message of the given type\n"
+"                              from standard input and write it in binary\n"
+"                              to standard output.  The message type must\n"
+"                              be defined in PROTO_FILES or their imports.\n"
+"  --decode=MESSAGE_TYPE       Read a binary message of the given type from\n"
+"                              standard input and write it in text format\n"
+"                              to standard output.  The message type must\n"
+"                              be defined in PROTO_FILES or their imports.\n"
+"  --decode_raw                Read an arbitrary protocol message from\n"
+"                              standard input and write the raw tag/value\n"
+"                              pairs in text format to standard output.  No\n"
+"                              PROTO_FILES should be given when using this\n"
+"                              flag.\n"
+"  -oFILE,                     Writes a FileDescriptorSet (a protocol buffer,\n"
+"    --descriptor_set_out=FILE defined in descriptor.proto) containing all of\n"
+"                              the input files to FILE.\n"
+"  --include_imports           When using --descriptor_set_out, also include\n"
+"                              all dependencies of the input files in the\n"
+"                              set, so that the set is self-contained.\n"
+"  --include_source_info       When using --descriptor_set_out, do not strip\n"
+"                              SourceCodeInfo from the FileDescriptorProto.\n"
+"                              This results in vastly larger descriptors that\n"
+"                              include information about the original\n"
+"                              location of each decl in the source file as\n"
+"                              well as surrounding comments.\n"
+"  --error_format=FORMAT       Set the format in which to print errors.\n"
+"                              FORMAT may be 'gcc' (the default) or 'msvs'\n"
+"                              (Microsoft Visual Studio format).\n"
+"  --print_free_field_numbers  Print the free field numbers of the messages\n"
+"                              defined in the given proto files. Groups share\n"
+"                              the same field number space with the parent \n"
+"                              message. Extension ranges are counted as \n"
+"                              occupied fields numbers."  << endl;
+  if (!plugin_prefix_.empty()) {
+    cerr <<
+"  --plugin=EXECUTABLE         Specifies a plugin executable to use.\n"
+"                              Normally, protoc searches the PATH for\n"
+"                              plugins, but you may specify additional\n"
+"                              executables not in the path using this flag.\n"
+"                              Additionally, EXECUTABLE may be of the form\n"
+"                              NAME=PATH, in which case the given plugin name\n"
+"                              is mapped to the given executable even if\n"
+"                              the executable's own name differs." << endl;
+  }
+
+  for (GeneratorMap::iterator iter = generators_by_flag_name_.begin();
+       iter != generators_by_flag_name_.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 vector<const FileDescriptor*>& parsed_files,
+    const OutputDirective& output_directive,
+    GeneratorContext* generator_context) {
+  // Call the generator.
+  string error;
+  if (output_directive.generator == NULL) {
+    // This is a plugin.
+    GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") &&
+          HasSuffixString(output_directive.name, "_out"))
+        << "Bad name for plugin generator: " << output_directive.name;
+
+    // Strip the "--" and "_out" and add the plugin prefix.
+    string plugin_name = plugin_prefix_ + "gen-" +
+        output_directive.name.substr(2, output_directive.name.size() - 6);
+
+    if (!GeneratePluginOutput(parsed_files, plugin_name,
+                              output_directive.parameter,
+                              generator_context, &error)) {
+      cerr << output_directive.name << ": " << error << endl;
+      return false;
+    }
+  } else {
+    // Regular generator.
+    string parameters = output_directive.parameter;
+    if (!generator_parameters_[output_directive.name].empty()) {
+      if (!parameters.empty()) {
+        parameters.append(",");
+      }
+      parameters.append(generator_parameters_[output_directive.name]);
+    }
+    for (int i = 0; i < parsed_files.size(); i++) {
+      if (!output_directive.generator->Generate(parsed_files[i], parameters,
+                                                generator_context, &error)) {
+        // Generator returned an error.
+        cerr << output_directive.name << ": " << parsed_files[i]->name() << ": "
+             << error << endl;
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+bool CommandLineInterface::GeneratePluginOutput(
+    const vector<const FileDescriptor*>& parsed_files,
+    const string& plugin_name,
+    const string& parameter,
+    GeneratorContext* generator_context,
+    string* error) {
+  CodeGeneratorRequest request;
+  CodeGeneratorResponse response;
+
+  // Build the request.
+  if (!parameter.empty()) {
+    request.set_parameter(parameter);
+  }
+
+  set<const FileDescriptor*> already_seen;
+  for (int i = 0; i < parsed_files.size(); i++) {
+    request.add_file_to_generate(parsed_files[i]->name());
+    GetTransitiveDependencies(parsed_files[i],
+                              true,  // Include source code info.
+                              &already_seen, request.mutable_proto_file());
+  }
+
+  // Invoke the plugin.
+  Subprocess subprocess;
+
+  if (plugins_.count(plugin_name) > 0) {
+    subprocess.Start(plugins_[plugin_name], Subprocess::EXACT_NAME);
+  } else {
+    subprocess.Start(plugin_name, Subprocess::SEARCH_PATH);
+  }
+
+  string communicate_error;
+  if (!subprocess.Communicate(request, &response, &communicate_error)) {
+    *error = strings::Substitute("$0: $1", plugin_name, communicate_error);
+    return false;
+  }
+
+  // Write the files.  We do this even if there was a generator error in order
+  // to match the behavior of a compiled-in generator.
+  scoped_ptr<io::ZeroCopyOutputStream> current_output;
+  for (int i = 0; i < response.file_size(); i++) {
+    const CodeGeneratorResponse::File& output_file = response.file(i);
+
+    if (!output_file.insertion_point().empty()) {
+      // Open a file for insert.
+      // We reset current_output to NULL first so that the old file is closed
+      // before the new one is opened.
+      current_output.reset();
+      current_output.reset(generator_context->OpenForInsert(
+          output_file.name(), output_file.insertion_point()));
+    } else if (!output_file.name().empty()) {
+      // Starting a new file.  Open it.
+      // We reset current_output to NULL first so that the old file is closed
+      // before the new one is opened.
+      current_output.reset();
+      current_output.reset(generator_context->Open(output_file.name()));
+    } else if (current_output == NULL) {
+      *error = strings::Substitute(
+        "$0: First file chunk returned by plugin did not specify a file name.",
+        plugin_name);
+      return false;
+    }
+
+    // Use CodedOutputStream for convenience; otherwise we'd need to provide
+    // our own buffer-copying loop.
+    io::CodedOutputStream writer(current_output.get());
+    writer.WriteString(output_file.content());
+  }
+
+  // Check for errors.
+  if (!response.error().empty()) {
+    // Generator returned an error.
+    *error = response.error();
+    return false;
+  }
+
+  return true;
+}
+
+bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
+  // Look up the type.
+  const Descriptor* type = pool->FindMessageTypeByName(codec_type_);
+  if (type == NULL) {
+    cerr << "Type not defined: " << codec_type_ << endl;
+    return false;
+  }
+
+  DynamicMessageFactory dynamic_factory(pool);
+  scoped_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
+
+  if (mode_ == MODE_ENCODE) {
+    SetFdToTextMode(STDIN_FILENO);
+    SetFdToBinaryMode(STDOUT_FILENO);
+  } else {
+    SetFdToBinaryMode(STDIN_FILENO);
+    SetFdToTextMode(STDOUT_FILENO);
+  }
+
+  io::FileInputStream in(STDIN_FILENO);
+  io::FileOutputStream out(STDOUT_FILENO);
+
+  if (mode_ == MODE_ENCODE) {
+    // Input is text.
+    ErrorPrinter error_collector(error_format_);
+    TextFormat::Parser parser;
+    parser.RecordErrorsTo(&error_collector);
+    parser.AllowPartialMessage(true);
+
+    if (!parser.Parse(&in, message.get())) {
+      cerr << "Failed to parse input." << endl;
+      return false;
+    }
+  } else {
+    // Input is binary.
+    if (!message->ParsePartialFromZeroCopyStream(&in)) {
+      cerr << "Failed to parse input." << endl;
+      return false;
+    }
+  }
+
+  if (!message->IsInitialized()) {
+    cerr << "warning:  Input message is missing required fields:  "
+         << message->InitializationErrorString() << endl;
+  }
+
+  if (mode_ == MODE_ENCODE) {
+    // Output is binary.
+    if (!message->SerializePartialToZeroCopyStream(&out)) {
+      cerr << "output: I/O error." << endl;
+      return false;
+    }
+  } else {
+    // Output is text.
+    if (!TextFormat::Print(*message, &out)) {
+      cerr << "output: I/O error." << endl;
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool CommandLineInterface::WriteDescriptorSet(
+    const vector<const FileDescriptor*> parsed_files) {
+  FileDescriptorSet file_set;
+
+  if (imports_in_descriptor_set_) {
+    set<const FileDescriptor*> already_seen;
+    for (int i = 0; i < parsed_files.size(); i++) {
+      GetTransitiveDependencies(parsed_files[i],
+                                source_info_in_descriptor_set_,
+                                &already_seen, file_set.mutable_file());
+    }
+  } else {
+    for (int i = 0; i < parsed_files.size(); i++) {
+      FileDescriptorProto* file_proto = file_set.add_file();
+      parsed_files[i]->CopyTo(file_proto);
+      if (source_info_in_descriptor_set_) {
+        parsed_files[i]->CopySourceCodeInfoTo(file_proto);
+      }
+    }
+  }
+
+  int fd;
+  do {
+    fd = open(descriptor_set_name_.c_str(),
+              O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
+  } while (fd < 0 && errno == EINTR);
+
+  if (fd < 0) {
+    perror(descriptor_set_name_.c_str());
+    return false;
+  }
+
+  io::FileOutputStream out(fd);
+  if (!file_set.SerializeToZeroCopyStream(&out)) {
+    cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl;
+    out.Close();
+    return false;
+  }
+  if (!out.Close()) {
+    cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl;
+    return false;
+  }
+
+  return true;
+}
+
+void CommandLineInterface::GetTransitiveDependencies(
+    const FileDescriptor* file, bool include_source_code_info,
+    set<const FileDescriptor*>* already_seen,
+    RepeatedPtrField<FileDescriptorProto>* output) {
+  if (!already_seen->insert(file).second) {
+    // Already saw this file.  Skip.
+    return;
+  }
+
+  // Add all dependencies.
+  for (int i = 0; i < file->dependency_count(); i++) {
+    GetTransitiveDependencies(file->dependency(i), include_source_code_info,
+                              already_seen, output);
+  }
+
+  // Add this file.
+  FileDescriptorProto* new_descriptor = output->Add();
+  file->CopyTo(new_descriptor);
+  if (include_source_code_info) {
+    file->CopySourceCodeInfoTo(new_descriptor);
+  }
+}
+
+namespace {
+
+// Utility function for PrintFreeFieldNumbers.
+// Stores occupied ranges into the ranges parameter, and next level of sub
+// message types into the nested_messages parameter.  The FieldRange is left
+// inclusive, right exclusive. i.e. [a, b).
+//
+// Nested Messages:
+// Note that it only stores the nested message type, iff the nested type is
+// either a direct child of the given descriptor, or the nested type is a
+// decendent of the given descriptor and all the nodes between the
+// nested type and the given descriptor are group types. e.g.
+//
+// message Foo {
+//   message Bar {
+//     message NestedBar {}
+//   }
+//   group Baz = 1 {
+//     group NestedBazGroup = 2 {
+//       message Quz {
+//         message NestedQuz {}
+//       }
+//     }
+//     message NestedBaz {}
+//   }
+// }
+//
+// In this case, Bar, Quz and NestedBaz will be added into the nested types.
+// Since free field numbers of group types will not be printed, this makes sure
+// the nested message types in groups will not be dropped. The nested_messages
+// parameter will contain the direct children (when groups are ignored in the
+// tree) of the given descriptor for the caller to traverse. The declaration
+// order of the nested messages is also preserved.
+typedef pair<int, int> FieldRange;
+void GatherOccupiedFieldRanges(const Descriptor* descriptor,
+                               set<FieldRange>* ranges,
+                               vector<const Descriptor*>* nested_messages) {
+  set<const Descriptor*> groups;
+  for (int i = 0; i < descriptor->field_count(); ++i) {
+    const FieldDescriptor* fd = descriptor->field(i);
+    ranges->insert(FieldRange(fd->number(), fd->number() + 1));
+    if (fd->type() == FieldDescriptor::TYPE_GROUP) {
+      groups.insert(fd->message_type());
+    }
+  }
+  for (int i = 0; i < descriptor->extension_range_count(); ++i) {
+    ranges->insert(FieldRange(descriptor->extension_range(i)->start,
+                              descriptor->extension_range(i)->end));
+  }
+  // Handle the nested messages/groups in declaration order to make it
+  // post-order strict.
+  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+    const Descriptor* nested_desc = descriptor->nested_type(i);
+    if (groups.find(nested_desc) != groups.end()) {
+      GatherOccupiedFieldRanges(nested_desc, ranges, nested_messages);
+    } else {
+      nested_messages->push_back(nested_desc);
+    }
+  }
+}
+
+// Utility function for PrintFreeFieldNumbers.
+// Actually prints the formatted free field numbers for given message name and
+// occupied ranges.
+void FormatFreeFieldNumbers(const string& name,
+                            const set<FieldRange>& ranges) {
+  string output;
+  StringAppendF(&output, "%-35s free:", name.c_str());
+  int next_free_number = 1;
+  for (set<FieldRange>::const_iterator i = ranges.begin();
+       i != ranges.end(); ++i) {
+    // This happens when groups re-use parent field numbers, in which
+    // case we skip the FieldRange entirely.
+    if (next_free_number >= i->second) continue;
+
+    if (next_free_number < i->first) {
+      if (next_free_number + 1 == i->first) {
+        // Singleton
+        StringAppendF(&output, " %d", next_free_number);
+      } else {
+        // Range
+        StringAppendF(&output, " %d-%d", next_free_number, i->first - 1);
+      }
+    }
+    next_free_number = i->second;
+  }
+  if (next_free_number <= FieldDescriptor::kMaxNumber) {
+    StringAppendF(&output, " %d-INF", next_free_number);
+  }
+  cout << output << endl;
+}
+
+}  // namespace
+
+void CommandLineInterface::PrintFreeFieldNumbers(
+    const Descriptor* descriptor) {
+  set<FieldRange> ranges;
+  vector<const Descriptor*> nested_messages;
+  GatherOccupiedFieldRanges(descriptor, &ranges, &nested_messages);
+
+  for (int i = 0; i < nested_messages.size(); ++i) {
+    PrintFreeFieldNumbers(nested_messages[i]);
+  }
+  FormatFreeFieldNumbers(descriptor->full_name(), ranges);
+}
+
+
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/command_line_interface.h b/protobuf/src/google/protobuf/compiler/command_line_interface.h
new file mode 100644
index 0000000..47f2891
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/command_line_interface.h
@@ -0,0 +1,378 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 Descriptor;            // descriptor.h
+class DescriptorPool;        // descriptor.h
+class FileDescriptor;        // descriptor.h
+class FileDescriptorProto;   // descriptor.pb.h
+template<typename T> class RepeatedPtrField;  // repeated_field.h
+
+namespace compiler {
+
+class CodeGenerator;        // code_generator.h
+class GeneratorContext;      // 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 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);
+
+  // Register a code generator for a language.
+  // Besides flag_name you can specify another option_flag_name that could be
+  // used to pass extra parameters to the registered code generator.
+  // Suppose you have registered a generator by calling:
+  //   command_line_interface.RegisterGenerator("--foo_out", "--foo_opt", ...)
+  // Then you could invoke the compiler with a command like:
+  //   protoc --foo_out=enable_bar:outdir --foo_opt=enable_baz
+  // This will pass "enable_bar,enable_baz" as the parameter to the generator.
+  void RegisterGenerator(const string& flag_name,
+                         const string& option_flag_name,
+                         CodeGenerator* generator,
+                         const string& help_text);
+
+  // Enables "plugins".  In this mode, if a command-line flag ends with "_out"
+  // but does not match any registered generator, the compiler will attempt to
+  // find a "plugin" to implement the generator.  Plugins are just executables.
+  // They should live somewhere in the PATH.
+  //
+  // The compiler determines the executable name to search for by concatenating
+  // exe_name_prefix with the unrecognized flag name, removing "_out".  So, for
+  // example, if exe_name_prefix is "protoc-" and you pass the flag --foo_out,
+  // the compiler will try to run the program "protoc-foo".
+  //
+  // The plugin program should implement the following usage:
+  //   plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS
+  // --out indicates the output directory (as passed to the --foo_out
+  // parameter); if omitted, the current directory should be used.  --parameter
+  // gives the generator parameter, if any was provided.  The PROTO_FILES list
+  // the .proto files which were given on the compiler command-line; these are
+  // the files for which the plugin is expected to generate output code.
+  // Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in
+  // descriptor.proto).  This is piped to the plugin's stdin.  The set will
+  // include descriptors for all the files listed in PROTO_FILES as well as
+  // all files that they import.  The plugin MUST NOT attempt to read the
+  // PROTO_FILES directly -- it must use the FileDescriptorSet.
+  //
+  // The plugin should generate whatever files are necessary, as code generators
+  // normally do.  It should write the names of all files it generates to
+  // stdout.  The names should be relative to the output directory, NOT absolute
+  // names or relative to the current directory.  If any errors occur, error
+  // messages should be written to stderr.  If an error is fatal, the plugin
+  // should exit with a non-zero exit code.
+  void AllowPlugins(const string& exe_name_prefix);
+
+  // 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 GeneratorContextImpl;
+  class MemoryOutputStream;
+
+  // 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);
+
+  // Return status for ParseArguments() and InterpretArgument().
+  enum ParseArgumentStatus {
+    PARSE_ARGUMENT_DONE_AND_CONTINUE,
+    PARSE_ARGUMENT_DONE_AND_EXIT,
+    PARSE_ARGUMENT_FAIL
+  };
+
+  // Parse all command-line arguments.
+  ParseArgumentStatus 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.
+  ParseArgumentStatus 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 vector<const FileDescriptor*>& parsed_files,
+                      const OutputDirective& output_directive,
+                      GeneratorContext* generator_context);
+  bool GeneratePluginOutput(const vector<const FileDescriptor*>& parsed_files,
+                            const string& plugin_name,
+                            const string& parameter,
+                            GeneratorContext* generator_context,
+                            string* error);
+
+  // Implements --encode and --decode.
+  bool EncodeOrDecode(const DescriptorPool* pool);
+
+  // Implements the --descriptor_set_out option.
+  bool WriteDescriptorSet(const vector<const FileDescriptor*> parsed_files);
+
+  // Get all transitive dependencies of the given file (including the file
+  // itself), adding them to the given list of FileDescriptorProtos.  The
+  // protos will be ordered such that every file is listed before any file that
+  // depends on it, so that you can call DescriptorPool::BuildFile() on them
+  // in order.  Any files in *already_seen will not be added, and each file
+  // added will be inserted into *already_seen.  If include_source_code_info is
+  // true then include the source code information in the FileDescriptorProtos.
+  static void GetTransitiveDependencies(
+      const FileDescriptor* file,
+      bool include_source_code_info,
+      set<const FileDescriptor*>* already_seen,
+      RepeatedPtrField<FileDescriptorProto>* output);
+
+  // Implements the --print_free_field_numbers. This function prints free field
+  // numbers into stdout for the message and it's nested message types in
+  // post-order, i.e. nested types first. Printed range are left-right
+  // inclusive, i.e. [a, b].
+  //
+  // Groups:
+  // For historical reasons, groups are considered to share the same
+  // field number space with the parent message, thus it will not print free
+  // field numbers for groups. The field numbers used in the groups are
+  // excluded in the free field numbers of the parent message.
+  //
+  // Extension Ranges:
+  // Extension ranges are considered ocuppied field numbers and they will not be
+  // listed as free numbers in the output.
+  void PrintFreeFieldNumbers(const Descriptor* descriptor);
+
+  // -----------------------------------------------------------------
+
+  // The name of the executable as invoked (i.e. argv[0]).
+  string executable_name_;
+
+  // Version info set with SetVersionInfo().
+  string version_info_;
+
+  // Registered generators.
+  struct GeneratorInfo {
+    string flag_name;
+    string option_flag_name;
+    CodeGenerator* generator;
+    string help_text;
+  };
+  typedef map<string, GeneratorInfo> GeneratorMap;
+  GeneratorMap generators_by_flag_name_;
+  GeneratorMap generators_by_option_name_;
+  // A map from generator names to the parameters specified using the option
+  // flag. For example, if the user invokes the compiler with:
+  //   protoc --foo_out=outputdir --foo_opt=enable_bar ...
+  // Then there will be an entry ("--foo_out", "enable_bar") in this map.
+  map<string, string> generator_parameters_;
+
+  // See AllowPlugins().  If this is empty, plugins aren't allowed.
+  string plugin_prefix_;
+
+  // Maps specific plugin names to files.  When executing a plugin, this map
+  // is searched first to find the plugin executable.  If not found here, the
+  // PATH (or other OS-specific search strategy) is searched.
+  map<string, string> plugins_;
+
+  // Stuff parsed from command line.
+  enum Mode {
+    MODE_COMPILE,  // Normal mode:  parse .proto files and compile them.
+    MODE_ENCODE,   // --encode:  read text from stdin, write binary to stdout.
+    MODE_DECODE,   // --decode:  read binary from stdin, write text to stdout.
+    MODE_PRINT,    // Print mode: print info of the given .proto files and exit.
+  };
+
+  Mode mode_;
+
+  enum PrintMode {
+    PRINT_NONE,               // Not in MODE_PRINT
+    PRINT_FREE_FIELDS,        // --print_free_fields
+  };
+
+  PrintMode print_mode_;
+
+  enum ErrorFormat {
+    ERROR_FORMAT_GCC,   // GCC error output format (default).
+    ERROR_FORMAT_MSVS   // Visual Studio output (--error_format=msvs).
+  };
+
+  ErrorFormat error_format_;
+
+  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;                // E.g. "--foo_out"
+    CodeGenerator* generator;   // NULL for plugins
+    string parameter;
+    string output_location;
+  };
+  vector<OutputDirective> output_directives_;
+
+  // When using --encode or --decode, this names the type we are encoding or
+  // decoding.  (Empty string indicates --decode_raw.)
+  string codec_type_;
+
+  // If --descriptor_set_out was given, this is the filename to which the
+  // FileDescriptorSet should be written.  Otherwise, empty.
+  string descriptor_set_name_;
+
+  // True if --include_imports was given, meaning that we should
+  // write all transitive dependencies to the DescriptorSet.  Otherwise, only
+  // the .proto files listed on the command-line are added.
+  bool imports_in_descriptor_set_;
+
+  // True if --include_source_info was given, meaning that we should not strip
+  // SourceCodeInfo from the DescriptorSet.
+  bool source_info_in_descriptor_set_;
+
+  // 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/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc b/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc
new file mode 100644
index 0000000..6bf7357
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -0,0 +1,1654 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+#else
+#include <unistd.h>
+#endif
+#include <memory>
+#include <vector>
+
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/mock_code_generator.h>
+#include <google/protobuf/compiler/subprocess.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#if defined(_WIN32)
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#ifndef F_OK
+#define F_OK 00  // not defined by MSVC for whatever reason
+#endif
+#endif
+
+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 NullCodeGenerator;
+
+  // Normally plugins are allowed for all tests.  Call this to explicitly
+  // disable them.
+  void DisallowPlugins() { disallow_plugins_ = true; }
+
+  // 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);
+
+  // Create a subdirectory within temp_directory_.
+  void CreateTempDir(const string& name);
+
+  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);
+
+  // Like ExpectErrorSubstring, but checks that Run() returned zero.
+  void ExpectErrorSubstringWithZeroReturnCode(
+      const string& expected_substring);
+
+  // Checks that the captured stdout is the same as the expected_text.
+  void ExpectCapturedStdout(const string& expected_text);
+
+  // 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 (or the generator in test_plugin.cc, which produces the same
+  // output).  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);
+  void ExpectGenerated(const string& generator_name,
+                       const string& parameter,
+                       const string& proto_name,
+                       const string& message_name,
+                       const string& output_directory);
+  void ExpectGeneratedWithMultipleInputs(const string& generator_name,
+                                         const string& all_proto_names,
+                                         const string& proto_name,
+                                         const string& message_name);
+  void ExpectGeneratedWithInsertions(const string& generator_name,
+                                     const string& parameter,
+                                     const string& insertions,
+                                     const string& proto_name,
+                                     const string& message_name);
+
+  void ExpectNullCodeGeneratorCalled(const string& parameter);
+
+  void ReadDescriptorSet(const string& filename,
+                         FileDescriptorSet* descriptor_set);
+
+ private:
+  // The object we are testing.
+  CommandLineInterface cli_;
+
+  // Was DisallowPlugins() called?
+  bool disallow_plugins_;
+
+  // 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_;
+
+  // The captured stdout.
+  string captured_stdout_;
+
+  // Pointers which need to be deleted later.
+  vector<CodeGenerator*> mock_generators_to_delete_;
+
+  NullCodeGenerator* null_generator_;
+};
+
+class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator {
+ public:
+  NullCodeGenerator() : called_(false) {}
+  ~NullCodeGenerator() {}
+
+  mutable bool called_;
+  mutable string parameter_;
+
+  // implements CodeGenerator ----------------------------------------
+  bool Generate(const FileDescriptor* file,
+                const string& parameter,
+                GeneratorContext* context,
+                string* error) const {
+    called_ = true;
+    parameter_ = parameter;
+    return true;
+  }
+};
+
+// ===================================================================
+
+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_OK(File::CreateDir(temp_directory_, 0777));
+
+  // Register generators.
+  CodeGenerator* generator = new MockCodeGenerator("test_generator");
+  mock_generators_to_delete_.push_back(generator);
+  cli_.RegisterGenerator("--test_out", "--test_opt", generator, "Test output.");
+  cli_.RegisterGenerator("-t", generator, "Test output.");
+
+  generator = new MockCodeGenerator("alt_generator");
+  mock_generators_to_delete_.push_back(generator);
+  cli_.RegisterGenerator("--alt_out", generator, "Alt output.");
+
+  generator = null_generator_ = new NullCodeGenerator();
+  mock_generators_to_delete_.push_back(generator);
+  cli_.RegisterGenerator("--null_out", generator, "Null output.");
+
+  disallow_plugins_ = false;
+}
+
+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 = Split(command, " ", true);
+
+  if (!disallow_plugins_) {
+    cli_.AllowPlugins("prefix-");
+    const char* possible_paths[] = {
+      // When building with shared libraries, libtool hides the real executable
+      // in .libs and puts a fake wrapper in the current directory.
+      // Unfortunately, due to an apparent bug on Cygwin/MinGW, if one program
+      // wrapped in this way (e.g. protobuf-tests.exe) tries to execute another
+      // program wrapped in this way (e.g. test_plugin.exe), the latter fails
+      // with error code 127 and no explanation message.  Presumably the problem
+      // is that the wrapper for protobuf-tests.exe set some environment
+      // variables that confuse the wrapper for test_plugin.exe.  Luckily, it
+      // turns out that if we simply invoke the wrapped test_plugin.exe
+      // directly, it works -- I guess the environment variables set by the
+      // protobuf-tests.exe wrapper happen to be correct for it too.  So we do
+      // that.
+      ".libs/test_plugin.exe",  // Win32 w/autotool (Cygwin / MinGW)
+      "test_plugin.exe",        // Other Win32 (MSVC)
+      "test_plugin",            // Unix
+    };
+
+    string plugin_path;
+
+    for (int i = 0; i < GOOGLE_ARRAYSIZE(possible_paths); i++) {
+      if (access(possible_paths[i], F_OK) == 0) {
+        plugin_path = possible_paths[i];
+        break;
+      }
+    }
+
+    if (plugin_path.empty()) {
+      GOOGLE_LOG(ERROR)
+          << "Plugin executable not found.  Plugin tests are likely to fail.";
+    } else {
+      args.push_back("--plugin=prefix-gen-plug=" + plugin_path);
+    }
+  }
+
+  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();
+  }
+
+  // TODO(jieluo): Cygwin doesn't work well if we try to capture stderr and
+  // stdout at the same time. Need to figure out why and add this capture back
+  // for Cygwin.
+#if !defined(__CYGWIN__)
+  CaptureTestStdout();
+#endif
+  CaptureTestStderr();
+
+  return_code_ = cli_.Run(args.size(), argv.get());
+
+  error_text_ = GetCapturedTestStderr();
+#if !defined(__CYGWIN__)
+  captured_stdout_ = GetCapturedTestStdout();
+#endif
+}
+
+// -------------------------------------------------------------------
+
+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);
+    if (!File::Exists(temp_directory_ + "/" + dir)) {
+      GOOGLE_CHECK_OK(File::RecursivelyCreateDir(temp_directory_ + "/" + dir,
+                                          0777));
+    }
+  }
+
+  // Write file.
+  string full_name = temp_directory_ + "/" + name;
+  GOOGLE_CHECK_OK(File::SetContents(full_name, contents, true));
+}
+
+void CommandLineInterfaceTest::CreateTempDir(const string& name) {
+  GOOGLE_CHECK_OK(File::RecursivelyCreateDir(temp_directory_ + "/" + name,
+                                      0777));
+}
+
+// -------------------------------------------------------------------
+
+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_);
+}
+
+void CommandLineInterfaceTest::ExpectErrorSubstringWithZeroReturnCode(
+    const string& expected_substring) {
+  EXPECT_EQ(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) {
+  MockCodeGenerator::ExpectGenerated(
+      generator_name, parameter, "", proto_name, message_name, proto_name,
+      temp_directory_);
+}
+
+void CommandLineInterfaceTest::ExpectGenerated(
+    const string& generator_name,
+    const string& parameter,
+    const string& proto_name,
+    const string& message_name,
+    const string& output_directory) {
+  MockCodeGenerator::ExpectGenerated(
+      generator_name, parameter, "", proto_name, message_name, proto_name,
+      temp_directory_ + "/" + output_directory);
+}
+
+void CommandLineInterfaceTest::ExpectGeneratedWithMultipleInputs(
+    const string& generator_name,
+    const string& all_proto_names,
+    const string& proto_name,
+    const string& message_name) {
+  MockCodeGenerator::ExpectGenerated(
+      generator_name, "", "", proto_name, message_name,
+      all_proto_names,
+      temp_directory_);
+}
+
+void CommandLineInterfaceTest::ExpectGeneratedWithInsertions(
+    const string& generator_name,
+    const string& parameter,
+    const string& insertions,
+    const string& proto_name,
+    const string& message_name) {
+  MockCodeGenerator::ExpectGenerated(
+      generator_name, parameter, insertions, proto_name, message_name,
+      proto_name, temp_directory_);
+}
+
+void CommandLineInterfaceTest::ExpectNullCodeGeneratorCalled(
+    const string& parameter) {
+  EXPECT_TRUE(null_generator_->called_);
+  EXPECT_EQ(parameter, null_generator_->parameter_);
+}
+
+void CommandLineInterfaceTest::ReadDescriptorSet(
+    const string& filename, FileDescriptorSet* descriptor_set) {
+  string path = temp_directory_ + "/" + filename;
+  string file_contents;
+  GOOGLE_CHECK_OK(File::GetContents(path, &file_contents, true));
+
+  if (!descriptor_set->ParseFromString(file_contents)) {
+    FAIL() << "Could not parse file contents: " << path;
+  }
+}
+
+void CommandLineInterfaceTest::ExpectCapturedStdout(
+    const string& expected_text) {
+  EXPECT_EQ(expected_text, captured_stdout_);
+}
+
+// ===================================================================
+
+TEST_F(CommandLineInterfaceTest, BasicOutput) {
+  // Test that the common case works.
+
+  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");
+}
+
+TEST_F(CommandLineInterfaceTest, BasicPlugin) {
+  // Test that basic plugins work.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --plug_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorAndPlugin) {
+  // Invoke a generator and a plugin at the same time.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+  ExpectGenerated("test_plugin", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputs) {
+  // Test parsing multiple input files.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "message Bar {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto bar.proto");
+
+  ExpectNoErrors();
+  ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+                                    "foo.proto", "Foo");
+  ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+                                    "bar.proto", "Bar");
+  ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+                                    "foo.proto", "Foo");
+  ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+                                    "bar.proto", "Bar");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleInputsWithImport) {
+  // Test parsing multiple input files with an import of a separate file.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "import \"baz.proto\";\n"
+    "message Bar {\n"
+    "  optional Baz a = 1;\n"
+    "}\n");
+  CreateTempFile("baz.proto",
+    "syntax = \"proto2\";\n"
+    "message Baz {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir --plug_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto bar.proto");
+
+  ExpectNoErrors();
+  ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+                                    "foo.proto", "Foo");
+  ExpectGeneratedWithMultipleInputs("test_generator", "foo.proto,bar.proto",
+                                    "bar.proto", "Bar");
+  ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+                                    "foo.proto", "Foo");
+  ExpectGeneratedWithMultipleInputs("test_plugin", "foo.proto,bar.proto",
+                                    "bar.proto", "Bar");
+}
+
+TEST_F(CommandLineInterfaceTest, CreateDirectory) {
+  // Test that when we output to a sub-directory, it is created.
+
+  CreateTempFile("bar/baz/foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempDir("out");
+  CreateTempDir("plugout");
+
+  Run("protocol_compiler --test_out=$tmpdir/out --plug_out=$tmpdir/plugout "
+      "--proto_path=$tmpdir bar/baz/foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "bar/baz/foo.proto", "Foo", "out");
+  ExpectGenerated("test_plugin", "", "bar/baz/foo.proto", "Foo", "plugout");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorParameters) {
+  // Test that generator parameters are correctly parsed from the command line.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --test_out=TestParameter:$tmpdir "
+      "--plug_out=TestPluginParameter:$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "TestParameter", "foo.proto", "Foo");
+  ExpectGenerated("test_plugin", "TestPluginParameter", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, ExtraGeneratorParameters) {
+  // Test that generator parameters specified with the option flag are
+  // correctly passed to the code generator.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  // Create the "a" and "b" sub-directories.
+  CreateTempDir("a");
+  CreateTempDir("b");
+
+  Run("protocol_compiler "
+      "--test_opt=foo1 "
+      "--test_out=bar:$tmpdir/a "
+      "--test_opt=foo2 "
+      "--test_out=baz:$tmpdir/b "
+      "--test_opt=foo3 "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated(
+      "test_generator", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a");
+  ExpectGenerated(
+      "test_generator", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b");
+}
+
+TEST_F(CommandLineInterfaceTest, Insert) {
+  // Test running a generator that inserts code into another's output.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler "
+      "--test_out=TestParameter:$tmpdir "
+      "--plug_out=TestPluginParameter:$tmpdir "
+      "--test_out=insert=test_generator,test_plugin:$tmpdir "
+      "--plug_out=insert=test_generator,test_plugin:$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGeneratedWithInsertions(
+      "test_generator", "TestParameter", "test_generator,test_plugin",
+      "foo.proto", "Foo");
+  ExpectGeneratedWithInsertions(
+      "test_plugin", "TestPluginParameter", "test_generator,test_plugin",
+      "foo.proto", "Foo");
+}
+
+#if defined(_WIN32)
+
+TEST_F(CommandLineInterfaceTest, WindowsOutputPath) {
+  // Test that the output path can be a Windows-style path.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n");
+
+  Run("protocol_compiler --null_out=C:\\ "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectNullCodeGeneratorCalled("");
+}
+
+TEST_F(CommandLineInterfaceTest, WindowsOutputPathAndParameter) {
+  // Test that we can have a windows-style output path and a parameter.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n");
+
+  Run("protocol_compiler --null_out=bar:C:\\ "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectNullCodeGeneratorCalled("bar");
+}
+
+TEST_F(CommandLineInterfaceTest, TrailingBackslash) {
+  // Test that the directories can end in backslashes.  Some users claim this
+  // doesn't work on their system.
+
+  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");
+}
+
+#endif  // defined(_WIN32) || defined(__CYGWIN__)
+
+TEST_F(CommandLineInterfaceTest, PathLookup) {
+  // Test that specifying multiple directories in the proto search path works.
+
+  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");
+}
+
+TEST_F(CommandLineInterfaceTest, ColonDelimitedPath) {
+  // Same as PathLookup, but we provide the proto_path in a single flag.
+
+  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");
+}
+
+TEST_F(CommandLineInterfaceTest, NonRootMapping) {
+  // Test setting up a search path mapping a directory to a non-root location.
+
+  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");
+}
+
+TEST_F(CommandLineInterfaceTest, MultipleGenerators) {
+  // Test that we can have multiple generators and use both in one invocation,
+  // each with a different output directory.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  // Create the "a" and "b" sub-directories.
+  CreateTempDir("a");
+  CreateTempDir("b");
+
+  Run("protocol_compiler "
+      "--test_out=$tmpdir/a "
+      "--alt_out=$tmpdir/b "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo", "a");
+  ExpectGenerated("alt_generator", "", "foo.proto", "Foo", "b");
+}
+
+TEST_F(CommandLineInterfaceTest, DisallowServicesNoServices) {
+  // Test that --disallow_services doesn't cause a problem when there are no
+  // services.
+
+  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");
+}
+
+TEST_F(CommandLineInterfaceTest, DisallowServicesHasService) {
+  // Test that --disallow_services produces an error when there are services.
+
+  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.
+
+  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");
+}
+
+TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) {
+  // Test that we can accept working-directory-relative input files.
+
+  SetInputsAreProtoPathRelative(false);
+
+  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");
+}
+
+TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "import \"foo.proto\";\n"
+    "message Bar {\n"
+    "  optional Foo foo = 1;\n"
+    "}\n");
+
+  Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+      "--proto_path=$tmpdir bar.proto");
+
+  ExpectNoErrors();
+
+  FileDescriptorSet descriptor_set;
+  ReadDescriptorSet("descriptor_set", &descriptor_set);
+  if (HasFatalFailure()) return;
+  EXPECT_EQ(1, descriptor_set.file_size());
+  EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
+  // Descriptor set should not have source code info.
+  EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "import \"foo.proto\";\n"
+    "message Bar {\n"
+    "  optional Foo foo = 1;\n"
+    "}\n");
+
+  Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+      "--include_source_info --proto_path=$tmpdir bar.proto");
+
+  ExpectNoErrors();
+
+  FileDescriptorSet descriptor_set;
+  ReadDescriptorSet("descriptor_set", &descriptor_set);
+  if (HasFatalFailure()) return;
+  EXPECT_EQ(1, descriptor_set.file_size());
+  EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
+  // Source code info included.
+  EXPECT_TRUE(descriptor_set.file(0).has_source_code_info());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSet) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "import \"foo.proto\";\n"
+    "message Bar {\n"
+    "  optional Foo foo = 1;\n"
+    "}\n");
+
+  Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+      "--include_imports --proto_path=$tmpdir bar.proto");
+
+  ExpectNoErrors();
+
+  FileDescriptorSet descriptor_set;
+  ReadDescriptorSet("descriptor_set", &descriptor_set);
+  if (HasFatalFailure()) return;
+  EXPECT_EQ(2, descriptor_set.file_size());
+  if (descriptor_set.file(0).name() == "bar.proto") {
+    std::swap(descriptor_set.mutable_file()->mutable_data()[0],
+              descriptor_set.mutable_file()->mutable_data()[1]);
+  }
+  EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+  EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
+  // Descriptor set should not have source code info.
+  EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
+  EXPECT_FALSE(descriptor_set.file(1).has_source_code_info());
+}
+
+TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSetWithSourceInfo) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+  CreateTempFile("bar.proto",
+    "syntax = \"proto2\";\n"
+    "import \"foo.proto\";\n"
+    "message Bar {\n"
+    "  optional Foo foo = 1;\n"
+    "}\n");
+
+  Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+      "--include_imports --include_source_info --proto_path=$tmpdir bar.proto");
+
+  ExpectNoErrors();
+
+  FileDescriptorSet descriptor_set;
+  ReadDescriptorSet("descriptor_set", &descriptor_set);
+  if (HasFatalFailure()) return;
+  EXPECT_EQ(2, descriptor_set.file_size());
+  if (descriptor_set.file(0).name() == "bar.proto") {
+    std::swap(descriptor_set.mutable_file()->mutable_data()[0],
+              descriptor_set.mutable_file()->mutable_data()[1]);
+  }
+  EXPECT_EQ("foo.proto", descriptor_set.file(0).name());
+  EXPECT_EQ("bar.proto", descriptor_set.file(1).name());
+  // Source code info included.
+  EXPECT_TRUE(descriptor_set.file(0).has_source_code_info());
+  EXPECT_TRUE(descriptor_set.file(1).has_source_code_info());
+}
+
+// -------------------------------------------------------------------
+
+TEST_F(CommandLineInterfaceTest, ParseErrors) {
+  // Test that parse errors are reported.
+
+  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.
+
+  // 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.
+
+  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);
+
+  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);
+
+  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.  Note that the "
+      "proto_path must be an exact prefix of the .proto file "
+      "names -- protoc is too dumb to figure out when two paths "
+      "(e.g. absolute and relative) are equivalent (it's harder "
+      "than you think).\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);
+
+  // 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);
+
+  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.
+
+  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.
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir");
+
+  ExpectErrorText("Missing input file.\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingOutputError) {
+  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) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  string output_file =
+      MockCodeGenerator::GetOutputFileName("test_generator", "foo.proto");
+
+  // Create a directory blocking our output location.
+  CreateTempDir(output_file);
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  // MockCodeGenerator no longer detects an error because we actually write to
+  // an in-memory location first, then dump to disk at the end.  This is no
+  // big deal.
+  //   ExpectErrorSubstring("MockCodeGenerator detected write error.");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  // Windows with MSVCRT.dll produces EPERM instead of EISDIR.
+  if (HasAlternateErrorSubstring(output_file + ": Permission denied")) {
+    return;
+  }
+#endif
+
+  ExpectErrorSubstring(output_file + ": Is a directory");
+}
+
+TEST_F(CommandLineInterfaceTest, PluginOutputWriteError) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  string output_file =
+      MockCodeGenerator::GetOutputFileName("test_plugin", "foo.proto");
+
+  // Create a directory blocking our output location.
+  CreateTempDir(output_file);
+
+  Run("protocol_compiler --plug_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+  // Windows with MSVCRT.dll produces EPERM instead of EISDIR.
+  if (HasAlternateErrorSubstring(output_file + ": Permission denied")) {
+    return;
+  }
+#endif
+
+  ExpectErrorSubstring(output_file + ": Is a directory");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputDirectoryNotFoundError) {
+  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, PluginOutputDirectoryNotFoundError) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --plug_out=$tmpdir/nosuchdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorSubstring("nosuchdir/: No such file or directory");
+}
+
+TEST_F(CommandLineInterfaceTest, OutputDirectoryIsFileError) {
+  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) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message MockCodeGenerator_Error {}\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorSubstring(
+      "--test_out: foo.proto: Saw message type MockCodeGenerator_Error.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginError) {
+  // Test a generator plugin that returns an error.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message MockCodeGenerator_Error {}\n");
+
+  Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorSubstring(
+      "--plug_out: foo.proto: Saw message type MockCodeGenerator_Error.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginFail) {
+  // Test a generator plugin that exits with an error code.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message MockCodeGenerator_Exit {}\n");
+
+  Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorSubstring("Saw message type MockCodeGenerator_Exit.");
+  ExpectErrorSubstring(
+      "--plug_out: prefix-gen-plug: Plugin failed with status code 123.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginCrash) {
+  // Test a generator plugin that crashes.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message MockCodeGenerator_Abort {}\n");
+
+  Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectErrorSubstring("Saw message type MockCodeGenerator_Abort.");
+
+#ifdef _WIN32
+  // Windows doesn't have signals.  It looks like abort()ing causes the process
+  // to exit with status code 3, but let's not depend on the exact number here.
+  ExpectErrorSubstring(
+      "--plug_out: prefix-gen-plug: Plugin failed with status code");
+#else
+  // Don't depend on the exact signal number.
+  ExpectErrorSubstring(
+      "--plug_out: prefix-gen-plug: Plugin killed by signal");
+#endif
+}
+
+TEST_F(CommandLineInterfaceTest, PluginReceivesSourceCodeInfo) {
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message MockCodeGenerator_HasSourceCodeInfo {}\n");
+
+  Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto");
+
+  ExpectErrorSubstring(
+      "Saw message type MockCodeGenerator_HasSourceCodeInfo: 1.");
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) {
+  // Test what happens if the plugin isn't found.
+
+  CreateTempFile("error.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler --badplug_out=TestParameter:$tmpdir "
+      "--plugin=prefix-gen-badplug=no_such_file "
+      "--proto_path=$tmpdir error.proto");
+
+#ifdef _WIN32
+  ExpectErrorSubstring("--badplug_out: prefix-gen-badplug: " +
+      Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND));
+#else
+  // Error written to stdout by child process after exec() fails.
+  ExpectErrorSubstring(
+      "no_such_file: program not found or is not executable");
+
+  // Error written by parent process when child fails.
+  ExpectErrorSubstring(
+      "--badplug_out: prefix-gen-badplug: Plugin failed with status code 1.");
+#endif
+}
+
+TEST_F(CommandLineInterfaceTest, GeneratorPluginNotAllowed) {
+  // Test what happens if plugins aren't allowed.
+
+  CreateTempFile("error.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  DisallowPlugins();
+  Run("protocol_compiler --plug_out=TestParameter:$tmpdir "
+      "--proto_path=$tmpdir error.proto");
+
+  ExpectErrorSubstring("Unknown flag: --plug_out");
+}
+
+TEST_F(CommandLineInterfaceTest, HelpText) {
+  Run("test_exec_name --help");
+
+  ExpectErrorSubstringWithZeroReturnCode("Usage: test_exec_name ");
+  ExpectErrorSubstringWithZeroReturnCode("--test_out=OUT_DIR");
+  ExpectErrorSubstringWithZeroReturnCode("Test output.");
+  ExpectErrorSubstringWithZeroReturnCode("--alt_out=OUT_DIR");
+  ExpectErrorSubstringWithZeroReturnCode("Alt output.");
+}
+
+TEST_F(CommandLineInterfaceTest, GccFormatErrors) {
+  // Test --error_format=gcc (which is the default, but we want to verify
+  // that it can be set explicitly).
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "badsyntax\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir --error_format=gcc foo.proto");
+
+  ExpectErrorText(
+    "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) {
+  // Test --error_format=msvs
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "badsyntax\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir --error_format=msvs foo.proto");
+
+  ExpectErrorText(
+    "$tmpdir/foo.proto(2) : error in column=1: Expected top-level statement "
+      "(e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) {
+  // Test --error_format=msvs
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "badsyntax\n");
+
+  Run("protocol_compiler --test_out=$tmpdir "
+      "--proto_path=$tmpdir --error_format=invalid foo.proto");
+
+  ExpectErrorText(
+    "Unknown error format: invalid\n");
+}
+
+// -------------------------------------------------------------------
+// Flag parsing tests
+
+TEST_F(CommandLineInterfaceTest, ParseSingleCharacterFlag) {
+  // Test that a single-character flag works.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler -t$tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseSpaceDelimitedValue) {
+  // Test that separating the flag value with a space works.
+
+  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");
+}
+
+TEST_F(CommandLineInterfaceTest, ParseSingleCharacterSpaceDelimitedValue) {
+  // Test that separating the flag value with a space works for
+  // single-character flags.
+
+  CreateTempFile("foo.proto",
+    "syntax = \"proto2\";\n"
+    "message Foo {}\n");
+
+  Run("protocol_compiler -t $tmpdir "
+      "--proto_path=$tmpdir foo.proto");
+
+  ExpectNoErrors();
+  ExpectGenerated("test_generator", "", "foo.proto", "Foo");
+}
+
+TEST_F(CommandLineInterfaceTest, MissingValueError) {
+  // Test that we get an error if a flag is missing its value.
+
+  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.
+
+  Run("protocol_compiler --test_out");
+
+  ExpectErrorText("Missing value for flag: --test_out\n");
+}
+
+TEST_F(CommandLineInterfaceTest, PrintFreeFieldNumbers) {
+  CreateTempFile(
+      "foo.proto",
+      "syntax = \"proto2\";\n"
+      "package foo;\n"
+      "message Foo {\n"
+      "  optional int32 a = 2;\n"
+      "  optional string b = 4;\n"
+      "  optional string c = 5;\n"
+      "  optional int64 d = 8;\n"
+      "  optional double e = 10;\n"
+      "}\n");
+  CreateTempFile(
+      "bar.proto",
+      "syntax = \"proto2\";\n"
+      "message Bar {\n"
+      "  optional int32 a = 2;\n"
+      "  extensions 4 to 5;\n"
+      "  optional int64 d = 8;\n"
+      "  extensions 10;\n"
+      "}\n");
+  CreateTempFile(
+      "baz.proto",
+      "syntax = \"proto2\";\n"
+      "message Baz {\n"
+      "  optional int32 a = 2;\n"
+      "  optional int64 d = 8;\n"
+      "  extensions 15 to max;\n"  // unordered.
+      "  extensions 13;\n"
+      "  extensions 10 to 12;\n"
+      "  extensions 5;\n"
+      "  extensions 4;\n"
+      "}\n");
+  CreateTempFile(
+      "quz.proto",
+      "syntax = \"proto2\";\n"
+      "message Quz {\n"
+      "  message Foo {}\n"  // nested message
+      "  optional int32 a = 2;\n"
+      "  optional group C = 4 {\n"
+      "    optional int32 d = 5;\n"
+      "  }\n"
+      "  extensions 8 to 10;\n"
+      "  optional group E = 11 {\n"
+      "    optional int32 f = 9;\n"    // explicitly reuse extension range 8-10
+      "    optional group G = 15 {\n"  // nested group
+      "      message Foo {}\n"         // nested message inside nested group
+      "    }\n"
+      "  }\n"
+      "}\n");
+
+  Run("protocol_compiler --print_free_field_numbers --proto_path=$tmpdir "
+      "foo.proto bar.proto baz.proto quz.proto");
+
+  ExpectNoErrors();
+
+  // TODO(jieluo): Cygwin doesn't work well if we try to capture stderr and
+  // stdout at the same time. Need to figure out why and add this test back
+  // for Cygwin.
+#if !defined(__CYGWIN__)
+  ExpectCapturedStdout(
+      "foo.Foo                             free: 1 3 6-7 9 11-INF\n"
+      "Bar                                 free: 1 3 6-7 9 11-INF\n"
+      "Baz                                 free: 1 3 6-7 9 14\n"
+      "Quz.Foo                             free: 1-INF\n"
+      "Quz.E.G.Foo                         free: 1-INF\n"
+      "Quz                                 free: 1 3 6-7 12-14 16-INF\n");
+#endif
+}
+
+// ===================================================================
+
+// Test for --encode and --decode.  Note that it would be easier to do this
+// test as a shell script, but we'd like to be able to run the test on
+// platforms that don't have a Bourne-compatible shell available (especially
+// Windows/MSVC).
+class EncodeDecodeTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    duped_stdin_ = dup(STDIN_FILENO);
+  }
+
+  virtual void TearDown() {
+    dup2(duped_stdin_, STDIN_FILENO);
+    close(duped_stdin_);
+  }
+
+  void RedirectStdinFromText(const string& input) {
+    string filename = TestTempDir() + "/test_stdin";
+    GOOGLE_CHECK_OK(File::SetContents(filename, input, true));
+    GOOGLE_CHECK(RedirectStdinFromFile(filename));
+  }
+
+  bool RedirectStdinFromFile(const string& filename) {
+    int fd = open(filename.c_str(), O_RDONLY);
+    if (fd < 0) return false;
+    dup2(fd, STDIN_FILENO);
+    close(fd);
+    return true;
+  }
+
+  // Remove '\r' characters from text.
+  string StripCR(const string& text) {
+    string result;
+
+    for (int i = 0; i < text.size(); i++) {
+      if (text[i] != '\r') {
+        result.push_back(text[i]);
+      }
+    }
+
+    return result;
+  }
+
+  enum Type { TEXT, BINARY };
+  enum ReturnCode { SUCCESS, ERROR };
+
+  bool Run(const string& command) {
+    vector<string> args;
+    args.push_back("protoc");
+    SplitStringUsing(command, " ", &args);
+    args.push_back("--proto_path=" + TestSourceDir());
+
+    scoped_array<const char*> argv(new const char* [args.size()]);
+    for (int i = 0; i < args.size(); i++) {
+      argv[i] = args[i].c_str();
+    }
+
+    CommandLineInterface cli;
+    cli.SetInputsAreProtoPathRelative(true);
+
+    CaptureTestStdout();
+    CaptureTestStderr();
+
+    int result = cli.Run(args.size(), argv.get());
+
+    captured_stdout_ = GetCapturedTestStdout();
+    captured_stderr_ = GetCapturedTestStderr();
+
+    return result == 0;
+  }
+
+  void ExpectStdoutMatchesBinaryFile(const string& filename) {
+    string expected_output;
+    GOOGLE_CHECK_OK(File::GetContents(filename, &expected_output, true));
+
+    // Don't use EXPECT_EQ because we don't want to print raw binary data to
+    // stdout on failure.
+    EXPECT_TRUE(captured_stdout_ == expected_output);
+  }
+
+  void ExpectStdoutMatchesTextFile(const string& filename) {
+    string expected_output;
+    GOOGLE_CHECK_OK(File::GetContents(filename, &expected_output, true));
+
+    ExpectStdoutMatchesText(expected_output);
+  }
+
+  void ExpectStdoutMatchesText(const string& expected_text) {
+    EXPECT_EQ(StripCR(expected_text), StripCR(captured_stdout_));
+  }
+
+  void ExpectStderrMatchesText(const string& expected_text) {
+    EXPECT_EQ(StripCR(expected_text), StripCR(captured_stderr_));
+  }
+
+ private:
+  int duped_stdin_;
+  string captured_stdout_;
+  string captured_stderr_;
+};
+
+TEST_F(EncodeDecodeTest, Encode) {
+  RedirectStdinFromFile(TestSourceDir() + "/google/protobuf/"
+    "testdata/text_format_unittest_data_oneof_implemented.txt");
+  EXPECT_TRUE(Run("google/protobuf/unittest.proto "
+                  "--encode=protobuf_unittest.TestAllTypes"));
+  ExpectStdoutMatchesBinaryFile(TestSourceDir() +
+    "/google/protobuf/testdata/golden_message_oneof_implemented");
+  ExpectStderrMatchesText("");
+}
+
+TEST_F(EncodeDecodeTest, Decode) {
+  RedirectStdinFromFile(TestSourceDir() +
+    "/google/protobuf/testdata/golden_message_oneof_implemented");
+  EXPECT_TRUE(Run("google/protobuf/unittest.proto "
+                  "--decode=protobuf_unittest.TestAllTypes"));
+  ExpectStdoutMatchesTextFile(TestSourceDir() +
+    "/google/protobuf/"
+    "testdata/text_format_unittest_data_oneof_implemented.txt");
+  ExpectStderrMatchesText("");
+}
+
+TEST_F(EncodeDecodeTest, Partial) {
+  RedirectStdinFromText("");
+  EXPECT_TRUE(Run("google/protobuf/unittest.proto "
+                  "--encode=protobuf_unittest.TestRequired"));
+  ExpectStdoutMatchesText("");
+  ExpectStderrMatchesText(
+    "warning:  Input message is missing required fields:  a, b, c\n");
+}
+
+TEST_F(EncodeDecodeTest, DecodeRaw) {
+  protobuf_unittest::TestAllTypes message;
+  message.set_optional_int32(123);
+  message.set_optional_string("foo");
+  string data;
+  message.SerializeToString(&data);
+
+  RedirectStdinFromText(data);
+  EXPECT_TRUE(Run("--decode_raw"));
+  ExpectStdoutMatchesText("1: 123\n"
+                          "14: \"foo\"\n");
+  ExpectStderrMatchesText("");
+}
+
+TEST_F(EncodeDecodeTest, UnknownType) {
+  EXPECT_FALSE(Run("google/protobuf/unittest.proto "
+                   "--encode=NoSuchType"));
+  ExpectStdoutMatchesText("");
+  ExpectStderrMatchesText("Type not defined: NoSuchType\n");
+}
+
+TEST_F(EncodeDecodeTest, ProtoParseError) {
+  EXPECT_FALSE(Run("google/protobuf/no_such_file.proto "
+                   "--encode=NoSuchType"));
+  ExpectStdoutMatchesText("");
+  ExpectStderrMatchesText(
+    "google/protobuf/no_such_file.proto: File not found.\n");
+}
+
+}  // anonymous namespace
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
new file mode 100644
index 0000000..4878819
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -0,0 +1,158 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/map_util.h>
+#include <google/protobuf/stubs/stl_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 MockGeneratorContext : public GeneratorContext {
+ public:
+  MockGeneratorContext() {}
+  ~MockGeneratorContext() {
+    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;
+    GOOGLE_CHECK_OK(
+        File::GetContents(TestSourceDir() + "/" + physical_filename,
+                          &actual_contents, true));
+    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 GeneratorContext --------------------------------------
+
+  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");
+  const FileDescriptor* plugin_proto_file =
+    importer.Import("google/protobuf/compiler/plugin.proto");
+  EXPECT_EQ("", error_collector.text_);
+  ASSERT_TRUE(proto_file != NULL);
+  ASSERT_TRUE(plugin_proto_file != NULL);
+
+  CppGenerator generator;
+  MockGeneratorContext context;
+  string error;
+  string parameter;
+  parameter = "dllexport_decl=LIBPROTOBUF_EXPORT";
+  ASSERT_TRUE(generator.Generate(proto_file, parameter,
+                                 &context, &error));
+  parameter = "dllexport_decl=LIBPROTOC_EXPORT";
+  ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter,
+                                 &context, &error));
+
+  context.ExpectFileMatches("google/protobuf/descriptor.pb.h",
+                            "google/protobuf/descriptor.pb.h");
+  context.ExpectFileMatches("google/protobuf/descriptor.pb.cc",
+                            "google/protobuf/descriptor.pb.cc");
+  context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.h",
+                            "google/protobuf/compiler/plugin.pb.h");
+  context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc",
+                            "google/protobuf/compiler/plugin.pb.cc");
+}
+
+}  // namespace
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc
new file mode 100644
index 0000000..c31cb5b
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -0,0 +1,288 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 {
+
+namespace {
+// The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value
+// is kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the
+// generation of the GOOGLE_ARRAYSIZE constant.
+bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
+  int32 max_value = descriptor->value(0)->number();
+  for (int i = 0; i < descriptor->value_count(); i++) {
+    if (descriptor->value(i)->number() > max_value) {
+      max_value = descriptor->value(i)->number();
+    }
+  }
+  return max_value != kint32max;
+}
+}  // namespace
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
+                             const Options& options)
+  : descriptor_(descriptor),
+    classname_(ClassName(descriptor, false)),
+    options_(options),
+    generate_array_size_(ShouldGenerateArraySize(descriptor)) {
+}
+
+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();
+    // In C++, an value of -2147483648 gets interpreted as the negative of
+    // 2147483648, and since 2147483648 can't fit in an integer, this produces a
+    // compiler warning.  This works around that issue.
+    vars["number"] = Int32ToString(descriptor_->value(i)->number());
+    vars["prefix"] = (descriptor_->containing_type() == NULL) ?
+      "" : classname_ + "_";
+
+    if (i > 0) printer->Print(",\n");
+    printer->Print(vars, "$prefix$$name$ = $number$");
+
+    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};\n");
+
+  vars["min_name"] = min_value->name();
+  vars["max_name"] = max_value->name();
+
+  if (options_.dllexport_decl.empty()) {
+    vars["dllexport"] = "";
+  } else {
+    vars["dllexport"] = options_.dllexport_decl + " ";
+  }
+
+  printer->Print(vars,
+    "$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");
+
+  if (generate_array_size_) {
+    printer->Print(vars,
+      "const int $prefix$$short_name$_ARRAYSIZE = "
+      "$prefix$$short_name$_MAX + 1;\n\n");
+  }
+
+  if (HasDescriptorMethods(descriptor_->file())) {
+    printer->Print(vars,
+      "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n");
+    // The _Name and _Parse methods
+    printer->Print(vars,
+      "inline const ::std::string& $classname$_Name($classname$ value) {\n"
+      "  return ::google::protobuf::internal::NameOfEnum(\n"
+      "    $classname$_descriptor(), value);\n"
+      "}\n");
+    printer->Print(vars,
+      "inline bool $classname$_Parse(\n"
+      "    const ::std::string& name, $classname$* value) {\n"
+      "  return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n"
+      "    $classname$_descriptor(), name, value);\n"
+      "}\n");
+  }
+}
+
+void EnumGenerator::
+GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
+  if (HasDescriptorMethods(descriptor_->file())) {
+    printer->Print(
+      "template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type {};\n"
+      "template <>\n"
+      "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
+      "  return $classname$_descriptor();\n"
+      "}\n",
+      "classname", ClassName(descriptor_, true));
+  }
+}
+
+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 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");
+  if (generate_array_size_) {
+    printer->Print(vars,
+      "static const int $nested_name$_ARRAYSIZE =\n"
+      "  $classname$_$nested_name$_ARRAYSIZE;\n");
+  }
+
+  if (HasDescriptorMethods(descriptor_->file())) {
+    printer->Print(vars,
+      "static inline const ::google::protobuf::EnumDescriptor*\n"
+      "$nested_name$_descriptor() {\n"
+      "  return $classname$_descriptor();\n"
+      "}\n");
+    printer->Print(vars,
+      "static inline const ::std::string& $nested_name$_Name($nested_name$ value) {\n"
+      "  return $classname$_Name(value);\n"
+      "}\n");
+    printer->Print(vars,
+      "static inline bool $nested_name$_Parse(const ::std::string& name,\n"
+      "    $nested_name$* value) {\n"
+      "  return $classname$_Parse(name, value);\n"
+      "}\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_;
+
+  if (HasDescriptorMethods(descriptor_->file())) {
+    printer->Print(vars,
+      "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
+      "  protobuf_AssignDescriptorsOnce();\n"
+      "  return $classname$_descriptor_;\n"
+      "}\n");
+  }
+
+  printer->Print(vars,
+    "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", Int32ToString(*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");
+    if (generate_array_size_) {
+      printer->Print(vars,
+        "const int $parent$::$nested_name$_ARRAYSIZE;\n");
+    }
+
+    printer->Print("#endif  // _MSC_VER\n");
+  }
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.h
new file mode 100644
index 0000000..1ebd7cf
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -0,0 +1,103 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/compiler/cpp/cpp_options.h>
+#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 Options& options);
+  ~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);
+
+  // Generate specialization of GetEnumDescriptor<MyEnum>().
+  // Precondition: in ::google::protobuf namespace.
+  void GenerateGetEnumDescriptorSpecializations(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_;
+  Options options_;
+  // whether to generate the *_ARRAYSIZE constant.
+  bool generate_array_size_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
new file mode 100644
index 0000000..20b18ad
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -0,0 +1,431 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+void SetEnumVariables(const FieldDescriptor* descriptor,
+                      map<string, string>* variables,
+                      const Options& options) {
+  SetCommonFieldVariables(descriptor, variables, options);
+  const EnumValueDescriptor* default_value = descriptor->default_value_enum();
+  (*variables)["type"] = ClassName(descriptor->enum_type(), true);
+  (*variables)["default"] = Int32ToString(default_value->number());
+  (*variables)["full_name"] = descriptor->full_name();
+}
+
+}  // namespace
+
+// ===================================================================
+
+EnumFieldGenerator::
+EnumFieldGenerator(const FieldDescriptor* descriptor,
+                   const Options& options)
+  : descriptor_(descriptor) {
+  SetEnumVariables(descriptor, &variables_, options);
+}
+
+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$deprecation$;\n"
+    "inline void set_$name$($type$ value)$deprecation$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $classname$::$name$() const {\n"
+    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+    "  return static_cast< $type$ >($name$_);\n"
+    "}\n"
+    "inline void $classname$::set_$name$($type$ value) {\n"
+    "  assert($type$_IsValid(value));\n"
+    "  set_has_$name$();\n"
+    "  $name$_ = value;\n"
+    "  // @@protoc_insertion_point(field_set:$full_name$)\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::
+GenerateSwappingCode(io::Printer* printer) const {
+  printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void EnumFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "int value;\n"
+    "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+    "         int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
+    "       input, &value)));\n"
+    "if ($type$_IsValid(value)) {\n"
+    "  set_$name$(static_cast< $type$ >(value));\n");
+  if (UseUnknownFieldSet(descriptor_->file())) {
+    printer->Print(variables_,
+      "} else {\n"
+      "  mutable_unknown_fields()->AddVarint($number$, value);\n");
+  } else {
+    printer->Print(
+      "} else {\n"
+      "  unknown_fields_stream.WriteVarint32(tag);\n"
+      "  unknown_fields_stream.WriteVarint32(value);\n");
+  }
+  printer->Print(variables_,
+    "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
+    "  $number$, this->$name$(), output);\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+  printer->Print(variables_,
+    "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
+    "  $number$, this->$name$(), target);\n");
+}
+
+void EnumFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ +\n"
+    "  ::google::protobuf::internal::WireFormatLite::EnumSize(this->$name$());\n");
+}
+
+// ===================================================================
+
+EnumOneofFieldGenerator::
+EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+                        const Options& options)
+  : EnumFieldGenerator(descriptor, options) {
+  SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {}
+
+void EnumOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $classname$::$name$() const {\n"
+    "  if (has_$name$()) {\n"
+    "    return static_cast< $type$ >($oneof_prefix$$name$_);\n"
+    "  }\n"
+    "  return static_cast< $type$ >($default$);\n"
+    "}\n"
+    "inline void $classname$::set_$name$($type$ value) {\n"
+    "  assert($type$_IsValid(value));\n"
+    "  if (!has_$name$()) {\n"
+    "    clear_$oneof_name$();\n"
+    "    set_has_$name$();\n"
+    "  }\n"
+    "  $oneof_prefix$$name$_ = value;\n"
+    "}\n");
+}
+
+void EnumOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$oneof_prefix$$name$_ = $default$;\n");
+}
+
+void EnumOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+  // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void EnumOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "  $classname$_default_oneof_instance_->$name$_ = $default$;\n");
+}
+
+// ===================================================================
+
+RepeatedEnumFieldGenerator::
+RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+                           const Options& options)
+  : descriptor_(descriptor) {
+  SetEnumVariables(descriptor, &variables_, options);
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+void RepeatedEnumFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "::google::protobuf::RepeatedField<int> $name$_;\n");
+  if (descriptor_->options().packed()
+      && HasGeneratedMethods(descriptor_->file())) {
+    printer->Print(variables_,
+      "mutable int _$name$_cached_byte_size_;\n");
+  }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $name$(int index) const$deprecation$;\n"
+    "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
+    "inline void add_$name$($type$ value)$deprecation$;\n");
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n"
+    "inline ::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $classname$::$name$(int index) const {\n"
+    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+    "  return static_cast< $type$ >($name$_.Get(index));\n"
+    "}\n"
+    "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+    "  assert($type$_IsValid(value));\n"
+    "  $name$_.Set(index, value);\n"
+    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+    "}\n"
+    "inline void $classname$::add_$name$($type$ value) {\n"
+    "  assert($type$_IsValid(value));\n"
+    "  $name$_.Add(value);\n"
+    "  // @@protoc_insertion_point(field_add:$full_name$)\n"
+    "}\n");
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedField<int>&\n"
+    "$classname$::$name$() const {\n"
+    "  // @@protoc_insertion_point(field_list:$full_name$)\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline ::google::protobuf::RepeatedField<int>*\n"
+    "$classname$::mutable_$name$() {\n"
+    "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+    "  return &$name$_;\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::
+GenerateSwappingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  // Not needed for repeated fields.
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  // Don't use ReadRepeatedPrimitive here so that the enum can be validated.
+  printer->Print(variables_,
+    "int value;\n"
+    "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+    "         int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
+    "       input, &value)));\n"
+    "if ($type$_IsValid(value)) {\n"
+    "  add_$name$(static_cast< $type$ >(value));\n");
+  if (UseUnknownFieldSet(descriptor_->file())) {
+    printer->Print(variables_,
+      "} else {\n"
+      "  mutable_unknown_fields()->AddVarint($number$, value);\n");
+  } else {
+    printer->Print(
+      "} else {\n"
+      "  unknown_fields_stream.WriteVarint32(tag);\n"
+      "  unknown_fields_stream.WriteVarint32(value);\n");
+  }
+  printer->Print("}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
+  if (!descriptor_->options().packed()) {
+    // We use a non-inlined implementation in this case, since this path will
+    // rarely be executed.
+    printer->Print(variables_,
+      "DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(\n"
+      "       input,\n"
+      "       &$type$_IsValid,\n"
+      "       this->mutable_$name$())));\n");
+  } else {
+    printer->Print(variables_,
+      "::google::protobuf::uint32 length;\n"
+      "DO_(input->ReadVarint32(&length));\n"
+      "::google::protobuf::io::CodedInputStream::Limit limit = "
+          "input->PushLimit(length);\n"
+      "while (input->BytesUntilLimit() > 0) {\n"
+      "  int value;\n"
+      "  DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+      "         int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
+      "       input, &value)));\n"
+      "  if ($type$_IsValid(value)) {\n"
+      "    add_$name$(static_cast< $type$ >(value));\n"
+      "  }\n"
+      "}\n"
+      "input->PopLimit(limit);\n");
+  }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  if (descriptor_->options().packed()) {
+    // Write the tag and the size.
+    printer->Print(variables_,
+      "if (this->$name$_size() > 0) {\n"
+      "  ::google::protobuf::internal::WireFormatLite::WriteTag(\n"
+      "    $number$,\n"
+      "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+      "    output);\n"
+      "  output->WriteVarint32(_$name$_cached_byte_size_);\n"
+      "}\n");
+  }
+  printer->Print(variables_,
+      "for (int i = 0; i < this->$name$_size(); i++) {\n");
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "  ::google::protobuf::internal::WireFormatLite::WriteEnumNoTag(\n"
+      "    this->$name$(i), output);\n");
+  } else {
+    printer->Print(variables_,
+      "  ::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
+      "    $number$, this->$name$(i), output);\n");
+  }
+  printer->Print("}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+  if (descriptor_->options().packed()) {
+    // Write the tag and the size.
+    printer->Print(variables_,
+      "if (this->$name$_size() > 0) {\n"
+      "  target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
+      "    $number$,\n"
+      "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+      "    target);\n"
+      "  target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
+      "    _$name$_cached_byte_size_, target);\n"
+      "}\n");
+  }
+  printer->Print(variables_,
+      "for (int i = 0; i < this->$name$_size(); i++) {\n");
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "  target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
+      "    this->$name$(i), target);\n");
+  } else {
+    printer->Print(variables_,
+      "  target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
+      "    $number$, this->$name$(i), target);\n");
+  }
+  printer->Print("}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "{\n"
+    "  int data_size = 0;\n");
+  printer->Indent();
+  printer->Print(variables_,
+      "for (int i = 0; i < this->$name$_size(); i++) {\n"
+      "  data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(\n"
+      "    this->$name$(i));\n"
+      "}\n");
+
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "if (data_size > 0) {\n"
+      "  total_size += $tag_size$ +\n"
+      "    ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
+      "}\n"
+      "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+      "_$name$_cached_byte_size_ = data_size;\n"
+      "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+      "total_size += data_size;\n");
+  } else {
+    printer->Print(variables_,
+      "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
+  }
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.h
new file mode 100644
index 0000000..def2b23
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.h
@@ -0,0 +1,122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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,
+                              const Options& options);
+  ~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 GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ protected:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
+};
+
+class EnumOneofFieldGenerator : public EnumFieldGenerator {
+ public:
+  explicit EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                   const Options& options);
+  ~EnumOneofFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumOneofFieldGenerator);
+};
+
+class RepeatedEnumFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+                                      const Options& options);
+  ~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 GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizesToArray(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/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc
new file mode 100644
index 0000000..468ca48
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -0,0 +1,210 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <map>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+// Returns the fully-qualified class name of the message that this field
+// extends. This function is used in the Google-internal code to handle some
+// legacy cases.
+string ExtendeeClassName(const FieldDescriptor* descriptor) {
+  const Descriptor* extendee = descriptor->containing_type();
+  return ClassName(extendee, true);
+}
+
+}  // anonymous namespace
+
+ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
+                                       const Options& options)
+  : descriptor_(descriptor),
+    options_(options) {
+  // 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(", ");
+      type_traits_.append(ClassName(descriptor_->enum_type(), true));
+      type_traits_.append("_IsValid>");
+      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"     ] = ExtendeeClassName(descriptor_);
+  vars["number"       ] = SimpleItoa(descriptor_->number());
+  vars["type_traits"  ] = type_traits_;
+  vars["name"         ] = descriptor_->name();
+  vars["field_type"   ] = SimpleItoa(static_cast<int>(descriptor_->type()));
+  vars["packed"       ] = descriptor_->options().packed() ? "true" : "false";
+  vars["constant_name"] = FieldConstantName(descriptor_);
+
+  // If this is a class member, it needs to be declared "static".  Otherwise,
+  // it needs to be "extern".  In the latter case, it also needs the DLL
+  // export/import specifier.
+  if (descriptor_->extension_scope() == NULL) {
+    vars["qualifier"] = "extern";
+    if (!options_.dllexport_decl.empty()) {
+      vars["qualifier"] = options_.dllexport_decl + " " + vars["qualifier"];
+    }
+  } else {
+    vars["qualifier"] = "static";
+  }
+
+  printer->Print(vars,
+    "static const int $constant_name$ = $number$;\n"
+    "$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
+    "    ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
+    "  $name$;\n"
+    );
+
+}
+
+void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
+  // If this is a class member, it needs to be declared in its class scope.
+  string scope = (descriptor_->extension_scope() == NULL) ? "" :
+    ClassName(descriptor_->extension_scope(), false) + "::";
+  string name = scope + descriptor_->name();
+
+  map<string, string> vars;
+  vars["extendee"     ] = ExtendeeClassName(descriptor_);
+  vars["type_traits"  ] = type_traits_;
+  vars["name"         ] = name;
+  vars["constant_name"] = FieldConstantName(descriptor_);
+  vars["default"      ] = DefaultValue(descriptor_);
+  vars["field_type"   ] = SimpleItoa(static_cast<int>(descriptor_->type()));
+  vars["packed"       ] = descriptor_->options().packed() ? "true" : "false";
+  vars["scope"        ] = scope;
+
+  if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+    // We need to declare a global string which will contain the default value.
+    // We cannot declare it at class scope because that would require exposing
+    // it in the header which would be annoying for other reasons.  So we
+    // replace :: with _ in the name and declare it as a global.
+    string global_name = StringReplace(name, "::", "_", true);
+    vars["global_name"] = global_name;
+    printer->Print(vars,
+      "const ::std::string $global_name$_default($default$);\n");
+
+    // Update the default to refer to the string global.
+    vars["default"] = global_name + "_default";
+  }
+
+  // Likewise, class members need to declare the field constant variable.
+  if (descriptor_->extension_scope() != NULL) {
+    printer->Print(vars,
+      "#ifndef _MSC_VER\n"
+      "const int $scope$$constant_name$;\n"
+      "#endif\n");
+  }
+
+  printer->Print(vars,
+    "::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
+    "    ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
+    "  $name$($constant_name$, $default$);\n");
+}
+
+void ExtensionGenerator::GenerateRegistration(io::Printer* printer) {
+  map<string, string> vars;
+  vars["extendee"   ] = ExtendeeClassName(descriptor_);
+  vars["number"     ] = SimpleItoa(descriptor_->number());
+  vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type()));
+  vars["is_repeated"] = descriptor_->is_repeated() ? "true" : "false";
+  vars["is_packed"  ] = (descriptor_->is_repeated() &&
+                         descriptor_->options().packed())
+                        ? "true" : "false";
+
+  switch (descriptor_->cpp_type()) {
+    case FieldDescriptor::CPPTYPE_ENUM:
+      printer->Print(vars,
+        "::google::protobuf::internal::ExtensionSet::RegisterEnumExtension(\n"
+        "  &$extendee$::default_instance(),\n"
+        "  $number$, $field_type$, $is_repeated$, $is_packed$,\n");
+      printer->Print(
+        "  &$type$_IsValid);\n",
+        "type", ClassName(descriptor_->enum_type(), true));
+      break;
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      printer->Print(vars,
+        "::google::protobuf::internal::ExtensionSet::RegisterMessageExtension(\n"
+        "  &$extendee$::default_instance(),\n"
+        "  $number$, $field_type$, $is_repeated$, $is_packed$,\n");
+      printer->Print(
+        "  &$type$::default_instance());\n",
+        "type", ClassName(descriptor_->message_type(), true));
+      break;
+    default:
+      printer->Print(vars,
+        "::google::protobuf::internal::ExtensionSet::RegisterExtension(\n"
+        "  &$extendee$::default_instance(),\n"
+        "  $number$, $field_type$, $is_repeated$, $is_packed$);\n");
+      break;
+  }
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.h
new file mode 100644
index 0000000..d354c16
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_extension.h
@@ -0,0 +1,86 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+#include <google/protobuf/compiler/cpp/cpp_options.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* desycriptor,
+                              const Options& options);
+  ~ExtensionGenerator();
+
+  // Header stuff.
+  void GenerateDeclaration(io::Printer* printer);
+
+  // Source file stuff.
+  void GenerateDefinition(io::Printer* printer);
+
+  // Generate code to register the extension.
+  void GenerateRegistration(io::Printer* printer);
+
+ private:
+  const FieldDescriptor* descriptor_;
+  string type_traits_;
+  Options options_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc
new file mode 100644
index 0000000..1e9a40a
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -0,0 +1,166 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+
+#include <google/protobuf/compiler/cpp/cpp_helpers.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/wire_format.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+                             map<string, string>* variables,
+                             const Options& options) {
+  (*variables)["name"] = FieldName(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()));
+  (*variables)["deprecation"] = descriptor->options().deprecated()
+      ? " PROTOBUF_DEPRECATED" : "";
+
+  (*variables)["cppget"] = "Get";
+}
+
+void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
+                                  map<string, string>* variables) {
+  (*variables)["oneof_prefix"] = descriptor->containing_oneof()->name() + "_.";
+  (*variables)["oneof_name"] = descriptor->containing_oneof()->name();
+}
+
+FieldGenerator::~FieldGenerator() {}
+
+void FieldGenerator::
+GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
+  // Reaching here indicates a bug. Cases are:
+  //   - This FieldGenerator should support packing, but this method should be
+  //     overridden.
+  //   - This FieldGenerator doesn't support packing, and this method should
+  //     never have been called.
+  GOOGLE_LOG(FATAL) << "GenerateMergeFromCodedStreamWithPacking() "
+             << "called on field generator that does not support packing.";
+
+}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
+                                     const Options& options)
+    : 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), options));
+  }
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
+                                                 const Options& options) {
+  if (field->is_repeated()) {
+    switch (field->cpp_type()) {
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        return new RepeatedMessageFieldGenerator(field, options);
+      case FieldDescriptor::CPPTYPE_STRING:
+        switch (field->options().ctype()) {
+          default:  // RepeatedStringFieldGenerator handles unknown ctypes.
+          case FieldOptions::STRING:
+            return new RepeatedStringFieldGenerator(field, options);
+        }
+      case FieldDescriptor::CPPTYPE_ENUM:
+        return new RepeatedEnumFieldGenerator(field, options);
+      default:
+        return new RepeatedPrimitiveFieldGenerator(field, options);
+    }
+  } else if (field->containing_oneof()) {
+    switch (field->cpp_type()) {
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        return new MessageOneofFieldGenerator(field, options);
+      case FieldDescriptor::CPPTYPE_STRING:
+        switch (field->options().ctype()) {
+          default:  // StringOneofFieldGenerator handles unknown ctypes.
+          case FieldOptions::STRING:
+            return new StringOneofFieldGenerator(field, options);
+        }
+      case FieldDescriptor::CPPTYPE_ENUM:
+        return new EnumOneofFieldGenerator(field, options);
+      default:
+        return new PrimitiveOneofFieldGenerator(field, options);
+    }
+  } else {
+    switch (field->cpp_type()) {
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        return new MessageFieldGenerator(field, options);
+      case FieldDescriptor::CPPTYPE_STRING:
+        switch (field->options().ctype()) {
+          default:  // StringFieldGenerator handles unknown ctypes.
+          case FieldOptions::STRING:
+            return new StringFieldGenerator(field, options);
+        }
+      case FieldDescriptor::CPPTYPE_ENUM:
+        return new EnumFieldGenerator(field, options);
+      default:
+        return new PrimitiveFieldGenerator(field, options);
+    }
+  }
+}
+
+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/protobuf/src/google/protobuf/compiler/cpp/cpp_field.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_field.h
new file mode 100644
index 0000000..96c2963
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_field.h
@@ -0,0 +1,185 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// 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 <map>
+#include <memory>
+#include <string>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/compiler/cpp/cpp_options.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Helper function: set variables in the map that are the same for all
+// field code generators.
+// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size',
+// 'deprecation'].
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+                             map<string, string>* variables,
+                             const Options& options);
+
+void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
+                                  map<string, string>* variables);
+
+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 static default variable for this field. These are placed inside
+  // the message class. Most field types don't need this, so the default
+  // implementation is empty.
+  virtual void GenerateStaticMembers(io::Printer* printer) const {}
+
+  // 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 lines of code (statements, not declarations) which swaps
+  // this field and the corresponding field of another message, which
+  // is stored in the generated code variable "other". This is used to
+  // define the Swap method. Details of usage can be found in
+  // message.cc under the GenerateSwap method.
+  virtual void GenerateSwappingCode(io::Printer* printer) const = 0;
+
+  // Generate initialization code for private members declared by
+  // GeneratePrivateMembers(). These go into the message class's SharedCtor()
+  // method, invoked by each of the generated constructors.
+  virtual void GenerateConstructorCode(io::Printer* printer) const = 0;
+
+  // Generate any code that needs to go in the class's SharedDtor() method,
+  // invoked by the destructor.
+  // Most field types don't need this, so the default implementation is empty.
+  virtual void GenerateDestructorCode(io::Printer* printer) const {}
+
+  // Generate code that allocates the fields's default instance.
+  virtual void GenerateDefaultInstanceAllocator(io::Printer* printer) const {}
+
+  // Generate code that should be run when ShutdownProtobufLibrary() is called,
+  // to delete all dynamically-allocated objects.
+  virtual void GenerateShutdownCode(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 decode this field from a packed value, which will be
+  // placed inside the message's MergeFromCodedStream() method.
+  virtual void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer)
+      const;
+
+  // 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 serialize this field directly to the array "target",
+  // which are placed within the message's SerializeWithCachedSizesToArray()
+  // method. This must also advance "target" past the written bytes.
+  virtual void GenerateSerializeWithCachedSizesToArray(
+      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, const Options& options);
+  ~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,
+                                       const Options& options);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc
new file mode 100644
index 0000000..fa19427
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -0,0 +1,665 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+#include <set>
+
+#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/compiler/cpp/cpp_field.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 Options& options)
+    : 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()]),
+      options_(options) {
+
+  for (int i = 0; i < file->message_type_count(); i++) {
+    message_generators_[i].reset(
+      new MessageGenerator(file->message_type(i), options));
+  }
+
+  for (int i = 0; i < file->enum_type_count(); i++) {
+    enum_generators_[i].reset(
+      new EnumGenerator(file->enum_type(i), options));
+  }
+
+  for (int i = 0; i < file->service_count(); i++) {
+    service_generators_[i].reset(
+      new ServiceGenerator(file->service(i), options));
+  }
+
+  for (int i = 0; i < file->extension_count(); i++) {
+    extension_generators_[i].reset(
+      new ExtensionGenerator(file->extension(i), options));
+  }
+
+  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"
+    "// source: $filename$\n"
+    "\n"
+    "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
+    "#define PROTOBUF_$filename_identifier$__INCLUDED\n"
+    "\n"
+    "#include <string>\n"
+    "\n",
+    "filename", file_->name(),
+    "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_util.h>\n");
+  if (file_->message_type_count() > 0) {
+    if (HasDescriptorMethods(file_)) {
+      printer->Print(
+        "#include <google/protobuf/message.h>\n");
+    } else {
+      printer->Print(
+        "#include <google/protobuf/message_lite.h>\n");
+    }
+  }
+  printer->Print(
+    "#include <google/protobuf/repeated_field.h>\n"
+    "#include <google/protobuf/extension_set.h>\n");
+
+  if (HasDescriptorMethods(file_) && HasEnumDefinitions(file_)) {
+    printer->Print(
+      "#include <google/protobuf/generated_enum_reflection.h>\n");
+  }
+
+  if (HasGenericServices(file_)) {
+    printer->Print(
+      "#include <google/protobuf/service.h>\n");
+  }
+
+  if (UseUnknownFieldSet(file_) && file_->message_type_count() > 0) {
+    printer->Print(
+      "#include <google/protobuf/unknown_field_set.h>\n");
+  }
+
+
+  set<string> public_import_names;
+  for (int i = 0; i < file_->public_dependency_count(); i++) {
+    public_import_names.insert(file_->public_dependency(i)->name());
+  }
+
+  for (int i = 0; i < file_->dependency_count(); i++) {
+    const string& name = file_->dependency(i)->name();
+    bool public_import = (public_import_names.count(name) != 0);
+
+
+    printer->Print(
+      "#include \"$dependency$.pb.h\"$iwyu$\n",
+      "dependency", StripProto(name),
+      "iwyu", (public_import) ? "  // IWYU pragma: export" : "");
+  }
+
+  printer->Print(
+    "// @@protoc_insertion_point(includes)\n");
+
+
+  // Open namespace.
+  GenerateNamespaceOpeners(printer);
+
+  // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile
+  // functions, so that we can declare them to be friends of each class.
+  printer->Print(
+    "\n"
+    "// Internal implementation detail -- do not call these.\n"
+    "void $dllexport_decl$ $adddescriptorsname$();\n",
+    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()),
+    "dllexport_decl", options_.dllexport_decl);
+
+  printer->Print(
+    // Note that we don't put dllexport_decl on these because they are only
+    // called by the .pb.cc file in which they are defined.
+    "void $assigndescriptorsname$();\n"
+    "void $shutdownfilename$();\n"
+    "\n",
+    "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()),
+    "shutdownfilename", GlobalShutdownFileName(file_->name()));
+
+  // 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");
+
+  if (HasGenericServices(file_)) {
+    // 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);
+  }
+
+  printer->Print(
+    "\n"
+    "// @@protoc_insertion_point(namespace_scope)\n");
+
+  // Close up namespace.
+  GenerateNamespaceClosers(printer);
+
+  // Emit GetEnumDescriptor specializations into google::protobuf namespace:
+  if (HasDescriptorMethods(file_)) {
+    // The SWIG conditional is to avoid a null-pointer dereference
+    // (bug 1984964) in swig-1.3.21 resulting from the following syntax:
+    //   namespace X { void Y<Z::W>(); }
+    // which appears in GetEnumDescriptor() specializations.
+    printer->Print(
+        "\n"
+        "#ifndef SWIG\n"
+        "namespace google {\nnamespace protobuf {\n"
+        "\n");
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+    }
+    for (int i = 0; i < file_->enum_type_count(); i++) {
+      enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+    }
+    printer->Print(
+        "\n"
+        "}  // namespace google\n}  // namespace protobuf\n"
+        "#endif  // SWIG\n");
+  }
+
+  printer->Print(
+    "\n"
+    "// @@protoc_insertion_point(global_scope)\n"
+    "\n");
+
+  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"
+    "// source: $filename$\n"
+    "\n"
+
+    // The generated code calls accessors that might be deprecated. We don't
+    // want the compiler to warn in generated code.
+    "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
+    "#include \"$basename$.pb.h\"\n"
+    "\n"
+    "#include <algorithm>\n"    // for swap()
+    "\n"
+    "#include <google/protobuf/stubs/common.h>\n"
+    "#include <google/protobuf/stubs/once.h>\n"
+    "#include <google/protobuf/io/coded_stream.h>\n"
+    "#include <google/protobuf/wire_format_lite_inl.h>\n",
+    "filename", file_->name(),
+    "basename", StripProto(file_->name()));
+
+  // Unknown fields implementation in lite mode uses StringOutputStream
+  if (!UseUnknownFieldSet(file_) && file_->message_type_count() > 0) {
+    printer->Print(
+      "#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n");
+  }
+
+  if (HasDescriptorMethods(file_)) {
+    printer->Print(
+      "#include <google/protobuf/descriptor.h>\n"
+      "#include <google/protobuf/generated_message_reflection.h>\n"
+      "#include <google/protobuf/reflection_ops.h>\n"
+      "#include <google/protobuf/wire_format.h>\n");
+  }
+
+  printer->Print(
+    "// @@protoc_insertion_point(includes)\n");
+
+  GenerateNamespaceOpeners(printer);
+
+  if (HasDescriptorMethods(file_)) {
+    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));
+    }
+
+    if (HasGenericServices(file_)) {
+      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.  (For the lite
+  // library, all this does is initialize default instances.)
+  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);
+  }
+
+  if (HasGenericServices(file_)) {
+    // 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);
+  }
+
+  printer->Print(
+    "\n"
+    "// @@protoc_insertion_point(namespace_scope)\n");
+
+  GenerateNamespaceClosers(printer);
+
+  printer->Print(
+    "\n"
+    "// @@protoc_insertion_point(global_scope)\n");
+}
+
+void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
+  // AddDescriptors() is a file-level procedure which adds the encoded
+  // FileDescriptorProto for this .proto file to the global DescriptorPool for
+  // generated files (DescriptorPool::generated_pool()). It either runs at
+  // static initialization time (by default) or when default_instance() is
+  // called for the first time (in LITE_RUNTIME mode with
+  // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also
+  // constructs default instances and registers extensions.
+  //
+  // Its sibling, AssignDescriptors(), actually pulls the compiled
+  // FileDescriptor from the DescriptorPool and uses it to populate all of
+  // the global variables which store pointers to the descriptor objects.
+  // It also constructs the reflection objects.  It is called the first time
+  // anyone calls descriptor() or GetReflection() on one of the types defined
+  // in the file.
+
+  // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
+  // and we only use AddDescriptors() to allocate default instances.
+  if (HasDescriptorMethods(file_)) {
+    printer->Print(
+      "\n"
+      "void $assigndescriptorsname$() {\n",
+      "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
+    printer->Indent();
+
+    // Make sure the file has found its way into the pool.  If a descriptor
+    // is requested *during* static init then AddDescriptors() may not have
+    // been called yet, so we call it manually.  Note that it's fine if
+    // AddDescriptors() is called multiple times.
+    printer->Print(
+      "$adddescriptorsname$();\n",
+      "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
+
+    // Get the file's descriptor from the pool.
+    printer->Print(
+      "const ::google::protobuf::FileDescriptor* file =\n"
+      "  ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
+      "    \"$filename$\");\n"
+      // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
+      // being unused when compiling an empty .proto file.
+      "GOOGLE_CHECK(file != NULL);\n",
+      "filename", file_->name());
+
+    // Go through all the stuff defined in this file and generated code to
+    // assign the global descriptor pointers based on the file descriptor.
+    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);
+    }
+    if (HasGenericServices(file_)) {
+      for (int i = 0; i < file_->service_count(); i++) {
+        service_generators_[i]->GenerateDescriptorInitializer(printer, i);
+      }
+    }
+
+    printer->Outdent();
+    printer->Print(
+      "}\n"
+      "\n");
+
+    // ---------------------------------------------------------------
+
+    // protobuf_AssignDescriptorsOnce():  The first time it is called, calls
+    // AssignDescriptors().  All later times, waits for the first call to
+    // complete and then returns.
+    printer->Print(
+      "namespace {\n"
+      "\n"
+      "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
+      "inline void protobuf_AssignDescriptorsOnce() {\n"
+      "  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
+      "                 &$assigndescriptorsname$);\n"
+      "}\n"
+      "\n",
+      "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
+
+    // protobuf_RegisterTypes():  Calls
+    // MessageFactory::InternalRegisterGeneratedType() for each message type.
+    printer->Print(
+      "void protobuf_RegisterTypes(const ::std::string&) {\n"
+      "  protobuf_AssignDescriptorsOnce();\n");
+    printer->Indent();
+
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      message_generators_[i]->GenerateTypeRegistrations(printer);
+    }
+
+    printer->Outdent();
+    printer->Print(
+      "}\n"
+      "\n"
+      "}  // namespace\n");
+  }
+
+  // -----------------------------------------------------------------
+
+  // ShutdownFile():  Deletes descriptors, default instances, etc. on shutdown.
+  printer->Print(
+    "\n"
+    "void $shutdownfilename$() {\n",
+    "shutdownfilename", GlobalShutdownFileName(file_->name()));
+  printer->Indent();
+
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateShutdownCode(printer);
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "}\n\n");
+
+  // -----------------------------------------------------------------
+
+  // Now generate the AddDescriptors() function.
+  PrintHandlingOptionalStaticInitializers(
+    file_, printer,
+    // With static initializers.
+    // Note that we don't need any special synchronization in the following code
+    // because it is called at static init time before any threads exist.
+    "void $adddescriptorsname$() {\n"
+    "  static bool already_here = false;\n"
+    "  if (already_here) return;\n"
+    "  already_here = true;\n"
+    "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
+    "\n",
+    // Without.
+    "void $adddescriptorsname$_impl() {\n"
+    "  GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
+    "\n",
+    // Vars.
+    "adddescriptorsname", GlobalAddDescriptorsName(file_->name()));
+
+  printer->Indent();
+
+  // Call the AddDescriptors() methods for all of our dependencies, to make
+  // sure they get added first.
+  for (int i = 0; i < file_->dependency_count(); i++) {
+    const FileDescriptor* dependency = file_->dependency(i);
+    // Print the namespace prefix for the dependency.
+    string add_desc_name = QualifiedFileLevelSymbol(
+        dependency->package(), GlobalAddDescriptorsName(dependency->name()));
+    // Call its AddDescriptors function.
+    printer->Print(
+      "$name$();\n",
+      "name", add_desc_name);
+  }
+
+  if (HasDescriptorMethods(file_)) {
+    // 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(
+      "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
+
+    // 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",
+                     EscapeTrigraphs(
+                         CEscape(file_data.substr(i, kBytesPerLine))));
+    }
+    printer->Print(
+        ", $size$);\n",
+      "size", SimpleItoa(file_data.size()));
+
+    // Call MessageFactory::InternalRegisterGeneratedFile().
+    printer->Print(
+      "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
+      "  \"$filename$\", &protobuf_RegisterTypes);\n",
+      "filename", file_->name());
+  }
+
+  // Allocate and initialize default instances.  This can't be done lazily
+  // since default instances are returned by simple accessors and are used with
+  // extensions.  Speaking of which, we also register extensions at this time.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateDefaultInstanceAllocator(printer);
+  }
+  for (int i = 0; i < file_->extension_count(); i++) {
+    extension_generators_[i]->GenerateRegistration(printer);
+  }
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateDefaultInstanceInitializer(printer);
+  }
+
+  printer->Print(
+    "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n",
+    "shutdownfilename", GlobalShutdownFileName(file_->name()));
+
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "\n");
+
+  PrintHandlingOptionalStaticInitializers(
+    file_, printer,
+    // With static initializers.
+    "// Force AddDescriptors() to be called at static initialization time.\n"
+    "struct StaticDescriptorInitializer_$filename$ {\n"
+    "  StaticDescriptorInitializer_$filename$() {\n"
+    "    $adddescriptorsname$();\n"
+    "  }\n"
+    "} static_descriptor_initializer_$filename$_;\n",
+    // Without.
+    "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n"
+    "void $adddescriptorsname$() {\n"
+    "  ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n"
+    "                 &$adddescriptorsname$_impl);\n"
+    "}\n",
+    // Vars.
+    "adddescriptorsname", GlobalAddDescriptorsName(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/protobuf/src/google/protobuf/compiler/cpp/cpp_file.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_file.h
new file mode 100644
index 0000000..4e4d8b6
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_options.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 Options& options);
+  ~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_;
+  const Options options_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc
new file mode 100644
index 0000000..75d558e
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -0,0 +1,125 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+#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>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+CppGenerator::CppGenerator() {}
+CppGenerator::~CppGenerator() {}
+
+bool CppGenerator::Generate(const FileDescriptor* file,
+                            const string& parameter,
+                            GeneratorContext* generator_context,
+                            string* error) const {
+  vector<pair<string, string> > options;
+  ParseGeneratorParameter(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.
+  Options file_options;
+
+  for (int i = 0; i < options.size(); i++) {
+    if (options[i].first == "dllexport_decl") {
+      file_options.dllexport_decl = options[i].second;
+    } else if (options[i].first == "safe_boundary_check") {
+      file_options.safe_boundary_check = true;
+    } else {
+      *error = "Unknown generator option: " + options[i].first;
+      return false;
+    }
+  }
+
+  // -----------------------------------------------------------------
+
+
+  string basename = StripProto(file->name());
+  basename.append(".pb");
+
+  FileGenerator file_generator(file, file_options);
+
+  // Generate header.
+  {
+    scoped_ptr<io::ZeroCopyOutputStream> output(
+        generator_context->Open(basename + ".h"));
+    io::Printer printer(output.get(), '$');
+    file_generator.GenerateHeader(&printer);
+  }
+
+  // Generate cc file.
+  {
+    scoped_ptr<io::ZeroCopyOutputStream> output(
+        generator_context->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/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h
new file mode 100644
index 0000000..3d517cf
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_generator.h
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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,
+                GeneratorContext* generator_context,
+                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/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc
new file mode 100644
index 0000000..b7a47ac
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -0,0 +1,494 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <limits>
+#include <map>
+#include <vector>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.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();
+
+// Returns whether the provided descriptor has an extension. This includes its
+// nested types.
+bool HasExtension(const Descriptor* descriptor) {
+  if (descriptor->extension_count() > 0) {
+    return true;
+  }
+  for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+    if (HasExtension(descriptor->nested_type(i))) {
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace
+
+string UnderscoresToCamelCase(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') {
+      // Capital letters 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;
+}
+
+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 SuperClassName(const Descriptor* descriptor) {
+  return HasDescriptorMethods(descriptor->file()) ?
+      "::google::protobuf::Message" : "::google::protobuf::MessageLite";
+}
+
+string FieldName(const FieldDescriptor* field) {
+  string result = field->name();
+  LowerString(&result);
+  if (kKeywords.count(result) > 0) {
+    result.append("_");
+  }
+  return result;
+}
+
+string FieldConstantName(const FieldDescriptor *field) {
+  string field_name = UnderscoresToCamelCase(field->name(), true);
+  string result = "k" + field_name + "FieldNumber";
+
+  if (!field->is_extension() &&
+      field->containing_type()->FindFieldByCamelcaseName(
+        field->camelcase_name()) != field) {
+    // This field's camelcase name is not unique.  As a hack, add the field
+    // number to the constant name.  This makes the constant rather useless,
+    // but what can we do?
+    result += "_" + SimpleItoa(field->number());
+  }
+
+  return result;
+}
+
+string FieldMessageTypeName(const FieldDescriptor* field) {
+  // Note:  The Google-internal version of Protocol Buffers uses this function
+  //   as a hook point for hacks to support legacy code.
+  return ClassName(field->message_type(), true);
+}
+
+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 "";
+}
+
+string Int32ToString(int number) {
+  // gcc rejects the decimal form of kint32min.
+  if (number == kint32min) {
+    GOOGLE_COMPILE_ASSERT(kint32min == (~0x7fffffff), kint32min_value_error);
+    return "(~0x7fffffff)";
+  } else {
+    return SimpleItoa(number);
+  }
+}
+
+string Int64ToString(int64 number) {
+  // gcc rejects the decimal form of kint64min
+  if (number == kint64min) {
+    // Make sure we are in a 2's complement system.
+    GOOGLE_COMPILE_ASSERT(kint64min == GOOGLE_LONGLONG(~0x7fffffffffffffff),
+                   kint64min_value_error);
+    return "GOOGLE_LONGLONG(~0x7fffffffffffffff)";
+  }
+  return "GOOGLE_LONGLONG(" + SimpleItoa(number) + ")";
+}
+
+string DefaultValue(const FieldDescriptor* field) {
+  switch (field->cpp_type()) {
+    case FieldDescriptor::CPPTYPE_INT32:
+      return Int32ToString(field->default_value_int32());
+    case FieldDescriptor::CPPTYPE_UINT32:
+      return SimpleItoa(field->default_value_uint32()) + "u";
+    case FieldDescriptor::CPPTYPE_INT64:
+      return Int64ToString(field->default_value_int64());
+    case FieldDescriptor::CPPTYPE_UINT64:
+      return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")";
+    case FieldDescriptor::CPPTYPE_DOUBLE: {
+      double value = field->default_value_double();
+      if (value == numeric_limits<double>::infinity()) {
+        return "::google::protobuf::internal::Infinity()";
+      } else if (value == -numeric_limits<double>::infinity()) {
+        return "-::google::protobuf::internal::Infinity()";
+      } else if (value != value) {
+        return "::google::protobuf::internal::NaN()";
+      } else {
+        return SimpleDtoa(value);
+      }
+    }
+    case FieldDescriptor::CPPTYPE_FLOAT:
+      {
+        float value = field->default_value_float();
+        if (value == numeric_limits<float>::infinity()) {
+          return "static_cast<float>(::google::protobuf::internal::Infinity())";
+        } else if (value == -numeric_limits<float>::infinity()) {
+          return "static_cast<float>(-::google::protobuf::internal::Infinity())";
+        } else if (value != value) {
+          return "static_cast<float>(::google::protobuf::internal::NaN())";
+        } else {
+          string float_value = SimpleFtoa(value);
+          // If floating point value contains a period (.) or an exponent
+          // (either E or e), then append suffix 'f' to make it a float
+          // literal.
+          if (float_value.find_first_of(".eE") != string::npos) {
+            float_value.push_back('f');
+          }
+          return float_value;
+        }
+      }
+    case FieldDescriptor::CPPTYPE_BOOL:
+      return field->default_value_bool() ? "true" : "false";
+    case FieldDescriptor::CPPTYPE_ENUM:
+      // Lazy:  Generate a static_cast because we don't have a helper function
+      //   that constructs the full name of an enum value.
+      return strings::Substitute(
+          "static_cast< $0 >($1)",
+          ClassName(field->enum_type(), true),
+          Int32ToString(field->default_value_enum()->number()));
+    case FieldDescriptor::CPPTYPE_STRING:
+      return "\"" + EscapeTrigraphs(
+        CEscape(field->default_value_string())) +
+        "\"";
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      return FieldMessageTypeName(field) + "::default_instance()";
+  }
+  // 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.)
+  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 AddDescriptors() function for a given file.
+string GlobalAddDescriptorsName(const string& filename) {
+  return "protobuf_AddDesc_" + FilenameIdentifier(filename);
+}
+
+// Return the name of the AssignDescriptors() function for a given file.
+string GlobalAssignDescriptorsName(const string& filename) {
+  return "protobuf_AssignDesc_" + FilenameIdentifier(filename);
+}
+
+// Return the name of the ShutdownFile() function for a given file.
+string GlobalShutdownFileName(const string& filename) {
+  return "protobuf_ShutdownFile_" + FilenameIdentifier(filename);
+}
+
+// Return the qualified C++ name for a file level symbol.
+string QualifiedFileLevelSymbol(const string& package, const string& name) {
+  if (package.empty()) {
+    return StrCat("::", name);
+  }
+  return StrCat("::", DotsToColons(package), "::", name);
+}
+
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape) {
+  return StringReplace(to_escape, "?", "\\?", true);
+}
+
+// Escaped function name to eliminate naming conflict.
+string SafeFunctionName(const Descriptor* descriptor,
+                        const FieldDescriptor* field,
+                        const string& prefix) {
+  // Do not use FieldName() since it will escape keywords.
+  string name = field->name();
+  LowerString(&name);
+  string function_name = prefix + name;
+  if (descriptor->FindFieldByName(function_name)) {
+    // Single underscore will also make it conflicting with the private data
+    // member. We use double underscore to escape function names.
+    function_name.append("__");
+  } else if (kKeywords.count(name) > 0) {
+    // If the field name is a keyword, we append the underscore back to keep it
+    // consistent with other function names.
+    function_name.append("_");
+  }
+  return function_name;
+}
+
+bool StaticInitializersForced(const FileDescriptor* file) {
+  if (HasDescriptorMethods(file) || file->extension_count() > 0) {
+    return true;
+  }
+  for (int i = 0; i < file->message_type_count(); ++i) {
+    if (HasExtension(file->message_type(i))) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void PrintHandlingOptionalStaticInitializers(
+    const FileDescriptor* file, io::Printer* printer,
+    const char* with_static_init, const char* without_static_init,
+    const char* var1, const string& val1,
+    const char* var2, const string& val2) {
+  map<string, string> vars;
+  if (var1) {
+    vars[var1] = val1;
+  }
+  if (var2) {
+    vars[var2] = val2;
+  }
+  PrintHandlingOptionalStaticInitializers(
+      vars, file, printer, with_static_init, without_static_init);
+}
+
+void PrintHandlingOptionalStaticInitializers(
+    const map<string, string>& vars, const FileDescriptor* file,
+    io::Printer* printer, const char* with_static_init,
+    const char* without_static_init) {
+  if (StaticInitializersForced(file)) {
+    printer->Print(vars, with_static_init);
+  } else {
+    printer->Print(vars, (string(
+      "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n") +
+      without_static_init +
+      "#else\n" +
+      with_static_init +
+      "#endif\n").c_str());
+  }
+}
+
+
+static bool HasEnumDefinitions(const Descriptor* message_type) {
+  if (message_type->enum_type_count() > 0) return true;
+  for (int i = 0; i < message_type->nested_type_count(); ++i) {
+    if (HasEnumDefinitions(message_type->nested_type(i))) return true;
+  }
+  return false;
+}
+
+bool HasEnumDefinitions(const FileDescriptor* file) {
+  if (file->enum_type_count() > 0) return true;
+  for (int i = 0; i < file->message_type_count(); ++i) {
+    if (HasEnumDefinitions(file->message_type(i))) return true;
+  }
+  return false;
+}
+
+bool IsStringOrMessage(const FieldDescriptor* field) {
+  switch (field->cpp_type()) {
+    case FieldDescriptor::CPPTYPE_INT32:
+    case FieldDescriptor::CPPTYPE_INT64:
+    case FieldDescriptor::CPPTYPE_UINT32:
+    case FieldDescriptor::CPPTYPE_UINT64:
+    case FieldDescriptor::CPPTYPE_DOUBLE:
+    case FieldDescriptor::CPPTYPE_FLOAT:
+    case FieldDescriptor::CPPTYPE_BOOL:
+    case FieldDescriptor::CPPTYPE_ENUM:
+      return false;
+    case FieldDescriptor::CPPTYPE_STRING:
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      return true;
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return false;
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h
new file mode 100644
index 0000000..5d30240
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -0,0 +1,206 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <map>
+#include <string>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+
+namespace io {
+class Printer;
+}
+
+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);
+
+string SuperClassName(const Descriptor* descriptor);
+
+// 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);
+
+// Get the unqualified name that should be used for a field's field
+// number constant.
+string FieldConstantName(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();
+}
+
+// Returns the fully-qualified type name field->message_type().  Usually this
+// is just ClassName(field->message_type(), true);
+string FieldMessageTypeName(const FieldDescriptor* field);
+
+// 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);
+
+// Return the code that evaluates to the number when compiled.
+string Int32ToString(int number);
+
+// Return the code that evaluates to the number when compiled.
+string Int64ToString(int64 number);
+
+// Get code that evaluates to the field's default value.
+string DefaultValue(const FieldDescriptor* field);
+
+// Convert a file name into a valid identifier.
+string FilenameIdentifier(const string& filename);
+
+// Return the name of the AddDescriptors() function for a given file.
+string GlobalAddDescriptorsName(const string& filename);
+
+// Return the name of the AssignDescriptors() function for a given file.
+string GlobalAssignDescriptorsName(const string& filename);
+
+// Return the qualified C++ name for a file level symbol.
+string QualifiedFileLevelSymbol(const string& package, const string& name);
+
+// Return the name of the ShutdownFile() function for a given file.
+string GlobalShutdownFileName(const string& filename);
+
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape);
+
+// Escaped function name to eliminate naming conflict.
+string SafeFunctionName(const Descriptor* descriptor,
+                        const FieldDescriptor* field,
+                        const string& prefix);
+
+// Do message classes in this file use UnknownFieldSet?
+// Otherwise, messages will store unknown fields in a string
+inline bool UseUnknownFieldSet(const FileDescriptor* file) {
+  return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+}
+
+
+// Does this file have any enum type definitions?
+bool HasEnumDefinitions(const FileDescriptor* file);
+
+// Does this file have generated parsing, serialization, and other
+// standard methods for which reflection-based fallback implementations exist?
+inline bool HasGeneratedMethods(const FileDescriptor* file) {
+  return file->options().optimize_for() != FileOptions::CODE_SIZE;
+}
+
+// Do message classes in this file have descriptor and reflection methods?
+inline bool HasDescriptorMethods(const FileDescriptor* file) {
+  return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+}
+
+// Should we generate generic services for this file?
+inline bool HasGenericServices(const FileDescriptor* file) {
+  return file->service_count() > 0 &&
+         file->options().optimize_for() != FileOptions::LITE_RUNTIME &&
+         file->options().cc_generic_services();
+}
+
+// Should string fields in this file verify that their contents are UTF-8?
+inline bool HasUtf8Verification(const FileDescriptor* file) {
+  return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+}
+
+// Should we generate a separate, super-optimized code path for serializing to
+// flat arrays?  We don't do this in Lite mode because we'd rather reduce code
+// size.
+inline bool HasFastArraySerialization(const FileDescriptor* file) {
+  return file->options().optimize_for() == FileOptions::SPEED;
+}
+
+// Returns whether we have to generate code with static initializers.
+bool StaticInitializersForced(const FileDescriptor* file);
+
+// Prints 'with_static_init' if static initializers have to be used for the
+// provided file. Otherwise emits both 'with_static_init' and
+// 'without_static_init' using #ifdef.
+void PrintHandlingOptionalStaticInitializers(
+    const FileDescriptor* file, io::Printer* printer,
+    const char* with_static_init, const char* without_static_init,
+    const char* var1 = NULL, const string& val1 = "",
+    const char* var2 = NULL, const string& val2 = "");
+
+void PrintHandlingOptionalStaticInitializers(
+    const map<string, string>& vars, const FileDescriptor* file,
+    io::Printer* printer, const char* with_static_init,
+    const char* without_static_init);
+
+
+// Returns true if the field's CPPTYPE is string or message.
+bool IsStringOrMessage(const FieldDescriptor* field);
+
+string UnderscoresToCamelCase(const string& input, bool cap_next_letter);
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc
new file mode 100644
index 0000000..3a9d263
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -0,0 +1,2645 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <map>
+#include <memory>
+#include <set>
+#include <utility>
+#include <vector>
+#include <google/protobuf/compiler/cpp/cpp_message.h>
+#include <google/protobuf/compiler/cpp/cpp_field.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;
+using internal::WireFormatLite;
+
+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();
+  }
+};
+
+// 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 "required" restriction check should be ignored for the
+// given field.
+inline static bool ShouldIgnoreRequiredFieldCheck(
+    const FieldDescriptor* field) {
+  return false;
+}
+
+// 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 &&
+        !ShouldIgnoreRequiredFieldCheck(field)) {
+      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);
+}
+
+// This returns an estimate of the compiler's alignment for the field.  This
+// can't guarantee to be correct because the generated code could be compiled on
+// different systems with different alignment rules.  The estimates below assume
+// 64-bit pointers.
+int EstimateAlignmentSize(const FieldDescriptor* field) {
+  if (field == NULL) return 0;
+  if (field->is_repeated()) return 8;
+  switch (field->cpp_type()) {
+    case FieldDescriptor::CPPTYPE_BOOL:
+      return 1;
+
+    case FieldDescriptor::CPPTYPE_INT32:
+    case FieldDescriptor::CPPTYPE_UINT32:
+    case FieldDescriptor::CPPTYPE_ENUM:
+    case FieldDescriptor::CPPTYPE_FLOAT:
+      return 4;
+
+    case FieldDescriptor::CPPTYPE_INT64:
+    case FieldDescriptor::CPPTYPE_UINT64:
+    case FieldDescriptor::CPPTYPE_DOUBLE:
+    case FieldDescriptor::CPPTYPE_STRING:
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      return 8;
+  }
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return -1;  // Make compiler happy.
+}
+
+// FieldGroup is just a helper for OptimizePadding below.  It holds a vector of
+// fields that are grouped together because they have compatible alignment, and
+// a preferred location in the final field ordering.
+class FieldGroup {
+ public:
+  FieldGroup()
+      : preferred_location_(0) {}
+
+  // A group with a single field.
+  FieldGroup(float preferred_location, const FieldDescriptor* field)
+      : preferred_location_(preferred_location),
+        fields_(1, field) {}
+
+  // Append the fields in 'other' to this group.
+  void Append(const FieldGroup& other) {
+    if (other.fields_.empty()) {
+      return;
+    }
+    // Preferred location is the average among all the fields, so we weight by
+    // the number of fields on each FieldGroup object.
+    preferred_location_ =
+        (preferred_location_ * fields_.size() +
+         (other.preferred_location_ * other.fields_.size())) /
+        (fields_.size() + other.fields_.size());
+    fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
+  }
+
+  void SetPreferredLocation(float location) { preferred_location_ = location; }
+  const vector<const FieldDescriptor*>& fields() const { return fields_; }
+
+  // FieldGroup objects sort by their preferred location.
+  bool operator<(const FieldGroup& other) const {
+    return preferred_location_ < other.preferred_location_;
+  }
+
+ private:
+  // "preferred_location_" is an estimate of where this group should go in the
+  // final list of fields.  We compute this by taking the average index of each
+  // field in this group in the original ordering of fields.  This is very
+  // approximate, but should put this group close to where its member fields
+  // originally went.
+  float preferred_location_;
+  vector<const FieldDescriptor*> fields_;
+  // We rely on the default copy constructor and operator= so this type can be
+  // used in a vector.
+};
+
+// Reorder 'fields' so that if the fields are output into a c++ class in the new
+// order, the alignment padding is minimized.  We try to do this while keeping
+// each field as close as possible to its original position so that we don't
+// reduce cache locality much for function that access each field in order.
+void OptimizePadding(vector<const FieldDescriptor*>* fields) {
+  // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
+  vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
+  for (int i = 0; i < fields->size(); ++i) {
+    switch (EstimateAlignmentSize((*fields)[i])) {
+      case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
+      case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
+      case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
+      default:
+        GOOGLE_LOG(FATAL) << "Unknown alignment size.";
+    }
+  }
+
+  // Now group fields aligned to 1 byte into sets of 4, and treat those like a
+  // single field aligned to 4 bytes.
+  for (int i = 0; i < aligned_to_1.size(); i += 4) {
+    FieldGroup field_group;
+    for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
+      field_group.Append(aligned_to_1[j]);
+    }
+    aligned_to_4.push_back(field_group);
+  }
+  // Sort by preferred location to keep fields as close to their original
+  // location as possible.  Using stable_sort ensures that the output is
+  // consistent across runs.
+  stable_sort(aligned_to_4.begin(), aligned_to_4.end());
+
+  // Now group fields aligned to 4 bytes (or the 4-field groups created above)
+  // into pairs, and treat those like a single field aligned to 8 bytes.
+  for (int i = 0; i < aligned_to_4.size(); i += 2) {
+    FieldGroup field_group;
+    for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
+      field_group.Append(aligned_to_4[j]);
+    }
+    if (i == aligned_to_4.size() - 1) {
+      // Move incomplete 4-byte block to the end.
+      field_group.SetPreferredLocation(fields->size() + 1);
+    }
+    aligned_to_8.push_back(field_group);
+  }
+  // Sort by preferred location.
+  stable_sort(aligned_to_8.begin(), aligned_to_8.end());
+
+  // Now pull out all the FieldDescriptors in order.
+  fields->clear();
+  for (int i = 0; i < aligned_to_8.size(); ++i) {
+    fields->insert(fields->end(),
+                   aligned_to_8[i].fields().begin(),
+                   aligned_to_8[i].fields().end());
+  }
+}
+
+string MessageTypeProtoName(const FieldDescriptor* field) {
+  return field->message_type()->full_name();
+}
+
+}
+
+// ===================================================================
+
+MessageGenerator::MessageGenerator(const Descriptor* descriptor,
+                                   const Options& options)
+    : descriptor_(descriptor),
+      classname_(ClassName(descriptor, false)),
+      options_(options),
+      field_generators_(descriptor, options),
+      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), options));
+  }
+
+  for (int i = 0; i < descriptor->enum_type_count(); i++) {
+    enum_generators_[i].reset(
+      new EnumGenerator(descriptor->enum_type(i), options));
+  }
+
+  for (int i = 0; i < descriptor->extension_count(); i++) {
+    extension_generators_[i].reset(
+      new ExtensionGenerator(descriptor->extension(i), options));
+  }
+}
+
+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::
+GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+  }
+  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+    enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(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;
+    SetCommonFieldVariables(field, &vars, options_);
+    vars["constant_name"] = FieldConstantName(field);
+
+    if (field->is_repeated()) {
+      printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
+    } else {
+      printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
+    }
+
+    printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
+    printer->Print(vars, "static const int $constant_name$ = $number$;\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.  We just call a macro located in
+    // extension_set.h since the accessors about 80 lines of static code.
+    printer->Print(
+      "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
+      "classname", classname_);
+  }
+
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print(
+        "inline $camel_oneof_name$Case $oneof_name$_case() const;\n",
+        "camel_oneof_name",
+        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true),
+        "oneof_name", descriptor_->oneof_decl(i)->name());
+  }
+}
+
+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;
+    SetCommonFieldVariables(field, &vars, options_);
+
+    // 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 if (field->containing_oneof()) {
+      // Singular field in a oneof
+      vars["field_name"] = UnderscoresToCamelCase(field->name(), true);
+      vars["oneof_name"] = field->containing_oneof()->name();
+      vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index());
+      printer->Print(vars,
+        "inline bool $classname$::has_$name$() const {\n"
+        "  return $oneof_name$_case() == k$field_name$;\n"
+        "}\n"
+        "inline void $classname$::set_has_$name$() {\n"
+        "  _oneof_case_[$oneof_index$] = k$field_name$;\n"
+        "}\n");
+    } else {
+      // Singular field.
+      char buffer[kFastToBufferSize];
+      vars["has_array_index"] = SimpleItoa(field->index() / 32);
+      vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), buffer);
+      printer->Print(vars,
+        "inline bool $classname$::has_$name$() const {\n"
+        "  return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"
+        "}\n"
+        "inline void $classname$::set_has_$name$() {\n"
+        "  _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n"
+        "}\n"
+        "inline void $classname$::clear_has_$name$() {\n"
+        "  _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"
+        "}\n"
+        );
+    }
+
+    // Generate clear_$name$()
+    printer->Print(vars,
+      "inline void $classname$::clear_$name$() {\n");
+
+    printer->Indent();
+
+    if (field->containing_oneof()) {
+      // Clear this field only if it is the active field in this oneof,
+      // otherwise ignore
+      printer->Print(vars,
+        "if (has_$name$()) {\n");
+      printer->Indent();
+      field_generators_.get(field).GenerateClearingCode(printer);
+      printer->Print(vars,
+        "clear_has_$oneof_name$();\n");
+      printer->Outdent();
+      printer->Print("}\n");
+    } else {
+      field_generators_.get(field).GenerateClearingCode(printer);
+      if (!field->is_repeated()) {
+        printer->Print(vars,
+                       "clear_has_$name$();\n");
+      }
+    }
+
+    printer->Outdent();
+    printer->Print("}\n");
+
+    // Generate type-specific accessors.
+    field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
+
+    printer->Print("\n");
+  }
+
+  // Generate has_$name$() and clear_has_$name$() functions for oneofs
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    map<string, string> vars;
+    vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
+    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+    vars["cap_oneof_name"] =
+        ToUpper(descriptor_->oneof_decl(i)->name());
+    vars["classname"] = classname_;
+    printer->Print(
+      vars,
+      "inline bool $classname$::has_$oneof_name$() {\n"
+      "  return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n"
+      "}\n"
+      "inline void $classname$::clear_has_$oneof_name$() {\n"
+      "  _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n"
+      "}\n");
+  }
+}
+
+// Helper for the code that emits the Clear() method.
+static bool CanClearByZeroing(const FieldDescriptor* field) {
+  if (field->is_repeated() || field->is_extension()) return false;
+  switch (field->cpp_type()) {
+    case internal::WireFormatLite::CPPTYPE_ENUM:
+      return field->default_value_enum()->number() == 0;
+    case internal::WireFormatLite::CPPTYPE_INT32:
+      return field->default_value_int32() == 0;
+    case internal::WireFormatLite::CPPTYPE_INT64:
+      return field->default_value_int64() == 0;
+    case internal::WireFormatLite::CPPTYPE_UINT32:
+      return field->default_value_uint32() == 0;
+    case internal::WireFormatLite::CPPTYPE_UINT64:
+      return field->default_value_uint64() == 0;
+    case internal::WireFormatLite::CPPTYPE_FLOAT:
+      return field->default_value_float() == 0;
+    case internal::WireFormatLite::CPPTYPE_DOUBLE:
+      return field->default_value_double() == 0;
+    case internal::WireFormatLite::CPPTYPE_BOOL:
+      return field->default_value_bool() == false;
+    default:
+      return false;
+  }
+}
+
+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());
+  vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
+  if (options_.dllexport_decl.empty()) {
+    vars["dllexport"] = "";
+  } else {
+    vars["dllexport"] = options_.dllexport_decl + " ";
+  }
+  vars["superclass"] = SuperClassName(descriptor_);
+
+  printer->Print(vars,
+    "class $dllexport$$classname$ : public $superclass$ {\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");
+
+  if (UseUnknownFieldSet(descriptor_->file())) {
+    printer->Print(
+      "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
+      "  return _unknown_fields_;\n"
+      "}\n"
+      "\n"
+      "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
+      "  return &_unknown_fields_;\n"
+      "}\n"
+      "\n");
+  } else {
+    printer->Print(
+      "inline const ::std::string& unknown_fields() const {\n"
+      "  return _unknown_fields_;\n"
+      "}\n"
+      "\n"
+      "inline ::std::string* mutable_unknown_fields() {\n"
+      "  return &_unknown_fields_;\n"
+      "}\n"
+      "\n");
+  }
+
+  // Only generate this member if it's not disabled.
+  if (HasDescriptorMethods(descriptor_->file()) &&
+      !descriptor_->options().no_standard_descriptor_accessor()) {
+    printer->Print(vars,
+      "static const ::google::protobuf::Descriptor* descriptor();\n");
+  }
+
+  printer->Print(vars,
+    "static const $classname$& default_instance();\n"
+    "\n");
+
+  // Generate enum values for every field in oneofs. One list is generated for
+  // each oneof with an additional *_NOT_SET value.
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print(
+        "enum $camel_oneof_name$Case {\n",
+        "camel_oneof_name",
+        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
+    printer->Indent();
+    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+      printer->Print(
+          "k$field_name$ = $field_number$,\n",
+          "field_name",
+          UnderscoresToCamelCase(
+              descriptor_->oneof_decl(i)->field(j)->name(), true),
+          "field_number",
+          SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number()));
+    }
+    printer->Print(
+        "$cap_oneof_name$_NOT_SET = 0,\n",
+        "cap_oneof_name",
+        ToUpper(descriptor_->oneof_decl(i)->name()));
+    printer->Outdent();
+    printer->Print(
+        "};\n"
+        "\n");
+  }
+
+  if (!StaticInitializersForced(descriptor_->file())) {
+    printer->Print(vars,
+      "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
+      "// Returns the internal default instance pointer. This function can\n"
+      "// return NULL thus should not be used by the user. This is intended\n"
+      "// for Protobuf internal code. Please use default_instance() declared\n"
+      "// above instead.\n"
+      "static inline const $classname$* internal_default_instance() {\n"
+      "  return default_instance_;\n"
+      "}\n"
+      "#endif\n"
+      "\n");
+  }
+
+
+  printer->Print(vars,
+    "void Swap($classname$* other);\n"
+    "\n"
+    "// implements Message ----------------------------------------------\n"
+    "\n"
+    "$classname$* New() const;\n");
+
+  if (HasGeneratedMethods(descriptor_->file())) {
+    if (HasDescriptorMethods(descriptor_->file())) {
+      printer->Print(vars,
+        "void CopyFrom(const ::google::protobuf::Message& from);\n"
+        "void MergeFrom(const ::google::protobuf::Message& from);\n");
+    } else {
+      printer->Print(vars,
+        "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
+    }
+
+    printer->Print(vars,
+      "void CopyFrom(const $classname$& from);\n"
+      "void MergeFrom(const $classname$& from);\n"
+      "void Clear();\n"
+      "bool IsInitialized() const;\n"
+      "\n"
+      "int ByteSize() const;\n"
+      "bool MergePartialFromCodedStream(\n"
+      "    ::google::protobuf::io::CodedInputStream* input);\n"
+      "void SerializeWithCachedSizes(\n"
+      "    ::google::protobuf::io::CodedOutputStream* output) const;\n");
+    // DiscardUnknownFields() is implemented in message.cc using reflections. We
+    // need to implement this function in generated code for messages.
+    if (!UseUnknownFieldSet(descriptor_->file())) {
+      printer->Print(
+        "void DiscardUnknownFields();\n");
+    }
+    if (HasFastArraySerialization(descriptor_->file())) {
+      printer->Print(
+        "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
+    }
+  }
+
+  // Check all FieldDescriptors including those in oneofs to estimate
+  // whether ::std::string is likely to be used, and depending on that
+  // estimate, set uses_string_ to true or false.  That contols
+  // whether to force initialization of empty_string_ in SharedCtor().
+  // It's often advantageous to do so to keep "is empty_string_
+  // inited?" code from appearing all over the place.
+  vector<const FieldDescriptor*> descriptors;
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    descriptors.push_back(descriptor_->field(i));
+  }
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+      descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
+    }
+  }
+  uses_string_ = false;
+  for (int i = 0; i < descriptors.size(); i++) {
+    const FieldDescriptor* field = descriptors[i];
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+      switch (field->options().ctype()) {
+        default: uses_string_ = true; break;
+      }
+    }
+  }
+
+  printer->Print(
+    "int GetCachedSize() const { return _cached_size_; }\n"
+    "private:\n"
+    "void SharedCtor();\n"
+    "void SharedDtor();\n"
+    "void SetCachedSize(int size) const;\n"
+    "public:\n");
+
+  if (HasDescriptorMethods(descriptor_->file())) {
+    printer->Print(
+      "::google::protobuf::Metadata GetMetadata() const;\n"
+      "\n");
+  } else {
+    printer->Print(
+      "::std::string GetTypeName() const;\n"
+      "\n");
+  }
+
+  printer->Print(
+    "// 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);
+  }
+
+
+  printer->Print(
+    "// @@protoc_insertion_point(class_scope:$full_name$)\n",
+    "full_name", descriptor_->full_name());
+
+  // Generate private members.
+  printer->Outdent();
+  printer->Print(" private:\n");
+  printer->Indent();
+
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    if (!descriptor_->field(i)->is_repeated()) {
+      printer->Print(
+        "inline void set_has_$name$();\n",
+        "name", FieldName(descriptor_->field(i)));
+      if (!descriptor_->field(i)->containing_oneof()) {
+        printer->Print(
+          "inline void clear_has_$name$();\n",
+          "name", FieldName(descriptor_->field(i)));
+      }
+    }
+  }
+  printer->Print("\n");
+
+  // Generate oneof function declarations
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print(
+        "inline bool has_$oneof_name$();\n"
+        "void clear_$oneof_name$();\n"
+        "inline void clear_has_$oneof_name$();\n\n",
+        "oneof_name", descriptor_->oneof_decl(i)->name());
+  }
+
+  // Prepare decls for _cached_size_ and _has_bits_.  Their position in the
+  // output will be determined later.
+
+  bool need_to_emit_cached_size = true;
+  // TODO(kenton):  Make _cached_size_ an atomic<int> when C++ supports it.
+  const string cached_size_decl = "mutable int _cached_size_;\n";
+
+  // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields.
+  size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
+  if (descriptor_->field_count() == 0) {
+    // 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.
+    sizeof_has_bits = 4;
+  }
+  const string has_bits_decl = sizeof_has_bits == 0 ? "" :
+      "::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n";
+
+
+  // To minimize padding, data members are divided into three sections:
+  // (1) members assumed to align to 8 bytes
+  // (2) members corresponding to message fields, re-ordered to optimize
+  //     alignment.
+  // (3) members assumed to align to 4 bytes.
+
+  // Members assumed to align to 8 bytes:
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "::google::protobuf::internal::ExtensionSet _extensions_;\n"
+      "\n");
+  }
+
+  if (UseUnknownFieldSet(descriptor_->file())) {
+    printer->Print(
+      "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
+      "\n");
+  } else {
+    printer->Print(
+      "::std::string _unknown_fields_;\n"
+      "\n");
+  }
+
+  // _has_bits_ is frequently accessed, so to reduce code size and improve
+  // speed, it should be close to the start of the object.  But, try not to
+  // waste space:_has_bits_ by itself always makes sense if its size is a
+  // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
+  // will work well.
+  printer->Print(has_bits_decl.c_str());
+  if ((sizeof_has_bits % 8) != 0) {
+    printer->Print(cached_size_decl.c_str());
+    need_to_emit_cached_size = false;
+  }
+
+  // Field members:
+
+  // List fields which doesn't belong to any oneof
+  vector<const FieldDescriptor*> fields;
+  hash_map<string, int> fieldname_to_chunk;
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    if (!descriptor_->field(i)->containing_oneof()) {
+      const FieldDescriptor* field = descriptor_->field(i);
+      fields.push_back(field);
+      fieldname_to_chunk[FieldName(field)] = i / 8;
+    }
+  }
+  OptimizePadding(&fields);
+  // Emit some private and static members
+  runs_of_fields_ = vector< vector<string> >(1);
+  for (int i = 0; i < fields.size(); ++i) {
+    const FieldDescriptor* field = fields[i];
+    const FieldGenerator& generator = field_generators_.get(field);
+    generator.GenerateStaticMembers(printer);
+    generator.GeneratePrivateMembers(printer);
+    if (CanClearByZeroing(field)) {
+      const string& fieldname = FieldName(field);
+      if (!runs_of_fields_.back().empty() &&
+          (fieldname_to_chunk[runs_of_fields_.back().back()] !=
+           fieldname_to_chunk[fieldname])) {
+        runs_of_fields_.push_back(vector<string>());
+      }
+      runs_of_fields_.back().push_back(fieldname);
+    } else if (!runs_of_fields_.back().empty()) {
+      runs_of_fields_.push_back(vector<string>());
+    }
+  }
+
+  // For each oneof generate a union
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print(
+        "union $camel_oneof_name$Union {\n",
+        "camel_oneof_name",
+        UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
+    printer->Indent();
+    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+      field_generators_.get(descriptor_->oneof_decl(i)->
+                            field(j)).GeneratePrivateMembers(printer);
+    }
+    printer->Outdent();
+    printer->Print(
+        "} $oneof_name$_;\n",
+        "oneof_name", descriptor_->oneof_decl(i)->name());
+    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+      field_generators_.get(descriptor_->oneof_decl(i)->
+                            field(j)).GenerateStaticMembers(printer);
+    }
+  }
+
+  // Members assumed to align to 4 bytes:
+
+  if (need_to_emit_cached_size) {
+    printer->Print(cached_size_decl.c_str());
+    need_to_emit_cached_size = false;
+  }
+
+  // Generate _oneof_case_.
+  if (descriptor_->oneof_decl_count() > 0) {
+    printer->Print(vars,
+      "::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n"
+      "\n");
+  }
+
+  // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
+  // friends so that they can access private static variables like
+  // default_instance_ and reflection_.
+  PrintHandlingOptionalStaticInitializers(
+    descriptor_->file(), printer,
+    // With static initializers.
+    "friend void $dllexport_decl$ $adddescriptorsname$();\n",
+    // Without.
+    "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
+    // Vars.
+    "dllexport_decl", options_.dllexport_decl,
+    "adddescriptorsname",
+    GlobalAddDescriptorsName(descriptor_->file()->name()));
+
+  printer->Print(
+    "friend void $assigndescriptorsname$();\n"
+    "friend void $shutdownfilename$();\n"
+    "\n",
+    "assigndescriptorsname",
+      GlobalAssignDescriptorsName(descriptor_->file()->name()),
+    "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
+
+  printer->Print(
+    "void InitAsDefaultInstance();\n"
+    "static $classname$* default_instance_;\n",
+    "classname", classname_);
+
+  printer->Outdent();
+  printer->Print(vars, "};");
+  GOOGLE_DCHECK(!need_to_emit_cached_size);
+}
+
+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);
+
+  // Generate oneof_case() functions.
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    map<string, string> vars;
+    vars["class_name"] = classname_;
+    vars["camel_oneof_name"] = UnderscoresToCamelCase(
+        descriptor_->oneof_decl(i)->name(), true);
+    vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
+    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+    printer->Print(
+        vars,
+        "inline $class_name$::$camel_oneof_name$Case $class_name$::"
+        "$oneof_name$_case() const {\n"
+        "  return $class_name$::$camel_oneof_name$Case("
+        "_oneof_case_[$oneof_index$]);\n"
+        "}\n");
+  }
+}
+
+void MessageGenerator::
+GenerateDescriptorDeclarations(io::Printer* printer) {
+  printer->Print(
+    "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
+    "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
+    "  $name$_reflection_ = NULL;\n",
+    "name", classname_);
+
+  // Generate oneof default instance for reflection usage.
+  if (descriptor_->oneof_decl_count() > 0) {
+    printer->Print("struct $name$OneofInstance {\n",
+                   "name", classname_);
+    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+      for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+        const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+        printer->Print("  ");
+        if (IsStringOrMessage(field)) {
+          printer->Print("const ");
+        }
+        field_generators_.get(field).GeneratePrivateMembers(printer);
+      }
+    }
+
+    printer->Print("}* $name$_default_oneof_instance_ = 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);
+
+  // Obtain the descriptor from the parent's descriptor.
+  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");
+  }
+
+  // Generate the offsets.
+  GenerateOffsets(printer);
+
+  // Construct the reflection object.
+  printer->Print(vars,
+    "$classname$_reflection_ =\n"
+    "  new ::google::protobuf::internal::GeneratedMessageReflection(\n"
+    "    $classname$_descriptor_,\n"
+    "    $classname$::default_instance_,\n"
+    "    $classname$_offsets_,\n"
+    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
+    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+      "$classname$, _unknown_fields_),\n");
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(vars,
+      "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+        "$classname$, _extensions_),\n");
+  } else {
+    // No extensions.
+    printer->Print(vars,
+      "    -1,\n");
+  }
+
+  if (descriptor_->oneof_decl_count() > 0) {
+    printer->Print(vars,
+    "    $classname$_default_oneof_instance_,\n"
+    "    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+      "$classname$, _oneof_case_[0]),\n");
+  }
+
+  printer->Print(
+    "    ::google::protobuf::DescriptorPool::generated_pool(),\n");
+  printer->Print(vars,
+    "    ::google::protobuf::MessageFactory::generated_factory(),\n");
+  printer->Print(vars,
+    "    sizeof($classname$));\n");
+
+  // Handle nested types.
+  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);
+  }
+}
+
+void MessageGenerator::
+GenerateTypeRegistrations(io::Printer* printer) {
+  // Register this message type with the message factory.
+  printer->Print(
+    "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
+    "  $classname$_descriptor_, &$classname$::default_instance());\n",
+    "classname", classname_);
+
+  // Handle nested types.
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateTypeRegistrations(printer);
+  }
+}
+
+void MessageGenerator::
+GenerateDefaultInstanceAllocator(io::Printer* printer) {
+  // Construct the default instances of all fields, as they will be used
+  // when creating the default instance of the entire message.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i))
+                     .GenerateDefaultInstanceAllocator(printer);
+  }
+
+  // Construct the default instance.  We can't call InitAsDefaultInstance() yet
+  // because we need to make sure all default instances that this one might
+  // depend on are constructed first.
+  printer->Print(
+    "$classname$::default_instance_ = new $classname$();\n",
+    "classname", classname_);
+
+  if ((descriptor_->oneof_decl_count() > 0) &&
+      HasDescriptorMethods(descriptor_->file())) {
+    printer->Print(
+    "$classname$_default_oneof_instance_ = new $classname$OneofInstance;\n",
+    "classname", classname_);
+  }
+
+  // Handle nested types.
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
+  }
+
+}
+
+void MessageGenerator::
+GenerateDefaultInstanceInitializer(io::Printer* printer) {
+  printer->Print(
+    "$classname$::default_instance_->InitAsDefaultInstance();\n",
+    "classname", classname_);
+
+  // Register extensions.
+  for (int i = 0; i < descriptor_->extension_count(); i++) {
+    extension_generators_[i]->GenerateRegistration(printer);
+  }
+
+  // Handle nested types.
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
+  }
+}
+
+void MessageGenerator::
+GenerateShutdownCode(io::Printer* printer) {
+  printer->Print(
+    "delete $classname$::default_instance_;\n",
+    "classname", classname_);
+
+  if (HasDescriptorMethods(descriptor_->file())) {
+    if (descriptor_->oneof_decl_count() > 0) {
+      printer->Print(
+        "delete $classname$_default_oneof_instance_;\n",
+        "classname", classname_);
+    }
+    printer->Print(
+      "delete $classname$_reflection_;\n",
+      "classname", classname_);
+  }
+
+  // Handle default instances of fields.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i))
+                     .GenerateShutdownCode(printer);
+  }
+
+  // Handle nested types.
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    nested_generators_[i]->GenerateShutdownCode(printer);
+  }
+}
+
+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");
+  }
+
+  // Generate non-inline field definitions.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i))
+                     .GenerateNonInlineAccessorDefinitions(printer);
+  }
+
+  // Generate field number constants.
+  printer->Print("#ifndef _MSC_VER\n");
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor *field = descriptor_->field(i);
+    printer->Print(
+      "const int $classname$::$constant_name$;\n",
+      "classname", ClassName(FieldScope(field), false),
+      "constant_name", FieldConstantName(field));
+  }
+  printer->Print(
+    "#endif  // !_MSC_VER\n"
+    "\n");
+
+  // Define extension identifiers.
+  for (int i = 0; i < descriptor_->extension_count(); i++) {
+    extension_generators_[i]->GenerateDefinition(printer);
+  }
+
+  GenerateStructors(printer);
+  printer->Print("\n");
+
+  if (descriptor_->oneof_decl_count() > 0) {
+    GenerateOneofClear(printer);
+    printer->Print("\n");
+  }
+
+  if (HasGeneratedMethods(descriptor_->file())) {
+    GenerateClear(printer);
+    printer->Print("\n");
+
+    GenerateMergeFromCodedStream(printer);
+    printer->Print("\n");
+
+    GenerateSerializeWithCachedSizes(printer);
+    printer->Print("\n");
+
+    if (HasFastArraySerialization(descriptor_->file())) {
+      GenerateSerializeWithCachedSizesToArray(printer);
+      printer->Print("\n");
+    }
+
+    GenerateByteSize(printer);
+    printer->Print("\n");
+
+    GenerateMergeFrom(printer);
+    printer->Print("\n");
+
+    GenerateCopyFrom(printer);
+    printer->Print("\n");
+
+    GenerateIsInitialized(printer);
+    printer->Print("\n");
+  }
+
+  GenerateSwap(printer);
+  printer->Print("\n");
+
+  if (HasDescriptorMethods(descriptor_->file())) {
+    printer->Print(
+      "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
+      "  protobuf_AssignDescriptorsOnce();\n"
+      "  ::google::protobuf::Metadata metadata;\n"
+      "  metadata.descriptor = $classname$_descriptor_;\n"
+      "  metadata.reflection = $classname$_reflection_;\n"
+      "  return metadata;\n"
+      "}\n"
+      "\n",
+      "classname", classname_);
+  } else {
+    printer->Print(
+      "::std::string $classname$::GetTypeName() const {\n"
+      "  return \"$type_name$\";\n"
+      "}\n"
+      "\n",
+      "classname", classname_,
+      "type_name", descriptor_->full_name());
+  }
+
+}
+
+void MessageGenerator::
+GenerateOffsets(io::Printer* printer) {
+  printer->Print(
+    "static const int $classname$_offsets_[$field_count$] = {\n",
+    "classname", classname_,
+    "field_count", SimpleItoa(max(
+        1, descriptor_->field_count() + descriptor_->oneof_decl_count())));
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    if (field->containing_oneof()) {
+      printer->Print(
+          "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
+          "$classname$_default_oneof_instance_, $name$_),\n",
+          "classname", classname_,
+          "name", FieldName(field));
+    } else {
+      printer->Print(
+          "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
+                                                 "$name$_),\n",
+          "classname", classname_,
+          "name", FieldName(field));
+    }
+  }
+
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
+    printer->Print(
+      "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
+      "classname", classname_,
+      "name", oneof->name());
+  }
+
+  printer->Outdent();
+  printer->Print("};\n");
+}
+
+void MessageGenerator::
+GenerateSharedConstructorCode(io::Printer* printer) {
+  printer->Print(
+    "void $classname$::SharedCtor() {\n",
+    "classname", classname_);
+  printer->Indent();
+
+  printer->Print(StrCat(
+      uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
+      "_cached_size_ = 0;\n").c_str());
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    if (!descriptor_->field(i)->containing_oneof()) {
+      field_generators_.get(descriptor_->field(i))
+          .GenerateConstructorCode(printer);
+    }
+  }
+
+  printer->Print(
+    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
+
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print(
+        "clear_has_$oneof_name$();\n",
+        "oneof_name", descriptor_->oneof_decl(i)->name());
+  }
+
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+void MessageGenerator::
+GenerateSharedDestructorCode(io::Printer* printer) {
+  printer->Print(
+    "void $classname$::SharedDtor() {\n",
+    "classname", classname_);
+  printer->Indent();
+  // Write the destructors for each field except oneof members.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    if (!descriptor_->field(i)->containing_oneof()) {
+      field_generators_.get(descriptor_->field(i))
+                       .GenerateDestructorCode(printer);
+    }
+  }
+
+  // Generate code to destruct oneofs. Clearing should do the work.
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print(
+        "if (has_$oneof_name$()) {\n"
+        "  clear_$oneof_name$();\n"
+        "}\n",
+        "oneof_name", descriptor_->oneof_decl(i)->name());
+  }
+
+  PrintHandlingOptionalStaticInitializers(
+    descriptor_->file(), printer,
+    // With static initializers.
+    "if (this != default_instance_) {\n",
+    // Without.
+    "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) {
+      // Skip oneof members
+      if (!field->containing_oneof()) {
+        printer->Print(
+            "  delete $name$_;\n",
+            "name", FieldName(field));
+      }
+    }
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "  }\n"
+    "}\n"
+    "\n");
+}
+
+void MessageGenerator::
+GenerateStructors(io::Printer* printer) {
+  string superclass = SuperClassName(descriptor_);
+
+  // Generate the default constructor.
+  printer->Print(
+    "$classname$::$classname$()\n"
+    "  : $superclass$() {\n"
+    "  SharedCtor();\n"
+    "  // @@protoc_insertion_point(constructor:$full_name$)\n"
+    "}\n",
+    "classname", classname_,
+    "superclass", superclass,
+    "full_name", descriptor_->full_name());
+
+  printer->Print(
+    "\n"
+    "void $classname$::InitAsDefaultInstance() {\n",
+    "classname", classname_);
+
+  // The default instance needs all of its embedded message pointers
+  // cross-linked to other default instances.  We can't do this initialization
+  // in the constructor because some other default instances may not have been
+  // constructed yet at that time.
+  // 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 &&
+        (field->containing_oneof() == NULL ||
+         HasDescriptorMethods(descriptor_->file()))) {
+      string name;
+      if (field->containing_oneof()) {
+        name = classname_ + "_default_oneof_instance_->";
+      }
+      name += FieldName(field);
+      PrintHandlingOptionalStaticInitializers(
+        descriptor_->file(), printer,
+        // With static initializers.
+        "  $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
+        // Without.
+        "  $name$_ = const_cast< $type$*>(\n"
+        "      $type$::internal_default_instance());\n",
+        // Vars.
+        "name", name,
+        "type", FieldMessageTypeName(field));
+    } else if (field->containing_oneof() &&
+               HasDescriptorMethods(descriptor_->file())) {
+      field_generators_.get(descriptor_->field(i))
+          .GenerateConstructorCode(printer);
+    }
+  }
+  printer->Print(
+    "}\n"
+    "\n");
+
+  // Generate the copy constructor.
+  printer->Print(
+    "$classname$::$classname$(const $classname$& from)\n"
+    "  : $superclass$() {\n"
+    "  SharedCtor();\n"
+    "  MergeFrom(from);\n"
+    "  // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
+    "}\n"
+    "\n",
+    "classname", classname_,
+    "superclass", superclass,
+    "full_name", descriptor_->full_name());
+
+  // Generate the shared constructor code.
+  GenerateSharedConstructorCode(printer);
+
+  // Generate the destructor.
+  printer->Print(
+    "$classname$::~$classname$() {\n"
+    "  // @@protoc_insertion_point(destructor:$full_name$)\n"
+    "  SharedDtor();\n"
+    "}\n"
+    "\n",
+    "classname", classname_,
+    "full_name", descriptor_->full_name());
+
+  // Generate the shared destructor code.
+  GenerateSharedDestructorCode(printer);
+
+  // Generate SetCachedSize.
+  printer->Print(
+    "void $classname$::SetCachedSize(int size) const {\n"
+    "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+    "  _cached_size_ = size;\n"
+    "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+    "}\n",
+    "classname", classname_);
+
+  // Only generate this member if it's not disabled.
+  if (HasDescriptorMethods(descriptor_->file()) &&
+      !descriptor_->options().no_standard_descriptor_accessor()) {
+    printer->Print(
+      "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
+      "  protobuf_AssignDescriptorsOnce();\n"
+      "  return $classname$_descriptor_;\n"
+      "}\n"
+      "\n",
+      "classname", classname_,
+      "adddescriptorsname",
+      GlobalAddDescriptorsName(descriptor_->file()->name()));
+  }
+
+  printer->Print(
+    "const $classname$& $classname$::default_instance() {\n",
+    "classname", classname_);
+
+  PrintHandlingOptionalStaticInitializers(
+    descriptor_->file(), printer,
+    // With static initializers.
+    "  if (default_instance_ == NULL) $adddescriptorsname$();\n",
+    // Without.
+    "  $adddescriptorsname$();\n",
+    // Vars.
+    "adddescriptorsname",
+    GlobalAddDescriptorsName(descriptor_->file()->name()));
+
+  printer->Print(
+    "  return *default_instance_;\n"
+    "}\n"
+    "\n"
+    "$classname$* $classname$::default_instance_ = NULL;\n"
+    "\n",
+    "classname", classname_);
+
+  printer->Print(
+    "$classname$* $classname$::New() const {\n"
+    "  return new $classname$;\n"
+    "}\n",
+    "classname", classname_);
+
+}
+
+// Return the number of bits set in n, a non-negative integer.
+static int popcnt(uint32 n) {
+  int result = 0;
+  while (n != 0) {
+    result += (n & 1);
+    n = n / 2;
+  }
+  return result;
+}
+
+void MessageGenerator::
+GenerateClear(io::Printer* printer) {
+  printer->Print("void $classname$::Clear() {\n",
+                 "classname", classname_);
+  printer->Indent();
+
+  // Step 1: Extensions
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print("_extensions_.Clear();\n");
+  }
+
+  // Step 2: Everything but extensions, repeateds, unions.
+  // These are handled in chunks of 8.  The first chunk is
+  // the non-extensions-non-repeateds-non-unions in
+  //  descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
+  // and the second chunk is the same for
+  //  descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
+  // etc.
+  set<int> step2_indices;
+  hash_map<string, int> fieldname_to_chunk;
+  hash_map<int, string> memsets_for_chunk;
+  hash_map<int, int> memset_field_count_for_chunk;
+  hash_set<string> handled;  // fields that appear anywhere in memsets_for_chunk
+  hash_map<int, uint32> fields_mask_for_chunk;
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    if (!field->is_repeated() && !field->containing_oneof()) {
+      step2_indices.insert(i);
+      int chunk = i / 8;
+      fieldname_to_chunk[FieldName(field)] = chunk;
+      fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32);
+    }
+  }
+
+  // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0.
+  // The generated code uses two macros to help it clear runs of fields:
+  // OFFSET_OF_FIELD_ computes the offset (in bytes) of a field in the Message.
+  // ZR_ zeroes a non-empty range of fields via memset.
+  const char* macros =
+      "#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \\\n"
+      "  &reinterpret_cast<$classname$*>(16)->f) - \\\n"
+      "   reinterpret_cast<char*>(16))\n\n"
+      "#define ZR_(first, last) do {                              \\\n"
+      "    size_t f = OFFSET_OF_FIELD_(first);                    \\\n"
+      "    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \\\n"
+      "    ::memset(&first, 0, n);                                \\\n"
+      "  } while (0)\n\n";
+  for (int i = 0; i < runs_of_fields_.size(); i++) {
+    const vector<string>& run = runs_of_fields_[i];
+    if (run.size() < 2) continue;
+    const string& first_field_name = run[0];
+    const string& last_field_name = run.back();
+    int chunk = fieldname_to_chunk[run[0]];
+    memsets_for_chunk[chunk].append(
+      "ZR_(" + first_field_name + "_, " + last_field_name + "_);\n");
+    for (int j = 0; j < run.size(); j++) {
+      GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]);
+      handled.insert(run[j]);
+    }
+    memset_field_count_for_chunk[chunk] += run.size();
+  }
+  const bool macros_are_needed = handled.size() > 0;
+  if (macros_are_needed) {
+    printer->Outdent();
+    printer->Print(macros,
+                   "classname", classname_);
+    printer->Indent();
+  }
+  // Step 2b: Finish step 2, ignoring fields handled in step 2a.
+  int last_index = -1;
+  bool chunk_block_in_progress = false;
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    if (step2_indices.count(i) == 0) continue;
+    const FieldDescriptor* field = descriptor_->field(i);
+    const string fieldname = FieldName(field);
+    if (i / 8 != last_index / 8 || last_index < 0) {
+      // End previous chunk, if there was one.
+      if (chunk_block_in_progress) {
+        printer->Outdent();
+        printer->Print("}\n");
+        chunk_block_in_progress = false;
+      }
+      // Start chunk.
+      const string& memsets = memsets_for_chunk[i / 8];
+      uint32 mask = fields_mask_for_chunk[i / 8];
+      int count = popcnt(mask);
+      if (count == 1 ||
+          (count <= 4 && count == memset_field_count_for_chunk[i / 8])) {
+        // No "if" here because the chunk is trivial.
+      } else {
+        printer->Print(
+          "if (_has_bits_[$index$ / 32] & $mask$) {\n",
+          "index", SimpleItoa(i / 8 * 8),
+          "mask", SimpleItoa(mask));
+        printer->Indent();
+        chunk_block_in_progress = true;
+      }
+      printer->Print(memsets.c_str());
+    }
+    last_index = i;
+    if (handled.count(fieldname) > 0) continue;
+
+    // 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("if (has_$name$()) {\n", "name", fieldname);
+      printer->Indent();
+    }
+
+    field_generators_.get(field).GenerateClearingCode(printer);
+
+    if (should_check_bit) {
+      printer->Outdent();
+      printer->Print("}\n");
+    }
+  }
+
+  if (chunk_block_in_progress) {
+    printer->Outdent();
+    printer->Print("}\n");
+  }
+  if (macros_are_needed) {
+    printer->Outdent();
+    printer->Print("\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n");
+    printer->Indent();
+  }
+
+  // Step 3: Repeated fields don't use _has_bits_; emit code to clear them here.
+  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);
+    }
+  }
+
+  // Step 4: Unions.
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print(
+        "clear_$oneof_name$();\n",
+        "oneof_name", descriptor_->oneof_decl(i)->name());
+  }
+
+  // Step 5: Everything else.
+  printer->Print(
+    "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
+
+  if (UseUnknownFieldSet(descriptor_->file())) {
+    printer->Print(
+      "mutable_unknown_fields()->Clear();\n");
+  } else {
+    printer->Print(
+      "mutable_unknown_fields()->clear();\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateOneofClear(io::Printer* printer) {
+  // Generated function clears the active field and union case (e.g. foo_case_).
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print(
+        "void $classname$::clear_$oneofname$() {\n",
+        "classname", classname_,
+        "oneofname", descriptor_->oneof_decl(i)->name());
+    printer->Indent();
+    printer->Print(
+        "switch($oneofname$_case()) {\n",
+        "oneofname", descriptor_->oneof_decl(i)->name());
+    printer->Indent();
+    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+      printer->Print(
+          "case k$field_name$: {\n",
+          "field_name", UnderscoresToCamelCase(field->name(), true));
+      printer->Indent();
+      // We clear only allocated objects in oneofs
+      if (!IsStringOrMessage(field)) {
+        printer->Print(
+            "// No need to clear\n");
+      } else {
+        field_generators_.get(field).GenerateClearingCode(printer);
+      }
+      printer->Print(
+          "break;\n");
+      printer->Outdent();
+      printer->Print(
+          "}\n");
+    }
+    printer->Print(
+        "case $cap_oneof_name$_NOT_SET: {\n"
+        "  break;\n"
+        "}\n",
+        "cap_oneof_name",
+        ToUpper(descriptor_->oneof_decl(i)->name()));
+    printer->Outdent();
+    printer->Print(
+        "}\n"
+        "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
+        "oneof_index", SimpleItoa(i),
+        "cap_oneof_name",
+        ToUpper(descriptor_->oneof_decl(i)->name()));
+    printer->Outdent();
+    printer->Print(
+        "}\n"
+        "\n");
+  }
+}
+
+void MessageGenerator::
+GenerateSwap(io::Printer* printer) {
+  // Generate the Swap member function.
+  printer->Print("void $classname$::Swap($classname$* other) {\n",
+                 "classname", classname_);
+  printer->Indent();
+  printer->Print("if (other != this) {\n");
+  printer->Indent();
+
+  if (HasGeneratedMethods(descriptor_->file())) {
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      const FieldDescriptor* field = descriptor_->field(i);
+      field_generators_.get(field).GenerateSwappingCode(printer);
+    }
+
+    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+      printer->Print(
+        "std::swap($oneof_name$_, other->$oneof_name$_);\n"
+        "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
+        "oneof_name", descriptor_->oneof_decl(i)->name(),
+        "i", SimpleItoa(i));
+    }
+
+    for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
+      printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
+                     "i", SimpleItoa(i));
+    }
+
+    if (UseUnknownFieldSet(descriptor_->file())) {
+      printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
+    } else {
+      printer->Print("_unknown_fields_.swap(other->_unknown_fields_);\n");
+    }
+    printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
+    if (descriptor_->extension_range_count() > 0) {
+      printer->Print("_extensions_.Swap(&other->_extensions_);\n");
+    }
+  } else {
+    printer->Print("GetReflection()->Swap(this, other);");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateMergeFrom(io::Printer* printer) {
+  if (HasDescriptorMethods(descriptor_->file())) {
+    // 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();
+
+    // 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(from, this);\n"
+      "} else {\n"
+      "  MergeFrom(*source);\n"
+      "}\n",
+      "classname", classname_);
+
+    printer->Outdent();
+    printer->Print("}\n\n");
+  } else {
+    // Generate CheckTypeAndMergeFrom().
+    printer->Print(
+      "void $classname$::CheckTypeAndMergeFrom(\n"
+      "    const ::google::protobuf::MessageLite& from) {\n"
+      "  MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
+      "}\n"
+      "\n",
+      "classname", classname_);
+  }
+
+  // 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 oneof fields. Oneof field requires oneof case check.
+  for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
+    printer->Print(
+        "switch (from.$oneofname$_case()) {\n",
+        "oneofname", descriptor_->oneof_decl(i)->name());
+    printer->Indent();
+    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+      printer->Print(
+          "case k$field_name$: {\n",
+          "field_name", UnderscoresToCamelCase(field->name(), true));
+      printer->Indent();
+      field_generators_.get(field).GenerateMergingCode(printer);
+      printer->Print(
+          "break;\n");
+      printer->Outdent();
+      printer->Print(
+          "}\n");
+    }
+    printer->Print(
+        "case $cap_oneof_name$_NOT_SET: {\n"
+        "  break;\n"
+        "}\n",
+        "cap_oneof_name",
+        ToUpper(descriptor_->oneof_decl(i)->name()));
+    printer->Outdent();
+    printer->Print(
+        "}\n");
+  }
+
+  // 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() && !field->containing_oneof()) {
+      // 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(
+          "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
+          "index", SimpleItoa(field->index()));
+        printer->Indent();
+      }
+
+      last_index = i;
+
+      printer->Print(
+        "if (from.has_$name$()) {\n",
+        "name", FieldName(field));
+      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");
+  }
+
+  if (UseUnknownFieldSet(descriptor_->file())) {
+    printer->Print(
+      "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
+  } else {
+    printer->Print(
+      "mutable_unknown_fields()->append(from.unknown_fields());\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateCopyFrom(io::Printer* printer) {
+  if (HasDescriptorMethods(descriptor_->file())) {
+    // 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()) {
+    // Special-case MessageSet.
+    printer->Print(
+      "bool $classname$::MergePartialFromCodedStream(\n"
+      "    ::google::protobuf::io::CodedInputStream* input) {\n",
+      "classname", classname_);
+
+    PrintHandlingOptionalStaticInitializers(
+      descriptor_->file(), printer,
+      // With static initializers.
+      "  return _extensions_.ParseMessageSet(input, default_instance_,\n"
+      "                                      mutable_unknown_fields());\n",
+      // Without.
+      "  return _extensions_.ParseMessageSet(input, &default_instance(),\n"
+      "                                      mutable_unknown_fields());\n",
+      // Vars.
+      "classname", classname_);
+
+    printer->Print(
+      "}\n");
+    return;
+  }
+
+  printer->Print(
+    "bool $classname$::MergePartialFromCodedStream(\n"
+    "    ::google::protobuf::io::CodedInputStream* input) {\n"
+    "#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure\n"
+    "  ::google::protobuf::uint32 tag;\n",
+    "classname", classname_);
+
+  if (!UseUnknownFieldSet(descriptor_->file())) {
+    printer->Print(
+      "  ::google::protobuf::io::StringOutputStream unknown_fields_string(\n"
+      "      mutable_unknown_fields());\n"
+      "  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
+      "      &unknown_fields_string);\n");
+  }
+
+  printer->Print(
+    "  // @@protoc_insertion_point(parse_start:$full_name$)\n",
+    "full_name", descriptor_->full_name());
+
+  printer->Indent();
+  printer->Print("for (;;) {\n");
+  printer->Indent();
+
+  scoped_array<const FieldDescriptor*> ordered_fields(
+      SortFieldsByNumber(descriptor_));
+  uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
+      WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
+  const int kCutoff0 = 127;               // fits in 1-byte varint
+  const int kCutoff1 = (127 << 7) + 127;  // fits in 2-byte varint
+  printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = "
+                 "input->ReadTagWithCutoff($max$);\n"
+                 "tag = p.first;\n"
+                 "if (!p.second) goto handle_unusual;\n",
+                 "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
+                                   (maxtag <= kCutoff1 ? kCutoff1 :
+                                    maxtag)));
+  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::WireFormatLite::"
+                   "GetTagFieldNumber(tag)) {\n");
+
+    printer->Indent();
+
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      const FieldDescriptor* field = ordered_fields[i];
+
+      PrintFieldComment(printer, field);
+
+      printer->Print(
+        "case $number$: {\n",
+        "number", SimpleItoa(field->number()));
+      printer->Indent();
+      const FieldGenerator& field_generator = field_generators_.get(field);
+
+      // Emit code to parse the common, expected case.
+      printer->Print("if (tag == $commontag$) {\n",
+                     "commontag", SimpleItoa(WireFormat::MakeTag(field)));
+
+      if (i > 0 || (field->is_repeated() && !field->options().packed())) {
+        printer->Print(
+          " parse_$name$:\n",
+          "name", field->name());
+      }
+
+      printer->Indent();
+      if (field->options().packed()) {
+        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
+      } else {
+        field_generator.GenerateMergeFromCodedStream(printer);
+      }
+      printer->Outdent();
+
+      // Emit code to parse unexpectedly packed or unpacked values.
+      if (field->is_packable() && field->options().packed()) {
+        internal::WireFormatLite::WireType wiretype =
+            WireFormat::WireTypeForFieldType(field->type());
+        printer->Print("} else if (tag == $uncommontag$) {\n",
+                       "uncommontag", SimpleItoa(
+                           internal::WireFormatLite::MakeTag(
+                               field->number(), wiretype)));
+        printer->Indent();
+        field_generator.GenerateMergeFromCodedStream(printer);
+        printer->Outdent();
+      } else if (field->is_packable() && !field->options().packed()) {
+        internal::WireFormatLite::WireType wiretype =
+            internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+        printer->Print("} else if (tag == $uncommontag$) {\n",
+                       "uncommontag", SimpleItoa(
+                           internal::WireFormatLite::MakeTag(
+                               field->number(), wiretype)));
+        printer->Indent();
+        field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
+        printer->Outdent();
+      }
+
+      printer->Print(
+        "} else {\n"
+        "  goto handle_unusual;\n"
+        "}\n");
+
+      // 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() && !field->options().packed()) {
+        // 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()) goto success;\n");
+      }
+
+      printer->Print(
+        "break;\n");
+
+      printer->Outdent();
+      printer->Print("}\n\n");
+    }
+
+    printer->Print("default: {\n");
+    printer->Indent();
+  }
+
+  printer->Outdent();
+  printer->Print("handle_unusual:\n");
+  printer->Indent();
+  // If tag is 0 or an end-group tag then this must be the end of the message.
+  printer->Print(
+    "if (tag == 0 ||\n"
+    "    ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
+    "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
+    "  goto success;\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 = WireFormatLite::MakeTag(
+        range->start, static_cast<WireFormatLite::WireType>(0));
+      uint32 end_tag = WireFormatLite::MakeTag(
+        range->end, static_cast<WireFormatLite::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");
+    if (UseUnknownFieldSet(descriptor_->file())) {
+      PrintHandlingOptionalStaticInitializers(
+        descriptor_->file(), printer,
+        // With static initializers.
+        "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
+        "                              mutable_unknown_fields()));\n",
+        // Without.
+        "  DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
+        "                              mutable_unknown_fields()));\n");
+    } else {
+      PrintHandlingOptionalStaticInitializers(
+        descriptor_->file(), printer,
+        // With static initializers.
+        "  DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
+        "                              &unknown_fields_stream));\n",
+        // Without.
+        "  DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
+        "                              &unknown_fields_stream));\n");
+    }
+    printer->Print(
+      "  continue;\n"
+      "}\n");
+  }
+
+  // We really don't recognize this tag.  Skip it.
+  if (UseUnknownFieldSet(descriptor_->file())) {
+    printer->Print(
+      "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
+      "      input, tag, mutable_unknown_fields()));\n");
+  } else {
+    printer->Print(
+      "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n"
+      "    input, tag, &unknown_fields_stream));\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"                   // for (;;)
+    "success:\n"
+    "  // @@protoc_insertion_point(parse_success:$full_name$)\n"
+    "  return true;\n"
+    "failure:\n"
+    "  // @@protoc_insertion_point(parse_failure:$full_name$)\n"
+    "  return false;\n"
+    "#undef DO_\n"
+    "}\n", "full_name", descriptor_->full_name());
+}
+
+void MessageGenerator::GenerateSerializeOneField(
+    io::Printer* printer, const FieldDescriptor* field, bool to_array) {
+  PrintFieldComment(printer, field);
+
+  if (!field->is_repeated()) {
+    printer->Print(
+      "if (has_$name$()) {\n",
+      "name", FieldName(field));
+    printer->Indent();
+  }
+
+  if (to_array) {
+    field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
+        printer);
+  } else {
+    field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
+  }
+
+  if (!field->is_repeated()) {
+    printer->Outdent();
+    printer->Print("}\n");
+  }
+  printer->Print("\n");
+}
+
+void MessageGenerator::GenerateSerializeOneExtensionRange(
+    io::Printer* printer, const Descriptor::ExtensionRange* range,
+    bool to_array) {
+  map<string, string> vars;
+  vars["start"] = SimpleItoa(range->start);
+  vars["end"] = SimpleItoa(range->end);
+  printer->Print(vars,
+    "// Extension range [$start$, $end$)\n");
+  if (to_array) {
+    printer->Print(vars,
+      "target = _extensions_.SerializeWithCachedSizesToArray(\n"
+      "    $start$, $end$, target);\n\n");
+  } else {
+    printer->Print(vars,
+      "_extensions_.SerializeWithCachedSizes(\n"
+      "    $start$, $end$, output);\n\n");
+  }
+}
+
+void MessageGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) {
+  if (descriptor_->options().message_set_wire_format()) {
+    // Special-case MessageSet.
+    printer->Print(
+      "void $classname$::SerializeWithCachedSizes(\n"
+      "    ::google::protobuf::io::CodedOutputStream* output) const {\n"
+      "  _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
+      "classname", classname_);
+    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+    printer->Print(
+      "  ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
+      "      unknown_fields(), output);\n");
+    printer->Print(
+      "}\n");
+    return;
+  }
+
+  printer->Print(
+    "void $classname$::SerializeWithCachedSizes(\n"
+    "    ::google::protobuf::io::CodedOutputStream* output) const {\n",
+    "classname", classname_);
+  printer->Indent();
+
+  printer->Print(
+    "// @@protoc_insertion_point(serialize_start:$full_name$)\n",
+    "full_name", descriptor_->full_name());
+
+  GenerateSerializeWithCachedSizesBody(printer, false);
+
+  printer->Print(
+    "// @@protoc_insertion_point(serialize_end:$full_name$)\n",
+    "full_name", descriptor_->full_name());
+
+  printer->Outdent();
+  printer->Print(
+    "}\n");
+}
+
+void MessageGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
+  if (descriptor_->options().message_set_wire_format()) {
+    // Special-case MessageSet.
+    printer->Print(
+      "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
+      "    ::google::protobuf::uint8* target) const {\n"
+      "  target =\n"
+      "      _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
+      "classname", classname_);
+    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+    printer->Print(
+      "  target = ::google::protobuf::internal::WireFormat::\n"
+      "             SerializeUnknownMessageSetItemsToArray(\n"
+      "               unknown_fields(), target);\n");
+    printer->Print(
+      "  return target;\n"
+      "}\n");
+    return;
+  }
+
+  printer->Print(
+    "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
+    "    ::google::protobuf::uint8* target) const {\n",
+    "classname", classname_);
+  printer->Indent();
+
+  printer->Print(
+    "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
+    "full_name", descriptor_->full_name());
+
+  GenerateSerializeWithCachedSizesBody(printer, true);
+
+  printer->Print(
+    "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
+    "full_name", descriptor_->full_name());
+
+  printer->Outdent();
+  printer->Print(
+    "  return target;\n"
+    "}\n");
+}
+
+void MessageGenerator::
+GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
+  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++],
+                                         to_array);
+    } else if (j == sorted_extensions.size()) {
+      GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
+    } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
+      GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
+    } else {
+      GenerateSerializeOneExtensionRange(printer,
+                                         sorted_extensions[j++],
+                                         to_array);
+    }
+  }
+
+  if (UseUnknownFieldSet(descriptor_->file())) {
+    printer->Print("if (!unknown_fields().empty()) {\n");
+    printer->Indent();
+    if (to_array) {
+      printer->Print(
+        "target = "
+            "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
+        "    unknown_fields(), target);\n");
+    } else {
+      printer->Print(
+        "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
+        "    unknown_fields(), output);\n");
+    }
+    printer->Outdent();
+
+    printer->Print(
+      "}\n");
+  } else {
+    printer->Print(
+      "output->WriteRaw(unknown_fields().data(),\n"
+      "                 unknown_fields().size());\n");
+  }
+}
+
+void MessageGenerator::
+GenerateByteSize(io::Printer* printer) {
+  if (descriptor_->options().message_set_wire_format()) {
+    // Special-case MessageSet.
+    printer->Print(
+      "int $classname$::ByteSize() const {\n"
+      "  int total_size = _extensions_.MessageSetByteSize();\n",
+      "classname", classname_);
+    GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+    printer->Print(
+      "  total_size += ::google::protobuf::internal::WireFormat::\n"
+      "      ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
+    printer->Print(
+      "  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+      "  _cached_size_ = total_size;\n"
+      "  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+      "  return total_size;\n"
+      "}\n");
+    return;
+  }
+
+  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() && !field->containing_oneof()) {
+      // 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");
+    }
+  }
+
+  // Fields inside a oneof don't use _has_bits_ so we count them in a separate
+  // pass.
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print(
+        "switch ($oneofname$_case()) {\n",
+        "oneofname", descriptor_->oneof_decl(i)->name());
+    printer->Indent();
+    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+      PrintFieldComment(printer, field);
+      printer->Print(
+          "case k$field_name$: {\n",
+          "field_name", UnderscoresToCamelCase(field->name(), true));
+      printer->Indent();
+      field_generators_.get(field).GenerateByteSize(printer);
+      printer->Print(
+          "break;\n");
+      printer->Outdent();
+      printer->Print(
+          "}\n");
+    }
+    printer->Print(
+        "case $cap_oneof_name$_NOT_SET: {\n"
+        "  break;\n"
+        "}\n",
+        "cap_oneof_name",
+        ToUpper(descriptor_->oneof_decl(i)->name()));
+    printer->Outdent();
+    printer->Print(
+        "}\n");
+  }
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "total_size += _extensions_.ByteSize();\n"
+      "\n");
+  }
+
+  if (UseUnknownFieldSet(descriptor_->file())) {
+    printer->Print("if (!unknown_fields().empty()) {\n");
+    printer->Indent();
+    printer->Print(
+      "total_size +=\n"
+      "  ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
+      "    unknown_fields());\n");
+    printer->Outdent();
+    printer->Print("}\n");
+  } else {
+    printer->Print(
+      "total_size += unknown_fields().size();\n"
+      "\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(
+    "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+    "_cached_size_ = total_size;\n"
+    "GOOGLE_SAFE_CONCURRENT_WRITES_END();\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 &&
+        !ShouldIgnoreRequiredFieldCheck(field) &&
+        HasRequiredFields(field->message_type())) {
+      if (field->is_repeated()) {
+        printer->Print(
+          "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
+          " return false;\n",
+          "name", FieldName(field));
+      } else {
+        if (field->options().weak()) {
+          // For weak fields, use the data member (google::protobuf::Message*) instead
+          // of the getter to avoid a link dependency on the weak message type
+          // which is only forward declared.
+          printer->Print(
+            "if (has_$name$()) {\n"
+            "  if (!this->$name$_->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/protobuf/src/google/protobuf/compiler/cpp/cpp_message.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_message.h
new file mode 100644
index 0000000..bfd3cec
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -0,0 +1,175 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+#include <string>
+#include <vector>
+#include <google/protobuf/compiler/cpp/cpp_field.h>
+#include <google/protobuf/compiler/cpp/cpp_options.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 Options& options);
+  ~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 specializations of GetEnumDescriptor<MyEnum>().
+  // Precondition: in ::google::protobuf namespace.
+  void GenerateGetEnumDescriptorSpecializations(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 code that calls MessageFactory::InternalRegisterGeneratedMessage()
+  // for all types.
+  void GenerateTypeRegistrations(io::Printer* printer);
+
+  // Generates code that allocates the message's default instance.
+  void GenerateDefaultInstanceAllocator(io::Printer* printer);
+
+  // Generates code that initializes the message's default instance.  This
+  // is separate from allocating because all default instances must be
+  // allocated before any can be initialized.
+  void GenerateDefaultInstanceInitializer(io::Printer* printer);
+
+  // Generates code that should be run when ShutdownProtobufLibrary() is called,
+  // to delete all dynamically-allocated objects.
+  void GenerateShutdownCode(io::Printer* printer);
+
+  // 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);
+
+  // The compiler typically generates multiple copies of each constructor and
+  // destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx
+  // Placing common code in a separate method reduces the generated code size.
+  //
+  // Generate the shared constructor code.
+  void GenerateSharedConstructorCode(io::Printer* printer);
+  // Generate the shared destructor code.
+  void GenerateSharedDestructorCode(io::Printer* printer);
+
+  // Generate standard Message methods.
+  void GenerateClear(io::Printer* printer);
+  void GenerateOneofClear(io::Printer* printer);
+  void GenerateMergeFromCodedStream(io::Printer* printer);
+  void GenerateSerializeWithCachedSizes(io::Printer* printer);
+  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer);
+  void GenerateSerializeWithCachedSizesBody(io::Printer* printer,
+                                            bool to_array);
+  void GenerateByteSize(io::Printer* printer);
+  void GenerateMergeFrom(io::Printer* printer);
+  void GenerateCopyFrom(io::Printer* printer);
+  void GenerateSwap(io::Printer* printer);
+  void GenerateIsInitialized(io::Printer* printer);
+
+  // Helpers for GenerateSerializeWithCachedSizes().
+  void GenerateSerializeOneField(io::Printer* printer,
+                                 const FieldDescriptor* field,
+                                 bool unbounded);
+  void GenerateSerializeOneExtensionRange(
+      io::Printer* printer, const Descriptor::ExtensionRange* range,
+      bool unbounded);
+
+
+  const Descriptor* descriptor_;
+  string classname_;
+  Options options_;
+  FieldGeneratorMap field_generators_;
+  vector< vector<string> > runs_of_fields_;  // that might be trivially cleared
+  scoped_array<scoped_ptr<MessageGenerator> > nested_generators_;
+  scoped_array<scoped_ptr<EnumGenerator> > enum_generators_;
+  scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
+  bool uses_string_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc
new file mode 100644
index 0000000..6ac15a5
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -0,0 +1,375 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+void SetMessageVariables(const FieldDescriptor* descriptor,
+                         map<string, string>* variables,
+                         const Options& options) {
+  SetCommonFieldVariables(descriptor, variables, options);
+  (*variables)["type"] = FieldMessageTypeName(descriptor);
+  (*variables)["stream_writer"] = (*variables)["declared_type"] +
+      (HasFastArraySerialization(descriptor->message_type()->file()) ?
+       "MaybeToArray" :
+       "");
+  // NOTE: Escaped here to unblock proto1->proto2 migration.
+  // TODO(liujisi): Extend this to apply for other conflicting methods.
+  (*variables)["release_name"] =
+      SafeFunctionName(descriptor->containing_type(),
+                       descriptor, "release_");
+  (*variables)["full_name"] = descriptor->full_name();
+}
+
+}  // namespace
+
+// ===================================================================
+
+MessageFieldGenerator::
+MessageFieldGenerator(const FieldDescriptor* descriptor,
+                      const Options& options)
+  : descriptor_(descriptor) {
+  SetMessageVariables(descriptor, &variables_, options);
+}
+
+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$deprecation$;\n"
+    "inline $type$* mutable_$name$()$deprecation$;\n"
+    "inline $type$* $release_name$()$deprecation$;\n"
+    "inline void set_allocated_$name$($type$* $name$)$deprecation$;\n");
+}
+
+void MessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const $type$& $classname$::$name$() const {\n"
+    "  // @@protoc_insertion_point(field_get:$full_name$)\n");
+
+  PrintHandlingOptionalStaticInitializers(
+    variables_, descriptor_->file(), printer,
+    // With static initializers.
+    "  return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
+    // Without.
+    "  return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
+
+  printer->Print(variables_,
+    "}\n"
+    "inline $type$* $classname$::mutable_$name$() {\n"
+    "  set_has_$name$();\n"
+    "  if ($name$_ == NULL) $name$_ = new $type$;\n"
+    "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline $type$* $classname$::$release_name$() {\n"
+    "  clear_has_$name$();\n"
+    "  $type$* temp = $name$_;\n"
+    "  $name$_ = NULL;\n"
+    "  return temp;\n"
+    "}\n"
+    "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+    "  delete $name$_;\n"
+    "  $name$_ = $name$;\n"
+    "  if ($name$) {\n"
+    "    set_has_$name$();\n"
+    "  } else {\n"
+    "    clear_has_$name$();\n"
+    "  }\n"
+    "  // @@protoc_insertion_point(field_set_allocated:$full_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::
+GenerateSwappingCode(io::Printer* printer) const {
+  printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void MessageFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = NULL;\n");
+}
+
+void MessageFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+    printer->Print(variables_,
+      "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
+      "     input, mutable_$name$()));\n");
+  } else {
+    printer->Print(variables_,
+      "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
+      "      $number$, input, mutable_$name$()));\n");
+  }
+}
+
+void MessageFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
+    "  $number$, this->$name$(), output);\n");
+}
+
+void MessageFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+  printer->Print(variables_,
+    "target = ::google::protobuf::internal::WireFormatLite::\n"
+    "  Write$declared_type$NoVirtualToArray(\n"
+    "    $number$, this->$name$(), target);\n");
+}
+
+void MessageFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ +\n"
+    "  ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
+    "    this->$name$());\n");
+}
+
+// ===================================================================
+
+MessageOneofFieldGenerator::
+MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+                           const Options& options)
+  : MessageFieldGenerator(descriptor, options) {
+  SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
+
+void MessageOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const $type$& $classname$::$name$() const {\n"
+    "  return has_$name$() ? *$oneof_prefix$$name$_\n"
+    "                      : $type$::default_instance();\n"
+    "}\n"
+    "inline $type$* $classname$::mutable_$name$() {\n"
+    "  if (!has_$name$()) {\n"
+    "    clear_$oneof_name$();\n"
+    "    set_has_$name$();\n"
+    "    $oneof_prefix$$name$_ = new $type$;\n"
+    "  }\n"
+    "  return $oneof_prefix$$name$_;\n"
+    "}\n"
+    "inline $type$* $classname$::$release_name$() {\n"
+    "  if (has_$name$()) {\n"
+    "    clear_has_$oneof_name$();\n"
+    "    $type$* temp = $oneof_prefix$$name$_;\n"
+    "    $oneof_prefix$$name$_ = NULL;\n"
+    "    return temp;\n"
+    "  } else {\n"
+    "    return NULL;\n"
+    "  }\n"
+    "}\n"
+    "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+    "  clear_$oneof_name$();\n"
+    "  if ($name$) {\n"
+    "    set_has_$name$();\n"
+    "    $oneof_prefix$$name$_ = $name$;\n"
+    "  }\n"
+    "}\n");
+}
+
+void MessageOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  // if it is the active field, it cannot be NULL.
+  printer->Print(variables_,
+    "delete $oneof_prefix$$name$_;\n");
+}
+
+void MessageOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+  // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void MessageOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  // Don't print any constructor code. The field is in a union. We allocate
+  // space only when this field is used.
+}
+
+// ===================================================================
+
+RepeatedMessageFieldGenerator::
+RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+                              const Options& options)
+  : descriptor_(descriptor) {
+  SetMessageVariables(descriptor, &variables_, options);
+}
+
+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 $type$& $name$(int index) const$deprecation$;\n"
+    "inline $type$* mutable_$name$(int index)$deprecation$;\n"
+    "inline $type$* add_$name$()$deprecation$;\n");
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+    "    $name$() const$deprecation$;\n"
+    "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+    "    mutable_$name$()$deprecation$;\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const $type$& $classname$::$name$(int index) const {\n"
+    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+    "  return $name$_.$cppget$(index);\n"
+    "}\n"
+    "inline $type$* $classname$::mutable_$name$(int index) {\n"
+    "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+    "  return $name$_.Mutable(index);\n"
+    "}\n"
+    "inline $type$* $classname$::add_$name$() {\n"
+    "  // @@protoc_insertion_point(field_add:$full_name$)\n"
+    "  return $name$_.Add();\n"
+    "}\n");
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+    "$classname$::$name$() const {\n"
+    "  // @@protoc_insertion_point(field_list:$full_name$)\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+    "$classname$::mutable_$name$() {\n"
+    "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+    "  return &$name$_;\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::
+GenerateSwappingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateConstructorCode(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::WireFormatLite::ReadMessageNoVirtual(\n"
+      "      input, add_$name$()));\n");
+  } else {
+    printer->Print(variables_,
+      "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
+      "      $number$, input, add_$name$()));\n");
+  }
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for (int i = 0; i < this->$name$_size(); i++) {\n"
+    "  ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
+    "    $number$, this->$name$(i), output);\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for (int i = 0; i < this->$name$_size(); i++) {\n"
+    "  target = ::google::protobuf::internal::WireFormatLite::\n"
+    "    Write$declared_type$NoVirtualToArray(\n"
+    "      $number$, this->$name$(i), target);\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ * this->$name$_size();\n"
+    "for (int i = 0; i < this->$name$_size(); i++) {\n"
+    "  total_size +=\n"
+    "    ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
+    "      this->$name$(i));\n"
+    "}\n");
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.h
new file mode 100644
index 0000000..2dff314
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -0,0 +1,121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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,
+                                 const Options& options);
+  ~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 GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ protected:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
+};
+
+class MessageOneofFieldGenerator : public MessageFieldGenerator {
+ public:
+  explicit MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                      const Options& options);
+  ~MessageOneofFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);
+};
+
+class RepeatedMessageFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+                                         const Options& options);
+  ~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 GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizesToArray(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/protobuf/src/google/protobuf/compiler/cpp/cpp_options.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_options.h
new file mode 100644
index 0000000..0c99cff
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_options.h
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: rennie@google.com (Jeffrey Rennie)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Generator options:
+struct Options {
+  Options() : safe_boundary_check(false) {
+  }
+  string dllexport_decl;
+  bool safe_boundary_check;
+};
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
new file mode 100644
index 0000000..2dbf14c
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
@@ -0,0 +1,123 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// TODO(kenton):  Share code with the versions of this test in other languages?
+//   It seemed like parameterizing it would add more complexity than it is
+//   worth.
+
+#include <memory>
+
+#include <google/protobuf/compiler/cpp/cpp_generator.h>
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/printer.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/testing/file.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+namespace {
+
+class TestGenerator : public CodeGenerator {
+ public:
+  TestGenerator() {}
+  ~TestGenerator() {}
+
+  virtual bool Generate(const FileDescriptor* file,
+                        const string& parameter,
+                        GeneratorContext* context,
+                        string* error) const {
+    TryInsert("test.pb.h", "includes", context);
+    TryInsert("test.pb.h", "namespace_scope", context);
+    TryInsert("test.pb.h", "global_scope", context);
+    TryInsert("test.pb.h", "class_scope:foo.Bar", context);
+    TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", context);
+
+    TryInsert("test.pb.cc", "includes", context);
+    TryInsert("test.pb.cc", "namespace_scope", context);
+    TryInsert("test.pb.cc", "global_scope", context);
+    return true;
+  }
+
+  void TryInsert(const string& filename, const string& insertion_point,
+                 GeneratorContext* context) const {
+    scoped_ptr<io::ZeroCopyOutputStream> output(
+        context->OpenForInsert(filename, insertion_point));
+    io::Printer printer(output.get(), '$');
+    printer.Print("// inserted $name$\n", "name", insertion_point);
+  }
+};
+
+// This test verifies that all the expected insertion points exist.  It does
+// not verify that they are correctly-placed; that would require actually
+// compiling the output which is a bit more than I care to do for this test.
+TEST(CppPluginTest, PluginTest) {
+  GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto",
+                             "syntax = \"proto2\";\n"
+                             "package foo;\n"
+                             "message Bar {\n"
+                             "  message Baz {}\n"
+                             "}\n",
+                             true));
+
+  google::protobuf::compiler::CommandLineInterface cli;
+  cli.SetInputsAreProtoPathRelative(true);
+
+  CppGenerator cpp_generator;
+  TestGenerator test_generator;
+  cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
+  cli.RegisterGenerator("--test_out", &test_generator, "");
+
+  string proto_path = "-I" + TestTempDir();
+  string cpp_out = "--cpp_out=" + TestTempDir();
+  string test_out = "--test_out=" + TestTempDir();
+
+  const char* argv[] = {
+    "protoc",
+    proto_path.c_str(),
+    cpp_out.c_str(),
+    test_out.c_str(),
+    "test.proto"
+  };
+
+  EXPECT_EQ(0, cli.Run(5, argv));
+}
+
+}  // namespace
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
new file mode 100644
index 0000000..44290a3
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -0,0 +1,451 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormatLite;
+
+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 WireFormatLite::kFixed32Size;
+    case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
+    case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
+    case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
+    case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
+    case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
+
+    case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::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;
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+                           map<string, string>* variables,
+                           const Options& options) {
+  SetCommonFieldVariables(descriptor, variables, options);
+  (*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type());
+  (*variables)["default"] = DefaultValue(descriptor);
+  (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+  int fixed_size = FixedSize(descriptor->type());
+  if (fixed_size != -1) {
+    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+  }
+  (*variables)["wire_format_field_type"] =
+      "::google::protobuf::internal::WireFormatLite::" + FieldDescriptorProto_Type_Name(
+          static_cast<FieldDescriptorProto_Type>(descriptor->type()));
+  (*variables)["full_name"] = descriptor->full_name();
+}
+
+}  // namespace
+
+// ===================================================================
+
+PrimitiveFieldGenerator::
+PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+                        const Options& options)
+  : descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, &variables_, options);
+}
+
+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$deprecation$;\n"
+    "inline void set_$name$($type$ value)$deprecation$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $classname$::$name$() const {\n"
+    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline void $classname$::set_$name$($type$ value) {\n"
+    "  set_has_$name$();\n"
+    "  $name$_ = value;\n"
+    "  // @@protoc_insertion_point(field_set:$full_name$)\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::
+GenerateSwappingCode(io::Printer* printer) const {
+  printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+    "         $type$, $wire_format_field_type$>(\n"
+    "       input, &$name$_)));\n"
+    "set_has_$name$();\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "::google::protobuf::internal::WireFormatLite::Write$declared_type$("
+      "$number$, this->$name$(), output);\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+  printer->Print(variables_,
+    "target = ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray("
+      "$number$, this->$name$(), target);\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::WireFormatLite::$declared_type$Size(\n"
+      "    this->$name$());\n");
+  } else {
+    printer->Print(variables_,
+      "total_size += $tag_size$ + $fixed_size$;\n");
+  }
+}
+
+// ===================================================================
+
+PrimitiveOneofFieldGenerator::
+PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+                             const Options& options)
+  : PrimitiveFieldGenerator(descriptor, options) {
+  SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {}
+
+void PrimitiveOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $classname$::$name$() const {\n"
+    "  if (has_$name$()) {\n"
+    "    return $oneof_prefix$$name$_;\n"
+    "  }\n"
+    "  return $default$;\n"
+    "}\n"
+    "inline void $classname$::set_$name$($type$ value) {\n"
+    "  if (!has_$name$()) {\n"
+    "    clear_$oneof_name$();\n"
+    "    set_has_$name$();\n"
+    "  }\n"
+    "  $oneof_prefix$$name$_ = value;\n"
+    "}\n");
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$oneof_prefix$$name$_ = $default$;\n");
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+  // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  printer->Print(
+      variables_,
+      "  $classname$_default_oneof_instance_->$name$_ = $default$;\n");
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "clear_$oneof_name$();\n"
+    "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+    "         $type$, $wire_format_field_type$>(\n"
+    "       input, &$oneof_prefix$$name$_)));\n"
+    "set_has_$name$();\n");
+}
+
+// ===================================================================
+
+RepeatedPrimitiveFieldGenerator::
+RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+                                const Options& options)
+  : descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, &variables_, options);
+
+  if (descriptor->options().packed()) {
+    variables_["packed_reader"] = "ReadPackedPrimitive";
+    variables_["repeated_reader"] = "ReadRepeatedPrimitiveNoInline";
+  } else {
+    variables_["packed_reader"] = "ReadPackedPrimitiveNoInline";
+    variables_["repeated_reader"] = "ReadRepeatedPrimitive";
+  }
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+void RepeatedPrimitiveFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "::google::protobuf::RepeatedField< $type$ > $name$_;\n");
+  if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) {
+    printer->Print(variables_,
+      "mutable int _$name$_cached_byte_size_;\n");
+  }
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $name$(int index) const$deprecation$;\n"
+    "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
+    "inline void add_$name$($type$ value)$deprecation$;\n");
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
+    "    $name$() const$deprecation$;\n"
+    "inline ::google::protobuf::RepeatedField< $type$ >*\n"
+    "    mutable_$name$()$deprecation$;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline $type$ $classname$::$name$(int index) const {\n"
+    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+    "  return $name$_.Get(index);\n"
+    "}\n"
+    "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+    "  $name$_.Set(index, value);\n"
+    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+    "}\n"
+    "inline void $classname$::add_$name$($type$ value) {\n"
+    "  $name$_.Add(value);\n"
+    "  // @@protoc_insertion_point(field_add:$full_name$)\n"
+    "}\n");
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
+    "$classname$::$name$() const {\n"
+    "  // @@protoc_insertion_point(field_list:$full_name$)\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline ::google::protobuf::RepeatedField< $type$ >*\n"
+    "$classname$::mutable_$name$() {\n"
+    "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+    "  return &$name$_;\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::
+GenerateSwappingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  // Not needed for repeated fields.
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_((::google::protobuf::internal::WireFormatLite::$repeated_reader$<\n"
+    "         $type$, $wire_format_field_type$>(\n"
+    "       $tag_size$, $tag$, input, this->mutable_$name$())));\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_((::google::protobuf::internal::WireFormatLite::$packed_reader$<\n"
+    "         $type$, $wire_format_field_type$>(\n"
+    "       input, this->mutable_$name$())));\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  if (descriptor_->options().packed()) {
+    // Write the tag and the size.
+    printer->Print(variables_,
+      "if (this->$name$_size() > 0) {\n"
+      "  ::google::protobuf::internal::WireFormatLite::WriteTag("
+          "$number$, "
+          "::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, "
+          "output);\n"
+      "  output->WriteVarint32(_$name$_cached_byte_size_);\n"
+      "}\n");
+  }
+  printer->Print(variables_,
+      "for (int i = 0; i < this->$name$_size(); i++) {\n");
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$NoTag(\n"
+      "    this->$name$(i), output);\n");
+  } else {
+    printer->Print(variables_,
+      "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+      "    $number$, this->$name$(i), output);\n");
+  }
+  printer->Print("}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+  if (descriptor_->options().packed()) {
+    // Write the tag and the size.
+    printer->Print(variables_,
+      "if (this->$name$_size() > 0) {\n"
+      "  target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
+      "    $number$,\n"
+      "    ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+      "    target);\n"
+      "  target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n"
+      "    _$name$_cached_byte_size_, target);\n"
+      "}\n");
+  }
+  printer->Print(variables_,
+      "for (int i = 0; i < this->$name$_size(); i++) {\n");
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "  target = ::google::protobuf::internal::WireFormatLite::\n"
+      "    Write$declared_type$NoTagToArray(this->$name$(i), target);\n");
+  } else {
+    printer->Print(variables_,
+      "  target = ::google::protobuf::internal::WireFormatLite::\n"
+      "    Write$declared_type$ToArray($number$, this->$name$(i), target);\n");
+  }
+  printer->Print("}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "{\n"
+    "  int data_size = 0;\n");
+  printer->Indent();
+  int fixed_size = FixedSize(descriptor_->type());
+  if (fixed_size == -1) {
+    printer->Print(variables_,
+      "for (int i = 0; i < this->$name$_size(); i++) {\n"
+      "  data_size += ::google::protobuf::internal::WireFormatLite::\n"
+      "    $declared_type$Size(this->$name$(i));\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "data_size = $fixed_size$ * this->$name$_size();\n");
+  }
+
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "if (data_size > 0) {\n"
+      "  total_size += $tag_size$ +\n"
+      "    ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
+      "}\n"
+      "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+      "_$name$_cached_byte_size_ = data_size;\n"
+      "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+      "total_size += data_size;\n");
+  } else {
+    printer->Print(variables_,
+      "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
+  }
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
new file mode 100644
index 0000000..97b5e86
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -0,0 +1,123 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// 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,
+                                   const Options& options);
+  ~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 GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ protected:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
+};
+
+class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
+ public:
+  explicit PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                        const Options& options);
+  ~PrimitiveOneofFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator);
+};
+
+class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+                                           const Options& options);
+  ~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 GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizesToArray(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/protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc
new file mode 100644
index 0000000..a8f303d
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_service.cc
@@ -0,0 +1,334 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 Options& options)
+  : descriptor_(descriptor) {
+  vars_["classname"] = descriptor_->name();
+  vars_["full_name"] = descriptor_->full_name();
+  if (options.dllexport_decl.empty()) {
+    vars_["dllexport"] = "";
+  } else {
+    vars_["dllexport"] = options.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"
+    "  protobuf_AssignDescriptorsOnce();\n"
+    "  return $classname$_descriptor_;\n"
+    "}\n"
+    "\n"
+    "const ::google::protobuf::ServiceDescriptor* $classname$::GetDescriptor() {\n"
+    "  protobuf_AssignDescriptorsOnce();\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$*,\n"
+      "                         $output_type$*,\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:  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(), 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(descriptor()->method($index$),\n"
+      "                       controller, request, response, done);\n"
+      "}\n");
+  }
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_service.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_service.h
new file mode 100644
index 0000000..ede2fd8
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_service.h
@@ -0,0 +1,118 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/compiler/cpp/cpp_options.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 Options& options);
+  ~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/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc
new file mode 100644
index 0000000..180d236
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -0,0 +1,642 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+void SetStringVariables(const FieldDescriptor* descriptor,
+                        map<string, string>* variables,
+                        const Options& options) {
+  SetCommonFieldVariables(descriptor, variables, options);
+  (*variables)["default"] = DefaultValue(descriptor);
+  (*variables)["default_length"] =
+      SimpleItoa(descriptor->default_value_string().length());
+  (*variables)["default_variable"] = descriptor->default_value_string().empty()
+      ? "&::google::protobuf::internal::GetEmptyStringAlreadyInited()"
+      : "_default_" + FieldName(descriptor) + "_";
+  (*variables)["pointer_type"] =
+      descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
+  // NOTE: Escaped here to unblock proto1->proto2 migration.
+  // TODO(liujisi): Extend this to apply for other conflicting methods.
+  (*variables)["release_name"] =
+      SafeFunctionName(descriptor->containing_type(),
+                       descriptor, "release_");
+  (*variables)["full_name"] = descriptor->full_name();
+}
+
+}  // namespace
+
+// ===================================================================
+
+StringFieldGenerator::
+StringFieldGenerator(const FieldDescriptor* descriptor,
+                     const Options& options)
+  : descriptor_(descriptor) {
+  SetStringVariables(descriptor, &variables_, options);
+}
+
+StringFieldGenerator::~StringFieldGenerator() {}
+
+void StringFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+  printer->Print(variables_, "::std::string* $name$_;\n");
+}
+
+void StringFieldGenerator::
+GenerateStaticMembers(io::Printer* printer) const {
+  if (!descriptor_->default_value_string().empty()) {
+    printer->Print(variables_, "static ::std::string* $default_variable$;\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().ctype() != FieldOptions::STRING) {
+    printer->Outdent();
+    printer->Print(
+      " private:\n"
+      "  // Hidden due to unknown ctype option.\n");
+    printer->Indent();
+  }
+
+  printer->Print(variables_,
+    "inline const ::std::string& $name$() const$deprecation$;\n"
+    "inline void set_$name$(const ::std::string& value)$deprecation$;\n"
+    "inline void set_$name$(const char* value)$deprecation$;\n"
+    "inline void set_$name$(const $pointer_type$* value, size_t size)"
+                 "$deprecation$;\n"
+    "inline ::std::string* mutable_$name$()$deprecation$;\n"
+    "inline ::std::string* $release_name$()$deprecation$;\n"
+    "inline void set_allocated_$name$(::std::string* $name$)$deprecation$;\n");
+
+
+  if (descriptor_->options().ctype() != FieldOptions::STRING) {
+    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"
+    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+    "  return *$name$_;\n"
+    "}\n"
+    "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+    "  set_has_$name$();\n"
+    "  if ($name$_ == $default_variable$) {\n"
+    "    $name$_ = new ::std::string;\n"
+    "  }\n"
+    "  $name$_->assign(value);\n"
+    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+    "}\n"
+    "inline void $classname$::set_$name$(const char* value) {\n"
+    "  set_has_$name$();\n"
+    "  if ($name$_ == $default_variable$) {\n"
+    "    $name$_ = new ::std::string;\n"
+    "  }\n"
+    "  $name$_->assign(value);\n"
+    "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
+    "}\n"
+    "inline "
+    "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
+    "  set_has_$name$();\n"
+    "  if ($name$_ == $default_variable$) {\n"
+    "    $name$_ = new ::std::string;\n"
+    "  }\n"
+    "  $name$_->assign(reinterpret_cast<const char*>(value), size);\n"
+    "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
+    "}\n"
+    "inline ::std::string* $classname$::mutable_$name$() {\n"
+    "  set_has_$name$();\n"
+    "  if ($name$_ == $default_variable$) {\n");
+  if (descriptor_->default_value_string().empty()) {
+    printer->Print(variables_,
+      "    $name$_ = new ::std::string;\n");
+  } else {
+    printer->Print(variables_,
+      "    $name$_ = new ::std::string(*$default_variable$);\n");
+  }
+  printer->Print(variables_,
+    "  }\n"
+    "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline ::std::string* $classname$::$release_name$() {\n"
+    "  clear_has_$name$();\n"
+    "  if ($name$_ == $default_variable$) {\n"
+    "    return NULL;\n"
+    "  } else {\n"
+    "    ::std::string* temp = $name$_;\n"
+    "    $name$_ = const_cast< ::std::string*>($default_variable$);\n"
+    "    return temp;\n"
+    "  }\n"
+    "}\n"
+    "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+    "  if ($name$_ != $default_variable$) {\n"
+    "    delete $name$_;\n"
+    "  }\n"
+    "  if ($name$) {\n"
+    "    set_has_$name$();\n"
+    "    $name$_ = $name$;\n"
+    "  } else {\n"
+    "    clear_has_$name$();\n"
+    "    $name$_ = const_cast< ::std::string*>($default_variable$);\n"
+    "  }\n"
+    "  // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+    "}\n");
+}
+
+void StringFieldGenerator::
+GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
+  if (!descriptor_->default_value_string().empty()) {
+    // Initialized in GenerateDefaultInstanceAllocator.
+    printer->Print(variables_,
+      "::std::string* $classname$::$default_variable$ = NULL;\n");
+  }
+}
+
+void StringFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+  if (descriptor_->default_value_string().empty()) {
+    printer->Print(variables_,
+      "if ($name$_ != $default_variable$) {\n"
+      "  $name$_->clear();\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "if ($name$_ != $default_variable$) {\n"
+      "  $name$_->assign(*$default_variable$);\n"
+      "}\n");
+  }
+}
+
+void StringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_, "set_$name$(from.$name$());\n");
+}
+
+void StringFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+  printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void StringFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$_ = const_cast< ::std::string*>($default_variable$);\n");
+}
+
+void StringFieldGenerator::
+GenerateDestructorCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($name$_ != $default_variable$) {\n"
+    "  delete $name$_;\n"
+    "}\n");
+}
+
+void StringFieldGenerator::
+GenerateDefaultInstanceAllocator(io::Printer* printer) const {
+  if (!descriptor_->default_value_string().empty()) {
+    printer->Print(variables_,
+      "$classname$::$default_variable$ =\n"
+      "    new ::std::string($default$, $default_length$);\n");
+  }
+}
+
+void StringFieldGenerator::
+GenerateShutdownCode(io::Printer* printer) const {
+  if (!descriptor_->default_value_string().empty()) {
+    printer->Print(variables_,
+      "delete $classname$::$default_variable$;\n");
+  }
+}
+
+void StringFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
+    "      input, this->mutable_$name$()));\n");
+  if (HasUtf8Verification(descriptor_->file()) &&
+      descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+    printer->Print(variables_,
+      "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+      "  this->$name$().data(), this->$name$().length(),\n"
+      "  ::google::protobuf::internal::WireFormat::PARSE,\n"
+      "  \"$name$\");\n");
+  }
+}
+
+void StringFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  if (HasUtf8Verification(descriptor_->file()) &&
+      descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+    printer->Print(variables_,
+      "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+      "  this->$name$().data(), this->$name$().length(),\n"
+      "  ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+      "  \"$name$\");\n");
+  }
+  printer->Print(variables_,
+    "::google::protobuf::internal::WireFormatLite::Write$declared_type$MaybeAliased(\n"
+    "  $number$, this->$name$(), output);\n");
+}
+
+void StringFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+  if (HasUtf8Verification(descriptor_->file()) &&
+      descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+    printer->Print(variables_,
+      "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+      "  this->$name$().data(), this->$name$().length(),\n"
+      "  ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+      "  \"$name$\");\n");
+  }
+  printer->Print(variables_,
+    "target =\n"
+    "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray(\n"
+    "    $number$, this->$name$(), target);\n");
+}
+
+void StringFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ +\n"
+    "  ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
+    "    this->$name$());\n");
+}
+
+// ===================================================================
+
+StringOneofFieldGenerator::
+StringOneofFieldGenerator(const FieldDescriptor* descriptor,
+                          const Options& options)
+  : StringFieldGenerator(descriptor, options) {
+  SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+StringOneofFieldGenerator::~StringOneofFieldGenerator() {}
+
+void StringOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const ::std::string& $classname$::$name$() const {\n"
+    "  if (has_$name$()) {\n"
+    "    return *$oneof_prefix$$name$_;\n"
+    "  }\n");
+  if (descriptor_->default_value_string().empty()) {
+    printer->Print(variables_,
+      "  return ::google::protobuf::internal::GetEmptyStringAlreadyInited();\n");
+  } else {
+    printer->Print(variables_,
+      "  return *$default_variable$;\n");
+  }
+  printer->Print(variables_,
+    "}\n"
+    "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+    "  if (!has_$name$()) {\n"
+    "    clear_$oneof_name$();\n"
+    "    set_has_$name$();\n"
+    "    $oneof_prefix$$name$_ = new ::std::string;\n"
+    "  }\n"
+    "  $oneof_prefix$$name$_->assign(value);\n"
+    "}\n"
+    "inline void $classname$::set_$name$(const char* value) {\n"
+    "  if (!has_$name$()) {\n"
+    "    clear_$oneof_name$();\n"
+    "    set_has_$name$();\n"
+    "    $oneof_prefix$$name$_ = new ::std::string;\n"
+    "  }\n"
+    "  $oneof_prefix$$name$_->assign(value);\n"
+    "}\n"
+    "inline "
+    "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
+    "  if (!has_$name$()) {\n"
+    "    clear_$oneof_name$();\n"
+    "    set_has_$name$();\n"
+    "    $oneof_prefix$$name$_ = new ::std::string;\n"
+    "  }\n"
+    "  $oneof_prefix$$name$_->assign(\n"
+    "      reinterpret_cast<const char*>(value), size);\n"
+    "}\n"
+    "inline ::std::string* $classname$::mutable_$name$() {\n"
+    "  if (!has_$name$()) {\n"
+    "    clear_$oneof_name$();\n"
+    "    set_has_$name$();\n");
+  if (descriptor_->default_value_string().empty()) {
+    printer->Print(variables_,
+      "    $oneof_prefix$$name$_ = new ::std::string;\n");
+  } else {
+    printer->Print(variables_,
+      "    $oneof_prefix$$name$_ = new ::std::string(*$default_variable$);\n");
+  }
+  printer->Print(variables_,
+    "  }\n"
+    "  return $oneof_prefix$$name$_;\n"
+    "}\n"
+    "inline ::std::string* $classname$::$release_name$() {\n"
+    "  if (has_$name$()) {\n"
+    "    clear_has_$oneof_name$();\n"
+    "    ::std::string* temp = $oneof_prefix$$name$_;\n"
+    "    $oneof_prefix$$name$_ = NULL;\n"
+    "    return temp;\n"
+    "  } else {\n"
+    "    return NULL;\n"
+    "  }\n"
+    "}\n"
+    "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+    "  clear_$oneof_name$();\n"
+    "  if ($name$) {\n"
+    "    set_has_$name$();\n"
+    "    $oneof_prefix$$name$_ = $name$;\n"
+    "  }\n"
+    "}\n");
+}
+
+void StringOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+    printer->Print(variables_,
+      "delete $oneof_prefix$$name$_;\n");
+}
+
+void StringOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+  // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void StringOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  if (!descriptor_->default_value_string().empty()) {
+    printer->Print(variables_,
+      "  $classname$_default_oneof_instance_->$name$_ = "
+      "$classname$::$default_variable$;\n");
+  } else {
+    printer->Print(variables_,
+      "  $classname$_default_oneof_instance_->$name$_ = "
+      "$default_variable$;\n");
+  }
+}
+
+void StringOneofFieldGenerator::
+GenerateDestructorCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (has_$name$()) {\n"
+    "  delete $oneof_prefix$$name$_;\n"
+    "}\n");
+}
+
+// ===================================================================
+
+RepeatedStringFieldGenerator::
+RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+                             const Options& options)
+  : descriptor_(descriptor) {
+  SetStringVariables(descriptor, &variables_, options);
+}
+
+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().ctype() != FieldOptions::STRING) {
+    printer->Outdent();
+    printer->Print(
+      " private:\n"
+      "  // Hidden due to unknown ctype option.\n");
+    printer->Indent();
+  }
+
+  printer->Print(variables_,
+    "inline const ::std::string& $name$(int index) const$deprecation$;\n"
+    "inline ::std::string* mutable_$name$(int index)$deprecation$;\n"
+    "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n"
+    "inline void set_$name$(int index, const char* value)$deprecation$;\n"
+    "inline "
+    "void set_$name$(int index, const $pointer_type$* value, size_t size)"
+                 "$deprecation$;\n"
+    "inline ::std::string* add_$name$()$deprecation$;\n"
+    "inline void add_$name$(const ::std::string& value)$deprecation$;\n"
+    "inline void add_$name$(const char* value)$deprecation$;\n"
+    "inline void add_$name$(const $pointer_type$* value, size_t size)"
+                 "$deprecation$;\n");
+
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const"
+                 "$deprecation$;\n"
+    "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
+                 "$deprecation$;\n");
+
+  if (descriptor_->options().ctype() != FieldOptions::STRING) {
+    printer->Outdent();
+    printer->Print(" public:\n");
+    printer->Indent();
+  }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+  printer->Print(variables_,
+    "inline const ::std::string& $classname$::$name$(int index) const {\n"
+    "  // @@protoc_insertion_point(field_get:$full_name$)\n"
+    "  return $name$_.$cppget$(index);\n"
+    "}\n"
+    "inline ::std::string* $classname$::mutable_$name$(int index) {\n"
+    "  // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+    "  return $name$_.Mutable(index);\n"
+    "}\n"
+    "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
+    "  // @@protoc_insertion_point(field_set:$full_name$)\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"
+    "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
+    "}\n"
+    "inline void "
+    "$classname$::set_$name$"
+    "(int index, const $pointer_type$* value, size_t size) {\n"
+    "  $name$_.Mutable(index)->assign(\n"
+    "    reinterpret_cast<const char*>(value), size);\n"
+    "  // @@protoc_insertion_point(field_set_pointer:$full_name$)\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"
+    "  // @@protoc_insertion_point(field_add:$full_name$)\n"
+    "}\n"
+    "inline void $classname$::add_$name$(const char* value) {\n"
+    "  $name$_.Add()->assign(value);\n"
+    "  // @@protoc_insertion_point(field_add_char:$full_name$)\n"
+    "}\n"
+    "inline void "
+    "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
+    "  $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
+    "  // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
+    "}\n");
+  printer->Print(variables_,
+    "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
+    "$classname$::$name$() const {\n"
+    "  // @@protoc_insertion_point(field_list:$full_name$)\n"
+    "  return $name$_;\n"
+    "}\n"
+    "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
+    "$classname$::mutable_$name$() {\n"
+    "  // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+    "  return &$name$_;\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::
+GenerateSwappingCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+  // Not needed for repeated fields.
+}
+
+void RepeatedStringFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+  printer->Print(variables_,
+    "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
+    "      input, this->add_$name$()));\n");
+  if (HasUtf8Verification(descriptor_->file()) &&
+      descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+    printer->Print(variables_,
+      "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+      "  this->$name$(this->$name$_size() - 1).data(),\n"
+      "  this->$name$(this->$name$_size() - 1).length(),\n"
+      "  ::google::protobuf::internal::WireFormat::PARSE,\n"
+      "  \"$name$\");\n");
+  }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for (int i = 0; i < this->$name$_size(); i++) {\n");
+  if (HasUtf8Verification(descriptor_->file()) &&
+      descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+    printer->Print(variables_,
+      "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+      "  this->$name$(i).data(), this->$name$(i).length(),\n"
+      "  ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+      "  \"$name$\");\n");
+  }
+  printer->Print(variables_,
+    "  ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+    "    $number$, this->$name$(i), output);\n"
+    "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for (int i = 0; i < this->$name$_size(); i++) {\n");
+  if (HasUtf8Verification(descriptor_->file()) &&
+      descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+    printer->Print(variables_,
+      "  ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+      "    this->$name$(i).data(), this->$name$(i).length(),\n"
+      "    ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+      "    \"$name$\");\n");
+  }
+  printer->Print(variables_,
+    "  target = ::google::protobuf::internal::WireFormatLite::\n"
+    "    Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
+    "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+  printer->Print(variables_,
+    "total_size += $tag_size$ * this->$name$_size();\n"
+    "for (int i = 0; i < this->$name$_size(); i++) {\n"
+    "  total_size += ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
+    "    this->$name$(i));\n"
+    "}\n");
+}
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.h
new file mode 100644
index 0000000..86da38f
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -0,0 +1,127 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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,
+                                const Options& options);
+  ~StringFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GeneratePrivateMembers(io::Printer* printer) const;
+  void GenerateStaticMembers(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 GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateDestructorCode(io::Printer* printer) const;
+  void GenerateDefaultInstanceAllocator(io::Printer* printer) const;
+  void GenerateShutdownCode(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+  void GenerateByteSize(io::Printer* printer) const;
+
+ protected:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator);
+};
+
+class StringOneofFieldGenerator : public StringFieldGenerator {
+ public:
+  explicit StringOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                     const Options& options);
+  ~StringOneofFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+  void GenerateClearingCode(io::Printer* printer) const;
+  void GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateDestructorCode(io::Printer* printer) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOneofFieldGenerator);
+};
+
+class RepeatedStringFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+                                        const Options& options);
+  ~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 GenerateSwappingCode(io::Printer* printer) const;
+  void GenerateConstructorCode(io::Printer* printer) const;
+  void GenerateMergeFromCodedStream(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+  void GenerateSerializeWithCachedSizesToArray(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/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
new file mode 100644
index 0000000..6b7f830
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto
@@ -0,0 +1,132 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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.
+
+
+// Some generic_services option(s) added automatically.
+// See:  http://go/proto2-generic-services-default
+option cc_generic_services = true;     // auto-added
+
+// 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;
+
+  enum TestEnum { FOO = 1; }
+  message Data1 { repeated int32 data = 1; }
+  message Data2 { repeated TestEnum data = 1; }
+  message Data3 { repeated string data = 1; }
+  message Data4 { repeated Data4 data = 1; }
+  message Data5 { repeated string data = 1 [ctype=STRING_PIECE]; }
+  message Data6 { repeated string data = 1 [ctype=CORD]; }
+
+  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;
+  optional uint32 class = 37;
+
+  // The generator used to #define a macro called "DO" inside the .cc file.
+  message DO {}
+  optional DO do = 32;
+
+  // Some template parameter names for extensions.
+  optional int32 field_type = 33;
+  optional bool is_packed = 34;
+
+  // test conflicting release_$name$. "length" and "do" field in this message
+  // must remain string or message fields to make the test valid.
+  optional string release_length = 35;
+  // A more extreme case, the field name "do" here is a keyword, which will be
+  // escaped to "do_" already. Test there is no conflict even with escaped field
+  // names.
+  optional DO release_do = 36;
+
+  extensions 1000 to max;
+}
+
+message TestConflictingSymbolNamesExtension {
+  extend TestConflictingSymbolNames {
+    repeated int32 repeated_int32_ext = 20423638 [packed=true];
+  }
+}
+
+message DummyMessage {}
+
+service TestConflictingMethodNames {
+  rpc Closure(DummyMessage) returns (DummyMessage);
+}
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc
new file mode 100644
index 0000000..93e1c3f
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -0,0 +1,2074 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <google/protobuf/compiler/cpp/cpp_unittest.h>
+
+#include <memory>
+#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/unittest_no_generic_services.pb.h>
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include <google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.h>
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.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>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace cpp_unittest {
+
+namespace protobuf_unittest = ::protobuf_unittest;
+
+
+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);
+  }
+};
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+// 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());
+}
+
+#endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+// ===================================================================
+
+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, Int32StringConversion) {
+  EXPECT_EQ("971", Int32ToString(971));
+  EXPECT_EQ("(~0x7fffffff)", Int32ToString(kint32min));
+  EXPECT_EQ("2147483647", Int32ToString(kint32max));
+}
+
+TEST(GeneratedMessageTest, Int64StringConversion) {
+  EXPECT_EQ("GOOGLE_LONGLONG(971)", Int64ToString(971));
+  EXPECT_EQ("GOOGLE_LONGLONG(-2147483648)", Int64ToString(kint32min));
+  EXPECT_EQ("GOOGLE_LONGLONG(~0x7fffffffffffffff)", Int64ToString(kint64min));
+  EXPECT_EQ("GOOGLE_LONGLONG(9223372036854775807)", Int64ToString(kint64max));
+}
+
+TEST(GeneratedMessageTest, FloatingPointDefaults) {
+  const unittest::TestExtremeDefaultValues& extreme_default =
+      unittest::TestExtremeDefaultValues::default_instance();
+
+  EXPECT_EQ(0.0f, extreme_default.zero_float());
+  EXPECT_EQ(1.0f, extreme_default.one_float());
+  EXPECT_EQ(1.5f, extreme_default.small_float());
+  EXPECT_EQ(-1.0f, extreme_default.negative_one_float());
+  EXPECT_EQ(-1.5f, extreme_default.negative_float());
+  EXPECT_EQ(2.0e8f, extreme_default.large_float());
+  EXPECT_EQ(-8e-28f, extreme_default.small_negative_float());
+  EXPECT_EQ(numeric_limits<double>::infinity(),
+            extreme_default.inf_double());
+  EXPECT_EQ(-numeric_limits<double>::infinity(),
+            extreme_default.neg_inf_double());
+  EXPECT_TRUE(extreme_default.nan_double() != extreme_default.nan_double());
+  EXPECT_EQ(numeric_limits<float>::infinity(),
+            extreme_default.inf_float());
+  EXPECT_EQ(-numeric_limits<float>::infinity(),
+            extreme_default.neg_inf_float());
+  EXPECT_TRUE(extreme_default.nan_float() != extreme_default.nan_float());
+}
+
+TEST(GeneratedMessageTest, Trigraph) {
+  const unittest::TestExtremeDefaultValues& extreme_default =
+      unittest::TestExtremeDefaultValues::default_instance();
+
+  EXPECT_EQ("? ? ?? ?? ??? ?\?/ ?\?-", extreme_default.cpp_trigraph());
+}
+
+TEST(GeneratedMessageTest, ExtremeSmallIntegerDefault) {
+  const unittest::TestExtremeDefaultValues& extreme_default =
+      unittest::TestExtremeDefaultValues::default_instance();
+  EXPECT_EQ(~0x7fffffff, kint32min);
+  EXPECT_EQ(GOOGLE_LONGLONG(~0x7fffffffffffffff), kint64min);
+  EXPECT_EQ(kint32min, extreme_default.really_small_int32());
+  EXPECT_EQ(kint64min, extreme_default.really_small_int64());
+}
+
+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, StringDefaults) {
+  unittest::TestExtremeDefaultValues message;
+  // Check if '\000' can be used in default string value.
+  EXPECT_EQ(string("hel\000lo", 6), message.string_with_zero());
+  EXPECT_EQ(string("wor\000ld", 6), message.bytes_with_zero());
+}
+
+TEST(GeneratedMessageTest, ReleaseString) {
+  // Check that release_foo() starts out NULL, and gives us a value
+  // that we can delete after it's been set.
+  unittest::TestAllTypes message;
+
+  EXPECT_EQ(NULL, message.release_default_string());
+  EXPECT_FALSE(message.has_default_string());
+  EXPECT_EQ("hello", message.default_string());
+
+  message.set_default_string("blah");
+  EXPECT_TRUE(message.has_default_string());
+  scoped_ptr<string> str(message.release_default_string());
+  EXPECT_FALSE(message.has_default_string());
+  ASSERT_TRUE(str != NULL);
+  EXPECT_EQ("blah", *str);
+
+  EXPECT_EQ(NULL, message.release_default_string());
+  EXPECT_FALSE(message.has_default_string());
+  EXPECT_EQ("hello", message.default_string());
+}
+
+TEST(GeneratedMessageTest, ReleaseMessage) {
+  // Check that release_foo() starts out NULL, and gives us a value
+  // that we can delete after it's been set.
+  unittest::TestAllTypes message;
+
+  EXPECT_EQ(NULL, message.release_optional_nested_message());
+  EXPECT_FALSE(message.has_optional_nested_message());
+
+  message.mutable_optional_nested_message()->set_bb(1);
+  scoped_ptr<unittest::TestAllTypes::NestedMessage> nest(
+      message.release_optional_nested_message());
+  EXPECT_FALSE(message.has_optional_nested_message());
+  ASSERT_TRUE(nest != NULL);
+  EXPECT_EQ(1, nest->bb());
+
+  EXPECT_EQ(NULL, message.release_optional_nested_message());
+  EXPECT_FALSE(message.has_optional_nested_message());
+}
+
+TEST(GeneratedMessageTest, SetAllocatedString) {
+  // Check that set_allocated_foo() works for strings.
+  unittest::TestAllTypes message;
+
+  EXPECT_FALSE(message.has_optional_string());
+  const string kHello("hello");
+  message.set_optional_string(kHello);
+  EXPECT_TRUE(message.has_optional_string());
+
+  message.set_allocated_optional_string(NULL);
+  EXPECT_FALSE(message.has_optional_string());
+  EXPECT_EQ("", message.optional_string());
+
+  message.set_allocated_optional_string(new string(kHello));
+  EXPECT_TRUE(message.has_optional_string());
+  EXPECT_EQ(kHello, message.optional_string());
+}
+
+TEST(GeneratedMessageTest, SetAllocatedMessage) {
+  // Check that set_allocated_foo() can be called in all cases.
+  unittest::TestAllTypes message;
+
+  EXPECT_FALSE(message.has_optional_nested_message());
+
+  message.mutable_optional_nested_message()->set_bb(1);
+  EXPECT_TRUE(message.has_optional_nested_message());
+
+  message.set_allocated_optional_nested_message(NULL);
+  EXPECT_FALSE(message.has_optional_nested_message());
+  EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &message.optional_nested_message());
+
+  message.mutable_optional_nested_message()->set_bb(1);
+  unittest::TestAllTypes::NestedMessage* nest =
+      message.release_optional_nested_message();
+  ASSERT_TRUE(nest != NULL);
+  EXPECT_FALSE(message.has_optional_nested_message());
+
+  message.set_allocated_optional_nested_message(nest);
+  EXPECT_TRUE(message.has_optional_nested_message());
+  EXPECT_EQ(1, message.optional_nested_message().bb());
+}
+
+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, EmbeddedNullsInBytesCharStar) {
+  unittest::TestAllTypes message;
+
+  const char* value = "\0lalala\0\0";
+  message.set_optional_bytes(value, 9);
+  ASSERT_EQ(9, message.optional_bytes().size());
+  EXPECT_EQ(0, memcmp(value, message.optional_bytes().data(), 9));
+
+  message.add_repeated_bytes(value, 9);
+  ASSERT_EQ(9, message.repeated_bytes(0).size());
+  EXPECT_EQ(0, memcmp(value, message.repeated_bytes(0).data(), 9));
+}
+
+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, StringCharStarLength) {
+  // Verify that we can use a char*,length to set one of the string fields.
+  unittest::TestAllTypes message;
+  message.set_optional_string("abcdef", 3);
+  EXPECT_EQ("abc", message.optional_string());
+
+  // Verify that we can use a char*,length to add to a repeated string field.
+  message.add_repeated_string("abcdef", 3);
+  EXPECT_EQ(1, message.repeated_string_size());
+  EXPECT_EQ("abc", message.repeated_string(0));
+
+  // Verify that we can use a char*,length to set a repeated string field.
+  message.set_repeated_string(0, "wxyz", 2);
+  EXPECT_EQ("wx", message.repeated_string(0));
+}
+
+
+TEST(GeneratedMessageTest, CopyFrom) {
+  unittest::TestAllTypes message1, message2;
+
+  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, SwapWithEmpty) {
+  unittest::TestAllTypes message1, message2;
+  TestUtil::SetAllFields(&message1);
+
+  TestUtil::ExpectAllFieldsSet(message1);
+  TestUtil::ExpectClear(message2);
+  message1.Swap(&message2);
+  TestUtil::ExpectAllFieldsSet(message2);
+  TestUtil::ExpectClear(message1);
+}
+
+TEST(GeneratedMessageTest, SwapWithSelf) {
+  unittest::TestAllTypes message;
+  TestUtil::SetAllFields(&message);
+  TestUtil::ExpectAllFieldsSet(message);
+  message.Swap(&message);
+  TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GeneratedMessageTest, SwapWithOther) {
+  unittest::TestAllTypes message1, message2;
+
+  message1.set_optional_int32(123);
+  message1.set_optional_string("abc");
+  message1.mutable_optional_nested_message()->set_bb(1);
+  message1.set_optional_nested_enum(unittest::TestAllTypes::FOO);
+  message1.add_repeated_int32(1);
+  message1.add_repeated_int32(2);
+  message1.add_repeated_string("a");
+  message1.add_repeated_string("b");
+  message1.add_repeated_nested_message()->set_bb(7);
+  message1.add_repeated_nested_message()->set_bb(8);
+  message1.add_repeated_nested_enum(unittest::TestAllTypes::FOO);
+  message1.add_repeated_nested_enum(unittest::TestAllTypes::BAR);
+
+  message2.set_optional_int32(456);
+  message2.set_optional_string("def");
+  message2.mutable_optional_nested_message()->set_bb(2);
+  message2.set_optional_nested_enum(unittest::TestAllTypes::BAR);
+  message2.add_repeated_int32(3);
+  message2.add_repeated_string("c");
+  message2.add_repeated_nested_message()->set_bb(9);
+  message2.add_repeated_nested_enum(unittest::TestAllTypes::BAZ);
+
+  message1.Swap(&message2);
+
+  EXPECT_EQ(456, message1.optional_int32());
+  EXPECT_EQ("def", message1.optional_string());
+  EXPECT_EQ(2, message1.optional_nested_message().bb());
+  EXPECT_EQ(unittest::TestAllTypes::BAR, message1.optional_nested_enum());
+  ASSERT_EQ(1, message1.repeated_int32_size());
+  EXPECT_EQ(3, message1.repeated_int32(0));
+  ASSERT_EQ(1, message1.repeated_string_size());
+  EXPECT_EQ("c", message1.repeated_string(0));
+  ASSERT_EQ(1, message1.repeated_nested_message_size());
+  EXPECT_EQ(9, message1.repeated_nested_message(0).bb());
+  ASSERT_EQ(1, message1.repeated_nested_enum_size());
+  EXPECT_EQ(unittest::TestAllTypes::BAZ, message1.repeated_nested_enum(0));
+
+  EXPECT_EQ(123, message2.optional_int32());
+  EXPECT_EQ("abc", message2.optional_string());
+  EXPECT_EQ(1, message2.optional_nested_message().bb());
+  EXPECT_EQ(unittest::TestAllTypes::FOO, message2.optional_nested_enum());
+  ASSERT_EQ(2, message2.repeated_int32_size());
+  EXPECT_EQ(1, message2.repeated_int32(0));
+  EXPECT_EQ(2, message2.repeated_int32(1));
+  ASSERT_EQ(2, message2.repeated_string_size());
+  EXPECT_EQ("a", message2.repeated_string(0));
+  EXPECT_EQ("b", message2.repeated_string(1));
+  ASSERT_EQ(2, message2.repeated_nested_message_size());
+  EXPECT_EQ(7, message2.repeated_nested_message(0).bb());
+  EXPECT_EQ(8, message2.repeated_nested_message(1).bb());
+  ASSERT_EQ(2, message2.repeated_nested_enum_size());
+  EXPECT_EQ(unittest::TestAllTypes::FOO, message2.repeated_nested_enum(0));
+  EXPECT_EQ(unittest::TestAllTypes::BAR, message2.repeated_nested_enum(1));
+}
+
+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.operator=(message2);
+  TestUtil::ExpectAllFieldsSet(message2);
+}
+
+#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \
+    !defined(GOOGLE_PROTOBUF_NO_RTTI)
+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);
+}
+#endif
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+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.get());
+
+  message2.CopyFrom(*message1);
+
+  TestUtil::ExpectAllFieldsSet(message2);
+}
+
+#endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+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);
+}
+
+#if !defined(PROTOBUF_TEST_NO_DESCRIPTORS) || \
+    !defined(GOOGLE_PROTOBUF_NO_RTTI)
+#ifdef PROTOBUF_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  // PROTOBUF_HAS_DEATH_TEST
+#endif  // !PROTOBUF_TEST_NO_DESCRIPTORS || !GOOGLE_PROTOBUF_NO_RTTI
+
+// Test the generated SerializeWithCachedSizesToArray(),
+TEST(GeneratedMessageTest, SerializationToArray) {
+  unittest::TestAllTypes message1, message2;
+  string data;
+  TestUtil::SetAllFields(&message1);
+  int size = message1.ByteSize();
+  data.resize(size);
+  uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+  uint8* end = message1.SerializeWithCachedSizesToArray(start);
+  EXPECT_EQ(size, end - start);
+  EXPECT_TRUE(message2.ParseFromString(data));
+  TestUtil::ExpectAllFieldsSet(message2);
+
+}
+
+TEST(GeneratedMessageTest, PackedFieldsSerializationToArray) {
+  unittest::TestPackedTypes packed_message1, packed_message2;
+  string packed_data;
+  TestUtil::SetPackedFields(&packed_message1);
+  int packed_size = packed_message1.ByteSize();
+  packed_data.resize(packed_size);
+  uint8* start = reinterpret_cast<uint8*>(string_as_array(&packed_data));
+  uint8* end = packed_message1.SerializeWithCachedSizesToArray(start);
+  EXPECT_EQ(packed_size, end - start);
+  EXPECT_TRUE(packed_message2.ParseFromString(packed_data));
+  TestUtil::ExpectPackedFieldsSet(packed_message2);
+}
+
+// Test the generated SerializeWithCachedSizes() by forcing the buffer to write
+// one byte at a time.
+TEST(GeneratedMessageTest, SerializationToStream) {
+  unittest::TestAllTypes message1, message2;
+  TestUtil::SetAllFields(&message1);
+  int size = message1.ByteSize();
+  string data;
+  data.resize(size);
+  {
+    // Allow the output stream to buffer only one byte at a time.
+    io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+    io::CodedOutputStream output_stream(&array_stream);
+    message1.SerializeWithCachedSizes(&output_stream);
+    EXPECT_FALSE(output_stream.HadError());
+    EXPECT_EQ(size, output_stream.ByteCount());
+  }
+  EXPECT_TRUE(message2.ParseFromString(data));
+  TestUtil::ExpectAllFieldsSet(message2);
+
+}
+
+TEST(GeneratedMessageTest, PackedFieldsSerializationToStream) {
+  unittest::TestPackedTypes message1, message2;
+  TestUtil::SetPackedFields(&message1);
+  int size = message1.ByteSize();
+  string data;
+  data.resize(size);
+  {
+    // Allow the output stream to buffer only one byte at a time.
+    io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+    io::CodedOutputStream output_stream(&array_stream);
+    message1.SerializeWithCachedSizes(&output_stream);
+    EXPECT_FALSE(output_stream.HadError());
+    EXPECT_EQ(size, output_stream.ByteCount());
+  }
+  EXPECT_TRUE(message2.ParseFromString(data));
+  TestUtil::ExpectPackedFieldsSet(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_());
+
+  message.set_class_(6);
+  EXPECT_EQ(6, message.class_());
+
+  // Instantiate extension template functions to test conflicting template
+  // parameter names.
+  typedef protobuf_unittest::TestConflictingSymbolNamesExtension ExtensionMessage;
+  message.AddExtension(ExtensionMessage::repeated_int32_ext, 123);
+  EXPECT_EQ(123,
+            message.GetExtension(ExtensionMessage::repeated_int32_ext, 0));
+}
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+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(GeneratedMessageTest, TestSpaceUsed) {
+  unittest::TestAllTypes message1;
+  // sizeof provides a lower bound on SpaceUsed().
+  EXPECT_LE(sizeof(unittest::TestAllTypes), message1.SpaceUsed());
+  const int empty_message_size = message1.SpaceUsed();
+
+  // Setting primitive types shouldn't affect the space used.
+  message1.set_optional_int32(123);
+  message1.set_optional_int64(12345);
+  message1.set_optional_uint32(123);
+  message1.set_optional_uint64(12345);
+  EXPECT_EQ(empty_message_size, message1.SpaceUsed());
+
+  // On some STL implementations, setting the string to a small value should
+  // only increase SpaceUsed() by the size of a string object, though this is
+  // not true everywhere.
+  message1.set_optional_string("abc");
+  EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsed());
+
+  // Setting a string to a value larger than the string object itself should
+  // increase SpaceUsed(), because it cannot store the value internally.
+  message1.set_optional_string(string(sizeof(string) + 1, 'x'));
+  int min_expected_increase = message1.optional_string().capacity() +
+      sizeof(string);
+  EXPECT_LE(empty_message_size + min_expected_increase,
+            message1.SpaceUsed());
+
+  int previous_size = message1.SpaceUsed();
+  // Adding an optional message should increase the size by the size of the
+  // nested message type. NestedMessage is simple enough (1 int field) that it
+  // is equal to sizeof(NestedMessage)
+  message1.mutable_optional_nested_message();
+  ASSERT_EQ(sizeof(unittest::TestAllTypes::NestedMessage),
+            message1.optional_nested_message().SpaceUsed());
+  EXPECT_EQ(previous_size +
+            sizeof(unittest::TestAllTypes::NestedMessage),
+            message1.SpaceUsed());
+}
+
+TEST(GeneratedMessageTest, TestOneofSpaceUsed) {
+  unittest::TestOneof2 message1;
+  EXPECT_LE(sizeof(unittest::TestOneof2), message1.SpaceUsed());
+
+  const int empty_message_size = message1.SpaceUsed();
+  // Setting primitive types shouldn't affect the space used.
+  message1.set_foo_int(123);
+  message1.set_bar_int(12345);
+  EXPECT_EQ(empty_message_size, message1.SpaceUsed());
+
+  // Setting a string in oneof to a small value should only increase SpaceUsed()
+  // by the size of a string object.
+  message1.set_foo_string("abc");
+  EXPECT_LE(empty_message_size + sizeof(string), message1.SpaceUsed());
+
+  // Setting a string in oneof to a value larger than the string object itself
+  // should increase SpaceUsed(), because it cannot store the value internally.
+  message1.set_foo_string(string(sizeof(string) + 1, 'x'));
+  int min_expected_increase = message1.foo_string().capacity() +
+      sizeof(string);
+  EXPECT_LE(empty_message_size + min_expected_increase,
+            message1.SpaceUsed());
+
+  // Setting a message in oneof should delete the other fields and increase the
+  // size by the size of the nested message type. NestedMessage is simple enough
+  // that it is equal to sizeof(NestedMessage)
+  message1.mutable_foo_message();
+  ASSERT_EQ(sizeof(unittest::TestOneof2::NestedMessage),
+            message1.foo_message().SpaceUsed());
+  EXPECT_EQ(empty_message_size +
+            sizeof(unittest::TestOneof2::NestedMessage),
+            message1.SpaceUsed());
+}
+
+#endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+
+TEST(GeneratedMessageTest, FieldConstantValues) {
+  unittest::TestRequired message;
+  EXPECT_EQ(unittest::TestAllTypes_NestedMessage::kBbFieldNumber, 1);
+  EXPECT_EQ(unittest::TestAllTypes::kOptionalInt32FieldNumber, 1);
+  EXPECT_EQ(unittest::TestAllTypes::kOptionalgroupFieldNumber, 16);
+  EXPECT_EQ(unittest::TestAllTypes::kOptionalNestedMessageFieldNumber, 18);
+  EXPECT_EQ(unittest::TestAllTypes::kOptionalNestedEnumFieldNumber, 21);
+  EXPECT_EQ(unittest::TestAllTypes::kRepeatedInt32FieldNumber, 31);
+  EXPECT_EQ(unittest::TestAllTypes::kRepeatedgroupFieldNumber, 46);
+  EXPECT_EQ(unittest::TestAllTypes::kRepeatedNestedMessageFieldNumber, 48);
+  EXPECT_EQ(unittest::TestAllTypes::kRepeatedNestedEnumFieldNumber, 51);
+}
+
+TEST(GeneratedMessageTest, ExtensionConstantValues) {
+  EXPECT_EQ(unittest::TestRequired::kSingleFieldNumber, 1000);
+  EXPECT_EQ(unittest::TestRequired::kMultiFieldNumber, 1001);
+  EXPECT_EQ(unittest::kOptionalInt32ExtensionFieldNumber, 1);
+  EXPECT_EQ(unittest::kOptionalgroupExtensionFieldNumber, 16);
+  EXPECT_EQ(unittest::kOptionalNestedMessageExtensionFieldNumber, 18);
+  EXPECT_EQ(unittest::kOptionalNestedEnumExtensionFieldNumber, 21);
+  EXPECT_EQ(unittest::kRepeatedInt32ExtensionFieldNumber, 31);
+  EXPECT_EQ(unittest::kRepeatedgroupExtensionFieldNumber, 46);
+  EXPECT_EQ(unittest::kRepeatedNestedMessageExtensionFieldNumber, 48);
+  EXPECT_EQ(unittest::kRepeatedNestedEnumExtensionFieldNumber, 51);
+}
+
+// ===================================================================
+
+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;
+    case unittest::TestAllTypes::NEG:
+      i = -1;
+      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::NEG,
+            unittest::TestAllTypes::NestedEnum_MIN);
+  EXPECT_EQ(unittest::TestAllTypes::BAZ,
+            unittest::TestAllTypes::NestedEnum_MAX);
+  EXPECT_EQ(4, unittest::TestAllTypes::NestedEnum_ARRAYSIZE);
+
+  EXPECT_EQ(unittest::FOREIGN_FOO, unittest::ForeignEnum_MIN);
+  EXPECT_EQ(unittest::FOREIGN_BAZ, unittest::ForeignEnum_MAX);
+  EXPECT_EQ(7, unittest::ForeignEnum_ARRAYSIZE);
+
+  EXPECT_EQ(1, unittest::TestEnumWithDupValue_MIN);
+  EXPECT_EQ(3, unittest::TestEnumWithDupValue_MAX);
+  EXPECT_EQ(4, unittest::TestEnumWithDupValue_ARRAYSIZE);
+
+  EXPECT_EQ(unittest::SPARSE_E, unittest::TestSparseEnum_MIN);
+  EXPECT_EQ(unittest::SPARSE_C, unittest::TestSparseEnum_MAX);
+  EXPECT_EQ(12589235, unittest::TestSparseEnum_ARRAYSIZE);
+
+  // Make sure we can take the address of _MIN, _MAX and _ARRAYSIZE.
+  void* null_pointer = 0;  // NULL may be integer-type, not pointer-type.
+  EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MIN);
+  EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_MAX);
+  EXPECT_NE(null_pointer, &unittest::TestAllTypes::NestedEnum_ARRAYSIZE);
+
+  EXPECT_NE(null_pointer, &unittest::ForeignEnum_MIN);
+  EXPECT_NE(null_pointer, &unittest::ForeignEnum_MAX);
+  EXPECT_NE(null_pointer, &unittest::ForeignEnum_ARRAYSIZE);
+
+  // 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;
+  }
+}
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+TEST(GeneratedEnumTest, Name) {
+  // "Names" in the presence of dup values are a bit arbitrary.
+  EXPECT_EQ("FOO1", unittest::TestEnumWithDupValue_Name(unittest::FOO1));
+  EXPECT_EQ("FOO1", unittest::TestEnumWithDupValue_Name(unittest::FOO2));
+
+  EXPECT_EQ("SPARSE_A", unittest::TestSparseEnum_Name(unittest::SPARSE_A));
+  EXPECT_EQ("SPARSE_B", unittest::TestSparseEnum_Name(unittest::SPARSE_B));
+  EXPECT_EQ("SPARSE_C", unittest::TestSparseEnum_Name(unittest::SPARSE_C));
+  EXPECT_EQ("SPARSE_D", unittest::TestSparseEnum_Name(unittest::SPARSE_D));
+  EXPECT_EQ("SPARSE_E", unittest::TestSparseEnum_Name(unittest::SPARSE_E));
+  EXPECT_EQ("SPARSE_F", unittest::TestSparseEnum_Name(unittest::SPARSE_F));
+  EXPECT_EQ("SPARSE_G", unittest::TestSparseEnum_Name(unittest::SPARSE_G));
+}
+
+TEST(GeneratedEnumTest, Parse) {
+  unittest::TestEnumWithDupValue dup_value = unittest::FOO1;
+  EXPECT_TRUE(unittest::TestEnumWithDupValue_Parse("FOO1", &dup_value));
+  EXPECT_EQ(unittest::FOO1, dup_value);
+  EXPECT_TRUE(unittest::TestEnumWithDupValue_Parse("FOO2", &dup_value));
+  EXPECT_EQ(unittest::FOO2, dup_value);
+  EXPECT_FALSE(unittest::TestEnumWithDupValue_Parse("FOO", &dup_value));
+}
+
+TEST(GeneratedEnumTest, GetEnumDescriptor) {
+  EXPECT_EQ(unittest::TestAllTypes::NestedEnum_descriptor(),
+            GetEnumDescriptor<unittest::TestAllTypes::NestedEnum>());
+  EXPECT_EQ(unittest::ForeignEnum_descriptor(),
+            GetEnumDescriptor<unittest::ForeignEnum>());
+  EXPECT_EQ(unittest::TestEnumWithDupValue_descriptor(),
+            GetEnumDescriptor<unittest::TestEnumWithDupValue>());
+  EXPECT_EQ(unittest::TestSparseEnum_descriptor(),
+            GetEnumDescriptor<unittest::TestSparseEnum>());
+}
+
+enum NonProtoEnum {
+  kFoo = 1,
+};
+
+TEST(GeneratedEnumTest, IsProtoEnumTypeTrait) {
+  EXPECT_TRUE(is_proto_enum<unittest::TestAllTypes::NestedEnum>::value);
+  EXPECT_TRUE(is_proto_enum<unittest::ForeignEnum>::value);
+  EXPECT_TRUE(is_proto_enum<unittest::TestEnumWithDupValue>::value);
+  EXPECT_TRUE(is_proto_enum<unittest::TestSparseEnum>::value);
+
+  EXPECT_FALSE(is_proto_enum<int>::value);
+  EXPECT_FALSE(is_proto_enum<NonProtoEnum>::value);
+}
+
+#endif  // PROTOBUF_TEST_NO_DESCRIPTORS
+
+// ===================================================================
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+
+// 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 PROTOBUF_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  // PROTOBUF_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_);
+}
+
+// ===================================================================
+
+class OneofTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+  }
+
+  void ExpectEnumCasesWork(const unittest::TestOneof2 &message) {
+    switch (message.foo_case()) {
+      case unittest::TestOneof2::kFooInt:
+        EXPECT_TRUE(message.has_foo_int());
+        break;
+      case unittest::TestOneof2::kFooString:
+        EXPECT_TRUE(message.has_foo_string());
+        break;
+      case unittest::TestOneof2::kFooBytes:
+        EXPECT_TRUE(message.has_foo_bytes());
+        break;
+      case unittest::TestOneof2::kFooEnum:
+        EXPECT_TRUE(message.has_foo_enum());
+        break;
+      case unittest::TestOneof2::kFooMessage:
+        EXPECT_TRUE(message.has_foo_message());
+        break;
+      case unittest::TestOneof2::kFoogroup:
+        EXPECT_TRUE(message.has_foogroup());
+        break;
+      case unittest::TestOneof2::FOO_NOT_SET:
+        break;
+    }
+  }
+};
+
+TEST_F(OneofTest, SettingOneFieldClearsOthers) {
+  unittest::TestOneof2 message;
+
+  message.set_foo_int(123);
+  EXPECT_TRUE(message.has_foo_int());
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+  message.set_foo_string("foo");
+  EXPECT_TRUE(message.has_foo_string());
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+
+  message.set_foo_bytes("qux");
+  EXPECT_TRUE(message.has_foo_bytes());
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+  message.set_foo_enum(unittest::TestOneof2::FOO);
+  EXPECT_TRUE(message.has_foo_enum());
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+  message.mutable_foo_message()->set_qux_int(234);
+  EXPECT_TRUE(message.has_foo_message());
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+  message.mutable_foogroup()->set_a(345);
+  EXPECT_TRUE(message.has_foogroup());
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+
+
+  // we repeat this because we didn't test if this properly clears other fields
+  // at the beginning.
+  message.set_foo_int(123);
+  EXPECT_TRUE(message.has_foo_int());
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message);
+}
+
+TEST_F(OneofTest, EnumCases) {
+  unittest::TestOneof2 message;
+
+  message.set_foo_int(123);
+  ExpectEnumCasesWork(message);
+  message.set_foo_string("foo");
+  ExpectEnumCasesWork(message);
+  message.set_foo_bytes("qux");
+  ExpectEnumCasesWork(message);
+  message.set_foo_enum(unittest::TestOneof2::FOO);
+  ExpectEnumCasesWork(message);
+  message.mutable_foo_message()->set_qux_int(234);
+  ExpectEnumCasesWork(message);
+  message.mutable_foogroup()->set_a(345);
+  ExpectEnumCasesWork(message);
+}
+
+TEST_F(OneofTest, PrimitiveType) {
+  unittest::TestOneof2 message;
+  // Unset field returns default value
+  EXPECT_EQ(message.foo_int(), 0);
+
+  message.set_foo_int(123);
+  EXPECT_TRUE(message.has_foo_int());
+  EXPECT_EQ(message.foo_int(), 123);
+  message.clear_foo_int();
+  EXPECT_FALSE(message.has_foo_int());
+}
+
+TEST_F(OneofTest, EnumType) {
+  unittest::TestOneof2 message;
+  // Unset field returns default value
+  EXPECT_EQ(message.foo_enum(), 1);
+
+  message.set_foo_enum(unittest::TestOneof2::FOO);
+  EXPECT_TRUE(message.has_foo_enum());
+  EXPECT_EQ(message.foo_enum(), unittest::TestOneof2::FOO);
+  message.clear_foo_enum();
+  EXPECT_FALSE(message.has_foo_enum());
+}
+
+TEST_F(OneofTest, SetString) {
+  // Check that setting a string field in various ways works
+  unittest::TestOneof2 message;
+
+  // Unset field returns default value
+  EXPECT_EQ(message.foo_string(), "");
+
+  message.set_foo_string("foo");
+  EXPECT_TRUE(message.has_foo_string());
+  EXPECT_EQ(message.foo_string(), "foo");
+  message.clear_foo_string();
+  EXPECT_FALSE(message.has_foo_string());
+
+  message.set_foo_string(string("bar"));
+  EXPECT_TRUE(message.has_foo_string());
+  EXPECT_EQ(message.foo_string(), "bar");
+  message.clear_foo_string();
+  EXPECT_FALSE(message.has_foo_string());
+
+
+  message.set_foo_string("qux", 3);
+  EXPECT_TRUE(message.has_foo_string());
+  EXPECT_EQ(message.foo_string(), "qux");
+  message.clear_foo_string();
+  EXPECT_FALSE(message.has_foo_string());
+
+  message.mutable_foo_string()->assign("quux");
+  EXPECT_TRUE(message.has_foo_string());
+  EXPECT_EQ(message.foo_string(), "quux");
+  message.clear_foo_string();
+  EXPECT_FALSE(message.has_foo_string());
+
+  message.set_foo_string("corge");
+  EXPECT_TRUE(message.has_foo_string());
+  EXPECT_EQ(message.foo_string(), "corge");
+  message.clear_foo_string();
+  EXPECT_FALSE(message.has_foo_string());
+}
+
+TEST_F(OneofTest, ReleaseString) {
+  // Check that release_foo() starts out NULL, and gives us a value
+  // that we can delete after it's been set.
+  unittest::TestOneof2 message;
+
+  EXPECT_EQ(NULL, message.release_foo_string());
+  EXPECT_FALSE(message.has_foo_string());
+
+  message.set_foo_string("blah");
+  EXPECT_TRUE(message.has_foo_string());
+  scoped_ptr<string> str(message.release_foo_string());
+  EXPECT_FALSE(message.has_foo_string());
+  ASSERT_TRUE(str != NULL);
+  EXPECT_EQ("blah", *str);
+
+  EXPECT_EQ(NULL, message.release_foo_string());
+  EXPECT_FALSE(message.has_foo_string());
+}
+
+TEST_F(OneofTest, SetAllocatedString) {
+  // Check that set_allocated_foo() works for strings.
+  unittest::TestOneof2 message;
+
+  EXPECT_FALSE(message.has_foo_string());
+  const string kHello("hello");
+  message.set_foo_string(kHello);
+  EXPECT_TRUE(message.has_foo_string());
+
+  message.set_allocated_foo_string(NULL);
+  EXPECT_FALSE(message.has_foo_string());
+  EXPECT_EQ("", message.foo_string());
+
+  message.set_allocated_foo_string(new string(kHello));
+  EXPECT_TRUE(message.has_foo_string());
+  EXPECT_EQ(kHello, message.foo_string());
+}
+
+
+TEST_F(OneofTest, SetMessage) {
+  // Check that setting a message field works
+  unittest::TestOneof2 message;
+
+  // Unset field returns default instance
+  EXPECT_EQ(&message.foo_message(),
+            &unittest::TestOneof2_NestedMessage::default_instance());
+  EXPECT_EQ(message.foo_message().qux_int(), 0);
+
+  message.mutable_foo_message()->set_qux_int(234);
+  EXPECT_TRUE(message.has_foo_message());
+  EXPECT_EQ(message.foo_message().qux_int(), 234);
+  message.clear_foo_message();
+  EXPECT_FALSE(message.has_foo_message());
+}
+
+TEST_F(OneofTest, ReleaseMessage) {
+  // Check that release_foo() starts out NULL, and gives us a value
+  // that we can delete after it's been set.
+  unittest::TestOneof2 message;
+
+  EXPECT_EQ(NULL, message.release_foo_message());
+  EXPECT_FALSE(message.has_foo_message());
+
+  message.mutable_foo_message()->set_qux_int(1);
+  EXPECT_TRUE(message.has_foo_message());
+  scoped_ptr<unittest::TestOneof2_NestedMessage> mes(
+      message.release_foo_message());
+  EXPECT_FALSE(message.has_foo_message());
+  ASSERT_TRUE(mes != NULL);
+  EXPECT_EQ(1, mes->qux_int());
+
+  EXPECT_EQ(NULL, message.release_foo_message());
+  EXPECT_FALSE(message.has_foo_message());
+}
+
+TEST_F(OneofTest, SetAllocatedMessage) {
+  // Check that set_allocated_foo() works for messages.
+  unittest::TestOneof2 message;
+
+  EXPECT_FALSE(message.has_foo_message());
+
+  message.mutable_foo_message()->set_qux_int(1);
+  EXPECT_TRUE(message.has_foo_message());
+
+  message.set_allocated_foo_message(NULL);
+  EXPECT_FALSE(message.has_foo_message());
+  EXPECT_EQ(&message.foo_message(),
+            &unittest::TestOneof2_NestedMessage::default_instance());
+
+  message.mutable_foo_message()->set_qux_int(1);
+  unittest::TestOneof2_NestedMessage* mes = message.release_foo_message();
+  ASSERT_TRUE(mes != NULL);
+  EXPECT_FALSE(message.has_foo_message());
+
+  message.set_allocated_foo_message(mes);
+  EXPECT_TRUE(message.has_foo_message());
+  EXPECT_EQ(1, message.foo_message().qux_int());
+}
+
+
+TEST_F(OneofTest, Clear) {
+  unittest::TestOneof2 message;
+
+  message.set_foo_int(1);
+  EXPECT_TRUE(message.has_foo_int());
+  message.clear_foo_int();
+  EXPECT_FALSE(message.has_foo_int());
+}
+
+TEST_F(OneofTest, Defaults) {
+  unittest::TestOneof2 message;
+
+  EXPECT_FALSE(message.has_foo_int());
+  EXPECT_EQ(message.foo_int(), 0);
+
+  EXPECT_FALSE(message.has_foo_string());
+  EXPECT_EQ(message.foo_string(), "");
+
+
+  EXPECT_FALSE(message.has_foo_bytes());
+  EXPECT_EQ(message.foo_bytes(), "");
+
+  EXPECT_FALSE(message.has_foo_enum());
+  EXPECT_EQ(message.foo_enum(), 1);
+
+  EXPECT_FALSE(message.has_foo_message());
+  EXPECT_EQ(message.foo_message().qux_int(), 0);
+
+  EXPECT_FALSE(message.has_foogroup());
+  EXPECT_EQ(message.foogroup().a(), 0);
+
+
+  EXPECT_FALSE(message.has_bar_int());
+  EXPECT_EQ(message.bar_int(), 5);
+
+  EXPECT_FALSE(message.has_bar_string());
+  EXPECT_EQ(message.bar_string(), "STRING");
+
+
+  EXPECT_FALSE(message.has_bar_bytes());
+  EXPECT_EQ(message.bar_bytes(), "BYTES");
+
+  EXPECT_FALSE(message.has_bar_enum());
+  EXPECT_EQ(message.bar_enum(), 2);
+}
+
+TEST_F(OneofTest, SwapWithEmpty) {
+  unittest::TestOneof2 message1, message2;
+  message1.set_foo_string("FOO");
+  EXPECT_TRUE(message1.has_foo_string());
+  message1.Swap(&message2);
+  EXPECT_FALSE(message1.has_foo_string());
+  EXPECT_TRUE(message2.has_foo_string());
+  EXPECT_EQ(message2.foo_string(), "FOO");
+}
+
+TEST_F(OneofTest, SwapWithSelf) {
+  unittest::TestOneof2 message;
+  message.set_foo_string("FOO");
+  EXPECT_TRUE(message.has_foo_string());
+  message.Swap(&message);
+  EXPECT_TRUE(message.has_foo_string());
+  EXPECT_EQ(message.foo_string(), "FOO");
+}
+
+TEST_F(OneofTest, SwapBothHasFields) {
+  unittest::TestOneof2 message1, message2;
+
+  message1.set_foo_string("FOO");
+  EXPECT_TRUE(message1.has_foo_string());
+  message2.mutable_foo_message()->set_qux_int(1);
+  EXPECT_TRUE(message2.has_foo_message());
+
+  message1.Swap(&message2);
+  EXPECT_FALSE(message1.has_foo_string());
+  EXPECT_FALSE(message2.has_foo_message());
+  EXPECT_TRUE(message1.has_foo_message());
+  EXPECT_EQ(message1.foo_message().qux_int(), 1);
+  EXPECT_TRUE(message2.has_foo_string());
+  EXPECT_EQ(message2.foo_string(), "FOO");
+}
+
+TEST_F(OneofTest, CopyContructor) {
+  unittest::TestOneof2 message1;
+  message1.set_foo_bytes("FOO");
+
+  unittest::TestOneof2 message2(message1);
+  EXPECT_TRUE(message2.has_foo_bytes());
+  EXPECT_EQ(message2.foo_bytes(), "FOO");
+}
+
+TEST_F(OneofTest, CopyFrom) {
+  unittest::TestOneof2 message1, message2;
+  message1.set_foo_enum(unittest::TestOneof2::BAR);
+  EXPECT_TRUE(message1.has_foo_enum());
+
+  message2.CopyFrom(message1);
+  EXPECT_TRUE(message2.has_foo_enum());
+  EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::BAR);
+
+  // Copying from self should be a no-op.
+  message2.CopyFrom(message2);
+  EXPECT_TRUE(message2.has_foo_enum());
+  EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::BAR);
+}
+
+TEST_F(OneofTest, CopyAssignmentOperator) {
+  unittest::TestOneof2 message1;
+  message1.mutable_foo_message()->set_qux_int(123);
+  EXPECT_TRUE(message1.has_foo_message());
+
+  unittest::TestOneof2 message2;
+  message2 = message1;
+  EXPECT_EQ(message2.foo_message().qux_int(), 123);
+
+  // Make sure that self-assignment does something sane.
+  message2 = message2;
+  EXPECT_EQ(message2.foo_message().qux_int(), 123);
+}
+
+TEST_F(OneofTest, UpcastCopyFrom) {
+  // Test the CopyFrom method that takes in the generic const Message&
+  // parameter.
+  unittest::TestOneof2 message1, message2;
+  message1.mutable_foogroup()->set_a(123);
+  EXPECT_TRUE(message1.has_foogroup());
+
+  const Message* source = implicit_cast<const Message*>(&message1);
+  message2.CopyFrom(*source);
+
+  EXPECT_TRUE(message2.has_foogroup());
+  EXPECT_EQ(message2.foogroup().a(), 123);
+}
+
+// Test the generated SerializeWithCachedSizesToArray(),
+// This indirectly tests MergePartialFromCodedStream()
+// We have to test each field type separately because we cannot set them at the
+// same time
+TEST_F(OneofTest, SerializationToArray) {
+  // Primitive type
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.set_foo_int(123);
+    int size = message1.ByteSize();
+    data.resize(size);
+    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* end = message1.SerializeWithCachedSizesToArray(start);
+    EXPECT_EQ(size, end - start);
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foo_int(), 123);
+  }
+
+  // String
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.set_foo_string("foo");
+    int size = message1.ByteSize();
+    data.resize(size);
+    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* end = message1.SerializeWithCachedSizesToArray(start);
+    EXPECT_EQ(size, end - start);
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foo_string(), "foo");
+  }
+
+
+  // Bytes
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.set_foo_bytes("qux");
+    int size = message1.ByteSize();
+    data.resize(size);
+    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* end = message1.SerializeWithCachedSizesToArray(start);
+    EXPECT_EQ(size, end - start);
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foo_bytes(), "qux");
+  }
+
+  // Enum
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.set_foo_enum(unittest::TestOneof2::FOO);
+    int size = message1.ByteSize();
+    data.resize(size);
+    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* end = message1.SerializeWithCachedSizesToArray(start);
+    EXPECT_EQ(size, end - start);
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::FOO);
+  }
+
+  // Message
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.mutable_foo_message()->set_qux_int(234);
+    int size = message1.ByteSize();
+    data.resize(size);
+    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* end = message1.SerializeWithCachedSizesToArray(start);
+    EXPECT_EQ(size, end - start);
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foo_message().qux_int(), 234);
+  }
+
+  // Group
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.mutable_foogroup()->set_a(345);
+    int size = message1.ByteSize();
+    data.resize(size);
+    uint8* start = reinterpret_cast<uint8*>(string_as_array(&data));
+    uint8* end = message1.SerializeWithCachedSizesToArray(start);
+    EXPECT_EQ(size, end - start);
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foogroup().a(), 345);
+  }
+
+}
+
+// Test the generated SerializeWithCachedSizes() by forcing the buffer to write
+// one byte at a time.
+// This indirectly tests MergePartialFromCodedStream()
+// We have to test each field type separately because we cannot set them at the
+// same time
+TEST_F(OneofTest, SerializationToStream) {
+  // Primitive type
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.set_foo_int(123);
+    int size = message1.ByteSize();
+    data.resize(size);
+
+    {
+      // Allow the output stream to buffer only one byte at a time.
+      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::CodedOutputStream output_stream(&array_stream);
+      message1.SerializeWithCachedSizes(&output_stream);
+      EXPECT_FALSE(output_stream.HadError());
+      EXPECT_EQ(size, output_stream.ByteCount());
+    }
+
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foo_int(), 123);
+  }
+
+  // String
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.set_foo_string("foo");
+    int size = message1.ByteSize();
+    data.resize(size);
+
+    {
+      // Allow the output stream to buffer only one byte at a time.
+      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::CodedOutputStream output_stream(&array_stream);
+      message1.SerializeWithCachedSizes(&output_stream);
+      EXPECT_FALSE(output_stream.HadError());
+      EXPECT_EQ(size, output_stream.ByteCount());
+    }
+
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foo_string(), "foo");
+  }
+
+
+  // Bytes
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.set_foo_bytes("qux");
+    int size = message1.ByteSize();
+    data.resize(size);
+
+    {
+      // Allow the output stream to buffer only one byte at a time.
+      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::CodedOutputStream output_stream(&array_stream);
+      message1.SerializeWithCachedSizes(&output_stream);
+      EXPECT_FALSE(output_stream.HadError());
+      EXPECT_EQ(size, output_stream.ByteCount());
+    }
+
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foo_bytes(), "qux");
+  }
+
+  // Enum
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.set_foo_enum(unittest::TestOneof2::FOO);
+    int size = message1.ByteSize();
+    data.resize(size);
+
+    {
+      // Allow the output stream to buffer only one byte at a time.
+      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::CodedOutputStream output_stream(&array_stream);
+      message1.SerializeWithCachedSizes(&output_stream);
+      EXPECT_FALSE(output_stream.HadError());
+      EXPECT_EQ(size, output_stream.ByteCount());
+    }
+
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::FOO);
+  }
+
+  // Message
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.mutable_foo_message()->set_qux_int(234);
+    int size = message1.ByteSize();
+    data.resize(size);
+
+    {
+      // Allow the output stream to buffer only one byte at a time.
+      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::CodedOutputStream output_stream(&array_stream);
+      message1.SerializeWithCachedSizes(&output_stream);
+      EXPECT_FALSE(output_stream.HadError());
+      EXPECT_EQ(size, output_stream.ByteCount());
+    }
+
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foo_message().qux_int(), 234);
+  }
+
+  // Group
+  {
+    unittest::TestOneof2 message1, message2;
+    string data;
+    message1.mutable_foogroup()->set_a(345);
+    int size = message1.ByteSize();
+    data.resize(size);
+
+    {
+      // Allow the output stream to buffer only one byte at a time.
+      io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+      io::CodedOutputStream output_stream(&array_stream);
+      message1.SerializeWithCachedSizes(&output_stream);
+      EXPECT_FALSE(output_stream.HadError());
+      EXPECT_EQ(size, output_stream.ByteCount());
+    }
+
+    EXPECT_TRUE(message2.ParseFromString(data));
+    EXPECT_EQ(message2.foogroup().a(), 345);
+  }
+
+}
+
+TEST_F(OneofTest, MergeFrom) {
+  unittest::TestOneof2 message1, message2;
+
+  message1.set_foo_int(123);
+  message2.MergeFrom(message1);
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+  EXPECT_TRUE(message2.has_foo_int());
+  EXPECT_EQ(message2.foo_int(), 123);
+
+  message1.set_foo_string("foo");
+  message2.MergeFrom(message1);
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+  EXPECT_TRUE(message2.has_foo_string());
+  EXPECT_EQ(message2.foo_string(), "foo");
+
+
+  message1.set_foo_bytes("qux");
+  message2.MergeFrom(message1);
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+  EXPECT_TRUE(message2.has_foo_bytes());
+  EXPECT_EQ(message2.foo_bytes(), "qux");
+
+  message1.set_foo_enum(unittest::TestOneof2::FOO);
+  message2.MergeFrom(message1);
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+  EXPECT_TRUE(message2.has_foo_enum());
+  EXPECT_EQ(message2.foo_enum(), unittest::TestOneof2::FOO);
+
+  message1.mutable_foo_message()->set_qux_int(234);
+  message2.MergeFrom(message1);
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+  EXPECT_TRUE(message2.has_foo_message());
+  EXPECT_EQ(message2.foo_message().qux_int(), 234);
+
+  message1.mutable_foogroup()->set_a(345);
+  message2.MergeFrom(message1);
+  TestUtil::ExpectAtMostOneFieldSetInOneof(message2);
+  EXPECT_TRUE(message2.has_foogroup());
+  EXPECT_EQ(message2.foogroup().a(), 345);
+
+}
+
+}  // namespace cpp_unittest
+}  // namespace cpp
+}  // namespace compiler
+
+namespace no_generic_services_test {
+  // Verify that no class called "TestService" was defined in
+  // unittest_no_generic_services.pb.h by defining a different type by the same
+  // name.  If such a service was generated, this will not compile.
+  struct TestService {
+    int i;
+  };
+}
+
+namespace compiler {
+namespace cpp {
+namespace cpp_unittest {
+
+TEST_F(GeneratedServiceTest, NoGenericServices) {
+  // Verify that non-services in unittest_no_generic_services.proto were
+  // generated.
+  no_generic_services_test::TestMessage message;
+  message.set_a(1);
+  message.SetExtension(no_generic_services_test::test_extension, 123);
+  no_generic_services_test::TestEnum e = no_generic_services_test::FOO;
+  EXPECT_EQ(e, 1);
+
+  // Verify that a ServiceDescriptor is generated for the service even if the
+  // class itself is not.
+  const FileDescriptor* file =
+      no_generic_services_test::TestMessage::descriptor()->file();
+
+  ASSERT_EQ(1, file->service_count());
+  EXPECT_EQ("TestService", file->service(0)->name());
+  ASSERT_EQ(1, file->service(0)->method_count());
+  EXPECT_EQ("Foo", file->service(0)->method(0)->name());
+}
+
+#endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
+
+// ===================================================================
+
+// This test must run last.  It verifies that descriptors were or were not
+// initialized depending on whether PROTOBUF_TEST_NO_DESCRIPTORS was defined.
+// When this is defined, we skip all tests which are expected to trigger
+// descriptor initialization.  This verifies that everything else still works
+// if descriptors are not initialized.
+TEST(DescriptorInitializationTest, Initialized) {
+#ifdef PROTOBUF_TEST_NO_DESCRIPTORS
+  bool should_have_descriptors = false;
+#else
+  bool should_have_descriptors = true;
+#endif
+
+  EXPECT_EQ(should_have_descriptors,
+    DescriptorPool::generated_pool()->InternalIsFileLoaded(
+      "google/protobuf/unittest.proto"));
+}
+
+}  // namespace cpp_unittest
+
+}  // namespace cpp
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.h b/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.h
new file mode 100644
index 0000000..69c8f44
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/cpp/cpp_unittest.h
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This header declares the namespace google::protobuf::protobuf_unittest in order to expose
+// any problems with the generated class names. We use this header to ensure
+// unittest.cc will declare the namespace prior to other includes, while obeying
+// normal include ordering.
+//
+// When generating a class name of "foo.Bar" we must ensure we prefix the class
+// name with "::", in case the namespace google::protobuf::foo exists. We intentionally
+// trigger that case here by declaring google::protobuf::protobuf_unittest.
+//
+// See ClassName in helpers.h for more details.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
+
+namespace google {
+namespace protobuf {
+namespace protobuf_unittest {}
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
diff --git a/protobuf/src/google/protobuf/compiler/importer.cc b/protobuf/src/google/protobuf/compiler/importer.cc
new file mode 100644
index 0000000..e6c446a
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/importer.cc
@@ -0,0 +1,480 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+
+#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
+#include <ctype.h>
+#endif
+
+// Returns true if the text looks like a Windows-style absolute path, starting
+// with a drive letter.  Example:  "C:\foo".  TODO(kenton):  Share this with
+// copy in command_line_interface.cc?
+static bool IsWindowsAbsolutePath(const string& text) {
+#if defined(_WIN32) || defined(__CYGWIN__)
+  return text.size() >= 3 && text[1] == ':' &&
+         isalpha(text[0]) &&
+         (text[2] == '/' || text[2] == '\\') &&
+         text.find_last_of(':') == 1;
+#else
+  return false;
+#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,
+                                 source_tree_->GetLastErrorMessage());
+    }
+    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()) {
+  pool_.EnforceWeakDependencies(true);
+  database_.RecordErrorsTo(error_collector);
+}
+
+Importer::~Importer() {}
+
+const FileDescriptor* Importer::Import(const string& filename) {
+  return pool_.FindFileByName(filename);
+}
+
+void Importer::AddUnusedImportTrackFile(const string& file_name) {
+  pool_.AddUnusedImportTrackFile(file_name);
+}
+
+void Importer::ClearUnusedImportTrackFiles() {
+  pool_.ClearUnusedImportTrackFiles();
+}
+
+// ===================================================================
+
+SourceTree::~SourceTree() {}
+
+string SourceTree::GetLastErrorMessage() {
+  return "File not found.";
+}
+
+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.
+  if (HasPrefixString(path, "\\\\")) {
+    // Avoid converting two leading backslashes.
+    path = "\\\\" + StringReplace(path.substr(2), "\\", "/", true);
+  } else {
+    path = StringReplace(path, "\\", "/", true);
+  }
+#endif
+
+  vector<string> canonical_parts;
+  vector<string> parts = Split(
+      path, "/", true);  // 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 = Join(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, "/") ||
+        IsWindowsAbsolutePath(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".
+      int after_prefix_start = -1;
+      if (filename[old_prefix.size()] == '/') {
+        after_prefix_start = old_prefix.size() + 1;
+      } else if (filename[old_prefix.size() - 1] == '/') {
+        // old_prefix is never empty, and canonicalized paths never have
+        // consecutive '/' characters.
+        after_prefix_start = old_prefix.size();
+      }
+      if (after_prefix_start != -1) {
+        // Yep.  So the prefixes are directories and the filename is a file
+        // inside them.
+        string after_prefix = filename.substr(after_prefix_start);
+        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;
+}
+
+bool DiskSourceTree::VirtualFileToDiskFile(const string& virtual_file,
+                                           string* disk_file) {
+  scoped_ptr<io::ZeroCopyInputStream> stream(
+      OpenVirtualFile(virtual_file, disk_file));
+  return stream != NULL;
+}
+
+io::ZeroCopyInputStream* DiskSourceTree::Open(const string& filename) {
+  return OpenVirtualFile(filename, NULL);
+}
+
+string DiskSourceTree::GetLastErrorMessage() {
+  return last_error_message_;
+}
+
+io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile(
+    const string& virtual_file,
+    string* disk_file) {
+  if (virtual_file != CanonicalizePath(virtual_file) ||
+      ContainsParentReference(virtual_file)) {
+    // 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.
+    last_error_message_ = "Backslashes, consecutive slashes, \".\", or \"..\" "
+                          "are not allowed in the virtual path";
+    return NULL;
+  }
+
+  for (int i = 0; i < mappings_.size(); i++) {
+    string temp_disk_file;
+    if (ApplyMapping(virtual_file, mappings_[i].virtual_path,
+                     mappings_[i].disk_path, &temp_disk_file)) {
+      io::ZeroCopyInputStream* stream = OpenDiskFile(temp_disk_file);
+      if (stream != NULL) {
+        if (disk_file != NULL) {
+          *disk_file = temp_disk_file;
+        }
+        return stream;
+      }
+
+      if (errno == EACCES) {
+        // The file exists but is not readable.
+        last_error_message_ = "Read access is denied for file: " +
+                              temp_disk_file;
+        return NULL;
+      }
+    }
+  }
+  last_error_message_ = "File not found.";
+  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/protobuf/src/google/protobuf/compiler/importer.h b/protobuf/src/google/protobuf/compiler/importer.h
new file mode 100644
index 0000000..f010fd0
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/importer.h
@@ -0,0 +1,317 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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_;
+  }
+
+  void AddUnusedImportTrackFile(const string& file_name);
+  void ClearUnusedImportTrackFiles();
+
+ 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;
+
+  // If Open() returns NULL, calling this method immediately will return an
+  // description of the error.
+  // Subclasses should implement this method and return a meaningful value for
+  // better error reporting.
+  // TODO(xiaofeng): change this to a pure virtual function.
+  virtual string GetLastErrorMessage();
+
+ 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);
+
+  // Given a virtual path, find the path to the file on disk.
+  // Return true and update disk_file with the on-disk path if the file exists.
+  // Return false and leave disk_file untouched if the file doesn't exist.
+  bool VirtualFileToDiskFile(const string& virtual_file, string* disk_file);
+
+  // implements SourceTree -------------------------------------------
+  virtual io::ZeroCopyInputStream* Open(const string& filename);
+
+  virtual string GetLastErrorMessage();
+
+ private:
+  struct Mapping {
+    string virtual_path;
+    string disk_path;
+
+    inline Mapping(const string& virtual_path_param,
+                   const string& disk_path_param)
+      : virtual_path(virtual_path_param), disk_path(disk_path_param) {}
+  };
+  vector<Mapping> mappings_;
+  string last_error_message_;
+
+  // Like Open(), but returns the on-disk path in disk_file if disk_file is
+  // non-NULL and the file could be successfully opened.
+  io::ZeroCopyInputStream* OpenVirtualFile(const string& virtual_file,
+                                           string* disk_file);
+
+  // 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/protobuf/src/google/protobuf/compiler/importer_unittest.cc b/protobuf/src/google/protobuf/compiler/importer_unittest.cc
new file mode 100644
index 0000000..387f135
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/importer_unittest.cc
@@ -0,0 +1,617 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+
+#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));
+    }
+  }
+
+  string GetLastErrorMessage() {
+    return "File not found.";
+  }
+
+ 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_OK(File::CreateDir(dirnames_[i], 0777));
+    }
+  }
+
+  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) {
+    GOOGLE_CHECK_OK(File::SetContents(filename, contents, true));
+  }
+
+  void AddSubdir(const string& dirname) {
+    GOOGLE_CHECK_OK(File::CreateDir(dirname, 0777));
+  }
+
+  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 ExpectCannotOpenFile(const string& filename,
+                            const string& error_message) {
+    scoped_ptr<io::ZeroCopyInputStream> input(source_tree_.Open(filename));
+    EXPECT_TRUE(input == NULL);
+    EXPECT_EQ(error_message, source_tree_.GetLastErrorMessage());
+  }
+
+  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!");
+  ExpectCannotOpenFile("bar", "File not found.");
+}
+
+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!");
+  ExpectCannotOpenFile("baz/bar", "File not found.");
+  ExpectCannotOpenFile("foo", "File not found.");
+  ExpectCannotOpenFile("bar", "File not found.");
+
+  // Non-canonical file names should not work.
+  ExpectCannotOpenFile("baz//foo",
+                       "Backslashes, consecutive slashes, \".\", or \"..\" are "
+                       "not allowed in the virtual path");
+  ExpectCannotOpenFile("baz/../baz/foo",
+                       "Backslashes, consecutive slashes, \".\", or \"..\" are "
+                       "not allowed in the virtual path");
+  ExpectCannotOpenFile("baz/./foo",
+                       "Backslashes, consecutive slashes, \".\", or \"..\" are "
+                       "not allowed in the virtual path");
+  ExpectCannotOpenFile("baz/foo/", "File not found.");
+}
+
+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.");
+  ExpectCannotOpenFile("../foo",
+                       "Backslashes, consecutive slashes, \".\", or \"..\" are "
+                       "not allowed in the virtual path");
+  ExpectCannotOpenFile("../bar/baz",
+                       "Backslashes, consecutive slashes, \".\", or \"..\" are "
+                       "not allowed in the virtual path");
+}
+
+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!");
+  ExpectCannotOpenFile("bar", "File not found.");
+}
+
+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!");
+  ExpectCannotOpenFile("baz", "File not found.");
+}
+
+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.
+  GOOGLE_CHECK_OK(File::CreateDir(dirnames_[0] + "/bar", 0777));
+
+  // 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");
+  source_tree_.MapPath("dir5", "/quux/");
+
+  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));
+
+  // "/foo" is not mapped (it should not be misintepreted as being under ".").
+  EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+    source_tree_.DiskFileToVirtualFile(
+      "/foo", &virtual_file, &shadowing_disk_file));
+
+#ifdef WIN32
+  // "C:\foo" is not mapped (it should not be misintepreted as being under ".").
+  EXPECT_EQ(DiskSourceTree::NO_MAPPING,
+    source_tree_.DiskFileToVirtualFile(
+      "C:\\foo", &virtual_file, &shadowing_disk_file));
+#endif  // WIN32
+
+  // 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);
+
+  // "/quux/bar" is under "/quux".
+  EXPECT_EQ(DiskSourceTree::CANNOT_OPEN,
+    source_tree_.DiskFileToVirtualFile(
+      "/quux/bar", &virtual_file, &shadowing_disk_file));
+  EXPECT_EQ("dir5/bar", virtual_file);
+}
+
+TEST_F(DiskSourceTreeTest, VirtualFileToDiskFile) {
+  // Test VirtualFileToDiskFile.
+
+  AddFile(dirnames_[0] + "/foo", "Hello World!");
+  AddFile(dirnames_[1] + "/foo", "This file should be hidden.");
+  AddFile(dirnames_[1] + "/quux", "This file should not be hidden.");
+  source_tree_.MapPath("bar", dirnames_[0]);
+  source_tree_.MapPath("bar", dirnames_[1]);
+
+  // Existent files, shadowed and non-shadowed case.
+  string disk_file;
+  EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", &disk_file));
+  EXPECT_EQ(dirnames_[0] + "/foo", disk_file);
+  EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/quux", &disk_file));
+  EXPECT_EQ(dirnames_[1] + "/quux", disk_file);
+
+  // Nonexistent file in existent directory and vice versa.
+  string not_touched = "not touched";
+  EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("bar/baz", &not_touched));
+  EXPECT_EQ("not touched", not_touched);
+  EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", &not_touched));
+  EXPECT_EQ("not touched", not_touched);
+
+  // Accept NULL as output parameter.
+  EXPECT_TRUE(source_tree_.VirtualFileToDiskFile("bar/foo", NULL));
+  EXPECT_FALSE(source_tree_.VirtualFileToDiskFile("baz/foo", NULL));
+}
+
+}  // namespace
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_context.cc b/protobuf/src/google/protobuf/compiler/java/java_context.cc
new file mode 100644
index 0000000..7d21fe6
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_context.cc
@@ -0,0 +1,195 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/compiler/java/java_context.h>
+
+#include <google/protobuf/compiler/java/java_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map_util.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+Context::Context(const FileDescriptor* file)
+    : name_resolver_(new ClassNameResolver) {
+  InitializeFieldGeneratorInfo(file);
+}
+
+Context::~Context() {
+}
+
+ClassNameResolver* Context::GetNameResolver() {
+  return name_resolver_.get();
+}
+
+namespace {
+// Whether two fields have conflicting accessors (assuming name1 and name2
+// are different). name1 and name2 are field1 and field2's camel-case name
+// respectively.
+bool IsConflicting(const FieldDescriptor* field1, const string& name1,
+                   const FieldDescriptor* field2, const string& name2,
+                   string* info) {
+  if (field1->is_repeated()) {
+    if (field2->is_repeated()) {
+      // Both fields are repeated.
+      return false;
+    } else {
+      // field1 is repeated, and field2 is not.
+      if (name1 + "Count" == name2) {
+        *info = "both repeated field \"" + field1->name() + "\" and singular " +
+            "field \"" + field2->name() + "\" generates the method \"" +
+            "get" + name1 + "Count()\"";
+        return true;
+      }
+      if (name1 + "List" == name2) {
+        *info = "both repeated field \"" + field1->name() + "\" and singular " +
+            "field \"" + field2->name() + "\" generates the method \"" +
+            "get" + name1 + "List()\"";
+        return true;
+      }
+      // Well, there are obviously many more conflicting cases, but it probably
+      // doesn't worth the effort to exhaust all of them because they rarely
+      // happen and as we are continuing adding new methods/changing existing
+      // methods the number of different conflicting cases will keep growing.
+      // We can just add more cases here when they are found in the real world.
+      return false;
+    }
+  } else {
+    if (field2->is_repeated()) {
+      return IsConflicting(field2, name2, field1, name1, info);
+    } else {
+      // None of the two fields are repeated.
+      return false;
+    }
+  }
+}
+}  // namespace
+
+void Context::InitializeFieldGeneratorInfo(const FileDescriptor* file) {
+  for (int i = 0; i < file->message_type_count(); ++i) {
+    InitializeFieldGeneratorInfoForMessage(file->message_type(i));
+  }
+}
+
+void Context::InitializeFieldGeneratorInfoForMessage(
+    const Descriptor* message) {
+  for (int i = 0; i < message->nested_type_count(); ++i) {
+    InitializeFieldGeneratorInfoForMessage(message->nested_type(i));
+  }
+  vector<const FieldDescriptor*> fields;
+  for (int i = 0; i < message->field_count(); ++i) {
+    fields.push_back(message->field(i));
+  }
+  InitializeFieldGeneratorInfoForFields(fields);
+
+  for (int i = 0; i < message->oneof_decl_count(); ++i) {
+    const OneofDescriptor* oneof = message->oneof_decl(i);
+    OneofGeneratorInfo info;
+    info.name = UnderscoresToCamelCase(oneof->name(), false);
+    info.capitalized_name = UnderscoresToCamelCase(oneof->name(), true);
+    oneof_generator_info_map_[oneof] = info;
+  }
+}
+
+void Context::InitializeFieldGeneratorInfoForFields(
+    const vector<const FieldDescriptor*>& fields) {
+  // Find out all fields that conflict with some other field in the same
+  // message.
+  vector<bool> is_conflict(fields.size());
+  vector<string> conflict_reason(fields.size());
+  for (int i = 0; i < fields.size(); ++i) {
+    const FieldDescriptor* field = fields[i];
+    const string& name = UnderscoresToCapitalizedCamelCase(field);
+    for (int j = i + 1; j < fields.size(); ++j) {
+      const FieldDescriptor* other = fields[j];
+      const string& other_name = UnderscoresToCapitalizedCamelCase(other);
+      if (name == other_name) {
+        is_conflict[i] = is_conflict[j] = true;
+        conflict_reason[i] = conflict_reason[j] =
+            "capitalized name of field \"" + field->name() +
+            "\" conflicts with field \"" + other->name() + "\"";
+      } else if (IsConflicting(field, name, other, other_name,
+                               &conflict_reason[j])) {
+        is_conflict[i] = is_conflict[j] = true;
+        conflict_reason[i] = conflict_reason[j];
+      }
+    }
+    if (is_conflict[i]) {
+      GOOGLE_LOG(WARNING) << "field \"" << field->full_name() << "\" is conflicting "
+                   << "with another field: " << conflict_reason[i];
+    }
+  }
+  for (int i = 0; i < fields.size(); ++i) {
+    const FieldDescriptor* field = fields[i];
+    FieldGeneratorInfo info;
+    info.name = UnderscoresToCamelCase(field);
+    info.capitalized_name = UnderscoresToCapitalizedCamelCase(field);
+    // For fields conflicting with some other fields, we append the field
+    // number to their field names in generated code to avoid conflicts.
+    if (is_conflict[i]) {
+      info.name += SimpleItoa(field->number());
+      info.capitalized_name += SimpleItoa(field->number());
+      info.disambiguated_reason = conflict_reason[i];
+    }
+    field_generator_info_map_[field] = info;
+  }
+}
+
+const FieldGeneratorInfo* Context::GetFieldGeneratorInfo(
+    const FieldDescriptor* field) const {
+  const FieldGeneratorInfo* result =
+      FindOrNull(field_generator_info_map_, field);
+  if (result == NULL) {
+    GOOGLE_LOG(FATAL) << "Can not find FieldGeneratorInfo for field: "
+               << field->full_name();
+  }
+  return result;
+}
+
+const OneofGeneratorInfo* Context::GetOneofGeneratorInfo(
+    const OneofDescriptor* oneof) const {
+  const OneofGeneratorInfo* result =
+      FindOrNull(oneof_generator_info_map_, oneof);
+  if (result == NULL) {
+    GOOGLE_LOG(FATAL) << "Can not find OneofGeneratorInfo for oneof: "
+               << oneof->name();
+  }
+  return result;
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_context.h b/protobuf/src/google/protobuf/compiler/java/java_context.h
new file mode 100644
index 0000000..5791445
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_context.h
@@ -0,0 +1,95 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+  class FileDescriptor;
+  class FieldDescriptor;
+  class OneofDescriptor;
+  class Descriptor;
+  namespace compiler {
+    namespace java {
+      class ClassNameResolver;  // name_resolver.h
+    }
+  }
+}  // namespace protobuf
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+struct FieldGeneratorInfo;
+struct OneofGeneratorInfo;
+// A context object holds the information that is shared among all code
+// generators.
+class Context {
+ public:
+  explicit Context(const FileDescriptor* file);
+  ~Context();
+
+  // Get the name resolver associated with this context. The resolver
+  // can be used to map descriptors to Java class names.
+  ClassNameResolver* GetNameResolver();
+
+  // Get the FieldGeneratorInfo for a given field.
+  const FieldGeneratorInfo* GetFieldGeneratorInfo(
+      const FieldDescriptor* field) const;
+
+  // Get the OneofGeneratorInfo for a given oneof.
+  const OneofGeneratorInfo* GetOneofGeneratorInfo(
+      const OneofDescriptor* oneof) const;
+
+ private:
+  void InitializeFieldGeneratorInfo(const FileDescriptor* file);
+  void InitializeFieldGeneratorInfoForMessage(const Descriptor* message);
+  void InitializeFieldGeneratorInfoForFields(
+      const vector<const FieldDescriptor*>& fields);
+
+  scoped_ptr<ClassNameResolver> name_resolver_;
+  map<const FieldDescriptor*, FieldGeneratorInfo> field_generator_info_map_;
+  map<const OneofDescriptor*, OneofGeneratorInfo> oneof_generator_info_map_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Context);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_doc_comment.cc b/protobuf/src/google/protobuf/compiler/java/java_doc_comment.cc
new file mode 100644
index 0000000..663f0c9
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_doc_comment.cc
@@ -0,0 +1,233 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+
+#include <vector>
+
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+string EscapeJavadoc(const string& input) {
+  string result;
+  result.reserve(input.size() * 2);
+
+  char prev = '*';
+
+  for (string::size_type i = 0; i < input.size(); i++) {
+    char c = input[i];
+    switch (c) {
+      case '*':
+        // Avoid "/*".
+        if (prev == '/') {
+          result.append("&#42;");
+        } else {
+          result.push_back(c);
+        }
+        break;
+      case '/':
+        // Avoid "*/".
+        if (prev == '*') {
+          result.append("&#47;");
+        } else {
+          result.push_back(c);
+        }
+        break;
+      case '@':
+        // '@' starts javadoc tags including the @deprecated tag, which will
+        // cause a compile-time error if inserted before a declaration that
+        // does not have a corresponding @Deprecated annotation.
+        result.append("&#64;");
+        break;
+      case '<':
+        // Avoid interpretation as HTML.
+        result.append("&lt;");
+        break;
+      case '>':
+        // Avoid interpretation as HTML.
+        result.append("&gt;");
+        break;
+      case '&':
+        // Avoid interpretation as HTML.
+        result.append("&amp;");
+        break;
+      case '\\':
+        // Java interprets Unicode escape sequences anywhere!
+        result.append("&#92;");
+        break;
+      default:
+        result.push_back(c);
+        break;
+    }
+
+    prev = c;
+  }
+
+  return result;
+}
+
+static void WriteDocCommentBodyForLocation(
+    io::Printer* printer, const SourceLocation& location) {
+  string comments = location.leading_comments.empty() ?
+      location.trailing_comments : location.leading_comments;
+  if (!comments.empty()) {
+    // TODO(kenton):  Ideally we should parse the comment text as Markdown and
+    //   write it back as HTML, but this requires a Markdown parser.  For now
+    //   we just use <pre> to get fixed-width text formatting.
+
+    // If the comment itself contains block comment start or end markers,
+    // HTML-escape them so that they don't accidentally close the doc comment.
+    comments = EscapeJavadoc(comments);
+
+    vector<string> lines = Split(comments, "\n");
+    while (!lines.empty() && lines.back().empty()) {
+      lines.pop_back();
+    }
+
+    printer->Print(
+        " *\n"
+        " * <pre>\n");
+    for (int i = 0; i < lines.size(); i++) {
+      // Most lines should start with a space.  Watch out for lines that start
+      // with a /, since putting that right after the leading asterisk will
+      // close the comment.
+      if (!lines[i].empty() && lines[i][0] == '/') {
+        printer->Print(" * $line$\n", "line", lines[i]);
+      } else {
+        printer->Print(" *$line$\n", "line", lines[i]);
+      }
+    }
+    printer->Print(" * </pre>\n");
+  }
+}
+
+template <typename DescriptorType>
+static void WriteDocCommentBody(
+    io::Printer* printer, const DescriptorType* descriptor) {
+  SourceLocation location;
+  if (descriptor->GetSourceLocation(&location)) {
+    WriteDocCommentBodyForLocation(printer, location);
+  }
+}
+
+static string FirstLineOf(const string& value) {
+  string result = value;
+
+  string::size_type pos = result.find_first_of('\n');
+  if (pos != string::npos) {
+    result.erase(pos);
+  }
+
+  // If line ends in an opening brace, make it "{ ... }" so it looks nice.
+  if (!result.empty() && result[result.size() - 1] == '{') {
+    result.append(" ... }");
+  }
+
+  return result;
+}
+
+void WriteMessageDocComment(io::Printer* printer, const Descriptor* message) {
+  printer->Print(
+    "/**\n"
+    " * Protobuf type {@code $fullname$}\n",
+    "fullname", EscapeJavadoc(message->full_name()));
+  WriteDocCommentBody(printer, message);
+  printer->Print(" */\n");
+}
+
+void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field) {
+  // In theory we should have slightly different comments for setters, getters,
+  // etc., but in practice everyone already knows the difference between these
+  // so it's redundant information.
+
+  // We use the field declaration as the first line of the comment, e.g.:
+  //   optional string foo = 5;
+  // This communicates a lot of information about the field in a small space.
+  // If the field is a group, the debug string might end with {.
+  printer->Print(
+    "/**\n"
+    " * <code>$def$</code>\n",
+    "def", EscapeJavadoc(FirstLineOf(field->DebugString())));
+  WriteDocCommentBody(printer, field);
+  printer->Print(" */\n");
+}
+
+void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_) {
+  printer->Print(
+    "/**\n"
+    " * Protobuf enum {@code $fullname$}\n",
+    "fullname", EscapeJavadoc(enum_->full_name()));
+  WriteDocCommentBody(printer, enum_);
+  printer->Print(" */\n");
+}
+
+void WriteEnumValueDocComment(io::Printer* printer,
+                              const EnumValueDescriptor* value) {
+  printer->Print(
+    "/**\n"
+    " * <code>$def$</code>\n",
+    "def", EscapeJavadoc(FirstLineOf(value->DebugString())));
+  WriteDocCommentBody(printer, value);
+  printer->Print(" */\n");
+}
+
+void WriteServiceDocComment(io::Printer* printer,
+                            const ServiceDescriptor* service) {
+  printer->Print(
+    "/**\n"
+    " * Protobuf service {@code $fullname$}\n",
+    "fullname", EscapeJavadoc(service->full_name()));
+  WriteDocCommentBody(printer, service);
+  printer->Print(" */\n");
+}
+
+void WriteMethodDocComment(io::Printer* printer,
+                           const MethodDescriptor* method) {
+  printer->Print(
+    "/**\n"
+    " * <code>$def$</code>\n",
+    "def", EscapeJavadoc(FirstLineOf(method->DebugString())));
+  WriteDocCommentBody(printer, method);
+  printer->Print(" */\n");
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_doc_comment.h b/protobuf/src/google/protobuf/compiler/java/java_doc_comment.h
new file mode 100644
index 0000000..7d9535c
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_doc_comment.h
@@ -0,0 +1,69 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
+
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+void WriteMessageDocComment(io::Printer* printer, const Descriptor* message);
+void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field);
+void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_);
+void WriteEnumValueDocComment(io::Printer* printer,
+                              const EnumValueDescriptor* value);
+void WriteServiceDocComment(io::Printer* printer,
+                            const ServiceDescriptor* service);
+void WriteMethodDocComment(io::Printer* printer,
+                           const MethodDescriptor* method);
+
+// Exposed for testing only.
+LIBPROTOC_EXPORT string EscapeJavadoc(const string& input);
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc b/protobuf/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc
new file mode 100644
index 0000000..ae582ea
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_doc_comment_unittest.cc
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+namespace {
+
+TEST(JavaDocCommentTest, Escaping) {
+  EXPECT_EQ("foo /&#42; bar *&#47; baz", EscapeJavadoc("foo /* bar */ baz"));
+  EXPECT_EQ("foo /&#42;&#47; baz", EscapeJavadoc("foo /*/ baz"));
+  EXPECT_EQ("{&#64;foo}", EscapeJavadoc("{@foo}"));
+  EXPECT_EQ("&lt;i&gt;&amp;&lt;/i&gt;", EscapeJavadoc("<i>&</i>"));
+  EXPECT_EQ("foo&#92;u1234bar", EscapeJavadoc("foo\\u1234bar"));
+  EXPECT_EQ("&#64;deprecated", EscapeJavadoc("@deprecated"));
+}
+
+// TODO(kenton):  It's hard to write a robust test of the doc comments -- we
+//   can only really compare the output against a golden value, which is a
+//   fairly tedious and fragile testing strategy.  If we want to go that route,
+//   it probably makes sense to bite the bullet and write a test that compares
+//   the whole generated output for unittest.proto against a golden value, with
+//   a very simple script that can be run to regenerate it with the latest code.
+//   This would mean that updates to the golden file would have to be included
+//   in any change to the code generator, which would actually be fairly useful
+//   as it allows the reviewer to see clearly how the generated code is
+//   changing.
+
+}  // namespace
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_enum.cc b/protobuf/src/google/protobuf/compiler/java/java_enum.cc
new file mode 100644
index 0000000..668377a
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_enum.cc
@@ -0,0 +1,333 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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_context.h>
+#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.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 {
+
+namespace {
+bool EnumHasCustomOptions(const EnumDescriptor* descriptor) {
+  if (descriptor->options().unknown_fields().field_count() > 0) return true;
+  for (int i = 0; i < descriptor->value_count(); ++i) {
+    const EnumValueDescriptor* value = descriptor->value(i);
+    if (value->options().unknown_fields().field_count() > 0) return true;
+  }
+  return false;
+}
+}  // namespace
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
+                             bool immutable_api,
+                             Context* context)
+  : descriptor_(descriptor), immutable_api_(immutable_api),
+    name_resolver_(context->GetNameResolver())  {
+  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) {
+  WriteEnumDocComment(printer, descriptor_);
+  if (HasDescriptorMethods(descriptor_)) {
+    printer->Print(
+      "public enum $classname$\n"
+      "    implements com.google.protobuf.ProtocolMessageEnum {\n",
+      "classname", descriptor_->name());
+  } else {
+    printer->Print(
+      "public enum $classname$\n"
+      "    implements com.google.protobuf.Internal.EnumLite {\n",
+      "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());
+    WriteEnumValueDocComment(printer, canonical_values_[i]);
+    if (canonical_values_[i]->options().deprecated()) {
+      printer->Print("@java.lang.Deprecated\n");
+    }
+    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();
+    WriteEnumValueDocComment(printer, aliases_[i].value);
+    printer->Print(vars,
+      "public static final $classname$ $name$ = $canonical_name$;\n");
+  }
+
+  for (int i = 0; i < descriptor_->value_count(); i++) {
+    map<string, string> vars;
+    vars["name"] = descriptor_->value(i)->name();
+    vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+    WriteEnumValueDocComment(printer, descriptor_->value(i));
+    printer->Print(vars,
+      "public static final int $name$_VALUE = $number$;\n");
+  }
+  printer->Print("\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"
+    "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+    "    internalGetValueMap() {\n"
+    "  return internalValueMap;\n"
+    "}\n"
+    "private static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+    "    internalValueMap =\n"
+    "      new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
+    "        public $classname$ findValueByNumber(int number) {\n"
+    "          return $classname$.valueOf(number);\n"
+    "        }\n"
+    "      };\n"
+    "\n",
+    "classname", descriptor_->name());
+
+  // -----------------------------------------------------------------
+  // Reflection
+
+  if (HasDescriptorMethods(descriptor_)) {
+    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) {
+      if (!MultipleJavaFiles(descriptor_->file(), immutable_api_)) {
+        printer->Print(
+          "  return $file$.getDescriptor().getEnumTypes().get($index$);\n",
+          "file", name_resolver_->GetClassName(descriptor_->file(),
+                                               immutable_api_),
+          "index", SimpleItoa(descriptor_->index()));
+      } else {
+        printer->Indent();
+        if (EnumHasCustomOptions(descriptor_)) {
+          // We need to load the immutable classes in order to parse custom
+          // options. However, since file level enums (no outer class) are
+          // shared by immutable code and mutable code, the immutable classes
+          // may not exist. So we try to use Java reflection to retrieve the
+          // descriptor from immutable classes.
+          printer->Print(
+            "try {\n"
+            "  java.lang.Class immutableFileClass =\n"
+            "      java.lang.Class.forName(\"$immutable_file_class_name$\");\n"
+            "  @java.lang.SuppressWarnings(\"unchecked\")\n"
+            "  java.lang.reflect.Method m =\n"
+            "      immutableFileClass.getMethod(\"getDescriptor\");\n"
+            "  com.google.protobuf.Descriptors.FileDescriptor file =\n"
+            "      (com.google.protobuf.Descriptors.FileDescriptor)\n"
+            "          m.invoke(immutableFileClass);\n"
+            "  return file.getEnumTypes().get($index$);\n"
+            "} catch (Exception e) {\n"
+            // Immutable classes cannot be found. Proceed as if custom options
+            // don't exist.
+            "}\n",
+            "immutable_file_class_name",
+            name_resolver_->GetImmutableClassName(descriptor_->file()),
+            "index", SimpleItoa(descriptor_->index()));
+        }
+        printer->Print(
+          "return $immutable_package$.$descriptor_class$.getDescriptor()\n"
+          "    .getEnumTypes().get($index$);\n",
+          "immutable_package", FileJavaPackage(descriptor_->file(), true),
+          "descriptor_class",
+          name_resolver_->GetDescriptorClassName(descriptor_->file()),
+          "index", SimpleItoa(descriptor_->index()));
+        printer->Outdent();
+      }
+    } else {
+      printer->Print(
+          "  return $parent$.$descriptor$.getEnumTypes().get($index$);\n",
+          "parent", name_resolver_->GetClassName(descriptor_->containing_type(),
+                                                 immutable_api_),
+          "descriptor", descriptor_->containing_type()->options()
+                        .no_standard_descriptor_accessor()
+                        ? "getDefaultInstance().getDescriptorForType()"
+                        : "getDescriptor()",
+          "index", SimpleItoa(descriptor_->index()));
+    }
+
+    printer->Print(
+      "}\n"
+      "\n"
+      "private static final $classname$[] VALUES = ",
+      "classname", descriptor_->name());
+
+    if (CanUseEnumValues()) {
+      // If the constants we are going to output are exactly the ones we
+      // have declared in the Java enum in the same order, then we can use
+      // the values() method that the Java compiler automatically generates
+      // for every enum.
+      printer->Print("values();\n");
+    } else {
+      printer->Print(
+        "{\n"
+        "  ");
+      for (int i = 0; i < descriptor_->value_count(); i++) {
+        printer->Print("$name$, ",
+          "name", descriptor_->value(i)->name());
+      }
+      printer->Print(
+          "\n"
+          "};\n");
+    }
+
+    printer->Print(
+      "\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"
+      "\n",
+      "classname", descriptor_->name());
+
+    // index is only used for reflection; lite implementation does not need it
+    printer->Print("private final int index;\n");
+  }
+
+  // -----------------------------------------------------------------
+
+  printer->Print(
+    "private final int value;\n\n"
+    "private $classname$(int index, int value) {\n",
+    "classname", descriptor_->name());
+  if (HasDescriptorMethods(descriptor_)) {
+    printer->Print("  this.index = index;\n");
+  }
+  printer->Print(
+    "  this.value = value;\n"
+    "}\n");
+
+  printer->Print(
+    "\n"
+    "// @@protoc_insertion_point(enum_scope:$full_name$)\n",
+    "full_name", descriptor_->full_name());
+
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+bool EnumGenerator::CanUseEnumValues() {
+  if (canonical_values_.size() != descriptor_->value_count()) {
+    return false;
+  }
+  for (int i = 0; i < descriptor_->value_count(); i++) {
+    if (descriptor_->value(i)->name() != canonical_values_[i]->name()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_enum.h b/protobuf/src/google/protobuf/compiler/java/java_enum.h
new file mode 100644
index 0000000..a0d91f5
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_enum.h
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 compiler {
+    namespace java {
+      class Context;           // context.h
+      class ClassNameResolver; // name_resolver.h
+    }
+  }
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class EnumGenerator {
+ public:
+  explicit EnumGenerator(const EnumDescriptor* descriptor,
+                         bool immutable_api,
+                         Context* context);
+  ~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_;
+
+  bool immutable_api_;
+
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+
+  bool CanUseEnumValues();
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc b/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc
new file mode 100644
index 0000000..1f0c4af
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -0,0 +1,778 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/stubs/common.h>
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_enum_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.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 {
+
+void SetEnumVariables(const FieldDescriptor* descriptor,
+                      int messageBitIndex,
+                      int builderBitIndex,
+                      const FieldGeneratorInfo* info,
+                      ClassNameResolver* name_resolver,
+                      map<string, string>* variables) {
+  SetCommonFieldVariables(descriptor, info, variables);
+
+  (*variables)["type"] =
+      name_resolver->GetImmutableClassName(descriptor->enum_type());
+  (*variables)["mutable_type"] =
+      name_resolver->GetMutableClassName(descriptor->enum_type());
+  (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
+  (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+  (*variables)["tag_size"] = SimpleItoa(
+      internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+  // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+  // by the proto compiler
+  (*variables)["deprecation"] = descriptor->options().deprecated()
+      ? "@java.lang.Deprecated " : "";
+  (*variables)["on_changed"] =
+      HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+  if (SupportFieldPresence(descriptor->file())) {
+    // For singular messages and builders, one bit is used for the hasField bit.
+    (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+    (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+    // Note that these have a trailing ";".
+    (*variables)["set_has_field_bit_message"] =
+        GenerateSetBit(messageBitIndex) + ";";
+    (*variables)["set_has_field_bit_builder"] =
+        GenerateSetBit(builderBitIndex) + ";";
+    (*variables)["clear_has_field_bit_builder"] =
+        GenerateClearBit(builderBitIndex) + ";";
+
+    (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+  } else {
+    (*variables)["set_has_field_bit_message"] = "";
+    (*variables)["set_has_field_bit_builder"] = "";
+    (*variables)["clear_has_field_bit_builder"] = "";
+
+    (*variables)["is_field_present_message"] =
+          (*variables)["name"] + "_ != " + (*variables)["default"];
+  }
+
+  // For repated builders, one bit is used for whether the array is immutable.
+  (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+  (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+  (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+  // For repeated fields, one bit is used for whether the array is immutable
+  // in the parsing constructor.
+  (*variables)["get_mutable_bit_parser"] =
+      GenerateGetBitMutableLocal(builderBitIndex);
+  (*variables)["set_mutable_bit_parser"] =
+      GenerateSetBitMutableLocal(builderBitIndex);
+
+  (*variables)["get_has_field_bit_from_local"] =
+      GenerateGetBitFromLocal(builderBitIndex);
+  (*variables)["set_has_field_bit_to_local"] =
+      GenerateSetBitToLocal(messageBitIndex);
+}
+
+}  // namespace
+
+// ===================================================================
+
+ImmutableEnumFieldGenerator::
+ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
+                            int messageBitIndex,
+                            int builderBitIndex,
+                            Context* context)
+  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+    builderBitIndex_(builderBitIndex),
+    name_resolver_(context->GetNameResolver()) {
+  SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
+                   context->GetFieldGeneratorInfo(descriptor),
+                   name_resolver_, &variables_);
+}
+
+ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {}
+
+int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
+  return 1;
+}
+
+int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
+  return 1;
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$boolean has$capitalized_name$();\n");
+  }
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private $type$ $name$_;\n");
+  PrintExtraFieldInfo(variables_, printer);
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $get_has_field_bit_message$;\n"
+      "}\n");
+  }
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  return $name$_;\n"
+    "}\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private $type$ $name$_ = $default$;\n");
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $get_has_field_bit_builder$;\n"
+      "}\n");
+  }
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  return $name$_;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
+    "  if (value == null) {\n"
+    "    throw new NullPointerException();\n"
+    "  }\n"
+    "  $set_has_field_bit_builder$\n"
+    "  $name$_ = value;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder clear$capitalized_name$() {\n"
+    "  $clear_has_field_bit_builder$\n"
+    "  $name$_ = $default$;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
+  // noop for enums
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$_ = $default$;\n"
+    "$clear_has_field_bit_builder$\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    printer->Print(variables_,
+      "if (other.has$capitalized_name$()) {\n"
+      "  set$capitalized_name$(other.get$capitalized_name$());\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "if (other.get$capitalized_name$() != $default$) {\n"
+      "  set$capitalized_name$(other.get$capitalized_name$());\n"
+      "}\n");
+  }
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    printer->Print(variables_,
+      "if ($get_has_field_bit_from_local$) {\n"
+      "  $set_has_field_bit_to_local$;\n"
+      "}\n");
+  }
+  printer->Print(variables_,
+    "result.$name$_ = $name$_;\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "int rawValue = input.readEnum();\n"
+    "$type$ value = $type$.valueOf(rawValue);\n"
+    "if (value == null) {\n");
+  if (UseUnknownFieldSet(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      "  unknownFields.mergeVarintField($number$, rawValue);\n");
+  } else {
+    printer->Print(variables_,
+      "  unknownFieldsCodedOutput.writeRawVarint32(tag);\n"
+      "  unknownFieldsCodedOutput.writeRawVarint32(rawValue);\n");
+  }
+  printer->Print(variables_,
+    "} else {\n"
+    "  $set_has_field_bit_message$\n"
+    "  $name$_ = value;\n"
+    "}\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+  // noop for enums
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($is_field_present_message$) {\n"
+    "  output.writeEnum($number$, $name$_.getNumber());\n"
+    "}\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($is_field_present_message$) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .computeEnumSize($number$, $name$_.getNumber());\n"
+    "}\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = result &&\n"
+    "    (get$capitalized_name$() == other.get$capitalized_name$());\n");
+}
+
+void ImmutableEnumFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "hash = (37 * hash) + $constant_name$;\n"
+    "hash = (53 * hash) + com.google.protobuf.Internal.hashEnum(\n"
+    "    get$capitalized_name$());\n");
+}
+
+string ImmutableEnumFieldGenerator::GetBoxedType() const {
+  return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
+}
+
+// ===================================================================
+
+ImmutableEnumOneofFieldGenerator::
+ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                 int messageBitIndex,
+                                 int builderBitIndex,
+                                 Context* context)
+    : ImmutableEnumFieldGenerator(
+          descriptor, messageBitIndex, builderBitIndex, context) {
+  const OneofGeneratorInfo* info =
+      context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+  SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableEnumOneofFieldGenerator::
+~ImmutableEnumOneofFieldGenerator() {}
+
+void ImmutableEnumOneofFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  PrintExtraFieldInfo(variables_, printer);
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $has_oneof_case_message$;\n"
+      "}\n");
+  }
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    return ($type$) $oneof_name$_;\n"
+    "  }\n"
+    "  return $default$;\n"
+    "}\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $has_oneof_case_message$;\n"
+      "}\n");
+  }
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    return ($type$) $oneof_name$_;\n"
+    "  }\n"
+    "  return $default$;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
+    "  if (value == null) {\n"
+    "    throw new NullPointerException();\n"
+    "  }\n"
+    "  $set_oneof_case_message$;\n"
+    "  $oneof_name$_ = value;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder clear$capitalized_name$() {\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    $clear_oneof_case_message$;\n"
+    "    $oneof_name$_ = null;\n"
+    "    $on_changed$\n"
+    "  }\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  result.$oneof_name$_ = $oneof_name$_;\n"
+    "}\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "set$capitalized_name$(other.get$capitalized_name$());\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "int rawValue = input.readEnum();\n"
+    "$type$ value = $type$.valueOf(rawValue);\n"
+    "if (value == null) {\n");
+  if (UseUnknownFieldSet(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      "  unknownFields.mergeVarintField($number$, rawValue);\n");
+  } else {
+    printer->Print(variables_,
+      "  unknownFieldsCodedOutput.writeRawVarint32(tag);\n"
+      "  unknownFieldsCodedOutput.writeRawVarint32(rawValue);\n");
+  }
+  printer->Print(variables_,
+    "} else {\n"
+    "  $set_oneof_case_message$;\n"
+    "  $oneof_name$_ = value;\n"
+    "}\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  output.writeEnum($number$, (($type$) $oneof_name$_).getNumber());\n"
+    "}\n");
+}
+
+void ImmutableEnumOneofFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .computeEnumSize($number$, (($type$) $oneof_name$_).getNumber());\n"
+    "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutableEnumFieldGenerator::
+RepeatedImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
+                                    int messageBitIndex,
+                                    int builderBitIndex,
+                                    Context* context)
+  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+    builderBitIndex_(builderBitIndex), context_(context),
+    name_resolver_(context->GetNameResolver()) {
+  SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
+                   context->GetFieldGeneratorInfo(descriptor),
+                   name_resolver_, &variables_);
+}
+
+RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {}
+
+int RepeatedImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
+  return 0;
+}
+
+int RepeatedImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
+  return 1;
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$int get$capitalized_name$Count();\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$$type$ get$capitalized_name$(int index);\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private java.util.List<$type$> $name$_;\n");
+  PrintExtraFieldInfo(variables_, printer);
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
+    "  return $name$_;\n"   // note:  unmodifiable list
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public int get$capitalized_name$Count() {\n"
+    "  return $name$_.size();\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+
+  if (descriptor_->options().packed() &&
+      HasGeneratedMethods(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      "private int $name$MemoizedSerializedSize;\n");
+  }
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    // One field is the list and the other field keeps track of whether the
+    // list is immutable. If it's immutable, the invariant is that it must
+    // either an instance of Collections.emptyList() or it's an ArrayList
+    // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+    // a refererence to the underlying ArrayList. This invariant allows us to
+    // share instances of lists between protocol buffers avoiding expensive
+    // memory allocations. Note, immutable is a strong guarantee here -- not
+    // just that the list cannot be modified via the reference but that the
+    // list can never be modified.
+    "private java.util.List<$type$> $name$_ =\n"
+    "  java.util.Collections.emptyList();\n"
+
+    "private void ensure$capitalized_name$IsMutable() {\n"
+    "  if (!$get_mutable_bit_builder$) {\n"
+    "    $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
+    "    $set_mutable_bit_builder$;\n"
+    "  }\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  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.
+    "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
+    "  return java.util.Collections.unmodifiableList($name$_);\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public int get$capitalized_name$Count() {\n"
+    "  return $name$_.size();\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    int index, $type$ value) {\n"
+    "  if (value == null) {\n"
+    "    throw new NullPointerException();\n"
+    "  }\n"
+    "  ensure$capitalized_name$IsMutable();\n"
+    "  $name$_.set(index, value);\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
+    "  if (value == null) {\n"
+    "    throw new NullPointerException();\n"
+    "  }\n"
+    "  ensure$capitalized_name$IsMutable();\n"
+    "  $name$_.add(value);\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder addAll$capitalized_name$(\n"
+    "    java.lang.Iterable<? extends $type$> values) {\n"
+    "  ensure$capitalized_name$IsMutable();\n"
+    "  com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+    "      values, $name$_);\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder clear$capitalized_name$() {\n"
+    "  $name$_ = java.util.Collections.emptyList();\n"
+    "  $clear_mutable_bit_builder$;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
+  // noop for enums
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$_ = java.util.Collections.emptyList();\n"
+    "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  // The code below does two optimizations:
+  //   1. If the other list is empty, there's nothing to do. This ensures we
+  //      don't allocate a new array if we already have an immutable one.
+  //   2. If the other list is non-empty and our current list is empty, we can
+  //      reuse the other list which is guaranteed to be immutable.
+  printer->Print(variables_,
+    "if (!other.$name$_.isEmpty()) {\n"
+    "  if ($name$_.isEmpty()) {\n"
+    "    $name$_ = other.$name$_;\n"
+    "    $clear_mutable_bit_builder$;\n"
+    "  } else {\n"
+    "    ensure$capitalized_name$IsMutable();\n"
+    "    $name$_.addAll(other.$name$_);\n"
+    "  }\n"
+    "  $on_changed$\n"
+    "}\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  // The code below ensures that the result has an immutable list. If our
+  // list is immutable, we can just reuse it. If not, we make it immutable.
+  printer->Print(variables_,
+    "if ($get_mutable_bit_builder$) {\n"
+    "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+    "  $clear_mutable_bit_builder$;\n"
+    "}\n"
+    "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  // Read and store the enum
+  printer->Print(variables_,
+    "int rawValue = input.readEnum();\n"
+    "$type$ value = $type$.valueOf(rawValue);\n"
+    "if (value == null) {\n");
+  if (UseUnknownFieldSet(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      "  unknownFields.mergeVarintField($number$, rawValue);\n");
+  } else {
+    printer->Print(variables_,
+      "  unknownFieldsCodedOutput.writeRawVarint32(tag);\n"
+      "  unknownFieldsCodedOutput.writeRawVarint32(rawValue);\n");
+  }
+  printer->Print(variables_,
+    "  } else {\n"
+    "  if (!$get_mutable_bit_parser$) {\n"
+    "    $name$_ = new java.util.ArrayList<$type$>();\n"
+    "    $set_mutable_bit_parser$;\n"
+    "  }\n"
+    "  $name$_.add(value);\n"
+    "}\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateParsingCodeFromPacked(io::Printer* printer) const {
+  // Wrap GenerateParsingCode's contents with a while loop.
+
+  printer->Print(variables_,
+    "int length = input.readRawVarint32();\n"
+    "int oldLimit = input.pushLimit(length);\n"
+    "while(input.getBytesUntilLimit() > 0) {\n");
+  printer->Indent();
+
+  GenerateParsingCode(printer);
+
+  printer->Outdent();
+  printer->Print(variables_,
+    "}\n"
+    "input.popLimit(oldLimit);\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($get_mutable_bit_parser$) {\n"
+    "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+    "}\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "if (get$capitalized_name$List().size() > 0) {\n"
+      "  output.writeRawVarint32($tag$);\n"
+      "  output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+      "}\n"
+      "for (int i = 0; i < $name$_.size(); i++) {\n"
+      "  output.writeEnumNoTag($name$_.get(i).getNumber());\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "for (int i = 0; i < $name$_.size(); i++) {\n"
+      "  output.writeEnum($number$, $name$_.get(i).getNumber());\n"
+      "}\n");
+  }
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "{\n"
+    "  int dataSize = 0;\n");
+  printer->Indent();
+
+  printer->Print(variables_,
+    "for (int i = 0; i < $name$_.size(); i++) {\n"
+    "  dataSize += com.google.protobuf.CodedOutputStream\n"
+    "    .computeEnumSizeNoTag($name$_.get(i).getNumber());\n"
+    "}\n");
+  printer->Print(
+    "size += dataSize;\n");
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "if (!get$capitalized_name$List().isEmpty()) {"
+      "  size += $tag_size$;\n"
+      "  size += com.google.protobuf.CodedOutputStream\n"
+      "    .computeRawVarint32Size(dataSize);\n"
+      "}");
+  } else {
+    printer->Print(variables_,
+      "size += $tag_size$ * $name$_.size();\n");
+  }
+
+  // cache the data size for packed fields.
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "$name$MemoizedSerializedSize = dataSize;\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = result && get$capitalized_name$List()\n"
+    "    .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedImmutableEnumFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (get$capitalized_name$Count() > 0) {\n"
+    "  hash = (37 * hash) + $constant_name$;\n"
+    "  hash = (53 * hash) + com.google.protobuf.Internal.hashEnumList(\n"
+    "      get$capitalized_name$List());\n"
+    "}\n");
+}
+
+string RepeatedImmutableEnumFieldGenerator::GetBoxedType() const {
+  return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_enum_field.h b/protobuf/src/google/protobuf/compiler/java/java_enum_field.h
new file mode 100644
index 0000000..6a9535a
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_enum_field.h
@@ -0,0 +1,158 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 Context;            // context.h
+      class ClassNameResolver;  // name_resolver.h
+    }
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
+ public:
+  explicit ImmutableEnumFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~ImmutableEnumFieldGenerator();
+
+  // implements ImmutableFieldGenerator ---------------------------------------
+  int GetNumBitsForMessage() const;
+  int GetNumBitsForBuilder() const;
+  void GenerateInterfaceMembers(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateInitializationCode(io::Printer* printer) const;
+  void GenerateBuilderClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateParsingDoneCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ protected:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  const int messageBitIndex_;
+  const int builderBitIndex_;
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumFieldGenerator);
+};
+
+class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator {
+ public:
+  ImmutableEnumOneofFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~ImmutableEnumOneofFieldGenerator();
+
+  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;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldGenerator);
+};
+
+class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator {
+ public:
+  explicit RepeatedImmutableEnumFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~RepeatedImmutableEnumFieldGenerator();
+
+  // implements ImmutableFieldGenerator ---------------------------------------
+  int GetNumBitsForMessage() const;
+  int GetNumBitsForBuilder() const;
+  void GenerateInterfaceMembers(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateInitializationCode(io::Printer* printer) const;
+  void GenerateBuilderClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateParsingCodeFromPacked(io::Printer* printer) const;
+  void GenerateParsingDoneCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  const int messageBitIndex_;
+  const int builderBitIndex_;
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableEnumFieldGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_extension.cc b/protobuf/src/google/protobuf/compiler/java/java_extension.cc
new file mode 100644
index 0000000..27cf416
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_extension.cc
@@ -0,0 +1,207 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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_context.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+ImmutableExtensionGenerator::ImmutableExtensionGenerator(
+    const FieldDescriptor* descriptor, Context* context)
+  : descriptor_(descriptor), context_(context),
+    name_resolver_(context->GetNameResolver()) {
+  if (descriptor_->extension_scope() != NULL) {
+    scope_ = name_resolver_->GetImmutableClassName(
+        descriptor_->extension_scope());
+  } else {
+    scope_ = name_resolver_->GetImmutableClassName(descriptor_->file());
+  }
+}
+
+ImmutableExtensionGenerator::~ImmutableExtensionGenerator() {}
+
+// Initializes the vars referenced in the generated code templates.
+void ExtensionGenerator::InitTemplateVars(const FieldDescriptor* descriptor,
+                                          const string& scope,
+                                          bool immutable,
+                                          ClassNameResolver* name_resolver,
+                                          map<string, string>* vars_pointer) {
+  map<string, string> &vars = *vars_pointer;
+  vars["scope"] = scope;
+  vars["name"] = UnderscoresToCamelCase(descriptor);
+  vars["containing_type"] =
+      name_resolver->GetClassName(descriptor->containing_type(), immutable);
+  vars["number"] = SimpleItoa(descriptor->number());
+  vars["constant_name"] = FieldConstantName(descriptor);
+  vars["index"] = SimpleItoa(descriptor->index());
+  vars["default"] = descriptor->is_repeated() ?
+      "" : DefaultValue(descriptor, immutable, name_resolver);
+  vars["type_constant"] = FieldTypeName(GetType(descriptor));
+  vars["packed"] = descriptor->options().packed() ? "true" : "false";
+  vars["enum_map"] = "null";
+  vars["prototype"] = "null";
+
+  JavaType java_type = GetJavaType(descriptor);
+  string singular_type;
+  switch (java_type) {
+    case JAVATYPE_MESSAGE:
+      singular_type = name_resolver->GetClassName(descriptor->message_type(),
+                                                   immutable);
+      vars["prototype"] = singular_type + ".getDefaultInstance()";
+      break;
+    case JAVATYPE_ENUM:
+      singular_type = name_resolver->GetClassName(descriptor->enum_type(),
+                                                   immutable);
+      vars["enum_map"] = singular_type + ".internalGetValueMap()";
+      break;
+    case JAVATYPE_STRING:
+      singular_type = "java.lang.String";
+      break;
+    case JAVATYPE_BYTES:
+      singular_type = immutable ? "com.google.protobuf.ByteString" : "byte[]";
+      break;
+    default:
+      singular_type = BoxedPrimitiveTypeName(java_type);
+      break;
+  }
+  vars["type"] = descriptor->is_repeated() ?
+      "java.util.List<" + singular_type + ">" : singular_type;
+  vars["singular_type"] = singular_type;
+}
+
+void ImmutableExtensionGenerator::Generate(io::Printer* printer) {
+  map<string, string> vars;
+  const bool kUseImmutableNames = true;
+  InitTemplateVars(descriptor_, scope_, kUseImmutableNames, name_resolver_,
+                   &vars);
+  printer->Print(vars,
+      "public static final int $constant_name$ = $number$;\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  if (HasDescriptorMethods(descriptor_->file())) {
+    // Non-lite extensions
+    if (descriptor_->extension_scope() == NULL) {
+      // Non-nested
+      printer->Print(
+          vars,
+          "public static final\n"
+          "  com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+          "    $containing_type$,\n"
+          "    $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
+          "        .newFileScopedGeneratedExtension(\n"
+          "      $singular_type$.class,\n"
+          "      $prototype$);\n");
+    } else {
+      // Nested
+      printer->Print(
+          vars,
+          "public static final\n"
+          "  com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+          "    $containing_type$,\n"
+          "    $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
+          "        .newMessageScopedGeneratedExtension(\n"
+          "      $scope$.getDefaultInstance(),\n"
+          "      $index$,\n"
+          "      $singular_type$.class,\n"
+          "      $prototype$);\n");
+    }
+  } else {
+    // Lite extensions
+    if (descriptor_->is_repeated()) {
+      printer->Print(
+          vars,
+          "public static final\n"
+          "  com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
+          "    $containing_type$,\n"
+          "    $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
+          "        .newRepeatedGeneratedExtension(\n"
+          "      $containing_type$.getDefaultInstance(),\n"
+          "      $prototype$,\n"
+          "      $enum_map$,\n"
+          "      $number$,\n"
+          "      com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
+          "      $packed$,\n"
+          "      $singular_type$.class);\n");
+    } else {
+      printer->Print(
+          vars,
+          "public static final\n"
+          "  com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n"
+          "    $containing_type$,\n"
+          "    $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n"
+          "        .newSingularGeneratedExtension(\n"
+          "      $containing_type$.getDefaultInstance(),\n"
+          "      $default$,\n"
+          "      $prototype$,\n"
+          "      $enum_map$,\n"
+          "      $number$,\n"
+          "      com.google.protobuf.WireFormat.FieldType.$type_constant$,\n"
+          "      $singular_type$.class);\n");
+    }
+  }
+}
+
+void ImmutableExtensionGenerator::GenerateNonNestedInitializationCode(
+    io::Printer* printer) {
+  if (descriptor_->extension_scope() == NULL &&
+      HasDescriptorMethods(descriptor_->file())) {
+    // Only applies to non-nested, non-lite extensions.
+    printer->Print(
+        "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
+        "name", UnderscoresToCamelCase(descriptor_),
+        "index", SimpleItoa(descriptor_->index()));
+  }
+}
+
+void ImmutableExtensionGenerator::GenerateRegistrationCode(
+    io::Printer* printer) {
+  printer->Print(
+    "registry.add($scope$.$name$);\n",
+    "scope", scope_,
+    "name", UnderscoresToCamelCase(descriptor_));
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_extension.h b/protobuf/src/google/protobuf/compiler/java/java_extension.h
new file mode 100644
index 0000000..f1701fb
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_extension.h
@@ -0,0 +1,109 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <map>
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+  class FieldDescriptor;       // descriptor.h
+  namespace compiler {
+    namespace java {
+      class Context;           // context.h
+      class ClassNameResolver; // name_resolver.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() {}
+  virtual ~ExtensionGenerator() {}
+
+  virtual void Generate(io::Printer* printer) = 0;
+  virtual void GenerateNonNestedInitializationCode(io::Printer* printer) = 0;
+  virtual void GenerateRegistrationCode(io::Printer* printer) = 0;
+
+ protected:
+  static void InitTemplateVars(const FieldDescriptor* descriptor,
+                               const string& scope,
+                               bool immutable,
+                               ClassNameResolver* name_resolver,
+                               map<string, string>* vars_pointer);
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+class ImmutableExtensionGenerator : public ExtensionGenerator {
+ public:
+  explicit ImmutableExtensionGenerator(const FieldDescriptor* descriptor,
+                                       Context* context);
+  virtual ~ImmutableExtensionGenerator();
+
+  virtual void Generate(io::Printer* printer);
+  virtual void GenerateNonNestedInitializationCode(io::Printer* printer);
+  virtual void GenerateRegistrationCode(io::Printer* printer);
+
+ protected:
+  const FieldDescriptor* descriptor_;
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+  string scope_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableExtensionGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_field.cc b/protobuf/src/google/protobuf/compiler/java/java_field.cc
new file mode 100644
index 0000000..d7b0f3f
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_field.cc
@@ -0,0 +1,213 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_enum_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_lazy_message_field.h>
+#include <google/protobuf/compiler/java/java_message_field.h>
+#include <google/protobuf/compiler/java/java_primitive_field.h>
+#include <google/protobuf/compiler/java/java_string_field.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 {
+
+ImmutableFieldGenerator* MakeImmutableGenerator(
+    const FieldDescriptor* field, int messageBitIndex, int builderBitIndex,
+    Context* context) {
+  if (field->is_repeated()) {
+    switch (GetJavaType(field)) {
+      case JAVATYPE_MESSAGE:
+        if (IsLazy(field)) {
+          return new RepeatedImmutableLazyMessageFieldGenerator(
+              field, messageBitIndex, builderBitIndex, context);
+        } else {
+          return new RepeatedImmutableMessageFieldGenerator(
+              field, messageBitIndex, builderBitIndex, context);
+        }
+      case JAVATYPE_ENUM:
+        return new RepeatedImmutableEnumFieldGenerator(
+            field, messageBitIndex, builderBitIndex, context);
+      case JAVATYPE_STRING:
+        return new RepeatedImmutableStringFieldGenerator(
+            field, messageBitIndex, builderBitIndex, context);
+      default:
+        return new RepeatedImmutablePrimitiveFieldGenerator(
+            field, messageBitIndex, builderBitIndex, context);
+    }
+  } else {
+    if (field->containing_oneof()) {
+      switch (GetJavaType(field)) {
+        case JAVATYPE_MESSAGE:
+          if (IsLazy(field)) {
+            return new ImmutableLazyMessageOneofFieldGenerator(
+                field, messageBitIndex, builderBitIndex, context);
+          } else {
+            return new ImmutableMessageOneofFieldGenerator(
+                field, messageBitIndex, builderBitIndex, context);
+          }
+        case JAVATYPE_ENUM:
+          return new ImmutableEnumOneofFieldGenerator(
+              field, messageBitIndex, builderBitIndex, context);
+        case JAVATYPE_STRING:
+          return new ImmutableStringOneofFieldGenerator(
+              field, messageBitIndex, builderBitIndex, context);
+        default:
+          return new ImmutablePrimitiveOneofFieldGenerator(
+              field, messageBitIndex, builderBitIndex, context);
+      }
+    } else {
+      switch (GetJavaType(field)) {
+        case JAVATYPE_MESSAGE:
+          if (IsLazy(field)) {
+            return new ImmutableLazyMessageFieldGenerator(
+                field, messageBitIndex, builderBitIndex, context);
+          } else {
+            return new ImmutableMessageFieldGenerator(
+                field, messageBitIndex, builderBitIndex, context);
+          }
+        case JAVATYPE_ENUM:
+          return new ImmutableEnumFieldGenerator(
+              field, messageBitIndex, builderBitIndex, context);
+        case JAVATYPE_STRING:
+          return new ImmutableStringFieldGenerator(
+              field, messageBitIndex, builderBitIndex, context);
+        default:
+          return new ImmutablePrimitiveFieldGenerator(
+              field, messageBitIndex, builderBitIndex, context);
+      }
+    }
+  }
+}
+
+
+static inline void ReportUnexpectedPackedFieldsCall(io::Printer* printer) {
+  // Reaching here indicates a bug. Cases are:
+  //   - This FieldGenerator should support packing,
+  //     but this method should be overridden.
+  //   - This FieldGenerator doesn't support packing, and this method
+  //     should never have been called.
+  GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
+             << "called on field generator that does not support packing.";
+}
+
+}  // namespace
+
+ImmutableFieldGenerator::~ImmutableFieldGenerator() {}
+
+void ImmutableFieldGenerator::
+GenerateParsingCodeFromPacked(io::Printer* printer) const {
+  ReportUnexpectedPackedFieldsCall(printer);
+}
+
+// ===================================================================
+
+template <>
+FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap(
+    const Descriptor* descriptor, Context* context)
+    : descriptor_(descriptor),
+      field_generators_(new scoped_ptr<
+          ImmutableFieldGenerator>[descriptor->field_count()]) {
+
+  // Construct all the FieldGenerators and assign them bit indices for their
+  // bit fields.
+  int messageBitIndex = 0;
+  int builderBitIndex = 0;
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    ImmutableFieldGenerator* generator = MakeImmutableGenerator(
+        descriptor->field(i), messageBitIndex, builderBitIndex, context);
+    field_generators_[i].reset(generator);
+    messageBitIndex += generator->GetNumBitsForMessage();
+    builderBitIndex += generator->GetNumBitsForBuilder();
+  }
+}
+
+template<>
+FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap() {}
+
+
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+                             const FieldGeneratorInfo* info,
+                             map<string, string>* variables) {
+  (*variables)["field_name"] = descriptor->name();
+  (*variables)["name"] = info->name;
+  (*variables)["capitalized_name"] = info->capitalized_name;
+  (*variables)["disambiguated_reason"] = info->disambiguated_reason;
+  (*variables)["constant_name"] = FieldConstantName(descriptor);
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+}
+
+void SetCommonOneofVariables(const FieldDescriptor* descriptor,
+                             const OneofGeneratorInfo* info,
+                             map<string, string>* variables) {
+  (*variables)["oneof_name"] = info->name;
+  (*variables)["oneof_capitalized_name"] = info->capitalized_name;
+  (*variables)["oneof_index"] =
+      SimpleItoa(descriptor->containing_oneof()->index());
+  (*variables)["set_oneof_case_message"] = info->name +
+      "Case_ = " + SimpleItoa(descriptor->number());
+  (*variables)["clear_oneof_case_message"] = info->name +
+      "Case_ = 0";
+  (*variables)["has_oneof_case_message"] = info->name +
+      "Case_ == " + SimpleItoa(descriptor->number());
+}
+
+void PrintExtraFieldInfo(const map<string, string>& variables,
+                         io::Printer* printer) {
+  const map<string, string>::const_iterator it =
+      variables.find("disambiguated_reason");
+  if (it != variables.end() && !it->second.empty()) {
+    printer->Print(
+        variables,
+        "// An alternative name is used for field \"$field_name$\" because:\n"
+        "//     $disambiguated_reason$\n");
+  }
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_field.h b/protobuf/src/google/protobuf/compiler/java/java_field.h
new file mode 100644
index 0000000..db339d5
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_field.h
@@ -0,0 +1,162 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <map>
+#include <memory>
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+  namespace compiler {
+    namespace java {
+      class Context;                // context.h
+      class ClassNameResolver;      // name_resolver.h
+    }
+  }
+  namespace io {
+    class Printer;                  // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableFieldGenerator {
+ public:
+  ImmutableFieldGenerator() {}
+  virtual ~ImmutableFieldGenerator();
+
+  virtual int GetNumBitsForMessage() const = 0;
+  virtual int GetNumBitsForBuilder() const = 0;
+  virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0;
+  virtual void GenerateMembers(io::Printer* printer) const = 0;
+  virtual void GenerateBuilderMembers(io::Printer* printer) const = 0;
+  virtual void GenerateInitializationCode(io::Printer* printer) const = 0;
+  virtual void GenerateBuilderClearCode(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 GenerateParsingCodeFromPacked(io::Printer* printer) const;
+  virtual void GenerateParsingDoneCode(io::Printer* printer) const = 0;
+  virtual void GenerateSerializationCode(io::Printer* printer) const = 0;
+  virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
+  virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer)
+      const = 0;
+
+  virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
+  virtual void GenerateHashCode(io::Printer* printer) const = 0;
+
+  virtual string GetBoxedType() const = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableFieldGenerator);
+};
+
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+template<typename FieldGeneratorType>
+class FieldGeneratorMap {
+ public:
+  explicit FieldGeneratorMap(const Descriptor* descriptor,
+                             Context* context);
+  ~FieldGeneratorMap();
+
+  const FieldGeneratorType& get(const FieldDescriptor* field) const;
+
+ private:
+  const Descriptor* descriptor_;
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+  scoped_array<scoped_ptr<FieldGeneratorType> > field_generators_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+template<typename FieldGeneratorType>
+inline const FieldGeneratorType&
+FieldGeneratorMap<FieldGeneratorType>::get(const FieldDescriptor* field) const {
+  GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+  return *field_generators_[field->index()];
+}
+
+// Instantiate template for mutable and immutable maps.
+template<>
+FieldGeneratorMap<ImmutableFieldGenerator>::
+FieldGeneratorMap(const Descriptor* descriptor,
+                  Context* context);
+
+template<>
+FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap();
+
+
+// Field information used in FieldGeneartors.
+struct FieldGeneratorInfo {
+  string name;
+  string capitalized_name;
+  string disambiguated_reason;
+};
+
+// Oneof information used in OneofFieldGeneartors.
+struct OneofGeneratorInfo {
+  string name;
+  string capitalized_name;
+};
+
+// Set some common variables used in variable FieldGenerators.
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+                             const FieldGeneratorInfo* info,
+                             map<string, string>* variables);
+
+// Set some common oneof variables used in OneofFieldGenerators.
+void SetCommonOneofVariables(const FieldDescriptor* descriptor,
+                             const OneofGeneratorInfo* info,
+                             map<string, string>* variables);
+
+// Print useful comments before a field's accessors.
+void PrintExtraFieldInfo(const map<string, string>& variables,
+                         io::Printer* printer);
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_file.cc b/protobuf/src/google/protobuf/compiler/java/java_file.cc
new file mode 100644
index 0000000..231b144
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_file.cc
@@ -0,0 +1,534 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_generator_factory.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_message.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/compiler/java/java_service.h>
+#include <google/protobuf/compiler/java/java_shared_code_generator.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/dynamic_message.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+
+
+// Recursively searches the given message to collect extensions.
+// Returns true if all the extensions can be recognized. The extensions will be
+// appended in to the extensions parameter.
+// Returns false when there are unknown fields, in which case the data in the
+// extensions output parameter is not reliable and should be discarded.
+bool CollectExtensions(const Message& message,
+                       vector<const FieldDescriptor*>* extensions) {
+  const Reflection* reflection = message.GetReflection();
+
+  // There are unknown fields that could be extensions, thus this call fails.
+  if (reflection->GetUnknownFields(message).field_count() > 0) return false;
+
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(message, &fields);
+
+  for (int i = 0; i < fields.size(); i++) {
+    if (fields[i]->is_extension()) extensions->push_back(fields[i]);
+
+    if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) {
+      if (fields[i]->is_repeated()) {
+        int size = reflection->FieldSize(message, fields[i]);
+        for (int j = 0; j < size; j++) {
+          const Message& sub_message =
+            reflection->GetRepeatedMessage(message, fields[i], j);
+          if (!CollectExtensions(sub_message, extensions)) return false;
+        }
+      } else {
+        const Message& sub_message = reflection->GetMessage(message, fields[i]);
+        if (!CollectExtensions(sub_message, extensions)) return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+// Finds all extensions in the given message and its sub-messages.  If the
+// message contains unknown fields (which could be extensions), then those
+// extensions are defined in alternate_pool.
+// The message will be converted to a DynamicMessage backed by alternate_pool
+// in order to handle this case.
+void CollectExtensions(const FileDescriptorProto& file_proto,
+                       const DescriptorPool& alternate_pool,
+                       vector<const FieldDescriptor*>* extensions,
+                       const string& file_data) {
+  if (!CollectExtensions(file_proto, extensions)) {
+    // There are unknown fields in the file_proto, which are probably
+    // extensions. We need to parse the data into a dynamic message based on the
+    // builder-pool to find out all extensions.
+    const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName(
+        file_proto.GetDescriptor()->full_name());
+    GOOGLE_CHECK(file_proto_desc)
+        << "Find unknown fields in FileDescriptorProto when building "
+        << file_proto.name()
+        << ". It's likely that those fields are custom options, however, "
+           "descriptor.proto is not in the transitive dependencies. "
+           "This normally should not happen. Please report a bug.";
+    DynamicMessageFactory factory;
+    scoped_ptr<Message> dynamic_file_proto(
+        factory.GetPrototype(file_proto_desc)->New());
+    GOOGLE_CHECK(dynamic_file_proto.get() != NULL);
+    GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data));
+
+    // Collect the extensions again from the dynamic message. There should be no
+    // more unknown fields this time, i.e. all the custom options should be
+    // parsed as extensions now.
+    extensions->clear();
+    GOOGLE_CHECK(CollectExtensions(*dynamic_file_proto, extensions))
+        << "Find unknown fields in FileDescriptorProto when building "
+        << file_proto.name()
+        << ". It's likely that those fields are custom options, however, "
+           "those options cannot be recognized in the builder pool. "
+           "This normally should not happen. Please report a bug.";
+  }
+}
+
+
+}  // namespace
+
+FileGenerator::FileGenerator(const FileDescriptor* file, bool immutable_api)
+    : file_(file),
+      java_package_(FileJavaPackage(file, immutable_api)),
+      message_generators_(
+          new scoped_ptr<MessageGenerator>[file->message_type_count()]),
+      extension_generators_(
+          new scoped_ptr<ExtensionGenerator>[file->extension_count()]),
+      context_(new Context(file)),
+      name_resolver_(context_->GetNameResolver()),
+      immutable_api_(immutable_api) {
+  classname_ = name_resolver_->GetFileClassName(file, immutable_api);
+  generator_factory_.reset(
+      new ImmutableGeneratorFactory(context_.get()));
+  for (int i = 0; i < file_->message_type_count(); ++i) {
+    message_generators_[i].reset(
+        generator_factory_->NewMessageGenerator(file_->message_type(i)));
+  }
+  for (int i = 0; i < file_->extension_count(); ++i) {
+    extension_generators_[i].reset(
+        generator_factory_->NewExtensionGenerator(file_->extension(i)));
+  }
+}
+
+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.
+  if (name_resolver_->HasConflictingClassName(file_, classname_)) {
+    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;
+  }
+  // If java_outer_classname option is not set and the default outer class name
+  // conflicts with a type defined in the message, we will append a suffix to
+  // avoid the conflict. This allows proto1 API protos to be dual-compiled into
+  // proto2 API without code change. When this happens we'd like to issue an
+  // warning to let the user know that the outer class name has been changed.
+  // Although we only do this automatic naming fix for immutable API, mutable
+  // outer class name will also be affected as it's contructed from immutable
+  // outer class name with an additional "Mutable" prefix. Since the naming
+  // change in mutable API is not caused by a naming conflict, we generate the
+  // warning for immutable API only.
+  if (immutable_api_ && !file_->options().has_java_outer_classname()) {
+    string default_classname =
+        name_resolver_->GetFileDefaultImmutableClassName(file_);
+    if (default_classname != classname_) {
+      GOOGLE_LOG(WARNING) << file_->name() << ": The default outer class name, \""
+                   << default_classname << "\", conflicts with a type "
+                   << "declared in the proto file and an alternative outer "
+                   << "class name is used: \"" << classname_ << "\". To avoid "
+                   << "this warning, please use the java_outer_classname "
+                   << "option to specify a different outer class name for "
+                   << "the .proto file.";
+    }
+  }
+  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"
+    "// source: $filename$\n"
+    "\n",
+    "filename", file_->name());
+  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();
+
+  // -----------------------------------------------------------------
+
+  printer->Print(
+    "public static void registerAllExtensions(\n"
+    "    com.google.protobuf.ExtensionRegistry$lite$ registry) {\n",
+    "lite", HasDescriptorMethods(file_) ? "" : "Lite");
+
+  printer->Indent();
+
+  for (int i = 0; i < file_->extension_count(); i++) {
+    extension_generators_[i]->GenerateRegistrationCode(printer);
+  }
+
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateExtensionRegistrationCode(printer);
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "}\n");
+
+  // -----------------------------------------------------------------
+
+  if (!MultipleJavaFiles(file_, immutable_api_)) {
+    for (int i = 0; i < file_->enum_type_count(); i++) {
+      EnumGenerator(file_->enum_type(i), immutable_api_, context_.get())
+          .Generate(printer);
+    }
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      message_generators_[i]->GenerateInterface(printer);
+      message_generators_[i]->Generate(printer);
+    }
+    if (HasGenericServices(file_)) {
+      for (int i = 0; i < file_->service_count(); i++) {
+        scoped_ptr<ServiceGenerator> generator(
+            generator_factory_->NewServiceGenerator(file_->service(i)));
+        generator->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++) {
+    extension_generators_[i]->Generate(printer);
+  }
+
+  // Static variables.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateStaticVariables(printer);
+  }
+
+  printer->Print("\n");
+
+  if (HasDescriptorMethods(file_)) {
+    if (immutable_api_) {
+      GenerateDescriptorInitializationCodeForImmutable(printer);
+    } else {
+      GenerateDescriptorInitializationCodeForMutable(printer);
+    }
+  } else {
+    printer->Print(
+      "static {\n");
+    printer->Indent();
+
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      message_generators_[i]->GenerateStaticVariableInitializers(printer);
+    }
+
+    printer->Outdent();
+    printer->Print(
+      "}\n");
+  }
+
+  printer->Print(
+    "\n"
+    "// @@protoc_insertion_point(outer_class_scope)\n");
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void FileGenerator::GenerateDescriptorInitializationCodeForImmutable(
+    io::Printer* printer) {
+  printer->Print(
+    "public static com.google.protobuf.Descriptors.FileDescriptor\n"
+    "    getDescriptor() {\n"
+    "  return descriptor;\n"
+    "}\n"
+    "private static com.google.protobuf.Descriptors.FileDescriptor\n"
+    "    descriptor;\n"
+    "static {\n");
+  printer->Indent();
+
+  SharedCodeGenerator shared_code_generator(file_);
+  shared_code_generator.GenerateDescriptors(printer);
+
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateStaticVariableInitializers(printer);
+  }
+  for (int i = 0; i < file_->extension_count(); i++) {
+    extension_generators_[i]->GenerateNonNestedInitializationCode(printer);
+  }
+
+  // Proto compiler builds a DescriptorPool, which holds all the descriptors to
+  // generate, when processing the ".proto" files. We call this DescriptorPool
+  // the parsed pool (a.k.a. file_->pool()).
+  //
+  // Note that when users try to extend the (.*)DescriptorProto in their
+  // ".proto" files, it does not affect the pre-built FileDescriptorProto class
+  // in proto compiler. When we put the descriptor data in the file_proto, those
+  // extensions become unknown fields.
+  //
+  // Now we need to find out all the extension value to the (.*)DescriptorProto
+  // in the file_proto message, and prepare an ExtensionRegistry to return.
+  //
+  // To find those extensions, we need to parse the data into a dynamic message
+  // of the FileDescriptor based on the builder-pool, then we can use
+  // reflections to find all extension fields
+  FileDescriptorProto file_proto;
+  file_->CopyTo(&file_proto);
+  string file_data;
+  file_proto.SerializeToString(&file_data);
+  vector<const FieldDescriptor*> extensions;
+  CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
+
+  if (extensions.size() > 0) {
+    // Must construct an ExtensionRegistry containing all existing extensions
+    // and use it to parse the descriptor data again to recognize extensions.
+    printer->Print(
+      "com.google.protobuf.ExtensionRegistry registry =\n"
+      "    com.google.protobuf.ExtensionRegistry.newInstance();\n");
+    for (int i = 0; i < extensions.size(); i++) {
+      scoped_ptr<ExtensionGenerator> generator(
+          generator_factory_->NewExtensionGenerator(extensions[i]));
+      generator->GenerateRegistrationCode(printer);
+    }
+    printer->Print(
+      "com.google.protobuf.Descriptors.FileDescriptor\n"
+      "    .internalUpdateFileDescriptor(descriptor, registry);\n");
+  }
+
+  // Force descriptor initialization of all dependencies.
+  for (int i = 0; i < file_->dependency_count(); i++) {
+    if (ShouldIncludeDependency(file_->dependency(i), true)) {
+      string dependency =
+          name_resolver_->GetImmutableClassName(file_->dependency(i));
+      printer->Print(
+        "$dependency$.getDescriptor();\n",
+        "dependency", dependency);
+    }
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "}\n");
+}
+
+void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer* printer) {
+  printer->Print(
+    "public static com.google.protobuf.Descriptors.FileDescriptor\n"
+    "    getDescriptor() {\n"
+    "  return descriptor;\n"
+    "}\n"
+    "private static com.google.protobuf.Descriptors.FileDescriptor\n"
+    "    descriptor;\n"
+    "static {\n");
+  printer->Indent();
+
+  printer->Print(
+    "descriptor = $immutable_package$.$descriptor_classname$.descriptor;\n",
+    "immutable_package", FileJavaPackage(file_, true),
+    "descriptor_classname", name_resolver_->GetDescriptorClassName(file_));
+
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    message_generators_[i]->GenerateStaticVariableInitializers(printer);
+  }
+  for (int i = 0; i < file_->extension_count(); i++) {
+    extension_generators_[i]->GenerateNonNestedInitializationCode(printer);
+  }
+
+  // Check if custom options exist. If any, try to load immutable classes since
+  // custom options are only represented with immutable messages.
+  FileDescriptorProto file_proto;
+  file_->CopyTo(&file_proto);
+  string file_data;
+  file_proto.SerializeToString(&file_data);
+  vector<const FieldDescriptor*> extensions;
+  CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
+
+  if (extensions.size() > 0) {
+    // Try to load immutable messages' outer class. Its initialization code
+    // will take care of interpreting custom options.
+    printer->Print(
+      "try {\n"
+      // Note that we have to load the immutable class dynamically here as
+      // we want the mutable code to be independent from the immutable code
+      // at compile time. It is required to implement dual-compile for
+      // mutable and immutable API in blaze.
+      "  java.lang.Class immutableClass = java.lang.Class.forName(\n"
+      "      \"$immutable_classname$\");\n"
+      "} catch (java.lang.ClassNotFoundException e) {\n"
+      // The immutable class can not be found. Custom options are left
+      // as unknown fields.
+      // TODO(xiaofeng): inform the user with a warning?
+      "}\n",
+      "immutable_classname", name_resolver_->GetImmutableClassName(file_));
+  }
+
+  // Force descriptor initialization of all dependencies.
+  for (int i = 0; i < file_->dependency_count(); i++) {
+    if (ShouldIncludeDependency(file_->dependency(i), false)) {
+      string dependency = name_resolver_->GetMutableClassName(
+          file_->dependency(i));
+      printer->Print(
+        "$dependency$.getDescriptor();\n",
+        "dependency", dependency);
+    }
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "}\n");
+}
+
+template<typename GeneratorClass, typename DescriptorClass>
+static void GenerateSibling(const string& package_dir,
+                            const string& java_package,
+                            const DescriptorClass* descriptor,
+                            GeneratorContext* context,
+                            vector<string>* file_list,
+                            const string& name_suffix,
+                            GeneratorClass* generator,
+                            void (GeneratorClass::*pfn)(io::Printer* printer)) {
+  string filename = package_dir + descriptor->name() + name_suffix + ".java";
+  file_list->push_back(filename);
+
+  scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+  io::Printer printer(output.get(), '$');
+
+  printer.Print(
+    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
+    "// source: $filename$\n"
+    "\n",
+    "filename", descriptor->file()->name());
+  if (!java_package.empty()) {
+    printer.Print(
+      "package $package$;\n"
+      "\n",
+      "package", java_package);
+  }
+
+  (generator->*pfn)(&printer);
+}
+
+void FileGenerator::GenerateSiblings(const string& package_dir,
+                                     GeneratorContext* context,
+                                     vector<string>* file_list) {
+  if (MultipleJavaFiles(file_, immutable_api_)) {
+    for (int i = 0; i < file_->enum_type_count(); i++) {
+      EnumGenerator generator(file_->enum_type(i), immutable_api_,
+                              context_.get());
+      GenerateSibling<EnumGenerator>(package_dir, java_package_,
+                                     file_->enum_type(i),
+                                     context, file_list, "",
+                                     &generator,
+                                     &EnumGenerator::Generate);
+    }
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      if (immutable_api_) {
+        GenerateSibling<MessageGenerator>(package_dir, java_package_,
+                                          file_->message_type(i),
+                                          context, file_list,
+                                          "OrBuilder",
+                                          message_generators_[i].get(),
+                                          &MessageGenerator::GenerateInterface);
+      }
+      GenerateSibling<MessageGenerator>(package_dir, java_package_,
+                                        file_->message_type(i),
+                                        context, file_list, "",
+                                        message_generators_[i].get(),
+                                        &MessageGenerator::Generate);
+    }
+    if (HasGenericServices(file_)) {
+      for (int i = 0; i < file_->service_count(); i++) {
+        scoped_ptr<ServiceGenerator> generator(
+            generator_factory_->NewServiceGenerator(file_->service(i)));
+        GenerateSibling<ServiceGenerator>(package_dir, java_package_,
+                                          file_->service(i),
+                                          context, file_list, "",
+                                          generator.get(),
+                                          &ServiceGenerator::Generate);
+      }
+    }
+  }
+}
+
+bool FileGenerator::ShouldIncludeDependency(
+    const FileDescriptor* descriptor, bool immutable_api) {
+  return true;
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_file.h b/protobuf/src/google/protobuf/compiler/java/java_file.h
new file mode 100644
index 0000000..c805b9a
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_file.h
@@ -0,0 +1,115 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+#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 GeneratorContext;      // code_generator.h
+    namespace java {
+      class Context;             // context.h
+      class MessageGenerator;    // message.h
+      class GeneratorFactory;    // generator_factory.h
+      class ExtensionGenerator;  // extension.h
+      class ClassNameResolver;   // name_resolver.h
+    }
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class FileGenerator {
+ public:
+  FileGenerator(const FileDescriptor* file, bool immutable_api = true);
+  ~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,
+                        GeneratorContext* generator_context,
+                        vector<string>* file_list);
+
+  const string& java_package() { return java_package_; }
+  const string& classname()    { return classname_;    }
+
+
+ private:
+  void GenerateDescriptorInitializationCodeForImmutable(io::Printer* printer);
+  void GenerateDescriptorInitializationCodeForMutable(io::Printer* printer);
+
+  bool ShouldIncludeDependency(const FileDescriptor* descriptor,
+                               bool immutable_api_);
+
+  const FileDescriptor* file_;
+  string java_package_;
+  string classname_;
+
+  scoped_array<scoped_ptr<MessageGenerator> > message_generators_;
+  scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
+  scoped_ptr<GeneratorFactory> generator_factory_;
+  scoped_ptr<Context> context_;
+  ClassNameResolver* name_resolver_;
+  bool immutable_api_;
+
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_generator.cc b/protobuf/src/google/protobuf/compiler/java/java_generator.cc
new file mode 100644
index 0000000..c3a47e3
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_generator.cc
@@ -0,0 +1,158 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+
+#include <google/protobuf/compiler/java/java_file.h>
+#include <google/protobuf/compiler/java/java_generator_factory.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_shared_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 {
+
+
+JavaGenerator::JavaGenerator() {}
+JavaGenerator::~JavaGenerator() {}
+
+bool JavaGenerator::Generate(const FileDescriptor* file,
+                             const string& parameter,
+                             GeneratorContext* context,
+                             string* error) const {
+  // -----------------------------------------------------------------
+  // parse generator options
+
+  // Name a file where we will write a list of generated file names, one
+  // per line.
+  string output_list_file;
+
+
+  vector<pair<string, string> > options;
+  ParseGeneratorParameter(parameter, &options);
+
+  bool generate_immutable_code = false;
+  bool generate_mutable_code = false;
+  bool generate_shared_code = false;
+  for (int i = 0; i < options.size(); i++) {
+    if (options[i].first == "output_list_file") {
+      output_list_file = options[i].second;
+    } else if (options[i].first == "immutable") {
+      generate_immutable_code = true;
+    } else if (options[i].first == "mutable") {
+      generate_mutable_code = true;
+    } else if (options[i].first == "shared") {
+      generate_shared_code = true;
+    } else {
+      *error = "Unknown generator option: " + options[i].first;
+      return false;
+    }
+  }
+
+  // By default we generate immutable code and shared code for immutable API.
+  if (!generate_immutable_code && !generate_mutable_code &&
+      !generate_shared_code) {
+    generate_immutable_code = true;
+    generate_shared_code = true;
+  }
+
+  // -----------------------------------------------------------------
+
+
+  vector<string> all_files;
+
+  vector<FileGenerator*> file_generators;
+  if (generate_immutable_code) {
+    file_generators.push_back(new FileGenerator(file, /* immutable = */ true));
+  }
+  for (int i = 0; i < file_generators.size(); ++i) {
+    if (!file_generators[i]->Validate(error)) {
+      for (int j = 0; j < file_generators.size(); ++j) {
+        delete file_generators[j];
+      }
+      return false;
+    }
+  }
+
+  for (int i = 0; i < file_generators.size(); ++i) {
+    FileGenerator* file_generator = file_generators[i];
+
+    string package_dir = JavaPackageToDir(file_generator->java_package());
+
+    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(
+        context->Open(java_filename));
+    io::Printer printer(output.get(), '$');
+    file_generator->Generate(&printer);
+
+    // Generate sibling files.
+    file_generator->GenerateSiblings(package_dir, context, &all_files);
+  }
+
+  for (int i = 0; i < file_generators.size(); ++i) {
+    delete file_generators[i];
+  }
+  file_generators.clear();
+
+  // 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(
+        context->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/protobuf/src/google/protobuf/compiler/java/java_generator.h b/protobuf/src/google/protobuf/compiler/java/java_generator.h
new file mode 100644
index 0000000..47f76be
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_generator.h
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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,
+                GeneratorContext* context,
+                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/protobuf/src/google/protobuf/compiler/java/java_generator_factory.cc b/protobuf/src/google/protobuf/compiler/java/java_generator_factory.cc
new file mode 100644
index 0000000..2d1437f
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_generator_factory.cc
@@ -0,0 +1,77 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+#include <google/protobuf/compiler/java/java_generator_factory.h>
+
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_enum_field.h>
+#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_field.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_message.h>
+#include <google/protobuf/compiler/java/java_service.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+GeneratorFactory::GeneratorFactory() {}
+GeneratorFactory::~GeneratorFactory() {}
+
+// ===================================================================
+
+ImmutableGeneratorFactory::ImmutableGeneratorFactory(
+    Context* context) : context_(context) {
+}
+ImmutableGeneratorFactory::~ImmutableGeneratorFactory() {}
+
+MessageGenerator* ImmutableGeneratorFactory::NewMessageGenerator(
+    const Descriptor* descriptor) const {
+  return new ImmutableMessageGenerator(descriptor, context_);
+}
+
+ExtensionGenerator* ImmutableGeneratorFactory::NewExtensionGenerator(
+    const FieldDescriptor* descriptor) const {
+  return new ImmutableExtensionGenerator(descriptor, context_);
+}
+
+ServiceGenerator* ImmutableGeneratorFactory::NewServiceGenerator(
+    const ServiceDescriptor* descriptor) const {
+  return new ImmutableServiceGenerator(descriptor, context_);
+}
+
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_generator_factory.h b/protobuf/src/google/protobuf/compiler/java/java_generator_factory.h
new file mode 100644
index 0000000..55365a9
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_generator_factory.h
@@ -0,0 +1,101 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+  class FieldDescriptor;         // descriptor.h
+  class Descriptor;              // descriptor.h
+  class ServiceDescriptor;       // descriptor.h
+  namespace compiler {
+    namespace java {
+      class MessageGenerator;    // message.h
+      class ExtensionGenerator;  // extension.h
+      class ServiceGenerator;    // service.h
+      class Context;             // context.h
+    }
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class GeneratorFactory {
+ public:
+  GeneratorFactory();
+  virtual ~GeneratorFactory();
+
+  virtual MessageGenerator* NewMessageGenerator(
+      const Descriptor* descriptor) const = 0;
+
+  virtual ExtensionGenerator* NewExtensionGenerator(
+      const FieldDescriptor* descriptor) const = 0;
+
+  virtual ServiceGenerator* NewServiceGenerator(
+      const ServiceDescriptor* descriptor) const = 0;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorFactory);
+};
+
+// Factory that creates generators for immutable-default messages.
+class ImmutableGeneratorFactory : public GeneratorFactory {
+ public:
+  ImmutableGeneratorFactory(Context* context);
+  virtual ~ImmutableGeneratorFactory();
+
+  virtual MessageGenerator* NewMessageGenerator(
+      const Descriptor* descriptor) const;
+
+  virtual ExtensionGenerator* NewExtensionGenerator(
+      const FieldDescriptor* descriptor) const;
+
+  virtual ServiceGenerator* NewServiceGenerator(
+      const ServiceDescriptor* descriptor) const;
+
+ private:
+  Context* context_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableGeneratorFactory);
+};
+
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_helpers.cc b/protobuf/src/google/protobuf/compiler/java/java_helpers.cc
new file mode 100644
index 0000000..3efd7ed
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_helpers.cc
@@ -0,0 +1,737 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <limits>
+#include <vector>
+
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+const char kThickSeparator[] =
+  "// ===================================================================\n";
+const char kThinSeparator[] =
+  "// -------------------------------------------------------------------\n";
+
+namespace {
+
+const char* kDefaultPackage = "";
+
+// Names that should be avoided as field names.
+// Using them will cause the compiler to generate accessors whose names are
+// colliding with methods defined in base classes.
+const char* kForbiddenWordList[] = {
+  // message base class:
+  "cached_size", "serialized_size",
+  // java.lang.Object:
+  "class",
+};
+
+bool IsForbidden(const string& field_name) {
+  for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) {
+    if (field_name == kForbiddenWordList[i]) {
+      return true;
+    }
+  }
+  return false;
+}
+
+string FieldName(const FieldDescriptor* field) {
+  string field_name;
+  // 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 (GetType(field) == FieldDescriptor::TYPE_GROUP) {
+    field_name = field->message_type()->name();
+  } else {
+    field_name = field->name();
+  }
+  if (IsForbidden(field_name)) {
+    // Append a trailing "#" to indicate that the name should be decorated to
+    // avoid collision with other names.
+    field_name += "#";
+  }
+  return field_name;
+}
+
+
+}  // namespace
+
+string UnderscoresToCamelCase(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;
+    }
+  }
+  // Add a trailing "_" if the name should be altered.
+  if (input[input.size() - 1] == '#') {
+    result += '_';
+  }
+  return result;
+}
+
+string UnderscoresToCamelCase(const FieldDescriptor* field) {
+  return UnderscoresToCamelCase(FieldName(field), false);
+}
+
+string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) {
+  return UnderscoresToCamelCase(FieldName(field), true);
+}
+
+string UnderscoresToCamelCase(const MethodDescriptor* method) {
+  return UnderscoresToCamelCase(method->name(), false);
+}
+
+string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
+  return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
+}
+
+string StripProto(const string& filename) {
+  if (HasSuffixString(filename, ".protodevel")) {
+    return StripSuffixString(filename, ".protodevel");
+  } else {
+    return StripSuffixString(filename, ".proto");
+  }
+}
+
+string FileClassName(const FileDescriptor* file, bool immutable) {
+  ClassNameResolver name_resolver;
+  return name_resolver.GetFileClassName(file, immutable);
+}
+
+string FileJavaPackage(const FileDescriptor* file, bool immutable) {
+  string result;
+
+  if (file->options().has_java_package()) {
+    result = file->options().java_package();
+  } else {
+    result = kDefaultPackage;
+    if (!file->package().empty()) {
+      if (!result.empty()) result += '.';
+      result += file->package();
+    }
+  }
+
+  return result;
+}
+
+string JavaPackageToDir(string package_name) {
+  string package_dir =
+    StringReplace(package_name, ".", "/", true);
+  if (!package_dir.empty()) package_dir += "/";
+  return package_dir;
+}
+
+// TODO(xiaofeng): This function is only kept for it's publicly referenced.
+// It should be removed after mutable API up-integration.
+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 Descriptor* descriptor) {
+  ClassNameResolver name_resolver;
+  return name_resolver.GetClassName(descriptor, true);
+}
+
+string ClassName(const EnumDescriptor* descriptor) {
+  ClassNameResolver name_resolver;
+  return name_resolver.GetClassName(descriptor, true);
+}
+
+string ClassName(const ServiceDescriptor* descriptor) {
+  ClassNameResolver name_resolver;
+  return name_resolver.GetClassName(descriptor, true);
+}
+
+string ClassName(const FileDescriptor* descriptor) {
+  ClassNameResolver name_resolver;
+  return name_resolver.GetClassName(descriptor, true);
+}
+
+string ExtraMessageInterfaces(const Descriptor* descriptor) {
+  string interfaces = "// @@protoc_insertion_point(message_implements:"
+      + descriptor->full_name() + ")";
+  return interfaces;
+}
+
+
+string ExtraBuilderInterfaces(const Descriptor* descriptor) {
+  string interfaces = "// @@protoc_insertion_point(builder_implements:"
+      + descriptor->full_name() + ")";
+  return interfaces;
+}
+
+string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) {
+  string interfaces = "// @@protoc_insertion_point(interface_extends:"
+      + descriptor->full_name() + ")";
+  return interfaces;
+}
+
+string FieldConstantName(const FieldDescriptor *field) {
+  string name = field->name() + "_FIELD_NUMBER";
+  UpperString(&name);
+  return name;
+}
+
+FieldDescriptor::Type GetType(const FieldDescriptor* field) {
+  return field->type();
+}
+
+JavaType GetJavaType(const FieldDescriptor* field) {
+  switch (GetType(field)) {
+    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;
+}
+
+const char* FieldTypeName(FieldDescriptor::Type field_type) {
+  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 AllAscii(const string& text) {
+  for (int i = 0; i < text.size(); i++) {
+    if ((text[i] & 0x80) != 0) {
+      return false;
+    }
+  }
+  return true;
+}
+
+string DefaultValue(const FieldDescriptor* field, bool immutable,
+                    ClassNameResolver* name_resolver) {
+  // Switch on CppType 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: {
+      double value = field->default_value_double();
+      if (value == numeric_limits<double>::infinity()) {
+        return "Double.POSITIVE_INFINITY";
+      } else if (value == -numeric_limits<double>::infinity()) {
+        return "Double.NEGATIVE_INFINITY";
+      } else if (value != value) {
+        return "Double.NaN";
+      } else {
+        return SimpleDtoa(value) + "D";
+      }
+    }
+    case FieldDescriptor::CPPTYPE_FLOAT: {
+      float value = field->default_value_float();
+      if (value == numeric_limits<float>::infinity()) {
+        return "Float.POSITIVE_INFINITY";
+      } else if (value == -numeric_limits<float>::infinity()) {
+        return "Float.NEGATIVE_INFINITY";
+      } else if (value != value) {
+        return "Float.NaN";
+      } else {
+        return SimpleFtoa(value) + "F";
+      }
+    }
+    case FieldDescriptor::CPPTYPE_BOOL:
+      return field->default_value_bool() ? "true" : "false";
+    case FieldDescriptor::CPPTYPE_STRING:
+      if (GetType(field) == FieldDescriptor::TYPE_BYTES) {
+        if (field->has_default_value()) {
+          // See comments in Internal.java for gory details.
+          return strings::Substitute(
+            "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")",
+            CEscape(field->default_value_string()));
+        } else {
+          return "com.google.protobuf.ByteString.EMPTY";
+        }
+      } else {
+        if (AllAscii(field->default_value_string())) {
+          // All chars are ASCII.  In this case CEscape() works fine.
+          return "\"" + CEscape(field->default_value_string()) + "\"";
+        } else {
+          // See comments in Internal.java for gory details.
+          return strings::Substitute(
+              "com.google.protobuf.Internal.stringDefaultValue(\"$0\")",
+              CEscape(field->default_value_string()));
+        }
+      }
+
+    case FieldDescriptor::CPPTYPE_ENUM:
+      return name_resolver->GetClassName(field->enum_type(), immutable) + "." +
+          field->default_value_enum()->name();
+
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      return name_resolver->GetClassName(field->message_type(), immutable) +
+          ".getDefaultInstance()";
+
+    // No default because we want the compiler to complain if any new
+    // types are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return "";
+}
+
+bool IsDefaultValueJavaDefault(const FieldDescriptor* field) {
+  // Switch on CppType since we need to know which default_value_* method
+  // of FieldDescriptor to call.
+  switch (field->cpp_type()) {
+    case FieldDescriptor::CPPTYPE_INT32:
+      return field->default_value_int32() == 0;
+    case FieldDescriptor::CPPTYPE_UINT32:
+      return field->default_value_uint32() == 0;
+    case FieldDescriptor::CPPTYPE_INT64:
+      return field->default_value_int64() == 0L;
+    case FieldDescriptor::CPPTYPE_UINT64:
+      return field->default_value_uint64() == 0L;
+    case FieldDescriptor::CPPTYPE_DOUBLE:
+      return field->default_value_double() == 0.0;
+    case FieldDescriptor::CPPTYPE_FLOAT:
+      return field->default_value_float() == 0.0;
+    case FieldDescriptor::CPPTYPE_BOOL:
+      return field->default_value_bool() == false;
+
+    case FieldDescriptor::CPPTYPE_STRING:
+    case FieldDescriptor::CPPTYPE_ENUM:
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      return false;
+
+    // No default because we want the compiler to complain if any new
+    // types are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return false;
+}
+
+const char* bit_masks[] = {
+  "0x00000001",
+  "0x00000002",
+  "0x00000004",
+  "0x00000008",
+  "0x00000010",
+  "0x00000020",
+  "0x00000040",
+  "0x00000080",
+
+  "0x00000100",
+  "0x00000200",
+  "0x00000400",
+  "0x00000800",
+  "0x00001000",
+  "0x00002000",
+  "0x00004000",
+  "0x00008000",
+
+  "0x00010000",
+  "0x00020000",
+  "0x00040000",
+  "0x00080000",
+  "0x00100000",
+  "0x00200000",
+  "0x00400000",
+  "0x00800000",
+
+  "0x01000000",
+  "0x02000000",
+  "0x04000000",
+  "0x08000000",
+  "0x10000000",
+  "0x20000000",
+  "0x40000000",
+  "0x80000000",
+};
+
+string GetBitFieldName(int index) {
+  string varName = "bitField";
+  varName += SimpleItoa(index);
+  varName += "_";
+  return varName;
+}
+
+string GetBitFieldNameForBit(int bitIndex) {
+  return GetBitFieldName(bitIndex / 32);
+}
+
+namespace {
+
+string GenerateGetBitInternal(const string& prefix, int bitIndex) {
+  string varName = prefix + GetBitFieldNameForBit(bitIndex);
+  int bitInVarIndex = bitIndex % 32;
+
+  string mask = bit_masks[bitInVarIndex];
+  string result = "((" + varName + " & " + mask + ") == " + mask + ")";
+  return result;
+}
+
+string GenerateSetBitInternal(const string& prefix, int bitIndex) {
+  string varName = prefix + GetBitFieldNameForBit(bitIndex);
+  int bitInVarIndex = bitIndex % 32;
+
+  string mask = bit_masks[bitInVarIndex];
+  string result = varName + " |= " + mask;
+  return result;
+}
+
+}  // namespace
+
+string GenerateGetBit(int bitIndex) {
+  return GenerateGetBitInternal("", bitIndex);
+}
+
+string GenerateSetBit(int bitIndex) {
+  return GenerateSetBitInternal("", bitIndex);
+}
+
+string GenerateClearBit(int bitIndex) {
+  string varName = GetBitFieldNameForBit(bitIndex);
+  int bitInVarIndex = bitIndex % 32;
+
+  string mask = bit_masks[bitInVarIndex];
+  string result = varName + " = (" + varName + " & ~" + mask + ")";
+  return result;
+}
+
+string GenerateGetBitFromLocal(int bitIndex) {
+  return GenerateGetBitInternal("from_", bitIndex);
+}
+
+string GenerateSetBitToLocal(int bitIndex) {
+  return GenerateSetBitInternal("to_", bitIndex);
+}
+
+string GenerateGetBitMutableLocal(int bitIndex) {
+  return GenerateGetBitInternal("mutable_", bitIndex);
+}
+
+string GenerateSetBitMutableLocal(int bitIndex) {
+  return GenerateSetBitInternal("mutable_", bitIndex);
+}
+
+bool IsReferenceType(JavaType type) {
+  switch (type) {
+    case JAVATYPE_INT    : return false;
+    case JAVATYPE_LONG   : return false;
+    case JAVATYPE_FLOAT  : return false;
+    case JAVATYPE_DOUBLE : return false;
+    case JAVATYPE_BOOLEAN: return false;
+    case JAVATYPE_STRING : return true;
+    case JAVATYPE_BYTES  : return true;
+    case JAVATYPE_ENUM   : return true;
+    case JAVATYPE_MESSAGE: return true;
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return false;
+}
+
+const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) {
+  switch (GetType(field)) {
+    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;
+}
+
+// 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 WireFormatLite::kFixed32Size;
+    case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
+    case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
+    case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
+    case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
+    case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
+
+    case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::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;
+}
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it. The caller should delete the returned array.
+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;
+}
+
+// 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).
+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 (GetJavaType(field) == JAVATYPE_MESSAGE) {
+      if (HasRequiredFields(field->message_type(), already_seen)) {
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+bool HasRequiredFields(const Descriptor* type) {
+  hash_set<const Descriptor*> already_seen;
+  return HasRequiredFields(type, &already_seen);
+}
+
+bool HasRepeatedFields(const Descriptor* descriptor) {
+  for (int i = 0; i < descriptor->field_count(); ++i) {
+    const FieldDescriptor* field = descriptor->field(i);
+    if (field->is_repeated()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_helpers.h b/protobuf/src/google/protobuf/compiler/java/java_helpers.h
new file mode 100644
index 0000000..93f23a9
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_helpers.h
@@ -0,0 +1,322 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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.pb.h>
+#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 a name to camel-case. If cap_first_letter is true, capitalize the
+// first letter.
+string UnderscoresToCamelCase(const string& name, bool cap_first_letter);
+// 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);
+
+// 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);
+
+// Strips ".proto" or ".protodevel" from the end of a filename.
+string StripProto(const string& filename);
+
+// Gets the unqualified class name for the file.  For each .proto file, there
+// will be one Java class containing all the immutable messages and another
+// Java class containing all the mutable messages.
+// TODO(xiaofeng): remove the default value after updating client code.
+string FileClassName(const FileDescriptor* file, bool immutable = true);
+
+// Returns the file's Java package name.
+string FileJavaPackage(const FileDescriptor* file, bool immutable = true);
+
+// Returns output directory for the given package name.
+string JavaPackageToDir(string package_name);
+
+// 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.
+// TODO(xiaofeng): this method is deprecated and should be removed in the
+// future.
+string ToJavaName(const string& full_name,
+                  const FileDescriptor* file);
+
+// TODO(xiaofeng): the following methods are kept for they are exposed
+// publicly in //google/protobuf/compiler/java/names.h. They return
+// immutable names only and should be removed after mutable API is
+// integrated into google3.
+string ClassName(const Descriptor* descriptor);
+string ClassName(const EnumDescriptor* descriptor);
+string ClassName(const ServiceDescriptor* descriptor);
+string ClassName(const FileDescriptor* descriptor);
+
+// Comma-separate list of option-specified interfaces implemented by the
+// Message, to follow the "implements" declaration of the Message definition.
+string ExtraMessageInterfaces(const Descriptor* descriptor);
+// Comma-separate list of option-specified interfaces implemented by the
+// MutableMessage, to follow the "implements" declaration of the MutableMessage
+// definition.
+string ExtraMutableMessageInterfaces(const Descriptor* descriptor);
+// Comma-separate list of option-specified interfaces implemented by the
+// Builder, to follow the "implements" declaration of the Builder definition.
+string ExtraBuilderInterfaces(const Descriptor* descriptor);
+// Comma-separate list of option-specified interfaces extended by the
+// MessageOrBuilder, to follow the "extends" declaration of the
+// MessageOrBuilder definition.
+string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor);
+
+// Get the unqualified Java class name for mutable messages. i.e. without
+// package or outer classnames.
+inline string ShortMutableJavaClassName(const Descriptor* descriptor) {
+  return descriptor->name();
+}
+
+
+// Whether we should generate multiple java files for messages.
+inline bool MultipleJavaFiles(
+    const FileDescriptor* descriptor, bool immutable) {
+  return descriptor->options().java_multiple_files();
+}
+
+// Get the unqualified name that should be used for a field's field
+// number constant.
+string FieldConstantName(const FieldDescriptor *field);
+
+// Returns the type of the FieldDescriptor.
+// This does nothing interesting for the open source release, but is used for
+// hacks that improve compatability with version 1 protocol buffers at Google.
+FieldDescriptor::Type GetType(const FieldDescriptor* field);
+
+enum JavaType {
+  JAVATYPE_INT,
+  JAVATYPE_LONG,
+  JAVATYPE_FLOAT,
+  JAVATYPE_DOUBLE,
+  JAVATYPE_BOOLEAN,
+  JAVATYPE_STRING,
+  JAVATYPE_BYTES,
+  JAVATYPE_ENUM,
+  JAVATYPE_MESSAGE
+};
+
+JavaType GetJavaType(const FieldDescriptor* field);
+
+// 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);
+
+// Get the name of the java enum constant representing this type. E.g.,
+// "INT32" for FieldDescriptor::TYPE_INT32. The enum constant's full
+// name is "com.google.protobuf.WireFormat.FieldType.INT32".
+const char* FieldTypeName(const FieldDescriptor::Type field_type);
+
+class ClassNameResolver;
+string DefaultValue(const FieldDescriptor* field, bool immutable,
+                    ClassNameResolver* name_resolver);
+inline string ImmutableDefaultValue(const FieldDescriptor* field,
+                                    ClassNameResolver* name_resolver) {
+  return DefaultValue(field, true, name_resolver);
+}
+bool IsDefaultValueJavaDefault(const FieldDescriptor* field);
+
+// Does this message class use UnknownFieldSet?
+// Otherwise, unknown fields will be stored in a ByteString object
+inline bool UseUnknownFieldSet(const Descriptor* descriptor) {
+  return descriptor->file()->options().optimize_for() !=
+           FileOptions::LITE_RUNTIME;
+}
+
+// Does this message class have generated parsing, serialization, and other
+// standard methods for which reflection-based fallback implementations exist?
+inline bool HasGeneratedMethods(const Descriptor* descriptor) {
+  return descriptor->file()->options().optimize_for() !=
+           FileOptions::CODE_SIZE;
+}
+
+// Does this message have specialized equals() and hashCode() methods?
+inline bool HasEqualsAndHashCode(const Descriptor* descriptor) {
+  return descriptor->file()->options().java_generate_equals_and_hash();
+}
+
+// Does this message class have descriptor and reflection methods?
+inline bool HasDescriptorMethods(const Descriptor* descriptor) {
+  return descriptor->file()->options().optimize_for() !=
+           FileOptions::LITE_RUNTIME;
+}
+inline bool HasDescriptorMethods(const EnumDescriptor* descriptor) {
+  return descriptor->file()->options().optimize_for() !=
+           FileOptions::LITE_RUNTIME;
+}
+inline bool HasDescriptorMethods(const FileDescriptor* descriptor) {
+  return descriptor->options().optimize_for() !=
+           FileOptions::LITE_RUNTIME;
+}
+
+inline bool HasNestedBuilders(const Descriptor* descriptor) {
+  // The proto-lite version doesn't support nested builders.
+  return descriptor->file()->options().optimize_for() !=
+           FileOptions::LITE_RUNTIME;
+}
+
+// Should we generate generic services for this file?
+inline bool HasGenericServices(const FileDescriptor *file) {
+  return file->service_count() > 0 &&
+         file->options().optimize_for() != FileOptions::LITE_RUNTIME &&
+         file->options().java_generic_services();
+}
+
+inline bool IsLazy(const FieldDescriptor* descriptor) {
+  // Currently, the proto-lite version suports lazy field.
+  // TODO(niwasaki): Support lazy fields also for other proto runtimes.
+  if (descriptor->file()->options().optimize_for() !=
+      FileOptions::LITE_RUNTIME) {
+    return false;
+  }
+  return descriptor->options().lazy();
+}
+
+// Methods for shared bitfields.
+
+// Gets the name of the shared bitfield for the given index.
+string GetBitFieldName(int index);
+
+// Gets the name of the shared bitfield for the given bit index.
+// Effectively, GetBitFieldName(bitIndex / 32)
+string GetBitFieldNameForBit(int bitIndex);
+
+// Generates the java code for the expression that returns the boolean value
+// of the bit of the shared bitfields for the given bit index.
+// Example: "((bitField1_ & 0x04) == 0x04)"
+string GenerateGetBit(int bitIndex);
+
+// Generates the java code for the expression that sets the bit of the shared
+// bitfields for the given bit index.
+// Example: "bitField1_ = (bitField1_ | 0x04)"
+string GenerateSetBit(int bitIndex);
+
+// Generates the java code for the expression that clears the bit of the shared
+// bitfields for the given bit index.
+// Example: "bitField1_ = (bitField1_ & ~0x04)"
+string GenerateClearBit(int bitIndex);
+
+// Does the same as GenerateGetBit but operates on the bit field on a local
+// variable. This is used by the builder to copy the value in the builder to
+// the message.
+// Example: "((from_bitField1_ & 0x04) == 0x04)"
+string GenerateGetBitFromLocal(int bitIndex);
+
+// Does the same as GenerateSetBit but operates on the bit field on a local
+// variable. This is used by the builder to copy the value in the builder to
+// the message.
+// Example: "to_bitField1_ = (to_bitField1_ | 0x04)"
+string GenerateSetBitToLocal(int bitIndex);
+
+// Does the same as GenerateGetBit but operates on the bit field on a local
+// variable. This is used by the parsing constructor to record if a repeated
+// field is mutable.
+// Example: "((mutable_bitField1_ & 0x04) == 0x04)"
+string GenerateGetBitMutableLocal(int bitIndex);
+
+// Does the same as GenerateSetBit but operates on the bit field on a local
+// variable. This is used by the parsing constructor to record if a repeated
+// field is mutable.
+// Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)"
+string GenerateSetBitMutableLocal(int bitIndex);
+
+// Returns whether the JavaType is a reference type.
+bool IsReferenceType(JavaType type);
+
+// Returns the capitalized name for calling relative functions in
+// CodedInputStream
+const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable);
+
+// For encodings with fixed sizes, returns that size in bytes.  Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type);
+
+// Comparators used to sort fields in MessageGenerator
+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. The caller should delete the returned array.
+const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor);
+
+// Check a message type and its sub-message types recursively to see if any of
+// them has a required field. Return true if a required field is found.
+bool HasRequiredFields(const Descriptor* descriptor);
+
+// Whether a .proto file supports field presence test for non-message types.
+inline bool SupportFieldPresence(const FileDescriptor* descriptor) {
+  return true;
+}
+
+// Check whether a mesasge has repeated fields.
+bool HasRepeatedFields(const Descriptor* descriptor);
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_lazy_message_field.cc b/protobuf/src/google/protobuf/compiler/java/java_lazy_message_field.cc
new file mode 100644
index 0000000..21cab7d
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_lazy_message_field.cc
@@ -0,0 +1,826 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: niwasaki@google.com (Naoki Iwasaki)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_lazy_message_field.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+ImmutableLazyMessageFieldGenerator::
+ImmutableLazyMessageFieldGenerator(
+    const FieldDescriptor* descriptor,
+    int messageBitIndex,
+    int builderBitIndex,
+    Context* context)
+    : ImmutableMessageFieldGenerator(
+          descriptor, messageBitIndex, builderBitIndex, context) {
+}
+
+ImmutableLazyMessageFieldGenerator::~ImmutableLazyMessageFieldGenerator() {}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private com.google.protobuf.LazyFieldLite $name$_ =\n"
+    "    new com.google.protobuf.LazyFieldLite();\n");
+
+  PrintExtraFieldInfo(variables_, printer);
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public boolean has$capitalized_name$() {\n"
+    "  return $get_has_field_bit_message$;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  return ($type$) $name$_.getValue($type$.getDefaultInstance());\n"
+   "}\n");
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+      "  return $name$_;\n"
+      "}\n");
+  }
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  // When using nested-builders, the code initially works just like the
+  // non-nested builder case. It only creates a nested builder lazily on
+  // demand and then forever delegates to it after creation.
+
+  printer->Print(variables_,
+    "private com.google.protobuf.LazyFieldLite $name$_ =\n"
+    "    new com.google.protobuf.LazyFieldLite();\n");
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      // If this builder is non-null, it is used and the other fields are
+      // ignored.
+      "private com.google.protobuf.SingleFieldBuilder<\n"
+      "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
+      "\n");
+  }
+
+  // The comments above the methods below are based on a hypothetical
+  // field of type "Field" called "Field".
+
+  // boolean hasField()
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public boolean has$capitalized_name$() {\n"
+    "  return $get_has_field_bit_builder$;\n"
+    "}\n");
+
+    printer->Print(variables_,
+      "$deprecation$public $type$ get$capitalized_name$() {\n"
+      "  return ($type$) $name$_.getValue($type$.getDefaultInstance());\n"
+      "}\n");
+
+  // Field.Builder setField(Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$($type$ value)",
+
+    "if (value == null) {\n"
+    "  throw new NullPointerException();\n"
+    "}\n"
+    "$name$_.setValue(value);\n"
+    "$on_changed$\n",
+
+     NULL,  // Lazy fields are supported only for lite-runtime.
+
+    "$set_has_field_bit_builder$;\n"
+    "return this;\n");
+
+  // Field.Builder setField(Field.Builder builderForValue)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    $type$.Builder builderForValue)",
+
+    "$name$_.setValue(builderForValue.build());\n"
+    "$on_changed$\n",
+
+    NULL,
+
+    "$set_has_field_bit_builder$;\n"
+    "return this;\n");
+
+  // Field.Builder mergeField(Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder merge$capitalized_name$($type$ value)",
+
+    "if ($get_has_field_bit_builder$ &&\n"
+    "    !$name$_.containsDefaultInstance()) {\n"
+    "  $name$_.setValue(\n"
+    "    $type$.newBuilder(\n"
+    "        get$capitalized_name$()).mergeFrom(value).buildPartial());\n"
+    "} else {\n"
+    "  $name$_.setValue(value);\n"
+    "}\n"
+    "$on_changed$\n",
+
+    NULL,
+
+    "$set_has_field_bit_builder$;\n"
+    "return this;\n");
+
+  // Field.Builder clearField()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder clear$capitalized_name$()",
+
+    "$name$_.clear();\n"
+    "$on_changed$\n",
+
+    NULL,
+
+    "$clear_has_field_bit_builder$;\n"
+    "return this;\n");
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
+      "  $set_has_field_bit_builder$;\n"
+      "  $on_changed$\n"
+      "  return get$capitalized_name$FieldBuilder().getBuilder();\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+      "  if ($name$Builder_ != null) {\n"
+      "    return $name$Builder_.getMessageOrBuilder();\n"
+      "  } else {\n"
+      "    return $name$_;\n"
+      "  }\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "private com.google.protobuf.SingleFieldBuilder<\n"
+      "    $type$, $type$.Builder, $type$OrBuilder> \n"
+      "    get$capitalized_name$FieldBuilder() {\n"
+      "  if ($name$Builder_ == null) {\n"
+      "    $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
+      "        $type$, $type$.Builder, $type$OrBuilder>(\n"
+      "            $name$_,\n"
+      "            getParentForChildren(),\n"
+      "            isClean());\n"
+      "    $name$_ = null;\n"
+      "  }\n"
+      "  return $name$Builder_;\n"
+      "}\n");
+  }
+}
+
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.clear();\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_.clear();\n");
+  printer->Print(variables_, "$clear_has_field_bit_builder$;\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (other.has$capitalized_name$()) {\n"
+    "  $name$_.merge(other.$name$_);\n"
+    "  $set_has_field_bit_builder$;\n"
+    "}\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+      "if ($get_has_field_bit_from_local$) {\n"
+      "  $set_has_field_bit_to_local$;\n"
+      "}\n");
+
+  printer->Print(variables_,
+      "result.$name$_.setByteString(\n"
+      "    $name$_.toByteString(),\n"
+      "    $name$_.getExtensionRegistry());\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$_.setByteString(input.readBytes(), extensionRegistry);\n");
+  printer->Print(variables_,
+    "$set_has_field_bit_message$;\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  // Do not de-serialize lazy fields.
+  printer->Print(variables_,
+    "if ($get_has_field_bit_message$) {\n"
+    "  output.writeBytes($number$, $name$_.toByteString());\n"
+    "}\n");
+}
+
+void ImmutableLazyMessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($get_has_field_bit_message$) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .computeLazyFieldSize($number$, $name$_);\n"
+    "}\n");
+}
+
+// ===================================================================
+
+ImmutableLazyMessageOneofFieldGenerator::
+ImmutableLazyMessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                        int messageBitIndex,
+                                        int builderBitIndex,
+                                        Context* context)
+    : ImmutableLazyMessageFieldGenerator(
+          descriptor, messageBitIndex, builderBitIndex, context) {
+  const OneofGeneratorInfo* info =
+      context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+  SetCommonOneofVariables(descriptor, info, &variables_);
+  variables_["lazy_type"] = "com.google.protobuf.LazyFieldLite";
+}
+
+ImmutableLazyMessageOneofFieldGenerator::
+~ImmutableLazyMessageOneofFieldGenerator() {}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  PrintExtraFieldInfo(variables_, printer);
+  WriteFieldDocComment(printer, descriptor_);
+
+  printer->Print(variables_,
+    "$deprecation$public boolean has$capitalized_name$() {\n"
+    "  return $has_oneof_case_message$;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n"
+    "        $type$.getDefaultInstance());\n"
+    "  }\n"
+    "  return $type$.getDefaultInstance();\n"
+    "}\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  // boolean hasField()
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public boolean has$capitalized_name$() {\n"
+    "  return $has_oneof_case_message$;\n"
+    "}\n");
+
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n"
+    "        $type$.getDefaultInstance());\n"
+    "  }\n"
+    "  return $type$.getDefaultInstance();\n"
+    "}\n");
+
+  // Field.Builder setField(Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$($type$ value)",
+
+    "if (value == null) {\n"
+    "  throw new NullPointerException();\n"
+    "}\n"
+    "if (!($has_oneof_case_message$)) {\n"
+    "  $oneof_name$_ = new $lazy_type$();\n"
+    "  $set_oneof_case_message$;\n"
+    "}\n"
+    "(($lazy_type$) $oneof_name$_).setValue(value);\n"
+    "$on_changed$\n",
+
+     NULL,  // Lazy fields are supported only for lite-runtime.
+
+    "return this;\n");
+
+  // Field.Builder setField(Field.Builder builderForValue)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    $type$.Builder builderForValue)",
+
+    "if (!($has_oneof_case_message$)) {\n"
+    "  $oneof_name$_ = new $lazy_type$();\n"
+    "  $set_oneof_case_message$;\n"
+    "}\n"
+    "(($lazy_type$) $oneof_name$_).setValue(builderForValue.build());\n"
+    "$on_changed$\n",
+
+    NULL,
+
+    "return this;\n");
+
+  // Field.Builder mergeField(Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder merge$capitalized_name$($type$ value)",
+
+    "if ($has_oneof_case_message$ &&\n"
+    "    !(($lazy_type$) $oneof_name$_).containsDefaultInstance()) {\n"
+    "  (($lazy_type$) $oneof_name$_).setValue(\n"
+    "    $type$.newBuilder(\n"
+    "        get$capitalized_name$()).mergeFrom(value).buildPartial());\n"
+    "} else {\n"
+    "  if (!($has_oneof_case_message$)) {\n"
+    "    $oneof_name$_ = new $lazy_type$();\n"
+    "    $set_oneof_case_message$;\n"
+    "  }\n"
+    "  (($lazy_type$) $oneof_name$_).setValue(value);\n"
+    "}\n"
+    "$on_changed$\n",
+
+    NULL,
+
+    "return this;\n");
+
+  // Field.Builder clearField()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder clear$capitalized_name$()",
+
+    "if ($has_oneof_case_message$) {\n"
+    "  $clear_oneof_case_message$;\n"
+    "  $oneof_name$_ = null;\n"
+    "  $on_changed$\n"
+    "}\n",
+
+    NULL,
+
+    "return this;\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!($has_oneof_case_message$)) {\n"
+    "  $oneof_name$_ = new $lazy_type$();\n"
+    "}\n"
+    "(($lazy_type$) $oneof_name$_).merge(\n"
+    "    ($lazy_type$) other.$oneof_name$_);\n"
+    "$set_oneof_case_message$;\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+                 "if ($has_oneof_case_message$) {\n");
+  printer->Indent();
+
+  printer->Print(variables_,
+      "result.$oneof_name$_ = new $lazy_type$();\n"
+      "(($lazy_type$) result.$oneof_name$_).setByteString(\n"
+      "    (($lazy_type$) $oneof_name$_).toByteString(),\n"
+      "    (($lazy_type$) $oneof_name$_).getExtensionRegistry());\n");
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!($has_oneof_case_message$)) {\n"
+    "  $oneof_name$_ = new $lazy_type$();\n"
+    "}\n"
+    "(($lazy_type$) $oneof_name$_).setByteString(\n"
+    "    input.readBytes(), extensionRegistry);\n"
+    "$set_oneof_case_message$;\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  // Do not de-serialize lazy fields.
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  output.writeBytes(\n"
+    "      $number$, (($lazy_type$) $oneof_name$_).toByteString());\n"
+    "}\n");
+}
+
+void ImmutableLazyMessageOneofFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .computeLazyFieldSize($number$, ($lazy_type$) $oneof_name$_);\n"
+    "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutableLazyMessageFieldGenerator::
+RepeatedImmutableLazyMessageFieldGenerator(
+    const FieldDescriptor* descriptor,
+    int messageBitIndex,
+    int builderBitIndex,
+    Context* context)
+    : RepeatedImmutableMessageFieldGenerator(
+          descriptor, messageBitIndex, builderBitIndex, context) {
+}
+
+
+RepeatedImmutableLazyMessageFieldGenerator::
+~RepeatedImmutableLazyMessageFieldGenerator() {}
+
+void RepeatedImmutableLazyMessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private java.util.List<com.google.protobuf.LazyFieldLite> $name$_;\n");
+  PrintExtraFieldInfo(variables_, printer);
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.util.List<$type$>\n"
+    "    get$capitalized_name$List() {\n"
+    "  java.util.List<$type$> list =\n"
+    "      new java.util.ArrayList<$type$>($name$_.size());\n"
+    "  for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n"
+    "    list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n"
+    "  }\n"
+    "  return list;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.util.List<? extends $type$OrBuilder>\n"
+    "    get$capitalized_name$OrBuilderList() {\n"
+    "  return get$capitalized_name$List();\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public int get$capitalized_name$Count() {\n"
+    "  return $name$_.size();\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+    "  return ($type$)\n"
+    "      $name$_.get(index).getValue($type$.getDefaultInstance());\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+    "    int index) {\n"
+    "  return ($type$OrBuilder)\n"
+    "      $name$_.get(index).getValue($type$.getDefaultInstance());\n"
+    "}\n");
+}
+
+void RepeatedImmutableLazyMessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  // When using nested-builders, the code initially works just like the
+  // non-nested builder case. It only creates a nested builder lazily on
+  // demand and then forever delegates to it after creation.
+
+  printer->Print(variables_,
+    "private java.util.List<com.google.protobuf.LazyFieldLite> $name$_ =\n"
+    "  java.util.Collections.emptyList();\n"
+
+    "private void ensure$capitalized_name$IsMutable() {\n"
+    "  if (!$get_mutable_bit_builder$) {\n"
+    "    $name$_ =\n"
+    "        new java.util.ArrayList<com.google.protobuf.LazyFieldLite>(\n"
+    "            $name$_);\n"
+    "    $set_mutable_bit_builder$;\n"
+    "   }\n"
+    "}\n"
+    "\n");
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      // If this builder is non-null, it is used and the other fields are
+      // ignored.
+      "private com.google.protobuf.RepeatedFieldBuilder<\n"
+      "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
+      "\n");
+  }
+
+  // The comments above the methods below are based on a hypothetical
+  // repeated field of type "Field" called "RepeatedField".
+
+  // List<Field> getRepeatedFieldList()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public java.util.List<$type$> get$capitalized_name$List()",
+
+    "java.util.List<$type$> list =\n"
+    "    new java.util.ArrayList<$type$>($name$_.size());\n"
+    "for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n"
+    "  list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n"
+    "}\n"
+    "return java.util.Collections.unmodifiableList(list);\n",
+
+    "return $name$Builder_.getMessageList();\n",
+
+    NULL);
+
+  // int getRepeatedFieldCount()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public int get$capitalized_name$Count()",
+
+    "return $name$_.size();\n",
+    "return $name$Builder_.getCount();\n",
+
+    NULL);
+
+  // Field getRepeatedField(int index)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public $type$ get$capitalized_name$(int index)",
+
+    "return ($type$) $name$_.get(index).getValue(\n"
+    "    $type$.getDefaultInstance());\n",
+
+    "return $name$Builder_.getMessage(index);\n",
+
+    NULL);
+
+  // Builder setRepeatedField(int index, Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    int index, $type$ value)",
+    "if (value == null) {\n"
+    "  throw new NullPointerException();\n"
+    "}\n"
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(value));\n"
+    "$on_changed$\n",
+    "$name$Builder_.setMessage(index, value);\n",
+    "return this;\n");
+
+  // Builder setRepeatedField(int index, Field.Builder builderForValue)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    int index, $type$.Builder builderForValue)",
+
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(\n"
+    "    builderForValue.build()));\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.setMessage(index, builderForValue.build());\n",
+
+    "return this;\n");
+
+  // Builder addRepeatedField(Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder add$capitalized_name$($type$ value)",
+
+    "if (value == null) {\n"
+    "  throw new NullPointerException();\n"
+    "}\n"
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.add(com.google.protobuf.LazyFieldLite.fromValue(value));\n"
+
+    "$on_changed$\n",
+
+    "$name$Builder_.addMessage(value);\n",
+
+    "return this;\n");
+
+  // Builder addRepeatedField(int index, Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder add$capitalized_name$(\n"
+    "    int index, $type$ value)",
+
+    "if (value == null) {\n"
+    "  throw new NullPointerException();\n"
+    "}\n"
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(value));\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.addMessage(index, value);\n",
+
+    "return this;\n");
+
+  // Builder addRepeatedField(Field.Builder builderForValue)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder add$capitalized_name$(\n"
+    "    $type$.Builder builderForValue)",
+
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.add(com.google.protobuf.LazyFieldLite.fromValue(\n"
+    "    builderForValue.build()));\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.addMessage(builderForValue.build());\n",
+
+    "return this;\n");
+
+  // Builder addRepeatedField(int index, Field.Builder builderForValue)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder add$capitalized_name$(\n"
+    "    int index, $type$.Builder builderForValue)",
+
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(\n"
+    "    builderForValue.build()));\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.addMessage(index, builderForValue.build());\n",
+
+    "return this;\n");
+
+  // Builder addAllRepeatedField(Iterable<Field> values)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder addAll$capitalized_name$(\n"
+    "    java.lang.Iterable<? extends $type$> values)",
+
+    "ensure$capitalized_name$IsMutable();\n"
+    "for (com.google.protobuf.MessageLite v : values) {\n"
+    "  $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(v));\n"
+    "}\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.addAllMessages(values);\n",
+
+    "return this;\n");
+
+  // Builder clearAllRepeatedField()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder clear$capitalized_name$()",
+
+    "$name$_ = java.util.Collections.emptyList();\n"
+    "$clear_mutable_bit_builder$;\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.clear();\n",
+
+    "return this;\n");
+
+  // Builder removeRepeatedField(int index)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder remove$capitalized_name$(int index)",
+
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.remove(index);\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.remove(index);\n",
+
+    "return this;\n");
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n"
+      "    int index) {\n"
+      "  return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
+      "}\n");
+
+    WriteFieldDocComment(printer, descriptor_);
+        printer->Print(variables_,
+      "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+      "    int index) {\n"
+      "  if ($name$Builder_ == null) {\n"
+      "    return $name$_.get(index);"
+      "  } else {\n"
+      "    return $name$Builder_.getMessageOrBuilder(index);\n"
+      "  }\n"
+      "}\n");
+
+    WriteFieldDocComment(printer, descriptor_);
+        printer->Print(variables_,
+      "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+      "     get$capitalized_name$OrBuilderList() {\n"
+      "  if ($name$Builder_ != null) {\n"
+      "    return $name$Builder_.getMessageOrBuilderList();\n"
+      "  } else {\n"
+      "    return java.util.Collections.unmodifiableList($name$_);\n"
+      "  }\n"
+      "}\n");
+
+    WriteFieldDocComment(printer, descriptor_);
+        printer->Print(variables_,
+      "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n"
+      "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
+      "      $type$.getDefaultInstance());\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+        printer->Print(variables_,
+      "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n"
+      "    int index) {\n"
+      "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
+      "      index, $type$.getDefaultInstance());\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+        printer->Print(variables_,
+      "$deprecation$public java.util.List<$type$.Builder> \n"
+      "     get$capitalized_name$BuilderList() {\n"
+      "  return get$capitalized_name$FieldBuilder().getBuilderList();\n"
+      "}\n"
+      "private com.google.protobuf.RepeatedFieldBuilder<\n"
+      "    $type$, $type$.Builder, $type$OrBuilder> \n"
+      "    get$capitalized_name$FieldBuilder() {\n"
+      "  if ($name$Builder_ == null) {\n"
+      "    $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n"
+      "        $type$, $type$.Builder, $type$OrBuilder>(\n"
+      "            $name$_,\n"
+      "            $get_mutable_bit_builder$,\n"
+      "            getParentForChildren(),\n"
+      "            isClean());\n"
+      "    $name$_ = null;\n"
+      "  }\n"
+      "  return $name$Builder_;\n"
+      "}\n");
+  }
+}
+
+void RepeatedImmutableLazyMessageFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!$get_mutable_bit_parser$) {\n"
+    "  $name$_ =\n"
+    "      new java.util.ArrayList<com.google.protobuf.LazyFieldLite>();\n"
+    "  $set_mutable_bit_parser$;\n"
+    "}\n"
+    "$name$_.add(new com.google.protobuf.LazyFieldLite(\n"
+    "    extensionRegistry, input.readBytes()));\n");
+}
+
+void RepeatedImmutableLazyMessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for (int i = 0; i < $name$_.size(); i++) {\n"
+    "  output.writeBytes($number$, $name$_.get(i).toByteString());\n"
+    "}\n");
+}
+
+void RepeatedImmutableLazyMessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for (int i = 0; i < $name$_.size(); i++) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .computeLazyFieldSize($number$, $name$_.get(i));\n"
+    "}\n");
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_lazy_message_field.h b/protobuf/src/google/protobuf/compiler/java/java_lazy_message_field.h
new file mode 100644
index 0000000..b1b7f28
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_lazy_message_field.h
@@ -0,0 +1,121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: niwasaki@google.com (Naoki Iwasaki)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__
+
+#include <google/protobuf/compiler/java/java_field.h>
+#include <google/protobuf/compiler/java/java_message_field.h>
+
+namespace google {
+namespace protobuf {
+  namespace compiler {
+    namespace java {
+      class Context;  // context.h
+    }
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableLazyMessageFieldGenerator
+    : public ImmutableMessageFieldGenerator {
+ public:
+  explicit ImmutableLazyMessageFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~ImmutableLazyMessageFieldGenerator();
+
+  // overroads ImmutableMessageFieldGenerator ---------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateInitializationCode(io::Printer* printer) const;
+  void GenerateBuilderClearCode(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;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageFieldGenerator);
+};
+
+class ImmutableLazyMessageOneofFieldGenerator
+    : public ImmutableLazyMessageFieldGenerator {
+ public:
+  ImmutableLazyMessageOneofFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~ImmutableLazyMessageOneofFieldGenerator();
+
+  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;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageOneofFieldGenerator);
+};
+
+class RepeatedImmutableLazyMessageFieldGenerator
+    : public RepeatedImmutableMessageFieldGenerator {
+ public:
+  explicit RepeatedImmutableLazyMessageFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~RepeatedImmutableLazyMessageFieldGenerator();
+
+  // overroads RepeatedImmutableMessageFieldGenerator -------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableLazyMessageFieldGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_message.cc b/protobuf/src/google/protobuf/compiler/java/java_message.cc
new file mode 100644
index 0000000..8aa89ac
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_message.cc
@@ -0,0 +1,1666 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/java/java_message.h>
+
+#include <algorithm>
+#include <google/protobuf/stubs/hash.h>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_extension.h>
+#include <google/protobuf/compiler/java/java_generator_factory.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+bool GenerateHasBits(const Descriptor* descriptor) {
+  return SupportFieldPresence(descriptor->file()) ||
+      HasRepeatedFields(descriptor);
+}
+}  // namespace
+
+// ===================================================================
+
+MessageGenerator::MessageGenerator(const Descriptor* descriptor)
+  : descriptor_(descriptor) {}
+
+MessageGenerator::~MessageGenerator() {}
+
+// ===================================================================
+// TODO(api): Move this class to a separate immutable_message.cc file.
+ImmutableMessageGenerator::ImmutableMessageGenerator(
+    const Descriptor* descriptor, Context* context)
+  : MessageGenerator(descriptor), context_(context),
+    name_resolver_(context->GetNameResolver()),
+    field_generators_(descriptor, context_) {
+}
+
+ImmutableMessageGenerator::~ImmutableMessageGenerator() {}
+
+void ImmutableMessageGenerator::GenerateStaticVariables(io::Printer* printer) {
+  if (HasDescriptorMethods(descriptor_)) {
+    // 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"] = name_resolver_->GetImmutableClassName(descriptor_);
+    if (descriptor_->containing_type() != NULL) {
+      vars["parent"] = UniqueFileScopeIdentifier(
+          descriptor_->containing_type());
+    }
+    if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
+      // 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.
+    printer->Print(vars,
+      "$private$static final com.google.protobuf.Descriptors.Descriptor\n"
+      "  internal_$identifier$_descriptor;\n");
+
+    // And the FieldAccessorTable.
+    GenerateFieldAccessorTable(printer);
+  }
+
+  // Generate static members for all nested types.
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    // TODO(kenton):  Reuse MessageGenerator objects?
+    ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
+      .GenerateStaticVariables(printer);
+  }
+}
+
+void ImmutableMessageGenerator::GenerateStaticVariableInitializers(
+    io::Printer* printer) {
+  if (HasDescriptorMethods(descriptor_)) {
+    map<string, string> vars;
+    vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+    vars["index"] = SimpleItoa(descriptor_->index());
+    vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
+    if (descriptor_->containing_type() != NULL) {
+      vars["parent"] = UniqueFileScopeIdentifier(
+          descriptor_->containing_type());
+    }
+
+    // The descriptor for this type.
+    if (descriptor_->containing_type() == NULL) {
+      printer->Print(vars,
+        "internal_$identifier$_descriptor =\n"
+        "  getDescriptor().getMessageTypes().get($index$);\n");
+    } else {
+      printer->Print(vars,
+        "internal_$identifier$_descriptor =\n"
+        "  internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
+    }
+
+    // And the FieldAccessorTable.
+    GenerateFieldAccessorTableInitializer(printer);
+  }
+
+  // Generate static member initializers for all nested types.
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    // TODO(kenton):  Reuse MessageGenerator objects?
+    ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
+      .GenerateStaticVariableInitializers(printer);
+  }
+}
+
+void ImmutableMessageGenerator::
+GenerateFieldAccessorTable(io::Printer* printer) {
+  map<string, string> vars;
+  vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
+  if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) {
+    // We can only make these package-private since the classes that use them
+    // are in separate files.
+    vars["private"] = "";
+  } else {
+    vars["private"] = "private ";
+  }
+  printer->Print(vars,
+    "$private$static\n"
+    "  com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+    "    internal_$identifier$_fieldAccessorTable;\n");
+}
+
+void ImmutableMessageGenerator::
+GenerateFieldAccessorTableInitializer(io::Printer* printer) {
+  printer->Print(
+    "internal_$identifier$_fieldAccessorTable = new\n"
+    "  com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
+    "    internal_$identifier$_descriptor,\n"
+    "    new java.lang.String[] { ",
+    "identifier",
+    UniqueFileScopeIdentifier(descriptor_));
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+    printer->Print(
+      "\"$field_name$\", ",
+      "field_name", info->capitalized_name);
+  }
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
+    const OneofGeneratorInfo* info = context_->GetOneofGeneratorInfo(oneof);
+    printer->Print(
+      "\"$oneof_name$\", ",
+      "oneof_name", info->capitalized_name);
+  }
+  printer->Print("});\n");
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
+  if (descriptor_->extension_range_count() > 0) {
+    if (HasDescriptorMethods(descriptor_)) {
+      printer->Print(
+        "public interface $classname$OrBuilder extends\n"
+        "    $extra_interfaces$\n"
+        "    com.google.protobuf.GeneratedMessage.\n"
+        "        ExtendableMessageOrBuilder<$classname$> {\n",
+        "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+        "classname", descriptor_->name());
+    } else {
+      printer->Print(
+        "public interface $classname$OrBuilder extends \n"
+        "    $extra_interfaces$\n"
+        "     com.google.protobuf.GeneratedMessageLite.\n"
+        "          ExtendableMessageOrBuilder<$classname$> {\n",
+        "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+        "classname", descriptor_->name());
+    }
+  } else {
+    if (HasDescriptorMethods(descriptor_)) {
+      printer->Print(
+        "public interface $classname$OrBuilder extends\n"
+        "    $extra_interfaces$\n"
+        "    com.google.protobuf.MessageOrBuilder {\n",
+        "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+        "classname", descriptor_->name());
+    } else {
+      printer->Print(
+        "public interface $classname$OrBuilder extends\n"
+        "    $extra_interfaces$\n"
+        "    com.google.protobuf.MessageLiteOrBuilder {\n",
+        "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
+        "classname", descriptor_->name());
+    }
+  }
+
+  printer->Indent();
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      printer->Print("\n");
+      field_generators_.get(descriptor_->field(i))
+                       .GenerateInterfaceMembers(printer);
+    }
+  printer->Outdent();
+
+  printer->Print("}\n");
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::Generate(io::Printer* printer) {
+  bool is_own_file =
+    descriptor_->containing_type() == NULL &&
+    MultipleJavaFiles(descriptor_->file(), /* immutable = */ true);
+
+  WriteMessageDocComment(printer, descriptor_);
+
+  // The builder_type stores the super type name of the nested Builder class.
+  string builder_type;
+  if (descriptor_->extension_range_count() > 0) {
+    if (HasDescriptorMethods(descriptor_)) {
+      printer->Print(
+        "public$static$final class $classname$ extends\n"
+        "    com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
+        "      $classname$> implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n",
+        "static", is_own_file ? " " : " static ",
+        "classname", descriptor_->name(),
+        "extra_interfaces", ExtraMessageInterfaces(descriptor_));
+      builder_type = strings::Substitute(
+          "com.google.protobuf.GeneratedMessage.ExtendableBuilder<$0, ?>",
+          name_resolver_->GetImmutableClassName(descriptor_));
+    } else {
+      printer->Print(
+        "public$static$final class $classname$ extends\n"
+        "    com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n"
+        "      $classname$> implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n",
+        "static", is_own_file ? " " : " static ",
+        "classname", descriptor_->name(),
+        "extra_interfaces", ExtraMessageInterfaces(descriptor_));
+      builder_type = strings::Substitute(
+          "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>",
+          name_resolver_->GetImmutableClassName(descriptor_));
+    }
+  } else {
+    if (HasDescriptorMethods(descriptor_)) {
+      printer->Print(
+        "public$static$final class $classname$ extends\n"
+        "    com.google.protobuf.GeneratedMessage implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n",
+        "static", is_own_file ? " " : " static ",
+        "classname", descriptor_->name(),
+        "extra_interfaces", ExtraMessageInterfaces(descriptor_));
+      builder_type = "com.google.protobuf.GeneratedMessage.Builder<?>";
+    } else {
+      printer->Print(
+        "public$static$final class $classname$ extends\n"
+        "    com.google.protobuf.GeneratedMessageLite implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n",
+        "static", is_own_file ? " " : " static ",
+        "classname", descriptor_->name(),
+        "extra_interfaces", ExtraMessageInterfaces(descriptor_));
+      builder_type = "com.google.protobuf.GeneratedMessageLite.Builder";
+    }
+  }
+  printer->Indent();
+  // Using builder_type, instead of Builder, prevents the Builder class from
+  // being loaded into PermGen space when the default instance is created.
+  // This optimizes the PermGen space usage for clients that do not modify
+  // messages.
+  printer->Print(
+    "// Use $classname$.newBuilder() to construct.\n"
+    "private $classname$($buildertype$ builder) {\n"
+    "  super(builder);\n"
+    "$set_unknown_fields$\n"
+    "}\n",
+    "classname", descriptor_->name(),
+    "buildertype", builder_type,
+    "set_unknown_fields",
+    "  this.unknownFields = builder.getUnknownFields();");
+  printer->Print(
+    // Used when constructing the default instance, which cannot be initialized
+    // immediately because it may cyclically refer to other default instances.
+    "private $classname$(boolean noInit) {$set_default_unknown_fields$}\n"
+    "\n"
+    "private static final $classname$ defaultInstance;\n"
+    "public static $classname$ getDefaultInstance() {\n"
+    "  return defaultInstance;\n"
+    "}\n"
+    "\n"
+    "public $classname$ getDefaultInstanceForType() {\n"
+    "  return defaultInstance;\n"
+    "}\n"
+    "\n",
+    "classname", descriptor_->name(),
+    "set_default_unknown_fields", UseUnknownFieldSet(descriptor_)
+        ? " this.unknownFields ="
+          " com.google.protobuf.UnknownFieldSet.getDefaultInstance(); "
+        : " this.unknownFields = com.google.protobuf.ByteString.EMPTY;");
+
+  if (UseUnknownFieldSet(descriptor_)) {
+    printer->Print(
+        "private final com.google.protobuf.UnknownFieldSet unknownFields;\n"
+        ""
+        "@java.lang.Override\n"
+        "public final com.google.protobuf.UnknownFieldSet\n"
+        "    getUnknownFields() {\n"
+        "  return this.unknownFields;\n"
+        "}\n");
+  } else {
+    printer->Print(
+        "private final com.google.protobuf.ByteString unknownFields;\n");
+  }
+
+  if (HasGeneratedMethods(descriptor_)) {
+    GenerateParsingConstructor(printer);
+  }
+
+  GenerateDescriptorMethods(printer);
+  GenerateParser(printer);
+
+  // Nested types
+  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+    EnumGenerator(descriptor_->enum_type(i), true, context_)
+        .Generate(printer);
+  }
+
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    ImmutableMessageGenerator messageGenerator(
+        descriptor_->nested_type(i), context_);
+    messageGenerator.GenerateInterface(printer);
+    messageGenerator.Generate(printer);
+  }
+
+  if (GenerateHasBits(descriptor_)) {
+    // Integers for bit fields.
+    int totalBits = 0;
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      totalBits += field_generators_.get(descriptor_->field(i))
+          .GetNumBitsForMessage();
+    }
+    int totalInts = (totalBits + 31) / 32;
+    for (int i = 0; i < totalInts; i++) {
+      printer->Print("private int $bit_field_name$;\n",
+        "bit_field_name", GetBitFieldName(i));
+    }
+  }
+
+  // oneof
+  map<string, string> vars;
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    vars["oneof_name"] = context_->GetOneofGeneratorInfo(
+        descriptor_->oneof_decl(i))->name;
+    vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
+        descriptor_->oneof_decl(i))->capitalized_name;
+    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+    // oneofCase_ and oneof_
+    printer->Print(vars,
+      "private int $oneof_name$Case_ = 0;\n"
+      "private java.lang.Object $oneof_name$_;\n");
+    // OneofCase enum
+    printer->Print(vars,
+      "public enum $oneof_capitalized_name$Case\n"
+      "    implements com.google.protobuf.Internal.EnumLite {\n");
+    printer->Indent();
+    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+      printer->Print(
+        "$field_name$($field_number$),\n",
+        "field_name",
+        ToUpper(field->name()),
+        "field_number",
+        SimpleItoa(field->number()));
+    }
+    printer->Print(
+      "$cap_oneof_name$_NOT_SET(0);\n",
+      "cap_oneof_name",
+      ToUpper(vars["oneof_name"]));
+    printer->Print(vars,
+      "private int value = 0;\n"
+      "private $oneof_capitalized_name$Case(int value) {\n"
+      "  this.value = value;\n"
+      "}\n");
+    printer->Print(vars,
+      "public static $oneof_capitalized_name$Case valueOf(int value) {\n"
+      "  switch (value) {\n");
+    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+      printer->Print(
+        "    case $field_number$: return $field_name$;\n",
+        "field_number",
+        SimpleItoa(field->number()),
+        "field_name",
+        ToUpper(field->name()));
+    }
+    printer->Print(
+      "    case 0: return $cap_oneof_name$_NOT_SET;\n"
+      "    default: throw new java.lang.IllegalArgumentException(\n"
+      "      \"Value is undefined for this oneof enum.\");\n"
+      "  }\n"
+      "}\n"
+      "public int getNumber() {\n"
+      "  return this.value;\n"
+      "}\n",
+      "cap_oneof_name", ToUpper(vars["oneof_name"]));
+    printer->Outdent();
+    printer->Print("};\n\n");
+    // oneofCase()
+    printer->Print(vars,
+      "public $oneof_capitalized_name$Case\n"
+      "get$oneof_capitalized_name$Case() {\n"
+      "  return $oneof_capitalized_name$Case.valueOf(\n"
+      "      $oneof_name$Case_);\n"
+      "}\n"
+      "\n");
+  }
+
+  // Fields
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    printer->Print("public static final int $constant_name$ = $number$;\n",
+      "constant_name", FieldConstantName(descriptor_->field(i)),
+      "number", SimpleItoa(descriptor_->field(i)->number()));
+    field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
+    printer->Print("\n");
+  }
+
+  // Called by the constructor, except in the case of the default instance,
+  // in which case this is called by static init code later on.
+  printer->Print("private void initFields() {\n");
+  printer->Indent();
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    if (!descriptor_->field(i)->containing_oneof()) {
+      field_generators_.get(descriptor_->field(i))
+          .GenerateInitializationCode(printer);
+    }
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+
+  if (HasGeneratedMethods(descriptor_)) {
+    GenerateIsInitialized(printer, MEMOIZE);
+    GenerateMessageSerializationMethods(printer);
+  }
+
+  if (HasEqualsAndHashCode(descriptor_)) {
+    GenerateEqualsAndHashCode(printer);
+  }
+
+
+  GenerateParseFromMethods(printer);
+  GenerateBuilder(printer);
+
+  // Carefully initialize the default instance in such a way that it doesn't
+  // conflict with other initialization.
+  printer->Print(
+    "\n"
+    "static {\n"
+    "  defaultInstance = new $classname$(true);\n"
+    "  defaultInstance.initFields();\n"
+    "}\n"
+    "\n"
+    "// @@protoc_insertion_point(class_scope:$full_name$)\n",
+    "classname", descriptor_->name(),
+    "full_name", descriptor_->full_name());
+
+  // Extensions must be declared after the defaultInstance is initialized
+  // because the defaultInstance is used by the extension to lazily retrieve
+  // the outer class's FileDescriptor.
+  for (int i = 0; i < descriptor_->extension_count(); i++) {
+    ImmutableExtensionGenerator(descriptor_->extension(i), context_)
+        .Generate(printer);
+  }
+
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+
+// ===================================================================
+
+void ImmutableMessageGenerator::
+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();
+  // writeTo(CodedOutputStream output) might be invoked without
+  // getSerializedSize() ever being called, but we need the memoized
+  // sizes in case this message has packed fields. Rather than emit checks for
+  // each packed field, just call getSerializedSize() up front for all messages.
+  // In most cases, getSerializedSize() will have already been called anyway by
+  // one of the wrapper writeTo() methods, making this call cheap.
+  printer->Print(
+    "getSerializedSize();\n");
+
+  if (descriptor_->extension_range_count() > 0) {
+    if (descriptor_->options().message_set_wire_format()) {
+      printer->Print(
+        "com.google.protobuf.GeneratedMessage$lite$\n"
+        "  .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n"
+        "    newMessageSetExtensionWriter();\n",
+        "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite",
+        "classname", name_resolver_->GetImmutableClassName(descriptor_));
+    } else {
+      printer->Print(
+        "com.google.protobuf.GeneratedMessage$lite$\n"
+        "  .ExtendableMessage<$classname$>.ExtensionWriter extensionWriter =\n"
+        "    newExtensionWriter();\n",
+        "lite", HasDescriptorMethods(descriptor_) ? "" : "Lite",
+        "classname", name_resolver_->GetImmutableClassName(descriptor_));
+    }
+  }
+
+  // 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 (UseUnknownFieldSet(descriptor_)) {
+    if (descriptor_->options().message_set_wire_format()) {
+      printer->Print(
+        "getUnknownFields().writeAsMessageSetTo(output);\n");
+    } else {
+      printer->Print(
+        "getUnknownFields().writeTo(output);\n");
+    }
+  } else {
+    printer->Print(
+      "output.writeRawBytes(unknownFields);\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) {
+    if (descriptor_->options().message_set_wire_format()) {
+      printer->Print(
+        "size += extensionsSerializedSizeAsMessageSet();\n");
+    } else {
+      printer->Print(
+        "size += extensionsSerializedSize();\n");
+    }
+  }
+
+  if (UseUnknownFieldSet(descriptor_)) {
+    if (descriptor_->options().message_set_wire_format()) {
+      printer->Print(
+        "size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
+    } else {
+      printer->Print(
+        "size += getUnknownFields().getSerializedSize();\n");
+    }
+  } else {
+    printer->Print(
+      "size += unknownFields.size();\n");
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "  memoizedSerializedSize = size;\n"
+    "  return size;\n"
+    "}\n"
+    "\n");
+
+  printer->Print(
+    "private static final long serialVersionUID = 0L;\n"
+    "@java.lang.Override\n"
+    "protected java.lang.Object writeReplace()\n"
+    "    throws java.io.ObjectStreamException {\n"
+    "  return super.writeReplace();\n"
+    "}\n"
+    "\n");
+}
+
+void ImmutableMessageGenerator::
+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 PARSER.parseFrom(data);\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    com.google.protobuf.ByteString data,\n"
+    "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return PARSER.parseFrom(data, extensionRegistry);\n"
+    "}\n"
+    "public static $classname$ parseFrom(byte[] data)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return PARSER.parseFrom(data);\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    byte[] data,\n"
+    "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+    "    throws com.google.protobuf.InvalidProtocolBufferException {\n"
+    "  return PARSER.parseFrom(data, extensionRegistry);\n"
+    "}\n"
+    "public static $classname$ parseFrom(java.io.InputStream input)\n"
+    "    throws java.io.IOException {\n"
+    "  return PARSER.parseFrom(input);\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    java.io.InputStream input,\n"
+    "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+    "    throws java.io.IOException {\n"
+    "  return PARSER.parseFrom(input, extensionRegistry);\n"
+    "}\n"
+    "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
+    "    throws java.io.IOException {\n"
+    "  return PARSER.parseDelimitedFrom(input);\n"
+    "}\n"
+    "public static $classname$ parseDelimitedFrom(\n"
+    "    java.io.InputStream input,\n"
+    "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+    "    throws java.io.IOException {\n"
+    "  return PARSER.parseDelimitedFrom(input, extensionRegistry);\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    com.google.protobuf.CodedInputStream input)\n"
+    "    throws java.io.IOException {\n"
+    "  return PARSER.parseFrom(input);\n"
+    "}\n"
+    "public static $classname$ parseFrom(\n"
+    "    com.google.protobuf.CodedInputStream input,\n"
+    "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+    "    throws java.io.IOException {\n"
+    "  return PARSER.parseFrom(input, extensionRegistry);\n"
+    "}\n"
+    "\n",
+    "classname", name_resolver_->GetImmutableClassName(descriptor_));
+}
+
+void ImmutableMessageGenerator::GenerateSerializeOneField(
+    io::Printer* printer, const FieldDescriptor* field) {
+  field_generators_.get(field).GenerateSerializationCode(printer);
+}
+
+void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
+    io::Printer* printer, const Descriptor::ExtensionRange* range) {
+  printer->Print(
+    "extensionWriter.writeUntil($end$, output);\n",
+    "end", SimpleItoa(range->end));
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
+  printer->Print(
+    "public static Builder newBuilder() { return Builder.create(); }\n"
+    "public Builder newBuilderForType() { return newBuilder(); }\n"
+    "public static Builder newBuilder($classname$ prototype) {\n"
+    "  return newBuilder().mergeFrom(prototype);\n"
+    "}\n"
+    "public Builder toBuilder() { return newBuilder(this); }\n"
+    "\n",
+    "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+  if (HasNestedBuilders(descriptor_)) {
+     printer->Print(
+      "@java.lang.Override\n"
+      "protected Builder newBuilderForType(\n"
+      "    com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
+      "  Builder builder = new Builder(parent);\n"
+      "  return builder;\n"
+      "}\n");
+  }
+
+  WriteMessageDocComment(printer, descriptor_);
+
+  if (descriptor_->extension_range_count() > 0) {
+    if (HasDescriptorMethods(descriptor_)) {
+      printer->Print(
+        "public static final class Builder extends\n"
+        "    com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
+        "      $classname$, Builder> implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n",
+        "classname", name_resolver_->GetImmutableClassName(descriptor_),
+        "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
+    } else {
+      printer->Print(
+        "public static final class Builder extends\n"
+        "    com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n"
+        "      $classname$, Builder> implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n",
+        "classname", name_resolver_->GetImmutableClassName(descriptor_),
+        "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
+    }
+  } else {
+    if (HasDescriptorMethods(descriptor_)) {
+      printer->Print(
+        "public static final class Builder extends\n"
+        "    com.google.protobuf.GeneratedMessage.Builder<Builder> implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n",
+        "classname", name_resolver_->GetImmutableClassName(descriptor_),
+        "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
+    } else {
+      printer->Print(
+        "public static final class Builder extends\n"
+        "    com.google.protobuf.GeneratedMessageLite.Builder<\n"
+        "      $classname$, Builder>\n"
+        "    implements\n"
+        "    $extra_interfaces$\n"
+        "    $classname$OrBuilder {\n",
+        "classname", name_resolver_->GetImmutableClassName(descriptor_),
+        "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
+    }
+  }
+  printer->Indent();
+
+  GenerateDescriptorMethods(printer);
+  GenerateCommonBuilderMethods(printer);
+
+  if (HasGeneratedMethods(descriptor_)) {
+    GenerateIsInitialized(printer, DONT_MEMOIZE);
+    GenerateBuilderParsingMethods(printer);
+  }
+
+  // oneof
+  map<string, string> vars;
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    vars["oneof_name"] = context_->GetOneofGeneratorInfo(
+        descriptor_->oneof_decl(i))->name;
+    vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
+        descriptor_->oneof_decl(i))->capitalized_name;
+    vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+    // oneofCase_ and oneof_
+    printer->Print(vars,
+      "private int $oneof_name$Case_ = 0;\n"
+      "private java.lang.Object $oneof_name$_;\n");
+    // oneofCase() and clearOneof()
+    printer->Print(vars,
+      "public $oneof_capitalized_name$Case\n"
+      "    get$oneof_capitalized_name$Case() {\n"
+      "  return $oneof_capitalized_name$Case.valueOf(\n"
+      "      $oneof_name$Case_);\n"
+      "}\n"
+      "\n"
+      "public Builder clear$oneof_capitalized_name$() {\n"
+      "  $oneof_name$Case_ = 0;\n"
+      "  $oneof_name$_ = null;\n");
+    if (HasDescriptorMethods(descriptor_)) {
+      printer->Print("  onChanged();\n");
+    }
+    printer->Print(
+      "  return this;\n"
+      "}\n"
+      "\n");
+  }
+
+  if (GenerateHasBits(descriptor_)) {
+    // Integers for bit fields.
+    int totalBits = 0;
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      totalBits += field_generators_.get(descriptor_->field(i))
+          .GetNumBitsForBuilder();
+    }
+    int totalInts = (totalBits + 31) / 32;
+    for (int i = 0; i < totalInts; i++) {
+      printer->Print("private int $bit_field_name$;\n",
+        "bit_field_name", GetBitFieldName(i));
+    }
+  }
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    printer->Print("\n");
+    field_generators_.get(descriptor_->field(i))
+                     .GenerateBuilderMembers(printer);
+  }
+
+  printer->Print(
+    "\n"
+    "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
+    "full_name", descriptor_->full_name());
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void ImmutableMessageGenerator::
+GenerateDescriptorMethods(io::Printer* printer) {
+  if (HasDescriptorMethods(descriptor_)) {
+    if (!descriptor_->options().no_standard_descriptor_accessor()) {
+      printer->Print(
+        "public static final com.google.protobuf.Descriptors.Descriptor\n"
+        "    getDescriptor() {\n"
+        "  return $fileclass$.internal_$identifier$_descriptor;\n"
+        "}\n"
+        "\n",
+        "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+        "identifier", UniqueFileScopeIdentifier(descriptor_));
+    }
+    printer->Print(
+      "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+      "    internalGetFieldAccessorTable() {\n"
+      "  return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
+      "      .ensureFieldAccessorsInitialized(\n"
+      "          $classname$.class, $classname$.Builder.class);\n"
+      "}\n"
+      "\n",
+      "classname", name_resolver_->GetImmutableClassName(descriptor_),
+      "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+      "identifier", UniqueFileScopeIdentifier(descriptor_));
+  }
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::
+GenerateCommonBuilderMethods(io::Printer* printer) {
+  printer->Print(
+    "// Construct using $classname$.newBuilder()\n"
+    "private Builder() {\n"
+    "  maybeForceBuilderInitialization();\n"
+    "}\n"
+    "\n",
+    "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+  if (HasDescriptorMethods(descriptor_)) {
+    printer->Print(
+      "private Builder(\n"
+      "    com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
+      "  super(parent);\n"
+      "  maybeForceBuilderInitialization();\n"
+      "}\n",
+      "classname", name_resolver_->GetImmutableClassName(descriptor_));
+  }
+
+
+  if (HasNestedBuilders(descriptor_)) {
+    printer->Print(
+      "private void maybeForceBuilderInitialization() {\n"
+      "  if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n");
+
+    printer->Indent();
+    printer->Indent();
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      if (!descriptor_->field(i)->containing_oneof()) {
+        field_generators_.get(descriptor_->field(i))
+            .GenerateFieldBuilderInitializationCode(printer);
+      }
+    }
+    printer->Outdent();
+    printer->Outdent();
+
+    printer->Print(
+      "  }\n"
+      "}\n");
+  } else {
+    printer->Print(
+      "private void maybeForceBuilderInitialization() {\n"
+      "}\n");
+  }
+
+  printer->Print(
+    "private static Builder create() {\n"
+    "  return new Builder();\n"
+    "}\n"
+    "\n"
+    "public Builder clear() {\n"
+    "  super.clear();\n",
+    "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    if (!descriptor_->field(i)->containing_oneof()) {
+      field_generators_.get(descriptor_->field(i))
+          .GenerateBuilderClearCode(printer);
+    }
+  }
+
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print(
+      "$oneof_name$Case_ = 0;\n"
+      "$oneof_name$_ = null;\n",
+      "oneof_name", context_->GetOneofGeneratorInfo(
+          descriptor_->oneof_decl(i))->name);
+  }
+
+  printer->Outdent();
+
+  printer->Print(
+    "  return this;\n"
+    "}\n"
+    "\n"
+    "public Builder clone() {\n"
+    "  return create().mergeFrom(buildPartial());\n"
+    "}\n"
+    "\n",
+    "classname", name_resolver_->GetImmutableClassName(descriptor_));
+  if (HasDescriptorMethods(descriptor_)) {
+    printer->Print(
+      "public com.google.protobuf.Descriptors.Descriptor\n"
+      "    getDescriptorForType() {\n"
+      "  return $fileclass$.internal_$identifier$_descriptor;\n"
+      "}\n"
+      "\n",
+      "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
+      "identifier", UniqueFileScopeIdentifier(descriptor_));
+  }
+  printer->Print(
+    "public $classname$ getDefaultInstanceForType() {\n"
+    "  return $classname$.getDefaultInstance();\n"
+    "}\n"
+    "\n",
+    "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+  // -----------------------------------------------------------------
+
+  printer->Print(
+    "public $classname$ build() {\n"
+    "  $classname$ result = buildPartial();\n"
+    "  if (!result.isInitialized()) {\n"
+    "    throw newUninitializedMessageException(result);\n"
+    "  }\n"
+    "  return result;\n"
+    "}\n"
+    "\n"
+    "public $classname$ buildPartial() {\n"
+    "  $classname$ result = new $classname$(this);\n",
+    "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+  printer->Indent();
+
+  int totalBuilderBits = 0;
+  int totalMessageBits = 0;
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const ImmutableFieldGenerator& field =
+        field_generators_.get(descriptor_->field(i));
+    totalBuilderBits += field.GetNumBitsForBuilder();
+    totalMessageBits += field.GetNumBitsForMessage();
+  }
+  int totalBuilderInts = (totalBuilderBits + 31) / 32;
+  int totalMessageInts = (totalMessageBits + 31) / 32;
+
+  if (GenerateHasBits(descriptor_)) {
+    // Local vars for from and to bit fields to avoid accessing the builder and
+    // message over and over for these fields. Seems to provide a slight
+    // perforamance improvement in micro benchmark and this is also what proto1
+    // code does.
+    for (int i = 0; i < totalBuilderInts; i++) {
+      printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n",
+        "bit_field_name", GetBitFieldName(i));
+    }
+    for (int i = 0; i < totalMessageInts; i++) {
+      printer->Print("int to_$bit_field_name$ = 0;\n",
+        "bit_field_name", GetBitFieldName(i));
+    }
+  }
+
+  // Output generation code for each field.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
+  }
+
+  if (GenerateHasBits(descriptor_)) {
+    // Copy the bit field results to the generated message
+    for (int i = 0; i < totalMessageInts; i++) {
+      printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n",
+        "bit_field_name", GetBitFieldName(i));
+    }
+  }
+
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n",
+                   "oneof_name", context_->GetOneofGeneratorInfo(
+                       descriptor_->oneof_decl(i))->name);
+  }
+
+  printer->Outdent();
+
+  if (HasDescriptorMethods(descriptor_)) {
+    printer->Print(
+    "  onBuilt();\n");
+  }
+
+  printer->Print(
+    "  return result;\n"
+    "}\n"
+    "\n",
+    "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+  // -----------------------------------------------------------------
+
+  if (HasGeneratedMethods(descriptor_)) {
+    // MergeFrom(Message other) requires the ability to distinguish the other
+    // messages type by its descriptor.
+    if (HasDescriptorMethods(descriptor_)) {
+      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",
+        "classname", name_resolver_->GetImmutableClassName(descriptor_));
+    }
+
+    printer->Print(
+      "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", name_resolver_->GetImmutableClassName(descriptor_));
+    printer->Indent();
+
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      if (!descriptor_->field(i)->containing_oneof()) {
+        field_generators_.get(
+            descriptor_->field(i)).GenerateMergingCode(printer);
+      }
+    }
+
+    // Merge oneof fields.
+    for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
+      printer->Print(
+        "switch (other.get$oneof_capitalized_name$Case()) {\n",
+        "oneof_capitalized_name",
+        context_->GetOneofGeneratorInfo(
+            descriptor_->oneof_decl(i))->capitalized_name);
+      printer->Indent();
+      for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+        const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+        printer->Print(
+          "case $field_name$: {\n",
+          "field_name",
+          ToUpper(field->name()));
+        printer->Indent();
+        field_generators_.get(field).GenerateMergingCode(printer);
+        printer->Print(
+            "break;\n");
+        printer->Outdent();
+        printer->Print(
+            "}\n");
+      }
+      printer->Print(
+        "case $cap_oneof_name$_NOT_SET: {\n"
+        "  break;\n"
+        "}\n",
+        "cap_oneof_name",
+        ToUpper(context_->GetOneofGeneratorInfo(
+            descriptor_->oneof_decl(i))->name));
+      printer->Outdent();
+      printer->Print(
+          "}\n");
+    }
+
+    printer->Outdent();
+
+    // if message type has extensions
+    if (descriptor_->extension_range_count() > 0) {
+      printer->Print(
+        "  this.mergeExtensionFields(other);\n");
+    }
+
+    if (UseUnknownFieldSet(descriptor_)) {
+      printer->Print(
+        "  this.mergeUnknownFields(other.getUnknownFields());\n");
+    } else {
+      printer->Print(
+        "  setUnknownFields(\n"
+        "      getUnknownFields().concat(other.unknownFields));\n");
+    }
+
+    printer->Print(
+      "  return this;\n"
+      "}\n"
+      "\n");
+  }
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::
+GenerateBuilderParsingMethods(io::Printer* printer) {
+  printer->Print(
+    "public Builder mergeFrom(\n"
+    "    com.google.protobuf.CodedInputStream input,\n"
+    "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+    "    throws java.io.IOException {\n"
+    "  $classname$ parsedMessage = null;\n"
+    "  try {\n"
+    "    parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n"
+    "  } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+    "    parsedMessage = ($classname$) e.getUnfinishedMessage();\n"
+    "    throw e;\n"
+    "  } finally {\n"
+    "    if (parsedMessage != null) {\n"
+    "      mergeFrom(parsedMessage);\n"
+    "    }\n"
+    "  }\n"
+    "  return this;\n"
+    "}\n",
+    "classname", name_resolver_->GetImmutableClassName(descriptor_));
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::GenerateIsInitialized(
+    io::Printer* printer, UseMemoization useMemoization) {
+  bool memoization = useMemoization == MEMOIZE;
+  if (memoization) {
+    // Memoizes whether the protocol buffer is fully initialized (has all
+    // required fields). -1 means not yet computed. 0 means false and 1 means
+    // true.
+    printer->Print(
+      "private byte memoizedIsInitialized = -1;\n");
+  }
+  printer->Print(
+    "public final boolean isInitialized() {\n");
+  printer->Indent();
+
+  if (memoization) {
+    // Don't directly compare to -1 to avoid an Android x86 JIT bug.
+    printer->Print(
+      "byte isInitialized = memoizedIsInitialized;\n"
+      "if (isInitialized == 1) return true;\n"
+      "if (isInitialized == 0) return false;\n"
+      "\n");
+  }
+
+  // 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);
+    const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+
+    if (field->is_required()) {
+      printer->Print(
+        "if (!has$name$()) {\n"
+        "  $memoize$\n"
+        "  return false;\n"
+        "}\n",
+        "name", info->capitalized_name,
+        "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+    }
+  }
+
+  // Now check that all embedded messages are initialized.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+    if (GetJavaType(field) == JAVATYPE_MESSAGE &&
+        HasRequiredFields(field->message_type())) {
+      switch (field->label()) {
+        case FieldDescriptor::LABEL_REQUIRED:
+          printer->Print(
+            "if (!get$name$().isInitialized()) {\n"
+             "  $memoize$\n"
+             "  return false;\n"
+             "}\n",
+            "type", name_resolver_->GetImmutableClassName(
+                field->message_type()),
+            "name", info->capitalized_name,
+            "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+          break;
+        case FieldDescriptor::LABEL_OPTIONAL:
+          printer->Print(
+            "if (has$name$()) {\n"
+            "  if (!get$name$().isInitialized()) {\n"
+            "    $memoize$\n"
+            "    return false;\n"
+            "  }\n"
+            "}\n",
+            "type", name_resolver_->GetImmutableClassName(
+                field->message_type()),
+            "name", info->capitalized_name,
+            "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+          break;
+        case FieldDescriptor::LABEL_REPEATED:
+          printer->Print(
+            "for (int i = 0; i < get$name$Count(); i++) {\n"
+            "  if (!get$name$(i).isInitialized()) {\n"
+            "    $memoize$\n"
+            "    return false;\n"
+            "  }\n"
+            "}\n",
+            "type", name_resolver_->GetImmutableClassName(
+                field->message_type()),
+            "name", info->capitalized_name,
+            "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+          break;
+      }
+    }
+  }
+
+  if (descriptor_->extension_range_count() > 0) {
+    printer->Print(
+      "if (!extensionsAreInitialized()) {\n"
+      "  $memoize$\n"
+      "  return false;\n"
+      "}\n",
+      "memoize", memoization ? "memoizedIsInitialized = 0;" : "");
+  }
+
+  printer->Outdent();
+
+  if (memoization) {
+    printer->Print(
+      "  memoizedIsInitialized = 1;\n");
+  }
+
+  printer->Print(
+    "  return true;\n"
+    "}\n"
+    "\n");
+}
+
+// ===================================================================
+
+namespace {
+bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) {
+  if (field->is_repeated()) {
+    return false;
+  }
+  if (SupportFieldPresence(field->file())) {
+    return true;
+  }
+  return GetJavaType(field) == JAVATYPE_MESSAGE &&
+      field->containing_oneof() == NULL;
+}
+}  // namespace
+
+void ImmutableMessageGenerator::
+GenerateEqualsAndHashCode(io::Printer* printer) {
+  printer->Print(
+    "@java.lang.Override\n"
+    "public boolean equals(final java.lang.Object obj) {\n");
+  printer->Indent();
+  printer->Print(
+    "if (obj == this) {\n"
+    " return true;\n"
+    "}\n"
+    "if (!(obj instanceof $classname$)) {\n"
+    "  return super.equals(obj);\n"
+    "}\n"
+    "$classname$ other = ($classname$) obj;\n"
+    "\n",
+    "classname", name_resolver_->GetImmutableClassName(descriptor_));
+
+  printer->Print("boolean result = true;\n");
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+    bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
+    if (check_has_bits) {
+      printer->Print(
+        "result = result && (has$name$() == other.has$name$());\n"
+        "if (has$name$()) {\n",
+        "name", info->capitalized_name);
+      printer->Indent();
+    }
+    field_generators_.get(field).GenerateEqualsCode(printer);
+    if (check_has_bits) {
+      printer->Outdent();
+      printer->Print(
+        "}\n");
+    }
+  }
+  if (HasDescriptorMethods(descriptor_)) {
+    printer->Print(
+      "result = result &&\n"
+      "    getUnknownFields().equals(other.getUnknownFields());\n");
+    if (descriptor_->extension_range_count() > 0) {
+      printer->Print(
+        "result = result &&\n"
+        "    getExtensionFields().equals(other.getExtensionFields());\n");
+    }
+  }
+  printer->Print(
+    "return result;\n");
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "\n");
+
+  printer->Print(
+    "@java.lang.Override\n"
+    "public int hashCode() {\n");
+  printer->Indent();
+  printer->Print(
+    "if (memoizedHashCode != 0) {\n");
+  printer->Indent();
+  printer->Print(
+    "return memoizedHashCode;\n");
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "int hash = 41;\n");
+
+  if (HasDescriptorMethods(descriptor_)) {
+    printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n");
+  } else {
+    // Include the hash of the class so that two objects with different types
+    // but the same field values will probably have different hashes.
+    printer->Print("hash = (19 * hash) + $classname$.class.hashCode();\n",
+      "classname", name_resolver_->GetImmutableClassName(descriptor_));
+  }
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+    bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
+    if (check_has_bits) {
+      printer->Print(
+        "if (has$name$()) {\n",
+        "name", info->capitalized_name);
+      printer->Indent();
+    }
+    field_generators_.get(field).GenerateHashCode(printer);
+    if (check_has_bits) {
+      printer->Outdent();
+      printer->Print("}\n");
+    }
+  }
+  if (HasDescriptorMethods(descriptor_)) {
+    if (descriptor_->extension_range_count() > 0) {
+      printer->Print(
+        "hash = hashFields(hash, getExtensionFields());\n");
+    }
+  }
+
+  if (UseUnknownFieldSet(descriptor_)) {
+    printer->Print(
+      "hash = (29 * hash) + getUnknownFields().hashCode();\n");
+  } else {
+    printer->Print(
+      "hash = (29 * hash) + unknownFields.hashCode();\n");
+  }
+  printer->Print(
+    "memoizedHashCode = hash;\n"
+    "return hash;\n");
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "\n");
+}
+
+// ===================================================================
+
+void ImmutableMessageGenerator::
+GenerateExtensionRegistrationCode(io::Printer* printer) {
+  for (int i = 0; i < descriptor_->extension_count(); i++) {
+    ImmutableExtensionGenerator(descriptor_->extension(i), context_)
+      .GenerateRegistrationCode(printer);
+  }
+
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    ImmutableMessageGenerator(descriptor_->nested_type(i), context_)
+      .GenerateExtensionRegistrationCode(printer);
+  }
+}
+
+// ===================================================================
+void ImmutableMessageGenerator::
+GenerateParsingConstructor(io::Printer* printer) {
+  scoped_array<const FieldDescriptor*> sorted_fields(
+      SortFieldsByNumber(descriptor_));
+
+  printer->Print(
+      "private $classname$(\n"
+      "    com.google.protobuf.CodedInputStream input,\n"
+      "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+      "    throws com.google.protobuf.InvalidProtocolBufferException {\n",
+      "classname", descriptor_->name());
+  printer->Indent();
+
+  // Initialize all fields to default.
+  printer->Print(
+      "initFields();\n");
+
+  // Use builder bits to track mutable repeated fields.
+  int totalBuilderBits = 0;
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const ImmutableFieldGenerator& field =
+        field_generators_.get(descriptor_->field(i));
+    totalBuilderBits += field.GetNumBitsForBuilder();
+  }
+  int totalBuilderInts = (totalBuilderBits + 31) / 32;
+  for (int i = 0; i < totalBuilderInts; i++) {
+    printer->Print("int mutable_$bit_field_name$ = 0;\n",
+      "bit_field_name", GetBitFieldName(i));
+  }
+
+  if (UseUnknownFieldSet(descriptor_)) {
+    printer->Print(
+      "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
+      "    com.google.protobuf.UnknownFieldSet.newBuilder();\n");
+  } else {
+    printer->Print(
+      "com.google.protobuf.ByteString.Output unknownFieldsOutput =\n"
+      "    com.google.protobuf.ByteString.newOutput();\n"
+      "com.google.protobuf.CodedOutputStream unknownFieldsCodedOutput =\n"
+      "    com.google.protobuf.CodedOutputStream.newInstance(\n"
+      "        unknownFieldsOutput);\n");
+  }
+
+  printer->Print(
+      "try {\n");
+  printer->Indent();
+
+  printer->Print(
+    "boolean done = false;\n"
+    "while (!done) {\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
+    "  done = true;\n"
+    "  break;\n"
+    "default: {\n"
+    "  if (!parseUnknownField(input,$unknown_fields$\n"
+    "                         extensionRegistry, tag)) {\n"
+    "    done = true;\n"  // it's an endgroup tag
+    "  }\n"
+    "  break;\n"
+    "}\n",
+    "unknown_fields", UseUnknownFieldSet(descriptor_)
+        ? " unknownFields," : " unknownFieldsCodedOutput,");
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = sorted_fields[i];
+    uint32 tag = WireFormatLite::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");
+
+    if (field->is_packable()) {
+      // To make packed = true wire compatible, we generate parsing code from a
+      // packed version of this field regardless of field->options().packed().
+      uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
+        WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+      printer->Print(
+        "case $tag$: {\n",
+        "tag", SimpleItoa(packed_tag));
+      printer->Indent();
+
+      field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
+
+      printer->Outdent();
+      printer->Print(
+        "  break;\n"
+        "}\n");
+    }
+  }
+
+  printer->Outdent();
+  printer->Outdent();
+  printer->Print(
+      "  }\n"     // switch (tag)
+      "}\n");     // while (!done)
+
+  printer->Outdent();
+  printer->Print(
+      "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+      "  throw e.setUnfinishedMessage(this);\n"
+      "} catch (java.io.IOException e) {\n"
+      "  throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+      "      e.getMessage()).setUnfinishedMessage(this);\n"
+      "} finally {\n");
+  printer->Indent();
+
+  // Make repeated field list immutable.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = sorted_fields[i];
+    field_generators_.get(field).GenerateParsingDoneCode(printer);
+  }
+
+  // Make unknown fields immutable.
+  if (UseUnknownFieldSet(descriptor_)) {
+    printer->Print(
+        "this.unknownFields = unknownFields.build();\n");
+  } else {
+    printer->Print(
+        "try {\n"
+        "  unknownFieldsCodedOutput.flush();\n"
+        "} catch (java.io.IOException e) {\n"
+        "// Should not happen\n"
+        "} finally {\n"
+        "  unknownFields = unknownFieldsOutput.toByteString();\n"
+        "}\n");
+  }
+
+  // Make extensions immutable.
+  printer->Print(
+      "makeExtensionsImmutable();\n");
+
+  printer->Outdent();
+  printer->Outdent();
+  printer->Print(
+      "  }\n"     // finally
+      "}\n");
+}
+
+// ===================================================================
+void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
+  printer->Print(
+      "public static com.google.protobuf.Parser<$classname$> PARSER =\n"
+      "    new com.google.protobuf.AbstractParser<$classname$>() {\n",
+      "classname", descriptor_->name());
+  printer->Indent();
+  printer->Print(
+      "public $classname$ parsePartialFrom(\n"
+      "    com.google.protobuf.CodedInputStream input,\n"
+      "    com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
+      "    throws com.google.protobuf.InvalidProtocolBufferException {\n",
+      "classname", descriptor_->name());
+  if (HasGeneratedMethods(descriptor_)) {
+    printer->Print(
+        "  return new $classname$(input, extensionRegistry);\n",
+        "classname", descriptor_->name());
+  } else {
+    // When parsing constructor isn't generated, use builder to parse messages.
+    // Note, will fallback to use reflection based mergeFieldFrom() in
+    // AbstractMessage.Builder.
+    printer->Indent();
+    printer->Print(
+        "Builder builder = newBuilder();\n"
+        "try {\n"
+        "  builder.mergeFrom(input, extensionRegistry);\n"
+        "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n"
+        "  throw e.setUnfinishedMessage(builder.buildPartial());\n"
+        "} catch (java.io.IOException e) {\n"
+        "  throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+        "      e.getMessage()).setUnfinishedMessage(builder.buildPartial());\n"
+        "}\n"
+        "return builder.buildPartial();\n");
+    printer->Outdent();
+  }
+  printer->Print(
+        "}\n");
+  printer->Outdent();
+  printer->Print(
+      "};\n"
+      "\n");
+
+  printer->Print(
+      "@java.lang.Override\n"
+      "public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
+      "  return PARSER;\n"
+      "}\n"
+      "\n",
+      "classname", descriptor_->name());
+}
+
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_message.h b/protobuf/src/google/protobuf/compiler/java/java_message.h
new file mode 100644
index 0000000..fece1c2
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_message.h
@@ -0,0 +1,140 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// 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 <map>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+  namespace compiler {
+    namespace java {
+      class Context;           // context.h
+      class ClassNameResolver; // name_resolver.h
+    }
+  }
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class MessageGenerator {
+ public:
+  explicit MessageGenerator(const Descriptor* descriptor);
+  virtual ~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.
+  virtual void GenerateStaticVariables(io::Printer* printer) = 0;
+
+  // Output code which initializes the static variables generated by
+  // GenerateStaticVariables().
+  virtual void GenerateStaticVariableInitializers(io::Printer* printer) = 0;
+
+  // Generate the class itself.
+  virtual void Generate(io::Printer* printer) = 0;
+
+  // Generates the base interface that both the class and its builder implement
+  virtual void GenerateInterface(io::Printer* printer) = 0;
+
+  // Generate code to register all contained extensions with an
+  // ExtensionRegistry.
+  virtual void GenerateExtensionRegistrationCode(io::Printer* printer) = 0;
+
+ protected:
+  const Descriptor* descriptor_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+class ImmutableMessageGenerator : public MessageGenerator {
+ public:
+  explicit ImmutableMessageGenerator(const Descriptor* descriptor,
+                                     Context* context);
+  virtual ~ImmutableMessageGenerator();
+
+  virtual void Generate(io::Printer* printer);
+  virtual void GenerateInterface(io::Printer* printer);
+  virtual void GenerateExtensionRegistrationCode(io::Printer* printer);
+  virtual void GenerateStaticVariables(io::Printer* printer);
+  virtual void GenerateStaticVariableInitializers(io::Printer* printer);
+
+ private:
+  enum UseMemoization {
+    MEMOIZE,
+    DONT_MEMOIZE
+  };
+
+  void GenerateFieldAccessorTable(io::Printer* printer);
+  void GenerateFieldAccessorTableInitializer(io::Printer* printer);
+
+  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 GenerateDescriptorMethods(io::Printer* printer);
+  void GenerateBuilderParsingMethods(io::Printer* printer);
+  void GenerateIsInitialized(io::Printer* printer,
+      UseMemoization useMemoization);
+  void GenerateEqualsAndHashCode(io::Printer* printer);
+  void GenerateParser(io::Printer* printer);
+  void GenerateParsingConstructor(io::Printer* printer);
+
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+  FieldGeneratorMap<ImmutableFieldGenerator> field_generators_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_message_field.cc b/protobuf/src/google/protobuf/compiler/java/java_message_field.cc
new file mode 100644
index 0000000..e681314
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_message_field.cc
@@ -0,0 +1,1343 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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_context.h>
+#include <google/protobuf/compiler/java/java_message_field.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.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 {
+
+void SetMessageVariables(const FieldDescriptor* descriptor,
+                         int messageBitIndex,
+                         int builderBitIndex,
+                         const FieldGeneratorInfo* info,
+                         ClassNameResolver* name_resolver,
+                         map<string, string>* variables) {
+  SetCommonFieldVariables(descriptor, info, variables);
+
+  (*variables)["type"] =
+      name_resolver->GetImmutableClassName(descriptor->message_type());
+  (*variables)["mutable_type"] =
+      name_resolver->GetMutableClassName(descriptor->message_type());
+  (*variables)["group_or_message"] =
+    (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ?
+    "Group" : "Message";
+  // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+  // by the proto compiler
+  (*variables)["deprecation"] = descriptor->options().deprecated()
+      ? "@java.lang.Deprecated " : "";
+  (*variables)["on_changed"] =
+      HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+  if (SupportFieldPresence(descriptor->file())) {
+    // For singular messages and builders, one bit is used for the hasField bit.
+    (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+    (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+    // Note that these have a trailing ";".
+    (*variables)["set_has_field_bit_message"] =
+        GenerateSetBit(messageBitIndex) + ";";
+    (*variables)["set_has_field_bit_builder"] =
+        GenerateSetBit(builderBitIndex) + ";";
+    (*variables)["clear_has_field_bit_builder"] =
+        GenerateClearBit(builderBitIndex) + ";";
+
+    (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+  } else {
+    (*variables)["set_has_field_bit_message"] = "";
+    (*variables)["set_has_field_bit_builder"] = "";
+    (*variables)["clear_has_field_bit_builder"] = "";
+
+    (*variables)["is_field_present_message"] =
+        (*variables)["name"] + "_ != null";
+  }
+
+  // For repated builders, one bit is used for whether the array is immutable.
+  (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+  (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+  (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+  // For repeated fields, one bit is used for whether the array is immutable
+  // in the parsing constructor.
+  (*variables)["get_mutable_bit_parser"] =
+      GenerateGetBitMutableLocal(builderBitIndex);
+  (*variables)["set_mutable_bit_parser"] =
+      GenerateSetBitMutableLocal(builderBitIndex);
+
+  (*variables)["get_has_field_bit_from_local"] =
+      GenerateGetBitFromLocal(builderBitIndex);
+  (*variables)["set_has_field_bit_to_local"] =
+      GenerateSetBitToLocal(messageBitIndex);
+}
+
+}  // namespace
+
+// ===================================================================
+
+ImmutableMessageFieldGenerator::
+ImmutableMessageFieldGenerator(const FieldDescriptor* descriptor,
+                      int messageBitIndex,
+                      int builderBitIndex,
+                      Context* context)
+  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+    builderBitIndex_(builderBitIndex), context_(context),
+    name_resolver_(context->GetNameResolver()) {
+    SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+                        context->GetFieldGeneratorInfo(descriptor),
+                        name_resolver_, &variables_);
+}
+
+ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
+
+int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
+  return 1;
+}
+
+int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
+  return 1;
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+  // TODO(jonp): In the future, consider having a method specific to the
+  // interface so that builders can choose dynamically to either return a
+  // message or a nested builder, so that asking for the interface doesn't
+  // cause a message to ever be built.
+  if (SupportFieldPresence(descriptor_->file()) ||
+      descriptor_->containing_oneof() == NULL) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$boolean has$capitalized_name$();\n");
+  }
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$$type$ get$capitalized_name$();\n");
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
+  }
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private $type$ $name$_;\n");
+  PrintExtraFieldInfo(variables_, printer);
+
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $get_has_field_bit_message$;\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$ get$capitalized_name$() {\n"
+      "  return $name$_;\n"
+      "}\n");
+
+    if (HasNestedBuilders(descriptor_->containing_type())) {
+      WriteFieldDocComment(printer, descriptor_);
+      printer->Print(variables_,
+        "$deprecation$public $type$OrBuilder "
+        "get$capitalized_name$OrBuilder() {\n"
+        "  return $name$_;\n"
+        "}\n");
+    }
+  } else {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $name$_ != null;\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$ get$capitalized_name$() {\n"
+      "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
+      "}\n");
+
+    if (HasNestedBuilders(descriptor_->containing_type())) {
+      WriteFieldDocComment(printer, descriptor_);
+      printer->Print(variables_,
+        "$deprecation$public $type$OrBuilder "
+        "get$capitalized_name$OrBuilder() {\n"
+        "  return get$capitalized_name$();\n"
+        "}\n");
+    }
+  }
+}
+
+void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
+    io::Printer* printer,
+    const char* regular_case,
+    const char* nested_builder_case) const {
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+     printer->Print(variables_, "if ($name$Builder_ == null) {\n");
+     printer->Indent();
+     printer->Print(variables_, regular_case);
+     printer->Outdent();
+     printer->Print("} else {\n");
+     printer->Indent();
+     printer->Print(variables_, nested_builder_case);
+     printer->Outdent();
+     printer->Print("}\n");
+   } else {
+     printer->Print(variables_, regular_case);
+   }
+}
+
+void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
+    io::Printer* printer,
+    const char* method_prototype,
+    const char* regular_case,
+    const char* nested_builder_case,
+    const char* trailing_code) const {
+  printer->Print(variables_, method_prototype);
+  printer->Print(" {\n");
+  printer->Indent();
+  PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
+  if (trailing_code != NULL) {
+    printer->Print(variables_, trailing_code);
+  }
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  // When using nested-builders, the code initially works just like the
+  // non-nested builder case. It only creates a nested builder lazily on
+  // demand and then forever delegates to it after creation.
+
+  bool support_field_presence = SupportFieldPresence(descriptor_->file());
+
+  if (support_field_presence) {
+    printer->Print(variables_,
+      // Used when the builder is null.
+      "private $type$ $name$_ = $type$.getDefaultInstance();\n");
+  } else {
+    printer->Print(variables_,
+      "private $type$ $name$_ = null;\n");
+  }
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      // If this builder is non-null, it is used and the other fields are
+      // ignored.
+      "private com.google.protobuf.SingleFieldBuilder<\n"
+      "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
+      "\n");
+  }
+
+  // The comments above the methods below are based on a hypothetical
+  // field of type "Field" called "Field".
+
+  // boolean hasField()
+  WriteFieldDocComment(printer, descriptor_);
+  if (support_field_presence) {
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $get_has_field_bit_builder$;\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $name$Builder_ != null || $name$_ != null;\n"
+      "}\n");
+  }
+
+  // Field getField()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public $type$ get$capitalized_name$()",
+
+    support_field_presence
+        ?  "return $name$_;\n"
+        : "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n",
+
+    "return $name$Builder_.getMessage();\n",
+
+    NULL);
+
+  // Field.Builder setField(Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$($type$ value)",
+
+    "if (value == null) {\n"
+    "  throw new NullPointerException();\n"
+    "}\n"
+    "$name$_ = value;\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.setMessage(value);\n",
+
+    "$set_has_field_bit_builder$\n"
+    "return this;\n");
+
+  // Field.Builder setField(Field.Builder builderForValue)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    $type$.Builder builderForValue)",
+
+    "$name$_ = builderForValue.build();\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.setMessage(builderForValue.build());\n",
+
+    "$set_has_field_bit_builder$\n"
+    "return this;\n");
+
+  // Field.Builder mergeField(Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder merge$capitalized_name$($type$ value)",
+
+    support_field_presence
+        ? "if ($get_has_field_bit_builder$ &&\n"
+          "    $name$_ != $type$.getDefaultInstance()) {\n"
+          "  $name$_ =\n"
+          "    $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
+          "} else {\n"
+          "  $name$_ = value;\n"
+          "}\n"
+          "$on_changed$\n"
+        : "if ($name$_ != null) {\n"
+          "  $name$_ =\n"
+          "    $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
+          "} else {\n"
+          "  $name$_ = value;\n"
+          "}\n"
+          "$on_changed$\n",
+
+    "$name$Builder_.mergeFrom(value);\n",
+
+    "$set_has_field_bit_builder$\n"
+    "return this;\n");
+
+  // Field.Builder clearField()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder clear$capitalized_name$()",
+
+    support_field_presence
+        ? "$name$_ = $type$.getDefaultInstance();\n"
+          "$on_changed$\n"
+        : "$name$_ = null;\n"
+          "$on_changed$\n",
+
+    support_field_presence
+        ? "$name$Builder_.clear();\n"
+        : "$name$_ = null;\n"
+          "$name$Builder_ = null;\n",
+
+    "$clear_has_field_bit_builder$\n"
+    "return this;\n");
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
+      "  $set_has_field_bit_builder$\n"
+      "  $on_changed$\n"
+      "  return get$capitalized_name$FieldBuilder().getBuilder();\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+      "  if ($name$Builder_ != null) {\n"
+      "    return $name$Builder_.getMessageOrBuilder();\n"
+      "  } else {\n");
+    if (support_field_presence) {
+      printer->Print(variables_,
+        "    return $name$_;\n");
+    } else {
+      printer->Print(variables_,
+        "    return $name$_ == null ?\n"
+        "        $type$.getDefaultInstance() : $name$_;\n");
+    }
+    printer->Print(variables_,
+      "  }\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "private com.google.protobuf.SingleFieldBuilder<\n"
+      "    $type$, $type$.Builder, $type$OrBuilder> \n"
+      "    get$capitalized_name$FieldBuilder() {\n"
+      "  if ($name$Builder_ == null) {\n"
+      "    $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
+      "        $type$, $type$.Builder, $type$OrBuilder>(\n"
+      "            get$capitalized_name$(),\n"
+      "            getParentForChildren(),\n"
+      "            isClean());\n"
+      "    $name$_ = null;\n"
+      "  }\n"
+      "  return $name$Builder_;\n"
+      "}\n");
+  }
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    printer->Print(variables_,
+      "get$capitalized_name$FieldBuilder();\n");
+  }
+}
+
+
+void ImmutableMessageFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    printer->Print(variables_, "$name$_ = $type$.getDefaultInstance();\n");
+  }
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    PrintNestedBuilderCondition(printer,
+      "$name$_ = $type$.getDefaultInstance();\n",
+
+      "$name$Builder_.clear();\n");
+    printer->Print(variables_, "$clear_has_field_bit_builder$\n");
+  } else {
+    PrintNestedBuilderCondition(printer,
+      "$name$_ = null;\n",
+
+      "$name$_ = null;\n"
+      "$name$Builder_ = null;\n");
+  }
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (other.has$capitalized_name$()) {\n"
+    "  merge$capitalized_name$(other.get$capitalized_name$());\n"
+    "}\n");
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    printer->Print(variables_,
+        "if ($get_has_field_bit_from_local$) {\n"
+        "  $set_has_field_bit_to_local$;\n"
+        "}\n");
+  }
+
+  PrintNestedBuilderCondition(printer,
+    "result.$name$_ = $name$_;\n",
+
+    "result.$name$_ = $name$Builder_.build();\n");
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$type$.Builder subBuilder = null;\n"
+    "if ($is_field_present_message$) {\n"
+    "  subBuilder = $name$_.toBuilder();\n"
+    "}\n");
+
+  if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
+    printer->Print(variables_,
+      "$name$_ = input.readGroup($number$, $type$.PARSER,\n"
+      "    extensionRegistry);\n");
+  } else {
+    printer->Print(variables_,
+      "$name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+  }
+
+  printer->Print(variables_,
+    "if (subBuilder != null) {\n"
+    "  subBuilder.mergeFrom($name$_);\n"
+    "  $name$_ = subBuilder.buildPartial();\n"
+    "}\n"
+    "$set_has_field_bit_message$\n");
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+  // noop for messages.
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($is_field_present_message$) {\n"
+    "  output.write$group_or_message$($number$, $name$_);\n"
+    "}\n");
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($is_field_present_message$) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .compute$group_or_message$Size($number$, $name$_);\n"
+    "}\n");
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = result && get$capitalized_name$()\n"
+    "    .equals(other.get$capitalized_name$());\n");
+}
+
+void ImmutableMessageFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "hash = (37 * hash) + $constant_name$;\n"
+    "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+}
+
+string ImmutableMessageFieldGenerator::GetBoxedType() const {
+  return name_resolver_->GetImmutableClassName(descriptor_->message_type());
+}
+
+// ===================================================================
+
+ImmutableMessageOneofFieldGenerator::
+ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                 int messageBitIndex,
+                                 int builderBitIndex,
+                                 Context* context)
+    : ImmutableMessageFieldGenerator(
+          descriptor, messageBitIndex, builderBitIndex, context) {
+  const OneofGeneratorInfo* info =
+      context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+  SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableMessageOneofFieldGenerator::
+~ImmutableMessageOneofFieldGenerator() {}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  PrintExtraFieldInfo(variables_, printer);
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $has_oneof_case_message$;\n"
+      "}\n");
+  }
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "     return ($type$) $oneof_name$_;\n"
+    "  }\n"
+    "  return $type$.getDefaultInstance();\n"
+    "}\n");
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+      "  if ($has_oneof_case_message$) {\n"
+      "     return ($type$) $oneof_name$_;\n"
+      "  }\n"
+      "  return $type$.getDefaultInstance();\n"
+      "}\n");
+  }
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  // When using nested-builders, the code initially works just like the
+  // non-nested builder case. It only creates a nested builder lazily on
+  // demand and then forever delegates to it after creation.
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      // If this builder is non-null, it is used and the other fields are
+      // ignored.
+      "private com.google.protobuf.SingleFieldBuilder<\n"
+      "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
+      "\n");
+  }
+
+  // The comments above the methods below are based on a hypothetical
+  // field of type "Field" called "Field".
+
+  if (SupportFieldPresence(descriptor_->file())) {
+    // boolean hasField()
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $has_oneof_case_message$;\n"
+      "}\n");
+  }
+
+  // Field getField()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public $type$ get$capitalized_name$()",
+
+    "if ($has_oneof_case_message$) {\n"
+    "  return ($type$) $oneof_name$_;\n"
+    "}\n"
+    "return $type$.getDefaultInstance();\n",
+
+    "if ($has_oneof_case_message$) {\n"
+    "  return $name$Builder_.getMessage();\n"
+    "}\n"
+    "return $type$.getDefaultInstance();\n",
+
+    NULL);
+
+  // Field.Builder setField(Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$($type$ value)",
+
+    "if (value == null) {\n"
+    "  throw new NullPointerException();\n"
+    "}\n"
+    "$oneof_name$_ = value;\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.setMessage(value);\n",
+
+    "$set_oneof_case_message$;\n"
+    "return this;\n");
+
+  // Field.Builder setField(Field.Builder builderForValue)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    $type$.Builder builderForValue)",
+
+    "$oneof_name$_ = builderForValue.build();\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.setMessage(builderForValue.build());\n",
+
+    "$set_oneof_case_message$;\n"
+    "return this;\n");
+
+  // Field.Builder mergeField(Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder merge$capitalized_name$($type$ value)",
+
+    "if ($has_oneof_case_message$ &&\n"
+    "    $oneof_name$_ != $type$.getDefaultInstance()) {\n"
+    "  $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
+    "      .mergeFrom(value).buildPartial();\n"
+    "} else {\n"
+    "  $oneof_name$_ = value;\n"
+    "}\n"
+    "$on_changed$\n",
+
+    "if ($has_oneof_case_message$) {\n"
+    "  $name$Builder_.mergeFrom(value);\n"
+    "}\n"
+    "$name$Builder_.setMessage(value);\n",
+
+    "$set_oneof_case_message$;\n"
+    "return this;\n");
+
+  // Field.Builder clearField()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder clear$capitalized_name$()",
+
+    "if ($has_oneof_case_message$) {\n"
+    "  $clear_oneof_case_message$;\n"
+    "  $oneof_name$_ = null;\n"
+    "  $on_changed$\n"
+    "}\n",
+
+    "if ($has_oneof_case_message$) {\n"
+    "  $clear_oneof_case_message$;\n"
+    "  $oneof_name$_ = null;\n"
+    "}\n"
+    "$name$Builder_.clear();\n",
+
+    "return this;\n");
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n"
+      "  return get$capitalized_name$FieldBuilder().getBuilder();\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n"
+      "  if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n"
+      "    return $name$Builder_.getMessageOrBuilder();\n"
+      "  } else {\n"
+      "    if ($has_oneof_case_message$) {\n"
+      "      return ($type$) $oneof_name$_;\n"
+      "    }\n"
+      "    return $type$.getDefaultInstance();\n"
+      "  }\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "private com.google.protobuf.SingleFieldBuilder<\n"
+      "    $type$, $type$.Builder, $type$OrBuilder> \n"
+      "    get$capitalized_name$FieldBuilder() {\n"
+      "  if ($name$Builder_ == null) {\n"
+      "    if (!($has_oneof_case_message$)) {\n"
+      "      $oneof_name$_ = $type$.getDefaultInstance();\n"
+      "    }\n"
+      "    $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n"
+      "        $type$, $type$.Builder, $type$OrBuilder>(\n"
+      "            ($type$) $oneof_name$_,\n"
+      "            getParentForChildren(),\n"
+      "            isClean());\n"
+      "    $oneof_name$_ = null;\n"
+      "  }\n"
+      "  $set_oneof_case_message$;\n"
+      "  return $name$Builder_;\n"
+      "}\n");
+  }
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+
+  printer->Print(variables_,
+                 "if ($has_oneof_case_message$) {\n");
+  printer->Indent();
+
+  PrintNestedBuilderCondition(printer,
+    "result.$oneof_name$_ = $oneof_name$_;\n",
+
+    "result.$oneof_name$_ = $name$Builder_.build();\n");
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "merge$capitalized_name$(other.get$capitalized_name$());\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$type$.Builder subBuilder = null;\n"
+    "if ($has_oneof_case_message$) {\n"
+    "  subBuilder = (($type$) $oneof_name$_).toBuilder();\n"
+    "}\n");
+
+  if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
+    printer->Print(variables_,
+      "$oneof_name$_ = input.readGroup($number$, $type$.PARSER,\n"
+      "    extensionRegistry);\n");
+  } else {
+    printer->Print(variables_,
+      "$oneof_name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+  }
+
+  printer->Print(variables_,
+    "if (subBuilder != null) {\n"
+    "  subBuilder.mergeFrom(($type$) $oneof_name$_);\n"
+    "  $oneof_name$_ = subBuilder.buildPartial();\n"
+    "}\n");
+  printer->Print(variables_,
+    "$set_oneof_case_message$;\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
+    "}\n");
+}
+
+void ImmutableMessageOneofFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
+    "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutableMessageFieldGenerator::
+RepeatedImmutableMessageFieldGenerator(const FieldDescriptor* descriptor,
+                                       int messageBitIndex,
+                                       int builderBitIndex,
+                                       Context* context)
+  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+    builderBitIndex_(builderBitIndex), context_(context),
+    name_resolver_(context->GetNameResolver())  {
+  SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
+                      context->GetFieldGeneratorInfo(descriptor),
+                      name_resolver_, &variables_);
+}
+
+RepeatedImmutableMessageFieldGenerator::
+~RepeatedImmutableMessageFieldGenerator() {}
+
+int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
+  return 0;
+}
+
+int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
+  return 1;
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+  // TODO(jonp): In the future, consider having methods specific to the
+  // interface so that builders can choose dynamically to either return a
+  // message or a nested builder, so that asking for the interface doesn't
+  // cause a message to ever be built.
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$java.util.List<$type$> \n"
+    "    get$capitalized_name$List();\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$$type$ get$capitalized_name$(int index);\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$int get$capitalized_name$Count();\n");
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
+      "    get$capitalized_name$OrBuilderList();\n");
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
+      "    int index);\n");
+  }
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private java.util.List<$type$> $name$_;\n");
+  PrintExtraFieldInfo(variables_, printer);
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
+    "  return $name$_;\n"   // note:  unmodifiable list
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+    "    get$capitalized_name$OrBuilderList() {\n"
+    "  return $name$_;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public int get$capitalized_name$Count() {\n"
+    "  return $name$_.size();\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+    "    int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+
+}
+
+void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
+    io::Printer* printer,
+    const char* regular_case,
+    const char* nested_builder_case) const {
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+     printer->Print(variables_, "if ($name$Builder_ == null) {\n");
+     printer->Indent();
+     printer->Print(variables_, regular_case);
+     printer->Outdent();
+     printer->Print("} else {\n");
+     printer->Indent();
+     printer->Print(variables_, nested_builder_case);
+     printer->Outdent();
+     printer->Print("}\n");
+   } else {
+     printer->Print(variables_, regular_case);
+   }
+}
+
+void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
+    io::Printer* printer,
+    const char* method_prototype,
+    const char* regular_case,
+    const char* nested_builder_case,
+    const char* trailing_code) const {
+  printer->Print(variables_, method_prototype);
+  printer->Print(" {\n");
+  printer->Indent();
+  PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
+  if (trailing_code != NULL) {
+    printer->Print(variables_, trailing_code);
+  }
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  // When using nested-builders, the code initially works just like the
+  // non-nested builder case. It only creates a nested builder lazily on
+  // demand and then forever delegates to it after creation.
+
+  printer->Print(variables_,
+    // Used when the builder is null.
+    // One field is the list and the other field keeps track of whether the
+    // list is immutable. If it's immutable, the invariant is that it must
+    // either an instance of Collections.emptyList() or it's an ArrayList
+    // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+    // a refererence to the underlying ArrayList. This invariant allows us to
+    // share instances of lists between protocol buffers avoiding expensive
+    // memory allocations. Note, immutable is a strong guarantee here -- not
+    // just that the list cannot be modified via the reference but that the
+    // list can never be modified.
+    "private java.util.List<$type$> $name$_ =\n"
+    "  java.util.Collections.emptyList();\n"
+
+    "private void ensure$capitalized_name$IsMutable() {\n"
+    "  if (!$get_mutable_bit_builder$) {\n"
+    "    $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
+    "    $set_mutable_bit_builder$;\n"
+    "   }\n"
+    "}\n"
+    "\n");
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      // If this builder is non-null, it is used and the other fields are
+      // ignored.
+      "private com.google.protobuf.RepeatedFieldBuilder<\n"
+      "    $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
+      "\n");
+  }
+
+  // The comments above the methods below are based on a hypothetical
+  // repeated field of type "Field" called "RepeatedField".
+
+  // List<Field> getRepeatedFieldList()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public java.util.List<$type$> get$capitalized_name$List()",
+
+    "return java.util.Collections.unmodifiableList($name$_);\n",
+    "return $name$Builder_.getMessageList();\n",
+
+    NULL);
+
+  // int getRepeatedFieldCount()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public int get$capitalized_name$Count()",
+
+    "return $name$_.size();\n",
+    "return $name$Builder_.getCount();\n",
+
+    NULL);
+
+  // Field getRepeatedField(int index)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public $type$ get$capitalized_name$(int index)",
+
+    "return $name$_.get(index);\n",
+
+    "return $name$Builder_.getMessage(index);\n",
+
+    NULL);
+
+  // Builder setRepeatedField(int index, Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    int index, $type$ value)",
+    "if (value == null) {\n"
+    "  throw new NullPointerException();\n"
+    "}\n"
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.set(index, value);\n"
+    "$on_changed$\n",
+    "$name$Builder_.setMessage(index, value);\n",
+    "return this;\n");
+
+  // Builder setRepeatedField(int index, Field.Builder builderForValue)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    int index, $type$.Builder builderForValue)",
+
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.set(index, builderForValue.build());\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.setMessage(index, builderForValue.build());\n",
+
+    "return this;\n");
+
+  // Builder addRepeatedField(Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder add$capitalized_name$($type$ value)",
+
+    "if (value == null) {\n"
+    "  throw new NullPointerException();\n"
+    "}\n"
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.add(value);\n"
+
+    "$on_changed$\n",
+
+    "$name$Builder_.addMessage(value);\n",
+
+    "return this;\n");
+
+  // Builder addRepeatedField(int index, Field value)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder add$capitalized_name$(\n"
+    "    int index, $type$ value)",
+
+    "if (value == null) {\n"
+    "  throw new NullPointerException();\n"
+    "}\n"
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.add(index, value);\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.addMessage(index, value);\n",
+
+    "return this;\n");
+
+  // Builder addRepeatedField(Field.Builder builderForValue)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder add$capitalized_name$(\n"
+    "    $type$.Builder builderForValue)",
+
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.add(builderForValue.build());\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.addMessage(builderForValue.build());\n",
+
+    "return this;\n");
+
+  // Builder addRepeatedField(int index, Field.Builder builderForValue)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder add$capitalized_name$(\n"
+    "    int index, $type$.Builder builderForValue)",
+
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.add(index, builderForValue.build());\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.addMessage(index, builderForValue.build());\n",
+
+    "return this;\n");
+
+  // Builder addAllRepeatedField(Iterable<Field> values)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder addAll$capitalized_name$(\n"
+    "    java.lang.Iterable<? extends $type$> values)",
+
+    "ensure$capitalized_name$IsMutable();\n"
+    "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+    "    values, $name$_);\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.addAllMessages(values);\n",
+
+    "return this;\n");
+
+  // Builder clearAllRepeatedField()
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder clear$capitalized_name$()",
+
+    "$name$_ = java.util.Collections.emptyList();\n"
+    "$clear_mutable_bit_builder$;\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.clear();\n",
+
+    "return this;\n");
+
+  // Builder removeRepeatedField(int index)
+  WriteFieldDocComment(printer, descriptor_);
+  PrintNestedBuilderFunction(printer,
+    "$deprecation$public Builder remove$capitalized_name$(int index)",
+
+    "ensure$capitalized_name$IsMutable();\n"
+    "$name$_.remove(index);\n"
+    "$on_changed$\n",
+
+    "$name$Builder_.remove(index);\n",
+
+    "return this;\n");
+
+  if (HasNestedBuilders(descriptor_->containing_type())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public $type$.Builder get$capitalized_name$Builder(\n"
+      "    int index) {\n"
+      "  return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
+      "}\n");
+
+    WriteFieldDocComment(printer, descriptor_);
+        printer->Print(variables_,
+      "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
+      "    int index) {\n"
+      "  if ($name$Builder_ == null) {\n"
+      "    return $name$_.get(index);"
+      "  } else {\n"
+      "    return $name$Builder_.getMessageOrBuilder(index);\n"
+      "  }\n"
+      "}\n");
+
+    WriteFieldDocComment(printer, descriptor_);
+        printer->Print(variables_,
+      "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
+      "     get$capitalized_name$OrBuilderList() {\n"
+      "  if ($name$Builder_ != null) {\n"
+      "    return $name$Builder_.getMessageOrBuilderList();\n"
+      "  } else {\n"
+      "    return java.util.Collections.unmodifiableList($name$_);\n"
+      "  }\n"
+      "}\n");
+
+    WriteFieldDocComment(printer, descriptor_);
+        printer->Print(variables_,
+      "$deprecation$public $type$.Builder add$capitalized_name$Builder() {\n"
+      "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
+      "      $type$.getDefaultInstance());\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+        printer->Print(variables_,
+      "$deprecation$public $type$.Builder add$capitalized_name$Builder(\n"
+      "    int index) {\n"
+      "  return get$capitalized_name$FieldBuilder().addBuilder(\n"
+      "      index, $type$.getDefaultInstance());\n"
+      "}\n");
+    WriteFieldDocComment(printer, descriptor_);
+        printer->Print(variables_,
+      "$deprecation$public java.util.List<$type$.Builder> \n"
+      "     get$capitalized_name$BuilderList() {\n"
+      "  return get$capitalized_name$FieldBuilder().getBuilderList();\n"
+      "}\n"
+      "private com.google.protobuf.RepeatedFieldBuilder<\n"
+      "    $type$, $type$.Builder, $type$OrBuilder> \n"
+      "    get$capitalized_name$FieldBuilder() {\n"
+      "  if ($name$Builder_ == null) {\n"
+      "    $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\n"
+      "        $type$, $type$.Builder, $type$OrBuilder>(\n"
+      "            $name$_,\n"
+      "            $get_mutable_bit_builder$,\n"
+      "            getParentForChildren(),\n"
+      "            isClean());\n"
+      "    $name$_ = null;\n"
+      "  }\n"
+      "  return $name$Builder_;\n"
+      "}\n");
+  }
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
+  printer->Print(variables_,
+    "get$capitalized_name$FieldBuilder();\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+  PrintNestedBuilderCondition(printer,
+    "$name$_ = java.util.Collections.emptyList();\n"
+    "$clear_mutable_bit_builder$;\n",
+
+    "$name$Builder_.clear();\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  // The code below does two optimizations (non-nested builder case):
+  //   1. If the other list is empty, there's nothing to do. This ensures we
+  //      don't allocate a new array if we already have an immutable one.
+  //   2. If the other list is non-empty and our current list is empty, we can
+  //      reuse the other list which is guaranteed to be immutable.
+  PrintNestedBuilderCondition(printer,
+    "if (!other.$name$_.isEmpty()) {\n"
+    "  if ($name$_.isEmpty()) {\n"
+    "    $name$_ = other.$name$_;\n"
+    "    $clear_mutable_bit_builder$;\n"
+    "  } else {\n"
+    "    ensure$capitalized_name$IsMutable();\n"
+    "    $name$_.addAll(other.$name$_);\n"
+    "  }\n"
+    "  $on_changed$\n"
+    "}\n",
+
+    "if (!other.$name$_.isEmpty()) {\n"
+    "  if ($name$Builder_.isEmpty()) {\n"
+    "    $name$Builder_.dispose();\n"
+    "    $name$Builder_ = null;\n"
+    "    $name$_ = other.$name$_;\n"
+    "    $clear_mutable_bit_builder$;\n"
+    "    $name$Builder_ = \n"
+    "      com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?\n"
+    "         get$capitalized_name$FieldBuilder() : null;\n"
+    "  } else {\n"
+    "    $name$Builder_.addAllMessages(other.$name$_);\n"
+    "  }\n"
+    "}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  // The code below (non-nested builder case) ensures that the result has an
+  // immutable list. If our list is immutable, we can just reuse it. If not,
+  // we make it immutable.
+  PrintNestedBuilderCondition(printer,
+    "if ($get_mutable_bit_builder$) {\n"
+    "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+    "  $clear_mutable_bit_builder$;\n"
+    "}\n"
+    "result.$name$_ = $name$_;\n",
+
+    "result.$name$_ = $name$Builder_.build();\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!$get_mutable_bit_parser$) {\n"
+    "  $name$_ = new java.util.ArrayList<$type$>();\n"
+    "  $set_mutable_bit_parser$;\n"
+    "}\n");
+
+  if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
+    printer->Print(variables_,
+      "$name$_.add(input.readGroup($number$, $type$.PARSER,\n"
+      "    extensionRegistry));\n");
+  } else {
+    printer->Print(variables_,
+      "$name$_.add(input.readMessage($type$.PARSER, extensionRegistry));\n");
+  }
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($get_mutable_bit_parser$) {\n"
+    "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+    "}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for (int i = 0; i < $name$_.size(); i++) {\n"
+    "  output.write$group_or_message$($number$, $name$_.get(i));\n"
+    "}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "for (int i = 0; i < $name$_.size(); i++) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .compute$group_or_message$Size($number$, $name$_.get(i));\n"
+    "}\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = result && get$capitalized_name$List()\n"
+    "    .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedImmutableMessageFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (get$capitalized_name$Count() > 0) {\n"
+    "  hash = (37 * hash) + $constant_name$;\n"
+    "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+    "}\n");
+}
+
+string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const {
+  return name_resolver_->GetImmutableClassName(descriptor_->message_type());
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_message_field.h b/protobuf/src/google/protobuf/compiler/java/java_message_field.h
new file mode 100644
index 0000000..ea8225a
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_message_field.h
@@ -0,0 +1,173 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 Context;           // context.h
+      class ClassNameResolver; // name_resolver.h
+    }
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
+ public:
+  explicit ImmutableMessageFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~ImmutableMessageFieldGenerator();
+
+  // implements ImmutableFieldGenerator ---------------------------------------
+  int GetNumBitsForMessage() const;
+  int GetNumBitsForBuilder() const;
+  void GenerateInterfaceMembers(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateInitializationCode(io::Printer* printer) const;
+  void GenerateBuilderClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateParsingDoneCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ protected:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  const int messageBitIndex_;
+  const int builderBitIndex_;
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+
+  void PrintNestedBuilderCondition(io::Printer* printer,
+      const char* regular_case, const char* nested_builder_case) const;
+  void PrintNestedBuilderFunction(io::Printer* printer,
+      const char* method_prototype, const char* regular_case,
+      const char* nested_builder_case,
+      const char* trailing_code) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldGenerator);
+};
+
+class ImmutableMessageOneofFieldGenerator
+    : public ImmutableMessageFieldGenerator {
+ public:
+  ImmutableMessageOneofFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~ImmutableMessageOneofFieldGenerator();
+
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldGenerator);
+};
+
+class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator {
+ public:
+  explicit RepeatedImmutableMessageFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~RepeatedImmutableMessageFieldGenerator();
+
+  // implements ImmutableFieldGenerator ---------------------------------------
+  int GetNumBitsForMessage() const;
+  int GetNumBitsForBuilder() const;
+  void GenerateInterfaceMembers(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateInitializationCode(io::Printer* printer) const;
+  void GenerateBuilderClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateParsingDoneCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ protected:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  const int messageBitIndex_;
+  const int builderBitIndex_;
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+
+  void PrintNestedBuilderCondition(io::Printer* printer,
+      const char* regular_case, const char* nested_builder_case) const;
+  void PrintNestedBuilderFunction(io::Printer* printer,
+      const char* method_prototype, const char* regular_case,
+      const char* nested_builder_case,
+      const char* trailing_code) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableMessageFieldGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_name_resolver.cc b/protobuf/src/google/protobuf/compiler/java/java_name_resolver.cc
new file mode 100644
index 0000000..0c363f9
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_name_resolver.cc
@@ -0,0 +1,266 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+// A suffix that will be appended to the file's outer class name if the name
+// conflicts with some other types defined in the file.
+const char* kOuterClassNameSuffix = "OuterClass";
+
+// Strip package name from a descriptor's full name.
+// For example:
+//   Full name   : foo.Bar.Baz
+//   Package name: foo
+//   After strip : Bar.Baz
+string StripPackageName(const string& full_name,
+                        const FileDescriptor* file) {
+  if (file->package().empty()) {
+    return full_name;
+  } else {
+    // Strip package name
+    return full_name.substr(file->package().size() + 1);
+  }
+}
+
+// Get the name of a message's Java class without package name prefix.
+string ClassNameWithoutPackage(const Descriptor* descriptor,
+                               bool immutable) {
+  return StripPackageName(descriptor->full_name(),
+                          descriptor->file());
+}
+
+// Get the name of an enum's Java class without package name prefix.
+string ClassNameWithoutPackage(const EnumDescriptor* descriptor,
+                               bool immutable) {
+  // Doesn't append "Mutable" for enum type's name.
+  const Descriptor* message_descriptor = descriptor->containing_type();
+  if (message_descriptor == NULL) {
+    return descriptor->name();
+  } else {
+    return ClassNameWithoutPackage(message_descriptor, immutable) +
+           "." + descriptor->name();
+  }
+}
+
+// Get the name of a service's Java class without package name prefix.
+string ClassNameWithoutPackage(const ServiceDescriptor* descriptor,
+                               bool immutable) {
+  string full_name = StripPackageName(descriptor->full_name(),
+                                      descriptor->file());
+  // We don't allow nested service definitions.
+  GOOGLE_CHECK(full_name.find('.') == string::npos);
+  return full_name;
+}
+
+// Check whether a given message or its nested types has the given class name.
+bool MessageHasConflictingClassName(const Descriptor* message,
+                                    const string& classname) {
+  if (message->name() == classname) return true;
+  for (int i = 0; i < message->nested_type_count(); ++i) {
+    if (MessageHasConflictingClassName(message->nested_type(i), classname)) {
+      return true;
+    }
+  }
+  for (int i = 0; i < message->enum_type_count(); ++i) {
+    if (message->enum_type(i)->name() == classname) {
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace
+
+ClassNameResolver::ClassNameResolver() {
+}
+
+ClassNameResolver::~ClassNameResolver() {
+}
+
+string ClassNameResolver::GetFileDefaultImmutableClassName(
+    const FileDescriptor* file) {
+  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 UnderscoresToCamelCase(StripProto(basename), true);
+}
+
+string ClassNameResolver::GetFileImmutableClassName(
+    const FileDescriptor* file) {
+  string& class_name = file_immutable_outer_class_names_[file];
+  if (class_name.empty()) {
+    if (file->options().has_java_outer_classname()) {
+      class_name = file->options().java_outer_classname();
+    } else {
+      class_name = GetFileDefaultImmutableClassName(file);
+      if (HasConflictingClassName(file, class_name)) {
+        class_name += kOuterClassNameSuffix;
+      }
+    }
+  }
+  return class_name;
+}
+
+string ClassNameResolver::GetFileClassName(const FileDescriptor* file,
+                                           bool immutable) {
+  if (immutable) {
+    return GetFileImmutableClassName(file);
+  } else {
+    return "Mutable" + GetFileImmutableClassName(file);
+  }
+}
+
+// Check whether there is any type defined in the proto file that has
+// the given class name.
+bool ClassNameResolver::HasConflictingClassName(
+    const FileDescriptor* file, const string& classname) {
+  for (int i = 0; i < file->enum_type_count(); i++) {
+    if (file->enum_type(i)->name() == classname) {
+      return true;
+    }
+  }
+  for (int i = 0; i < file->service_count(); i++) {
+    if (file->service(i)->name() == classname) {
+      return true;
+    }
+  }
+  for (int i = 0; i < file->message_type_count(); i++) {
+    if (MessageHasConflictingClassName(file->message_type(i), classname)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+string ClassNameResolver::GetDescriptorClassName(
+    const FileDescriptor* descriptor) {
+  return GetFileImmutableClassName(descriptor);
+}
+
+string ClassNameResolver::GetClassName(const FileDescriptor* descriptor,
+                                       bool immutable) {
+  string result = FileJavaPackage(descriptor, immutable);
+  if (!result.empty()) result += '.';
+  result += GetFileClassName(descriptor, immutable);
+  return result;
+}
+
+// Get the full name of a Java class by prepending the Java package name
+// or outer class name.
+string ClassNameResolver::GetClassFullName(const string& name_without_package,
+                                           const FileDescriptor* file,
+                                           bool immutable,
+                                           bool multiple_files) {
+  string result;
+  if (multiple_files) {
+    result = FileJavaPackage(file, immutable);
+  } else {
+    result = GetClassName(file, immutable);
+  }
+  if (!result.empty()) {
+    result += '.';
+  }
+  result += name_without_package;
+  return result;
+}
+
+string ClassNameResolver::GetClassName(const Descriptor* descriptor,
+                                       bool immutable) {
+  return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
+                          descriptor->file(), immutable,
+                          MultipleJavaFiles(descriptor->file(), immutable));
+}
+
+string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor,
+                                       bool immutable) {
+  return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
+                          descriptor->file(), immutable,
+                          MultipleJavaFiles(descriptor->file(), immutable));
+}
+
+string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor,
+                                       bool immutable) {
+  return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable),
+                          descriptor->file(), immutable,
+                          MultipleJavaFiles(descriptor->file(), immutable));
+}
+
+// Get the Java Class style full name of a message.
+string ClassNameResolver::GetJavaClassFullName(
+    const string& name_without_package,
+    const FileDescriptor* file,
+    bool immutable) {
+  string result;
+  if (MultipleJavaFiles(file, immutable)) {
+    result = FileJavaPackage(file, immutable);
+    if (!result.empty()) result += '.';
+  } else {
+    result = GetClassName(file, immutable);
+    if (!result.empty()) result += '$';
+  }
+  result += StringReplace(name_without_package, ".", "$", true);
+  return result;
+}
+
+string ClassNameResolver::GetExtensionIdentifierName(
+    const FieldDescriptor* descriptor, bool immutable) {
+  return GetClassName(descriptor->containing_type(), immutable) + "." +
+         descriptor->name();
+}
+
+
+string ClassNameResolver::GetJavaImmutableClassName(
+    const Descriptor* descriptor) {
+  return GetJavaClassFullName(
+      ClassNameWithoutPackage(descriptor, true),
+      descriptor->file(), true);
+}
+
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_name_resolver.h b/protobuf/src/google/protobuf/compiler/java/java_name_resolver.h
new file mode 100644
index 0000000..ab60b0a
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_name_resolver.h
@@ -0,0 +1,124 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+class Descriptor;
+class EnumDescriptor;
+class FieldDescriptor;
+class FileDescriptor;
+class ServiceDescriptor;
+
+namespace compiler {
+namespace java {
+
+// Used to get the Java class related names for a given descriptor. It caches
+// the results to avoid redundant calculation across multiple name queries.
+// Thread-safety note: This class is *not* thread-safe.
+class ClassNameResolver {
+ public:
+  ClassNameResolver();
+  ~ClassNameResolver();
+
+  // Gets the unqualified outer class name for the file.
+  string GetFileClassName(const FileDescriptor* file, bool immutable);
+  // Gets the unqualified immutable outer class name of a file.
+  string GetFileImmutableClassName(const FileDescriptor* file);
+  // Gets the unqualified default immutable outer class name of a file
+  // (converted from the proto file's name).
+  string GetFileDefaultImmutableClassName(const FileDescriptor* file);
+
+  // Check whether there is any type defined in the proto file that has
+  // the given class name.
+  bool HasConflictingClassName(const FileDescriptor* file,
+                               const string& classname);
+
+  // Gets the name of the outer class that holds descriptor information.
+  // Descriptors are shared between immutable messages and mutable messages.
+  // Since both of them are generated optionally, the descriptors need to be
+  // put in another common place.
+  string GetDescriptorClassName(const FileDescriptor* file);
+
+  // Gets the fully-qualified class name corresponding to the given descriptor.
+  string GetClassName(const Descriptor* descriptor, bool immutable);
+  string GetClassName(const EnumDescriptor* descriptor, bool immutable);
+  string GetClassName(const ServiceDescriptor* descriptor, bool immutable);
+  string GetClassName(const FileDescriptor* descriptor, bool immutable);
+
+  template<class DescriptorType>
+  string GetImmutableClassName(const DescriptorType* descriptor) {
+    return GetClassName(descriptor, true);
+  }
+  template<class DescriptorType>
+  string GetMutableClassName(const DescriptorType* descriptor) {
+    return GetClassName(descriptor, false);
+  }
+
+  // Gets the fully qualified name of an extension identifier.
+  string GetExtensionIdentifierName(const FieldDescriptor* descriptor,
+                                    bool immutable);
+
+  // Gets the fully qualified name for generated classes in Java convention.
+  // Nested classes will be separated using '$' instead of '.'
+  // For example:
+  //   com.package.OuterClass$OuterMessage$InnerMessage
+  string GetJavaImmutableClassName(const Descriptor* descriptor);
+ private:
+  // Get the full name of a Java class by prepending the Java package name
+  // or outer class name.
+  string GetClassFullName(const string& name_without_package,
+                          const FileDescriptor* file,
+                          bool immutable,
+                          bool multiple_files);
+  // Get the Java Class style full name of a message.
+  string GetJavaClassFullName(
+      const string& name_without_package,
+      const FileDescriptor* file,
+      bool immutable);
+  // Caches the result to provide better performance.
+  map<const FileDescriptor*, string> file_immutable_outer_class_names_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ClassNameResolver);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc b/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc
new file mode 100644
index 0000000..c4d6995
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_plugin_unittest.cc
@@ -0,0 +1,124 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// TODO(kenton):  Share code with the versions of this test in other languages?
+//   It seemed like parameterizing it would add more complexity than it is
+//   worth.
+
+#include <memory>
+
+#include <google/protobuf/compiler/java/java_generator.h>
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/printer.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/testing/file.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+namespace {
+
+class TestGenerator : public CodeGenerator {
+ public:
+  TestGenerator() {}
+  ~TestGenerator() {}
+
+  virtual bool Generate(const FileDescriptor* file,
+                        const string& parameter,
+                        GeneratorContext* context,
+                        string* error) const {
+    string filename = "Test.java";
+    TryInsert(filename, "outer_class_scope", context);
+    TryInsert(filename, "class_scope:foo.Bar", context);
+    TryInsert(filename, "class_scope:foo.Bar.Baz", context);
+    TryInsert(filename, "builder_scope:foo.Bar", context);
+    TryInsert(filename, "builder_scope:foo.Bar.Baz", context);
+    TryInsert(filename, "enum_scope:foo.Qux", context);
+    return true;
+  }
+
+  void TryInsert(const string& filename, const string& insertion_point,
+                 GeneratorContext* context) const {
+    scoped_ptr<io::ZeroCopyOutputStream> output(
+        context->OpenForInsert(filename, insertion_point));
+    io::Printer printer(output.get(), '$');
+    printer.Print("// inserted $name$\n", "name", insertion_point);
+  }
+};
+
+// This test verifies that all the expected insertion points exist.  It does
+// not verify that they are correctly-placed; that would require actually
+// compiling the output which is a bit more than I care to do for this test.
+TEST(JavaPluginTest, PluginTest) {
+  GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto",
+                             "syntax = \"proto2\";\n"
+                             "package foo;\n"
+                             "option java_package = \"\";\n"
+                             "option java_outer_classname = \"Test\";\n"
+                             "message Bar {\n"
+                             "  message Baz {}\n"
+                             "}\n"
+                             "enum Qux { BLAH = 1; }\n",
+                             true));
+
+  google::protobuf::compiler::CommandLineInterface cli;
+  cli.SetInputsAreProtoPathRelative(true);
+
+  JavaGenerator java_generator;
+  TestGenerator test_generator;
+  cli.RegisterGenerator("--java_out", &java_generator, "");
+  cli.RegisterGenerator("--test_out", &test_generator, "");
+
+  string proto_path = "-I" + TestTempDir();
+  string java_out = "--java_out=" + TestTempDir();
+  string test_out = "--test_out=" + TestTempDir();
+
+  const char* argv[] = {
+    "protoc",
+    proto_path.c_str(),
+    java_out.c_str(),
+    test_out.c_str(),
+    "test.proto"
+  };
+
+  EXPECT_EQ(0, cli.Run(5, argv));
+}
+
+}  // namespace
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc b/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc
new file mode 100644
index 0000000..6713d29
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -0,0 +1,877 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/stubs/common.h>
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/compiler/java/java_primitive_field.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 {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+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;
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+                           int messageBitIndex,
+                           int builderBitIndex,
+                           const FieldGeneratorInfo* info,
+                           ClassNameResolver* name_resolver,
+                           map<string, string>* variables) {
+  SetCommonFieldVariables(descriptor, info, variables);
+
+  (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
+  (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
+  (*variables)["field_type"] = (*variables)["type"];
+  (*variables)["field_list_type"] = "java.util.List<" +
+      (*variables)["boxed_type"] + ">";
+  (*variables)["empty_list"] = "java.util.Collections.emptyList()";
+  (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
+  (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ?
+      "" : ("= " + ImmutableDefaultValue(descriptor, name_resolver));
+  (*variables)["capitalized_type"] =
+      GetCapitalizedType(descriptor, /* immutable = */ true);
+  (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
+  (*variables)["tag_size"] = SimpleItoa(
+      WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+  if (IsReferenceType(GetJavaType(descriptor))) {
+    (*variables)["null_check"] =
+        "  if (value == null) {\n"
+        "    throw new NullPointerException();\n"
+        "  }\n";
+  } else {
+    (*variables)["null_check"] = "";
+  }
+  // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+  // by the proto compiler
+  (*variables)["deprecation"] = descriptor->options().deprecated()
+      ? "@java.lang.Deprecated " : "";
+  int fixed_size = FixedSize(GetType(descriptor));
+  if (fixed_size != -1) {
+    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+  }
+  (*variables)["on_changed"] =
+      HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+  if (SupportFieldPresence(descriptor->file())) {
+    // For singular messages and builders, one bit is used for the hasField bit.
+    (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+    (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+    // Note that these have a trailing ";".
+    (*variables)["set_has_field_bit_message"] =
+        GenerateSetBit(messageBitIndex) + ";";
+    (*variables)["set_has_field_bit_builder"] =
+        GenerateSetBit(builderBitIndex) + ";";
+    (*variables)["clear_has_field_bit_builder"] =
+        GenerateClearBit(builderBitIndex) + ";";
+
+    (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+  } else {
+    (*variables)["set_has_field_bit_message"] = "";
+    (*variables)["set_has_field_bit_builder"] = "";
+    (*variables)["clear_has_field_bit_builder"] = "";
+
+    if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
+      (*variables)["is_field_present_message"] =
+          "!" + (*variables)["name"] + "_.isEmpty()";
+    } else {
+      (*variables)["is_field_present_message"] =
+          (*variables)["name"] + "_ != " + (*variables)["default"];
+    }
+  }
+
+  // For repated builders, one bit is used for whether the array is immutable.
+  (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+  (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+  (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+  // For repeated fields, one bit is used for whether the array is immutable
+  // in the parsing constructor.
+  (*variables)["get_mutable_bit_parser"] =
+      GenerateGetBitMutableLocal(builderBitIndex);
+  (*variables)["set_mutable_bit_parser"] =
+      GenerateSetBitMutableLocal(builderBitIndex);
+
+  (*variables)["get_has_field_bit_from_local"] =
+      GenerateGetBitFromLocal(builderBitIndex);
+  (*variables)["set_has_field_bit_to_local"] =
+      GenerateSetBitToLocal(messageBitIndex);
+}
+
+}  // namespace
+
+// ===================================================================
+
+ImmutablePrimitiveFieldGenerator::
+ImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+                                 int messageBitIndex,
+                                 int builderBitIndex,
+                                 Context* context)
+  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+    builderBitIndex_(builderBitIndex), context_(context),
+    name_resolver_(context->GetNameResolver()) {
+  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+                        context->GetFieldGeneratorInfo(descriptor),
+                        name_resolver_, &variables_);
+}
+
+ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {}
+
+int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
+  return 1;
+}
+
+int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
+  return 1;
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$boolean has$capitalized_name$();\n");
+  }
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$$type$ get$capitalized_name$();\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private $field_type$ $name$_;\n");
+  PrintExtraFieldInfo(variables_, printer);
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $get_has_field_bit_message$;\n"
+      "}\n");
+  }
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  return $name$_;\n"
+    "}\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private $field_type$ $name$_ $default_init$;\n");
+
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $get_has_field_bit_builder$;\n"
+      "}\n");
+  }
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  return $name$_;\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
+    "$null_check$"
+    "  $set_has_field_bit_builder$\n"
+    "  $name$_ = value;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder clear$capitalized_name$() {\n"
+    "  $clear_has_field_bit_builder$\n");
+  JavaType type = GetJavaType(descriptor_);
+  if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
+    // The default value is not a simple literal so we want to avoid executing
+    // it multiple times.  Instead, get the default out of the default instance.
+    printer->Print(variables_,
+      "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
+  } else {
+    printer->Print(variables_,
+      "  $name$_ = $default$;\n");
+  }
+  printer->Print(variables_,
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
+  // noop for primitives
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$_ = $default$;\n"
+    "$clear_has_field_bit_builder$\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    printer->Print(variables_,
+      "if (other.has$capitalized_name$()) {\n"
+      "  set$capitalized_name$(other.get$capitalized_name$());\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "if (other.get$capitalized_name$() != $default$) {\n"
+      "  set$capitalized_name$(other.get$capitalized_name$());\n"
+      "}\n");
+  }
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    printer->Print(variables_,
+      "if ($get_has_field_bit_from_local$) {\n"
+      "  $set_has_field_bit_to_local$;\n"
+      "}\n");
+  }
+  printer->Print(variables_,
+    "result.$name$_ = $name$_;\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$set_has_field_bit_message$\n"
+    "$name$_ = input.read$capitalized_type$();\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+  // noop for primitives.
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($is_field_present_message$) {\n"
+    "  output.write$capitalized_type$($number$, $name$_);\n"
+    "}\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($is_field_present_message$) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .compute$capitalized_type$Size($number$, $name$_);\n"
+    "}\n");
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  switch (GetJavaType(descriptor_)) {
+    case JAVATYPE_INT:
+    case JAVATYPE_LONG:
+    case JAVATYPE_BOOLEAN:
+      printer->Print(variables_,
+        "result = result && (get$capitalized_name$()\n"
+        "    == other.get$capitalized_name$());\n");
+      break;
+
+    case JAVATYPE_FLOAT:
+      printer->Print(variables_,
+        "result = result && (\n"
+        "    java.lang.Float.floatToIntBits(get$capitalized_name$())\n"
+        "    == java.lang.Float.floatToIntBits(\n"
+        "        other.get$capitalized_name$()));\n");
+      break;
+
+    case JAVATYPE_DOUBLE:
+      printer->Print(variables_,
+        "result = result && (\n"
+        "    java.lang.Double.doubleToLongBits(get$capitalized_name$())\n"
+        "    == java.lang.Double.doubleToLongBits(\n"
+        "        other.get$capitalized_name$()));\n");
+      break;
+
+    case JAVATYPE_STRING:
+    case JAVATYPE_BYTES:
+      printer->Print(variables_,
+        "result = result && get$capitalized_name$()\n"
+        "    .equals(other.get$capitalized_name$());\n");
+      break;
+
+    case JAVATYPE_ENUM:
+    case JAVATYPE_MESSAGE:
+    default:
+      GOOGLE_LOG(FATAL) << "Can't get here.";
+      break;
+  }
+}
+
+void ImmutablePrimitiveFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "hash = (37 * hash) + $constant_name$;\n");
+  switch (GetJavaType(descriptor_)) {
+    case JAVATYPE_INT:
+      printer->Print(variables_,
+        "hash = (53 * hash) + get$capitalized_name$();\n");
+      break;
+
+    case JAVATYPE_LONG:
+      printer->Print(variables_,
+        "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
+        "    get$capitalized_name$());\n");
+      break;
+
+    case JAVATYPE_BOOLEAN:
+      printer->Print(variables_,
+        "hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(\n"
+        "    get$capitalized_name$());\n");
+      break;
+
+    case JAVATYPE_FLOAT:
+      printer->Print(variables_,
+        "hash = (53 * hash) + java.lang.Float.floatToIntBits(\n"
+        "    get$capitalized_name$());\n");
+      break;
+
+    case JAVATYPE_DOUBLE:
+      printer->Print(variables_,
+        "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
+        "    java.lang.Double.doubleToLongBits(get$capitalized_name$()));\n");
+      break;
+
+    case JAVATYPE_STRING:
+    case JAVATYPE_BYTES:
+      printer->Print(variables_,
+        "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+      break;
+
+    case JAVATYPE_ENUM:
+    case JAVATYPE_MESSAGE:
+    default:
+      GOOGLE_LOG(FATAL) << "Can't get here.";
+      break;
+  }
+}
+
+string ImmutablePrimitiveFieldGenerator::GetBoxedType() const {
+  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+// ===================================================================
+
+ImmutablePrimitiveOneofFieldGenerator::
+ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                 int messageBitIndex,
+                                 int builderBitIndex,
+                                 Context* context)
+    : ImmutablePrimitiveFieldGenerator(
+          descriptor, messageBitIndex, builderBitIndex, context) {
+  const OneofGeneratorInfo* info =
+      context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+  SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutablePrimitiveOneofFieldGenerator::
+~ImmutablePrimitiveOneofFieldGenerator() {}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  PrintExtraFieldInfo(variables_, printer);
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $has_oneof_case_message$;\n"
+      "}\n");
+  }
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    return ($boxed_type$) $oneof_name$_;\n"
+    "  }\n"
+    "  return $default$;\n"
+    "}\n");
+}
+
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $has_oneof_case_message$;\n"
+      "}\n");
+  }
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$() {\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    return ($boxed_type$) $oneof_name$_;\n"
+    "  }\n"
+    "  return $default$;\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
+    "$null_check$"
+    "  $set_oneof_case_message$;\n"
+    "  $oneof_name$_ = value;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder clear$capitalized_name$() {\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    $clear_oneof_case_message$;\n"
+    "    $oneof_name$_ = null;\n"
+    "    $on_changed$\n"
+    "  }\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  result.$oneof_name$_ = $oneof_name$_;\n"
+    "}\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "set$capitalized_name$(other.get$capitalized_name$());\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$set_oneof_case_message$;\n"
+    "$oneof_name$_ = input.read$capitalized_type$();\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  output.write$capitalized_type$(\n"
+    "      $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"
+    "}\n");
+}
+
+void ImmutablePrimitiveOneofFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .compute$capitalized_type$Size(\n"
+    "        $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"
+    "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutablePrimitiveFieldGenerator::
+RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+                                         int messageBitIndex,
+                                         int builderBitIndex,
+                                         Context* context)
+  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+    builderBitIndex_(builderBitIndex), context_(context),
+    name_resolver_(context->GetNameResolver()) {
+  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+                        context->GetFieldGeneratorInfo(descriptor),
+                        name_resolver_, &variables_);
+}
+
+RepeatedImmutablePrimitiveFieldGenerator::
+~RepeatedImmutablePrimitiveFieldGenerator() {}
+
+int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
+  return 0;
+}
+
+int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
+  return 1;
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$int get$capitalized_name$Count();\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$$type$ get$capitalized_name$(int index);\n");
+}
+
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private $field_list_type$ $name$_;\n");
+  PrintExtraFieldInfo(variables_, printer);
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.util.List<$boxed_type$>\n"
+    "    get$capitalized_name$List() {\n"
+    "  return $name$_;\n"   // note:  unmodifiable list
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public int get$capitalized_name$Count() {\n"
+    "  return $name$_.size();\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+
+  if (descriptor_->options().packed() &&
+      HasGeneratedMethods(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      "private int $name$MemoizedSerializedSize = -1;\n");
+  }
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  // One field is the list and the bit field keeps track of whether the
+  // list is immutable. If it's immutable, the invariant is that it must
+  // either an instance of Collections.emptyList() or it's an ArrayList
+  // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+  // a refererence to the underlying ArrayList. This invariant allows us to
+  // share instances of lists between protocol buffers avoiding expensive
+  // memory allocations. Note, immutable is a strong guarantee here -- not
+  // just that the list cannot be modified via the reference but that the
+  // list can never be modified.
+  printer->Print(variables_,
+    "private $field_list_type$ $name$_ = $empty_list$;\n");
+
+  printer->Print(variables_,
+    "private void ensure$capitalized_name$IsMutable() {\n"
+    "  if (!$get_mutable_bit_builder$) {\n"
+    "    $name$_ = new java.util.ArrayList<$boxed_type$>($name$_);\n"
+    "    $set_mutable_bit_builder$;\n"
+    "   }\n"
+    "}\n");
+
+    // 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.
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.util.List<$boxed_type$>\n"
+    "    get$capitalized_name$List() {\n"
+    "  return java.util.Collections.unmodifiableList($name$_);\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public int get$capitalized_name$Count() {\n"
+    "  return $name$_.size();\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    int index, $type$ value) {\n"
+    "$null_check$"
+    "  ensure$capitalized_name$IsMutable();\n"
+    "  $name$_.set(index, value);\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
+    "$null_check$"
+    "  ensure$capitalized_name$IsMutable();\n"
+    "  $name$_.add(value);\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder addAll$capitalized_name$(\n"
+    "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
+    "  ensure$capitalized_name$IsMutable();\n"
+    "  com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+    "      values, $name$_);\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder clear$capitalized_name$() {\n"
+    "  $name$_ = $empty_list$;\n"
+    "  $clear_mutable_bit_builder$;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
+  // noop for primitives
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$_ = $empty_list$;\n"
+    "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  // The code below does two optimizations:
+  //   1. If the other list is empty, there's nothing to do. This ensures we
+  //      don't allocate a new array if we already have an immutable one.
+  //   2. If the other list is non-empty and our current list is empty, we can
+  //      reuse the other list which is guaranteed to be immutable.
+  printer->Print(variables_,
+    "if (!other.$name$_.isEmpty()) {\n"
+    "  if ($name$_.isEmpty()) {\n"
+    "    $name$_ = other.$name$_;\n"
+    "    $clear_mutable_bit_builder$;\n"
+    "  } else {\n"
+    "    ensure$capitalized_name$IsMutable();\n"
+    "    $name$_.addAll(other.$name$_);\n"
+    "  }\n"
+    "  $on_changed$\n"
+    "}\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  // The code below ensures that the result has an immutable list. If our
+  // list is immutable, we can just reuse it. If not, we make it immutable.
+  printer->Print(variables_,
+    "if ($get_mutable_bit_builder$) {\n"
+    "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+    "  $clear_mutable_bit_builder$;\n"
+    "}\n"
+    "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!$get_mutable_bit_parser$) {\n"
+    "  $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+    "  $set_mutable_bit_parser$;\n"
+    "}\n"
+    "$name$_.add(input.read$capitalized_type$());\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateParsingCodeFromPacked(io::Printer* printer) const {
+  printer->Print(variables_,
+    "int length = input.readRawVarint32();\n"
+    "int limit = input.pushLimit(length);\n"
+    "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
+    "  $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+    "  $set_mutable_bit_parser$;\n"
+    "}\n"
+    "while (input.getBytesUntilLimit() > 0) {\n"
+    "  $name$_.add(input.read$capitalized_type$());\n"
+    "}\n"
+    "input.popLimit(limit);\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($get_mutable_bit_parser$) {\n"
+    "  $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
+    "}\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "if (get$capitalized_name$List().size() > 0) {\n"
+      "  output.writeRawVarint32($tag$);\n"
+      "  output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+      "}\n"
+      "for (int i = 0; i < $name$_.size(); i++) {\n"
+      "  output.write$capitalized_type$NoTag($name$_.get(i));\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "for (int i = 0; i < $name$_.size(); i++) {\n"
+      "  output.write$capitalized_type$($number$, $name$_.get(i));\n"
+      "}\n");
+  }
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "{\n"
+    "  int dataSize = 0;\n");
+  printer->Indent();
+
+  if (FixedSize(GetType(descriptor_)) == -1) {
+    printer->Print(variables_,
+      "for (int i = 0; i < $name$_.size(); i++) {\n"
+      "  dataSize += com.google.protobuf.CodedOutputStream\n"
+      "    .compute$capitalized_type$SizeNoTag($name$_.get(i));\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n");
+  }
+
+  printer->Print(
+      "size += dataSize;\n");
+
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "if (!get$capitalized_name$List().isEmpty()) {\n"
+      "  size += $tag_size$;\n"
+      "  size += com.google.protobuf.CodedOutputStream\n"
+      "      .computeInt32SizeNoTag(dataSize);\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "size += $tag_size$ * get$capitalized_name$List().size();\n");
+  }
+
+  // cache the data size for packed fields.
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "$name$MemoizedSerializedSize = dataSize;\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = result && get$capitalized_name$List()\n"
+    "    .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedImmutablePrimitiveFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (get$capitalized_name$Count() > 0) {\n"
+    "  hash = (37 * hash) + $constant_name$;\n"
+    "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+    "}\n");
+}
+
+string RepeatedImmutablePrimitiveFieldGenerator::GetBoxedType() const {
+  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h b/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h
new file mode 100644
index 0000000..d0cd12d
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_primitive_field.h
@@ -0,0 +1,160 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 Context;           // context.h
+      class ClassNameResolver; // name_resolver.h
+    }
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator {
+ public:
+  explicit ImmutablePrimitiveFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~ImmutablePrimitiveFieldGenerator();
+
+  // implements ImmutableFieldGenerator ---------------------------------------
+  int GetNumBitsForMessage() const;
+  int GetNumBitsForBuilder() const;
+  void GenerateInterfaceMembers(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateInitializationCode(io::Printer* printer) const;
+  void GenerateBuilderClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateParsingDoneCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ protected:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  const int messageBitIndex_;
+  const int builderBitIndex_;
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveFieldGenerator);
+};
+
+class ImmutablePrimitiveOneofFieldGenerator
+    : public ImmutablePrimitiveFieldGenerator {
+ public:
+  ImmutablePrimitiveOneofFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~ImmutablePrimitiveOneofFieldGenerator();
+
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldGenerator);
+};
+
+class RepeatedImmutablePrimitiveFieldGenerator
+    : public ImmutableFieldGenerator {
+ public:
+  explicit RepeatedImmutablePrimitiveFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  virtual ~RepeatedImmutablePrimitiveFieldGenerator();
+
+  // implements ImmutableFieldGenerator ---------------------------------------
+  int GetNumBitsForMessage() const;
+  int GetNumBitsForBuilder() const;
+  void GenerateInterfaceMembers(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateInitializationCode(io::Printer* printer) const;
+  void GenerateBuilderClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateParsingCodeFromPacked(io::Printer* printer) const;
+  void GenerateParsingDoneCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  const int messageBitIndex_;
+  const int builderBitIndex_;
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutablePrimitiveFieldGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_service.cc b/protobuf/src/google/protobuf/compiler/java/java_service.cc
new file mode 100644
index 0000000..7baead1
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_service.cc
@@ -0,0 +1,473 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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_context.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.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() {}
+
+// ===================================================================
+ImmutableServiceGenerator::ImmutableServiceGenerator(
+    const ServiceDescriptor* descriptor, Context* context)
+    : ServiceGenerator(descriptor), context_(context),
+    name_resolver_(context->GetNameResolver()) {}
+
+ImmutableServiceGenerator::~ImmutableServiceGenerator() {}
+
+void ImmutableServiceGenerator::Generate(io::Printer* printer) {
+  bool is_own_file =
+    MultipleJavaFiles(descriptor_->file(), /* immutable = */ true);
+  WriteServiceDocComment(printer, descriptor_);
+  printer->Print(
+    "public $static$ abstract class $classname$\n"
+    "    implements com.google.protobuf.Service {\n",
+    "static", is_own_file ? "" : "static",
+    "classname", descriptor_->name());
+  printer->Indent();
+
+  printer->Print(
+    "protected $classname$() {}\n\n",
+    "classname", descriptor_->name());
+
+  GenerateInterface(printer);
+
+  GenerateNewReflectiveServiceMethod(printer);
+  GenerateNewReflectiveBlockingServiceMethod(printer);
+
+  GenerateAbstractMethods(printer);
+
+  // Generate getDescriptor() and getDescriptorForType().
+  printer->Print(
+    "public static final\n"
+    "    com.google.protobuf.Descriptors.ServiceDescriptor\n"
+    "    getDescriptor() {\n"
+    "  return $file$.getDescriptor().getServices().get($index$);\n"
+    "}\n",
+    "file", name_resolver_->GetImmutableClassName(descriptor_->file()),
+    "index", SimpleItoa(descriptor_->index()));
+  GenerateGetDescriptorForType(printer);
+
+  // Generate more stuff.
+  GenerateCallMethod(printer);
+  GenerateGetPrototype(REQUEST, printer);
+  GenerateGetPrototype(RESPONSE, printer);
+  GenerateStub(printer);
+  GenerateBlockingStub(printer);
+
+  // Add an insertion point.
+  printer->Print(
+    "\n"
+    "// @@protoc_insertion_point(class_scope:$full_name$)\n",
+    "full_name", descriptor_->full_name());
+
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+void ImmutableServiceGenerator::GenerateGetDescriptorForType(
+    io::Printer* printer) {
+  printer->Print(
+    "public final com.google.protobuf.Descriptors.ServiceDescriptor\n"
+    "    getDescriptorForType() {\n"
+    "  return getDescriptor();\n"
+    "}\n");
+}
+
+void ImmutableServiceGenerator::GenerateInterface(io::Printer* printer) {
+  printer->Print("public interface Interface {\n");
+  printer->Indent();
+  GenerateAbstractMethods(printer);
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+void ImmutableServiceGenerator::GenerateNewReflectiveServiceMethod(
+    io::Printer* printer) {
+  printer->Print(
+    "public static com.google.protobuf.Service newReflectiveService(\n"
+    "    final Interface impl) {\n"
+    "  return new $classname$() {\n",
+    "classname", descriptor_->name());
+  printer->Indent();
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    printer->Print("@java.lang.Override\n");
+    GenerateMethodSignature(printer, method, IS_CONCRETE);
+    printer->Print(
+      " {\n"
+      "  impl.$method$(controller, request, done);\n"
+      "}\n\n",
+      "method", UnderscoresToCamelCase(method));
+  }
+
+  printer->Outdent();
+  printer->Print("};\n");
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+void ImmutableServiceGenerator::GenerateNewReflectiveBlockingServiceMethod(
+    io::Printer* printer) {
+  printer->Print(
+    "public static com.google.protobuf.BlockingService\n"
+    "    newReflectiveBlockingService(final BlockingInterface impl) {\n"
+    "  return new com.google.protobuf.BlockingService() {\n");
+  printer->Indent();
+  printer->Indent();
+
+  GenerateGetDescriptorForType(printer);
+
+  GenerateCallBlockingMethod(printer);
+  GenerateGetPrototype(REQUEST, printer);
+  GenerateGetPrototype(RESPONSE, printer);
+
+  printer->Outdent();
+  printer->Print("};\n");
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+void ImmutableServiceGenerator::GenerateAbstractMethods(io::Printer* printer) {
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    WriteMethodDocComment(printer, method);
+    GenerateMethodSignature(printer, method, IS_ABSTRACT);
+    printer->Print(";\n\n");
+  }
+}
+
+void ImmutableServiceGenerator::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"] = name_resolver_->GetImmutableClassName(
+        method->input_type());
+    vars["output"] = name_resolver_->GetImmutableClassName(
+        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.AssertionError(\"Can't get here.\");\n");
+
+  printer->Outdent();
+  printer->Outdent();
+
+  printer->Print(
+    "  }\n"
+    "}\n"
+    "\n");
+}
+
+void ImmutableServiceGenerator::GenerateCallBlockingMethod(
+    io::Printer* printer) {
+  printer->Print(
+    "\n"
+    "public final com.google.protobuf.Message callBlockingMethod(\n"
+    "    com.google.protobuf.Descriptors.MethodDescriptor method,\n"
+    "    com.google.protobuf.RpcController controller,\n"
+    "    com.google.protobuf.Message request)\n"
+    "    throws com.google.protobuf.ServiceException {\n"
+    "  if (method.getService() != getDescriptor()) {\n"
+    "    throw new java.lang.IllegalArgumentException(\n"
+    "      \"Service.callBlockingMethod() given method descriptor for \" +\n"
+    "      \"wrong 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"] = name_resolver_->GetImmutableClassName(
+        method->input_type());
+    vars["output"] = name_resolver_->GetImmutableClassName(
+        method->output_type());
+    printer->Print(vars,
+      "case $index$:\n"
+      "  return impl.$method$(controller, ($input$)request);\n");
+  }
+
+  printer->Print(
+    "default:\n"
+    "  throw new java.lang.AssertionError(\"Can't get here.\");\n");
+
+  printer->Outdent();
+  printer->Outdent();
+
+  printer->Print(
+    "  }\n"
+    "}\n"
+    "\n");
+}
+
+void ImmutableServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
+                                            io::Printer* printer) {
+  /*
+   * TODO(cpovirk): The exception message says "Service.foo" when it may be
+   * "BlockingService.foo."  Consider fixing.
+   */
+  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"] = name_resolver_->GetImmutableClassName(
+      (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.AssertionError(\"Can't get here.\");\n");
+
+  printer->Outdent();
+  printer->Outdent();
+
+  printer->Print(
+    "  }\n"
+    "}\n"
+    "\n");
+}
+
+void ImmutableServiceGenerator::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$ implements Interface {"
+    "\n",
+    "classname", name_resolver_->GetImmutableClassName(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);
+    printer->Print("\n");
+    GenerateMethodSignature(printer, method, IS_CONCRETE);
+    printer->Print(" {\n");
+    printer->Indent();
+
+    map<string, string> vars;
+    vars["index"] = SimpleItoa(i);
+    vars["output"] = name_resolver_->GetImmutableClassName(
+        method->output_type());
+    printer->Print(vars,
+      "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");
+
+    printer->Outdent();
+    printer->Print("}\n");
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "\n");
+}
+
+void ImmutableServiceGenerator::GenerateBlockingStub(io::Printer* printer) {
+  printer->Print(
+    "public static BlockingInterface newBlockingStub(\n"
+    "    com.google.protobuf.BlockingRpcChannel channel) {\n"
+    "  return new BlockingStub(channel);\n"
+    "}\n"
+    "\n");
+
+  printer->Print(
+    "public interface BlockingInterface {");
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    GenerateBlockingMethodSignature(printer, method);
+    printer->Print(";\n");
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "\n");
+
+  printer->Print(
+    "private static final class BlockingStub implements BlockingInterface {\n");
+  printer->Indent();
+
+  printer->Print(
+    "private BlockingStub(com.google.protobuf.BlockingRpcChannel channel) {\n"
+    "  this.channel = channel;\n"
+    "}\n"
+    "\n"
+    "private final com.google.protobuf.BlockingRpcChannel channel;\n");
+
+  for (int i = 0; i < descriptor_->method_count(); i++) {
+    const MethodDescriptor* method = descriptor_->method(i);
+    GenerateBlockingMethodSignature(printer, method);
+    printer->Print(" {\n");
+    printer->Indent();
+
+    map<string, string> vars;
+    vars["index"] = SimpleItoa(i);
+    vars["output"] = name_resolver_->GetImmutableClassName(
+        method->output_type());
+    printer->Print(vars,
+      "return ($output$) channel.callBlockingMethod(\n"
+      "  getDescriptor().getMethods().get($index$),\n"
+      "  controller,\n"
+      "  request,\n"
+      "  $output$.getDefaultInstance());\n");
+
+    printer->Outdent();
+    printer->Print(
+      "}\n"
+      "\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void ImmutableServiceGenerator::GenerateMethodSignature(io::Printer* printer,
+                                               const MethodDescriptor* method,
+                                               IsAbstract is_abstract) {
+  map<string, string> vars;
+  vars["name"] = UnderscoresToCamelCase(method);
+  vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
+  vars["output"] = name_resolver_->GetImmutableClassName(method->output_type());
+  vars["abstract"] = (is_abstract == IS_ABSTRACT) ? "abstract" : "";
+  printer->Print(vars,
+    "public $abstract$ void $name$(\n"
+    "    com.google.protobuf.RpcController controller,\n"
+    "    $input$ request,\n"
+    "    com.google.protobuf.RpcCallback<$output$> done)");
+}
+
+void ImmutableServiceGenerator::GenerateBlockingMethodSignature(
+    io::Printer* printer,
+    const MethodDescriptor* method) {
+  map<string, string> vars;
+  vars["method"] = UnderscoresToCamelCase(method);
+  vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
+  vars["output"] = name_resolver_->GetImmutableClassName(method->output_type());
+  printer->Print(vars,
+    "\n"
+    "public $output$ $method$(\n"
+    "    com.google.protobuf.RpcController controller,\n"
+    "    $input$ request)\n"
+    "    throws com.google.protobuf.ServiceException");
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_service.h b/protobuf/src/google/protobuf/compiler/java/java_service.h
new file mode 100644
index 0000000..6707e82
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_service.h
@@ -0,0 +1,135 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 compiler {
+    namespace java {
+      class Context;            // context.h
+      class ClassNameResolver;  // name_resolver.h
+    }
+  }
+  namespace io {
+    class Printer;              // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ServiceGenerator {
+ public:
+  explicit ServiceGenerator(const ServiceDescriptor* descriptor);
+  virtual ~ServiceGenerator();
+
+  virtual void Generate(io::Printer* printer) = 0;
+
+  enum RequestOrResponse { REQUEST, RESPONSE };
+  enum IsAbstract { IS_ABSTRACT, IS_CONCRETE };
+
+ protected:
+  const ServiceDescriptor* descriptor_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
+};
+
+class ImmutableServiceGenerator : public ServiceGenerator {
+ public:
+  explicit ImmutableServiceGenerator(const ServiceDescriptor* descriptor,
+                                     Context* context);
+  virtual ~ImmutableServiceGenerator();
+
+  virtual void Generate(io::Printer* printer);
+
+ private:
+
+  // Generate the getDescriptorForType() method.
+  void GenerateGetDescriptorForType(io::Printer* printer);
+
+  // Generate a Java interface for the service.
+  void GenerateInterface(io::Printer* printer);
+
+  // Generate newReflectiveService() method.
+  void GenerateNewReflectiveServiceMethod(io::Printer* printer);
+
+  // Generate newReflectiveBlockingService() method.
+  void GenerateNewReflectiveBlockingServiceMethod(io::Printer* printer);
+
+  // Generate abstract method declarations for all methods.
+  void GenerateAbstractMethods(io::Printer* printer);
+
+  // Generate the implementation of Service.callMethod().
+  void GenerateCallMethod(io::Printer* printer);
+
+  // Generate the implementation of BlockingService.callBlockingMethod().
+  void GenerateCallBlockingMethod(io::Printer* printer);
+
+  // Generate the implementations of Service.get{Request,Response}Prototype().
+  void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer);
+
+  // Generate a stub implementation of the service.
+  void GenerateStub(io::Printer* printer);
+
+  // Generate a method signature, possibly abstract, without body or trailing
+  // semicolon.
+  void GenerateMethodSignature(io::Printer* printer,
+                               const MethodDescriptor* method,
+                               IsAbstract is_abstract);
+
+  // Generate a blocking stub interface and implementation of the service.
+  void GenerateBlockingStub(io::Printer* printer);
+
+  // Generate the method signature for one method of a blocking stub.
+  void GenerateBlockingMethodSignature(io::Printer* printer,
+                                       const MethodDescriptor* method);
+
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableServiceGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+#endif  // NET_PROTO2_COMPILER_JAVA_SERVICE_H__
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.cc b/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.cc
new file mode 100644
index 0000000..ea77f79
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.cc
@@ -0,0 +1,201 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: xiaofeng@google.com (Feng Xiao)
+
+#include <google/protobuf/compiler/java/java_shared_code_generator.h>
+
+#include <memory>
+
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.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/descriptor.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+SharedCodeGenerator::SharedCodeGenerator(const FileDescriptor* file)
+  : name_resolver_(new ClassNameResolver), file_(file) {
+}
+
+SharedCodeGenerator::~SharedCodeGenerator() {
+}
+
+void SharedCodeGenerator::Generate(GeneratorContext* context,
+                                   vector<string>* file_list) {
+  string java_package = FileJavaPackage(file_);
+  string package_dir = JavaPackageToDir(java_package);
+
+  if (HasDescriptorMethods(file_)) {
+    // Generate descriptors.
+    string classname = name_resolver_->GetDescriptorClassName(file_);
+    string filename = package_dir + classname + ".java";
+    file_list->push_back(filename);
+    scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+    scoped_ptr<io::Printer> printer(new io::Printer(output.get(), '$'));
+
+    printer->Print(
+      "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
+      "// source: $filename$\n"
+      "\n",
+      "filename", file_->name());
+    if (!java_package.empty()) {
+      printer->Print(
+        "package $package$;\n"
+        "\n",
+        "package", java_package);
+    }
+    printer->Print(
+      "public final class $classname$ {\n"
+      "  public static com.google.protobuf.Descriptors.FileDescriptor\n"
+      "      descriptor;\n"
+      "  static {\n",
+      "classname", classname);
+    printer->Indent();
+    printer->Indent();
+    GenerateDescriptors(printer.get());
+    printer->Outdent();
+    printer->Outdent();
+    printer->Print(
+      "  }\n"
+      "}\n");
+
+    printer.reset();
+    output.reset();
+  }
+}
+
+
+void SharedCodeGenerator::GenerateDescriptors(io::Printer* printer) {
+  // 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(
+    "java.lang.String[] descriptorData = {\n");
+  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) {
+      // Every 400 lines, start a new string literal, in order to avoid the
+      // 64k length limit.
+      if (i % 400 == 0) {
+        printer->Print(",\n");
+      } else {
+        printer->Print(" +\n");
+      }
+    }
+    printer->Print("\"$data$\"",
+      "data", CEscape(file_data.substr(i, kBytesPerLine)));
+  }
+
+  printer->Outdent();
+  printer->Print("\n};\n");
+
+  // -----------------------------------------------------------------
+  // Create the InternalDescriptorAssigner.
+
+  printer->Print(
+    "com.google.protobuf.Descriptors.FileDescriptor."
+    "InternalDescriptorAssigner assigner =\n"
+    "    new com.google.protobuf.Descriptors.FileDescriptor."
+    "    InternalDescriptorAssigner() {\n"
+    "      public com.google.protobuf.ExtensionRegistry assignDescriptors(\n"
+    "          com.google.protobuf.Descriptors.FileDescriptor root) {\n"
+    "        descriptor = root;\n"
+    // Custom options will be handled when immutable messages' outer class is
+    // loaded. Here we just return null and let custom options be unknown
+    // fields.
+    "        return null;\n"
+    "      }\n"
+    "    };\n");
+
+  // -----------------------------------------------------------------
+  // Find out all dependencies.
+  vector<pair<string, string> > dependencies;
+  for (int i = 0; i < file_->dependency_count(); i++) {
+    if (ShouldIncludeDependency(file_->dependency(i))) {
+      string filename = file_->dependency(i)->name();
+      string classname = FileJavaPackage(file_->dependency(i)) + "." +
+                         name_resolver_->GetDescriptorClassName(
+                             file_->dependency(i));
+      dependencies.push_back(make_pair(filename, classname));
+    }
+  }
+
+  // -----------------------------------------------------------------
+  // Invoke internalBuildGeneratedFileFrom() to build the file.
+  printer->Print(
+    "com.google.protobuf.Descriptors.FileDescriptor\n"
+    "  .internalBuildGeneratedFileFrom(descriptorData,\n"
+    "    new com.google.protobuf.Descriptors.FileDescriptor[] {\n");
+
+  for (int i = 0; i < dependencies.size(); i++) {
+    const string& dependency = dependencies[i].second;
+    printer->Print(
+        "      $dependency$.getDescriptor(),\n",
+        "dependency", dependency);
+  }
+
+  printer->Print(
+    "    }, assigner);\n");
+}
+
+bool SharedCodeGenerator::ShouldIncludeDependency(
+    const FileDescriptor* descriptor) {
+  return true;
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.h b/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.h
new file mode 100644
index 0000000..1bb2f3d
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_shared_code_generator.h
@@ -0,0 +1,90 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: xiaofeng@google.com (Feng Xiao)
+//
+// Generators that generate shared code between immutable API and mutable API.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+  class FileDescriptor;        // descriptor.h
+  namespace compiler {
+    class GeneratorContext;    // code_generator.h
+    namespace java {
+      class ClassNameResolver;       // name_resolver.h
+    }
+  }
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+// A generator that generates code that are shared between immutable API
+// and mutable API. Currently only descriptors are shared.
+class SharedCodeGenerator {
+ public:
+  explicit SharedCodeGenerator(const FileDescriptor* file);
+  ~SharedCodeGenerator();
+
+  void Generate(GeneratorContext* generator_context,
+                vector<string>* file_list);
+  void GenerateDescriptors(io::Printer* printer);
+
+ private:
+  // Returns whether the dependency should be included in the output file.
+  // Always returns true for opensource, but used internally at Google to help
+  // improve compatibility with version 1 of protocol buffers.
+  bool ShouldIncludeDependency(const FileDescriptor* descriptor);
+
+  scoped_ptr<ClassNameResolver> name_resolver_;
+  const FileDescriptor* file_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SharedCodeGenerator);
+};
+
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__
diff --git a/protobuf/src/google/protobuf/compiler/java/java_string_field.cc b/protobuf/src/google/protobuf/compiler/java/java_string_field.cc
new file mode 100644
index 0000000..8889a74
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_string_field.cc
@@ -0,0 +1,1056 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Author: jonp@google.com (Jon Perlow)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/compiler/java/java_string_field.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 {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+                           int messageBitIndex,
+                           int builderBitIndex,
+                           const FieldGeneratorInfo* info,
+                           ClassNameResolver* name_resolver,
+                           map<string, string>* variables) {
+  SetCommonFieldVariables(descriptor, info, variables);
+
+  (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY";
+
+  (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
+  (*variables)["default_init"] =
+      "= " + ImmutableDefaultValue(descriptor, name_resolver);
+  (*variables)["capitalized_type"] = "String";
+  (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
+  (*variables)["tag_size"] = SimpleItoa(
+      WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
+  (*variables)["null_check"] =
+      "  if (value == null) {\n"
+      "    throw new NullPointerException();\n"
+      "  }\n";
+
+  // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
+  // by the proto compiler
+  (*variables)["deprecation"] = descriptor->options().deprecated()
+      ? "@java.lang.Deprecated " : "";
+  (*variables)["on_changed"] =
+      HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
+
+  if (SupportFieldPresence(descriptor->file())) {
+    // For singular messages and builders, one bit is used for the hasField bit.
+    (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
+    (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
+
+    // Note that these have a trailing ";".
+    (*variables)["set_has_field_bit_message"] =
+        GenerateSetBit(messageBitIndex) + ";";
+    (*variables)["set_has_field_bit_builder"] =
+        GenerateSetBit(builderBitIndex) + ";";
+    (*variables)["clear_has_field_bit_builder"] =
+        GenerateClearBit(builderBitIndex) + ";";
+
+    (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
+  } else {
+    (*variables)["set_has_field_bit_message"] = "";
+    (*variables)["set_has_field_bit_builder"] = "";
+    (*variables)["clear_has_field_bit_builder"] = "";
+
+    (*variables)["is_field_present_message"] =
+        "!get" + (*variables)["capitalized_name"] + "Bytes().isEmpty()";
+  }
+
+  // For repeated builders, one bit is used for whether the array is immutable.
+  (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
+  (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
+  (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
+
+  // For repeated fields, one bit is used for whether the array is immutable
+  // in the parsing constructor.
+  (*variables)["get_mutable_bit_parser"] =
+      GenerateGetBitMutableLocal(builderBitIndex);
+  (*variables)["set_mutable_bit_parser"] =
+      GenerateSetBitMutableLocal(builderBitIndex);
+
+  (*variables)["get_has_field_bit_from_local"] =
+      GenerateGetBitFromLocal(builderBitIndex);
+  (*variables)["set_has_field_bit_to_local"] =
+      GenerateSetBitToLocal(messageBitIndex);
+}
+
+bool CheckUtf8(const FieldDescriptor* descriptor) {
+  return descriptor->file()->options().java_string_check_utf8();
+}
+
+}  // namespace
+
+// ===================================================================
+
+ImmutableStringFieldGenerator::
+ImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
+                              int messageBitIndex,
+                              int builderBitIndex,
+                              Context* context)
+  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+    builderBitIndex_(builderBitIndex), context_(context),
+    name_resolver_(context->GetNameResolver()) {
+  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+                        context->GetFieldGeneratorInfo(descriptor),
+                        name_resolver_, &variables_);
+}
+
+ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {}
+
+int ImmutableStringFieldGenerator::GetNumBitsForMessage() const {
+  return 1;
+}
+
+int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
+  return 1;
+}
+
+// A note about how strings are handled. This code used to just store a String
+// in the Message. This had two issues:
+//
+//  1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded
+//     strings, but rather fields that were raw bytes incorrectly marked
+//     as strings in the proto file. This is common because in the proto1
+//     syntax, string was the way to indicate bytes and C++ engineers can
+//     easily make this mistake without affecting the C++ API. By converting to
+//     strings immediately, some java code might corrupt these byte arrays as
+//     it passes through a java server even if the field was never accessed by
+//     application code.
+//
+//  2. There's a performance hit to converting between bytes and strings and
+//     it many cases, the field is never even read by the application code. This
+//     avoids unnecessary conversions in the common use cases.
+//
+// So now, the field for String is maintained as an Object reference which can
+// either store a String or a ByteString. The code uses an instanceof check
+// to see which one it has and converts to the other one if needed. It remembers
+// the last value requested (in a thread safe manner) as this is most likely
+// the one needed next. The thread safety is such that if two threads both
+// convert the field because the changes made by each thread were not visible to
+// the other, they may cause a conversion to happen more times than would
+// otherwise be necessary. This was deemed better than adding synchronization
+// overhead. It will not cause any corruption issues or affect the behavior of
+// the API. The instanceof check is also highly optimized in the JVM and we
+// decided it was better to reduce the memory overhead by not having two
+// separate fields but rather use dynamic type checking.
+//
+// For single fields, the logic for this is done inside the generated code. For
+// repeated fields, the logic is done in LazyStringArrayList and
+// UnmodifiableLazyStringList.
+void ImmutableStringFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$boolean has$capitalized_name$();\n");
+  }
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$java.lang.String get$capitalized_name$();\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$com.google.protobuf.ByteString\n"
+    "    get$capitalized_name$Bytes();\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private java.lang.Object $name$_;\n");
+  PrintExtraFieldInfo(variables_, printer);
+
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $get_has_field_bit_message$;\n"
+      "}\n");
+  }
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.lang.String get$capitalized_name$() {\n"
+    "  java.lang.Object ref = $name$_;\n"
+    "  if (ref instanceof java.lang.String) {\n"
+    "    return (java.lang.String) ref;\n"
+    "  } else {\n"
+    "    com.google.protobuf.ByteString bs = \n"
+    "        (com.google.protobuf.ByteString) ref;\n"
+      "    java.lang.String s = bs.toStringUtf8();\n");
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+      "    $name$_ = s;\n");
+  } else {
+    printer->Print(variables_,
+      "    if (bs.isValidUtf8()) {\n"
+      "      $name$_ = s;\n"
+      "    }\n");
+  }
+  printer->Print(variables_,
+    "    return s;\n"
+    "  }\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public com.google.protobuf.ByteString\n"
+    "    get$capitalized_name$Bytes() {\n"
+    "  java.lang.Object ref = $name$_;\n"
+    "  if (ref instanceof java.lang.String) {\n"
+    "    com.google.protobuf.ByteString b = \n"
+    "        com.google.protobuf.ByteString.copyFromUtf8(\n"
+    "            (java.lang.String) ref);\n"
+    "    $name$_ = b;\n"
+    "    return b;\n"
+    "  } else {\n"
+    "    return (com.google.protobuf.ByteString) ref;\n"
+    "  }\n"
+    "}\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private java.lang.Object $name$_ $default_init$;\n");
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $get_has_field_bit_builder$;\n"
+      "}\n");
+  }
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.lang.String get$capitalized_name$() {\n"
+    "  java.lang.Object ref = $name$_;\n"
+    "  if (!(ref instanceof java.lang.String)) {\n"
+    "    com.google.protobuf.ByteString bs =\n"
+    "        (com.google.protobuf.ByteString) ref;\n"
+    "    java.lang.String s = bs.toStringUtf8();\n");
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+      "    $name$_ = s;\n");
+  } else {
+    printer->Print(variables_,
+      "    if (bs.isValidUtf8()) {\n"
+      "      $name$_ = s;\n"
+      "    }\n");
+  }
+  printer->Print(variables_,
+    "    return s;\n"
+    "  } else {\n"
+    "    return (java.lang.String) ref;\n"
+    "  }\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public com.google.protobuf.ByteString\n"
+    "    get$capitalized_name$Bytes() {\n"
+    "  java.lang.Object ref = $name$_;\n"
+    "  if (ref instanceof String) {\n"
+    "    com.google.protobuf.ByteString b = \n"
+    "        com.google.protobuf.ByteString.copyFromUtf8(\n"
+    "            (java.lang.String) ref);\n"
+    "    $name$_ = b;\n"
+    "    return b;\n"
+    "  } else {\n"
+    "    return (com.google.protobuf.ByteString) ref;\n"
+    "  }\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    java.lang.String value) {\n"
+    "$null_check$"
+    "  $set_has_field_bit_builder$\n"
+    "  $name$_ = value;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder clear$capitalized_name$() {\n"
+    "  $clear_has_field_bit_builder$\n");
+  // The default value is not a simple literal so we want to avoid executing
+  // it multiple times.  Instead, get the default out of the default instance.
+  printer->Print(variables_,
+    "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
+  printer->Print(variables_,
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$Bytes(\n"
+    "    com.google.protobuf.ByteString value) {\n"
+    "$null_check$");
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+      "  checkByteStringIsUtf8(value);\n");
+  }
+  printer->Print(variables_,
+    "  $set_has_field_bit_builder$\n"
+    "  $name$_ = value;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
+  // noop for primitives
+}
+
+void ImmutableStringFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$_ = $default$;\n"
+    "$clear_has_field_bit_builder$\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    // Allow a slight breach of abstraction here in order to avoid forcing
+    // all string fields to Strings when copying fields from a Message.
+    printer->Print(variables_,
+      "if (other.has$capitalized_name$()) {\n"
+      "  $set_has_field_bit_builder$\n"
+      "  $name$_ = other.$name$_;\n"
+      "  $on_changed$\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "if (!other.get$capitalized_name$().isEmpty()) {\n"
+      "  $name$_ = other.$name$_;\n"
+      "  $on_changed$\n"
+      "}\n");
+  }
+}
+
+void ImmutableStringFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    printer->Print(variables_,
+      "if ($get_has_field_bit_from_local$) {\n"
+      "  $set_has_field_bit_to_local$;\n"
+      "}\n");
+  }
+  printer->Print(variables_,
+    "result.$name$_ = $name$_;\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+      "String s = input.readStringRequireUtf8();\n"
+      "$set_has_field_bit_message$\n"
+      "$name$_ = s;\n");
+  } else {
+    printer->Print(variables_,
+      "com.google.protobuf.ByteString bs = input.readBytes();\n"
+      "$set_has_field_bit_message$\n"
+      "$name$_ = bs;\n");
+  }
+}
+
+void ImmutableStringFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+  // noop for strings.
+}
+
+void ImmutableStringFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($is_field_present_message$) {\n"
+    "  output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+    "}\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($is_field_present_message$) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+    "}\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = result && get$capitalized_name$()\n"
+    "    .equals(other.get$capitalized_name$());\n");
+}
+
+void ImmutableStringFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "hash = (37 * hash) + $constant_name$;\n");
+  printer->Print(variables_,
+    "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
+}
+
+string ImmutableStringFieldGenerator::GetBoxedType() const {
+  return "java.lang.String";
+}
+
+// ===================================================================
+
+ImmutableStringOneofFieldGenerator::
+ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor,
+                                   int messageBitIndex,
+                                   int builderBitIndex,
+                                   Context* context)
+    : ImmutableStringFieldGenerator(
+          descriptor, messageBitIndex, builderBitIndex, context) {
+  const OneofGeneratorInfo* info =
+      context->GetOneofGeneratorInfo(descriptor->containing_oneof());
+  SetCommonOneofVariables(descriptor, info, &variables_);
+}
+
+ImmutableStringOneofFieldGenerator::
+~ImmutableStringOneofFieldGenerator() {}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  PrintExtraFieldInfo(variables_, printer);
+
+  if (SupportFieldPresence(descriptor_->file())) {
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public boolean has$capitalized_name$() {\n"
+    "  return $has_oneof_case_message$;\n"
+    "}\n");
+  }
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.lang.String get$capitalized_name$() {\n"
+    "  java.lang.Object ref $default_init$;\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    ref = $oneof_name$_;\n"
+    "  }\n"
+    "  if (ref instanceof java.lang.String) {\n"
+    "    return (java.lang.String) ref;\n"
+    "  } else {\n"
+    "    com.google.protobuf.ByteString bs = \n"
+    "        (com.google.protobuf.ByteString) ref;\n"
+    "    java.lang.String s = bs.toStringUtf8();\n");
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+    "    if ($has_oneof_case_message$) {\n"
+    "      $oneof_name$_ = s;\n"
+    "    }\n");
+  } else {
+    printer->Print(variables_,
+    "    if (bs.isValidUtf8() && ($has_oneof_case_message$)) {\n"
+    "      $oneof_name$_ = s;\n"
+    "    }\n");
+  }
+  printer->Print(variables_,
+    "    return s;\n"
+    "  }\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+
+  printer->Print(variables_,
+    "$deprecation$public com.google.protobuf.ByteString\n"
+    "    get$capitalized_name$Bytes() {\n"
+    "  java.lang.Object ref $default_init$;\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    ref = $oneof_name$_;\n"
+    "  }\n"
+    "  if (ref instanceof java.lang.String) {\n"
+    "    com.google.protobuf.ByteString b = \n"
+    "        com.google.protobuf.ByteString.copyFromUtf8(\n"
+    "            (java.lang.String) ref);\n"
+    "    if ($has_oneof_case_message$) {\n"
+    "      $oneof_name$_ = b;\n"
+    "    }\n"
+    "    return b;\n"
+    "  } else {\n"
+    "    return (com.google.protobuf.ByteString) ref;\n"
+    "  }\n"
+    "}\n");
+}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  if (SupportFieldPresence(descriptor_->file())) {
+    WriteFieldDocComment(printer, descriptor_);
+    printer->Print(variables_,
+      "$deprecation$public boolean has$capitalized_name$() {\n"
+      "  return $has_oneof_case_message$;\n"
+      "}\n");
+  }
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.lang.String get$capitalized_name$() {\n"
+    "  java.lang.Object ref $default_init$;\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    ref = $oneof_name$_;\n"
+    "  }\n"
+    "  if (!(ref instanceof java.lang.String)) {\n"
+    "    com.google.protobuf.ByteString bs =\n"
+    "        (com.google.protobuf.ByteString) ref;\n"
+    "    java.lang.String s = bs.toStringUtf8();\n"
+    "    if ($has_oneof_case_message$) {\n");
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+      "      $oneof_name$_ = s;\n");
+  } else {
+    printer->Print(variables_,
+      "      if (bs.isValidUtf8()) {\n"
+      "        $oneof_name$_ = s;\n"
+      "      }\n");
+  }
+  printer->Print(variables_,
+    "    }\n"
+    "    return s;\n"
+    "  } else {\n"
+    "    return (java.lang.String) ref;\n"
+    "  }\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public com.google.protobuf.ByteString\n"
+    "    get$capitalized_name$Bytes() {\n"
+    "  java.lang.Object ref $default_init$;\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    ref = $oneof_name$_;\n"
+    "  }\n"
+    "  if (ref instanceof String) {\n"
+    "    com.google.protobuf.ByteString b = \n"
+    "        com.google.protobuf.ByteString.copyFromUtf8(\n"
+    "            (java.lang.String) ref);\n"
+    "    if ($has_oneof_case_message$) {\n"
+    "      $oneof_name$_ = b;\n"
+    "    }\n"
+    "    return b;\n"
+    "  } else {\n"
+    "    return (com.google.protobuf.ByteString) ref;\n"
+    "  }\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    java.lang.String value) {\n"
+    "$null_check$"
+    "  $set_oneof_case_message$;\n"
+    "  $oneof_name$_ = value;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder clear$capitalized_name$() {\n"
+    "  if ($has_oneof_case_message$) {\n"
+    "    $clear_oneof_case_message$;\n"
+    "    $oneof_name$_ = null;\n"
+    "    $on_changed$\n"
+    "  }\n"
+    "  return this;\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$Bytes(\n"
+    "    com.google.protobuf.ByteString value) {\n"
+    "$null_check$");
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+      "  checkByteStringIsUtf8(value);\n");
+  }
+  printer->Print(variables_,
+    "  $set_oneof_case_message$;\n"
+    "  $oneof_name$_ = value;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  // Allow a slight breach of abstraction here in order to avoid forcing
+  // all string fields to Strings when copying fields from a Message.
+  printer->Print(variables_,
+    "$set_oneof_case_message$;\n"
+    "$oneof_name$_ = other.$oneof_name$_;\n"
+    "$on_changed$\n");
+}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  result.$oneof_name$_ = $oneof_name$_;\n"
+    "}\n");
+}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+      "String s = input.readStringRequireUtf8();\n"
+      "$set_oneof_case_message$;\n"
+      "$oneof_name$_ = s;\n}\n");
+  } else {
+    printer->Print(variables_,
+      "com.google.protobuf.ByteString bs = input.readBytes();\n"
+      "$set_oneof_case_message$;\n"
+      "$oneof_name$_ = bs;\n");
+  }
+}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+    "}\n");
+}
+
+void ImmutableStringOneofFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($has_oneof_case_message$) {\n"
+    "  size += com.google.protobuf.CodedOutputStream\n"
+    "    .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+    "}\n");
+}
+
+// ===================================================================
+
+RepeatedImmutableStringFieldGenerator::
+RepeatedImmutableStringFieldGenerator(const FieldDescriptor* descriptor,
+                                      int messageBitIndex,
+                                      int builderBitIndex,
+                                      Context* context)
+  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
+    builderBitIndex_(builderBitIndex), context_(context),
+    name_resolver_(context->GetNameResolver()) {
+  SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
+                        context->GetFieldGeneratorInfo(descriptor),
+                        name_resolver_, &variables_);
+}
+
+RepeatedImmutableStringFieldGenerator::
+~RepeatedImmutableStringFieldGenerator() {}
+
+int RepeatedImmutableStringFieldGenerator::GetNumBitsForMessage() const {
+  return 0;
+}
+
+int RepeatedImmutableStringFieldGenerator::GetNumBitsForBuilder() const {
+  return 1;
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateInterfaceMembers(io::Printer* printer) const {
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$com.google.protobuf.ProtocolStringList\n"
+    "    get$capitalized_name$List();\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$int get$capitalized_name$Count();\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$java.lang.String get$capitalized_name$(int index);\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$com.google.protobuf.ByteString\n"
+    "    get$capitalized_name$Bytes(int index);\n");
+}
+
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private com.google.protobuf.LazyStringList $name$_;\n");
+  PrintExtraFieldInfo(variables_, printer);
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public com.google.protobuf.ProtocolStringList\n"
+    "    get$capitalized_name$List() {\n"
+    "  return $name$_;\n"   // note:  unmodifiable list
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public int get$capitalized_name$Count() {\n"
+    "  return $name$_.size();\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public com.google.protobuf.ByteString\n"
+    "    get$capitalized_name$Bytes(int index) {\n"
+    "  return $name$_.getByteString(index);\n"
+    "}\n");
+
+  if (descriptor_->options().packed() &&
+      HasGeneratedMethods(descriptor_->containing_type())) {
+    printer->Print(variables_,
+      "private int $name$MemoizedSerializedSize = -1;\n");
+  }
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateBuilderMembers(io::Printer* printer) const {
+  // One field is the list and the bit field keeps track of whether the
+  // list is immutable. If it's immutable, the invariant is that it must
+  // either an instance of Collections.emptyList() or it's an ArrayList
+  // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
+  // a refererence to the underlying ArrayList. This invariant allows us to
+  // share instances of lists between protocol buffers avoiding expensive
+  // memory allocations. Note, immutable is a strong guarantee here -- not
+  // just that the list cannot be modified via the reference but that the
+  // list can never be modified.
+  printer->Print(variables_,
+    "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n");
+
+  printer->Print(variables_,
+    "private void ensure$capitalized_name$IsMutable() {\n"
+    "  if (!$get_mutable_bit_builder$) {\n"
+    "    $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
+    "    $set_mutable_bit_builder$;\n"
+    "   }\n"
+    "}\n");
+
+    // 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.
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public com.google.protobuf.ProtocolStringList\n"
+    "    get$capitalized_name$List() {\n"
+    "  return $name$_.getUnmodifiableView();\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public int get$capitalized_name$Count() {\n"
+    "  return $name$_.size();\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n"
+    "  return $name$_.get(index);\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public com.google.protobuf.ByteString\n"
+    "    get$capitalized_name$Bytes(int index) {\n"
+    "  return $name$_.getByteString(index);\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder set$capitalized_name$(\n"
+    "    int index, java.lang.String value) {\n"
+    "$null_check$"
+    "  ensure$capitalized_name$IsMutable();\n"
+    "  $name$_.set(index, value);\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder add$capitalized_name$(\n"
+    "    java.lang.String value) {\n"
+    "$null_check$"
+    "  ensure$capitalized_name$IsMutable();\n"
+    "  $name$_.add(value);\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder addAll$capitalized_name$(\n"
+    "    java.lang.Iterable<java.lang.String> values) {\n"
+    "  ensure$capitalized_name$IsMutable();\n"
+    "  com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
+    "      values, $name$_);\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder clear$capitalized_name$() {\n"
+    "  $name$_ = $empty_list$;\n"
+    "  $clear_mutable_bit_builder$;\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+
+  WriteFieldDocComment(printer, descriptor_);
+  printer->Print(variables_,
+    "$deprecation$public Builder add$capitalized_name$Bytes(\n"
+    "    com.google.protobuf.ByteString value) {\n"
+    "$null_check$");
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+      "  checkByteStringIsUtf8(value);\n");
+  }
+  printer->Print(variables_,
+    "  ensure$capitalized_name$IsMutable();\n"
+    "  $name$_.add(value);\n"
+    "  $on_changed$\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
+  // noop for primitives
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateInitializationCode(io::Printer* printer) const {
+  printer->Print(variables_, "$name$_ = $empty_list$;\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateBuilderClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$_ = $empty_list$;\n"
+    "$clear_mutable_bit_builder$;\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  // The code below does two optimizations:
+  //   1. If the other list is empty, there's nothing to do. This ensures we
+  //      don't allocate a new array if we already have an immutable one.
+  //   2. If the other list is non-empty and our current list is empty, we can
+  //      reuse the other list which is guaranteed to be immutable.
+  printer->Print(variables_,
+    "if (!other.$name$_.isEmpty()) {\n"
+    "  if ($name$_.isEmpty()) {\n"
+    "    $name$_ = other.$name$_;\n"
+    "    $clear_mutable_bit_builder$;\n"
+    "  } else {\n"
+    "    ensure$capitalized_name$IsMutable();\n"
+    "    $name$_.addAll(other.$name$_);\n"
+    "  }\n"
+    "  $on_changed$\n"
+    "}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateBuildingCode(io::Printer* printer) const {
+  // The code below ensures that the result has an immutable list. If our
+  // list is immutable, we can just reuse it. If not, we make it immutable.
+
+  printer->Print(variables_,
+    "if ($get_mutable_bit_builder$) {\n"
+    "  $name$_ = $name$_.getUnmodifiableView();\n"
+    "  $clear_mutable_bit_builder$;\n"
+    "}\n"
+    "result.$name$_ = $name$_;\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+    "String s = input.readStringRequireUtf8();\n");
+  } else {
+    printer->Print(variables_,
+    "com.google.protobuf.ByteString bs = input.readBytes();\n");
+  }
+  printer->Print(variables_,
+    "if (!$get_mutable_bit_parser$) {\n"
+    "  $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
+    "  $set_mutable_bit_parser$;\n"
+    "}\n");
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+      "$name$_.add(s);\n");
+  } else {
+    printer->Print(variables_,
+      "$name$_.add(bs);\n");
+  }
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateParsingCodeFromPacked(io::Printer* printer) const {
+  printer->Print(variables_,
+    "int length = input.readRawVarint32();\n"
+    "int limit = input.pushLimit(length);\n"
+    "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
+    "  $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
+    "  $set_mutable_bit_parser$;\n"
+    "}\n"
+    "while (input.getBytesUntilLimit() > 0) {\n");
+  if (CheckUtf8(descriptor_)) {
+    printer->Print(variables_,
+      "  String s = input.readStringRequireUtf8();\n");
+  } else {
+    printer->Print(variables_,
+      "  String s = input.readString();\n");
+  }
+  printer->Print(variables_,
+    "  $name$.add(s);\n");
+  printer->Print(variables_,
+    "}\n"
+    "input.popLimit(limit);\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateParsingDoneCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($get_mutable_bit_parser$) {\n"
+    "  $name$_ = $name$_.getUnmodifiableView();\n"
+    "}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "if (get$capitalized_name$List().size() > 0) {\n"
+      "  output.writeRawVarint32($tag$);\n"
+      "  output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+      "}\n"
+      "for (int i = 0; i < $name$_.size(); i++) {\n"
+      "  output.write$capitalized_type$NoTag($name$_.get(i));\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "for (int i = 0; i < $name$_.size(); i++) {\n"
+      "  output.writeBytes($number$, $name$_.getByteString(i));\n"
+      "}\n");
+  }
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "{\n"
+    "  int dataSize = 0;\n");
+  printer->Indent();
+
+  printer->Print(variables_,
+    "for (int i = 0; i < $name$_.size(); i++) {\n"
+    "  dataSize += com.google.protobuf.CodedOutputStream\n"
+    "    .computeBytesSizeNoTag($name$_.getByteString(i));\n"
+    "}\n");
+
+  printer->Print(
+      "size += dataSize;\n");
+
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "if (!get$capitalized_name$List().isEmpty()) {\n"
+      "  size += $tag_size$;\n"
+      "  size += com.google.protobuf.CodedOutputStream\n"
+      "      .computeInt32SizeNoTag(dataSize);\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "size += $tag_size$ * get$capitalized_name$List().size();\n");
+  }
+
+  // cache the data size for packed fields.
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "$name$MemoizedSerializedSize = dataSize;\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = result && get$capitalized_name$List()\n"
+    "    .equals(other.get$capitalized_name$List());\n");
+}
+
+void RepeatedImmutableStringFieldGenerator::
+GenerateHashCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (get$capitalized_name$Count() > 0) {\n"
+    "  hash = (37 * hash) + $constant_name$;\n"
+    "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
+    "}\n");
+}
+
+string RepeatedImmutableStringFieldGenerator::GetBoxedType() const {
+  return "String";
+}
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/java/java_string_field.h b/protobuf/src/google/protobuf/compiler/java/java_string_field.h
new file mode 100644
index 0000000..1ea44de
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/java/java_string_field.h
@@ -0,0 +1,160 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Author: jonp@google.com (Jon Perlow)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/java/java_field.h>
+
+namespace google {
+namespace protobuf {
+  namespace compiler {
+    namespace java {
+      class Context;           // context.h
+      class ClassNameResolver; // name_resolver.h
+    }
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class ImmutableStringFieldGenerator : public ImmutableFieldGenerator {
+ public:
+  explicit ImmutableStringFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~ImmutableStringFieldGenerator();
+
+  // implements ImmutableFieldGenerator ---------------------------------------
+  int GetNumBitsForMessage() const;
+  int GetNumBitsForBuilder() const;
+  void GenerateInterfaceMembers(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateInitializationCode(io::Printer* printer) const;
+  void GenerateBuilderClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateParsingDoneCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ protected:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  const int messageBitIndex_;
+  const int builderBitIndex_;
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringFieldGenerator);
+};
+
+class ImmutableStringOneofFieldGenerator
+    : public ImmutableStringFieldGenerator {
+ public:
+  ImmutableStringOneofFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~ImmutableStringOneofFieldGenerator();
+
+ private:
+  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;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldGenerator);
+};
+
+class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator {
+ public:
+  explicit RepeatedImmutableStringFieldGenerator(
+      const FieldDescriptor* descriptor, int messageBitIndex,
+      int builderBitIndex, Context* context);
+  ~RepeatedImmutableStringFieldGenerator();
+
+  // implements ImmutableFieldGenerator ---------------------------------------
+  int GetNumBitsForMessage() const;
+  int GetNumBitsForBuilder() const;
+  void GenerateInterfaceMembers(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateBuilderMembers(io::Printer* printer) const;
+  void GenerateInitializationCode(io::Printer* printer) const;
+  void GenerateBuilderClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateBuildingCode(io::Printer* printer) const;
+  void GenerateParsingCode(io::Printer* printer) const;
+  void GenerateParsingCodeFromPacked(io::Printer* printer) const;
+  void GenerateParsingDoneCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateFieldBuilderInitializationCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCode(io::Printer* printer) const;
+
+  string GetBoxedType() const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  const int messageBitIndex_;
+  const int builderBitIndex_;
+  Context* context_;
+  ClassNameResolver* name_resolver_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableStringFieldGenerator);
+};
+
+}  // namespace java
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum.cc b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum.cc
new file mode 100644
index 0000000..d74a149
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum.cc
@@ -0,0 +1,96 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javamicro/javamicro_params.h>
+#include <google/protobuf/compiler/javamicro/javamicro_enum.h>
+#include <google/protobuf/compiler/javamicro/javamicro_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 javamicro {
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, const Params& params)
+  : params_(params), 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) {
+  printer->Print("// enum $classname$\n", "classname", descriptor_->name());
+  for (int i = 0; i < canonical_values_.size(); i++) {
+    map<string, string> vars;
+    vars["name"] = canonical_values_[i]->name();
+    vars["canonical_value"] = SimpleItoa(canonical_values_[i]->number());
+    printer->Print(vars,
+      "public static final int $name$ = $canonical_value$;\n");
+  }
+
+  // -----------------------------------------------------------------
+
+  for (int i = 0; i < aliases_.size(); i++) {
+    map<string, string> vars;
+    vars["name"] = aliases_[i].value->name();
+    vars["canonical_name"] = aliases_[i].canonical_value->name();
+    printer->Print(vars,
+      "public static final int $name$ = $canonical_name$;\n");
+  }
+
+  printer->Print("\n");
+}
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum.h b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum.h
new file mode 100644
index 0000000..9cf226f
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum.h
@@ -0,0 +1,87 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/compiler/javamicro/javamicro_params.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+class EnumGenerator {
+ public:
+  explicit EnumGenerator(const EnumDescriptor* descriptor, const Params& params);
+  ~EnumGenerator();
+
+  void Generate(io::Printer* printer);
+
+ private:
+  const Params& params_;
+  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 javamicro
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc
new file mode 100644
index 0000000..0ff49a3
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum_field.cc
@@ -0,0 +1,333 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javamicro/javamicro_enum_field.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/javamicro/javamicro_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 javamicro {
+
+namespace {
+
+// TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
+//   repeat code between this and the other field types.
+void SetEnumVariables(const Params& params,
+    const FieldDescriptor* descriptor, map<string, string>* variables) {
+  (*variables)["name"] =
+    UnderscoresToCamelCase(descriptor);
+  (*variables)["capitalized_name"] =
+    UnderscoresToCapitalizedCamelCase(descriptor);
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["type"] = "int";
+  (*variables)["default"] = DefaultValue(params, descriptor);
+  (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+  (*variables)["tag_size"] = SimpleItoa(
+      internal::WireFormat::TagSize(descriptor->number(), descriptor->type()));
+  (*variables)["message_name"] = descriptor->containing_type()->name();
+}
+
+}  // namespace
+
+// ===================================================================
+
+EnumFieldGenerator::
+EnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetEnumVariables(params, descriptor, &variables_);
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {}
+
+void EnumFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private boolean has$capitalized_name$;\n"
+    "private int $name$_ = $default$;\n"
+    "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
+    "public int get$capitalized_name$() { return $name$_; }\n"
+    "public $message_name$ set$capitalized_name$(int value) {\n"
+    "  has$capitalized_name$ = true;\n"
+    "  $name$_ = value;\n"
+    "  return this;\n"
+    "}\n"
+    "public $message_name$ clear$capitalized_name$() {\n"
+    "  has$capitalized_name$ = false;\n"
+    "  $name$_ = $default$;\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "what is other??"
+    "if (other.has$capitalized_name$()) {\n"
+    "  set$capitalized_name$(other.get$capitalized_name$());\n"
+    "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "  set$capitalized_name$(input.readInt32());\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (has$capitalized_name$()) {\n"
+    "  output.writeInt32($number$, get$capitalized_name$());\n"
+    "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (has$capitalized_name$()) {\n"
+    "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+    "    .computeInt32Size($number$, get$capitalized_name$());\n"
+    "}\n");
+}
+
+string EnumFieldGenerator::GetBoxedType() const {
+  return ClassName(params_, descriptor_->enum_type());
+}
+
+// ===================================================================
+
+RepeatedEnumFieldGenerator::
+RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetEnumVariables(params, descriptor, &variables_);
+  if (descriptor_->options().packed()) {
+    GOOGLE_LOG(FATAL) << "MicroRuntime does not support packed";
+  }
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+void RepeatedEnumFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  if (params_.java_use_vector()) {
+    printer->Print(variables_,
+      "private java.util.Vector $name$_ = new java.util.Vector();\n"
+      "public java.util.Vector get$capitalized_name$List() {\n"
+      "  return $name$_;\n"
+      "}\n"
+      "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
+      "public int get$capitalized_name$(int index) {\n"
+      "  return ((Integer)$name$_.elementAt(index)).intValue();\n"
+      "}\n"
+      "public $message_name$ set$capitalized_name$(int index, int value) {\n"
+      "  $name$_.setElementAt(new Integer(value), index);\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ add$capitalized_name$(int value) {\n"
+      "  $name$_.addElement(new Integer(value));\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ clear$capitalized_name$() {\n"
+      "  $name$_.removeAllElements();\n"
+      "  return this;\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "private java.util.List<Integer> $name$_ =\n"
+      "  java.util.Collections.emptyList();\n"
+      "public java.util.List<Integer> get$capitalized_name$List() {\n"
+      "  return $name$_;\n"   // note:  unmodifiable list
+      "}\n"
+      "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
+      "public int get$capitalized_name$(int index) {\n"
+      "  return $name$_.get(index);\n"
+      "}\n"
+      "public $message_name$ set$capitalized_name$(int index, int value) {\n"
+      "  $name$_.set(index, value);\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ add$capitalized_name$(int value) {\n"
+      "  if ($name$_.isEmpty()) {\n"
+      "    $name$_ = new java.util.ArrayList<java.lang.Integer>();\n"
+      "  }\n"
+      "  $name$_.add(value);\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ clear$capitalized_name$() {\n"
+      "  $name$_ = java.util.Collections.emptyList();\n"
+      "  return this;\n"
+      "}\n");
+  }
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "private int $name$MemoizedSerializedSize;\n");
+  }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  if (params_.java_use_vector()) {
+    printer->Print(variables_,
+      "if (other.$name$_.size() != 0) {\n"
+      "  for (int i = 0; i < other.$name$_.size(); i++)) {\n"
+      "    result.$name$_.addElement(other.$name$_.elementAt(i));\n"
+      "  }\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "if (!other.$name$_.isEmpty()) {\n"
+      "  if (result.$name$_.isEmpty()) {\n"
+      "    result.$name$_ = new java.util.ArrayList<java.lang.Integer>();\n"
+      "  }\n"
+      "  result.$name$_.addAll(other.$name$_);\n"
+      "}\n");
+  }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  // If packed, set up the while loop
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "int length = input.readRawVarint32();\n"
+      "int oldLimit = input.pushLimit(length);\n"
+      "while(input.getBytesUntilLimit() > 0) {\n");
+    printer->Indent();
+  }
+
+  // Read and store the enum
+  printer->Print(variables_,
+    "  add$capitalized_name$(input.readInt32());\n");
+
+  if (descriptor_->options().packed()) {
+    printer->Outdent();
+    printer->Print(variables_,
+      "}\n"
+      "input.popLimit(oldLimit);\n");
+  }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+        "if (get$capitalized_name$List().size() > 0) {\n"
+        "  output.writeRawVarint32($tag$);\n"
+        "  output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+        "}\n");
+    if (params_.java_use_vector()) {
+      printer->Print(variables_,
+        "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
+        "  output.writeRawVarint32(get$capitalized_name$(i));\n"
+        "}\n");
+    } else {
+      printer->Print(variables_,
+        "for ($type$ element : get$capitalized_name$List()) {\n"
+        "  output.writeRawVarint32(element.getNumber());\n"
+        "}\n");
+    }
+  } else {
+    if (params_.java_use_vector()) {
+      printer->Print(variables_,
+        "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
+        "  output.writeInt32($number$, (int)get$capitalized_name$(i));\n"
+        "}\n");
+    } else {
+      printer->Print(variables_,
+        "for (java.lang.Integer element : get$capitalized_name$List()) {\n"
+        "  output.writeInt32($number$, element);\n"
+        "}\n");
+    }
+  }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "{\n"
+    "  int dataSize = 0;\n");
+    printer->Indent();
+  if (params_.java_use_vector()) {
+    printer->Print(variables_,
+      "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
+      "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+      "    .computeInt32SizeNoTag(get$capitalized_name$(i));\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "for (java.lang.Integer element : get$capitalized_name$List()) {\n"
+      "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+      "    .computeInt32SizeNoTag(element);\n"
+      "}\n");
+  }
+  printer->Print(
+      "size += dataSize;\n");
+  if (descriptor_->options().packed()) {
+      printer->Print(variables_,
+        "if (get$capitalized_name$List().size() != 0) {"
+        "  size += $tag_size$;\n"
+        "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+        "    .computeRawVarint32Size(dataSize);\n"
+        "}");
+  } else {
+    printer->Print(variables_,
+        "size += $tag_size$ * get$capitalized_name$List().size();\n");
+  }
+
+  // cache the data size for packed fields.
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "$name$MemoizedSerializedSize = dataSize;\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+string RepeatedEnumFieldGenerator::GetBoxedType() const {
+  return ClassName(params_, descriptor_->enum_type());
+}
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum_field.h b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum_field.h
new file mode 100644
index 0000000..ab671c1
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_enum_field.h
@@ -0,0 +1,94 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javamicro/javamicro_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+class EnumFieldGenerator : public FieldGenerator {
+ public:
+  explicit EnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params);
+  ~EnumFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateMergingCode(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, const Params& params);
+  ~RepeatedEnumFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateMergingCode(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 javamicro
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_field.cc b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_field.cc
new file mode 100644
index 0000000..a2ea4f9
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_field.cc
@@ -0,0 +1,102 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/javamicro/javamicro_field.h>
+#include <google/protobuf/compiler/javamicro/javamicro_helpers.h>
+#include <google/protobuf/compiler/javamicro/javamicro_primitive_field.h>
+#include <google/protobuf/compiler/javamicro/javamicro_enum_field.h>
+#include <google/protobuf/compiler/javamicro/javamicro_message_field.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+FieldGenerator::~FieldGenerator() {}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, const Params &params)
+  : 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), params));
+  }
+  for (int i = 0; i < descriptor->extension_count(); i++) {
+    extension_generators_[i].reset(MakeGenerator(descriptor->extension(i), params));
+  }
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field, const Params &params) {
+  if (field->is_repeated()) {
+    switch (GetJavaType(field)) {
+      case JAVATYPE_MESSAGE:
+        return new RepeatedMessageFieldGenerator(field, params);
+      case JAVATYPE_ENUM:
+        return new RepeatedEnumFieldGenerator(field, params);
+      default:
+        return new RepeatedPrimitiveFieldGenerator(field, params);
+    }
+  } else {
+    switch (GetJavaType(field)) {
+      case JAVATYPE_MESSAGE:
+        return new MessageFieldGenerator(field, params);
+      case JAVATYPE_ENUM:
+        return new EnumFieldGenerator(field, params);
+      default:
+        return new PrimitiveFieldGenerator(field, params);
+    }
+  }
+}
+
+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 javamicro
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_field.h b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_field.h
new file mode 100644
index 0000000..1530778
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_field.h
@@ -0,0 +1,98 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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>
+#include <google/protobuf/compiler/javamicro/javamicro_params.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+class FieldGenerator {
+ public:
+  //FieldGenerator() {}
+  FieldGenerator(const Params& params) : params_(params) {}
+  virtual ~FieldGenerator();
+
+  virtual void GenerateMembers(io::Printer* printer) const = 0;
+  virtual void GenerateMergingCode(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;
+
+ protected:
+  const Params& params_;
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
+};
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+class FieldGeneratorMap {
+ public:
+  explicit FieldGeneratorMap(const Descriptor* descriptor, const Params &params);
+  ~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, const Params &params);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_file.cc b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_file.cc
new file mode 100644
index 0000000..43bf012
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_file.cc
@@ -0,0 +1,237 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <iostream>
+
+#include <google/protobuf/compiler/javamicro/javamicro_file.h>
+#include <google/protobuf/compiler/javamicro/javamicro_enum.h>
+#include <google/protobuf/compiler/javamicro/javamicro_helpers.h>
+#include <google/protobuf/compiler/javamicro/javamicro_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 javamicro {
+
+namespace {
+
+// Recursively searches the given message to see if it contains any extensions.
+bool UsesExtensions(const Message& message) {
+  const Reflection* reflection = message.GetReflection();
+
+  // We conservatively assume that unknown fields are extensions.
+  if (reflection->GetUnknownFields(message).field_count() > 0) return true;
+
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(message, &fields);
+
+  for (int i = 0; i < fields.size(); i++) {
+    if (fields[i]->is_extension()) return true;
+
+    if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (fields[i]->is_repeated()) {
+        int size = reflection->FieldSize(message, fields[i]);
+        for (int j = 0; j < size; j++) {
+          const Message& sub_message =
+            reflection->GetRepeatedMessage(message, fields[i], j);
+          if (UsesExtensions(sub_message)) return true;
+        }
+      } else {
+        const Message& sub_message = reflection->GetMessage(message, fields[i]);
+        if (UsesExtensions(sub_message)) return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+}  // namespace
+
+FileGenerator::FileGenerator(const FileDescriptor* file, const Params& params)
+  : file_(file),
+    params_(params),
+    java_package_(FileJavaPackage(params, file)),
+    classname_(FileClassName(params, file)) {}
+
+FileGenerator::~FileGenerator() {}
+
+bool FileGenerator::Validate(string* error) {
+  // Check for extensions
+  FileDescriptorProto file_proto;
+  file_->CopyTo(&file_proto);
+  if (UsesExtensions(file_proto)) {
+    error->assign(file_->name());
+    error->append(
+      ": Java MICRO_RUNTIME does not support extensions\"");
+    return false;
+  }
+
+  if (file_->service_count() != 0) {
+    error->assign(file_->name());
+    error->append(
+      ": Java MICRO_RUNTIME does not support services\"");
+    return false;
+  }
+
+  if (!IsOuterClassNeeded(params_, file_)) {
+    return true;
+  }
+
+  // Check whether legacy javamicro generator would omit the outer class.
+  if (!params_.has_java_outer_classname(file_->name())
+      && file_->message_type_count() == 1
+      && file_->enum_type_count() == 0 && file_->extension_count() == 0) {
+    cout << "INFO: " << file_->name() << ":" << endl;
+    cout << "Javamicro generator has changed to align with java generator. "
+        "An outer class will be created for this file and the single message "
+        "in the file will become a nested class. Use java_multiple_files to "
+        "skip generating the outer class, or set an explicit "
+        "java_outer_classname to suppress this message." << endl;
+  }
+
+  // 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; !found_conflict && i < file_->message_type_count(); i++) {
+    if (file_->message_type(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();
+
+  // -----------------------------------------------------------------
+
+  for (int i = 0; i < file_->enum_type_count(); i++) {
+    EnumGenerator(file_->enum_type(i), params_).Generate(printer);
+  }
+
+  if (!params_.java_multiple_files(file_->name())) {
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      MessageGenerator(file_->message_type(i), params_).Generate(printer);
+    }
+  }
+
+  // Static variables.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    // TODO(kenton):  Reuse MessageGenerator objects?
+    MessageGenerator(file_->message_type(i), params_).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,
+                            const Params& params) {
+  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, params).Generate(&printer);
+}
+
+void FileGenerator::GenerateSiblings(const string& package_dir,
+                                     OutputDirectory* output_directory,
+                                     vector<string>* file_list) {
+  if (params_.java_multiple_files(file_->name())) {
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      GenerateSibling<MessageGenerator>(package_dir, java_package_,
+                                        file_->message_type(i),
+                                        output_directory, file_list, params_);
+    }
+  }
+}
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_file.h b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_file.h
new file mode 100644
index 0000000..1804abf
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_file.h
@@ -0,0 +1,92 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/javamicro/javamicro_params.h>
+
+namespace google {
+namespace protobuf {
+  class FileDescriptor;        // descriptor.h
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+class FileGenerator {
+ public:
+  explicit FileGenerator(const FileDescriptor* file, const Params& params);
+  ~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_;
+  const Params& params_;
+  string java_package_;
+  string classname_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
+};
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_generator.cc b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_generator.cc
new file mode 100644
index 0000000..1b74509
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_generator.cc
@@ -0,0 +1,210 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/javamicro/javamicro_params.h>
+#include <google/protobuf/compiler/javamicro/javamicro_generator.h>
+#include <google/protobuf/compiler/javamicro/javamicro_file.h>
+#include <google/protobuf/compiler/javamicro/javamicro_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 javamicro {
+
+void UpdateParamsRecursively(Params& params,
+    const FileDescriptor* file) {
+  // Add any parameters for this file
+  if (file->options().has_java_outer_classname()) {
+    params.set_java_outer_classname(
+      file->name(), file->options().java_outer_classname());
+  }
+  if (file->options().has_java_package()) {
+    params.set_java_package(
+      file->name(), file->options().java_package());
+  }
+  if (file->options().has_java_multiple_files()) {
+    params.set_java_multiple_files(
+      file->name(), file->options().java_multiple_files());
+  }
+
+  // Loop through all dependent files recursively
+  // adding dep
+  for (int i = 0; i < file->dependency_count(); i++) {
+    UpdateParamsRecursively(params, file->dependency(i));
+  }
+}
+
+JavaMicroGenerator::JavaMicroGenerator() {}
+JavaMicroGenerator::~JavaMicroGenerator() {}
+
+bool JavaMicroGenerator::Generate(const FileDescriptor* file,
+                             const string& parameter,
+                             OutputDirectory* output_directory,
+                             string* error) const {
+  vector<pair<string, string> > options;
+
+//  GOOGLE_LOG(INFO) << "wink: JavaMicroGenerator::Generate INFO";
+//  GOOGLE_LOG(WARNING) << "wink: JavaMicroGenerator::Generate WARNING";
+//  GOOGLE_LOG(ERROR) << "wink: JavaMicroGenerator::Generate ERROR";
+//  GOOGLE_LOG(FATAL) << "wink: JavaMicroGenerator::Generate";
+
+  ParseGeneratorParameter(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;
+  Params params(file->name());
+
+  // Update per file params
+  UpdateParamsRecursively(params, file);
+
+  // Replace any existing options with ones from command line
+  for (int i = 0; i < options.size(); i++) {
+    // GOOGLE_LOG(WARNING) << "first=" << options[i].first
+    //                     << " second=" << options[i].second;
+    if (options[i].first == "output_list_file") {
+      output_list_file = options[i].second;
+    } else if (options[i].first == "opt") {
+      if (options[i].second == "speed") {
+        params.set_optimization(JAVAMICRO_OPT_SPEED);
+      } else if (options[i].second == "space") {
+        params.set_optimization(JAVAMICRO_OPT_SPACE);
+      } else {
+        *error = "Unknown javamicro generator option: opt="
+                  + options[i].second + " expecting opt=space or opt=speed";
+        return false;
+      }
+    } else if (options[i].first == "java_package") {
+        vector<string> parts;
+        SplitStringUsing(options[i].second, "|", &parts);
+        if (parts.size() != 2) {
+          *error = "Bad java_package, expecting filename|PackageName found '"
+            + options[i].second + "'";
+          return false;
+        }
+        params.set_java_package(parts[0], parts[1]);
+    } else if (options[i].first == "java_outer_classname") {
+        vector<string> parts;
+        SplitStringUsing(options[i].second, "|", &parts);
+        if (parts.size() != 2) {
+          *error = "Bad java_outer_classname, "
+                   "expecting filename|ClassName found '"
+                   + options[i].second + "'";
+          return false;
+        }
+        params.set_java_outer_classname(parts[0], parts[1]);
+    } else if (options[i].first == "java_multiple_files") {
+        params.set_override_java_multiple_files(options[i].second == "true");
+    } else if (options[i].first == "java_use_vector") {
+        params.set_java_use_vector(options[i].second == "true");
+    } else {
+      *error = "Ignore unknown javamicro generator option: " + options[i].first;
+    }
+  }
+
+#if 0
+  GOOGLE_LOG(WARNING) << "optimization()=" << params.optimization();
+  GOOGLE_LOG(WARNING) << "java_multiple_files()=" << params.java_multiple_files();
+  GOOGLE_LOG(WARNING) << "java_use_vector()=" << params.java_use_vector();
+
+  GOOGLE_LOG(WARNING) << "----------";
+  for (Params::NameMap::const_iterator it = params.java_packages().begin();
+       it != params.java_packages().end();
+       ++it) {
+    GOOGLE_LOG(WARNING) << "cn.filename=" << it->first << " package=" << it->second;
+  }
+  for (Params::NameMap::const_iterator it = params.java_outer_classnames().begin();
+       it != params.java_outer_classnames().end();
+       ++it) {
+    GOOGLE_LOG(WARNING) << "cn.filename=" << it->first << " classname=" << it->second;
+  }
+  GOOGLE_LOG(WARNING) << "==========";
+
+#endif
+
+  // -----------------------------------------------------------------
+
+  FileGenerator file_generator(file, params);
+  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;
+
+  if (IsOuterClassNeeded(params, file)) {
+    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/protobuf/src/google/protobuf/compiler/javamicro/javamicro_generator.h b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_generator.h
new file mode 100644
index 0000000..a1c33b7
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_generator.h
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Generates Java micro code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MICRO_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_MICRO_GENERATOR_H__
+
+#include <string>
+#include <google/protobuf/compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+// CodeGenerator implementation which generates Java micro code.  If you create your
+// own protocol compiler binary and you want it to support Java output for the
+// micro runtime, you can do so by registering an instance of this CodeGenerator with
+// the CommandLineInterface in your main() function.
+class LIBPROTOC_EXPORT JavaMicroGenerator : public CodeGenerator {
+ public:
+  JavaMicroGenerator();
+  ~JavaMicroGenerator();
+
+  // implements CodeGenerator ----------------------------------------
+  bool Generate(const FileDescriptor* file,
+                const string& parameter,
+                OutputDirectory* output_directory,
+                string* error) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaMicroGenerator);
+};
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MICRO_GENERATOR_H__
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc
new file mode 100644
index 0000000..f6ce653
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc
@@ -0,0 +1,356 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <limits>
+#include <vector>
+
+#include <google/protobuf/compiler/javamicro/javamicro_helpers.h>
+#include <google/protobuf/compiler/javamicro/javamicro_params.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+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 Params& params, const FileDescriptor* file) {
+  if (params.has_java_outer_classname(file->name())) {
+    return params.java_outer_classname(file->name());
+  } else {
+    // Use the filename itself with underscores removed
+    // and a CamelCase style name.
+    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 Params& params, const FileDescriptor* file) {
+  if (params.has_java_package(file->name())) {
+    return params.java_package(file->name());
+  } else {
+    string result = kDefaultPackage;
+    if (!file->package().empty()) {
+      if (!result.empty()) result += '.';
+      result += file->package();
+    }
+    return result;
+  }
+}
+
+bool IsOuterClassNeeded(const Params& params, const FileDescriptor* file) {
+  // Enums and extensions need the outer class as the scope.
+  if (file->enum_type_count() != 0 || file->extension_count() != 0) {
+    return true;
+  }
+  // Messages need the outer class only if java_multiple_files is false.
+  return !params.java_multiple_files(file->name());
+}
+
+string ToJavaName(const Params& params, const string& name, bool is_class,
+    const Descriptor* parent, const FileDescriptor* file) {
+  string result;
+  if (parent != NULL) {
+    result.append(ClassName(params, parent));
+  } else if (is_class && params.java_multiple_files(file->name())) {
+    result.append(FileJavaPackage(params, file));
+  } else {
+    result.append(ClassName(params, file));
+  }
+  if (!result.empty()) result.append(1, '.');
+  result.append(name); // TODO(maxtroy): add '_' if name is a Java keyword.
+  return result;
+}
+
+string ClassName(const Params& params, const FileDescriptor* descriptor) {
+  string result = FileJavaPackage(params, descriptor);
+  if (!result.empty()) result += '.';
+  result += FileClassName(params, descriptor);
+  return result;
+}
+
+string ClassName(const Params& params, const EnumDescriptor* descriptor) {
+  // An enum's class name is the enclosing message's class name or the outer
+  // class name.
+  const Descriptor* parent = descriptor->containing_type();
+  if (parent != NULL) {
+    return ClassName(params, parent);
+  } else {
+    return ClassName(params, descriptor->file());
+  }
+}
+
+string FieldConstantName(const FieldDescriptor *field) {
+  string name = field->name() + "_FIELD_NUMBER";
+  UpperString(&name);
+  return name;
+}
+
+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.micro.ByteStringMicro";
+    case JAVATYPE_ENUM   : return "java.lang.Integer";
+    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;
+}
+
+bool AllAscii(const string& text) {
+  for (int i = 0; i < text.size(); i++) {
+    if ((text[i] & 0x80) != 0) {
+      return false;
+    }
+  }
+  return true;
+}
+
+string DefaultValue(const Params& params, 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: {
+     double value = field->default_value_double();
+      if (value == numeric_limits<double>::infinity()) {
+        return "Double.POSITIVE_INFINITY";
+      } else if (value == -numeric_limits<double>::infinity()) {
+        return "Double.NEGATIVE_INFINITY";
+      } else if (value != value) {
+        return "Double.NaN";
+      } else {
+        return SimpleDtoa(value) + "D";
+      }
+    }
+    case FieldDescriptor::CPPTYPE_FLOAT: {
+      float value = field->default_value_float();
+      if (value == numeric_limits<float>::infinity()) {
+        return "Float.POSITIVE_INFINITY";
+      } else if (value == -numeric_limits<float>::infinity()) {
+        return "Float.NEGATIVE_INFINITY";
+      } else if (value != value) {
+        return "Float.NaN";
+      } else {
+        return SimpleFtoa(value) + "F";
+      }
+    }
+    case FieldDescriptor::CPPTYPE_BOOL:
+      return field->default_value_bool() ? "true" : "false";
+    case FieldDescriptor::CPPTYPE_STRING:
+      if (field->type() == FieldDescriptor::TYPE_BYTES) {
+        if (field->has_default_value()) {
+          // See comments in Internal.java for gory details.
+          return strings::Substitute(
+            "com.google.protobuf.micro.ByteStringMicro.copyFromUtf8(\"$0\")",
+            CEscape(field->default_value_string()));
+        } else {
+          return "com.google.protobuf.micro.ByteStringMicro.EMPTY";
+        }
+      } else {
+        if (AllAscii(field->default_value_string())) {
+          // All chars are ASCII.  In this case CEscape() works fine.
+          return "\"" + CEscape(field->default_value_string()) + "\"";
+        } else {
+          // See comments in Internal.java for gory details.
+          // BUG: Internal NOT SUPPORTED need to fix!!
+          return strings::Substitute(
+            "com.google.protobuf.micro.Internal.stringDefaultValue(\"$0\")",
+            CEscape(field->default_value_string()));
+        }
+      }
+
+    case FieldDescriptor::CPPTYPE_ENUM:
+      return ClassName(params, field->enum_type()) + "." +
+             field->default_value_enum()->name();
+
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      return ClassName(params, field->message_type()) + ".getDefaultInstance()";
+
+    // No default because we want the compiler to complain if any new
+    // types are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return "";
+}
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_helpers.h b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_helpers.h
new file mode 100644
index 0000000..6131c15
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_helpers.h
@@ -0,0 +1,138 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/compiler/javamicro/javamicro_params.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+// 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 Params& params, const FileDescriptor* file);
+
+// Returns the file's Java package name.
+string FileJavaPackage(const Params& params, const FileDescriptor* file);
+
+// Returns whether the Java outer class is needed, i.e. whether the option
+// java_multiple_files is false, or the proto file contains any file-scope
+// enums/extensions.
+bool IsOuterClassNeeded(const Params& params, const FileDescriptor* file);
+
+// Converts the given simple name of a proto entity to its fully-qualified name
+// in the Java namespace, given that it is in the given file enclosed in the
+// given parent message (or NULL for file-scope entities). Whether the file's
+// outer class name should be included in the return value depends on factors
+// inferrable from the given arguments, including is_class which indicates
+// whether the entity translates to a Java class.
+string ToJavaName(const Params& params, const string& name, bool is_class,
+    const Descriptor* parent, const FileDescriptor* file);
+
+// These return the fully-qualified class name corresponding to the given
+// descriptor.
+inline string ClassName(const Params& params, const Descriptor* descriptor) {
+  return ToJavaName(params, descriptor->name(), true,
+                    descriptor->containing_type(), descriptor->file());
+}
+string ClassName(const Params& params, const EnumDescriptor* descriptor);
+inline string ClassName(const Params& params,
+    const ServiceDescriptor* descriptor) {
+  return ToJavaName(params, descriptor->name(), true, NULL, descriptor->file());
+}
+inline string ExtensionIdentifierName(const Params& params,
+    const FieldDescriptor* descriptor) {
+  return ToJavaName(params, descriptor->name(), false,
+                    descriptor->extension_scope(), descriptor->file());
+}
+string ClassName(const Params& params, const FileDescriptor* descriptor);
+
+// Get the unqualified name that should be used for a field's field
+// number constant.
+string FieldConstantName(const FieldDescriptor *field);
+
+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);
+
+string DefaultValue(const Params& params, const FieldDescriptor* field);
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message.cc b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message.cc
new file mode 100644
index 0000000..cf48b3c
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message.cc
@@ -0,0 +1,480 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javamicro/javamicro_message.h>
+#include <google/protobuf/compiler/javamicro/javamicro_enum.h>
+#include <google/protobuf/compiler/javamicro/javamicro_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 javamicro {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+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();
+  }
+};
+
+// 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, const Params& params)
+  : params_(params),
+    descriptor_(descriptor),
+    field_generators_(descriptor, params) {
+}
+
+MessageGenerator::~MessageGenerator() {}
+
+void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
+  // 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), params_)
+      .GenerateStaticVariables(printer);
+  }
+}
+
+void MessageGenerator::GenerateStaticVariableInitializers(
+    io::Printer* printer) {
+  // Generate static member initializers for all nested types.
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    // TODO(kenton):  Reuse MessageGenerator objects?
+    MessageGenerator(descriptor_->nested_type(i), params_)
+      .GenerateStaticVariableInitializers(printer);
+  }
+
+  if (descriptor_->extension_count() != 0) {
+    GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n";
+  }
+}
+
+void MessageGenerator::Generate(io::Printer* printer) {
+  const string& file_name = descriptor_->file()->name();
+  bool is_own_file =
+    params_.java_multiple_files(file_name)
+      && descriptor_->containing_type() == NULL;
+
+  if ((descriptor_->extension_count() != 0)
+      || (descriptor_->extension_range_count() != 0)) {
+    GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n";
+  }
+
+  // Note: Fields (which will be emitted in the loop, below) may have the same names as fields in
+  // the inner or outer class.  This causes Java warnings, but is not fatal, so we suppress those
+  // warnings here in the class declaration.
+  printer->Print(
+    "@SuppressWarnings(\"hiding\")\n"
+    "public $modifiers$ final class $classname$ extends\n"
+    "    com.google.protobuf.micro.MessageMicro {\n",
+    "modifiers", is_own_file ? "" : "static",
+    "classname", descriptor_->name());
+  printer->Indent();
+  printer->Print(
+    "public $classname$() {}\n"
+    "\n",
+    "classname", descriptor_->name());
+
+  // Nested types and extensions
+  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+    EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer);
+  }
+
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer);
+  }
+
+  // Fields
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    PrintFieldComment(printer, descriptor_->field(i));
+    printer->Print("public static final int $constant_name$ = $number$;\n",
+      "constant_name", FieldConstantName(descriptor_->field(i)),
+      "number", SimpleItoa(descriptor_->field(i)->number()));
+    field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
+    printer->Print("\n");
+  }
+
+  GenerateClear(printer);
+  GenerateIsInitialized(printer);
+  GenerateMessageSerializationMethods(printer);
+  GenerateMergeFromMethods(printer);
+  GenerateParseFromMethods(printer);
+
+  printer->Outdent();
+  printer->Print("}\n\n");
+}
+
+// ===================================================================
+
+void MessageGenerator::
+GenerateMessageSerializationMethods(io::Printer* printer) {
+  scoped_array<const FieldDescriptor*> sorted_fields(
+    SortFieldsByNumber(descriptor_));
+
+  if (descriptor_->extension_range_count() != 0) {
+    GOOGLE_LOG(FATAL) << "Extensions not supported in MICRO_RUNTIME\n";
+  }
+
+  // writeTo only throws an exception if it contains one or more fields to write
+  if (descriptor_->field_count() > 0) {
+    printer->Print(
+      "@Override\n"
+      "public void writeTo(com.google.protobuf.micro.CodedOutputStreamMicro output)\n"
+      "                    throws java.io.IOException {\n");
+  } else {
+    printer->Print(
+      "@Override\n"
+      "public void writeTo(com.google.protobuf.micro.CodedOutputStreamMicro output) {\n");
+  }
+  printer->Indent();
+
+  // Output the fields in sorted order
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+      GenerateSerializeOneField(printer, sorted_fields[i]);
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "}\n"
+    "\n"
+    "private int cachedSize = -1;\n"
+    "@Override\n"
+    "public int getCachedSize() {\n"
+    "  if (cachedSize < 0) {\n"
+    "    // getSerializedSize sets cachedSize\n"
+    "    getSerializedSize();\n"
+    "  }\n"
+    "  return cachedSize;\n"
+    "}\n"
+    "\n"
+    "@Override\n"
+    "public int getSerializedSize() {\n"
+    "  int size = 0;\n");
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "  cachedSize = size;\n"
+    "  return size;\n"
+    "}\n"
+    "\n");
+}
+
+void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) {
+  scoped_array<const FieldDescriptor*> sorted_fields(
+    SortFieldsByNumber(descriptor_));
+
+  if (params_.java_use_vector()) {
+    printer->Print(
+      "@Override\n"
+      "public com.google.protobuf.micro.MessageMicro mergeFrom(\n"
+      "    com.google.protobuf.micro.CodedInputStreamMicro input)\n"
+      "    throws java.io.IOException {\n",
+      "classname", descriptor_->name());
+  } else {
+    printer->Print(
+      "@Override\n"
+      "public $classname$ mergeFrom(\n"
+      "    com.google.protobuf.micro.CodedInputStreamMicro input)\n"
+      "    throws java.io.IOException {\n",
+      "classname", descriptor_->name());
+  }
+  printer->Indent();
+
+  printer->Print(
+    "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
+    "  return this;\n"
+    "default: {\n"
+    "  if (!parseUnknownField(input, tag)) {\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 = WireFormatLite::MakeTag(field->number(),
+      WireFormat::WireTypeForField(field));
+
+    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::
+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(byte[] data)\n"
+    "    throws com.google.protobuf.micro.InvalidProtocolBufferMicroException {\n"
+    "  return ($classname$) (new $classname$().mergeFrom(data));\n"
+    "}\n"
+    "\n"
+    "public static $classname$ parseFrom(\n"
+    "        com.google.protobuf.micro.CodedInputStreamMicro input)\n"
+    "    throws java.io.IOException {\n"
+    "  return new $classname$().mergeFrom(input);\n"
+    "}\n"
+    "\n",
+    "classname", descriptor_->name());
+}
+
+void MessageGenerator::GenerateSerializeOneField(
+    io::Printer* printer, const FieldDescriptor* field) {
+  field_generators_.get(field).GenerateSerializationCode(printer);
+}
+
+void MessageGenerator::GenerateClear(io::Printer* printer) {
+  printer->Print(
+    "public final $classname$ clear() {\n",
+    "classname", descriptor_->name());
+  printer->Indent();
+
+  // Call clear for all of the fields.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    printer->Print(
+      "clear$name$();\n",
+      "name", UnderscoresToCapitalizedCamelCase(field));
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "  cachedSize = -1;\n"
+    "  return this;\n"
+    "}\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(params_, 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(params_, field->message_type()),
+            "name", UnderscoresToCapitalizedCamelCase(field));
+          break;
+        case FieldDescriptor::LABEL_REPEATED:
+          if (params_.java_use_vector()) {
+            printer->Print(
+              "for (int i = 0; i < get$name$List().size(); i++) {\n"
+              "  if (get$name$(i).isInitialized()) return false;\n"
+              "}\n",
+              "type", ClassName(params_, field->message_type()),
+              "name", UnderscoresToCapitalizedCamelCase(field));
+          } else {
+            printer->Print(
+              "for ($type$ element : get$name$List()) {\n"
+              "  if (!element.isInitialized()) return false;\n"
+              "}\n",
+              "type", ClassName(params_, 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 javamicro
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message.h b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message.h
new file mode 100644
index 0000000..f44c7a7
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message.h
@@ -0,0 +1,93 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javamicro/javamicro_params.h>
+#include <google/protobuf/compiler/javamicro/javamicro_field.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+class MessageGenerator {
+ public:
+  explicit MessageGenerator(const Descriptor* descriptor, const Params& params);
+  ~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);
+
+  // Output code which initializes the static variables generated by
+  // GenerateStaticVariables().
+  void GenerateStaticVariableInitializers(io::Printer* printer);
+
+  // Generate the class itself.
+  void Generate(io::Printer* printer);
+
+ private:
+  void GenerateMessageSerializationMethods(io::Printer* printer);
+  void GenerateMergeFromMethods(io::Printer* printer);
+  void GenerateParseFromMethods(io::Printer* printer);
+  void GenerateSerializeOneField(io::Printer* printer,
+                                 const FieldDescriptor* field);
+
+  void GenerateClear(io::Printer* printer);
+  void GenerateIsInitialized(io::Printer* printer);
+
+  const Params& params_;
+  const Descriptor* descriptor_;
+  FieldGeneratorMap field_generators_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message_field.cc b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message_field.cc
new file mode 100644
index 0000000..103c302
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message_field.cc
@@ -0,0 +1,302 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javamicro/javamicro_message_field.h>
+#include <google/protobuf/compiler/javamicro/javamicro_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 javamicro {
+
+namespace {
+
+// TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
+//   repeat code between this and the other field types.
+void SetMessageVariables(const Params& params,
+    const FieldDescriptor* descriptor, map<string, string>* variables) {
+  (*variables)["name"] =
+    UnderscoresToCamelCase(descriptor);
+  (*variables)["capitalized_name"] =
+    UnderscoresToCapitalizedCamelCase(descriptor);
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["type"] = ClassName(params, descriptor->message_type());
+  (*variables)["group_or_message"] =
+    (descriptor->type() == FieldDescriptor::TYPE_GROUP) ?
+    "Group" : "Message";
+  (*variables)["message_name"] = descriptor->containing_type()->name();
+  //(*variables)["message_type"] = descriptor->message_type()->name();
+}
+
+}  // namespace
+
+// ===================================================================
+
+MessageFieldGenerator::
+MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetMessageVariables(params, descriptor, &variables_);
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {}
+
+void MessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  printer->Print(variables_,
+    "private boolean has$capitalized_name$;\n"
+//    "private $type$ $name$_ = null;\n"
+//    "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
+//    "public $type$ get$capitalized_name$() { return $name$_; }\n"
+    "private $type$ $name$_ = null;\n"
+    "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
+    "public $type$ get$capitalized_name$() { return $name$_; }\n"
+    "public $message_name$ set$capitalized_name$($type$ value) {\n"
+    "  if (value == null) {\n"
+    "    throw new NullPointerException();\n"
+    "  }\n"
+    "  has$capitalized_name$ = true;\n"
+    "  $name$_ = value;\n"
+    "  return this;\n"
+    "}\n"
+    "public $message_name$ clear$capitalized_name$() {\n"
+    "  has$capitalized_name$ = false;\n"
+    "  $name$_ = null;\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::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$type$ value = new $type$();\n");
+
+  if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
+    printer->Print(variables_,
+      "input.readGroup(value, $number$);\n");
+  } else {
+    printer->Print(variables_,
+      "input.readMessage(value);\n");
+  }
+
+  printer->Print(variables_,
+    "set$capitalized_name$(value);\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.micro.CodedOutputStreamMicro\n"
+    "    .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
+    "}\n");
+}
+
+string MessageFieldGenerator::GetBoxedType() const {
+  return ClassName(params_, descriptor_->message_type());
+}
+
+// ===================================================================
+
+RepeatedMessageFieldGenerator::
+RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetMessageVariables(params, descriptor, &variables_);
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+
+void RepeatedMessageFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  if (params_.java_use_vector()) {
+    printer->Print(variables_,
+      "private java.util.Vector $name$_ = new java.util.Vector();\n"
+      "public java.util.Vector get$capitalized_name$List() {\n"
+      "  return $name$_;\n"
+      "}\n"
+      "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
+      "public $type$ get$capitalized_name$(int index) {\n"
+      "  return ($type$) $name$_.elementAt(index);\n"
+      "}\n"
+      "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
+      "  if (value == null) {\n"
+      "    throw new NullPointerException();\n"
+      "  }\n"
+      "  $name$_.setElementAt(value, index);\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ add$capitalized_name$($type$ value) {\n"
+      "  if (value == null) {\n"
+      "    throw new NullPointerException();\n"
+      "  }\n"
+      "  $name$_.addElement(value);\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ clear$capitalized_name$() {\n"
+      "  $name$_.removeAllElements();\n"
+      "  return this;\n"
+      "}\n");
+  } else {
+    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"
+      "}\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"
+      "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
+      "  if (value == null) {\n"
+      "    throw new NullPointerException();\n"
+      "  }\n"
+      "  $name$_.set(index, value);\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ add$capitalized_name$($type$ value) {\n"
+      "  if (value == null) {\n"
+      "    throw new NullPointerException();\n"
+      "  }\n"
+      "  if ($name$_.isEmpty()) {\n"
+      "    $name$_ = new java.util.ArrayList<$type$>();\n"
+      "  }\n"
+      "  $name$_.add(value);\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ clear$capitalized_name$() {\n"
+      "  $name$_ = java.util.Collections.emptyList();\n"
+      "  return this;\n"
+      "}\n");
+  }
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  if (params_.java_use_vector()) {
+    printer->Print(variables_,
+      "if (other.$name$_.size() != 0) {\n"
+      "  for (int i = 0; i < other.$name$_.size(); i++) {\n"
+      "    result.$name$_.addElement(other.$name$_.elementAt(i));\n"
+      "  }\n"
+      "}\n");
+  } else {
+    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::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$type$ value = new $type$();\n");
+
+  if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
+    printer->Print(variables_,
+      "input.readGroup(value, $number$);\n");
+  } else {
+    printer->Print(variables_,
+      "input.readMessage(value);\n");
+  }
+
+  printer->Print(variables_,
+    "add$capitalized_name$(value);\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  if (params_.java_use_vector()) {
+    printer->Print(variables_,
+      "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
+      "  output.write$group_or_message$($number$, get$capitalized_name$(i));\n"
+      "}\n");
+  } else {
+    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 {
+  if (params_.java_use_vector()) {
+    printer->Print(variables_,
+      "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
+      "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+      "    .compute$group_or_message$Size($number$, get$capitalized_name$(i));\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "for ($type$ element : get$capitalized_name$List()) {\n"
+      "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+      "    .compute$group_or_message$Size($number$, element);\n"
+      "}\n");
+  }
+}
+
+string RepeatedMessageFieldGenerator::GetBoxedType() const {
+  return ClassName(params_, descriptor_->message_type());
+}
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message_field.h b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message_field.h
new file mode 100644
index 0000000..a32aa4e
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_message_field.h
@@ -0,0 +1,95 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javamicro/javamicro_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+class MessageFieldGenerator : public FieldGenerator {
+ public:
+  explicit MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params);
+  ~MessageFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateMergingCode(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,
+        const Params& params);
+  ~RepeatedMessageFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateMergingCode(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 javamicro
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_params.h b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_params.h
new file mode 100644
index 0000000..7e47a00
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_params.h
@@ -0,0 +1,170 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2010 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: wink@google.com (Wink Saville)
+
+#ifndef PROTOBUF_COMPILER_JAVAMICRO_JAVAMICRO_PARAMS_H_
+#define PROTOBUF_COMPILER_JAVAMICRO_JAVAMICRO_PARAMS_H_
+
+#include <map>
+#include <set>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+enum eOptimization { JAVAMICRO_OPT_SPEED, JAVAMICRO_OPT_SPACE, JAVAMICRO_OPT_DEFAULT = JAVAMICRO_OPT_SPACE };
+enum eMultipleFiles { JAVAMICRO_MUL_UNSET, JAVAMICRO_MUL_FALSE, JAVAMICRO_MUL_TRUE };
+
+// Parameters for used by the generators
+class Params {
+ public:
+  typedef map<string, string> NameMap;
+  typedef set<string> NameSet;
+ private:
+  string empty_;
+  string base_name_;
+  eOptimization optimization_;
+  eMultipleFiles override_java_multiple_files_;
+  bool java_use_vector_;
+  NameMap java_packages_;
+  NameMap java_outer_classnames_;
+  NameSet java_multiple_files_;
+
+ public:
+  Params(const string & base_name) :
+    empty_(""),
+    base_name_(base_name),
+    optimization_(JAVAMICRO_OPT_DEFAULT),
+    override_java_multiple_files_(JAVAMICRO_MUL_UNSET),
+    java_use_vector_(false) {
+  }
+
+  const string& base_name() const {
+    return base_name_;
+  }
+
+  bool has_java_package(const string& file_name) const {
+    return java_packages_.find(file_name)
+                        != java_packages_.end();
+  }
+  void set_java_package(const string& file_name,
+      const string& java_package) {
+    java_packages_[file_name] = java_package;
+  }
+  const string& java_package(const string& file_name) const {
+    NameMap::const_iterator itr;
+
+    itr = java_packages_.find(file_name);
+    if  (itr == java_packages_.end()) {
+      return empty_;
+    } else {
+      return itr->second;
+    }
+  }
+  const NameMap& java_packages() {
+    return java_packages_;
+  }
+
+  bool has_java_outer_classname(const string& file_name) const {
+    return java_outer_classnames_.find(file_name)
+                        != java_outer_classnames_.end();
+  }
+  void set_java_outer_classname(const string& file_name,
+      const string& java_outer_classname) {
+    java_outer_classnames_[file_name] = java_outer_classname;
+  }
+  const string& java_outer_classname(const string& file_name) const {
+    NameMap::const_iterator itr;
+
+    itr = java_outer_classnames_.find(file_name);
+    if  (itr == java_outer_classnames_.end()) {
+      return empty_;
+    } else {
+      return itr->second;
+    }
+  }
+  const NameMap& java_outer_classnames() {
+    return java_outer_classnames_;
+  }
+
+  void set_optimization(eOptimization optimization) {
+    optimization_ = optimization;
+  }
+  eOptimization optimization() const {
+    return optimization_;
+  }
+
+  void set_override_java_multiple_files(bool value) {
+    if (value) {
+      override_java_multiple_files_ = JAVAMICRO_MUL_TRUE;
+    } else {
+      override_java_multiple_files_ = JAVAMICRO_MUL_FALSE;
+    }
+  }
+  void clear_override_java_multiple_files() {
+    override_java_multiple_files_ = JAVAMICRO_MUL_UNSET;
+  }
+
+  void set_java_multiple_files(const string& file_name, bool value) {
+    if (value) {
+      java_multiple_files_.insert(file_name);
+    } else {
+      java_multiple_files_.erase(file_name);
+    }
+  }
+  bool java_multiple_files(const string& file_name) const {
+    switch (override_java_multiple_files_) {
+      case JAVAMICRO_MUL_FALSE:
+        return false;
+      case JAVAMICRO_MUL_TRUE:
+        return true;
+      default:
+        return java_multiple_files_.find(file_name)
+                != java_multiple_files_.end();
+    }
+  }
+
+  void set_java_use_vector(bool value) {
+    java_use_vector_ = value;
+  }
+  bool java_use_vector() const {
+    return java_use_vector_;
+  }
+
+};
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+#endif  // PROTOBUF_COMPILER_JAVAMICRO_JAVAMICRO_PARAMS_H_
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc
new file mode 100644
index 0000000..70f5ac8
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.cc
@@ -0,0 +1,676 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javamicro/javamicro_primitive_field.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/javamicro/javamicro_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 javamicro {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+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.micro.ByteStringMicro";
+    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;
+}
+
+bool IsReferenceType(JavaType type) {
+  switch (type) {
+    case JAVATYPE_INT    : return false;
+    case JAVATYPE_LONG   : return false;
+    case JAVATYPE_FLOAT  : return false;
+    case JAVATYPE_DOUBLE : return false;
+    case JAVATYPE_BOOLEAN: return false;
+    case JAVATYPE_STRING : return true;
+    case JAVATYPE_BYTES  : return true;
+    case JAVATYPE_ENUM   : return false;
+    case JAVATYPE_MESSAGE: return true;
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return false;
+}
+
+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;
+}
+
+// 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 WireFormatLite::kFixed32Size;
+    case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
+    case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
+    case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
+    case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
+    case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
+
+    case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::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;
+}
+
+// Return true if the type is a that has variable length
+// for instance String's.
+bool IsVariableLenType(JavaType type) {
+  switch (type) {
+    case JAVATYPE_INT    : return false;
+    case JAVATYPE_LONG   : return false;
+    case JAVATYPE_FLOAT  : return false;
+    case JAVATYPE_DOUBLE : return false;
+    case JAVATYPE_BOOLEAN: return false;
+    case JAVATYPE_STRING : return true;
+    case JAVATYPE_BYTES  : return true;
+    case JAVATYPE_ENUM   : return false;
+    case JAVATYPE_MESSAGE: return true;
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return false;
+}
+
+bool IsFastStringHandling(const FieldDescriptor* descriptor,
+      const Params params) {
+  return ((params.optimization() == JAVAMICRO_OPT_SPEED)
+      && (GetJavaType(descriptor) == JAVATYPE_STRING));
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params,
+                           map<string, string>* variables) {
+  (*variables)["name"] =
+    UnderscoresToCamelCase(descriptor);
+  (*variables)["capitalized_name"] =
+    UnderscoresToCapitalizedCamelCase(descriptor);
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
+  (*variables)["default"] = DefaultValue(params, descriptor);
+  (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
+  (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
+  (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
+  (*variables)["tag_size"] = SimpleItoa(
+      WireFormat::TagSize(descriptor->number(), descriptor->type()));
+  if (IsReferenceType(GetJavaType(descriptor))) {
+    (*variables)["null_check"] =
+        "  if (value == null) {\n"
+        "    throw new NullPointerException();\n"
+        "  }\n";
+  } else {
+    (*variables)["null_check"] = "";
+  }
+  int fixed_size = FixedSize(descriptor->type());
+  if (fixed_size != -1) {
+    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+  }
+  (*variables)["message_name"] = descriptor->containing_type()->name();
+}
+}  // namespace
+
+// ===================================================================
+
+PrimitiveFieldGenerator::
+PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, params, &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 $type$ get$capitalized_name$() { return $name$_; }\n"
+    "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n");
+  if (IsFastStringHandling(descriptor_, params_)) {
+    printer->Print(variables_,
+      "private byte [] $name$Utf8_ = null;\n"
+      "public $message_name$ set$capitalized_name$($type$ value) {\n"
+      "  has$capitalized_name$ = true;\n"
+      "  $name$_ = value;\n"
+      "  $name$Utf8_ = null;\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ clear$capitalized_name$() {\n"
+      "  has$capitalized_name$ = false;\n"
+      "  $name$_ = $default$;\n"
+      "  $name$Utf8_ = null;\n"
+      "  return this;\n"
+      "}\n");
+  } else {
+    if (IsVariableLenType(GetJavaType(descriptor_))) {
+      printer->Print(variables_,
+        "public $message_name$ set$capitalized_name$($type$ value) {\n"
+        "  has$capitalized_name$ = true;\n"
+        "  $name$_ = value;\n"
+        "  return this;\n"
+        "}\n"
+        "public $message_name$ clear$capitalized_name$() {\n"
+        "  has$capitalized_name$ = false;\n"
+        "  $name$_ = $default$;\n"
+        "  return this;\n"
+        "}\n");
+    } else {
+      printer->Print(variables_,
+        "public $message_name$ set$capitalized_name$($type$ value) {\n"
+        "  has$capitalized_name$ = true;\n"
+        "  $name$_ = value;\n"
+        "  return this;\n"
+        "}\n"
+        "public $message_name$ clear$capitalized_name$() {\n"
+        "  has$capitalized_name$ = false;\n"
+        "  $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::
+GenerateParsingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "set$capitalized_name$(input.read$capitalized_type$());\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  if (IsFastStringHandling(descriptor_, params_)) {
+    printer->Print(variables_,
+      "if (has$capitalized_name$()) {\n"
+      "  output.writeByteArray($number$, $name$Utf8_);\n"
+      "}\n");
+  } else {
+    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 {
+  if (IsFastStringHandling(descriptor_, params_)) {
+    printer->Print(variables_,
+      "if (has$capitalized_name$()) {\n"
+      "  try {\n"
+      "    $name$Utf8_ = $name$_.getBytes(\"UTF-8\");\n"
+      "  } catch (java.io.UnsupportedEncodingException e) {\n"
+      "    throw new RuntimeException(\"UTF-8 not supported.\");\n"
+      "  }\n"
+      "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+      "    .computeByteArraySize($number$, $name$Utf8_);\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "if (has$capitalized_name$()) {\n"
+      "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+      "    .compute$capitalized_type$Size($number$, get$capitalized_name$());\n"
+      "}\n");
+  }
+}
+
+string PrimitiveFieldGenerator::GetBoxedType() const {
+  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+// ===================================================================
+
+RepeatedPrimitiveFieldGenerator::
+RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, params, &variables_);
+  if (descriptor_->options().packed()) {
+    GOOGLE_LOG(FATAL) << "MicroRuntime does not support packed";
+  }
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer) const {
+  if (IsFastStringHandling(descriptor_, params_)) {
+    if (params_.java_use_vector()) {
+      printer->Print(variables_,
+        "private java.util.Vector $name$_ = new java.util.Vector();\n"
+        "public java.util.Vector get$capitalized_name$List() {\n"
+        "  return $name$_;\n"
+        "}\n"
+        "private java.util.Vector $name$Utf8_ = new java.util.Vector();\n"
+        "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
+        "public $type$ get$capitalized_name$(int index) {\n"
+        "  return (($type$)$name$_.elementAt(index));\n"
+        "}\n"
+        "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
+        "$null_check$"
+        "  $name$_.setElementAt(value, index);\n"
+        "  $name$Utf8_ = null;\n"
+        "  return this;\n"
+        "}\n"
+        "public $message_name$ add$capitalized_name$($type$ value) {\n"
+        "$null_check$"
+        "  $name$_.addElement(value);\n"
+        "  $name$Utf8_ = null;\n"
+        "  return this;\n"
+        "}\n"
+        "public $message_name$ clear$capitalized_name$() {\n"
+        "  $name$_.removeAllElements();\n"
+        "  $name$Utf8_ = null;\n"
+        "  return this;\n"
+        "}\n");
+    } else {
+      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"
+        "private java.util.List<byte []> $name$Utf8_ = null;\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"
+        "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
+        "$null_check$"
+        "  $name$_.set(index, value);\n"
+        "  $name$Utf8_ = null;\n"
+        "  return this;\n"
+        "}\n"
+        "public $message_name$ add$capitalized_name$($type$ value) {\n"
+        "$null_check$"
+        "  if ($name$_.isEmpty()) {\n"
+        "    $name$_ = new java.util.ArrayList<$type$>();\n"
+        "  }\n"
+        "  $name$_.add(value);\n"
+        "  $name$Utf8_ = null;\n"
+        "  return this;\n"
+        "}\n"
+        "public $message_name$ clear$capitalized_name$() {\n"
+        "  $name$_ = java.util.Collections.emptyList();\n"
+        "  $name$Utf8_ = null;\n"
+        "  return this;\n"
+        "}\n");
+    }
+  } else if (params_.java_use_vector()) {
+    if (IsReferenceType(GetJavaType(descriptor_))) {
+      printer->Print(variables_,
+        "private java.util.Vector $name$_ = new java.util.Vector();\n"
+        "public java.util.Vector get$capitalized_name$List() {\n"
+        "  return $name$_;\n"
+        "}\n"
+        "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
+        "public $type$ get$capitalized_name$(int index) {\n"
+        "  return ($type$) $name$_.elementAt(index);\n"
+        "}\n"
+        "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
+        "$null_check$"
+        "  $name$_.setElementAt(value, index);\n"
+        "  return this;\n"
+        "}\n"
+        "public $message_name$ add$capitalized_name$($type$ value) {\n"
+        "$null_check$"
+        "  $name$_.addElement(value);\n"
+        "  return this;\n"
+        "}\n"
+        "public $message_name$ clear$capitalized_name$() {\n"
+        "  $name$_.removeAllElements();\n"
+        "  return this;\n"
+        "}\n");
+    } else {
+      printer->Print(variables_,
+        "private java.util.Vector $name$_ = new java.util.Vector();\n"
+        "public java.util.Vector get$capitalized_name$List() {\n"
+        "  return $name$_;\n"
+        "}\n"
+        "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
+        "public $type$ get$capitalized_name$(int index) {\n"
+        "  return (($boxed_type$)$name$_.elementAt(index)).$type$Value();\n"
+        "}\n"
+        "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
+        "$null_check$"
+        "  $name$_.setElementAt(new $boxed_type$(value), index);\n"
+        "  return this;\n"
+        "}\n"
+        "public $message_name$ add$capitalized_name$($type$ value) {\n"
+        "$null_check$"
+        "  $name$_.addElement(new $boxed_type$(value));\n"
+        "  return this;\n"
+        "}\n"
+        "public $message_name$ clear$capitalized_name$() {\n"
+        "  $name$_.removeAllElements();\n"
+        "  return this;\n"
+        "}\n");
+    }
+  } else {
+    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"
+      "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
+      "$null_check$"
+      "  $name$_.set(index, value);\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ add$capitalized_name$($type$ value) {\n"
+      "$null_check$"
+      "  if ($name$_.isEmpty()) {\n"
+      "    $name$_ = new java.util.ArrayList<$boxed_type$>();\n"
+      "  }\n"
+      "  $name$_.add(value);\n"
+      "  return this;\n"
+      "}\n"
+      "public $message_name$ clear$capitalized_name$() {\n"
+      "  $name$_ = java.util.Collections.emptyList();\n"
+      "  return this;\n"
+      "}\n");
+  }
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "private int $name$MemoizedSerializedSize;\n");
+  }
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  if (params_.java_use_vector()) {
+    printer->Print(variables_,
+      "if (other.$name$_.size() != 0) {\n"
+      "  for (int i = 0; i < other.$name$_.size(); i++)) {\n"
+      "    result.$name$_.addElement(other.$name$_.elementAt(i));\n"
+      "  }\n"
+      "}\n");
+  } else {
+    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 RepeatedPrimitiveFieldGenerator::
+GenerateParsingCode(io::Printer* printer) const {
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "int length = input.readRawVarint32();\n"
+      "int limit = input.pushLimit(length);\n"
+      "while (input.getBytesUntilLimit() > 0) {\n"
+      "  add$capitalized_name$(input.read$capitalized_type$());\n"
+      "}\n"
+      "input.popLimit(limit);\n");
+  } else {
+    printer->Print(variables_,
+      "add$capitalized_name$(input.read$capitalized_type$());\n");
+  }
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "if (get$capitalized_name$List().size() > 0) {\n"
+        "  output.writeRawVarint32($tag$);\n"
+        "  output.writeRawVarint32($name$MemoizedSerializedSize);\n"
+        "}\n");
+    if (params_.java_use_vector()) {
+      printer->Print(variables_,
+        "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
+        "  output.write$capitalized_type$NoTag(get$capitalized_name$(i));\n"
+        "}\n");
+    } else {
+      printer->Print(variables_,
+        "for ($type$ element : get$capitalized_name$List()) {\n"
+        "  output.write$capitalized_type$NoTag(element);\n"
+        "}\n");
+    }
+  } else {
+    if (params_.java_use_vector()) {
+      if (IsFastStringHandling(descriptor_, params_)) {
+        printer->Print(variables_,
+          "for (int i = 0; i < $name$Utf8_.size(); i++) {\n"
+          "  output.writeByteArray($number$, (byte []) $name$Utf8_.get(i));\n"
+          "}\n");
+      } else {
+        printer->Print(variables_,
+          "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
+          "  output.write$capitalized_type$($number$, get$capitalized_name$(i));\n"
+          "}\n");
+      }
+    } else {
+      if (IsFastStringHandling(descriptor_, params_)) {
+        printer->Print(variables_,
+          "for (byte [] element : $name$Utf8_) {\n"
+          "  output.writeByteArray($number$, element);\n"
+          "}\n");
+      } else {
+        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_,
+    "{\n"
+    "  int dataSize = 0;\n");
+  printer->Indent();
+
+  if (FixedSize(descriptor_->type()) == -1) {
+    if (params_.java_use_vector()) {
+      if (IsFastStringHandling(descriptor_, params_)) {
+        printer->Print(variables_,
+          "$name$Utf8_ = new java.util.Vector();\n"
+          "byte[] bytes = null;\n"
+          "int sizeArray = get$capitalized_name$List().size();\n"
+          "for (int i = 0; i < sizeArray; i++) {\n"
+          "  $type$ element = ($type$)$name$_.elementAt(i);\n"
+          "  try {\n"
+          "    bytes = element.getBytes(\"UTF-8\");\n"
+          "  } catch (java.io.UnsupportedEncodingException e) {\n"
+          "    throw new RuntimeException(\"UTF-8 not supported.\");\n"
+          "  }\n"
+          "  $name$Utf8_.addElement(bytes);\n"
+          "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+          "    .computeByteArraySizeNoTag(bytes);\n"
+          "}\n");
+      } else {
+        printer->Print(variables_,
+          "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
+          "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+          "    .compute$capitalized_type$SizeNoTag(($type$)get$capitalized_name$(i));\n"
+          "}\n");
+      }
+    } else {
+      if (IsFastStringHandling(descriptor_, params_)) {
+          printer->Print(variables_,
+            "$name$Utf8_ = new java.util.ArrayList<byte[]>();\n"
+            "byte[] bytes = null;\n"
+            "int sizeArray = get$capitalized_name$List().size();\n"
+            "for (int i = 0; i < sizeArray; i++) {\n"
+            "   $type$ element = get$capitalized_name$(i);\n"
+            "  try {\n"
+            "    bytes = element.getBytes(\"UTF-8\");\n"
+            "  } catch (java.io.UnsupportedEncodingException e) {\n"
+            "    throw new RuntimeException(\"UTF-8 not supported.\");\n"
+            "  }\n"
+            "  $name$Utf8_.add(bytes);\n"
+            "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+            "    .computeByteArraySizeNoTag(bytes);\n"
+            "}\n");
+      } else {
+        printer->Print(variables_,
+            "for ($type$ element : get$capitalized_name$List()) {\n"
+            "  dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+            "    .compute$capitalized_type$SizeNoTag(element);\n"
+          "}\n");
+      }
+    }
+  } else {
+    printer->Print(variables_,
+      "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n");
+  }
+
+  printer->Print(
+      "size += dataSize;\n");
+
+  if (descriptor_->options().packed()) {
+    if (params_.java_use_vector()) {
+      printer->Print(variables_,
+        "if (get$capitalized_name$List().size() != 0) {\n");
+    } else {
+      printer->Print(variables_,
+        "if (!get$capitalized_name$List().isEmpty()) {\n");
+    }
+    printer->Print(variables_,
+        "  size += $tag_size$;\n"
+        "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
+        "      .computeInt32SizeNoTag(dataSize);\n"
+        "}\n");
+  } else {
+    printer->Print(variables_,
+      "size += $tag_size$ * get$capitalized_name$List().size();\n");
+  }
+
+  // cache the data size for packed fields.
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "$name$MemoizedSerializedSize = dataSize;\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+string RepeatedPrimitiveFieldGenerator::GetBoxedType() const {
+  return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
+}
+
+}  // namespace javamicro
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.h b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.h
new file mode 100644
index 0000000..88d8eec
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javamicro/javamicro_primitive_field.h
@@ -0,0 +1,94 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVAMICRO_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVAMICRO_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/javamicro/javamicro_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javamicro {
+
+class PrimitiveFieldGenerator : public FieldGenerator {
+ public:
+  explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params &params);
+  ~PrimitiveFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateMergingCode(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, const Params& params);
+  ~RepeatedPrimitiveFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer) const;
+  void GenerateMergingCode(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 javamicro
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVAMICRO_PRIMITIVE_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_enum.cc b/protobuf/src/google/protobuf/compiler/javanano/javanano_enum.cc
new file mode 100644
index 0000000..c6e8dfe
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_enum.cc
@@ -0,0 +1,143 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javanano/javanano_params.h>
+#include <google/protobuf/compiler/javanano/javanano_enum.h>
+#include <google/protobuf/compiler/javanano/javanano_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 javanano {
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, const Params& params)
+  : params_(params), 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) {
+  printer->Print(
+      "\n"
+      "// enum $classname$\n",
+      "classname", descriptor_->name());
+
+  const string classname = RenameJavaKeywords(descriptor_->name());
+
+  // Start of container interface
+  // If generating intdefs, we use the container interface as the intdef if
+  // present. Otherwise, we just make an empty @interface parallel to the
+  // constants.
+  bool use_intdef = params_.generate_intdefs();
+  bool use_shell_class = params_.java_enum_style();
+  if (use_intdef) {
+    // @IntDef annotation so tools can enforce correctness
+    // Annotations will be discarded by the compiler
+    printer->Print("@java.lang.annotation.Retention("
+      "java.lang.annotation.RetentionPolicy.SOURCE)\n"
+      "@android.support.annotation.IntDef({\n");
+    printer->Indent();
+    for (int i = 0; i < canonical_values_.size(); i++) {
+      const string constant_name =
+          RenameJavaKeywords(canonical_values_[i]->name());
+      if (use_shell_class) {
+        printer->Print("$classname$.$name$,\n",
+          "classname", classname,
+          "name", constant_name);
+      } else {
+        printer->Print("$name$,\n", "name", constant_name);
+      }
+    }
+    printer->Outdent();
+    printer->Print("})\n");
+  }
+  if (use_shell_class || use_intdef) {
+    printer->Print(
+      "public $at_for_intdef$interface $classname$ {\n",
+      "classname", classname,
+      "at_for_intdef", use_intdef ? "@" : "");
+    if (use_shell_class) {
+        printer->Indent();
+    } else {
+        printer->Print("}\n\n");
+    }
+  }
+
+  // Canonical values
+  for (int i = 0; i < canonical_values_.size(); i++) {
+    printer->Print(
+      "public static final int $name$ = $canonical_value$;\n",
+      "name", RenameJavaKeywords(canonical_values_[i]->name()),
+      "canonical_value", SimpleItoa(canonical_values_[i]->number()));
+  }
+
+  // Aliases
+  for (int i = 0; i < aliases_.size(); i++) {
+    printer->Print(
+      "public static final int $name$ = $canonical_name$;\n",
+      "name", RenameJavaKeywords(aliases_[i].value->name()),
+      "canonical_name", RenameJavaKeywords(aliases_[i].canonical_value->name()));
+  }
+
+  // End of container interface
+  if (use_shell_class) {
+    printer->Outdent();
+    printer->Print("}\n");
+  }
+}
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_enum.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_enum.h
new file mode 100644
index 0000000..d6f463e
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_enum.h
@@ -0,0 +1,87 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/compiler/javanano/javanano_params.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+class EnumGenerator {
+ public:
+  explicit EnumGenerator(const EnumDescriptor* descriptor, const Params& params);
+  ~EnumGenerator();
+
+  void Generate(io::Printer* printer);
+
+ private:
+  const Params& params_;
+  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 javanano
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_enum_field.cc b/protobuf/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
new file mode 100644
index 0000000..39a4eeb
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_enum_field.cc
@@ -0,0 +1,600 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javanano/javanano_enum_field.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/javanano/javanano_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 javanano {
+
+namespace {
+
+// TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
+//   repeat code between this and the other field types.
+void SetEnumVariables(const Params& params,
+    const FieldDescriptor* descriptor, map<string, string>* variables) {
+  (*variables)["name"] =
+    RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
+  (*variables)["capitalized_name"] =
+    RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  if (params.use_reference_types_for_primitives()
+      && !params.reftypes_primitive_enums()
+      && !descriptor->is_repeated()) {
+    (*variables)["type"] = "java.lang.Integer";
+    (*variables)["default"] = "null";
+  } else {
+    (*variables)["type"] = "int";
+    (*variables)["default"] = DefaultValue(params, descriptor);
+  }
+  (*variables)["repeated_default"] =
+      "com.google.protobuf.nano.WireFormatNano.EMPTY_INT_ARRAY";
+  (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+  (*variables)["tag_size"] = SimpleItoa(
+      internal::WireFormat::TagSize(descriptor->number(), descriptor->type()));
+  (*variables)["non_packed_tag"] = SimpleItoa(
+      internal::WireFormatLite::MakeTag(descriptor->number(),
+          internal::WireFormat::WireTypeForFieldType(descriptor->type())));
+  (*variables)["message_name"] = descriptor->containing_type()->name();
+  const EnumDescriptor* enum_type = descriptor->enum_type();
+  (*variables)["message_type_intdef"] = "@"
+      + ToJavaName(params, enum_type->name(), true,
+          enum_type->containing_type(), enum_type->file());
+}
+
+void LoadEnumValues(const Params& params,
+    const EnumDescriptor* enum_descriptor, vector<string>* canonical_values) {
+  string enum_class_name = ClassName(params, enum_descriptor);
+  for (int i = 0; i < enum_descriptor->value_count(); i++) {
+    const EnumValueDescriptor* value = enum_descriptor->value(i);
+    const EnumValueDescriptor* canonical_value =
+        enum_descriptor->FindValueByNumber(value->number());
+    if (value == canonical_value) {
+      canonical_values->push_back(
+          enum_class_name + "." + RenameJavaKeywords(value->name()));
+    }
+  }
+}
+
+void PrintCaseLabels(
+    io::Printer* printer, const vector<string>& canonical_values) {
+  for (int i = 0; i < canonical_values.size(); i++) {
+    printer->Print(
+      "  case $value$:\n",
+      "value", canonical_values[i]);
+  }
+}
+
+}  // namespace
+
+// ===================================================================
+
+EnumFieldGenerator::
+EnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetEnumVariables(params, descriptor, &variables_);
+  LoadEnumValues(params, descriptor->enum_type(), &canonical_values_);
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {}
+
+void EnumFieldGenerator::
+GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
+  if (params_.generate_intdefs()) {
+    printer->Print(variables_, "$message_type_intdef$\n");
+  }
+  printer->Print(variables_, "public $type$ $name$;\n");
+
+  if (params_.generate_has()) {
+    printer->Print(variables_,
+      "public boolean has$capitalized_name$;\n");
+  }
+}
+
+void EnumFieldGenerator::
+GenerateClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$ = $default$;\n");
+
+  if (params_.generate_has()) {
+    printer->Print(variables_,
+      "has$capitalized_name$ = false;\n");
+  }
+}
+
+void EnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  if (params_.store_unknown_fields()) {
+    printer->Print("int initialPos = input.getPosition();\n");
+  }
+  printer->Print(variables_,
+    "int value = input.readInt32();\n"
+    "switch (value) {\n");
+  PrintCaseLabels(printer, canonical_values_);
+  printer->Print(variables_,
+    "    this.$name$ = value;\n");
+  if (params_.generate_has()) {
+    printer->Print(variables_,
+      "    has$capitalized_name$ = true;\n");
+  }
+  printer->Print(
+    "    break;\n");
+  if (params_.store_unknown_fields()) {
+    // If storing unknown fields, store invalid values there.
+    // This is consistent with full protobuf, but note that if a client writes
+    // a new value to this field, both will be serialized on the wire, and
+    // other clients which are aware of unknown fields will see the previous
+    // value, not the new one.
+    printer->Print(
+      "  default:\n"
+      "    input.rewindToPosition(initialPos);\n"
+      "    storeUnknownField(input, tag);\n"
+      "    break;\n");
+  }
+  printer->Print("}\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  if (descriptor_->is_required() && !params_.generate_has()) {
+    // Always serialize a required field if we don't have the 'has' signal.
+    printer->Print(variables_,
+      "output.writeInt32($number$, this.$name$);\n");
+  } else {
+    if (params_.generate_has()) {
+      printer->Print(variables_,
+        "if (this.$name$ != $default$ || has$capitalized_name$) {\n");
+    } else {
+      printer->Print(variables_,
+        "if (this.$name$ != $default$) {\n");
+    }
+    printer->Print(variables_,
+      "  output.writeInt32($number$, this.$name$);\n"
+      "}\n");
+  }
+}
+
+void EnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  if (descriptor_->is_required() && !params_.generate_has()) {
+    printer->Print(variables_,
+      "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+      "  .computeInt32Size($number$, this.$name$);\n");
+  } else {
+    if (params_.generate_has()) {
+      printer->Print(variables_,
+        "if (this.$name$ != $default$ || has$capitalized_name$) {\n");
+    } else {
+      printer->Print(variables_,
+        "if (this.$name$ != $default$) {\n");
+    }
+    printer->Print(variables_,
+      "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+      "    .computeInt32Size($number$, this.$name$);\n"
+      "}\n");
+  }
+}
+
+void EnumFieldGenerator::GenerateEqualsCode(io::Printer* printer) const {
+  if (params_.use_reference_types_for_primitives()
+        && !params_.reftypes_primitive_enums()) {
+    printer->Print(variables_,
+      "if (this.$name$ == null) {\n"
+      "  if (other.$name$ != null) {\n"
+      "    return false;\n"
+      "  }\n"
+      "} else if (!this.$name$.equals(other.$name$)) {\n"
+      "  return false;"
+      "}\n");
+  } else {
+    // We define equality as serialized form equality. If generate_has(),
+    // then if the field value equals the default value in both messages,
+    // but one's 'has' field is set and the other's is not, the serialized
+    // forms are different and we should return false.
+    printer->Print(variables_,
+      "if (this.$name$ != other.$name$");
+    if (params_.generate_has()) {
+      printer->Print(variables_,
+        "\n"
+        "    || (this.$name$ == $default$\n"
+        "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
+    }
+    printer->Print(") {\n"
+      "  return false;\n"
+      "}\n");
+  }
+}
+
+void EnumFieldGenerator::GenerateHashCodeCode(io::Printer* printer) const {
+  printer->Print(
+    "result = 31 * result + ");
+  if (params_.use_reference_types_for_primitives()
+        && !params_.reftypes_primitive_enums()) {
+    printer->Print(variables_,
+      "(this.$name$ == null ? 0 : this.$name$)");
+  } else {
+    printer->Print(variables_,
+      "this.$name$");
+  }
+  printer->Print(";\n");
+}
+
+// ===================================================================
+
+AccessorEnumFieldGenerator::
+AccessorEnumFieldGenerator(const FieldDescriptor* descriptor,
+    const Params& params, int has_bit_index)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetEnumVariables(params, descriptor, &variables_);
+  LoadEnumValues(params, descriptor->enum_type(), &canonical_values_);
+  SetBitOperationVariables("has", has_bit_index, &variables_);
+}
+
+AccessorEnumFieldGenerator::~AccessorEnumFieldGenerator() {}
+
+void AccessorEnumFieldGenerator::
+GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
+  printer->Print(variables_, "private int $name$_;\n");
+  if (params_.generate_intdefs()) {
+    printer->Print(variables_, "$message_type_intdef$\n");
+  }
+  printer->Print(variables_,
+    "public int get$capitalized_name$() {\n"
+    "  return $name$_;\n"
+    "}\n"
+    "public $message_name$ set$capitalized_name$(");
+  if (params_.generate_intdefs()) {
+    printer->Print(variables_,
+      "\n"
+      "    $message_type_intdef$ ");
+  }
+  printer->Print(variables_,
+    "int value) {\n"
+    "  $name$_ = value;\n"
+    "  $set_has$;\n"
+    "  return this;\n"
+    "}\n"
+    "public boolean has$capitalized_name$() {\n"
+    "  return $get_has$;\n"
+    "}\n"
+    "public $message_name$ clear$capitalized_name$() {\n"
+    "  $name$_ = $default$;\n"
+    "  $clear_has$;\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void AccessorEnumFieldGenerator::
+GenerateClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$_ = $default$;\n");
+}
+
+void AccessorEnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  if (params_.store_unknown_fields()) {
+    printer->Print("int initialPos = input.getPosition();\n");
+  }
+  printer->Print(variables_,
+    "int value = input.readInt32();\n"
+    "switch (value) {\n");
+  PrintCaseLabels(printer, canonical_values_);
+  printer->Print(variables_,
+    "    $name$_ = value;\n"
+    "    $set_has$;\n"
+    "    break;\n");
+  if (params_.store_unknown_fields()) {
+    // If storing unknown fields, store invalid values there.
+    // This is consistent with full protobuf, but note that if a client writes
+    // a new value to this field, both will be serialized on the wire, and
+    // other clients which are aware of unknown fields will see the previous
+    // value, not the new one.
+    printer->Print(
+      "  default:\n"
+      "    input.rewindToPosition(initialPos);\n"
+      "    storeUnknownField(input, tag);\n"
+      "    break;\n");
+  }
+  printer->Print("}\n");
+}
+
+void AccessorEnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($get_has$) {\n"
+    "  output.writeInt32($number$, $name$_);\n"
+    "}\n");
+}
+
+void AccessorEnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($get_has$) {\n"
+    "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+    "    .computeInt32Size($number$, $name$_);\n"
+    "}\n");
+}
+
+void AccessorEnumFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($different_has$\n"
+    "    || $name$_ != other.$name$_) {\n"
+    "  return false;\n"
+    "}\n");
+}
+
+void AccessorEnumFieldGenerator::
+GenerateHashCodeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = 31 * result + $name$_;\n");
+}
+
+// ===================================================================
+
+RepeatedEnumFieldGenerator::
+RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetEnumVariables(params, descriptor, &variables_);
+  LoadEnumValues(params, descriptor->enum_type(), &canonical_values_);
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+void RepeatedEnumFieldGenerator::
+GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
+  printer->Print(variables_,
+    "public $type$[] $name$;\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$ = $repeated_default$;\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  // First, figure out the maximum length of the array, then parse,
+  // and finally copy the valid values to the field.
+  printer->Print(variables_,
+    "int length = com.google.protobuf.nano.WireFormatNano\n"
+    "    .getRepeatedFieldArrayLength(input, $non_packed_tag$);\n"
+    "int[] validValues = new int[length];\n"
+    "int validCount = 0;\n"
+    "for (int i = 0; i < length; i++) {\n"
+    "  if (i != 0) { // tag for first value already consumed.\n"
+    "    input.readTag();\n"
+    "  }\n");
+  if (params_.store_unknown_fields()) {
+    printer->Print("  int initialPos = input.getPosition();\n");
+  }
+  printer->Print(
+    "  int value = input.readInt32();\n"
+    "  switch (value) {\n");
+  printer->Indent();
+  PrintCaseLabels(printer, canonical_values_);
+  printer->Outdent();
+  printer->Print(variables_,
+    "      validValues[validCount++] = value;\n"
+    "      break;\n");
+  if (params_.store_unknown_fields()) {
+    // If storing unknown fields, store invalid values there.
+    // This is consistent with full protobuf. Note that this can lead to very
+    // strange behaviors if a value is serialized and reread, e.g. changes in
+    // value ordering.
+    printer->Print(
+      "    default:\n"
+      "      input.rewindToPosition(initialPos);\n"
+      "      storeUnknownField(input, tag);\n"
+      "      break;\n");
+  }
+  printer->Print(variables_,
+    "  }\n"
+    "}\n"
+    "if (validCount != 0) {\n"
+    "  int i = this.$name$ == null ? 0 : this.$name$.length;\n"
+    "  if (i == 0 && validCount == validValues.length) {\n"
+    "    this.$name$ = validValues;\n"
+    "  } else {\n"
+    "    int[] newArray = new int[i + validCount];\n"
+    "    if (i != 0) {\n"
+    "      java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
+    "    }\n"
+    "    java.lang.System.arraycopy(validValues, 0, newArray, i, validCount);\n"
+    "    this.$name$ = newArray;\n"
+    "  }\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergingCodeFromPacked(io::Printer* printer) const {
+  printer->Print(variables_,
+    "int bytes = input.readRawVarint32();\n"
+    "int limit = input.pushLimit(bytes);\n"
+    "// First pass to compute array length.\n"
+    "int arrayLength = 0;\n"
+    "int startPos = input.getPosition();\n"
+    "while (input.getBytesUntilLimit() > 0) {\n"
+    "  switch (input.readInt32()) {\n");
+  printer->Indent();
+  PrintCaseLabels(printer, canonical_values_);
+  printer->Outdent();
+  printer->Print(variables_,
+    "      arrayLength++;\n"
+    "      break;\n"
+    "  }\n"
+    "}\n"
+    "if (arrayLength != 0) {\n"
+    "  input.rewindToPosition(startPos);\n"
+    "  int i = this.$name$ == null ? 0 : this.$name$.length;\n"
+    "  int[] newArray = new int[i + arrayLength];\n"
+    "  if (i != 0) {\n"
+    "    java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
+    "  }\n"
+    "  while (input.getBytesUntilLimit() > 0) {\n");
+  if (params_.store_unknown_fields()) {
+    printer->Print("    int initialPos = input.getPosition();\n");
+  }
+  printer->Print(variables_,
+    "    int value = input.readInt32();\n"
+    "    switch (value) {\n");
+  printer->Indent();
+  printer->Indent();
+  PrintCaseLabels(printer, canonical_values_);
+  printer->Outdent();
+  printer->Outdent();
+  printer->Print(variables_,
+    "        newArray[i++] = value;\n"
+    "        break;\n");
+  if (params_.store_unknown_fields()) {
+    // If storing unknown fields, store invalid values there.
+    // This is consistent with full protobuf. Note that this can lead to very
+    // strange behaviors if a value is serialized and reread, e.g. changes in
+    // value ordering.
+    printer->Print(variables_,
+      "      default:\n"
+      "        input.rewindToPosition(initialPos);\n"
+      "        storeUnknownField(input, $non_packed_tag$);\n"
+      "        break;\n");
+  }
+  printer->Print(variables_,
+    "    }\n"
+    "  }\n"
+    "  this.$name$ = newArray;\n"
+    "}\n"
+    "input.popLimit(limit);\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateRepeatedDataSizeCode(io::Printer* printer) const {
+  // Creates a variable dataSize and puts the serialized size in there.
+  printer->Print(variables_,
+    "int dataSize = 0;\n"
+    "for (int i = 0; i < this.$name$.length; i++) {\n"
+    "  int element = this.$name$[i];\n"
+    "  dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+    "      .computeInt32SizeNoTag(element);\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null && this.$name$.length > 0) {\n");
+  printer->Indent();
+
+  if (descriptor_->options().packed()) {
+    GenerateRepeatedDataSizeCode(printer);
+    printer->Print(variables_,
+      "output.writeRawVarint32($tag$);\n"
+      "output.writeRawVarint32(dataSize);\n"
+      "for (int i = 0; i < this.$name$.length; i++) {\n"
+      "  output.writeRawVarint32(this.$name$[i]);\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "for (int i = 0; i < this.$name$.length; i++) {\n"
+      "  output.writeInt32($number$, this.$name$[i]);\n"
+      "}\n");
+  }
+
+  printer->Outdent();
+  printer->Print(variables_,
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null && this.$name$.length > 0) {\n");
+  printer->Indent();
+
+  GenerateRepeatedDataSizeCode(printer);
+
+  printer->Print(
+    "size += dataSize;\n");
+  if (descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "size += $tag_size$;\n"
+      "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+      "    .computeRawVarint32Size(dataSize);\n");
+  } else {
+    printer->Print(variables_,
+      "size += $tag_size$ * this.$name$.length;\n");
+  }
+
+  printer->Outdent();
+
+  printer->Print(
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateFixClonedCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null && this.$name$.length > 0) {\n"
+    "  cloned.$name$ = this.$name$.clone();\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!com.google.protobuf.nano.InternalNano.equals(\n"
+    "    this.$name$, other.$name$)) {\n"
+    "  return false;\n"
+    "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateHashCodeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = 31 * result\n"
+    "    + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
+}
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_enum_field.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_enum_field.h
new file mode 100644
index 0000000..8622463
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_enum_field.h
@@ -0,0 +1,126 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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 <vector>
+#include <google/protobuf/compiler/javanano/javanano_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+class EnumFieldGenerator : public FieldGenerator {
+ public:
+  explicit EnumFieldGenerator(
+      const FieldDescriptor* descriptor, const Params& params);
+  ~EnumFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer, bool lazy_init) const;
+  void GenerateClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCodeCode(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  vector<string> canonical_values_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
+};
+
+class AccessorEnumFieldGenerator : public FieldGenerator {
+ public:
+  explicit AccessorEnumFieldGenerator(const FieldDescriptor* descriptor,
+      const Params& params, int has_bit_index);
+  ~AccessorEnumFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer, bool lazy_init) const;
+  void GenerateClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCodeCode(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  vector<string> canonical_values_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AccessorEnumFieldGenerator);
+};
+
+class RepeatedEnumFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedEnumFieldGenerator(
+      const FieldDescriptor* descriptor, const Params& params);
+  ~RepeatedEnumFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer, bool lazy_init) const;
+  void GenerateClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateMergingCodeFromPacked(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCodeCode(io::Printer* printer) const;
+  void GenerateFixClonedCode(io::Printer* printer) const;
+
+ private:
+  void GenerateRepeatedDataSizeCode(io::Printer* printer) const;
+
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+  vector<string> canonical_values_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
+};
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_extension.cc b/protobuf/src/google/protobuf/compiler/javanano/javanano_extension.cc
new file mode 100644
index 0000000..0b9d1d8
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_extension.cc
@@ -0,0 +1,150 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: bduff@google.com (Brian Duff)
+
+#include <google/protobuf/compiler/javanano/javanano_extension.h>
+#include <google/protobuf/compiler/javanano/javanano_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/wire_format.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+const char* GetTypeConstantName(const FieldDescriptor::Type type) {
+  switch (type) {
+    case FieldDescriptor::TYPE_INT32   : return "TYPE_INT32"   ;
+    case FieldDescriptor::TYPE_UINT32  : return "TYPE_UINT32"  ;
+    case FieldDescriptor::TYPE_SINT32  : return "TYPE_SINT32"  ;
+    case FieldDescriptor::TYPE_FIXED32 : return "TYPE_FIXED32" ;
+    case FieldDescriptor::TYPE_SFIXED32: return "TYPE_SFIXED32";
+    case FieldDescriptor::TYPE_INT64   : return "TYPE_INT64"   ;
+    case FieldDescriptor::TYPE_UINT64  : return "TYPE_UINT64"  ;
+    case FieldDescriptor::TYPE_SINT64  : return "TYPE_SINT64"  ;
+    case FieldDescriptor::TYPE_FIXED64 : return "TYPE_FIXED64" ;
+    case FieldDescriptor::TYPE_SFIXED64: return "TYPE_SFIXED64";
+    case FieldDescriptor::TYPE_FLOAT   : return "TYPE_FLOAT"   ;
+    case FieldDescriptor::TYPE_DOUBLE  : return "TYPE_DOUBLE"  ;
+    case FieldDescriptor::TYPE_BOOL    : return "TYPE_BOOL"    ;
+    case FieldDescriptor::TYPE_STRING  : return "TYPE_STRING"  ;
+    case FieldDescriptor::TYPE_BYTES   : return "TYPE_BYTES"   ;
+    case FieldDescriptor::TYPE_ENUM    : return "TYPE_ENUM"    ;
+    case FieldDescriptor::TYPE_GROUP   : return "TYPE_GROUP"   ;
+    case FieldDescriptor::TYPE_MESSAGE : return "TYPE_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;
+}
+
+}  // namespace
+
+void SetVariables(const FieldDescriptor* descriptor, const Params params,
+                  map<string, string>* variables) {
+  (*variables)["extends"] = ClassName(params, descriptor->containing_type());
+  (*variables)["name"] = RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
+  bool repeated = descriptor->is_repeated();
+  (*variables)["repeated"] = repeated ? "Repeated" : "";
+  (*variables)["type"] = GetTypeConstantName(descriptor->type());
+  JavaType java_type = GetJavaType(descriptor->type());
+  string tag = SimpleItoa(WireFormat::MakeTag(descriptor));
+  if (java_type == JAVATYPE_MESSAGE) {
+    (*variables)["ext_type"] = "MessageTyped";
+    string message_type = ClassName(params, descriptor->message_type());
+    if (repeated) {
+      message_type += "[]";
+    }
+    (*variables)["class"] = message_type;
+    // For message typed extensions, tags_params contains a single tag
+    // for both singular and repeated cases.
+    (*variables)["tag_params"] = tag;
+  } else {
+    (*variables)["ext_type"] = "PrimitiveTyped";
+    if (!repeated) {
+      (*variables)["class"] = BoxedPrimitiveTypeName(java_type);
+      (*variables)["tag_params"] = tag;
+    } else {
+      (*variables)["class"] = PrimitiveTypeName(java_type) + "[]";
+      if (!descriptor->is_packable()) {
+        // Non-packable: nonPackedTag == tag, packedTag == 0
+        (*variables)["tag_params"] = tag + ", " + tag + ", 0";
+      } else if (descriptor->options().packed()) {
+        // Packable and packed: tag == packedTag
+        string non_packed_tag = SimpleItoa(WireFormatLite::MakeTag(
+            descriptor->number(),
+            WireFormat::WireTypeForFieldType(descriptor->type())));
+        (*variables)["tag_params"] = tag + ", " + non_packed_tag + ", " + tag;
+      } else {
+        // Packable and not packed: tag == nonPackedTag
+        string packed_tag = SimpleItoa(WireFormatLite::MakeTag(
+            descriptor->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
+        (*variables)["tag_params"] = tag + ", " + tag + ", " + packed_tag;
+      }
+    }
+  }
+}
+
+ExtensionGenerator::
+ExtensionGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : params_(params), descriptor_(descriptor) {
+  SetVariables(descriptor, params, &variables_);
+}
+
+ExtensionGenerator::~ExtensionGenerator() {}
+
+void ExtensionGenerator::Generate(io::Printer* printer) const {
+  printer->Print("\n");
+  PrintFieldComment(printer, descriptor_);
+  printer->Print(variables_,
+    "public static final com.google.protobuf.nano.Extension<\n"
+    "    $extends$,\n"
+    "    $class$> $name$ =\n"
+    "        com.google.protobuf.nano.Extension.create$repeated$$ext_type$(\n"
+    "            com.google.protobuf.nano.Extension.$type$,\n"
+    "            $class$.class,\n"
+    "            $tag_params$L);\n");
+}
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_extension.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_extension.h
new file mode 100644
index 0000000..c6543eb
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_extension.h
@@ -0,0 +1,74 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: bduff@google.com (Brian Duff)
+//  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>
+#include <google/protobuf/compiler/javanano/javanano_params.h>
+#include <google/protobuf/descriptor.pb.h>
+
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+class ExtensionGenerator {
+ public:
+  explicit ExtensionGenerator(const FieldDescriptor* descriptor, const Params& params);
+  ~ExtensionGenerator();
+
+  void Generate(io::Printer* printer) const;
+
+ private:
+  const Params& params_;
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H_
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_field.cc b/protobuf/src/google/protobuf/compiler/javanano/javanano_field.cc
new file mode 100644
index 0000000..e3e4cef
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_field.cc
@@ -0,0 +1,143 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/javanano/javanano_field.h>
+#include <google/protobuf/compiler/javanano/javanano_helpers.h>
+#include <google/protobuf/compiler/javanano/javanano_primitive_field.h>
+#include <google/protobuf/compiler/javanano/javanano_enum_field.h>
+#include <google/protobuf/compiler/javanano/javanano_message_field.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+FieldGenerator::~FieldGenerator() {}
+
+bool FieldGenerator::SavedDefaultNeeded() const {
+  // No saved default for this field by default.
+  // Subclasses whose instances may need saved defaults will override this
+  // and return the appropriate value.
+  return false;
+}
+
+void FieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const {
+  // No saved default for this field by default.
+  // Subclasses whose instances may need saved defaults will override this
+  // and generate the appropriate init code to the printer.
+}
+
+void FieldGenerator::GenerateMergingCodeFromPacked(io::Printer* printer) const {
+  // Reaching here indicates a bug. Cases are:
+  //   - This FieldGenerator should support packing, but this method should be
+  //     overridden.
+  //   - This FieldGenerator doesn't support packing, and this method should
+  //     never have been called.
+  GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
+             << "called on field generator that does not support packing.";
+}
+
+// =============================================
+
+FieldGeneratorMap::FieldGeneratorMap(
+    const Descriptor* descriptor, const Params &params)
+  : descriptor_(descriptor),
+    field_generators_(
+      new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
+
+  int next_has_bit_index = 0;
+  bool saved_defaults_needed = false;
+  // Construct all the FieldGenerators.
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    FieldGenerator* field_generator = MakeGenerator(
+        descriptor->field(i), params, &next_has_bit_index);
+    saved_defaults_needed = saved_defaults_needed
+        || field_generator->SavedDefaultNeeded();
+    field_generators_[i].reset(field_generator);
+  }
+  total_bits_ = next_has_bit_index;
+  saved_defaults_needed_ = saved_defaults_needed;
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
+    const Params &params, int* next_has_bit_index) {
+  JavaType java_type = GetJavaType(field);
+  if (field->is_repeated()) {
+    switch (java_type) {
+      case JAVATYPE_MESSAGE:
+        return new RepeatedMessageFieldGenerator(field, params);
+      case JAVATYPE_ENUM:
+        return new RepeatedEnumFieldGenerator(field, params);
+      default:
+        return new RepeatedPrimitiveFieldGenerator(field, params);
+    }
+  } else if (params.optional_field_accessors() && field->is_optional()
+      && java_type != JAVATYPE_MESSAGE) {
+    // We need a has-bit for each primitive/enum field because their default
+    // values could be same as explicitly set values. But we don't need it
+    // for a message field because they have no defaults and Nano uses 'null'
+    // for unset messages, which cannot be set explicitly.
+    switch (java_type) {
+      case JAVATYPE_ENUM:
+        return new AccessorEnumFieldGenerator(
+            field, params, (*next_has_bit_index)++);
+      default:
+        return new AccessorPrimitiveFieldGenerator(
+            field, params, (*next_has_bit_index)++);
+    }
+  } else {
+    switch (java_type) {
+      case JAVATYPE_MESSAGE:
+        return new MessageFieldGenerator(field, params);
+      case JAVATYPE_ENUM:
+        return new EnumFieldGenerator(field, params);
+      default:
+        return new PrimitiveFieldGenerator(field, params);
+    }
+  }
+}
+
+FieldGeneratorMap::~FieldGeneratorMap() {}
+
+const FieldGenerator& FieldGeneratorMap::get(
+    const FieldDescriptor* field) const {
+  GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+  return *field_generators_[field->index()];
+}
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_field.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_field.h
new file mode 100644
index 0000000..e015259
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_field.h
@@ -0,0 +1,120 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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>
+#include <google/protobuf/compiler/javanano/javanano_params.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+class FieldGenerator {
+ public:
+  FieldGenerator(const Params& params) : params_(params) {}
+  virtual ~FieldGenerator();
+
+  virtual bool SavedDefaultNeeded() const;
+  virtual void GenerateInitSavedDefaultCode(io::Printer* printer) const;
+
+  // Generates code for Java fields and methods supporting this field.
+  // If this field needs a saved default (SavedDefaultNeeded() is true),
+  // then @lazy_init controls how the static field for that default value
+  // and its initialization code should be generated. If @lazy_init is
+  // true, the static field is not declared final and the initialization
+  // code is generated only when GenerateInitSavedDefaultCode is called;
+  // otherwise, the static field is declared final and initialized inline.
+  // GenerateInitSavedDefaultCode will not be called in the latter case.
+  virtual void GenerateMembers(
+      io::Printer* printer, bool lazy_init) const = 0;
+
+  virtual void GenerateClearCode(io::Printer* printer) const = 0;
+  virtual void GenerateMergingCode(io::Printer* printer) const = 0;
+
+  // Generates code to merge from packed serialized form. The default
+  // implementation will fail; subclasses which can handle packed serialized
+  // forms will override this and print appropriate code to the printer.
+  virtual void GenerateMergingCodeFromPacked(io::Printer* printer) const;
+
+  virtual void GenerateSerializationCode(io::Printer* printer) const = 0;
+  virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0;
+  virtual void GenerateEqualsCode(io::Printer* printer) const = 0;
+  virtual void GenerateHashCodeCode(io::Printer* printer) const = 0;
+  virtual void GenerateFixClonedCode(io::Printer* printer) const {}
+
+ protected:
+  const Params& params_;
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
+};
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+class FieldGeneratorMap {
+ public:
+  explicit FieldGeneratorMap(const Descriptor* descriptor, const Params &params);
+  ~FieldGeneratorMap();
+
+  const FieldGenerator& get(const FieldDescriptor* field) const;
+  int total_bits() const { return total_bits_; }
+  bool saved_defaults_needed() const { return saved_defaults_needed_; }
+
+ private:
+  const Descriptor* descriptor_;
+  scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
+  int total_bits_;
+  bool saved_defaults_needed_;
+
+  static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
+      const Params &params, int* next_has_bit_index);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_file.cc b/protobuf/src/google/protobuf/compiler/javanano/javanano_file.cc
new file mode 100644
index 0000000..d8c5111
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_file.cc
@@ -0,0 +1,265 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <iostream>
+
+#include <google/protobuf/compiler/javanano/javanano_file.h>
+#include <google/protobuf/compiler/javanano/javanano_enum.h>
+#include <google/protobuf/compiler/javanano/javanano_extension.h>
+#include <google/protobuf/compiler/javanano/javanano_helpers.h>
+#include <google/protobuf/compiler/javanano/javanano_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 javanano {
+
+namespace {
+
+// Recursively searches the given message to see if it contains any extensions.
+bool UsesExtensions(const Message& message) {
+  const Reflection* reflection = message.GetReflection();
+
+  // We conservatively assume that unknown fields are extensions.
+  if (reflection->GetUnknownFields(message).field_count() > 0) return true;
+
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(message, &fields);
+
+  for (int i = 0; i < fields.size(); i++) {
+    if (fields[i]->is_extension()) return true;
+
+    if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (fields[i]->is_repeated()) {
+        int size = reflection->FieldSize(message, fields[i]);
+        for (int j = 0; j < size; j++) {
+          const Message& sub_message =
+            reflection->GetRepeatedMessage(message, fields[i], j);
+          if (UsesExtensions(sub_message)) return true;
+        }
+      } else {
+        const Message& sub_message = reflection->GetMessage(message, fields[i]);
+        if (UsesExtensions(sub_message)) return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+}  // namespace
+
+FileGenerator::FileGenerator(const FileDescriptor* file, const Params& params)
+  : file_(file),
+    params_(params),
+    java_package_(FileJavaPackage(params, file)),
+    classname_(FileClassName(params, file)) {}
+
+FileGenerator::~FileGenerator() {}
+
+bool FileGenerator::Validate(string* error) {
+  // Check for extensions
+  FileDescriptorProto file_proto;
+  file_->CopyTo(&file_proto);
+  if (UsesExtensions(file_proto) && !params_.store_unknown_fields()) {
+    error->assign(file_->name());
+    error->append(
+        ": Java NANO_RUNTIME only supports extensions when the "
+        "'store_unknown_fields' generator option is 'true'.");
+    return false;
+  }
+
+  if (file_->service_count() != 0 && !params_.ignore_services()) {
+    error->assign(file_->name());
+    error->append(
+      ": Java NANO_RUNTIME does not support services\"");
+    return false;
+  }
+
+  if (!IsOuterClassNeeded(params_, file_)) {
+    return true;
+  }
+
+  // Check whether legacy javanano generator would omit the outer class.
+  if (!params_.has_java_outer_classname(file_->name())
+      && file_->message_type_count() == 1
+      && file_->enum_type_count() == 0 && file_->extension_count() == 0) {
+    cout << "INFO: " << file_->name() << ":" << endl;
+    cout << "Javanano generator has changed to align with java generator. "
+        "An outer class will be created for this file and the single message "
+        "in the file will become a nested class. Use java_multiple_files to "
+        "skip generating the outer class, or set an explicit "
+        "java_outer_classname to suppress this message." << endl;
+  }
+
+  // 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; !found_conflict && i < file_->message_type_count(); i++) {
+    if (file_->message_type(i)->name() == classname_) {
+      found_conflict = true;
+    }
+  }
+  if (params_.java_enum_style()) {
+    for (int i = 0; !found_conflict && i < file_->enum_type_count(); i++) {
+      if (file_->enum_type(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");
+  if (!java_package_.empty()) {
+    printer->Print(
+      "\n"
+      "package $package$;\n",
+      "package", java_package_);
+  }
+
+  printer->Print("\n// @@protoc_insertion_point(imports_scope)\n");
+
+  // Note: constants (from enums, emitted in the loop below) may have the same names as constants
+  // in the nested classes. This causes Java warnings, but is not fatal, so we suppress those
+  // warnings here in the top-most class declaration.
+  printer->Print(
+    "\n"
+    "@SuppressWarnings(\"hiding\")\n"
+    "public interface $classname$ {\n",
+    "classname", classname_);
+  printer->Indent();
+
+  // -----------------------------------------------------------------
+
+  // Extensions.
+  for (int i = 0; i < file_->extension_count(); i++) {
+    ExtensionGenerator(file_->extension(i), params_).Generate(printer);
+  }
+
+  // Enums.
+  for (int i = 0; i < file_->enum_type_count(); i++) {
+    EnumGenerator(file_->enum_type(i), params_).Generate(printer);
+  }
+
+  // Messages.
+  if (!params_.java_multiple_files(file_->name())) {
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      MessageGenerator(file_->message_type(i), params_).Generate(printer);
+    }
+  }
+
+  // Static variables.
+  for (int i = 0; i < file_->message_type_count(); i++) {
+    // TODO(kenton):  Reuse MessageGenerator objects?
+    MessageGenerator(file_->message_type(i), params_).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,
+                            const Params& params) {
+  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");
+  if (!java_package.empty()) {
+    printer.Print(
+      "\n"
+      "package $package$;\n",
+      "package", java_package);
+  }
+
+  GeneratorClass(descriptor, params).Generate(&printer);
+}
+
+void FileGenerator::GenerateSiblings(const string& package_dir,
+                                     OutputDirectory* output_directory,
+                                     vector<string>* file_list) {
+  if (params_.java_multiple_files(file_->name())) {
+    for (int i = 0; i < file_->message_type_count(); i++) {
+      GenerateSibling<MessageGenerator>(package_dir, java_package_,
+                                        file_->message_type(i),
+                                        output_directory, file_list, params_);
+    }
+
+    if (params_.java_enum_style()) {
+      for (int i = 0; i < file_->enum_type_count(); i++) {
+        GenerateSibling<EnumGenerator>(package_dir, java_package_,
+                                       file_->enum_type(i),
+                                       output_directory, file_list, params_);
+      }
+    }
+  }
+}
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_file.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_file.h
new file mode 100644
index 0000000..cfcd7c6
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_file.h
@@ -0,0 +1,92 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/javanano/javanano_params.h>
+
+namespace google {
+namespace protobuf {
+  class FileDescriptor;        // descriptor.h
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+class FileGenerator {
+ public:
+  explicit FileGenerator(const FileDescriptor* file, const Params& params);
+  ~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_;
+  const Params& params_;
+  string java_package_;
+  string classname_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
+};
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_generator.cc b/protobuf/src/google/protobuf/compiler/javanano/javanano_generator.cc
new file mode 100644
index 0000000..e842791
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_generator.cc
@@ -0,0 +1,235 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/compiler/javanano/javanano_params.h>
+#include <google/protobuf/compiler/javanano/javanano_generator.h>
+#include <google/protobuf/compiler/javanano/javanano_file.h>
+#include <google/protobuf/compiler/javanano/javanano_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 javanano {
+
+namespace {
+
+string TrimString(const string& s) {
+  string::size_type start = s.find_first_not_of(" \n\r\t");
+  if (start == string::npos) {
+    return "";
+  }
+  string::size_type end = s.find_last_not_of(" \n\r\t") + 1;
+  return s.substr(start, end - start);
+}
+
+} // namespace
+
+void UpdateParamsRecursively(Params& params,
+    const FileDescriptor* file) {
+  // Add any parameters for this file
+  if (file->options().has_java_outer_classname()) {
+    params.set_java_outer_classname(
+      file->name(), file->options().java_outer_classname());
+  }
+  if (file->options().has_java_package()) {
+    params.set_java_package(
+      file->name(), file->options().java_package());
+  }
+  if (file->options().has_java_multiple_files()) {
+    params.set_java_multiple_files(
+      file->name(), file->options().java_multiple_files());
+  }
+
+  // Loop through all dependent files recursively
+  // adding dep
+  for (int i = 0; i < file->dependency_count(); i++) {
+    UpdateParamsRecursively(params, file->dependency(i));
+  }
+}
+
+JavaNanoGenerator::JavaNanoGenerator() {}
+JavaNanoGenerator::~JavaNanoGenerator() {}
+
+bool JavaNanoGenerator::Generate(const FileDescriptor* file,
+                             const string& parameter,
+                             OutputDirectory* output_directory,
+                             string* error) const {
+  vector<pair<string, string> > options;
+
+  ParseGeneratorParameter(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;
+  Params params(file->name());
+
+  // Update per file params
+  UpdateParamsRecursively(params, file);
+
+  // Replace any existing options with ones from command line
+  for (int i = 0; i < options.size(); i++) {
+    string option_name = TrimString(options[i].first);
+    string option_value = TrimString(options[i].second);
+    if (option_name == "output_list_file") {
+      output_list_file = option_value;
+    } else if (option_name == "java_package") {
+        vector<string> parts;
+        SplitStringUsing(option_value, "|", &parts);
+        if (parts.size() != 2) {
+          *error = "Bad java_package, expecting filename|PackageName found '"
+            + option_value + "'";
+          return false;
+        }
+        params.set_java_package(parts[0], parts[1]);
+    } else if (option_name == "java_outer_classname") {
+        vector<string> parts;
+        SplitStringUsing(option_value, "|", &parts);
+        if (parts.size() != 2) {
+          *error = "Bad java_outer_classname, "
+                   "expecting filename|ClassName found '"
+                   + option_value + "'";
+          return false;
+        }
+        params.set_java_outer_classname(parts[0], parts[1]);
+    } else if (option_name == "store_unknown_fields") {
+      params.set_store_unknown_fields(option_value == "true");
+    } else if (option_name == "java_multiple_files") {
+      params.set_override_java_multiple_files(option_value == "true");
+    } else if (option_name == "java_nano_generate_has") {
+      params.set_generate_has(option_value == "true");
+    } else if (option_name == "enum_style") {
+      params.set_java_enum_style(option_value == "java");
+    } else if (option_name == "optional_field_style") {
+      params.set_optional_field_accessors(option_value == "accessors");
+      params.set_use_reference_types_for_primitives(option_value == "reftypes"
+          || option_value == "reftypes_compat_mode");
+      params.set_reftypes_primitive_enums(
+          option_value == "reftypes_compat_mode");
+      if (option_value == "reftypes_compat_mode") {
+        params.set_generate_clear(false);
+      }
+    } else if (option_name == "generate_equals") {
+      params.set_generate_equals(option_value == "true");
+    } else if (option_name == "ignore_services") {
+      params.set_ignore_services(option_value == "true");
+    } else if (option_name == "parcelable_messages") {
+      params.set_parcelable_messages(option_value == "true");
+    } else if (option_name == "generate_clone") {
+      params.set_generate_clone(option_value == "true");
+    } else if (option_name == "generate_intdefs") {
+      params.set_generate_intdefs(option_value == "true");
+    } else if (option_name == "generate_clear") {
+      params.set_generate_clear(option_value == "true");
+    } else if (option_name == "bytes_offset_length") {
+      params.set_bytes_offset_length(option_value == "true");
+    } else {
+      *error = "Ignore unknown javanano generator option: " + option_name;
+    }
+  }
+
+  // Check illegal parameter combinations
+  // Note: the enum-like optional_field_style generator param ensures
+  // that we can never have illegal combinations of field styles
+  // (e.g. reftypes and accessors can't be on at the same time).
+  if (params.generate_has()
+      && (params.optional_field_accessors()
+          || params.use_reference_types_for_primitives())) {
+    error->assign("java_nano_generate_has=true cannot be used in conjunction"
+        " with optional_field_style=accessors or optional_field_style=reftypes");
+    return false;
+  }
+
+  // Theoretically possible, but not implemented.
+  if (params.bytes_offset_length()
+      && (params.optional_field_accessors() || params.generate_equals())) {
+    error->assign("bytes_offset_length=true cannot be used in conjunction"
+        " with optional_field_style=accessors or generate_equals=true");
+    return false;
+  }
+
+  // -----------------------------------------------------------------
+
+  FileGenerator file_generator(file, params);
+  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;
+
+  if (IsOuterClassNeeded(params, file)) {
+    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/protobuf/src/google/protobuf/compiler/javanano/javanano_generator.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_generator.h
new file mode 100644
index 0000000..0c1e3a4
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_generator.h
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Generates Java nano code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_NANO_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_NANO_GENERATOR_H__
+
+#include <string>
+#include <google/protobuf/compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+// CodeGenerator implementation which generates Java nano code.  If you create your
+// own protocol compiler binary and you want it to support Java output for the
+// nano runtime, you can do so by registering an instance of this CodeGenerator with
+// the CommandLineInterface in your main() function.
+class LIBPROTOC_EXPORT JavaNanoGenerator : public CodeGenerator {
+ public:
+  JavaNanoGenerator();
+  ~JavaNanoGenerator();
+
+  // implements CodeGenerator ----------------------------------------
+  bool Generate(const FileDescriptor* file,
+                const string& parameter,
+                OutputDirectory* output_directory,
+                string* error) const;
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaNanoGenerator);
+};
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_NANO_GENERATOR_H__
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_helpers.cc b/protobuf/src/google/protobuf/compiler/javanano/javanano_helpers.cc
new file mode 100644
index 0000000..2149418
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_helpers.cc
@@ -0,0 +1,566 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <limits>
+#include <vector>
+
+#include <google/protobuf/compiler/javanano/javanano_helpers.h>
+#include <google/protobuf/compiler/javanano/javanano_params.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+const char kThickSeparator[] =
+  "// ===================================================================\n";
+const char kThinSeparator[] =
+  "// -------------------------------------------------------------------\n";
+
+class RenameKeywords {
+ private:
+  hash_set<string> java_keywords_set_;
+
+ public:
+  RenameKeywords() {
+    static const char* kJavaKeywordsList[] = {
+      // Reserved Java Keywords
+      "abstract", "assert", "boolean", "break", "byte", "case", "catch",
+      "char", "class", "const", "continue", "default", "do", "double", "else",
+      "enum", "extends", "final", "finally", "float", "for", "goto", "if",
+      "implements", "import", "instanceof", "int", "interface", "long",
+      "native", "new", "package", "private", "protected", "public", "return",
+      "short", "static", "strictfp", "super", "switch", "synchronized",
+      "this", "throw", "throws", "transient", "try", "void", "volatile", "while",
+
+      // Reserved Keywords for Literals
+      "false", "null", "true"
+    };
+
+    for (int i = 0; i < GOOGLE_ARRAYSIZE(kJavaKeywordsList); i++) {
+      java_keywords_set_.insert(kJavaKeywordsList[i]);
+    }
+  }
+
+  // Used to rename the a field name if it's a java keyword.  Specifically
+  // this is used to rename the ["name"] or ["capitalized_name"] field params.
+  // (http://docs.oracle.com/javase/tutorial/java/nutsandbolts/_keywords.html)
+  string RenameJavaKeywordsImpl(const string& input) {
+    string result = input;
+
+    if (java_keywords_set_.find(result) != java_keywords_set_.end()) {
+      result += "_";
+    }
+
+    return result;
+  }
+
+};
+
+static RenameKeywords sRenameKeywords;
+
+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 RenameJavaKeywords(const string& input) {
+  return sRenameKeywords.RenameJavaKeywordsImpl(input);
+}
+
+string StripProto(const string& filename) {
+  if (HasSuffixString(filename, ".protodevel")) {
+    return StripSuffixString(filename, ".protodevel");
+  } else {
+    return StripSuffixString(filename, ".proto");
+  }
+}
+
+string FileClassName(const Params& params, const FileDescriptor* file) {
+  if (params.has_java_outer_classname(file->name())) {
+    return params.java_outer_classname(file->name());
+  } else {
+    // Use the filename itself with underscores removed
+    // and a CamelCase style name.
+    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 Params& params, const FileDescriptor* file) {
+  if (params.has_java_package(file->name())) {
+    return params.java_package(file->name());
+  } else {
+    string result = kDefaultPackage;
+    if (!file->package().empty()) {
+      if (!result.empty()) result += '.';
+      result += file->package();
+    }
+    return result;
+  }
+}
+
+bool IsOuterClassNeeded(const Params& params, const FileDescriptor* file) {
+  // If java_multiple_files is false, the outer class is always needed.
+  if (!params.java_multiple_files(file->name())) {
+    return true;
+  }
+
+  // File-scope extensions need the outer class as the scope.
+  if (file->extension_count() != 0) {
+    return true;
+  }
+
+  // If container interfaces are not generated, file-scope enums need the
+  // outer class as the scope.
+  if (file->enum_type_count() != 0 && !params.java_enum_style()) {
+    return true;
+  }
+
+  return false;
+}
+
+string ToJavaName(const Params& params, const string& name, bool is_class,
+    const Descriptor* parent, const FileDescriptor* file) {
+  string result;
+  if (parent != NULL) {
+    result.append(ClassName(params, parent));
+  } else if (is_class && params.java_multiple_files(file->name())) {
+    result.append(FileJavaPackage(params, file));
+  } else {
+    result.append(ClassName(params, file));
+  }
+  if (!result.empty()) result.append(1, '.');
+  result.append(RenameJavaKeywords(name));
+  return result;
+}
+
+string ClassName(const Params& params, const FileDescriptor* descriptor) {
+  string result = FileJavaPackage(params, descriptor);
+  if (!result.empty()) result += '.';
+  result += FileClassName(params, descriptor);
+  return result;
+}
+
+string ClassName(const Params& params, const EnumDescriptor* descriptor) {
+  const Descriptor* parent = descriptor->containing_type();
+  // When using Java enum style, an enum's class name contains the enum name.
+  // Use the standard ToJavaName translation.
+  if (params.java_enum_style()) {
+    return ToJavaName(params, descriptor->name(), true, parent,
+                      descriptor->file());
+  }
+  // Otherwise the enum members are accessed from the enclosing class.
+  if (parent != NULL) {
+    return ClassName(params, parent);
+  } else {
+    return ClassName(params, descriptor->file());
+  }
+}
+
+string FieldConstantName(const FieldDescriptor *field) {
+  string name = field->name() + "_FIELD_NUMBER";
+  UpperString(&name);
+  return name;
+}
+
+string FieldDefaultConstantName(const FieldDescriptor *field) {
+  return "_" + RenameJavaKeywords(UnderscoresToCamelCase(field)) + "Default";
+}
+
+void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
+  // We don't want to print group bodies so we cut off after the first line
+  // (the second line for extensions).
+  string def = field->DebugString();
+  string::size_type first_line_end = def.find_first_of('\n');
+  printer->Print("// $def$\n",
+    "def", def.substr(0, first_line_end));
+  if (field->is_extension()) {
+    string::size_type second_line_start = first_line_end + 1;
+    string::size_type second_line_length =
+        def.find('\n', second_line_start) - second_line_start;
+    printer->Print("// $def$\n",
+      "def", def.substr(second_line_start, second_line_length));
+  }
+}
+
+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;
+}
+
+string 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 "byte[]";
+    case JAVATYPE_ENUM   : return "int";
+    case JAVATYPE_MESSAGE: return "";
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return "";
+}
+
+string 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 "byte[]";
+    case JAVATYPE_ENUM   : return "java.lang.Integer";
+    case JAVATYPE_MESSAGE: return "";
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return "";
+}
+
+string EmptyArrayName(const Params& params, const FieldDescriptor* field) {
+  switch (GetJavaType(field)) {
+    case JAVATYPE_INT    : return "com.google.protobuf.nano.WireFormatNano.EMPTY_INT_ARRAY";
+    case JAVATYPE_LONG   : return "com.google.protobuf.nano.WireFormatNano.EMPTY_LONG_ARRAY";
+    case JAVATYPE_FLOAT  : return "com.google.protobuf.nano.WireFormatNano.EMPTY_FLOAT_ARRAY";
+    case JAVATYPE_DOUBLE : return "com.google.protobuf.nano.WireFormatNano.EMPTY_DOUBLE_ARRAY";
+    case JAVATYPE_BOOLEAN: return "com.google.protobuf.nano.WireFormatNano.EMPTY_BOOLEAN_ARRAY";
+    case JAVATYPE_STRING : return "com.google.protobuf.nano.WireFormatNano.EMPTY_STRING_ARRAY";
+    case JAVATYPE_BYTES  : return "com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES_ARRAY";
+    case JAVATYPE_ENUM   : return "com.google.protobuf.nano.WireFormatNano.EMPTY_INT_ARRAY";
+    case JAVATYPE_MESSAGE: return ClassName(params, field->message_type()) + ".EMPTY_ARRAY";
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return "";
+}
+
+string DefaultValue(const Params& params, const FieldDescriptor* field) {
+  if (field->label() == FieldDescriptor::LABEL_REPEATED) {
+    return EmptyArrayName(params, field);
+  }
+
+  if (params.use_reference_types_for_primitives()) {
+    if (params.reftypes_primitive_enums()
+          && field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+      return "Integer.MIN_VALUE";
+    }
+    return "null";
+  }
+
+  // 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: {
+      double value = field->default_value_double();
+      if (value == numeric_limits<double>::infinity()) {
+        return "Double.POSITIVE_INFINITY";
+      } else if (value == -numeric_limits<double>::infinity()) {
+        return "Double.NEGATIVE_INFINITY";
+      } else if (value != value) {
+        return "Double.NaN";
+      } else {
+        return SimpleDtoa(value) + "D";
+      }
+    }
+    case FieldDescriptor::CPPTYPE_FLOAT: {
+      float value = field->default_value_float();
+      if (value == numeric_limits<float>::infinity()) {
+        return "Float.POSITIVE_INFINITY";
+      } else if (value == -numeric_limits<float>::infinity()) {
+        return "Float.NEGATIVE_INFINITY";
+      } else if (value != value) {
+        return "Float.NaN";
+      } else {
+        return SimpleFtoa(value) + "F";
+      }
+    }
+    case FieldDescriptor::CPPTYPE_BOOL:
+      return field->default_value_bool() ? "true" : "false";
+    case FieldDescriptor::CPPTYPE_STRING:
+      if (!field->default_value_string().empty()) {
+        // Point it to the static final in the generated code.
+        return FieldDefaultConstantName(field);
+      } else {
+        if (field->type() == FieldDescriptor::TYPE_BYTES) {
+          return "com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES";
+        } else {
+          return "\"\"";
+        }
+      }
+
+    case FieldDescriptor::CPPTYPE_ENUM:
+      return ClassName(params, field->enum_type()) + "." +
+             RenameJavaKeywords(field->default_value_enum()->name());
+
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      return "null";
+
+    // No default because we want the compiler to complain if any new
+    // types are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return "";
+}
+
+
+static const char* kBitMasks[] = {
+  "0x00000001",
+  "0x00000002",
+  "0x00000004",
+  "0x00000008",
+  "0x00000010",
+  "0x00000020",
+  "0x00000040",
+  "0x00000080",
+
+  "0x00000100",
+  "0x00000200",
+  "0x00000400",
+  "0x00000800",
+  "0x00001000",
+  "0x00002000",
+  "0x00004000",
+  "0x00008000",
+
+  "0x00010000",
+  "0x00020000",
+  "0x00040000",
+  "0x00080000",
+  "0x00100000",
+  "0x00200000",
+  "0x00400000",
+  "0x00800000",
+
+  "0x01000000",
+  "0x02000000",
+  "0x04000000",
+  "0x08000000",
+  "0x10000000",
+  "0x20000000",
+  "0x40000000",
+  "0x80000000",
+};
+
+string GetBitFieldName(int index) {
+  string var_name = "bitField";
+  var_name += SimpleItoa(index);
+  var_name += "_";
+  return var_name;
+}
+
+string GetBitFieldNameForBit(int bit_index) {
+  return GetBitFieldName(bit_index / 32);
+}
+
+string GenerateGetBit(int bit_index) {
+  string var_name = GetBitFieldNameForBit(bit_index);
+  int bit_in_var_index = bit_index % 32;
+
+  string mask = kBitMasks[bit_in_var_index];
+  string result = "((" + var_name + " & " + mask + ") != 0)";
+  return result;
+}
+
+string GenerateSetBit(int bit_index) {
+  string var_name = GetBitFieldNameForBit(bit_index);
+  int bit_in_var_index = bit_index % 32;
+
+  string mask = kBitMasks[bit_in_var_index];
+  string result = var_name + " |= " + mask;
+  return result;
+}
+
+string GenerateClearBit(int bit_index) {
+  string var_name = GetBitFieldNameForBit(bit_index);
+  int bit_in_var_index = bit_index % 32;
+
+  string mask = kBitMasks[bit_in_var_index];
+  string result = var_name + " = (" + var_name + " & ~" + mask + ")";
+  return result;
+}
+
+string GenerateDifferentBit(int bit_index) {
+  string var_name = GetBitFieldNameForBit(bit_index);
+  int bit_in_var_index = bit_index % 32;
+
+  string mask = kBitMasks[bit_in_var_index];
+  string result = "((" + var_name + " & " + mask
+      + ") != (other." + var_name + " & " + mask + "))";
+  return result;
+}
+
+void SetBitOperationVariables(const string name,
+    int bitIndex, map<string, string>* variables) {
+  (*variables)["get_" + name] = GenerateGetBit(bitIndex);
+  (*variables)["set_" + name] = GenerateSetBit(bitIndex);
+  (*variables)["clear_" + name] = GenerateClearBit(bitIndex);
+  (*variables)["different_" + name] = GenerateDifferentBit(bitIndex);
+}
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_helpers.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_helpers.h
new file mode 100644
index 0000000..886bff8
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_helpers.h
@@ -0,0 +1,189 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/compiler/javanano/javanano_params.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+// 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);
+
+// Appends an "_" to the end of a field where the name is a reserved java
+// keyword.  For example int32 public = 1 will generate int public_.
+string RenameJavaKeywords(const string& input);
+
+// 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 Params& params, const FileDescriptor* file);
+
+// Returns the file's Java package name.
+string FileJavaPackage(const Params& params, const FileDescriptor* file);
+
+// Returns whether the Java outer class is needed, i.e. whether the option
+// java_multiple_files is false, or the proto file contains any file-scope
+// enums/extensions.
+bool IsOuterClassNeeded(const Params& params, const FileDescriptor* file);
+
+// Converts the given simple name of a proto entity to its fully-qualified name
+// in the Java namespace, given that it is in the given file enclosed in the
+// given parent message (or NULL for file-scope entities). Whether the file's
+// outer class name should be included in the return value depends on factors
+// inferrable from the given arguments, including is_class which indicates
+// whether the entity translates to a Java class.
+string ToJavaName(const Params& params, const string& name, bool is_class,
+    const Descriptor* parent, const FileDescriptor* file);
+
+// These return the fully-qualified class name corresponding to the given
+// descriptor.
+inline string ClassName(const Params& params, const Descriptor* descriptor) {
+  return ToJavaName(params, descriptor->name(), true,
+                    descriptor->containing_type(), descriptor->file());
+}
+string ClassName(const Params& params, const EnumDescriptor* descriptor);
+inline string ClassName(const Params& params,
+    const ServiceDescriptor* descriptor) {
+  return ToJavaName(params, descriptor->name(), true, NULL, descriptor->file());
+}
+inline string ExtensionIdentifierName(const Params& params,
+    const FieldDescriptor* descriptor) {
+  return ToJavaName(params, descriptor->name(), false,
+                    descriptor->extension_scope(), descriptor->file());
+}
+string ClassName(const Params& params, const FileDescriptor* descriptor);
+
+// Get the unqualified name that should be used for a field's field
+// number constant.
+string FieldConstantName(const FieldDescriptor *field);
+
+string FieldDefaultConstantName(const FieldDescriptor *field);
+
+// Print the field's proto-syntax definition as a comment.
+void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field);
+
+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());
+}
+
+string PrimitiveTypeName(JavaType 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.
+string BoxedPrimitiveTypeName(JavaType type);
+
+string EmptyArrayName(const Params& params, const FieldDescriptor* field);
+
+string DefaultValue(const Params& params, const FieldDescriptor* field);
+
+
+// Methods for shared bitfields.
+
+// Gets the name of the shared bitfield for the given field index.
+string GetBitFieldName(int index);
+
+// Gets the name of the shared bitfield for the given bit index.
+// Effectively, GetBitFieldName(bit_index / 32)
+string GetBitFieldNameForBit(int bit_index);
+
+// Generates the java code for the expression that returns whether the bit at
+// the given bit index is set.
+// Example: "((bitField1_ & 0x04000000) != 0)"
+string GenerateGetBit(int bit_index);
+
+// Generates the java code for the expression that sets the bit at the given
+// bit index.
+// Example: "bitField1_ |= 0x04000000"
+string GenerateSetBit(int bit_index);
+
+// Generates the java code for the expression that clears the bit at the given
+// bit index.
+// Example: "bitField1_ = (bitField1_ & ~0x04000000)"
+string GenerateClearBit(int bit_index);
+
+// Generates the java code for the expression that returns whether the bit at
+// the given bit index contains different values in the current object and
+// another object accessible via the variable 'other'.
+// Example: "((bitField1_ & 0x04000000) != (other.bitField1_ & 0x04000000))"
+string GenerateDifferentBit(int bit_index);
+
+// Sets the 'get_*', 'set_*', 'clear_*' and 'different_*' variables, where * is
+// the given name of the bit, to the appropriate Java expressions for the given
+// bit index.
+void SetBitOperationVariables(const string name,
+    int bitIndex, map<string, string>* variables);
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_message.cc b/protobuf/src/google/protobuf/compiler/javanano/javanano_message.cc
new file mode 100644
index 0000000..b639435
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_message.cc
@@ -0,0 +1,620 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javanano/javanano_message.h>
+#include <google/protobuf/compiler/javanano/javanano_enum.h>
+#include <google/protobuf/compiler/javanano/javanano_extension.h>
+#include <google/protobuf/compiler/javanano/javanano_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 javanano {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+struct FieldOrderingByNumber {
+  inline bool operator()(const FieldDescriptor* a,
+                         const FieldDescriptor* b) const {
+    return a->number() < b->number();
+  }
+};
+
+// 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;
+}
+
+}  // namespace
+
+// ===================================================================
+
+MessageGenerator::MessageGenerator(const Descriptor* descriptor, const Params& params)
+  : params_(params),
+    descriptor_(descriptor),
+    field_generators_(descriptor, params) {
+}
+
+MessageGenerator::~MessageGenerator() {}
+
+void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
+  // 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), params_)
+      .GenerateStaticVariables(printer);
+  }
+}
+
+void MessageGenerator::GenerateStaticVariableInitializers(
+    io::Printer* printer) {
+  // Generate static member initializers for all nested types.
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+   // TODO(kenton):  Reuse MessageGenerator objects?
+    MessageGenerator(descriptor_->nested_type(i), params_)
+      .GenerateStaticVariableInitializers(printer);
+  }
+}
+
+void MessageGenerator::Generate(io::Printer* printer) {
+  if (!params_.store_unknown_fields() &&
+      (descriptor_->extension_count() != 0 || descriptor_->extension_range_count() != 0)) {
+    GOOGLE_LOG(FATAL) << "Extensions are only supported in NANO_RUNTIME if the "
+        "'store_unknown_fields' generator option is 'true'\n";
+  }
+
+  const string& file_name = descriptor_->file()->name();
+  bool is_own_file =
+    params_.java_multiple_files(file_name)
+      && descriptor_->containing_type() == NULL;
+
+  if (is_own_file) {
+    // Note: constants (from enums and fields requiring stored defaults, emitted in the loop below)
+    // may have the same names as constants in the nested classes. This causes Java warnings, but
+    // is not fatal, so we suppress those warnings here in the top-most class declaration.
+    printer->Print(
+      "\n"
+      "@SuppressWarnings(\"hiding\")\n"
+      "public final class $classname$ extends\n",
+      "classname", descriptor_->name());
+  } else {
+    printer->Print(
+      "\n"
+      "public static final class $classname$ extends\n",
+      "classname", descriptor_->name());
+  }
+  if (params_.store_unknown_fields() && params_.parcelable_messages()) {
+    printer->Print(
+      "    com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$>",
+      "classname", descriptor_->name());
+  } else if (params_.store_unknown_fields()) {
+    printer->Print(
+      "    com.google.protobuf.nano.ExtendableMessageNano<$classname$>",
+      "classname", descriptor_->name());
+  } else if (params_.parcelable_messages()) {
+    printer->Print(
+      "    com.google.protobuf.nano.android.ParcelableMessageNano");
+  } else {
+    printer->Print(
+      "    com.google.protobuf.nano.MessageNano");
+  }
+  if (params_.generate_clone()) {
+    printer->Print(" implements java.lang.Cloneable {\n");
+  } else {
+    printer->Print(" {\n");
+  }
+  printer->Indent();
+
+  if (params_.parcelable_messages()) {
+    printer->Print(
+      "\n"
+      "// Used by Parcelable\n"
+      "@SuppressWarnings({\"unused\"})\n"
+      "public static final android.os.Parcelable.Creator<$classname$> CREATOR =\n"
+      "    new com.google.protobuf.nano.android.ParcelableMessageNanoCreator<\n"
+      "        $classname$>($classname$.class);\n",
+      "classname", descriptor_->name());
+  }
+
+  // Nested types and extensions
+  for (int i = 0; i < descriptor_->extension_count(); i++) {
+    ExtensionGenerator(descriptor_->extension(i), params_).Generate(printer);
+  }
+
+  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+    EnumGenerator(descriptor_->enum_type(i), params_).Generate(printer);
+  }
+
+  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+    MessageGenerator(descriptor_->nested_type(i), params_).Generate(printer);
+  }
+
+  // Lazy initialization of otherwise static final fields can help prevent the
+  // class initializer from being generated. We want to prevent it because it
+  // stops ProGuard from inlining any methods in this class into call sites and
+  // therefore reducing the method count. However, extensions are best kept as
+  // public static final fields with initializers, so with their existence we
+  // won't bother with lazy initialization.
+  bool lazy_init = descriptor_->extension_count() == 0;
+
+  // Empty array
+  if (lazy_init) {
+    printer->Print(
+      "\n"
+      "private static volatile $classname$[] _emptyArray;\n"
+      "public static $classname$[] emptyArray() {\n"
+      "  // Lazily initializes the empty array\n"
+      "  if (_emptyArray == null) {\n"
+      "    synchronized (\n"
+      "        com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
+      "      if (_emptyArray == null) {\n"
+      "        _emptyArray = new $classname$[0];\n"
+      "      }\n"
+      "    }\n"
+      "  }\n"
+      "  return _emptyArray;\n"
+      "}\n",
+      "classname", descriptor_->name());
+  } else {
+    printer->Print(
+      "\n"
+      "private static final $classname$[] EMPTY_ARRAY = {};\n"
+      "public static $classname$[] emptyArray() {\n"
+      "  return EMPTY_ARRAY;\n"
+      "}\n",
+      "classname", descriptor_->name());
+  }
+
+  // Integers for bit fields
+  int totalInts = (field_generators_.total_bits() + 31) / 32;
+  if (totalInts > 0) {
+    printer->Print("\n");
+    for (int i = 0; i < totalInts; i++) {
+      printer->Print("private int $bit_field_name$;\n",
+        "bit_field_name", GetBitFieldName(i));
+    }
+  }
+
+  // Fields and maybe their default values
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    printer->Print("\n");
+    PrintFieldComment(printer, descriptor_->field(i));
+    field_generators_.get(descriptor_->field(i)).GenerateMembers(
+        printer, lazy_init);
+  }
+
+  // Insertion point for proto compiler plugins
+  printer->Print("\n// @@protoc_insertion_point(class_scope:$classname$)\n",
+                 "classname", descriptor_->full_name());
+
+  // Constructor, with lazy init code if needed
+  if (lazy_init && field_generators_.saved_defaults_needed()) {
+    printer->Print(
+      "\n"
+      "private static volatile boolean _classInitialized;\n"
+      "\n"
+      "public $classname$() {\n"
+      "  // Lazily initializes the field defaults\n"
+      "  if (!_classInitialized) {\n"
+      "    synchronized (\n"
+      "        com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) {\n"
+      "      if (!_classInitialized) {\n",
+      "classname", descriptor_->name());
+    printer->Indent();
+    printer->Indent();
+    printer->Indent();
+    printer->Indent();
+    for (int i = 0; i < descriptor_->field_count(); i++) {
+      field_generators_.get(descriptor_->field(i))
+          .GenerateInitSavedDefaultCode(printer);
+    }
+    printer->Outdent();
+    printer->Outdent();
+    printer->Outdent();
+    printer->Outdent();
+    printer->Print(
+      "        _classInitialized = true;\n"
+      "      }\n"
+      "    }\n"
+      "  }\n");
+    if (params_.generate_clear()) {
+      printer->Print("  clear();\n");
+    }
+    printer->Print("}\n");
+  } else {
+    printer->Print(
+      "\n"
+      "public $classname$() {\n",
+      "classname", descriptor_->name());
+    if (params_.generate_clear()) {
+      printer->Print("  clear();\n");
+    } else {
+      printer->Indent();
+      GenerateFieldInitializers(printer);
+      printer->Outdent();
+    }
+    printer->Print("}\n");
+  }
+
+  // Other methods in this class
+
+  GenerateClear(printer);
+
+  if (params_.generate_clone()) {
+    GenerateClone(printer);
+  }
+
+  if (params_.generate_equals()) {
+    GenerateEquals(printer);
+    GenerateHashCode(printer);
+  }
+
+  GenerateMessageSerializationMethods(printer);
+  GenerateMergeFromMethods(printer);
+  GenerateParseFromMethods(printer);
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+// ===================================================================
+
+void MessageGenerator::
+GenerateMessageSerializationMethods(io::Printer* printer) {
+  // Rely on the parent implementations of writeTo() and getSerializedSize()
+  // if there are no fields to serialize in this message.
+  if (descriptor_->field_count() == 0) {
+    return;
+  }
+
+  scoped_array<const FieldDescriptor*> sorted_fields(
+    SortFieldsByNumber(descriptor_));
+
+  printer->Print(
+    "\n"
+    "@Override\n"
+    "public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output)\n"
+    "    throws java.io.IOException {\n");
+  printer->Indent();
+
+  // Output the fields in sorted order
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    GenerateSerializeOneField(printer, sorted_fields[i]);
+  }
+
+  // The parent implementation will write any unknown fields if necessary.
+  printer->Print(
+    "super.writeTo(output);\n");
+
+  printer->Outdent();
+  printer->Print("}\n");
+
+  // The parent implementation will get the serialized size for unknown
+  // fields if necessary.
+  printer->Print(
+    "\n"
+    "@Override\n"
+    "protected int computeSerializedSize() {\n"
+    "  int size = super.computeSerializedSize();\n");
+  printer->Indent();
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "  return size;\n"
+    "}\n");
+}
+
+void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) {
+  scoped_array<const FieldDescriptor*> sorted_fields(
+    SortFieldsByNumber(descriptor_));
+
+  printer->Print(
+    "\n"
+    "@Override\n"
+    "public $classname$ mergeFrom(\n"
+    "        com.google.protobuf.nano.CodedInputByteBufferNano input)\n"
+    "    throws java.io.IOException {\n",
+    "classname", descriptor_->name());
+
+  printer->Indent();
+
+  printer->Print(
+    "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
+    "  return this;\n"
+    "default: {\n");
+
+  printer->Indent();
+  if (params_.store_unknown_fields()) {
+    printer->Print(
+        "if (!super.storeUnknownField(input, tag)) {\n"
+        "  return this;\n"
+        "}\n");
+  } else {
+    printer->Print(
+        "if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) {\n"
+        "  return this;\n"   // it's an endgroup tag
+        "}\n");
+  }
+  printer->Print("break;\n");
+  printer->Outdent();
+  printer->Print("}\n");
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = sorted_fields[i];
+    uint32 tag = WireFormatLite::MakeTag(field->number(),
+      WireFormat::WireTypeForFieldType(field->type()));
+
+    printer->Print(
+      "case $tag$: {\n",
+      "tag", SimpleItoa(tag));
+    printer->Indent();
+
+    field_generators_.get(field).GenerateMergingCode(printer);
+
+    printer->Outdent();
+    printer->Print(
+      "  break;\n"
+      "}\n");
+
+    if (field->is_packable()) {
+      // To make packed = true wire compatible, we generate parsing code from a
+      // packed version of this field regardless of field->options().packed().
+      uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
+        WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+      printer->Print(
+        "case $tag$: {\n",
+        "tag", SimpleItoa(packed_tag));
+      printer->Indent();
+
+      field_generators_.get(field).GenerateMergingCodeFromPacked(printer);
+
+      printer->Outdent();
+      printer->Print(
+        "  break;\n"
+        "}\n");
+    }
+  }
+
+  printer->Outdent();
+  printer->Outdent();
+  printer->Outdent();
+  printer->Print(
+    "    }\n"     // switch (tag)
+    "  }\n"       // while (true)
+    "}\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(
+    "\n"
+    "public static $classname$ parseFrom(byte[] data)\n"
+    "    throws com.google.protobuf.nano.InvalidProtocolBufferNanoException {\n"
+    "  return com.google.protobuf.nano.MessageNano.mergeFrom(new $classname$(), data);\n"
+    "}\n"
+    "\n"
+    "public static $classname$ parseFrom(\n"
+    "        com.google.protobuf.nano.CodedInputByteBufferNano input)\n"
+    "    throws java.io.IOException {\n"
+    "  return new $classname$().mergeFrom(input);\n"
+    "}\n",
+    "classname", descriptor_->name());
+}
+
+void MessageGenerator::GenerateSerializeOneField(
+    io::Printer* printer, const FieldDescriptor* field) {
+  field_generators_.get(field).GenerateSerializationCode(printer);
+}
+
+void MessageGenerator::GenerateClear(io::Printer* printer) {
+  if (!params_.generate_clear()) {
+    return;
+  }
+  printer->Print(
+    "\n"
+    "public $classname$ clear() {\n",
+    "classname", descriptor_->name());
+  printer->Indent();
+
+  GenerateFieldInitializers(printer);
+
+  printer->Outdent();
+  printer->Print(
+    "  return this;\n"
+    "}\n");
+}
+
+void MessageGenerator::GenerateFieldInitializers(io::Printer* printer) {
+  // Clear bit fields.
+  int totalInts = (field_generators_.total_bits() + 31) / 32;
+  for (int i = 0; i < totalInts; i++) {
+    printer->Print("$bit_field_name$ = 0;\n",
+      "bit_field_name", GetBitFieldName(i));
+  }
+
+  // Call clear for all of the fields.
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    field_generators_.get(field).GenerateClearCode(printer);
+  }
+
+  // Clear unknown fields.
+  if (params_.store_unknown_fields()) {
+    printer->Print("unknownFieldData = null;\n");
+  }
+  printer->Print("cachedSize = -1;\n");
+}
+
+void MessageGenerator::GenerateClone(io::Printer* printer) {
+  printer->Print(
+    "@Override\n"
+    "public $classname$ clone() {\n",
+    "classname", descriptor_->name());
+  printer->Indent();
+
+  printer->Print(
+    "$classname$ cloned;\n"
+    "try {\n"
+    "  cloned = ($classname$) super.clone();\n"
+    "} catch (java.lang.CloneNotSupportedException e) {\n"
+    "  throw new java.lang.AssertionError(e);\n"
+    "}\n",
+    "classname", descriptor_->name());
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    field_generators_.get(descriptor_->field(i)).GenerateFixClonedCode(printer);
+  }
+
+  printer->Outdent();
+  printer->Print(
+    "  return cloned;\n"
+    "}\n"
+    "\n");
+}
+
+void MessageGenerator::GenerateEquals(io::Printer* printer) {
+  // Don't override if there are no fields. We could generate an
+  // equals method that compares types, but often empty messages
+  // are used as namespaces.
+  if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) {
+    return;
+  }
+
+  printer->Print(
+    "\n"
+    "@Override\n"
+    "public boolean equals(Object o) {\n");
+  printer->Indent();
+  printer->Print(
+    "if (o == this) {\n"
+    "  return true;\n"
+    "}\n"
+    "if (!(o instanceof $classname$)) {\n"
+    "  return false;\n"
+    "}\n"
+    "$classname$ other = ($classname$) o;\n",
+    "classname", descriptor_->name());
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    field_generators_.get(field).GenerateEqualsCode(printer);
+  }
+
+  if (params_.store_unknown_fields()) {
+    printer->Print(
+      "if (unknownFieldData == null || unknownFieldData.isEmpty()) {\n"
+      "  return other.unknownFieldData == null || other.unknownFieldData.isEmpty();\n"
+      "} else {\n"
+      "  return unknownFieldData.equals(other.unknownFieldData);\n"
+      "}");
+  } else {
+    printer->Print(
+      "return true;\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void MessageGenerator::GenerateHashCode(io::Printer* printer) {
+  if (descriptor_->field_count() == 0 && !params_.store_unknown_fields()) {
+    return;
+  }
+
+  printer->Print(
+    "\n"
+    "@Override\n"
+    "public int hashCode() {\n");
+  printer->Indent();
+
+  printer->Print("int result = 17;\n");
+  printer->Print("result = 31 * result + getClass().getName().hashCode();\n");
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    field_generators_.get(field).GenerateHashCodeCode(printer);
+  }
+
+  if (params_.store_unknown_fields()) {
+    printer->Print(
+      "result = 31 * result + \n"
+      "  (unknownFieldData == null || unknownFieldData.isEmpty() ? 0 : \n"
+      "  unknownFieldData.hashCode());\n");
+  }
+
+  printer->Print("return result;\n");
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+// ===================================================================
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_message.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_message.h
new file mode 100644
index 0000000..1bb6557
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_message.h
@@ -0,0 +1,97 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/compiler/javanano/javanano_helpers.h>
+#include <google/protobuf/compiler/javanano/javanano_field.h>
+#include <google/protobuf/compiler/javanano/javanano_params.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class Printer;             // printer.h
+  }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+class MessageGenerator {
+ public:
+  explicit MessageGenerator(const Descriptor* descriptor, const Params& params);
+  ~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);
+
+  // Output code which initializes the static variables generated by
+  // GenerateStaticVariables().
+  void GenerateStaticVariableInitializers(io::Printer* printer);
+
+  // Generate the class itself.
+  void Generate(io::Printer* printer);
+
+ private:
+  void GenerateMessageSerializationMethods(io::Printer* printer);
+  void GenerateMergeFromMethods(io::Printer* printer);
+  void GenerateParseFromMethods(io::Printer* printer);
+  void GenerateSerializeOneField(io::Printer* printer,
+                                 const FieldDescriptor* field);
+
+  void GenerateClear(io::Printer* printer);
+  void GenerateFieldInitializers(io::Printer* printer);
+  void GenerateEquals(io::Printer* printer);
+  void GenerateHashCode(io::Printer* printer);
+  void GenerateClone(io::Printer* printer);
+
+  const Params& params_;
+  const Descriptor* descriptor_;
+  FieldGeneratorMap field_generators_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_message_field.cc b/protobuf/src/google/protobuf/compiler/javanano/javanano_message_field.cc
new file mode 100644
index 0000000..4752644
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_message_field.cc
@@ -0,0 +1,280 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javanano/javanano_message_field.h>
+#include <google/protobuf/compiler/javanano/javanano_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 javanano {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+// TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
+//   repeat code between this and the other field types.
+void SetMessageVariables(const Params& params,
+    const FieldDescriptor* descriptor, map<string, string>* variables) {
+  (*variables)["name"] =
+    RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
+  (*variables)["capitalized_name"] =
+    RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["type"] = ClassName(params, descriptor->message_type());
+  (*variables)["group_or_message"] =
+    (descriptor->type() == FieldDescriptor::TYPE_GROUP) ?
+    "Group" : "Message";
+  (*variables)["message_name"] = descriptor->containing_type()->name();
+  //(*variables)["message_type"] = descriptor->message_type()->name();
+  (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
+}
+
+}  // namespace
+
+// ===================================================================
+
+MessageFieldGenerator::
+MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetMessageVariables(params, descriptor, &variables_);
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {}
+
+void MessageFieldGenerator::
+GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
+  printer->Print(variables_,
+    "public $type$ $name$;\n");
+}
+
+void MessageFieldGenerator::
+GenerateClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$ = null;\n");
+}
+
+void MessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ == null) {\n"
+    "  this.$name$ = new $type$();\n"
+    "}\n");
+
+  if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
+    printer->Print(variables_,
+      "input.readGroup(this.$name$, $number$);\n");
+  } else {
+    printer->Print(variables_,
+      "input.readMessage(this.$name$);\n");
+  }
+}
+
+void MessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null) {\n"
+    "  output.write$group_or_message$($number$, this.$name$);\n"
+    "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null) {\n"
+    "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+    "    .compute$group_or_message$Size($number$, this.$name$);\n"
+    "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateFixClonedCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null) {\n"
+    "  cloned.$name$ = this.$name$.clone();\n"
+    "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ == null) { \n"
+    "  if (other.$name$ != null) {\n"
+    "    return false;\n"
+    "  }\n"
+    "} else {\n"
+    "  if (!this.$name$.equals(other.$name$)) {\n"
+    "    return false;\n"
+    "  }\n"
+    "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateHashCodeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = 31 * result +\n"
+    "    (this.$name$ == null ? 0 : this.$name$.hashCode());\n");
+}
+
+// ===================================================================
+
+RepeatedMessageFieldGenerator::
+RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetMessageVariables(params, descriptor, &variables_);
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+
+void RepeatedMessageFieldGenerator::
+GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const {
+  printer->Print(variables_,
+    "public $type$[] $name$;\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$ = $type$.emptyArray();\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  // First, figure out the length of the array, then parse.
+  printer->Print(variables_,
+    "int arrayLength = com.google.protobuf.nano.WireFormatNano\n"
+    "    .getRepeatedFieldArrayLength(input, $tag$);\n"
+    "int i = this.$name$ == null ? 0 : this.$name$.length;\n"
+    "$type$[] newArray =\n"
+    "    new $type$[i + arrayLength];\n"
+    "if (i != 0) {\n"
+    "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
+    "}\n"
+    "for (; i < newArray.length - 1; i++) {\n"
+    "  newArray[i] = new $type$();\n");
+
+  if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
+    printer->Print(variables_,
+      "  input.readGroup(newArray[i], $number$);\n");
+  } else {
+    printer->Print(variables_,
+      "  input.readMessage(newArray[i]);\n");
+  }
+
+  printer->Print(variables_,
+    "  input.readTag();\n"
+    "}\n"
+    "// Last one without readTag.\n"
+    "newArray[i] = new $type$();\n");
+
+  if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
+    printer->Print(variables_,
+      "input.readGroup(newArray[i], $number$);\n");
+  } else {
+    printer->Print(variables_,
+      "input.readMessage(newArray[i]);\n");
+  }
+
+  printer->Print(variables_,
+    "this.$name$ = newArray;\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null && this.$name$.length > 0) {\n"
+    "  for (int i = 0; i < this.$name$.length; i++) {\n"
+    "    $type$ element = this.$name$[i];\n"
+    "    if (element != null) {\n"
+    "      output.write$group_or_message$($number$, element);\n"
+    "    }\n"
+    "  }\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null && this.$name$.length > 0) {\n"
+    "  for (int i = 0; i < this.$name$.length; i++) {\n"
+    "    $type$ element = this.$name$[i];\n"
+    "    if (element != null) {\n"
+    "      size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+    "        .compute$group_or_message$Size($number$, element);\n"
+    "    }\n"
+    "  }\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateFixClonedCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null && this.$name$.length > 0) {\n"
+    "  cloned.$name$ = new $type$[this.$name$.length];\n"
+    "  for (int i = 0; i < this.$name$.length; i++) {\n"
+    "    if (this.$name$[i] != null) {\n"
+    "      cloned.$name$[i] = this.$name$[i].clone();\n"
+    "    }\n"
+    "  }\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!com.google.protobuf.nano.InternalNano.equals(\n"
+    "    this.$name$, other.$name$)) {\n"
+    "  return false;\n"
+    "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateHashCodeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = 31 * result\n"
+    "    + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
+}
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_message_field.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_message_field.h
new file mode 100644
index 0000000..1edff25
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_message_field.h
@@ -0,0 +1,98 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/javanano/javanano_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+class MessageFieldGenerator : public FieldGenerator {
+ public:
+  explicit MessageFieldGenerator(
+      const FieldDescriptor* descriptor, const Params& params);
+  ~MessageFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer, bool lazy_init) const;
+  void GenerateClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCodeCode(io::Printer* printer) const;
+  void GenerateFixClonedCode(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,
+        const Params& params);
+  ~RepeatedMessageFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer, bool lazy_init) const;
+  void GenerateClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCodeCode(io::Printer* printer) const;
+  void GenerateFixClonedCode(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
+};
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_params.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_params.h
new file mode 100644
index 0000000..482c6c2
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_params.h
@@ -0,0 +1,278 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2010 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: wink@google.com (Wink Saville)
+
+#ifndef PROTOBUF_COMPILER_JAVANANO_JAVANANO_PARAMS_H_
+#define PROTOBUF_COMPILER_JAVANANO_JAVANANO_PARAMS_H_
+
+#include <map>
+#include <set>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+enum eMultipleFiles { JAVANANO_MUL_UNSET, JAVANANO_MUL_FALSE, JAVANANO_MUL_TRUE };
+
+// Parameters for used by the generators
+class Params {
+ public:
+  typedef map<string, string> NameMap;
+  typedef set<string> NameSet;
+ private:
+  string empty_;
+  string base_name_;
+  eMultipleFiles override_java_multiple_files_;
+  bool store_unknown_fields_;
+  NameMap java_packages_;
+  NameMap java_outer_classnames_;
+  NameSet java_multiple_files_;
+  bool generate_has_;
+  bool java_enum_style_;
+  bool optional_field_accessors_;
+  bool use_reference_types_for_primitives_;
+  bool generate_equals_;
+  bool ignore_services_;
+  bool parcelable_messages_;
+  bool reftypes_primitive_enums_;
+  bool generate_clear_;
+  bool generate_clone_;
+  bool generate_intdefs_;
+  bool bytes_offset_length_;
+
+ public:
+  Params(const string & base_name) :
+    empty_(""),
+    base_name_(base_name),
+    override_java_multiple_files_(JAVANANO_MUL_UNSET),
+    store_unknown_fields_(false),
+    generate_has_(false),
+    java_enum_style_(false),
+    optional_field_accessors_(false),
+    use_reference_types_for_primitives_(false),
+    generate_equals_(false),
+    ignore_services_(false),
+    parcelable_messages_(false),
+    reftypes_primitive_enums_(false),
+    generate_clear_(true),
+    generate_clone_(false),
+    generate_intdefs_(false),
+    bytes_offset_length_(false) {
+  }
+
+  const string& base_name() const {
+    return base_name_;
+  }
+
+  bool has_java_package(const string& file_name) const {
+    return java_packages_.find(file_name)
+                        != java_packages_.end();
+  }
+  void set_java_package(const string& file_name,
+      const string& java_package) {
+    java_packages_[file_name] = java_package;
+  }
+  const string& java_package(const string& file_name) const {
+    NameMap::const_iterator itr;
+
+    itr = java_packages_.find(file_name);
+    if  (itr == java_packages_.end()) {
+      return empty_;
+    } else {
+      return itr->second;
+    }
+  }
+  const NameMap& java_packages() {
+    return java_packages_;
+  }
+
+  bool has_java_outer_classname(const string& file_name) const {
+    return java_outer_classnames_.find(file_name)
+                        != java_outer_classnames_.end();
+  }
+  void set_java_outer_classname(const string& file_name,
+      const string& java_outer_classname) {
+    java_outer_classnames_[file_name] = java_outer_classname;
+  }
+  const string& java_outer_classname(const string& file_name) const {
+    NameMap::const_iterator itr;
+
+    itr = java_outer_classnames_.find(file_name);
+    if  (itr == java_outer_classnames_.end()) {
+      return empty_;
+    } else {
+      return itr->second;
+    }
+  }
+  const NameMap& java_outer_classnames() {
+    return java_outer_classnames_;
+  }
+
+  void set_override_java_multiple_files(bool java_multiple_files) {
+    if (java_multiple_files) {
+      override_java_multiple_files_ = JAVANANO_MUL_TRUE;
+    } else {
+      override_java_multiple_files_ = JAVANANO_MUL_FALSE;
+    }
+  }
+  void clear_override_java_multiple_files() {
+    override_java_multiple_files_ = JAVANANO_MUL_UNSET;
+  }
+
+  void set_java_multiple_files(const string& file_name, bool value) {
+    if (value) {
+      java_multiple_files_.insert(file_name);
+    } else {
+      java_multiple_files_.erase(file_name);
+    }
+  }
+  bool java_multiple_files(const string& file_name) const {
+    switch (override_java_multiple_files_) {
+      case JAVANANO_MUL_FALSE:
+        return false;
+      case JAVANANO_MUL_TRUE:
+        return true;
+      default:
+        return java_multiple_files_.find(file_name)
+                != java_multiple_files_.end();
+    }
+  }
+
+  void set_store_unknown_fields(bool value) {
+    store_unknown_fields_ = value;
+  }
+  bool store_unknown_fields() const {
+    return store_unknown_fields_;
+  }
+
+  void set_generate_has(bool value) {
+    generate_has_ = value;
+  }
+  bool generate_has() const {
+    return generate_has_;
+  }
+
+  void set_java_enum_style(bool value) {
+    java_enum_style_ = value;
+  }
+  bool java_enum_style() const {
+    return java_enum_style_;
+  }
+
+  void set_optional_field_accessors(bool value) {
+    optional_field_accessors_ = value;
+  }
+  bool optional_field_accessors() const {
+    return optional_field_accessors_;
+  }
+
+  void set_use_reference_types_for_primitives(bool value) {
+    use_reference_types_for_primitives_ = value;
+  }
+  bool use_reference_types_for_primitives() const {
+    return use_reference_types_for_primitives_;
+  }
+
+  void set_generate_equals(bool value) {
+    generate_equals_ = value;
+  }
+  bool generate_equals() const {
+    return generate_equals_;
+  }
+
+  void set_ignore_services(bool value) {
+    ignore_services_ = value;
+  }
+  bool ignore_services() const {
+    return ignore_services_;
+  }
+
+  void set_parcelable_messages(bool value) {
+    parcelable_messages_ = value;
+  }
+  bool parcelable_messages() const {
+    return parcelable_messages_;
+  }
+
+  void set_reftypes_primitive_enums(bool value) {
+    reftypes_primitive_enums_ = value;
+  }
+  bool reftypes_primitive_enums() const {
+    return reftypes_primitive_enums_;
+  }
+
+  void set_generate_clear(bool value) {
+    generate_clear_ = value;
+  }
+  bool generate_clear() const {
+    return generate_clear_;
+  }
+
+  void set_generate_clone(bool value) {
+    generate_clone_ = value;
+  }
+  bool generate_clone() const {
+    return generate_clone_;
+  }
+
+  void set_generate_intdefs(bool value) {
+    generate_intdefs_ = value;
+  }
+  bool generate_intdefs() const {
+    return generate_intdefs_;
+  }
+
+  // An advanced setting which uses buffer/offset/length tuples for each
+  // non-repeated bytes field, instead of a byte array which is serialized
+  // directly.
+  // The field is considered present iff the offset is not equal to the default
+  // value of -1; the value of the buffer has no relevance otherwise.
+  // In serialization, the [fieldName]Buffer array will be serialized starting
+  // at [fieldName]Offset and with length [fieldName]Length.
+  // In deserialization, the underlying byte array will be the same instance
+  // backing the underlying CodedInputByteBufferNano for all bytes fields, with
+  // appropriate offsets and lengths.
+  // Use with caution! This feature comes with no SLA.
+  void set_bytes_offset_length(bool value) {
+    bytes_offset_length_ = value;
+  }
+  bool bytes_offset_length() const {
+    return bytes_offset_length_;
+  }
+};
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+#endif  // PROTOBUF_COMPILER_JAVANANO_JAVANANO_PARAMS_H_
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc b/protobuf/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
new file mode 100644
index 0000000..7a1655e
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc
@@ -0,0 +1,972 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <math.h>
+#include <string>
+
+#include <google/protobuf/compiler/javanano/javanano_primitive_field.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/javanano/javanano_helpers.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+bool IsReferenceType(JavaType type) {
+  switch (type) {
+    case JAVATYPE_INT    : return false;
+    case JAVATYPE_LONG   : return false;
+    case JAVATYPE_FLOAT  : return false;
+    case JAVATYPE_DOUBLE : return false;
+    case JAVATYPE_BOOLEAN: return false;
+    case JAVATYPE_STRING : return true;
+    case JAVATYPE_BYTES  : return true;
+    case JAVATYPE_ENUM   : return false;
+    case JAVATYPE_MESSAGE: return true;
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return false;
+}
+
+bool IsArrayType(JavaType type) {
+  switch (type) {
+    case JAVATYPE_INT    : return false;
+    case JAVATYPE_LONG   : return false;
+    case JAVATYPE_FLOAT  : return false;
+    case JAVATYPE_DOUBLE : return false;
+    case JAVATYPE_BOOLEAN: return false;
+    case JAVATYPE_STRING : return false;
+    case JAVATYPE_BYTES  : return true;
+    case JAVATYPE_ENUM   : return false;
+    case JAVATYPE_MESSAGE: return false;
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return false;
+}
+
+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;
+}
+
+// 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 WireFormatLite::kFixed32Size;
+    case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
+    case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
+    case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
+    case FieldDescriptor::TYPE_FLOAT   : return WireFormatLite::kFloatSize;
+    case FieldDescriptor::TYPE_DOUBLE  : return WireFormatLite::kDoubleSize;
+
+    case FieldDescriptor::TYPE_BOOL    : return WireFormatLite::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;
+}
+
+// Return true if the type is a that has variable length
+// for instance String's.
+bool IsVariableLenType(JavaType type) {
+  switch (type) {
+    case JAVATYPE_INT    : return false;
+    case JAVATYPE_LONG   : return false;
+    case JAVATYPE_FLOAT  : return false;
+    case JAVATYPE_DOUBLE : return false;
+    case JAVATYPE_BOOLEAN: return false;
+    case JAVATYPE_STRING : return true;
+    case JAVATYPE_BYTES  : return true;
+    case JAVATYPE_ENUM   : return false;
+    case JAVATYPE_MESSAGE: return true;
+
+    // No default because we want the compiler to complain if any new
+    // JavaTypes are added.
+  }
+
+  GOOGLE_LOG(FATAL) << "Can't get here.";
+  return false;
+}
+
+bool AllAscii(const string& text) {
+  for (int i = 0; i < text.size(); i++) {
+    if ((text[i] & 0x80) != 0) {
+      return false;
+    }
+  }
+  return true;
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params,
+                           map<string, string>* variables) {
+  (*variables)["name"] =
+    RenameJavaKeywords(UnderscoresToCamelCase(descriptor));
+  (*variables)["capitalized_name"] =
+    RenameJavaKeywords(UnderscoresToCapitalizedCamelCase(descriptor));
+  (*variables)["number"] = SimpleItoa(descriptor->number());
+  if (params.use_reference_types_for_primitives()
+      && !descriptor->is_repeated()) {
+    (*variables)["type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
+  } else {
+    (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor));
+  }
+  // Deals with defaults. For C++-string types (string and bytes),
+  // we might need to have the generated code do the unicode decoding
+  // (see comments in InternalNano.java for gory details.). We would
+  // like to do this once into a static field and re-use that from
+  // then on.
+  if (descriptor->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
+      !descriptor->default_value_string().empty() &&
+      !params.use_reference_types_for_primitives()) {
+    if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
+      (*variables)["default"] = DefaultValue(params, descriptor);
+      (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
+      (*variables)["default_constant_value"] = strings::Substitute(
+          "com.google.protobuf.nano.InternalNano.bytesDefaultValue(\"$0\")",
+          CEscape(descriptor->default_value_string()));
+      (*variables)["default_copy_if_needed"] =
+          (*variables)["default"] + ".clone()";
+    } else if (AllAscii(descriptor->default_value_string())) {
+      // All chars are ASCII.  In this case directly referencing a
+      // CEscape()'d string literal works fine.
+      (*variables)["default"] =
+          "\"" + CEscape(descriptor->default_value_string()) + "\"";
+      (*variables)["default_copy_if_needed"] = (*variables)["default"];
+    } else {
+      // Strings where some chars are non-ASCII. We need to save the
+      // default value.
+      (*variables)["default"] = DefaultValue(params, descriptor);
+      (*variables)["default_constant"] = FieldDefaultConstantName(descriptor);
+      (*variables)["default_constant_value"] = strings::Substitute(
+          "com.google.protobuf.nano.InternalNano.stringDefaultValue(\"$0\")",
+          CEscape(descriptor->default_value_string()));
+      (*variables)["default_copy_if_needed"] = (*variables)["default"];
+    }
+  } else {
+    // Non-string, non-bytes field. Defaults are literals.
+    (*variables)["default"] = DefaultValue(params, descriptor);
+    (*variables)["default_copy_if_needed"] = (*variables)["default"];
+  }
+  (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor));
+  (*variables)["capitalized_type"] = GetCapitalizedType(descriptor);
+  (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor));
+  (*variables)["tag_size"] = SimpleItoa(
+      WireFormat::TagSize(descriptor->number(), descriptor->type()));
+  (*variables)["non_packed_tag"] = SimpleItoa(
+      internal::WireFormatLite::MakeTag(descriptor->number(),
+          internal::WireFormat::WireTypeForFieldType(descriptor->type())));
+  int fixed_size = FixedSize(descriptor->type());
+  if (fixed_size != -1) {
+    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+  }
+  (*variables)["message_name"] = descriptor->containing_type()->name();
+  (*variables)["empty_array_name"] = EmptyArrayName(params, descriptor);
+}
+}  // namespace
+
+// ===================================================================
+
+PrimitiveFieldGenerator::
+PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, params, &variables_);
+}
+
+PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+
+bool PrimitiveFieldGenerator::SavedDefaultNeeded() const {
+  return variables_.find("default_constant") != variables_.end();
+}
+
+void PrimitiveFieldGenerator::GenerateInitSavedDefaultCode(io::Printer* printer) const {
+  if (variables_.find("default_constant") != variables_.end()) {
+    printer->Print(variables_,
+      "$default_constant$ = $default_constant_value$;\n");
+  }
+}
+
+void PrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer, bool lazy_init) const {
+  if (variables_.find("default_constant") != variables_.end()) {
+    // Those primitive types that need a saved default.
+    if (lazy_init) {
+      printer->Print(variables_,
+        "private static $type$ $default_constant$;\n");
+    } else {
+      printer->Print(variables_,
+        "private static final $type$ $default_constant$ =\n"
+        "    $default_constant_value$;\n");
+    }
+  }
+
+  JavaType java_type = GetJavaType(descriptor_);
+  if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
+    printer->Print(variables_,
+      "public $type$ $name$Buffer;\n"
+      "public int $name$Offset;\n"
+      "public int $name$Length;\n");
+  } else {
+    printer->Print(variables_,
+      "public $type$ $name$;\n");
+  }
+
+  if (params_.generate_has()) {
+    printer->Print(variables_,
+      "public boolean has$capitalized_name$;\n");
+  }
+}
+
+void PrimitiveFieldGenerator::
+GenerateClearCode(io::Printer* printer) const {
+  JavaType java_type = GetJavaType(descriptor_);
+  if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
+    printer->Print(variables_,
+      "$name$Buffer = $default_copy_if_needed$;\n"
+      "$name$Offset = -1;\n"
+      "$name$Length = 0;\n");
+  } else {
+    printer->Print(variables_,
+      "$name$ = $default_copy_if_needed$;\n");
+  }
+
+  if (params_.generate_has()) {
+    printer->Print(variables_,
+      "has$capitalized_name$ = false;\n");
+  }
+}
+
+void PrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  JavaType java_type = GetJavaType(descriptor_);
+  if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
+    printer->Print(variables_,
+      "this.$name$Buffer = input.getBuffer();\n"
+      "this.$name$Length = input.readRawVarint32();\n"
+      "this.$name$Offset = input.getAbsolutePosition();\n"
+      "input.skipRawBytes(this.$name$Length);\n");
+  } else {
+    printer->Print(variables_,
+      "this.$name$ = input.read$capitalized_type$();\n");
+  }
+
+  if (params_.generate_has()) {
+    printer->Print(variables_,
+      "has$capitalized_name$ = true;\n");
+  }
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializationConditional(io::Printer* printer) const {
+  if (params_.use_reference_types_for_primitives()) {
+    // For reference type mode, serialize based on equality
+    // to null.
+    printer->Print(variables_,
+      "if (this.$name$ != null) {\n");
+    return;
+  }
+  if (params_.generate_has()) {
+    printer->Print(variables_,
+      "if (has$capitalized_name$ || ");
+  } else {
+    printer->Print(variables_,
+      "if (");
+  }
+  JavaType java_type = GetJavaType(descriptor_);
+  if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
+    printer->Print(variables_,
+      "this.$name$Offset != -1) {\n");
+  } else if (IsArrayType(java_type)) {
+    printer->Print(variables_,
+      "!java.util.Arrays.equals(this.$name$, $default$)) {\n");
+  } else if (IsReferenceType(java_type)) {
+    printer->Print(variables_,
+      "!this.$name$.equals($default$)) {\n");
+  } else if (java_type == JAVATYPE_FLOAT) {
+    printer->Print(variables_,
+      "java.lang.Float.floatToIntBits(this.$name$)\n"
+      "    != java.lang.Float.floatToIntBits($default$)) {\n");
+  } else if (java_type == JAVATYPE_DOUBLE) {
+    printer->Print(variables_,
+      "java.lang.Double.doubleToLongBits(this.$name$)\n"
+      "    != java.lang.Double.doubleToLongBits($default$)) {\n");
+  } else {
+    printer->Print(variables_,
+      "this.$name$ != $default$) {\n");
+  }
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  if (descriptor_->is_required() && !params_.generate_has()) {
+    // Always serialize a required field if we don't have the 'has' signal.
+    GenerateWriteCode(printer);
+  } else {
+    GenerateSerializationConditional(printer);
+    printer->Indent();
+    GenerateWriteCode(printer);
+    printer->Outdent();
+    printer->Print("}\n");
+  }
+}
+
+void PrimitiveFieldGenerator::
+GenerateWriteCode(io::Printer* printer) const {
+  JavaType java_type = GetJavaType(descriptor_);
+  if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
+    printer->Print(variables_,
+      "output.write$capitalized_type$($number$, this.$name$Buffer,\n"
+      "    this.$name$Offset, this.$name$Length);\n");
+  } else {
+    printer->Print(variables_,
+      "output.write$capitalized_type$($number$, this.$name$);\n");
+  }
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  if (descriptor_->is_required() && !params_.generate_has()) {
+    GenerateComputeSizeCode(printer);
+  } else {
+    GenerateSerializationConditional(printer);
+    printer->Indent();
+    GenerateComputeSizeCode(printer);
+    printer->Outdent();
+    printer->Print("}\n");
+  }
+}
+
+void PrimitiveFieldGenerator::
+GenerateComputeSizeCode(io::Printer* printer) const {
+  JavaType java_type = GetJavaType(descriptor_);
+  if (java_type == JAVATYPE_BYTES && params_.bytes_offset_length()) {
+    printer->Print(variables_,
+      "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+      "    .compute$capitalized_type$Size($number$, this.$name$Length);\n");
+  } else {
+    printer->Print(variables_,
+      "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+      "    .compute$capitalized_type$Size($number$, this.$name$);\n");
+  }
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateFixClonedCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null && this.$name$.length > 0) {\n"
+    "  cloned.$name$ = this.$name$.clone();\n"
+    "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  // We define equality as serialized form equality. If generate_has(),
+  // then if the field value equals the default value in both messages,
+  // but one's 'has' field is set and the other's is not, the serialized
+  // forms are different and we should return false.
+  JavaType java_type = GetJavaType(descriptor_);
+  if (java_type == JAVATYPE_BYTES) {
+    printer->Print(variables_,
+      "if (!java.util.Arrays.equals(this.$name$, other.$name$)");
+    if (params_.generate_has()) {
+      printer->Print(variables_,
+        "\n"
+        "    || (java.util.Arrays.equals(this.$name$, $default$)\n"
+        "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
+    }
+    printer->Print(") {\n"
+      "  return false;\n"
+      "}\n");
+  } else if (java_type == JAVATYPE_STRING
+      || params_.use_reference_types_for_primitives()) {
+    printer->Print(variables_,
+      "if (this.$name$ == null) {\n"
+      "  if (other.$name$ != null) {\n"
+      "    return false;\n"
+      "  }\n"
+      "} else if (!this.$name$.equals(other.$name$)");
+    if (params_.generate_has()) {
+      printer->Print(variables_,
+        "\n"
+        "    || (this.$name$.equals($default$)\n"
+        "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
+    }
+    printer->Print(") {\n"
+      "  return false;\n"
+      "}\n");
+  } else if (java_type == JAVATYPE_FLOAT) {
+    printer->Print(variables_,
+      "{\n"
+      "  int bits = java.lang.Float.floatToIntBits(this.$name$);\n"
+      "  if (bits != java.lang.Float.floatToIntBits(other.$name$)");
+    if (params_.generate_has()) {
+      printer->Print(variables_,
+        "\n"
+        "      || (bits == java.lang.Float.floatToIntBits($default$)\n"
+        "          && this.has$capitalized_name$ != other.has$capitalized_name$)");
+    }
+    printer->Print(") {\n"
+      "    return false;\n"
+      "  }\n"
+      "}\n");
+  } else if (java_type == JAVATYPE_DOUBLE) {
+    printer->Print(variables_,
+      "{\n"
+      "  long bits = java.lang.Double.doubleToLongBits(this.$name$);\n"
+      "  if (bits != java.lang.Double.doubleToLongBits(other.$name$)");
+    if (params_.generate_has()) {
+      printer->Print(variables_,
+        "\n"
+        "      || (bits == java.lang.Double.doubleToLongBits($default$)\n"
+        "          && this.has$capitalized_name$ != other.has$capitalized_name$)");
+    }
+    printer->Print(") {\n"
+      "    return false;\n"
+      "  }\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "if (this.$name$ != other.$name$");
+    if (params_.generate_has()) {
+      printer->Print(variables_,
+        "\n"
+        "    || (this.$name$ == $default$\n"
+        "        && this.has$capitalized_name$ != other.has$capitalized_name$)");
+    }
+    printer->Print(") {\n"
+      "  return false;\n"
+      "}\n");
+  }
+}
+
+void PrimitiveFieldGenerator::
+GenerateHashCodeCode(io::Printer* printer) const {
+  JavaType java_type = GetJavaType(descriptor_);
+  if (java_type == JAVATYPE_BYTES) {
+    printer->Print(variables_,
+      "result = 31 * result + java.util.Arrays.hashCode(this.$name$);\n");
+  } else if (java_type == JAVATYPE_STRING
+      || params_.use_reference_types_for_primitives()) {
+    printer->Print(variables_,
+      "result = 31 * result\n"
+      "    + (this.$name$ == null ? 0 : this.$name$.hashCode());\n");
+  } else {
+    switch (java_type) {
+      // For all Java primitive types below, the hash codes match the
+      // results of BoxedType.valueOf(primitiveValue).hashCode().
+      case JAVATYPE_INT:
+        printer->Print(variables_,
+          "result = 31 * result + this.$name$;\n");
+        break;
+      case JAVATYPE_LONG:
+        printer->Print(variables_,
+          "result = 31 * result\n"
+          "    + (int) (this.$name$ ^ (this.$name$ >>> 32));\n");
+        break;
+      case JAVATYPE_FLOAT:
+        printer->Print(variables_,
+          "result = 31 * result\n"
+          "    + java.lang.Float.floatToIntBits(this.$name$);\n");
+        break;
+      case JAVATYPE_DOUBLE:
+        printer->Print(variables_,
+          "{\n"
+          "  long v = java.lang.Double.doubleToLongBits(this.$name$);\n"
+          "  result = 31 * result + (int) (v ^ (v >>> 32));\n"
+          "}\n");
+        break;
+      case JAVATYPE_BOOLEAN:
+        printer->Print(variables_,
+          "result = 31 * result + (this.$name$ ? 1231 : 1237);\n");
+        break;
+      default:
+        GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
+        break;
+    }
+  }
+}
+
+// ===================================================================
+
+AccessorPrimitiveFieldGenerator::
+AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+     const Params& params, int has_bit_index)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, params, &variables_);
+  SetBitOperationVariables("has", has_bit_index, &variables_);
+}
+
+AccessorPrimitiveFieldGenerator::~AccessorPrimitiveFieldGenerator() {}
+
+bool AccessorPrimitiveFieldGenerator::SavedDefaultNeeded() const {
+  return variables_.find("default_constant") != variables_.end();
+}
+
+void AccessorPrimitiveFieldGenerator::
+GenerateInitSavedDefaultCode(io::Printer* printer) const {
+  if (variables_.find("default_constant") != variables_.end()) {
+    printer->Print(variables_,
+      "$default_constant$ = $default_constant_value$;\n");
+  }
+}
+
+void AccessorPrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer, bool lazy_init) const {
+  if (variables_.find("default_constant") != variables_.end()) {
+    // Those primitive types that need a saved default.
+    if (lazy_init) {
+      printer->Print(variables_,
+        "private static $type$ $default_constant$;\n");
+    } else {
+      printer->Print(variables_,
+        "private static final $type$ $default_constant$ =\n"
+        "    $default_constant_value$;\n");
+    }
+  }
+  printer->Print(variables_,
+    "private $type$ $name$_;\n"
+    "public $type$ get$capitalized_name$() {\n"
+    "  return $name$_;\n"
+    "}\n"
+    "public $message_name$ set$capitalized_name$($type$ value) {\n");
+  if (IsReferenceType(GetJavaType(descriptor_))) {
+    printer->Print(variables_,
+      "  if (value == null) {\n"
+      "    throw new java.lang.NullPointerException();\n"
+      "  }\n");
+  }
+  printer->Print(variables_,
+    "  $name$_ = value;\n"
+    "  $set_has$;\n"
+    "  return this;\n"
+    "}\n"
+    "public boolean has$capitalized_name$() {\n"
+    "  return $get_has$;\n"
+    "}\n"
+    "public $message_name$ clear$capitalized_name$() {\n"
+    "  $name$_ = $default_copy_if_needed$;\n"
+    "  $clear_has$;\n"
+    "  return this;\n"
+    "}\n");
+}
+
+void AccessorPrimitiveFieldGenerator::
+GenerateClearCode(io::Printer* printer) const {
+  
+  printer->Print(variables_,
+    "$name$_ = $default_copy_if_needed$;\n");
+}
+
+void AccessorPrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$_ = input.read$capitalized_type$();\n"
+    "$set_has$;\n");
+}
+
+void AccessorPrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($get_has$) {\n"
+    "  output.write$capitalized_type$($number$, $name$_);\n"
+    "}\n");
+}
+
+void AccessorPrimitiveFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if ($get_has$) {\n"
+    "  size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+    "      .compute$capitalized_type$Size($number$, $name$_);\n"
+    "}\n");
+}
+
+void AccessorPrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  switch (GetJavaType(descriptor_)) {
+    // For all Java primitive types below, the equality checks match the
+    // results of BoxedType.valueOf(primitiveValue).equals(otherValue).
+    case JAVATYPE_FLOAT:
+      printer->Print(variables_,
+        "if ($different_has$\n"
+        "    || java.lang.Float.floatToIntBits($name$_)\n"
+        "        != java.lang.Float.floatToIntBits(other.$name$_)) {\n"
+        "  return false;\n"
+        "}\n");
+      break;
+    case JAVATYPE_DOUBLE:
+      printer->Print(variables_,
+        "if ($different_has$\n"
+        "    || java.lang.Double.doubleToLongBits($name$_)\n"
+        "        != java.lang.Double.doubleToLongBits(other.$name$_)) {\n"
+        "  return false;\n"
+        "}\n");
+      break;
+    case JAVATYPE_INT:
+    case JAVATYPE_LONG:
+    case JAVATYPE_BOOLEAN:
+      printer->Print(variables_,
+        "if ($different_has$\n"
+        "    || $name$_ != other.$name$_) {\n"
+        "  return false;\n"
+        "}\n");
+      break;
+    case JAVATYPE_STRING:
+      // Accessor style would guarantee $name$_ non-null
+      printer->Print(variables_,
+        "if ($different_has$\n"
+        "    || !$name$_.equals(other.$name$_)) {\n"
+        "  return false;\n"
+        "}\n");
+      break;
+    case JAVATYPE_BYTES:
+      // Accessor style would guarantee $name$_ non-null
+      printer->Print(variables_,
+        "if ($different_has$\n"
+        "    || !java.util.Arrays.equals($name$_, other.$name$_)) {\n"
+        "  return false;\n"
+        "}\n");
+      break;
+    default:
+      GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
+      break;
+  }
+}
+
+void AccessorPrimitiveFieldGenerator::
+GenerateHashCodeCode(io::Printer* printer) const {
+  switch (GetJavaType(descriptor_)) {
+    // For all Java primitive types below, the hash codes match the
+    // results of BoxedType.valueOf(primitiveValue).hashCode().
+    case JAVATYPE_INT:
+      printer->Print(variables_,
+        "result = 31 * result + $name$_;\n");
+      break;
+    case JAVATYPE_LONG:
+      printer->Print(variables_,
+        "result = 31 * result + (int) ($name$_ ^ ($name$_ >>> 32));\n");
+      break;
+    case JAVATYPE_FLOAT:
+      printer->Print(variables_,
+        "result = 31 * result +\n"
+        "    java.lang.Float.floatToIntBits($name$_);\n");
+      break;
+    case JAVATYPE_DOUBLE:
+      printer->Print(variables_,
+        "{\n"
+        "  long v = java.lang.Double.doubleToLongBits($name$_);\n"
+        "  result = 31 * result + (int) (v ^ (v >>> 32));\n"
+        "}\n");
+      break;
+    case JAVATYPE_BOOLEAN:
+      printer->Print(variables_,
+        "result = 31 * result + ($name$_ ? 1231 : 1237);\n");
+      break;
+    case JAVATYPE_STRING:
+      // Accessor style would guarantee $name$_ non-null
+      printer->Print(variables_,
+        "result = 31 * result + $name$_.hashCode();\n");
+      break;
+    case JAVATYPE_BYTES:
+      // Accessor style would guarantee $name$_ non-null
+      printer->Print(variables_,
+        "result = 31 * result + java.util.Arrays.hashCode($name$_);\n");
+      break;
+    default:
+      GOOGLE_LOG(ERROR) << "unknown java type for primitive field";
+      break;
+  }
+}
+
+// ===================================================================
+
+RepeatedPrimitiveFieldGenerator::
+RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
+  : FieldGenerator(params), descriptor_(descriptor) {
+  SetPrimitiveVariables(descriptor, params, &variables_);
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMembers(io::Printer* printer, bool /*unused init_defaults*/) const {
+  printer->Print(variables_,
+    "public $type$[] $name$;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateClearCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "$name$ = $default$;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+  // First, figure out the length of the array, then parse.
+  printer->Print(variables_,
+    "int arrayLength = com.google.protobuf.nano.WireFormatNano\n"
+    "    .getRepeatedFieldArrayLength(input, $non_packed_tag$);\n"
+    "int i = this.$name$ == null ? 0 : this.$name$.length;\n");
+
+  if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
+    printer->Print(variables_,
+      "byte[][] newArray = new byte[i + arrayLength][];\n");
+  } else {
+    printer->Print(variables_,
+      "$type$[] newArray = new $type$[i + arrayLength];\n");
+  }
+  printer->Print(variables_,
+    "if (i != 0) {\n"
+    "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
+    "}\n"
+    "for (; i < newArray.length - 1; i++) {\n"
+    "  newArray[i] = input.read$capitalized_type$();\n"
+    "  input.readTag();\n"
+    "}\n"
+    "// Last one without readTag.\n"
+    "newArray[i] = input.read$capitalized_type$();\n"
+    "this.$name$ = newArray;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergingCodeFromPacked(io::Printer* printer) const {
+  printer->Print(
+    "int length = input.readRawVarint32();\n"
+    "int limit = input.pushLimit(length);\n");
+
+  // If we know the elements will all be of the same size, the arrayLength
+  // can be calculated much more easily. However, FixedSize() returns 1 for
+  // repeated bool fields, which are guaranteed to have the fixed size of
+  // 1 byte per value only if we control the output. On the wire they can
+  // legally appear as variable-size integers, so we need to use the slow
+  // way for repeated bool fields.
+  if (descriptor_->type() == FieldDescriptor::TYPE_BOOL
+      || FixedSize(descriptor_->type()) == -1) {
+    printer->Print(variables_,
+      "// First pass to compute array length.\n"
+      "int arrayLength = 0;\n"
+      "int startPos = input.getPosition();\n"
+      "while (input.getBytesUntilLimit() > 0) {\n"
+      "  input.read$capitalized_type$();\n"
+      "  arrayLength++;\n"
+      "}\n"
+      "input.rewindToPosition(startPos);\n");
+  } else {
+    printer->Print(variables_,
+      "int arrayLength = length / $fixed_size$;\n");
+  }
+
+  printer->Print(variables_,
+    "int i = this.$name$ == null ? 0 : this.$name$.length;\n"
+    "$type$[] newArray = new $type$[i + arrayLength];\n"
+    "if (i != 0) {\n"
+    "  java.lang.System.arraycopy(this.$name$, 0, newArray, 0, i);\n"
+    "}\n"
+    "for (; i < newArray.length; i++) {\n"
+    "  newArray[i] = input.read$capitalized_type$();\n"
+    "}\n"
+    "this.$name$ = newArray;\n"
+    "input.popLimit(limit);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateRepeatedDataSizeCode(io::Printer* printer) const {
+  // Creates a variable dataSize and puts the serialized size in there.
+  // If the element type is a Java reference type, also generates
+  // dataCount which stores the number of non-null elements in the field.
+  if (IsReferenceType(GetJavaType(descriptor_))) {
+    printer->Print(variables_,
+      "int dataCount = 0;\n"
+      "int dataSize = 0;\n"
+      "for (int i = 0; i < this.$name$.length; i++) {\n"
+      "  $type$ element = this.$name$[i];\n"
+      "  if (element != null) {\n"
+      "    dataCount++;\n"
+      "    dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+      "        .compute$capitalized_type$SizeNoTag(element);\n"
+      "  }\n"
+      "}\n");
+  } else if (FixedSize(descriptor_->type()) == -1) {
+    printer->Print(variables_,
+      "int dataSize = 0;\n"
+      "for (int i = 0; i < this.$name$.length; i++) {\n"
+      "  $type$ element = this.$name$[i];\n"
+      "  dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+      "      .compute$capitalized_type$SizeNoTag(element);\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "int dataSize = $fixed_size$ * this.$name$.length;\n");
+  }
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializationCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null && this.$name$.length > 0) {\n");
+  printer->Indent();
+
+  if (descriptor_->is_packable() && descriptor_->options().packed()) {
+    GenerateRepeatedDataSizeCode(printer);
+    printer->Print(variables_,
+      "output.writeRawVarint32($tag$);\n"
+      "output.writeRawVarint32(dataSize);\n"
+      "for (int i = 0; i < this.$name$.length; i++) {\n"
+      "  output.write$capitalized_type$NoTag(this.$name$[i]);\n"
+      "}\n");
+  } else if (IsReferenceType(GetJavaType(descriptor_))) {
+    printer->Print(variables_,
+      "for (int i = 0; i < this.$name$.length; i++) {\n"
+      "  $type$ element = this.$name$[i];\n"
+      "  if (element != null) {\n"
+      "    output.write$capitalized_type$($number$, element);\n"
+      "  }\n"
+      "}\n");
+  } else {
+    printer->Print(variables_,
+      "for (int i = 0; i < this.$name$.length; i++) {\n"
+      "  output.write$capitalized_type$($number$, this.$name$[i]);\n"
+      "}\n");
+  }
+
+  printer->Outdent();
+  printer->Print("}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializedSizeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (this.$name$ != null && this.$name$.length > 0) {\n");
+  printer->Indent();
+
+  GenerateRepeatedDataSizeCode(printer);
+
+  printer->Print(
+    "size += dataSize;\n");
+  if (descriptor_->is_packable() && descriptor_->options().packed()) {
+    printer->Print(variables_,
+      "size += $tag_size$;\n"
+      "size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
+      "    .computeRawVarint32Size(dataSize);\n");
+  } else if (IsReferenceType(GetJavaType(descriptor_))) {
+    printer->Print(variables_,
+      "size += $tag_size$ * dataCount;\n");
+  } else {
+    printer->Print(variables_,
+      "size += $tag_size$ * this.$name$.length;\n");
+  }
+
+  printer->Outdent();
+
+  printer->Print(
+    "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateEqualsCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "if (!com.google.protobuf.nano.InternalNano.equals(\n"
+    "    this.$name$, other.$name$)) {\n"
+    "  return false;\n"
+    "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateHashCodeCode(io::Printer* printer) const {
+  printer->Print(variables_,
+    "result = 31 * result\n"
+    "    + com.google.protobuf.nano.InternalNano.hashCode(this.$name$);\n");
+}
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/javanano/javanano_primitive_field.h b/protobuf/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
new file mode 100644
index 0000000..daa712e
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/javanano/javanano_primitive_field.h
@@ -0,0 +1,129 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVANANO_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVANANO_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/compiler/javanano/javanano_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace javanano {
+
+class PrimitiveFieldGenerator : public FieldGenerator {
+ public:
+  explicit PrimitiveFieldGenerator(
+      const FieldDescriptor* descriptor, const Params &params);
+  ~PrimitiveFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  bool SavedDefaultNeeded() const;
+  void GenerateInitSavedDefaultCode(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer, bool lazy_init) const;
+  void GenerateClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCodeCode(io::Printer* printer) const;
+
+ private:
+  void GenerateSerializationConditional(io::Printer* printer) const;
+  void GenerateWriteCode(io::Printer* printer) const;
+  void GenerateComputeSizeCode(io::Printer* printer) const;
+
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
+};
+
+class AccessorPrimitiveFieldGenerator : public FieldGenerator {
+ public:
+  explicit AccessorPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+      const Params &params, int has_bit_index);
+  ~AccessorPrimitiveFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  bool SavedDefaultNeeded() const;
+  void GenerateInitSavedDefaultCode(io::Printer* printer) const;
+  void GenerateMembers(io::Printer* printer, bool lazy_init) const;
+  void GenerateClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCodeCode(io::Printer* printer) const;
+
+ private:
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AccessorPrimitiveFieldGenerator);
+};
+
+class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
+ public:
+  explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params);
+  ~RepeatedPrimitiveFieldGenerator();
+
+  // implements FieldGenerator ---------------------------------------
+  void GenerateMembers(io::Printer* printer, bool lazy_init) const;
+  void GenerateClearCode(io::Printer* printer) const;
+  void GenerateMergingCode(io::Printer* printer) const;
+  void GenerateMergingCodeFromPacked(io::Printer* printer) const;
+  void GenerateSerializationCode(io::Printer* printer) const;
+  void GenerateSerializedSizeCode(io::Printer* printer) const;
+  void GenerateEqualsCode(io::Printer* printer) const;
+  void GenerateHashCodeCode(io::Printer* printer) const;
+  void GenerateFixClonedCode(io::Printer* printer) const;
+
+ private:
+  void GenerateRepeatedDataSizeCode(io::Printer* printer) const;
+
+  const FieldDescriptor* descriptor_;
+  map<string, string> variables_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
+};
+
+}  // namespace javanano
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_JAVANANO_PRIMITIVE_FIELD_H__
diff --git a/protobuf/src/google/protobuf/compiler/main.cc b/protobuf/src/google/protobuf/compiler/main.cc
new file mode 100644
index 0000000..1fc60ce
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/main.cc
@@ -0,0 +1,73 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+#include <google/protobuf/compiler/javamicro/javamicro_generator.h>
+#include <google/protobuf/compiler/javanano/javanano_generator.h>
+
+
+int main(int argc, char* argv[]) {
+
+  google::protobuf::compiler::CommandLineInterface cli;
+  cli.AllowPlugins("protoc-");
+
+  // Proto2 C++
+  google::protobuf::compiler::cpp::CppGenerator cpp_generator;
+  cli.RegisterGenerator("--cpp_out", "--cpp_opt", &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.");
+
+  // Proto2 JavaMicro
+  google::protobuf::compiler::javamicro::JavaMicroGenerator javamicro_generator;
+  cli.RegisterGenerator("--javamicro_out", &javamicro_generator,
+                        "Generate Java source file micro runtime.");
+
+  // Proto2 JavaNano
+  google::protobuf::compiler::javanano::JavaNanoGenerator javanano_generator;
+  cli.RegisterGenerator("--javanano_out", &javanano_generator,
+                        "Generate Java source file nano runtime.");
+
+  return cli.Run(argc, argv);
+}
diff --git a/protobuf/src/google/protobuf/compiler/mock_code_generator.cc b/protobuf/src/google/protobuf/compiler/mock_code_generator.cc
new file mode 100644
index 0000000..916b0cc
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/mock_code_generator.cc
@@ -0,0 +1,240 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/compiler/mock_code_generator.h>
+
+#include <memory>
+
+#include <google/protobuf/testing/file.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// Returns the list of the names of files in all_files in the form of a
+// comma-separated string.
+string CommaSeparatedList(const vector<const FileDescriptor*> all_files) {
+  vector<string> names;
+  for (int i = 0; i < all_files.size(); i++) {
+    names.push_back(all_files[i]->name());
+  }
+  return Join(names, ",");
+}
+
+static const char* kFirstInsertionPointName = "first_mock_insertion_point";
+static const char* kSecondInsertionPointName = "second_mock_insertion_point";
+static const char* kFirstInsertionPoint =
+    "# @@protoc_insertion_point(first_mock_insertion_point) is here\n";
+static const char* kSecondInsertionPoint =
+    "  # @@protoc_insertion_point(second_mock_insertion_point) is here\n";
+
+MockCodeGenerator::MockCodeGenerator(const string& name)
+    : name_(name) {}
+
+MockCodeGenerator::~MockCodeGenerator() {}
+
+void MockCodeGenerator::ExpectGenerated(
+    const string& name,
+    const string& parameter,
+    const string& insertions,
+    const string& file,
+    const string& first_message_name,
+    const string& first_parsed_file_name,
+    const string& output_directory) {
+  string content;
+  GOOGLE_CHECK_OK(
+      File::GetContents(output_directory + "/" + GetOutputFileName(name, file),
+                        &content, true));
+
+  vector<string> lines = Split(content, "\n", true);
+
+  while (!lines.empty() && lines.back().empty()) {
+    lines.pop_back();
+  }
+  for (int i = 0; i < lines.size(); i++) {
+    lines[i] += "\n";
+  }
+
+  vector<string> insertion_list;
+  if (!insertions.empty()) {
+    SplitStringUsing(insertions, ",", &insertion_list);
+  }
+
+  EXPECT_EQ(lines.size(), 3 + insertion_list.size() * 2);
+  EXPECT_EQ(GetOutputFileContent(name, parameter, file,
+                                 first_parsed_file_name, first_message_name),
+            lines[0]);
+
+  EXPECT_EQ(kFirstInsertionPoint, lines[1 + insertion_list.size()]);
+  EXPECT_EQ(kSecondInsertionPoint, lines[2 + insertion_list.size() * 2]);
+
+  for (int i = 0; i < insertion_list.size(); i++) {
+    EXPECT_EQ(GetOutputFileContent(insertion_list[i], "first_insert",
+                                   file, file, first_message_name),
+              lines[1 + i]);
+    // Second insertion point is indented, so the inserted text should
+    // automatically be indented too.
+    EXPECT_EQ("  " + GetOutputFileContent(insertion_list[i], "second_insert",
+                                          file, file, first_message_name),
+              lines[2 + insertion_list.size() + i]);
+  }
+}
+
+bool MockCodeGenerator::Generate(
+    const FileDescriptor* file,
+    const string& parameter,
+    GeneratorContext* context,
+    string* error) const {
+  for (int i = 0; i < file->message_type_count(); i++) {
+    if (HasPrefixString(file->message_type(i)->name(), "MockCodeGenerator_")) {
+      string command = StripPrefixString(file->message_type(i)->name(),
+                                         "MockCodeGenerator_");
+      if (command == "Error") {
+        *error = "Saw message type MockCodeGenerator_Error.";
+        return false;
+      } else if (command == "Exit") {
+        cerr << "Saw message type MockCodeGenerator_Exit." << endl;
+        exit(123);
+      } else if (command == "Abort") {
+        cerr << "Saw message type MockCodeGenerator_Abort." << endl;
+        abort();
+      } else if (command == "HasSourceCodeInfo") {
+        FileDescriptorProto file_descriptor_proto;
+        file->CopySourceCodeInfoTo(&file_descriptor_proto);
+        bool has_source_code_info =
+            file_descriptor_proto.has_source_code_info() &&
+            file_descriptor_proto.source_code_info().location_size() > 0;
+        cerr << "Saw message type MockCodeGenerator_HasSourceCodeInfo: "
+             << has_source_code_info << "." << endl;
+        abort();
+      } else {
+        GOOGLE_LOG(FATAL) << "Unknown MockCodeGenerator command: " << command;
+      }
+    }
+  }
+
+  if (HasPrefixString(parameter, "insert=")) {
+    vector<string> insert_into;
+    SplitStringUsing(StripPrefixString(parameter, "insert="),
+                     ",", &insert_into);
+
+    for (int i = 0; i < insert_into.size(); i++) {
+      {
+        scoped_ptr<io::ZeroCopyOutputStream> output(context->OpenForInsert(
+            GetOutputFileName(insert_into[i], file), kFirstInsertionPointName));
+        io::Printer printer(output.get(), '$');
+        printer.PrintRaw(GetOutputFileContent(name_, "first_insert",
+                                              file, context));
+        if (printer.failed()) {
+          *error = "MockCodeGenerator detected write error.";
+          return false;
+        }
+      }
+
+      {
+        scoped_ptr<io::ZeroCopyOutputStream> output(
+            context->OpenForInsert(GetOutputFileName(insert_into[i], file),
+                                   kSecondInsertionPointName));
+        io::Printer printer(output.get(), '$');
+        printer.PrintRaw(GetOutputFileContent(name_, "second_insert",
+                                              file, context));
+        if (printer.failed()) {
+          *error = "MockCodeGenerator detected write error.";
+          return false;
+        }
+      }
+    }
+  } else {
+    scoped_ptr<io::ZeroCopyOutputStream> output(
+        context->Open(GetOutputFileName(name_, file)));
+
+    io::Printer printer(output.get(), '$');
+    printer.PrintRaw(GetOutputFileContent(name_, parameter,
+                                          file, context));
+    printer.PrintRaw(kFirstInsertionPoint);
+    printer.PrintRaw(kSecondInsertionPoint);
+
+    if (printer.failed()) {
+      *error = "MockCodeGenerator detected write error.";
+      return false;
+    }
+  }
+
+  return true;
+}
+
+string MockCodeGenerator::GetOutputFileName(const string& generator_name,
+                                            const FileDescriptor* file) {
+  return GetOutputFileName(generator_name, file->name());
+}
+
+string MockCodeGenerator::GetOutputFileName(const string& generator_name,
+                                            const string& file) {
+  return file + ".MockCodeGenerator." + generator_name;
+}
+
+string MockCodeGenerator::GetOutputFileContent(
+    const string& generator_name,
+    const string& parameter,
+    const FileDescriptor* file,
+    GeneratorContext *context) {
+  vector<const FileDescriptor*> all_files;
+  context->ListParsedFiles(&all_files);
+  return GetOutputFileContent(
+      generator_name, parameter, file->name(),
+      CommaSeparatedList(all_files),
+      file->message_type_count() > 0 ?
+          file->message_type(0)->name() : "(none)");
+}
+
+string MockCodeGenerator::GetOutputFileContent(
+    const string& generator_name,
+    const string& parameter,
+    const string& file,
+    const string& parsed_file_list,
+    const string& first_message_name) {
+  return strings::Substitute("$0: $1, $2, $3, $4\n",
+      generator_name, parameter, file,
+      first_message_name, parsed_file_list);
+}
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/mock_code_generator.h b/protobuf/src/google/protobuf/compiler/mock_code_generator.h
new file mode 100644
index 0000000..8c8348d
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/mock_code_generator.h
@@ -0,0 +1,117 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
+
+#include <string>
+#include <google/protobuf/compiler/code_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// A mock CodeGenerator, used by command_line_interface_unittest.  This is in
+// its own file so that it can be used both directly and as a plugin.
+//
+// Generate() produces some output which can be checked by ExpectCalled().  The
+// generator can run in a different process (e.g. a plugin).
+//
+// If the parameter is "insert=NAMES", the MockCodeGenerator will insert lines
+// into the files generated by other MockCodeGenerators instead of creating
+// its own file.  NAMES is a comma-separated list of the names of those other
+// MockCodeGenerators.
+//
+// MockCodeGenerator will also modify its behavior slightly if the input file
+// contains a message type with one of the following names:
+//   MockCodeGenerator_Error:  Causes Generate() to return false and set the
+//     error message to "Saw message type MockCodeGenerator_Error."
+//   MockCodeGenerator_Exit:  Generate() prints "Saw message type
+//     MockCodeGenerator_Exit." to stderr and then calls exit(123).
+//   MockCodeGenerator_Abort:  Generate() prints "Saw message type
+//     MockCodeGenerator_Abort." to stderr and then calls abort().
+//   MockCodeGenerator_HasSourceCodeInfo:  Causes Generate() to abort after
+//     printing "Saw message type MockCodeGenerator_HasSourceCodeInfo: FOO." to
+//     stderr, where FOO is "1" if the supplied FileDescriptorProto has source
+//     code info, and "0" otherwise.
+class MockCodeGenerator : public CodeGenerator {
+ public:
+  MockCodeGenerator(const string& name);
+  virtual ~MockCodeGenerator();
+
+  // Expect (via gTest) that a MockCodeGenerator with the given name was called
+  // with the given parameters by inspecting the output location.
+  //
+  // |insertions| is a comma-separated list of names of MockCodeGenerators which
+  // should have inserted lines into this file.
+  // |parsed_file_list| is a comma-separated list of names of the files
+  // that are being compiled together in this run.
+  static void ExpectGenerated(const string& name,
+                              const string& parameter,
+                              const string& insertions,
+                              const string& file,
+                              const string& first_message_name,
+                              const string& parsed_file_list,
+                              const string& output_directory);
+
+  // Get the name of the file which would be written by the given generator.
+  static string GetOutputFileName(const string& generator_name,
+                                  const FileDescriptor* file);
+  static string GetOutputFileName(const string& generator_name,
+                                  const string& file);
+
+  // implements CodeGenerator ----------------------------------------
+
+  virtual bool Generate(const FileDescriptor* file,
+                        const string& parameter,
+                        GeneratorContext* context,
+                        string* error) const;
+
+ private:
+  string name_;
+
+  static string GetOutputFileContent(const string& generator_name,
+                                     const string& parameter,
+                                     const FileDescriptor* file,
+                                     GeneratorContext *context);
+  static string GetOutputFileContent(const string& generator_name,
+                                     const string& parameter,
+                                     const string& file,
+                                     const string& parsed_file_list,
+                                     const string& first_message_name);
+};
+
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
diff --git a/protobuf/src/google/protobuf/compiler/package_info.h b/protobuf/src/google/protobuf/compiler/package_info.h
new file mode 100644
index 0000000..fb6b473
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/package_info.h
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/protobuf/src/google/protobuf/compiler/parser.cc b/protobuf/src/google/protobuf/compiler/parser.cc
new file mode 100644
index 0000000..474a8f8
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/parser.cc
@@ -0,0 +1,1750 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Recursive descent FTW.
+
+#include <float.h>
+#include <google/protobuf/stubs/hash.h>
+#include <limits>
+
+
+#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),
+    stop_after_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::ConsumeSignedInteger(int* output, const char* error) {
+  bool is_negative = false;
+  uint64 max_value = kint32max;
+  if (TryConsume("-")) {
+    is_negative = true;
+    max_value += 1;
+  }
+  uint64 value = 0;
+  DO(ConsumeInteger64(max_value, &value, error));
+  if (is_negative) value *= -1;
+  *output = value;
+  return true;
+}
+
+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 if (LookingAt("inf")) {
+    *output = numeric_limits<double>::infinity();
+    input_->Next();
+    return true;
+  } else if (LookingAt("nan")) {
+    *output = numeric_limits<double>::quiet_NaN();
+    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();
+    // Allow C++ like concatenation of adjacent string tokens.
+    while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+      io::Tokenizer::ParseStringAppend(input_->current().text, output);
+      input_->Next();
+    }
+    return true;
+  } else {
+    AddError(error);
+    return false;
+  }
+}
+
+bool Parser::TryConsumeEndOfDeclaration(const char* text,
+                                        const LocationRecorder* location) {
+  if (LookingAt(text)) {
+    string leading, trailing;
+    input_->NextWithComments(&trailing, NULL, &leading);
+
+    // Save the leading comments for next time, and recall the leading comments
+    // from last time.
+    leading.swap(upcoming_doc_comments_);
+
+    if (location != NULL) {
+      location->AttachComments(&leading, &trailing);
+    }
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool Parser::ConsumeEndOfDeclaration(const char* text,
+                                     const LocationRecorder* location) {
+  if (TryConsumeEndOfDeclaration(text, location)) {
+    return true;
+  } else {
+    AddError("Expected \"" + string(text) + "\".");
+    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);
+}
+
+// -------------------------------------------------------------------
+
+Parser::LocationRecorder::LocationRecorder(Parser* parser)
+  : parser_(parser),
+    location_(parser_->source_code_info_->add_location()) {
+  location_->add_span(parser_->input_->current().line);
+  location_->add_span(parser_->input_->current().column);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent) {
+  Init(parent);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+                                           int path1) {
+  Init(parent);
+  AddPath(path1);
+}
+
+Parser::LocationRecorder::LocationRecorder(const LocationRecorder& parent,
+                                           int path1, int path2) {
+  Init(parent);
+  AddPath(path1);
+  AddPath(path2);
+}
+
+void Parser::LocationRecorder::Init(const LocationRecorder& parent) {
+  parser_ = parent.parser_;
+  location_ = parser_->source_code_info_->add_location();
+  location_->mutable_path()->CopyFrom(parent.location_->path());
+
+  location_->add_span(parser_->input_->current().line);
+  location_->add_span(parser_->input_->current().column);
+}
+
+Parser::LocationRecorder::~LocationRecorder() {
+  if (location_->span_size() <= 2) {
+    EndAt(parser_->input_->previous());
+  }
+}
+
+void Parser::LocationRecorder::AddPath(int path_component) {
+  location_->add_path(path_component);
+}
+
+void Parser::LocationRecorder::StartAt(const io::Tokenizer::Token& token) {
+  location_->set_span(0, token.line);
+  location_->set_span(1, token.column);
+}
+
+void Parser::LocationRecorder::StartAt(const LocationRecorder& other) {
+  location_->set_span(0, other.location_->span(0));
+  location_->set_span(1, other.location_->span(1));
+}
+
+void Parser::LocationRecorder::EndAt(const io::Tokenizer::Token& token) {
+  if (token.line != location_->span(0)) {
+    location_->add_span(token.line);
+  }
+  location_->add_span(token.end_column);
+}
+
+void Parser::LocationRecorder::RecordLegacyLocation(const Message* descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location) {
+  if (parser_->source_location_table_ != NULL) {
+    parser_->source_location_table_->Add(
+        descriptor, location, location_->span(0), location_->span(1));
+  }
+}
+
+void Parser::LocationRecorder::AttachComments(
+    string* leading, string* trailing) const {
+  GOOGLE_CHECK(!location_->has_leading_comments());
+  GOOGLE_CHECK(!location_->has_trailing_comments());
+
+  if (!leading->empty()) {
+    location_->mutable_leading_comments()->swap(*leading);
+  }
+  if (!trailing->empty()) {
+    location_->mutable_trailing_comments()->swap(*trailing);
+  }
+}
+
+// -------------------------------------------------------------------
+
+void Parser::SkipStatement() {
+  while (true) {
+    if (AtEnd()) {
+      return;
+    } else if (LookingAtType(io::Tokenizer::TYPE_SYMBOL)) {
+      if (TryConsumeEndOfDeclaration(";", NULL)) {
+        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 (TryConsumeEndOfDeclaration("}", NULL)) {
+        return;
+      } else if (TryConsume("{")) {
+        SkipRestOfBlock();
+      }
+    }
+    input_->Next();
+  }
+}
+
+// ===================================================================
+
+bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
+  input_ = input;
+  had_errors_ = false;
+  syntax_identifier_.clear();
+
+  // Note that |file| could be NULL at this point if
+  // stop_after_syntax_identifier_ is true.  So, we conservatively allocate
+  // SourceCodeInfo on the stack, then swap it into the FileDescriptorProto
+  // later on.
+  SourceCodeInfo source_code_info;
+  source_code_info_ = &source_code_info;
+
+  if (LookingAtType(io::Tokenizer::TYPE_START)) {
+    // Advance to first token.
+    input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_);
+  }
+
+  {
+    LocationRecorder root_location(this);
+
+    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 if (!stop_after_syntax_identifier_) {
+      syntax_identifier_ = "proto2";
+    }
+
+    if (stop_after_syntax_identifier_) return !had_errors_;
+
+    // Repeatedly parse statements until we reach the end of the file.
+    while (!AtEnd()) {
+      if (!ParseTopLevelStatement(file, root_location)) {
+        // This statement failed to parse.  Skip it, but keep looping to parse
+        // other statements.
+        SkipStatement();
+
+        if (LookingAt("}")) {
+          AddError("Unmatched \"}\".");
+          input_->NextWithComments(NULL, NULL, &upcoming_doc_comments_);
+        }
+      }
+    }
+  }
+
+  input_ = NULL;
+  source_code_info_ = NULL;
+  source_code_info.Swap(file->mutable_source_code_info());
+  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(ConsumeEndOfDeclaration(";", NULL));
+
+  syntax_identifier_ = syntax;
+
+  if (syntax != "proto2" && !stop_after_syntax_identifier_) {
+    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,
+                                    const LocationRecorder& root_location) {
+  if (TryConsumeEndOfDeclaration(";", NULL)) {
+    // empty statement; ignore
+    return true;
+  } else if (LookingAt("message")) {
+    LocationRecorder location(root_location,
+      FileDescriptorProto::kMessageTypeFieldNumber, file->message_type_size());
+    return ParseMessageDefinition(file->add_message_type(), location, file);
+  } else if (LookingAt("enum")) {
+    LocationRecorder location(root_location,
+      FileDescriptorProto::kEnumTypeFieldNumber, file->enum_type_size());
+    return ParseEnumDefinition(file->add_enum_type(), location, file);
+  } else if (LookingAt("service")) {
+    LocationRecorder location(root_location,
+      FileDescriptorProto::kServiceFieldNumber, file->service_size());
+    return ParseServiceDefinition(file->add_service(), location, file);
+  } else if (LookingAt("extend")) {
+    LocationRecorder location(root_location,
+        FileDescriptorProto::kExtensionFieldNumber);
+    return ParseExtend(file->mutable_extension(),
+                       file->mutable_message_type(),
+                       root_location,
+                       FileDescriptorProto::kMessageTypeFieldNumber,
+                       location, file);
+  } else if (LookingAt("import")) {
+    return ParseImport(file->mutable_dependency(),
+                       file->mutable_public_dependency(),
+                       file->mutable_weak_dependency(),
+                       root_location, file);
+  } else if (LookingAt("package")) {
+    return ParsePackage(file, root_location, file);
+  } else if (LookingAt("option")) {
+    LocationRecorder location(root_location,
+        FileDescriptorProto::kOptionsFieldNumber);
+    return ParseOption(file->mutable_options(), location, file,
+                       OPTION_STATEMENT);
+  } else {
+    AddError("Expected top-level statement (e.g. \"message\").");
+    return false;
+  }
+}
+
+// -------------------------------------------------------------------
+// Messages
+
+bool Parser::ParseMessageDefinition(
+    DescriptorProto* message,
+    const LocationRecorder& message_location,
+    const FileDescriptorProto* containing_file) {
+  DO(Consume("message"));
+  {
+    LocationRecorder location(message_location,
+                              DescriptorProto::kNameFieldNumber);
+    location.RecordLegacyLocation(
+        message, DescriptorPool::ErrorCollector::NAME);
+    DO(ConsumeIdentifier(message->mutable_name(), "Expected message name."));
+  }
+  DO(ParseMessageBlock(message, message_location, containing_file));
+  return true;
+}
+
+namespace {
+
+const int kMaxExtensionRangeSentinel = -1;
+
+bool IsMessageSetWireFormatMessage(const DescriptorProto& message) {
+  const MessageOptions& options = message.options();
+  for (int i = 0; i < options.uninterpreted_option_size(); ++i) {
+    const UninterpretedOption& uninterpreted = options.uninterpreted_option(i);
+    if (uninterpreted.name_size() == 1 &&
+        uninterpreted.name(0).name_part() == "message_set_wire_format" &&
+        uninterpreted.identifier_value() == "true") {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Modifies any extension ranges that specified 'max' as the end of the
+// extension range, and sets them to the type-specific maximum. The actual max
+// tag number can only be determined after all options have been parsed.
+void AdjustExtensionRangesWithMaxEndNumber(DescriptorProto* message) {
+  const bool is_message_set = IsMessageSetWireFormatMessage(*message);
+  const int max_extension_number = is_message_set ?
+      kint32max :
+      FieldDescriptor::kMaxNumber + 1;
+  for (int i = 0; i < message->extension_range_size(); ++i) {
+    if (message->extension_range(i).end() == kMaxExtensionRangeSentinel) {
+      message->mutable_extension_range(i)->set_end(max_extension_number);
+    }
+  }
+}
+
+}  // namespace
+
+bool Parser::ParseMessageBlock(DescriptorProto* message,
+                               const LocationRecorder& message_location,
+                               const FileDescriptorProto* containing_file) {
+  DO(ConsumeEndOfDeclaration("{", &message_location));
+
+  while (!TryConsumeEndOfDeclaration("}", NULL)) {
+    if (AtEnd()) {
+      AddError("Reached end of input in message definition (missing '}').");
+      return false;
+    }
+
+    if (!ParseMessageStatement(message, message_location, containing_file)) {
+      // This statement failed to parse.  Skip it, but keep looping to parse
+      // other statements.
+      SkipStatement();
+    }
+  }
+
+  if (message->extension_range_size() > 0) {
+    AdjustExtensionRangesWithMaxEndNumber(message);
+  }
+  return true;
+}
+
+bool Parser::ParseMessageStatement(DescriptorProto* message,
+                                   const LocationRecorder& message_location,
+                                   const FileDescriptorProto* containing_file) {
+  if (TryConsumeEndOfDeclaration(";", NULL)) {
+    // empty statement; ignore
+    return true;
+  } else if (LookingAt("message")) {
+    LocationRecorder location(message_location,
+                              DescriptorProto::kNestedTypeFieldNumber,
+                              message->nested_type_size());
+    return ParseMessageDefinition(message->add_nested_type(), location,
+                                  containing_file);
+  } else if (LookingAt("enum")) {
+    LocationRecorder location(message_location,
+                              DescriptorProto::kEnumTypeFieldNumber,
+                              message->enum_type_size());
+    return ParseEnumDefinition(message->add_enum_type(), location,
+                               containing_file);
+  } else if (LookingAt("extensions")) {
+    LocationRecorder location(message_location,
+                              DescriptorProto::kExtensionRangeFieldNumber);
+    return ParseExtensions(message, location, containing_file);
+  } else if (LookingAt("extend")) {
+    LocationRecorder location(message_location,
+                              DescriptorProto::kExtensionFieldNumber);
+    return ParseExtend(message->mutable_extension(),
+                       message->mutable_nested_type(),
+                       message_location,
+                       DescriptorProto::kNestedTypeFieldNumber,
+                       location, containing_file);
+  } else if (LookingAt("option")) {
+    LocationRecorder location(message_location,
+                              DescriptorProto::kOptionsFieldNumber);
+    return ParseOption(message->mutable_options(), location,
+                       containing_file, OPTION_STATEMENT);
+  } else if (LookingAt("oneof")) {
+    int oneof_index = message->oneof_decl_size();
+    LocationRecorder oneof_location(message_location,
+                                    DescriptorProto::kOneofDeclFieldNumber,
+                                    oneof_index);
+
+    return ParseOneof(message->add_oneof_decl(), message,
+                      oneof_index, oneof_location, message_location,
+                      containing_file);
+  } else {
+    LocationRecorder location(message_location,
+                              DescriptorProto::kFieldFieldNumber,
+                              message->field_size());
+    return ParseMessageField(message->add_field(),
+                             message->mutable_nested_type(),
+                             message_location,
+                             DescriptorProto::kNestedTypeFieldNumber,
+                             location,
+                             containing_file);
+  }
+}
+
+bool Parser::ParseMessageField(FieldDescriptorProto* field,
+                               RepeatedPtrField<DescriptorProto>* messages,
+                               const LocationRecorder& parent_location,
+                               int location_field_number_for_nested_type,
+                               const LocationRecorder& field_location,
+                               const FileDescriptorProto* containing_file) {
+  {
+    LocationRecorder location(field_location,
+                              FieldDescriptorProto::kLabelFieldNumber);
+    FieldDescriptorProto::Label label;
+    DO(ParseLabel(&label, containing_file));
+    field->set_label(label);
+  }
+
+  return ParseMessageFieldNoLabel(field, messages, parent_location,
+                                  location_field_number_for_nested_type,
+                                  field_location,
+                                  containing_file);
+}
+
+bool Parser::ParseMessageFieldNoLabel(
+    FieldDescriptorProto* field,
+    RepeatedPtrField<DescriptorProto>* messages,
+    const LocationRecorder& parent_location,
+    int location_field_number_for_nested_type,
+    const LocationRecorder& field_location,
+    const FileDescriptorProto* containing_file) {
+  // Parse type.
+  {
+    LocationRecorder location(field_location);  // add path later
+    location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::TYPE);
+
+    FieldDescriptorProto::Type type = FieldDescriptorProto::TYPE_INT32;
+    string type_name;
+    DO(ParseType(&type, &type_name));
+    if (type_name.empty()) {
+      location.AddPath(FieldDescriptorProto::kTypeFieldNumber);
+      field->set_type(type);
+    } else {
+      location.AddPath(FieldDescriptorProto::kTypeNameFieldNumber);
+      field->set_type_name(type_name);
+    }
+  }
+
+  // Parse name and '='.
+  io::Tokenizer::Token name_token = input_->current();
+  {
+    LocationRecorder location(field_location,
+                              FieldDescriptorProto::kNameFieldNumber);
+    location.RecordLegacyLocation(field, DescriptorPool::ErrorCollector::NAME);
+    DO(ConsumeIdentifier(field->mutable_name(), "Expected field name."));
+  }
+  DO(Consume("=", "Missing field number."));
+
+  // Parse field number.
+  {
+    LocationRecorder location(field_location,
+                              FieldDescriptorProto::kNumberFieldNumber);
+    location.RecordLegacyLocation(
+        field, DescriptorPool::ErrorCollector::NUMBER);
+    int number;
+    DO(ConsumeInteger(&number, "Expected field number."));
+    field->set_number(number);
+  }
+
+  // Parse options.
+  DO(ParseFieldOptions(field, field_location, containing_file));
+
+  // Deal with groups.
+  if (field->has_type() && field->type() == FieldDescriptorProto::TYPE_GROUP) {
+    // Awkward:  Since a group declares both a message type and a field, we
+    //   have to create overlapping locations.
+    LocationRecorder group_location(parent_location);
+    group_location.StartAt(field_location);
+    group_location.AddPath(location_field_number_for_nested_type);
+    group_location.AddPath(messages->size());
+
+    DescriptorProto* group = messages->Add();
+    group->set_name(field->name());
+
+    // Record name location to match the field name's location.
+    {
+      LocationRecorder location(group_location,
+                                DescriptorProto::kNameFieldNumber);
+      location.StartAt(name_token);
+      location.EndAt(name_token);
+      location.RecordLegacyLocation(
+          group, DescriptorPool::ErrorCollector::NAME);
+    }
+
+    // The field's type_name also comes from the name.  Confusing!
+    {
+      LocationRecorder location(field_location,
+                                FieldDescriptorProto::kTypeNameFieldNumber);
+      location.StartAt(name_token);
+      location.EndAt(name_token);
+    }
+
+    // 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, group_location, containing_file));
+    } else {
+      AddError("Missing group body.");
+      return false;
+    }
+  } else {
+    DO(ConsumeEndOfDeclaration(";", &field_location));
+  }
+
+  return true;
+}
+
+bool Parser::ParseFieldOptions(FieldDescriptorProto* field,
+                               const LocationRecorder& field_location,
+                               const FileDescriptorProto* containing_file) {
+  if (!LookingAt("[")) return true;
+
+  LocationRecorder location(field_location,
+                            FieldDescriptorProto::kOptionsFieldNumber);
+
+  DO(Consume("["));
+
+  // Parse field options.
+  do {
+    if (LookingAt("default")) {
+      // We intentionally pass field_location rather than location here, since
+      // the default value is not actually an option.
+      DO(ParseDefaultAssignment(field, field_location, containing_file));
+    } else {
+      DO(ParseOption(field->mutable_options(), location,
+                     containing_file, OPTION_ASSIGNMENT));
+    }
+  } while (TryConsume(","));
+
+  DO(Consume("]"));
+  return true;
+}
+
+bool Parser::ParseDefaultAssignment(
+    FieldDescriptorProto* field,
+    const LocationRecorder& field_location,
+    const FileDescriptorProto* containing_file) {
+  if (field->has_default_value()) {
+    AddError("Already set option \"default\".");
+    field->clear_default_value();
+  }
+
+  DO(Consume("default"));
+  DO(Consume("="));
+
+  LocationRecorder location(field_location,
+                            FieldDescriptorProto::kDefaultValueFieldNumber);
+  location.RecordLegacyLocation(
+      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. (If it were a primitive type, |field| would have a type set
+    // already.) In this case, simply take the current string as the default
+    // value; we will catch the error later if it is not a valid enum value.
+    // (N.B. that we do not check whether the current token is an identifier:
+    // doing so throws strange errors when the user mistypes a primitive
+    // typename and we assume it's an enum. E.g.: "optional int foo = 1 [default
+    // = 42]". In such a case the fundamental error is really that "int" is not
+    // a type, not that "42" is not an identifier. See b/12533582.)
+    *default_value = input_->current().text;
+    input_->Next();
+    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 for field default value."));
+      // 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 for field default value."));
+      // 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:
+      // Note: When file opton java_string_check_utf8 is true, if a
+      // non-string representation (eg byte[]) is later supported, it must
+      // be checked for UTF-8-ness.
+      DO(ConsumeString(default_value, "Expected string for field default "
+                       "value."));
+      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 enum identifier for field "
+                                          "default value."));
+      break;
+
+    case FieldDescriptorProto::TYPE_MESSAGE:
+    case FieldDescriptorProto::TYPE_GROUP:
+      AddError("Messages can't have default values.");
+      return false;
+  }
+
+  return true;
+}
+
+bool Parser::ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
+                                 const LocationRecorder& part_location,
+                                 const FileDescriptorProto* containing_file) {
+  UninterpretedOption::NamePart* name = uninterpreted_option->add_name();
+  string identifier;  // We parse identifiers into this string.
+  if (LookingAt("(")) {  // This is an extension.
+    DO(Consume("("));
+
+    {
+      LocationRecorder location(
+          part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
+      // An extension name consists of dot-separated identifiers, and may begin
+      // with a dot.
+      if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+        DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+        name->mutable_name_part()->append(identifier);
+      }
+      while (LookingAt(".")) {
+        DO(Consume("."));
+        name->mutable_name_part()->append(".");
+        DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+        name->mutable_name_part()->append(identifier);
+      }
+    }
+
+    DO(Consume(")"));
+    name->set_is_extension(true);
+  } else {  // This is a regular field.
+    LocationRecorder location(
+        part_location, UninterpretedOption::NamePart::kNamePartFieldNumber);
+    DO(ConsumeIdentifier(&identifier, "Expected identifier."));
+    name->mutable_name_part()->append(identifier);
+    name->set_is_extension(false);
+  }
+  return true;
+}
+
+bool Parser::ParseUninterpretedBlock(string* value) {
+  // Note that enclosing braces are not added to *value.
+  // We do NOT use ConsumeEndOfStatement for this brace because it's delimiting
+  // an expression, not a block of statements.
+  DO(Consume("{"));
+  int brace_depth = 1;
+  while (!AtEnd()) {
+    if (LookingAt("{")) {
+      brace_depth++;
+    } else if (LookingAt("}")) {
+      brace_depth--;
+      if (brace_depth == 0) {
+        input_->Next();
+        return true;
+      }
+    }
+    // TODO(sanjay): Interpret line/column numbers to preserve formatting
+    if (!value->empty()) value->push_back(' ');
+    value->append(input_->current().text);
+    input_->Next();
+  }
+  AddError("Unexpected end of stream while parsing aggregate value.");
+  return false;
+}
+
+// We don't interpret the option here. Instead we store it in an
+// UninterpretedOption, to be interpreted later.
+bool Parser::ParseOption(Message* options,
+                         const LocationRecorder& options_location,
+                         const FileDescriptorProto* containing_file,
+                         OptionStyle style) {
+  // Create an entry in the uninterpreted_option field.
+  const FieldDescriptor* uninterpreted_option_field = options->GetDescriptor()->
+      FindFieldByName("uninterpreted_option");
+  GOOGLE_CHECK(uninterpreted_option_field != NULL)
+      << "No field named \"uninterpreted_option\" in the Options proto.";
+
+  const Reflection* reflection = options->GetReflection();
+
+  LocationRecorder location(
+      options_location, uninterpreted_option_field->number(),
+      reflection->FieldSize(*options, uninterpreted_option_field));
+
+  if (style == OPTION_STATEMENT) {
+    DO(Consume("option"));
+  }
+
+  UninterpretedOption* uninterpreted_option = down_cast<UninterpretedOption*>(
+      options->GetReflection()->AddMessage(options,
+                                           uninterpreted_option_field));
+
+  // Parse dot-separated name.
+  {
+    LocationRecorder name_location(location,
+                                   UninterpretedOption::kNameFieldNumber);
+    name_location.RecordLegacyLocation(
+        uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_NAME);
+
+    {
+      LocationRecorder part_location(name_location,
+                                     uninterpreted_option->name_size());
+      DO(ParseOptionNamePart(uninterpreted_option, part_location,
+                             containing_file));
+    }
+
+    while (LookingAt(".")) {
+      DO(Consume("."));
+      LocationRecorder part_location(name_location,
+                                     uninterpreted_option->name_size());
+      DO(ParseOptionNamePart(uninterpreted_option, part_location,
+                             containing_file));
+    }
+  }
+
+  DO(Consume("="));
+
+  {
+    LocationRecorder value_location(location);
+    value_location.RecordLegacyLocation(
+        uninterpreted_option, DescriptorPool::ErrorCollector::OPTION_VALUE);
+
+    // All values are a single token, except for negative numbers, which consist
+    // of a single '-' symbol, followed by a positive number.
+    bool is_negative = TryConsume("-");
+
+    switch (input_->current().type) {
+      case io::Tokenizer::TYPE_START:
+        GOOGLE_LOG(FATAL) << "Trying to read value before any tokens have been read.";
+        return false;
+
+      case io::Tokenizer::TYPE_END:
+        AddError("Unexpected end of stream while parsing option value.");
+        return false;
+
+      case io::Tokenizer::TYPE_IDENTIFIER: {
+        value_location.AddPath(
+            UninterpretedOption::kIdentifierValueFieldNumber);
+        if (is_negative) {
+          AddError("Invalid '-' symbol before identifier.");
+          return false;
+        }
+        string value;
+        DO(ConsumeIdentifier(&value, "Expected identifier."));
+        uninterpreted_option->set_identifier_value(value);
+        break;
+      }
+
+      case io::Tokenizer::TYPE_INTEGER: {
+        uint64 value;
+        uint64 max_value =
+            is_negative ? static_cast<uint64>(kint64max) + 1 : kuint64max;
+        DO(ConsumeInteger64(max_value, &value, "Expected integer."));
+        if (is_negative) {
+          value_location.AddPath(
+              UninterpretedOption::kNegativeIntValueFieldNumber);
+          uninterpreted_option->set_negative_int_value(
+              -static_cast<int64>(value));
+        } else {
+          value_location.AddPath(
+              UninterpretedOption::kPositiveIntValueFieldNumber);
+          uninterpreted_option->set_positive_int_value(value);
+        }
+        break;
+      }
+
+      case io::Tokenizer::TYPE_FLOAT: {
+        value_location.AddPath(UninterpretedOption::kDoubleValueFieldNumber);
+        double value;
+        DO(ConsumeNumber(&value, "Expected number."));
+        uninterpreted_option->set_double_value(is_negative ? -value : value);
+        break;
+      }
+
+      case io::Tokenizer::TYPE_STRING: {
+        value_location.AddPath(UninterpretedOption::kStringValueFieldNumber);
+        if (is_negative) {
+          AddError("Invalid '-' symbol before string.");
+          return false;
+        }
+        string value;
+        DO(ConsumeString(&value, "Expected string."));
+        uninterpreted_option->set_string_value(value);
+        break;
+      }
+
+      case io::Tokenizer::TYPE_SYMBOL:
+        if (LookingAt("{")) {
+          value_location.AddPath(
+              UninterpretedOption::kAggregateValueFieldNumber);
+          DO(ParseUninterpretedBlock(
+              uninterpreted_option->mutable_aggregate_value()));
+        } else {
+          AddError("Expected option value.");
+          return false;
+        }
+        break;
+    }
+  }
+
+  if (style == OPTION_STATEMENT) {
+    DO(ConsumeEndOfDeclaration(";", &location));
+  }
+
+
+  return true;
+}
+
+bool Parser::ParseExtensions(DescriptorProto* message,
+                             const LocationRecorder& extensions_location,
+                             const FileDescriptorProto* containing_file) {
+  // Parse the declaration.
+  DO(Consume("extensions"));
+
+  do {
+    // Note that kExtensionRangeFieldNumber was already pushed by the parent.
+    LocationRecorder location(extensions_location,
+                              message->extension_range_size());
+
+    DescriptorProto::ExtensionRange* range = message->add_extension_range();
+    location.RecordLegacyLocation(
+        range, DescriptorPool::ErrorCollector::NUMBER);
+
+    int start, end;
+    io::Tokenizer::Token start_token;
+
+    {
+      LocationRecorder start_location(
+          location, DescriptorProto::ExtensionRange::kStartFieldNumber);
+      start_token = input_->current();
+      DO(ConsumeInteger(&start, "Expected field number range."));
+    }
+
+    if (TryConsume("to")) {
+      LocationRecorder end_location(
+          location, DescriptorProto::ExtensionRange::kEndFieldNumber);
+      if (TryConsume("max")) {
+        // Set to the sentinel value - 1 since we increment the value below.
+        // The actual value of the end of the range should be set with
+        // AdjustExtensionRangesWithMaxEndNumber.
+        end = kMaxExtensionRangeSentinel - 1;
+      } else {
+        DO(ConsumeInteger(&end, "Expected integer."));
+      }
+    } else {
+      LocationRecorder end_location(
+          location, DescriptorProto::ExtensionRange::kEndFieldNumber);
+      end_location.StartAt(start_token);
+      end_location.EndAt(start_token);
+      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(ConsumeEndOfDeclaration(";", &extensions_location));
+  return true;
+}
+
+bool Parser::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
+                         RepeatedPtrField<DescriptorProto>* messages,
+                         const LocationRecorder& parent_location,
+                         int location_field_number_for_nested_type,
+                         const LocationRecorder& extend_location,
+                         const FileDescriptorProto* containing_file) {
+  DO(Consume("extend"));
+
+  // Parse the extendee type.
+  io::Tokenizer::Token extendee_start = input_->current();
+  string extendee;
+  DO(ParseUserDefinedType(&extendee));
+  io::Tokenizer::Token extendee_end = input_->previous();
+
+  // Parse the block.
+  DO(ConsumeEndOfDeclaration("{", &extend_location));
+
+  bool is_first = true;
+
+  do {
+    if (AtEnd()) {
+      AddError("Reached end of input in extend definition (missing '}').");
+      return false;
+    }
+
+    // Note that kExtensionFieldNumber was already pushed by the parent.
+    LocationRecorder location(extend_location, extensions->size());
+
+    FieldDescriptorProto* field = extensions->Add();
+
+    {
+      LocationRecorder extendee_location(
+          location, FieldDescriptorProto::kExtendeeFieldNumber);
+      extendee_location.StartAt(extendee_start);
+      extendee_location.EndAt(extendee_end);
+
+      if (is_first) {
+        extendee_location.RecordLegacyLocation(
+            field, DescriptorPool::ErrorCollector::EXTENDEE);
+        is_first = false;
+      }
+    }
+
+    field->set_extendee(extendee);
+
+    if (!ParseMessageField(field, messages, parent_location,
+                           location_field_number_for_nested_type,
+                           location,
+                           containing_file)) {
+      // This statement failed to parse.  Skip it, but keep looping to parse
+      // other statements.
+      SkipStatement();
+    }
+  } while (!TryConsumeEndOfDeclaration("}", NULL));
+
+  return true;
+}
+
+bool Parser::ParseOneof(OneofDescriptorProto* oneof_decl,
+                        DescriptorProto* containing_type,
+                        int oneof_index,
+                        const LocationRecorder& oneof_location,
+                        const LocationRecorder& containing_type_location,
+                        const FileDescriptorProto* containing_file) {
+  DO(Consume("oneof"));
+
+  {
+    LocationRecorder name_location(oneof_location,
+                                   OneofDescriptorProto::kNameFieldNumber);
+    DO(ConsumeIdentifier(oneof_decl->mutable_name(), "Expected oneof name."));
+  }
+
+  DO(ConsumeEndOfDeclaration("{", &oneof_location));
+
+  do {
+    if (AtEnd()) {
+      AddError("Reached end of input in oneof definition (missing '}').");
+      return false;
+    }
+
+    // Print a nice error if the user accidentally tries to place a label
+    // on an individual member of a oneof.
+    if (LookingAt("required") ||
+        LookingAt("optional") ||
+        LookingAt("repeated")) {
+      AddError("Fields in oneofs must not have labels (required / optional "
+               "/ repeated).");
+      // We can continue parsing here because we understand what the user
+      // meant.  The error report will still make parsing fail overall.
+      input_->Next();
+    }
+
+    LocationRecorder field_location(containing_type_location,
+                                    DescriptorProto::kFieldFieldNumber,
+                                    containing_type->field_size());
+
+    FieldDescriptorProto* field = containing_type->add_field();
+    field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+    field->set_oneof_index(oneof_index);
+
+    if (!ParseMessageFieldNoLabel(field,
+                                  containing_type->mutable_nested_type(),
+                                  containing_type_location,
+                                  DescriptorProto::kNestedTypeFieldNumber,
+                                  field_location,
+                                  containing_file)) {
+      // This statement failed to parse.  Skip it, but keep looping to parse
+      // other statements.
+      SkipStatement();
+    }
+  } while (!TryConsumeEndOfDeclaration("}", NULL));
+
+  return true;
+}
+
+// -------------------------------------------------------------------
+// Enums
+
+bool Parser::ParseEnumDefinition(EnumDescriptorProto* enum_type,
+                                 const LocationRecorder& enum_location,
+                                 const FileDescriptorProto* containing_file) {
+  DO(Consume("enum"));
+
+  {
+    LocationRecorder location(enum_location,
+                              EnumDescriptorProto::kNameFieldNumber);
+    location.RecordLegacyLocation(
+        enum_type, DescriptorPool::ErrorCollector::NAME);
+    DO(ConsumeIdentifier(enum_type->mutable_name(), "Expected enum name."));
+  }
+
+  DO(ParseEnumBlock(enum_type, enum_location, containing_file));
+  return true;
+}
+
+bool Parser::ParseEnumBlock(EnumDescriptorProto* enum_type,
+                            const LocationRecorder& enum_location,
+                            const FileDescriptorProto* containing_file) {
+  DO(ConsumeEndOfDeclaration("{", &enum_location));
+
+  while (!TryConsumeEndOfDeclaration("}", NULL)) {
+    if (AtEnd()) {
+      AddError("Reached end of input in enum definition (missing '}').");
+      return false;
+    }
+
+    if (!ParseEnumStatement(enum_type, enum_location, containing_file)) {
+      // This statement failed to parse.  Skip it, but keep looping to parse
+      // other statements.
+      SkipStatement();
+    }
+  }
+
+  return true;
+}
+
+bool Parser::ParseEnumStatement(EnumDescriptorProto* enum_type,
+                                const LocationRecorder& enum_location,
+                                const FileDescriptorProto* containing_file) {
+  if (TryConsumeEndOfDeclaration(";", NULL)) {
+    // empty statement; ignore
+    return true;
+  } else if (LookingAt("option")) {
+    LocationRecorder location(enum_location,
+                              EnumDescriptorProto::kOptionsFieldNumber);
+    return ParseOption(enum_type->mutable_options(), location,
+                       containing_file, OPTION_STATEMENT);
+  } else {
+    LocationRecorder location(enum_location,
+        EnumDescriptorProto::kValueFieldNumber, enum_type->value_size());
+    return ParseEnumConstant(enum_type->add_value(), location, containing_file);
+  }
+}
+
+bool Parser::ParseEnumConstant(EnumValueDescriptorProto* enum_value,
+                               const LocationRecorder& enum_value_location,
+                               const FileDescriptorProto* containing_file) {
+  // Parse name.
+  {
+    LocationRecorder location(enum_value_location,
+                              EnumValueDescriptorProto::kNameFieldNumber);
+    location.RecordLegacyLocation(
+        enum_value, DescriptorPool::ErrorCollector::NAME);
+    DO(ConsumeIdentifier(enum_value->mutable_name(),
+                         "Expected enum constant name."));
+  }
+
+  DO(Consume("=", "Missing numeric value for enum constant."));
+
+  // Parse value.
+  {
+    LocationRecorder location(
+        enum_value_location, EnumValueDescriptorProto::kNumberFieldNumber);
+    location.RecordLegacyLocation(
+        enum_value, DescriptorPool::ErrorCollector::NUMBER);
+
+    int number;
+    DO(ConsumeSignedInteger(&number, "Expected integer."));
+    enum_value->set_number(number);
+  }
+
+  DO(ParseEnumConstantOptions(enum_value, enum_value_location,
+                              containing_file));
+
+  DO(ConsumeEndOfDeclaration(";", &enum_value_location));
+
+  return true;
+}
+
+bool Parser::ParseEnumConstantOptions(
+    EnumValueDescriptorProto* value,
+    const LocationRecorder& enum_value_location,
+    const FileDescriptorProto* containing_file) {
+  if (!LookingAt("[")) return true;
+
+  LocationRecorder location(
+      enum_value_location, EnumValueDescriptorProto::kOptionsFieldNumber);
+
+  DO(Consume("["));
+
+  do {
+    DO(ParseOption(value->mutable_options(), location,
+                   containing_file, OPTION_ASSIGNMENT));
+  } while (TryConsume(","));
+
+  DO(Consume("]"));
+  return true;
+}
+
+// -------------------------------------------------------------------
+// Services
+
+bool Parser::ParseServiceDefinition(
+    ServiceDescriptorProto* service,
+    const LocationRecorder& service_location,
+    const FileDescriptorProto* containing_file) {
+  DO(Consume("service"));
+
+  {
+    LocationRecorder location(service_location,
+                              ServiceDescriptorProto::kNameFieldNumber);
+    location.RecordLegacyLocation(
+        service, DescriptorPool::ErrorCollector::NAME);
+    DO(ConsumeIdentifier(service->mutable_name(), "Expected service name."));
+  }
+
+  DO(ParseServiceBlock(service, service_location, containing_file));
+  return true;
+}
+
+bool Parser::ParseServiceBlock(ServiceDescriptorProto* service,
+                               const LocationRecorder& service_location,
+                               const FileDescriptorProto* containing_file) {
+  DO(ConsumeEndOfDeclaration("{", &service_location));
+
+  while (!TryConsumeEndOfDeclaration("}", NULL)) {
+    if (AtEnd()) {
+      AddError("Reached end of input in service definition (missing '}').");
+      return false;
+    }
+
+    if (!ParseServiceStatement(service, service_location, containing_file)) {
+      // This statement failed to parse.  Skip it, but keep looping to parse
+      // other statements.
+      SkipStatement();
+    }
+  }
+
+  return true;
+}
+
+bool Parser::ParseServiceStatement(ServiceDescriptorProto* service,
+                                   const LocationRecorder& service_location,
+                                   const FileDescriptorProto* containing_file) {
+  if (TryConsumeEndOfDeclaration(";", NULL)) {
+    // empty statement; ignore
+    return true;
+  } else if (LookingAt("option")) {
+    LocationRecorder location(
+        service_location, ServiceDescriptorProto::kOptionsFieldNumber);
+    return ParseOption(service->mutable_options(), location,
+                       containing_file, OPTION_STATEMENT);
+  } else {
+    LocationRecorder location(service_location,
+        ServiceDescriptorProto::kMethodFieldNumber, service->method_size());
+    return ParseServiceMethod(service->add_method(), location, containing_file);
+  }
+}
+
+bool Parser::ParseServiceMethod(MethodDescriptorProto* method,
+                                const LocationRecorder& method_location,
+                                const FileDescriptorProto* containing_file) {
+  DO(Consume("rpc"));
+
+  {
+    LocationRecorder location(method_location,
+                              MethodDescriptorProto::kNameFieldNumber);
+    location.RecordLegacyLocation(
+        method, DescriptorPool::ErrorCollector::NAME);
+    DO(ConsumeIdentifier(method->mutable_name(), "Expected method name."));
+  }
+
+  // Parse input type.
+  DO(Consume("("));
+  {
+    LocationRecorder location(method_location,
+                              MethodDescriptorProto::kInputTypeFieldNumber);
+    location.RecordLegacyLocation(
+        method, DescriptorPool::ErrorCollector::INPUT_TYPE);
+    DO(ParseUserDefinedType(method->mutable_input_type()));
+  }
+  DO(Consume(")"));
+
+  // Parse output type.
+  DO(Consume("returns"));
+  DO(Consume("("));
+  {
+    LocationRecorder location(method_location,
+                              MethodDescriptorProto::kOutputTypeFieldNumber);
+    location.RecordLegacyLocation(
+        method, DescriptorPool::ErrorCollector::OUTPUT_TYPE);
+    DO(ParseUserDefinedType(method->mutable_output_type()));
+  }
+  DO(Consume(")"));
+
+  if (LookingAt("{")) {
+    // Options!
+    DO(ParseOptions(method_location,
+                    containing_file,
+                    MethodDescriptorProto::kOptionsFieldNumber,
+                    method->mutable_options()));
+  } else {
+    DO(ConsumeEndOfDeclaration(";", &method_location));
+  }
+
+  return true;
+}
+
+
+bool Parser::ParseOptions(const LocationRecorder& parent_location,
+                          const FileDescriptorProto* containing_file,
+                          const int optionsFieldNumber,
+                          Message* mutable_options) {
+  // Options!
+  ConsumeEndOfDeclaration("{", &parent_location);
+  while (!TryConsumeEndOfDeclaration("}", NULL)) {
+    if (AtEnd()) {
+      AddError("Reached end of input in method options (missing '}').");
+      return false;
+    }
+
+    if (TryConsumeEndOfDeclaration(";", NULL)) {
+      // empty statement; ignore
+    } else {
+      LocationRecorder location(parent_location,
+                                optionsFieldNumber);
+      if (!ParseOption(mutable_options, location, containing_file,
+                       OPTION_STATEMENT)) {
+        // This statement failed to parse.  Skip it, but keep looping to
+        // parse other statements.
+        SkipStatement();
+      }
+    }
+  }
+
+  return true;
+}
+
+// -------------------------------------------------------------------
+
+bool Parser::ParseLabel(FieldDescriptorProto::Label* label,
+                        const FileDescriptorProto* containing_file) {
+  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,
+                          const LocationRecorder& root_location,
+                          const FileDescriptorProto* containing_file) {
+  if (file->has_package()) {
+    AddError("Multiple package definitions.");
+    // Don't append the new package to the old one.  Just replace it.  Not
+    // that it really matters since this is an error anyway.
+    file->clear_package();
+  }
+
+  DO(Consume("package"));
+
+  {
+    LocationRecorder location(root_location,
+                              FileDescriptorProto::kPackageFieldNumber);
+    location.RecordLegacyLocation(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(".");
+    }
+
+    location.EndAt(input_->previous());
+
+    DO(ConsumeEndOfDeclaration(";", &location));
+  }
+
+  return true;
+}
+
+bool Parser::ParseImport(RepeatedPtrField<string>* dependency,
+                         RepeatedField<int32>* public_dependency,
+                         RepeatedField<int32>* weak_dependency,
+                         const LocationRecorder& root_location,
+                         const FileDescriptorProto* containing_file) {
+  DO(Consume("import"));
+  if (LookingAt("public")) {
+    LocationRecorder location(
+        root_location, FileDescriptorProto::kPublicDependencyFieldNumber,
+        public_dependency->size());
+    DO(Consume("public"));
+    *public_dependency->Add() = dependency->size();
+  } else if (LookingAt("weak")) {
+    LocationRecorder location(
+        root_location, FileDescriptorProto::kWeakDependencyFieldNumber,
+        weak_dependency->size());
+    DO(Consume("weak"));
+    *weak_dependency->Add() = dependency->size();
+  }
+  {
+    LocationRecorder location(root_location,
+                              FileDescriptorProto::kDependencyFieldNumber,
+                              dependency->size());
+    DO(ConsumeString(dependency->Add(),
+      "Expected a string naming the file to import."));
+
+    location.EndAt(input_->previous());
+
+    DO(ConsumeEndOfDeclaration(";", &location));
+  }
+  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/protobuf/src/google/protobuf/compiler/parser.h b/protobuf/src/google/protobuf/compiler/parser.h
new file mode 100644
index 0000000..d0a2359
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/parser.h
@@ -0,0 +1,522 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/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:
+
+  // DEPRECATED:  New code should use the SourceCodeInfo embedded in the
+  //   FileDescriptorProto.
+  //
+  // 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;
+  }
+
+  // Requests 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& GetSyntaxIdentifier() { 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;
+  }
+
+  // Call SetStopAfterSyntaxIdentifier(true) to tell the parser to stop
+  // parsing as soon as it has seen the syntax identifier, or lack thereof.
+  // This is useful for quickly identifying the syntax of the file without
+  // parsing the whole thing.  If this is enabled, no error will be recorded
+  // if the syntax identifier is something other than "proto2" (since
+  // presumably the caller intends to deal with that), but other kinds of
+  // errors (e.g. parse errors) will still be reported.  When this is enabled,
+  // you may pass a NULL FileDescriptorProto to Parse().
+  void SetStopAfterSyntaxIdentifier(bool value) {
+    stop_after_syntax_identifier_ = value;
+  }
+
+ private:
+  class LocationRecorder;
+
+  // =================================================================
+  // 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 signed integer and store its value in "output".
+  bool ConsumeSignedInteger(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);
+
+  // Consume a token representing the end of the statement.  Comments between
+  // this token and the next will be harvested for documentation.  The given
+  // LocationRecorder should refer to the declaration that was just parsed;
+  // it will be populated with these comments.
+  //
+  // TODO(kenton):  The LocationRecorder is const because historically locations
+  //   have been passed around by const reference, for no particularly good
+  //   reason.  We should probably go through and change them all to mutable
+  //   pointer to make this more intuitive.
+  bool TryConsumeEndOfDeclaration(const char* text,
+                                  const LocationRecorder* location);
+  bool ConsumeEndOfDeclaration(const char* text,
+                               const LocationRecorder* location);
+
+  // -----------------------------------------------------------------
+  // 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);
+
+  // Records a location in the SourceCodeInfo.location table (see
+  // descriptor.proto).  We use RAII to ensure that the start and end locations
+  // are recorded -- the constructor records the start location and the
+  // destructor records the end location.  Since the parser is
+  // recursive-descent, this works out beautifully.
+  class LIBPROTOBUF_EXPORT LocationRecorder {
+   public:
+    // Construct the file's "root" location.
+    LocationRecorder(Parser* parser);
+
+    // Construct a location that represents a declaration nested within the
+    // given parent.  E.g. a field's location is nested within the location
+    // for a message type.  The parent's path will be copied, so you should
+    // call AddPath() only to add the path components leading from the parent
+    // to the child (as opposed to leading from the root to the child).
+    LocationRecorder(const LocationRecorder& parent);
+
+    // Convenience constructors that call AddPath() one or two times.
+    LocationRecorder(const LocationRecorder& parent, int path1);
+    LocationRecorder(const LocationRecorder& parent, int path1, int path2);
+
+    ~LocationRecorder();
+
+    // Add a path component.  See SourceCodeInfo.Location.path in
+    // descriptor.proto.
+    void AddPath(int path_component);
+
+    // By default the location is considered to start at the current token at
+    // the time the LocationRecorder is created.  StartAt() sets the start
+    // location to the given token instead.
+    void StartAt(const io::Tokenizer::Token& token);
+
+    // Start at the same location as some other LocationRecorder.
+    void StartAt(const LocationRecorder& other);
+
+    // By default the location is considered to end at the previous token at
+    // the time the LocationRecorder is destroyed.  EndAt() sets the end
+    // location to the given token instead.
+    void EndAt(const io::Tokenizer::Token& token);
+
+    // Records the start point of this location to the SourceLocationTable that
+    // was passed to RecordSourceLocationsTo(), if any.  SourceLocationTable
+    // is an older way of keeping track of source locations which is still
+    // used in some places.
+    void RecordLegacyLocation(const Message* descriptor,
+        DescriptorPool::ErrorCollector::ErrorLocation location);
+
+    // Attaches leading and trailing comments to the location.  The two strings
+    // will be swapped into place, so after this is called *leading and
+    // *trailing will be empty.
+    //
+    // TODO(kenton):  See comment on TryConsumeEndOfDeclaration(), above, for
+    //   why this is const.
+    void AttachComments(string* leading, string* trailing) const;
+
+   private:
+    Parser* parser_;
+    SourceCodeInfo::Location* location_;
+
+    void Init(const LocationRecorder& parent);
+  };
+
+  // =================================================================
+  // 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,
+                              const LocationRecorder& root_location);
+
+  // Parse various language high-level language construrcts.
+  bool ParseMessageDefinition(DescriptorProto* message,
+                              const LocationRecorder& message_location,
+                              const FileDescriptorProto* containing_file);
+  bool ParseEnumDefinition(EnumDescriptorProto* enum_type,
+                           const LocationRecorder& enum_location,
+                           const FileDescriptorProto* containing_file);
+  bool ParseServiceDefinition(ServiceDescriptorProto* service,
+                              const LocationRecorder& service_location,
+                              const FileDescriptorProto* containing_file);
+  bool ParsePackage(FileDescriptorProto* file,
+                    const LocationRecorder& root_location,
+                    const FileDescriptorProto* containing_file);
+  bool ParseImport(RepeatedPtrField<string>* dependency,
+                   RepeatedField<int32>* public_dependency,
+                   RepeatedField<int32>* weak_dependency,
+                   const LocationRecorder& root_location,
+                   const FileDescriptorProto* containing_file);
+  bool ParseOption(Message* options,
+                   const LocationRecorder& options_location,
+                   const FileDescriptorProto* containing_file);
+
+  // 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,
+                         const LocationRecorder& message_location,
+                         const FileDescriptorProto* containing_file);
+  bool ParseEnumBlock(EnumDescriptorProto* enum_type,
+                      const LocationRecorder& enum_location,
+                      const FileDescriptorProto* containing_file);
+  bool ParseServiceBlock(ServiceDescriptorProto* service,
+                         const LocationRecorder& service_location,
+                         const FileDescriptorProto* containing_file);
+
+  // Parse one statement within a message, enum, or service block, inclunding
+  // final semicolon.
+  bool ParseMessageStatement(DescriptorProto* message,
+                             const LocationRecorder& message_location,
+                             const FileDescriptorProto* containing_file);
+  bool ParseEnumStatement(EnumDescriptorProto* message,
+                          const LocationRecorder& enum_location,
+                          const FileDescriptorProto* containing_file);
+  bool ParseServiceStatement(ServiceDescriptorProto* message,
+                             const LocationRecorder& service_location,
+                             const FileDescriptorProto* containing_file);
+
+  // Parse a field of a message.  If the field is a group, its type will be
+  // added to "messages".
+  //
+  // parent_location and location_field_number_for_nested_type are needed when
+  // parsing groups -- we need to generate a nested message type within the
+  // parent and record its location accordingly.  Since the parent could be
+  // either a FileDescriptorProto or a DescriptorProto, we must pass in the
+  // correct field number to use.
+  bool ParseMessageField(FieldDescriptorProto* field,
+                         RepeatedPtrField<DescriptorProto>* messages,
+                         const LocationRecorder& parent_location,
+                         int location_field_number_for_nested_type,
+                         const LocationRecorder& field_location,
+                         const FileDescriptorProto* containing_file);
+
+  // Like ParseMessageField() but expects the label has already been filled in
+  // by the caller.
+  bool ParseMessageFieldNoLabel(FieldDescriptorProto* field,
+                                RepeatedPtrField<DescriptorProto>* messages,
+                                const LocationRecorder& parent_location,
+                                int location_field_number_for_nested_type,
+                                const LocationRecorder& field_location,
+                                const FileDescriptorProto* containing_file);
+
+  // Parse an "extensions" declaration.
+  bool ParseExtensions(DescriptorProto* message,
+                       const LocationRecorder& extensions_location,
+                       const FileDescriptorProto* containing_file);
+
+  // Parse an "extend" declaration.  (See also comments for
+  // ParseMessageField().)
+  bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions,
+                   RepeatedPtrField<DescriptorProto>* messages,
+                   const LocationRecorder& parent_location,
+                   int location_field_number_for_nested_type,
+                   const LocationRecorder& extend_location,
+                   const FileDescriptorProto* containing_file);
+
+  // Parse a "oneof" declaration.  The caller is responsible for setting
+  // oneof_decl->label() since it will have had to parse the label before it
+  // knew it was parsing a oneof.
+  bool ParseOneof(OneofDescriptorProto* oneof_decl,
+                  DescriptorProto* containing_type,
+                  int oneof_index,
+                  const LocationRecorder& oneof_location,
+                  const LocationRecorder& containing_type_location,
+                  const FileDescriptorProto* containing_file);
+
+  // Parse a single enum value within an enum block.
+  bool ParseEnumConstant(EnumValueDescriptorProto* enum_value,
+                         const LocationRecorder& enum_value_location,
+                         const FileDescriptorProto* containing_file);
+
+  // Parse enum constant options, i.e. the list in square brackets at the end
+  // of the enum constant value definition.
+  bool ParseEnumConstantOptions(EnumValueDescriptorProto* value,
+                                const LocationRecorder& enum_value_location,
+                                const FileDescriptorProto* containing_file);
+
+  // Parse a single method within a service definition.
+  bool ParseServiceMethod(MethodDescriptorProto* method,
+                          const LocationRecorder& method_location,
+                          const FileDescriptorProto* containing_file);
+
+
+  // Parse options of a single method or stream.
+  bool ParseOptions(const LocationRecorder& parent_location,
+                    const FileDescriptorProto* containing_file,
+                    const int optionsFieldNumber,
+                    Message* mutable_options);
+
+  // Parse "required", "optional", or "repeated" and fill in "label"
+  // with the value.
+  bool ParseLabel(FieldDescriptorProto::Label* label,
+                  const FileDescriptorProto* containing_file);
+
+  // 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,
+                         const LocationRecorder& field_location,
+                         const FileDescriptorProto* containing_file);
+
+  // Parse the "default" option.  This needs special handling because its
+  // type is the field's type.
+  bool ParseDefaultAssignment(FieldDescriptorProto* field,
+                              const LocationRecorder& field_location,
+                              const FileDescriptorProto* containing_file);
+
+  enum OptionStyle {
+    OPTION_ASSIGNMENT,  // just "name = value"
+    OPTION_STATEMENT    // "option name = value;"
+  };
+
+  // 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 ParseOption(Message* options,
+                   const LocationRecorder& options_location,
+                   const FileDescriptorProto* containing_file,
+                   OptionStyle style);
+
+  // Parses a single part of a multipart option name. A multipart name consists
+  // of names separated by dots. Each name is either an identifier or a series
+  // of identifiers separated by dots and enclosed in parentheses. E.g.,
+  // "foo.(bar.baz).qux".
+  bool ParseOptionNamePart(UninterpretedOption* uninterpreted_option,
+                           const LocationRecorder& part_location,
+                           const FileDescriptorProto* containing_file);
+
+  // Parses a string surrounded by balanced braces.  Strips off the outer
+  // braces and stores the enclosed string in *value.
+  // E.g.,
+  //     { foo }                     *value gets 'foo'
+  //     { foo { bar: box } }        *value gets 'foo { bar: box }'
+  //     {}                          *value gets ''
+  //
+  // REQUIRES: LookingAt("{")
+  // When finished successfully, we are looking at the first token past
+  // the ending brace.
+  bool ParseUninterpretedBlock(string* value);
+
+  // =================================================================
+
+  io::Tokenizer* input_;
+  io::ErrorCollector* error_collector_;
+  SourceCodeInfo* source_code_info_;
+  SourceLocationTable* source_location_table_;  // legacy
+  bool had_errors_;
+  bool require_syntax_identifier_;
+  bool stop_after_syntax_identifier_;
+  string syntax_identifier_;
+
+  // Leading doc comments for the next declaration.  These are not complete
+  // yet; use ConsumeEndOfDeclaration() to get the complete comments.
+  string upcoming_doc_comments_;
+
+  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.
+//
+// This is semi-obsolete:  FileDescriptorProto.source_code_info now contains
+// far more complete information about source locations.  However, as of this
+// writing you still need to use SourceLocationTable when integrating with
+// DescriptorPool.
+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/protobuf/src/google/protobuf/compiler/parser_unittest.cc b/protobuf/src/google/protobuf/compiler/parser_unittest.cc
new file mode 100644
index 0000000..9ec29a4
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/parser_unittest.cc
@@ -0,0 +1,2612 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <memory>
+#include <vector>
+#include <algorithm>
+#include <map>
+
+#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/unittest_custom_options.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/map_util.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_);
+
+    // We don't cover SourceCodeInfo in these tests.
+    actual.clear_source_code_info();
+
+    // 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_;
+};
+
+// ===================================================================
+
+TEST_F(ParserTest, StopAfterSyntaxIdentifier) {
+  SetupParser(
+    "// blah\n"
+    "syntax = \"foobar\";\n"
+    "this line will not be parsed\n");
+  parser_->SetStopAfterSyntaxIdentifier(true);
+  EXPECT_TRUE(parser_->Parse(input_.get(), NULL));
+  EXPECT_EQ("", error_collector_.text_);
+  EXPECT_EQ("foobar", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParserTest, StopAfterOmittedSyntaxIdentifier) {
+  SetupParser(
+    "// blah\n"
+    "this line will not be parsed\n");
+  parser_->SetStopAfterSyntaxIdentifier(true);
+  EXPECT_TRUE(parser_->Parse(input_.get(), NULL));
+  EXPECT_EQ("", error_collector_.text_);
+  EXPECT_EQ("", parser_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParserTest, StopAfterSyntaxIdentifierWithErrors) {
+  SetupParser(
+    "// blah\n"
+    "syntax = error;\n");
+  parser_->SetStopAfterSyntaxIdentifier(true);
+  EXPECT_FALSE(parser_->Parse(input_.get(), NULL));
+  EXPECT_EQ("1:9: Expected syntax identifier.\n", error_collector_.text_);
+}
+
+// ===================================================================
+
+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_->GetSyntaxIdentifier());
+}
+
+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_->GetSyntaxIdentifier());
+}
+
+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_->GetSyntaxIdentifier());
+}
+
+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 double foo = 1 [default= inf ];\n"
+    "  required double foo = 1 [default=-inf ];\n"
+    "  required double foo = 1 [default= nan ];\n"
+    "  required string foo = 1 [default='13\\001'];\n"
+    "  required string foo = 1 [default='a' \"b\" \n \"c\"];\n"
+    "  required bytes  foo = 1 [default='14\\002'];\n"
+    "  required bytes  foo = 1 [default='a' \"b\" \n 'c'];\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_DOUBLE  default_value:\"inf\"       "ETC" }"
+    "  field { type:TYPE_DOUBLE  default_value:\"-inf\"      "ETC" }"
+    "  field { type:TYPE_DOUBLE  default_value:\"nan\"       "ETC" }"
+    "  field { type:TYPE_STRING  default_value:\"13\\001\"   "ETC" }"
+    "  field { type:TYPE_STRING  default_value:\"abc\"       "ETC" }"
+    "  field { type:TYPE_BYTES   default_value:\"14\\\\002\" "ETC" }"
+    "  field { type:TYPE_BYTES   default_value:\"abc\"       "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\n"
+    "      [ctype=CORD, (foo)=7, foo.(.bar.baz).qux.quux.(corge)=-33, \n"
+    "       (quux)=\"x\040y\", (baz.qux)=hey];\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name: \"foo\" label: LABEL_OPTIONAL type: TYPE_STRING number: 1"
+    "          options { uninterpreted_option: { name { name_part: \"ctype\" "
+    "                                                   is_extension: false } "
+    "                                            identifier_value: \"CORD\"  }"
+    "                    uninterpreted_option: { name { name_part: \"foo\" "
+    "                                                   is_extension: true } "
+    "                                            positive_int_value: 7  }"
+    "                    uninterpreted_option: { name { name_part: \"foo\" "
+    "                                                   is_extension: false } "
+    "                                            name { name_part: \".bar.baz\""
+    "                                                   is_extension: true } "
+    "                                            name { name_part: \"qux\" "
+    "                                                   is_extension: false } "
+    "                                            name { name_part: \"quux\" "
+    "                                                   is_extension: false } "
+    "                                            name { name_part: \"corge\" "
+    "                                                   is_extension: true } "
+    "                                            negative_int_value: -33 }"
+    "                    uninterpreted_option: { name { name_part: \"quux\" "
+    "                                                   is_extension: true } "
+    "                                            string_value: \"x y\" }"
+    "                    uninterpreted_option: { name { name_part: \"baz.qux\" "
+    "                                                   is_extension: true } "
+    "                                            identifier_value: \"hey\" }"
+    "          }"
+    "  }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, Oneof) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  oneof foo {\n"
+    "    int32 a = 1;\n"
+    "    string b = 2;\n"
+    "    TestMessage c = 3;\n"
+    "    group D = 4 { optional int32 i = 5; }\n"
+    "  }\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
+    "          oneof_index:0 }"
+    "  field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
+    "          oneof_index:0 }"
+    "  field { name:\"c\" label:LABEL_OPTIONAL type_name:\"TestMessage\" "
+    "          number:3 oneof_index:0 }"
+    "  field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_GROUP "
+    "          type_name:\"D\" number:4 oneof_index:0 }"
+    "  oneof_decl {"
+    "    name: \"foo\""
+    "  }"
+    "  nested_type {"
+    "    name: \"D\""
+    "    field { name:\"i\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 }"
+    "  }"
+    "}");
+}
+
+TEST_F(ParseMessageTest, MultipleOneofs) {
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  oneof foo {\n"
+    "    int32 a = 1;\n"
+    "    string b = 2;\n"
+    "  }\n"
+    "  oneof bar {\n"
+    "    int32 c = 3;\n"
+    "    string d = 4;\n"
+    "  }\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "  field { name:\"a\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 "
+    "          oneof_index:0 }"
+    "  field { name:\"b\" label:LABEL_OPTIONAL type:TYPE_STRING number:2 "
+    "          oneof_index:0 }"
+    "  field { name:\"c\" label:LABEL_OPTIONAL type:TYPE_INT32 number:3 "
+    "          oneof_index:1 }"
+    "  field { name:\"d\" label:LABEL_OPTIONAL type:TYPE_STRING number:4 "
+    "          oneof_index:1 }"
+    "  oneof_decl {"
+    "    name: \"foo\""
+    "  }"
+    "  oneof_decl {"
+    "    name: \"bar\""
+    "  }"
+    "}");
+}
+
+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, LargerMaxForMessageSetWireFormatMessages) {
+  // Messages using the message_set_wire_format option can accept larger
+  // extension numbers, as the numbers are not encoded as int32 field values
+  // rather than tags.
+  ExpectParsesTo(
+    "message TestMessage {\n"
+    "  extensions 4 to max;\n"
+    "  option message_set_wire_format = true;\n"
+    "}\n",
+
+    "message_type {"
+    "  name: \"TestMessage\""
+    "    extension_range { start:4 end: 0x7fffffff }"
+    "  options {\n"
+    "    uninterpreted_option { \n"
+    "      name {\n"
+    "        name_part: \"message_set_wire_format\"\n"
+    "        is_extension: false\n"
+    "      }\n"
+    "      identifier_value: \"true\"\n"
+    "    }\n"
+    "  }\n"
+    "}");
+}
+
+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"
+    "  HEX_MAX = 0x7FFFFFFF;\n"
+    "  HEX_MIN = -0x80000000;\n"
+    "  INT_MAX = 2147483647;\n"
+    "  INT_MIN = -2147483648;\n"
+    "}\n",
+
+    "enum_type {"
+    "  name: \"TestEnum\""
+    "  value { name:\"FOO\" number:13 }"
+    "  value { name:\"BAR\" number:-10 }"
+    "  value { name:\"BAZ\" number:500 }"
+    "  value { name:\"HEX_MAX\" number:2147483647 }"
+    "  value { name:\"HEX_MIN\" number:-2147483648 }"
+    "  value { name:\"INT_MAX\" number:2147483647 }"
+    "  value { name:\"INT_MIN\" number:-2147483648 }"
+    "}");
+}
+
+TEST_F(ParseEnumTest, ValueOptions) {
+  ExpectParsesTo(
+    "enum TestEnum {\n"
+    "  FOO = 13;\n"
+    "  BAR = -10 [ (something.text) = 'abc' ];\n"
+    "  BAZ = 500 [ (something.text) = 'def', other = 1 ];\n"
+    "}\n",
+
+    "enum_type {"
+    "  name: \"TestEnum\""
+    "  value { name: \"FOO\" number: 13 }"
+    "  value { name: \"BAR\" number: -10 "
+    "    options { "
+    "      uninterpreted_option { "
+    "        name { name_part: \"something.text\" is_extension: true } "
+    "        string_value: \"abc\" "
+    "      } "
+    "    } "
+    "  } "
+    "  value { name: \"BAZ\" number: 500 "
+    "    options { "
+    "      uninterpreted_option { "
+    "        name { name_part: \"something.text\" is_extension: true } "
+    "        string_value: \"def\" "
+    "      } "
+    "      uninterpreted_option { "
+    "        name { name_part: \"other\" is_extension: false } "
+    "        positive_int_value: 1 "
+    "      } "
+    "    } "
+    "  } "
+    "}");
+}
+
+// ===================================================================
+
+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, MethodsAndStreams) {
+  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, ParsePublicImports) {
+  ExpectParsesTo(
+    "import \"foo.proto\";\n"
+    "import public \"bar.proto\";\n"
+    "import \"baz.proto\";\n"
+    "import public \"qux.proto\";\n",
+    "dependency: \"foo.proto\""
+    "dependency: \"bar.proto\""
+    "dependency: \"baz.proto\""
+    "dependency: \"qux.proto\""
+    "public_dependency: 1 "
+    "public_dependency: 3 ");
+}
+
+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 {"
+    "uninterpreted_option { name { name_part: \"java_package\" "
+    "                              is_extension: false }"
+    "                       string_value: \"com.google.foo\"} "
+    "uninterpreted_option { name { name_part: \"optimize_for\" "
+    "                              is_extension: false }"
+    "                       identifier_value: \"CODE_SIZE\" } "
+    "}");
+}
+
+// ===================================================================
+// 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_->GetSyntaxIdentifier());
+}
+
+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_->GetSyntaxIdentifier());
+}
+
+TEST_F(ParseErrorTest, SimpleSyntaxError) {
+  ExpectHasErrors(
+    "message TestMessage @#$ { blah }",
+    "0:20: Expected \"{\".\n");
+  EXPECT_EQ("proto2", parser_->GetSyntaxIdentifier());
+}
+
+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 identifier.\n");
+}
+
+TEST_F(ParseErrorTest, NonExtensionOptionNameBeginningWithDot) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [.foo=1];\n"
+    "}\n",
+    "1:27: Expected identifier.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueTypeMismatch) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [default=true];\n"
+    "}\n",
+    "1:35: Expected integer for field default value.\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 for field default value.\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, EnumValueOutOfRange) {
+  ExpectHasErrors(
+    "enum TestEnum {\n"
+    "  HEX_TOO_BIG   =  0x80000000;\n"
+    "  HEX_TOO_SMALL = -0x80000001;\n"
+    "  INT_TOO_BIG   =  2147483648;\n"
+    "  INT_TOO_SMALL = -2147483649;\n"
+    "}\n",
+    "1:19: Integer out of range.\n"
+    "2:19: Integer out of range.\n"
+    "3:19: Integer out of range.\n"
+    "4:19: Integer out of range.\n");
+}
+
+TEST_F(ParseErrorTest, DefaultValueMissing) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  optional uint32 foo = 1 [default=];\n"
+    "}\n",
+    "1:35: Expected integer for field default value.\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, MissingOneofName) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  oneof {\n"
+    "    int32 bar = 1;\n"
+    "  }\n"
+    "}\n",
+    "1:8: Expected oneof name.\n");
+}
+
+TEST_F(ParseErrorTest, LabelInOneof) {
+  ExpectHasErrors(
+    "message TestMessage {\n"
+    "  oneof foo {\n"
+    "    optional int32 bar = 1;\n"
+    "  }\n"
+    "}\n",
+    "2:4: Fields in oneofs must not have labels (required / optional "
+      "/ repeated).\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");
+}
+
+TEST_F(ParseErrorTest, EofInAggregateValue) {
+  ExpectHasErrors(
+      "option (fileopt) = { i:100\n",
+      "1:0: Unexpected end of stream while parsing aggregate value.\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:45: Expected \"=\".\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");
+}
+
+// ===================================================================
+// 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, FileOptionNameError) {
+  ExpectHasValidationErrors(
+    "option foo = 5;",
+    "0:7: Option \"foo\" unknown.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FileOptionValueError) {
+  ExpectHasValidationErrors(
+    "option java_outer_classname = 5;",
+    "0:30: Value must be quoted string for string option "
+    "\"google.protobuf.FileOptions.java_outer_classname\".\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldOptionNameError) {
+  ExpectHasValidationErrors(
+    "message Foo {\n"
+    "  optional bool bar = 1 [foo=1];\n"
+    "}\n",
+    "1:25: Option \"foo\" unknown.\n");
+}
+
+TEST_F(ParserValidationErrorTest, FieldOptionValueError) {
+  ExpectHasValidationErrors(
+    "message Foo {\n"
+    "  optional int32 bar = 1 [ctype=1];\n"
+    "}\n",
+    "1:32: Value must be identifier for enum-valued option "
+    "\"google.protobuf.FieldOptions.ctype\".\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_F(ParserValidationErrorTest, ResovledUndefinedError) {
+  // Create another file which defines symbol ".base.bar".
+  FileDescriptorProto other_file;
+  other_file.set_name("base.proto");
+  other_file.set_package("base");
+  other_file.add_message_type()->set_name("bar");
+  EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
+
+  // Define "foo.base" and try "base.bar".
+  // "base.bar" is resolved to "foo.base.bar" which is not defined.
+  ExpectHasValidationErrors(
+    "package foo.base;\n"
+    "import \"base.proto\";\n"
+    "message qux {\n"
+    "  optional base.bar baz = 1;\n"
+    "  optional .base.bar quz = 2;\n"
+    "}\n",
+    "3:11: \"base.bar\" is resolved to \"foo.base.bar\","
+    " which is not defined. The innermost scope is searched first "
+    "in name resolution. Consider using a leading '.'(i.e., \".base.bar\")"
+    " to start from the outermost scope.\n");
+}
+
+TEST_F(ParserValidationErrorTest, ResovledUndefinedOptionError) {
+  // Build descriptor message in test pool
+  FileDescriptorProto descriptor_proto;
+  DescriptorProto::descriptor()->file()->CopyTo(&descriptor_proto);
+  ASSERT_TRUE(pool_.BuildFile(descriptor_proto) != NULL);
+
+  // base2.proto:
+  //   package baz
+  //   import google/protobuf/descriptor.proto
+  //   message Bar { optional int32 foo = 1; }
+  //   extend FileOptions { optional Bar bar = 7672757; }
+  FileDescriptorProto other_file;
+  other_file.set_name("base2.proto");
+  other_file.set_package("baz");
+  other_file.add_dependency();
+  other_file.set_dependency(0, descriptor_proto.name());
+
+  DescriptorProto* message(other_file.add_message_type());
+  message->set_name("Bar");
+  FieldDescriptorProto* field(message->add_field());
+  field->set_name("foo");
+  field->set_number(1);
+  field->set_label(FieldDescriptorProto_Label_LABEL_OPTIONAL);
+  field->set_type(FieldDescriptorProto_Type_TYPE_INT32);
+
+  FieldDescriptorProto* extension(other_file.add_extension());
+  extension->set_name("bar");
+  extension->set_number(7672757);
+  extension->set_label(FieldDescriptorProto_Label_LABEL_OPTIONAL);
+  extension->set_type(FieldDescriptorProto_Type_TYPE_MESSAGE);
+  extension->set_type_name("Bar");
+  extension->set_extendee("google.protobuf.FileOptions");
+
+  EXPECT_TRUE(pool_.BuildFile(other_file) != NULL);
+
+  // qux.proto:
+  //   package qux.baz
+  //   option (baz.bar).foo = 1;
+  //
+  // Although "baz.bar" is already defined, the lookup code will try
+  // "qux.baz.bar", since it's the match from the innermost scope,
+  // which will cause a symbol not defined error.
+  ExpectHasValidationErrors(
+      "package qux.baz;\n"
+      "import \"base2.proto\";\n"
+      "option (baz.bar).foo = 1;\n",
+      "2:7: Option \"(baz.bar)\" is resolved to \"(qux.baz.bar)\","
+      " which is not defined. The innermost scope is searched first "
+      "in name resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\")"
+      " to start from the outermost scope.\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 (note, 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) const {
+    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_)
+      << "Failed to parse:\n" << debug_string;
+
+  // 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* public_import =
+      protobuf_unittest_import::PublicImportMessage::descriptor()->file();
+  FileDescriptorProto public_import_proto;
+  public_import->CopyTo(&public_import_proto);
+  ASSERT_TRUE(pool_.BuildFile(public_import_proto) != NULL);
+  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();
+  ASSERT_TRUE(actual != NULL)
+      << "Failed to validate:\n" << debug_string;
+  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());
+}
+
+TEST_F(ParseDecriptorDebugTest, TestCustomOptions) {
+  const FileDescriptor* original_file =
+     protobuf_unittest::AggregateMessage::descriptor()->file();
+  FileDescriptorProto expected;
+  original_file->CopyTo(&expected);
+
+  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(original_file->name());
+
+  // unittest_custom_options.proto depends on descriptor.proto.
+  const FileDescriptor* import = FileDescriptorProto::descriptor()->file();
+  FileDescriptorProto import_proto;
+  import->CopyTo(&import_proto);
+  ASSERT_TRUE(pool_.BuildFile(import_proto) != NULL);
+  const FileDescriptor* actual = pool_.BuildFile(parsed);
+  ASSERT_TRUE(actual != NULL);
+  parsed.Clear();
+  actual->CopyTo(&parsed);
+
+  // 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);
+
+  EXPECT_EQ(expected.DebugString(), parsed.DebugString());
+}
+
+// ===================================================================
+// SourceCodeInfo tests.
+
+// Follows a path -- as defined by SourceCodeInfo.Location.path -- from a
+// message to a particular sub-field.
+// * If the target is itself a message, sets *output_message to point at it,
+//   *output_field to NULL, and *output_index to -1.
+// * Otherwise, if the target is an element of a repeated field, sets
+//   *output_message to the containing message, *output_field to the descriptor
+//   of the field, and *output_index to the index of the element.
+// * Otherwise, the target is a field (possibly a repeated field, but not any
+//   one element).  Sets *output_message to the containing message,
+//   *output_field to the descriptor of the field, and *output_index to -1.
+// Returns true if the path was valid, false otherwise.  A gTest failure is
+// recorded before returning false.
+bool FollowPath(const Message& root,
+                const int* path_begin, const int* path_end,
+                const Message** output_message,
+                const FieldDescriptor** output_field,
+                int* output_index) {
+  if (path_begin == path_end) {
+    // Path refers to this whole message.
+    *output_message = &root;
+    *output_field = NULL;
+    *output_index = -1;
+    return true;
+  }
+
+  const Descriptor* descriptor = root.GetDescriptor();
+  const Reflection* reflection = root.GetReflection();
+
+  const FieldDescriptor* field = descriptor->FindFieldByNumber(*path_begin);
+
+  if (field == NULL) {
+    ADD_FAILURE() << descriptor->name() << " has no field number: "
+                  << *path_begin;
+    return false;
+  }
+
+  ++path_begin;
+
+  if (field->is_repeated()) {
+    if (path_begin == path_end) {
+      // Path refers to the whole repeated field.
+      *output_message = &root;
+      *output_field = field;
+      *output_index = -1;
+      return true;
+    }
+
+    int index = *path_begin++;
+    int size = reflection->FieldSize(root, field);
+
+    if (index >= size) {
+      ADD_FAILURE() << descriptor->name() << "." << field->name()
+                    << " has size " << size << ", but path contained index: "
+                    << index;
+      return false;
+    }
+
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      // Descend into child message.
+      const Message& child = reflection->GetRepeatedMessage(root, field, index);
+      return FollowPath(child, path_begin, path_end,
+                        output_message, output_field, output_index);
+    } else if (path_begin == path_end) {
+      // Path refers to this element.
+      *output_message = &root;
+      *output_field = field;
+      *output_index = index;
+      return true;
+    } else {
+      ADD_FAILURE() << descriptor->name() << "." << field->name()
+                    << " is not a message; cannot descend into it.";
+      return false;
+    }
+  } else {
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      const Message& child = reflection->GetMessage(root, field);
+      return FollowPath(child, path_begin, path_end,
+                        output_message, output_field, output_index);
+    } else if (path_begin == path_end) {
+      // Path refers to this field.
+      *output_message = &root;
+      *output_field = field;
+      *output_index = -1;
+      return true;
+    } else {
+      ADD_FAILURE() << descriptor->name() << "." << field->name()
+                    << " is not a message; cannot descend into it.";
+      return false;
+    }
+  }
+}
+
+// Check if two spans are equal.
+bool CompareSpans(const RepeatedField<int>& span1,
+                  const RepeatedField<int>& span2) {
+  if (span1.size() != span2.size()) return false;
+  for (int i = 0; i < span1.size(); i++) {
+    if (span1.Get(i) != span2.Get(i)) return false;
+  }
+  return true;
+}
+
+// Test fixture for source info tests, which check that source locations are
+// recorded correctly in FileDescriptorProto.source_code_info.location.
+class SourceInfoTest : public ParserTest {
+ protected:
+  // The parsed file (initialized by Parse()).
+  FileDescriptorProto file_;
+
+  // Parse the given text as a .proto file and populate the spans_ map with
+  // all the source location spans in its SourceCodeInfo table.
+  bool Parse(const char* text) {
+    ExtractMarkers(text);
+    SetupParser(text_without_markers_.c_str());
+    if (!parser_->Parse(input_.get(), &file_)) {
+      return false;
+    }
+
+    const SourceCodeInfo& source_info = file_.source_code_info();
+    for (int i = 0; i < source_info.location_size(); i++) {
+      const SourceCodeInfo::Location& location = source_info.location(i);
+      const Message* descriptor_proto = NULL;
+      const FieldDescriptor* field = NULL;
+      int index = 0;
+      if (!FollowPath(file_, location.path().begin(), location.path().end(),
+                      &descriptor_proto, &field, &index)) {
+        return false;
+      }
+
+      spans_.insert(make_pair(SpanKey(*descriptor_proto, field, index),
+                              &location));
+    }
+
+    return true;
+  }
+
+  virtual void TearDown() {
+    EXPECT_TRUE(spans_.empty())
+        << "Forgot to call HasSpan() for:\n"
+        << spans_.begin()->second->DebugString();
+  }
+
+  // -----------------------------------------------------------------
+  // HasSpan() checks that the span of source code delimited by the given
+  // tags (comments) correspond via the SourceCodeInfo table to the given
+  // part of the FileDescriptorProto.  (If unclear, look at the actual tests;
+  // it should quickly become obvious.)
+
+  bool HasSpan(char start_marker, char end_marker,
+               const Message& descriptor_proto) {
+    return HasSpanWithComment(
+        start_marker, end_marker, descriptor_proto, NULL, -1, NULL, NULL);
+  }
+
+  bool HasSpanWithComment(char start_marker, char end_marker,
+                          const Message& descriptor_proto,
+                          const char* expected_leading_comments,
+                          const char* expected_trailing_comments) {
+    return HasSpanWithComment(
+        start_marker, end_marker, descriptor_proto, NULL, -1,
+        expected_leading_comments, expected_trailing_comments);
+  }
+
+  bool HasSpan(char start_marker, char end_marker,
+               const Message& descriptor_proto, const string& field_name) {
+    return HasSpan(start_marker, end_marker, descriptor_proto, field_name, -1);
+  }
+
+  bool HasSpan(char start_marker, char end_marker,
+               const Message& descriptor_proto, const string& field_name,
+               int index) {
+    return HasSpan(start_marker, end_marker, descriptor_proto,
+                   field_name, index, NULL, NULL);
+  }
+
+  bool HasSpan(char start_marker, char end_marker,
+               const Message& descriptor_proto,
+               const string& field_name, int index,
+               const char* expected_leading_comments,
+               const char* expected_trailing_comments) {
+    const FieldDescriptor* field =
+        descriptor_proto.GetDescriptor()->FindFieldByName(field_name);
+    if (field == NULL) {
+      ADD_FAILURE() << descriptor_proto.GetDescriptor()->name()
+                    << " has no such field: " << field_name;
+      return false;
+    }
+
+    return HasSpanWithComment(
+        start_marker, end_marker, descriptor_proto, field, index,
+        expected_leading_comments, expected_trailing_comments);
+  }
+
+  bool HasSpan(const Message& descriptor_proto) {
+    return HasSpanWithComment(
+        '\0', '\0', descriptor_proto, NULL, -1, NULL, NULL);
+  }
+
+  bool HasSpan(const Message& descriptor_proto, const string& field_name) {
+    return HasSpan('\0', '\0', descriptor_proto, field_name, -1);
+  }
+
+  bool HasSpan(const Message& descriptor_proto, const string& field_name,
+               int index) {
+    return HasSpan('\0', '\0', descriptor_proto, field_name, index);
+  }
+
+  bool HasSpanWithComment(char start_marker, char end_marker,
+                          const Message& descriptor_proto,
+                          const FieldDescriptor* field, int index,
+                          const char* expected_leading_comments,
+                          const char* expected_trailing_comments) {
+    pair<SpanMap::iterator, SpanMap::iterator> range =
+        spans_.equal_range(SpanKey(descriptor_proto, field, index));
+
+    if (start_marker == '\0') {
+      if (range.first == range.second) {
+        return false;
+      } else {
+        spans_.erase(range.first);
+        return true;
+      }
+    } else {
+      pair<int, int> start_pos = FindOrDie(markers_, start_marker);
+      pair<int, int> end_pos = FindOrDie(markers_, end_marker);
+
+      RepeatedField<int> expected_span;
+      expected_span.Add(start_pos.first);
+      expected_span.Add(start_pos.second);
+      if (end_pos.first != start_pos.first) {
+        expected_span.Add(end_pos.first);
+      }
+      expected_span.Add(end_pos.second);
+
+      for (SpanMap::iterator iter = range.first; iter != range.second; ++iter) {
+        if (CompareSpans(expected_span, iter->second->span())) {
+          if (expected_leading_comments == NULL) {
+            EXPECT_FALSE(iter->second->has_leading_comments());
+          } else {
+            EXPECT_TRUE(iter->second->has_leading_comments());
+            EXPECT_EQ(expected_leading_comments,
+                      iter->second->leading_comments());
+          }
+          if (expected_trailing_comments == NULL) {
+            EXPECT_FALSE(iter->second->has_trailing_comments());
+          } else {
+            EXPECT_TRUE(iter->second->has_trailing_comments());
+            EXPECT_EQ(expected_trailing_comments,
+                      iter->second->trailing_comments());
+          }
+
+          spans_.erase(iter);
+          return true;
+        }
+      }
+
+      return false;
+    }
+  }
+
+ private:
+  struct SpanKey {
+    const Message* descriptor_proto;
+    const FieldDescriptor* field;
+    int index;
+
+    inline SpanKey() {}
+    inline SpanKey(const Message& descriptor_proto_param,
+                   const FieldDescriptor* field_param,
+                   int index_param)
+        : descriptor_proto(&descriptor_proto_param), field(field_param),
+          index(index_param) {}
+
+    inline bool operator<(const SpanKey& other) const {
+      if (descriptor_proto < other.descriptor_proto) return true;
+      if (descriptor_proto > other.descriptor_proto) return false;
+      if (field < other.field) return true;
+      if (field > other.field) return false;
+      return index < other.index;
+    }
+  };
+
+  typedef multimap<SpanKey, const SourceCodeInfo::Location*> SpanMap;
+  SpanMap spans_;
+  map<char, pair<int, int> > markers_;
+  string text_without_markers_;
+
+  void ExtractMarkers(const char* text) {
+    markers_.clear();
+    text_without_markers_.clear();
+    int line = 0;
+    int column = 0;
+    while (*text != '\0') {
+      if (*text == '$') {
+        ++text;
+        GOOGLE_CHECK_NE('\0', *text);
+        if (*text == '$') {
+          text_without_markers_ += '$';
+          ++column;
+        } else {
+          markers_[*text] = make_pair(line, column);
+          ++text;
+          GOOGLE_CHECK_EQ('$', *text);
+        }
+      } else if (*text == '\n') {
+        ++line;
+        column = 0;
+        text_without_markers_ += *text;
+      } else {
+        text_without_markers_ += *text;
+        ++column;
+      }
+      ++text;
+    }
+  }
+};
+
+TEST_F(SourceInfoTest, BasicFileDecls) {
+  EXPECT_TRUE(Parse(
+      "$a$syntax = \"proto2\";\n"
+      "package $b$foo.bar$c$;\n"
+      "import $d$\"baz.proto\"$e$;\n"
+      "import $f$\"qux.proto\"$g$;$h$\n"
+      "\n"
+      "// comment ignored\n"));
+
+  EXPECT_TRUE(HasSpan('a', 'h', file_));
+  EXPECT_TRUE(HasSpan('b', 'c', file_, "package"));
+  EXPECT_TRUE(HasSpan('d', 'e', file_, "dependency", 0));
+  EXPECT_TRUE(HasSpan('f', 'g', file_, "dependency", 1));
+}
+
+TEST_F(SourceInfoTest, Messages) {
+  EXPECT_TRUE(Parse(
+      "$a$message $b$Foo$c$ {}$d$\n"
+      "$e$message $f$Bar$g$ {}$h$\n"));
+
+  EXPECT_TRUE(HasSpan('a', 'd', file_.message_type(0)));
+  EXPECT_TRUE(HasSpan('b', 'c', file_.message_type(0), "name"));
+  EXPECT_TRUE(HasSpan('e', 'h', file_.message_type(1)));
+  EXPECT_TRUE(HasSpan('f', 'g', file_.message_type(1), "name"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, Fields) {
+  EXPECT_TRUE(Parse(
+      "message Foo {\n"
+      "  $a$optional$b$ $c$int32$d$ $e$bar$f$ = $g$1$h$;$i$\n"
+      "  $j$repeated$k$ $l$X.Y$m$ $n$baz$o$ = $p$2$q$;$r$\n"
+      "}\n"));
+
+  const FieldDescriptorProto& field1 = file_.message_type(0).field(0);
+  const FieldDescriptorProto& field2 = file_.message_type(0).field(1);
+
+  EXPECT_TRUE(HasSpan('a', 'i', field1));
+  EXPECT_TRUE(HasSpan('a', 'b', field1, "label"));
+  EXPECT_TRUE(HasSpan('c', 'd', field1, "type"));
+  EXPECT_TRUE(HasSpan('e', 'f', field1, "name"));
+  EXPECT_TRUE(HasSpan('g', 'h', field1, "number"));
+
+  EXPECT_TRUE(HasSpan('j', 'r', field2));
+  EXPECT_TRUE(HasSpan('j', 'k', field2, "label"));
+  EXPECT_TRUE(HasSpan('l', 'm', field2, "type_name"));
+  EXPECT_TRUE(HasSpan('n', 'o', field2, "name"));
+  EXPECT_TRUE(HasSpan('p', 'q', field2, "number"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.message_type(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Extensions) {
+  EXPECT_TRUE(Parse(
+      "$a$extend $b$Foo$c$ {\n"
+      "  $d$optional$e$ int32 bar = 1;$f$\n"
+      "  $g$repeated$h$ X.Y baz = 2;$i$\n"
+      "}$j$\n"
+      "$k$extend $l$Bar$m$ {\n"
+      "  $n$optional int32 qux = 1;$o$\n"
+      "}$p$\n"));
+
+  const FieldDescriptorProto& field1 = file_.extension(0);
+  const FieldDescriptorProto& field2 = file_.extension(1);
+  const FieldDescriptorProto& field3 = file_.extension(2);
+
+  EXPECT_TRUE(HasSpan('a', 'j', file_, "extension"));
+  EXPECT_TRUE(HasSpan('k', 'p', file_, "extension"));
+
+  EXPECT_TRUE(HasSpan('d', 'f', field1));
+  EXPECT_TRUE(HasSpan('d', 'e', field1, "label"));
+  EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee"));
+
+  EXPECT_TRUE(HasSpan('g', 'i', field2));
+  EXPECT_TRUE(HasSpan('g', 'h', field2, "label"));
+  EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee"));
+
+  EXPECT_TRUE(HasSpan('n', 'o', field3));
+  EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(field1, "type"));
+  EXPECT_TRUE(HasSpan(field1, "name"));
+  EXPECT_TRUE(HasSpan(field1, "number"));
+  EXPECT_TRUE(HasSpan(field2, "type_name"));
+  EXPECT_TRUE(HasSpan(field2, "name"));
+  EXPECT_TRUE(HasSpan(field2, "number"));
+  EXPECT_TRUE(HasSpan(field3, "label"));
+  EXPECT_TRUE(HasSpan(field3, "type"));
+  EXPECT_TRUE(HasSpan(field3, "name"));
+  EXPECT_TRUE(HasSpan(field3, "number"));
+}
+
+TEST_F(SourceInfoTest, NestedExtensions) {
+  EXPECT_TRUE(Parse(
+      "message Message {\n"
+      "  $a$extend $b$Foo$c$ {\n"
+      "    $d$optional$e$ int32 bar = 1;$f$\n"
+      "    $g$repeated$h$ X.Y baz = 2;$i$\n"
+      "  }$j$\n"
+      "  $k$extend $l$Bar$m$ {\n"
+      "    $n$optional int32 qux = 1;$o$\n"
+      "  }$p$\n"
+      "}\n"));
+
+  const FieldDescriptorProto& field1 = file_.message_type(0).extension(0);
+  const FieldDescriptorProto& field2 = file_.message_type(0).extension(1);
+  const FieldDescriptorProto& field3 = file_.message_type(0).extension(2);
+
+  EXPECT_TRUE(HasSpan('a', 'j', file_.message_type(0), "extension"));
+  EXPECT_TRUE(HasSpan('k', 'p', file_.message_type(0), "extension"));
+
+  EXPECT_TRUE(HasSpan('d', 'f', field1));
+  EXPECT_TRUE(HasSpan('d', 'e', field1, "label"));
+  EXPECT_TRUE(HasSpan('b', 'c', field1, "extendee"));
+
+  EXPECT_TRUE(HasSpan('g', 'i', field2));
+  EXPECT_TRUE(HasSpan('g', 'h', field2, "label"));
+  EXPECT_TRUE(HasSpan('b', 'c', field2, "extendee"));
+
+  EXPECT_TRUE(HasSpan('n', 'o', field3));
+  EXPECT_TRUE(HasSpan('l', 'm', field3, "extendee"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.message_type(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+  EXPECT_TRUE(HasSpan(field1, "type"));
+  EXPECT_TRUE(HasSpan(field1, "name"));
+  EXPECT_TRUE(HasSpan(field1, "number"));
+  EXPECT_TRUE(HasSpan(field2, "type_name"));
+  EXPECT_TRUE(HasSpan(field2, "name"));
+  EXPECT_TRUE(HasSpan(field2, "number"));
+  EXPECT_TRUE(HasSpan(field3, "label"));
+  EXPECT_TRUE(HasSpan(field3, "type"));
+  EXPECT_TRUE(HasSpan(field3, "name"));
+  EXPECT_TRUE(HasSpan(field3, "number"));
+}
+
+TEST_F(SourceInfoTest, ExtensionRanges) {
+  EXPECT_TRUE(Parse(
+      "message Message {\n"
+      "  $a$extensions $b$1$c$ to $d$4$e$, $f$6$g$;$h$\n"
+      "  $i$extensions $j$8$k$ to $l$max$m$;$n$\n"
+      "}\n"));
+
+  const DescriptorProto::ExtensionRange& range1 =
+      file_.message_type(0).extension_range(0);
+  const DescriptorProto::ExtensionRange& range2 =
+      file_.message_type(0).extension_range(1);
+  const DescriptorProto::ExtensionRange& range3 =
+      file_.message_type(0).extension_range(2);
+
+  EXPECT_TRUE(HasSpan('a', 'h', file_.message_type(0), "extension_range"));
+  EXPECT_TRUE(HasSpan('i', 'n', file_.message_type(0), "extension_range"));
+
+  EXPECT_TRUE(HasSpan('b', 'e', range1));
+  EXPECT_TRUE(HasSpan('b', 'c', range1, "start"));
+  EXPECT_TRUE(HasSpan('d', 'e', range1, "end"));
+
+  EXPECT_TRUE(HasSpan('f', 'g', range2));
+  EXPECT_TRUE(HasSpan('f', 'g', range2, "start"));
+  EXPECT_TRUE(HasSpan('f', 'g', range2, "end"));
+
+  EXPECT_TRUE(HasSpan('j', 'm', range3));
+  EXPECT_TRUE(HasSpan('j', 'k', range3, "start"));
+  EXPECT_TRUE(HasSpan('l', 'm', range3, "end"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.message_type(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Oneofs) {
+  EXPECT_TRUE(Parse(
+      "message Foo {\n"
+      "  $a$oneof $c$foo$d$ {\n"
+      "    $e$int32$f$ $g$a$h$ = $i$1$j$;$k$\n"
+      "  }$r$\n"
+      "}\n"));
+
+  const OneofDescriptorProto& oneof_decl = file_.message_type(0).oneof_decl(0);
+  const FieldDescriptorProto& field = file_.message_type(0).field(0);
+
+  EXPECT_TRUE(HasSpan('a', 'r', oneof_decl));
+  EXPECT_TRUE(HasSpan('c', 'd', oneof_decl, "name"));
+
+  EXPECT_TRUE(HasSpan('e', 'k', field));
+  EXPECT_TRUE(HasSpan('e', 'f', field, "type"));
+  EXPECT_TRUE(HasSpan('g', 'h', field, "name"));
+  EXPECT_TRUE(HasSpan('i', 'j', field, "number"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.message_type(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, NestedMessages) {
+  EXPECT_TRUE(Parse(
+      "message Foo {\n"
+      "  $a$message $b$Bar$c$ {\n"
+      "    $d$message $e$Baz$f$ {}$g$\n"
+      "  }$h$\n"
+      "  $i$message $j$Qux$k$ {}$l$\n"
+      "}\n"));
+
+  const DescriptorProto& bar = file_.message_type(0).nested_type(0);
+  const DescriptorProto& baz = bar.nested_type(0);
+  const DescriptorProto& qux = file_.message_type(0).nested_type(1);
+
+  EXPECT_TRUE(HasSpan('a', 'h', bar));
+  EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
+  EXPECT_TRUE(HasSpan('d', 'g', baz));
+  EXPECT_TRUE(HasSpan('e', 'f', baz, "name"));
+  EXPECT_TRUE(HasSpan('i', 'l', qux));
+  EXPECT_TRUE(HasSpan('j', 'k', qux, "name"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.message_type(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Groups) {
+  EXPECT_TRUE(Parse(
+      "message Foo {\n"
+      "  message Bar {}\n"
+      "  $a$optional$b$ $c$group$d$ $e$Baz$f$ = $g$1$h$ {\n"
+      "    $i$message Qux {}$j$\n"
+      "  }$k$\n"
+      "}\n"));
+
+  const DescriptorProto& bar = file_.message_type(0).nested_type(0);
+  const DescriptorProto& baz = file_.message_type(0).nested_type(1);
+  const DescriptorProto& qux = baz.nested_type(0);
+  const FieldDescriptorProto& field = file_.message_type(0).field(0);
+
+  EXPECT_TRUE(HasSpan('a', 'k', field));
+  EXPECT_TRUE(HasSpan('a', 'b', field, "label"));
+  EXPECT_TRUE(HasSpan('c', 'd', field, "type"));
+  EXPECT_TRUE(HasSpan('e', 'f', field, "name"));
+  EXPECT_TRUE(HasSpan('e', 'f', field, "type_name"));
+  EXPECT_TRUE(HasSpan('g', 'h', field, "number"));
+
+  EXPECT_TRUE(HasSpan('a', 'k', baz));
+  EXPECT_TRUE(HasSpan('e', 'f', baz, "name"));
+  EXPECT_TRUE(HasSpan('i', 'j', qux));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.message_type(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+  EXPECT_TRUE(HasSpan(bar));
+  EXPECT_TRUE(HasSpan(bar, "name"));
+  EXPECT_TRUE(HasSpan(qux, "name"));
+}
+
+TEST_F(SourceInfoTest, Enums) {
+  EXPECT_TRUE(Parse(
+      "$a$enum $b$Foo$c$ {}$d$\n"
+      "$e$enum $f$Bar$g$ {}$h$\n"));
+
+  EXPECT_TRUE(HasSpan('a', 'd', file_.enum_type(0)));
+  EXPECT_TRUE(HasSpan('b', 'c', file_.enum_type(0), "name"));
+  EXPECT_TRUE(HasSpan('e', 'h', file_.enum_type(1)));
+  EXPECT_TRUE(HasSpan('f', 'g', file_.enum_type(1), "name"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, EnumValues) {
+  EXPECT_TRUE(Parse(
+      "enum Foo {\n"
+      "  $a$BAR$b$ = $c$1$d$;$e$\n"
+      "  $f$BAZ$g$ = $h$2$i$;$j$\n"
+      "}"));
+
+  const EnumValueDescriptorProto& bar = file_.enum_type(0).value(0);
+  const EnumValueDescriptorProto& baz = file_.enum_type(0).value(1);
+
+  EXPECT_TRUE(HasSpan('a', 'e', bar));
+  EXPECT_TRUE(HasSpan('a', 'b', bar, "name"));
+  EXPECT_TRUE(HasSpan('c', 'd', bar, "number"));
+  EXPECT_TRUE(HasSpan('f', 'j', baz));
+  EXPECT_TRUE(HasSpan('f', 'g', baz, "name"));
+  EXPECT_TRUE(HasSpan('h', 'i', baz, "number"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, NestedEnums) {
+  EXPECT_TRUE(Parse(
+      "message Foo {\n"
+      "  $a$enum $b$Bar$c$ {}$d$\n"
+      "  $e$enum $f$Baz$g$ {}$h$\n"
+      "}\n"));
+
+  const EnumDescriptorProto& bar = file_.message_type(0).enum_type(0);
+  const EnumDescriptorProto& baz = file_.message_type(0).enum_type(1);
+
+  EXPECT_TRUE(HasSpan('a', 'd', bar));
+  EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
+  EXPECT_TRUE(HasSpan('e', 'h', baz));
+  EXPECT_TRUE(HasSpan('f', 'g', baz, "name"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.message_type(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+}
+
+TEST_F(SourceInfoTest, Services) {
+  EXPECT_TRUE(Parse(
+      "$a$service $b$Foo$c$ {}$d$\n"
+      "$e$service $f$Bar$g$ {}$h$\n"));
+
+  EXPECT_TRUE(HasSpan('a', 'd', file_.service(0)));
+  EXPECT_TRUE(HasSpan('b', 'c', file_.service(0), "name"));
+  EXPECT_TRUE(HasSpan('e', 'h', file_.service(1)));
+  EXPECT_TRUE(HasSpan('f', 'g', file_.service(1), "name"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+}
+
+TEST_F(SourceInfoTest, MethodsAndStreams) {
+  EXPECT_TRUE(Parse(
+      "service Foo {\n"
+      "  $a$rpc $b$Bar$c$($d$X$e$) returns($f$Y$g$);$h$"
+      "  $i$rpc $j$Baz$k$($l$Z$m$) returns($n$W$o$);$p$"
+      "}"));
+
+  const MethodDescriptorProto& bar = file_.service(0).method(0);
+  const MethodDescriptorProto& baz = file_.service(0).method(1);
+
+  EXPECT_TRUE(HasSpan('a', 'h', bar));
+  EXPECT_TRUE(HasSpan('b', 'c', bar, "name"));
+  EXPECT_TRUE(HasSpan('d', 'e', bar, "input_type"));
+  EXPECT_TRUE(HasSpan('f', 'g', bar, "output_type"));
+
+  EXPECT_TRUE(HasSpan('i', 'p', baz));
+  EXPECT_TRUE(HasSpan('j', 'k', baz, "name"));
+  EXPECT_TRUE(HasSpan('l', 'm', baz, "input_type"));
+  EXPECT_TRUE(HasSpan('n', 'o', baz, "output_type"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.service(0)));
+  EXPECT_TRUE(HasSpan(file_.service(0), "name"));
+}
+
+
+TEST_F(SourceInfoTest, Options) {
+  EXPECT_TRUE(Parse(
+      "$a$option $b$foo$c$.$d$($e$bar.baz$f$)$g$ = "
+          "$h$123$i$;$j$\n"
+      "$k$option qux = $l$-123$m$;$n$\n"
+      "$o$option corge = $p$abc$q$;$r$\n"
+      "$s$option grault = $t$'blah'$u$;$v$\n"
+      "$w$option garply = $x${ yadda yadda }$y$;$z$\n"
+      "$0$option waldo = $1$123.0$2$;$3$\n"
+  ));
+
+  const UninterpretedOption& option1 = file_.options().uninterpreted_option(0);
+  const UninterpretedOption& option2 = file_.options().uninterpreted_option(1);
+  const UninterpretedOption& option3 = file_.options().uninterpreted_option(2);
+  const UninterpretedOption& option4 = file_.options().uninterpreted_option(3);
+  const UninterpretedOption& option5 = file_.options().uninterpreted_option(4);
+  const UninterpretedOption& option6 = file_.options().uninterpreted_option(5);
+
+  EXPECT_TRUE(HasSpan('a', 'j', file_.options()));
+  EXPECT_TRUE(HasSpan('a', 'j', option1));
+  EXPECT_TRUE(HasSpan('b', 'g', option1, "name"));
+  EXPECT_TRUE(HasSpan('b', 'c', option1.name(0)));
+  EXPECT_TRUE(HasSpan('b', 'c', option1.name(0), "name_part"));
+  EXPECT_TRUE(HasSpan('d', 'g', option1.name(1)));
+  EXPECT_TRUE(HasSpan('e', 'f', option1.name(1), "name_part"));
+  EXPECT_TRUE(HasSpan('h', 'i', option1, "positive_int_value"));
+
+  EXPECT_TRUE(HasSpan('k', 'n', file_.options()));
+  EXPECT_TRUE(HasSpan('l', 'm', option2, "negative_int_value"));
+
+  EXPECT_TRUE(HasSpan('o', 'r', file_.options()));
+  EXPECT_TRUE(HasSpan('p', 'q', option3, "identifier_value"));
+
+  EXPECT_TRUE(HasSpan('s', 'v', file_.options()));
+  EXPECT_TRUE(HasSpan('t', 'u', option4, "string_value"));
+
+  EXPECT_TRUE(HasSpan('w', 'z', file_.options()));
+  EXPECT_TRUE(HasSpan('x', 'y', option5, "aggregate_value"));
+
+  EXPECT_TRUE(HasSpan('0', '3', file_.options()));
+  EXPECT_TRUE(HasSpan('1', '2', option6, "double_value"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(option2));
+  EXPECT_TRUE(HasSpan(option3));
+  EXPECT_TRUE(HasSpan(option4));
+  EXPECT_TRUE(HasSpan(option5));
+  EXPECT_TRUE(HasSpan(option6));
+  EXPECT_TRUE(HasSpan(option2, "name"));
+  EXPECT_TRUE(HasSpan(option3, "name"));
+  EXPECT_TRUE(HasSpan(option4, "name"));
+  EXPECT_TRUE(HasSpan(option5, "name"));
+  EXPECT_TRUE(HasSpan(option6, "name"));
+  EXPECT_TRUE(HasSpan(option2.name(0)));
+  EXPECT_TRUE(HasSpan(option3.name(0)));
+  EXPECT_TRUE(HasSpan(option4.name(0)));
+  EXPECT_TRUE(HasSpan(option5.name(0)));
+  EXPECT_TRUE(HasSpan(option6.name(0)));
+  EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(option3.name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(option4.name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(option5.name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(option6.name(0), "name_part"));
+}
+
+TEST_F(SourceInfoTest, ScopedOptions) {
+  EXPECT_TRUE(Parse(
+    "message Foo {\n"
+    "  $a$option mopt = 1;$b$\n"
+    "}\n"
+    "enum Bar {\n"
+    "  $c$option eopt = 1;$d$\n"
+    "}\n"
+    "service Baz {\n"
+    "  $e$option sopt = 1;$f$\n"
+    "  rpc M(X) returns(Y) {\n"
+    "    $g$option mopt = 1;$h$\n"
+    "  }\n"
+    "}\n"));
+
+  EXPECT_TRUE(HasSpan('a', 'b', file_.message_type(0).options()));
+  EXPECT_TRUE(HasSpan('c', 'd', file_.enum_type(0).options()));
+  EXPECT_TRUE(HasSpan('e', 'f', file_.service(0).options()));
+  EXPECT_TRUE(HasSpan('g', 'h', file_.service(0).method(0).options()));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.message_type(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+  EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+                      .uninterpreted_option(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+                      .uninterpreted_option(0), "name"));
+  EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+                      .uninterpreted_option(0).name(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+                      .uninterpreted_option(0).name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(file_.message_type(0).options()
+                      .uninterpreted_option(0), "positive_int_value"));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+                      .uninterpreted_option(0)));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+                      .uninterpreted_option(0), "name"));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+                      .uninterpreted_option(0).name(0)));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+                      .uninterpreted_option(0).name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0).options()
+                      .uninterpreted_option(0), "positive_int_value"));
+  EXPECT_TRUE(HasSpan(file_.service(0)));
+  EXPECT_TRUE(HasSpan(file_.service(0), "name"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(0)));
+  EXPECT_TRUE(HasSpan(file_.service(0).options()
+                      .uninterpreted_option(0)));
+  EXPECT_TRUE(HasSpan(file_.service(0).options()
+                      .uninterpreted_option(0), "name"));
+  EXPECT_TRUE(HasSpan(file_.service(0).options()
+                      .uninterpreted_option(0).name(0)));
+  EXPECT_TRUE(HasSpan(file_.service(0).options()
+                      .uninterpreted_option(0).name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(file_.service(0).options()
+                      .uninterpreted_option(0), "positive_int_value"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(0), "name"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(0), "input_type"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(0), "output_type"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+                      .uninterpreted_option(0)));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+                      .uninterpreted_option(0), "name"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+                      .uninterpreted_option(0).name(0)));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+                      .uninterpreted_option(0).name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(file_.service(0).method(0).options()
+                      .uninterpreted_option(0), "positive_int_value"));
+}
+
+TEST_F(SourceInfoTest, FieldOptions) {
+  // The actual "name = value" pairs are parsed by the same code as for
+  // top-level options so we won't re-test that -- just make sure that the
+  // syntax used for field options is understood.
+  EXPECT_TRUE(Parse(
+      "message Foo {"
+      "  optional int32 bar = 1 "
+          "$a$[default=$b$123$c$,$d$opt1=123$e$,"
+          "$f$opt2='hi'$g$]$h$;"
+      "}\n"
+  ));
+
+  const FieldDescriptorProto& field = file_.message_type(0).field(0);
+  const UninterpretedOption& option1 = field.options().uninterpreted_option(0);
+  const UninterpretedOption& option2 = field.options().uninterpreted_option(1);
+
+  EXPECT_TRUE(HasSpan('a', 'h', field.options()));
+  EXPECT_TRUE(HasSpan('b', 'c', field, "default_value"));
+  EXPECT_TRUE(HasSpan('d', 'e', option1));
+  EXPECT_TRUE(HasSpan('f', 'g', option2));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.message_type(0)));
+  EXPECT_TRUE(HasSpan(file_.message_type(0), "name"));
+  EXPECT_TRUE(HasSpan(field));
+  EXPECT_TRUE(HasSpan(field, "label"));
+  EXPECT_TRUE(HasSpan(field, "type"));
+  EXPECT_TRUE(HasSpan(field, "name"));
+  EXPECT_TRUE(HasSpan(field, "number"));
+  EXPECT_TRUE(HasSpan(option1, "name"));
+  EXPECT_TRUE(HasSpan(option2, "name"));
+  EXPECT_TRUE(HasSpan(option1.name(0)));
+  EXPECT_TRUE(HasSpan(option2.name(0)));
+  EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
+  EXPECT_TRUE(HasSpan(option2, "string_value"));
+}
+
+TEST_F(SourceInfoTest, EnumValueOptions) {
+  // The actual "name = value" pairs are parsed by the same code as for
+  // top-level options so we won't re-test that -- just make sure that the
+  // syntax used for enum options is understood.
+  EXPECT_TRUE(Parse(
+      "enum Foo {"
+      "  BAR = 1 $a$[$b$opt1=123$c$,$d$opt2='hi'$e$]$f$;"
+      "}\n"
+  ));
+
+  const EnumValueDescriptorProto& value = file_.enum_type(0).value(0);
+  const UninterpretedOption& option1 = value.options().uninterpreted_option(0);
+  const UninterpretedOption& option2 = value.options().uninterpreted_option(1);
+
+  EXPECT_TRUE(HasSpan('a', 'f', value.options()));
+  EXPECT_TRUE(HasSpan('b', 'c', option1));
+  EXPECT_TRUE(HasSpan('d', 'e', option2));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0)));
+  EXPECT_TRUE(HasSpan(file_.enum_type(0), "name"));
+  EXPECT_TRUE(HasSpan(value));
+  EXPECT_TRUE(HasSpan(value, "name"));
+  EXPECT_TRUE(HasSpan(value, "number"));
+  EXPECT_TRUE(HasSpan(option1, "name"));
+  EXPECT_TRUE(HasSpan(option2, "name"));
+  EXPECT_TRUE(HasSpan(option1.name(0)));
+  EXPECT_TRUE(HasSpan(option2.name(0)));
+  EXPECT_TRUE(HasSpan(option1.name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(option2.name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(option1, "positive_int_value"));
+  EXPECT_TRUE(HasSpan(option2, "string_value"));
+}
+
+TEST_F(SourceInfoTest, DocComments) {
+  EXPECT_TRUE(Parse(
+      "// Foo leading\n"
+      "// line 2\n"
+      "$a$message Foo {\n"
+      "  // Foo trailing\n"
+      "  // line 2\n"
+      "\n"
+      "  // ignored\n"
+      "\n"
+      "  // bar leading\n"
+      "  $b$optional int32 bar = 1;$c$\n"
+      "  // bar trailing\n"
+      "}$d$\n"
+      "// ignored\n"
+  ));
+
+  const DescriptorProto& foo = file_.message_type(0);
+  const FieldDescriptorProto& bar = foo.field(0);
+
+  EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
+      " Foo leading\n line 2\n",
+      " Foo trailing\n line 2\n"));
+  EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
+      " bar leading\n",
+      " bar trailing\n"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(foo, "name"));
+  EXPECT_TRUE(HasSpan(bar, "label"));
+  EXPECT_TRUE(HasSpan(bar, "type"));
+  EXPECT_TRUE(HasSpan(bar, "name"));
+  EXPECT_TRUE(HasSpan(bar, "number"));
+}
+
+TEST_F(SourceInfoTest, DocComments2) {
+  EXPECT_TRUE(Parse(
+      "// ignored\n"
+      "syntax = \"proto2\";\n"
+      "// Foo leading\n"
+      "// line 2\n"
+      "$a$message Foo {\n"
+      "  /* Foo trailing\n"
+      "   * line 2 */\n"
+      "  // ignored\n"
+      "  /* bar leading\n"
+      "   */"
+      "  $b$optional int32 bar = 1;$c$  // bar trailing\n"
+      "  // ignored\n"
+      "}$d$\n"
+      "// ignored\n"
+      "\n"
+      "// option leading\n"
+      "$e$option baz = 123;$f$\n"
+      "// option trailing\n"
+  ));
+
+  const DescriptorProto& foo = file_.message_type(0);
+  const FieldDescriptorProto& bar = foo.field(0);
+  const UninterpretedOption& baz = file_.options().uninterpreted_option(0);
+
+  EXPECT_TRUE(HasSpanWithComment('a', 'd', foo,
+      " Foo leading\n line 2\n",
+      " Foo trailing\n line 2 "));
+  EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
+      " bar leading\n",
+      " bar trailing\n"));
+  EXPECT_TRUE(HasSpanWithComment('e', 'f', baz,
+      " option leading\n",
+      " option trailing\n"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(foo, "name"));
+  EXPECT_TRUE(HasSpan(bar, "label"));
+  EXPECT_TRUE(HasSpan(bar, "type"));
+  EXPECT_TRUE(HasSpan(bar, "name"));
+  EXPECT_TRUE(HasSpan(bar, "number"));
+  EXPECT_TRUE(HasSpan(file_.options()));
+  EXPECT_TRUE(HasSpan(baz, "name"));
+  EXPECT_TRUE(HasSpan(baz.name(0)));
+  EXPECT_TRUE(HasSpan(baz.name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(baz, "positive_int_value"));
+}
+
+TEST_F(SourceInfoTest, DocComments3) {
+  EXPECT_TRUE(Parse(
+      "$a$message Foo {\n"
+      "  // bar leading\n"
+      "  $b$optional int32 bar = 1 [(baz.qux) = {}];$c$\n"
+      "  // bar trailing\n"
+      "}$d$\n"
+      "// ignored\n"
+  ));
+
+  const DescriptorProto& foo = file_.message_type(0);
+  const FieldDescriptorProto& bar = foo.field(0);
+
+  EXPECT_TRUE(HasSpanWithComment('b', 'c', bar,
+      " bar leading\n",
+      " bar trailing\n"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(foo));
+  EXPECT_TRUE(HasSpan(foo, "name"));
+  EXPECT_TRUE(HasSpan(bar, "label"));
+  EXPECT_TRUE(HasSpan(bar, "type"));
+  EXPECT_TRUE(HasSpan(bar, "name"));
+  EXPECT_TRUE(HasSpan(bar, "number"));
+  EXPECT_TRUE(HasSpan(bar.options()));
+  EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0)));
+  EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0), "name"));
+  EXPECT_TRUE(HasSpan(bar.options().uninterpreted_option(0).name(0)));
+  EXPECT_TRUE(HasSpan(
+      bar.options().uninterpreted_option(0).name(0), "name_part"));
+  EXPECT_TRUE(HasSpan(
+      bar.options().uninterpreted_option(0), "aggregate_value"));
+}
+
+TEST_F(SourceInfoTest, DocCommentsOneof) {
+  EXPECT_TRUE(Parse(
+      "// ignored\n"
+      "syntax = \"proto2\";\n"
+      "// Foo leading\n"
+      "$a$message Foo {\n"
+      "  /* Foo trailing\n"
+      "   */\n"
+      "  // ignored\n"
+      "  /* bar leading\n"
+      "   * line 2 */\n"
+      "  $b$oneof bar {\n"
+      "  /* bar trailing\n"
+      "   * line 2 */\n"
+      "  // ignored\n"
+      "  /* bar_int leading\n"
+      "   */\n"
+      "  $c$int32 bar_int = 1;$d$  // bar_int trailing\n"
+      "  // ignored\n"
+      "  }$e$\n"
+      "}$f$\n"));
+
+  const DescriptorProto& foo = file_.message_type(0);
+  const OneofDescriptorProto& bar = foo.oneof_decl(0);
+  const FieldDescriptorProto& bar_int = foo.field(0);
+
+  EXPECT_TRUE(HasSpanWithComment('a', 'f', foo,
+      " Foo leading\n",
+      " Foo trailing\n"));
+  EXPECT_TRUE(HasSpanWithComment('b', 'e', bar,
+      " bar leading\n line 2 ",
+      " bar trailing\n line 2 "));
+  EXPECT_TRUE(HasSpanWithComment('c', 'd', bar_int,
+      " bar_int leading\n",
+      " bar_int trailing\n"));
+
+  // Ignore these.
+  EXPECT_TRUE(HasSpan(file_));
+  EXPECT_TRUE(HasSpan(foo, "name"));
+  EXPECT_TRUE(HasSpan(bar, "name"));
+  EXPECT_TRUE(HasSpan(bar_int, "type"));
+  EXPECT_TRUE(HasSpan(bar_int, "name"));
+  EXPECT_TRUE(HasSpan(bar_int, "number"));
+}
+
+// ===================================================================
+
+}  // anonymous namespace
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/plugin.cc b/protobuf/src/google/protobuf/compiler/plugin.cc
new file mode 100644
index 0000000..9011a6b
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/plugin.cc
@@ -0,0 +1,163 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/compiler/plugin.h>
+
+#include <iostream>
+#include <set>
+
+#ifdef _WIN32
+#include <io.h>
+#include <fcntl.h>
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#else
+#include <unistd.h>
+#endif
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/compiler/plugin.pb.h>
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+class GeneratorResponseContext : public GeneratorContext {
+ public:
+  GeneratorResponseContext(CodeGeneratorResponse* response,
+                           const vector<const FileDescriptor*>& parsed_files)
+      : response_(response),
+        parsed_files_(parsed_files) {}
+  virtual ~GeneratorResponseContext() {}
+
+  // implements GeneratorContext --------------------------------------
+
+  virtual io::ZeroCopyOutputStream* Open(const string& filename) {
+    CodeGeneratorResponse::File* file = response_->add_file();
+    file->set_name(filename);
+    return new io::StringOutputStream(file->mutable_content());
+  }
+
+  virtual io::ZeroCopyOutputStream* OpenForInsert(
+      const string& filename, const string& insertion_point) {
+    CodeGeneratorResponse::File* file = response_->add_file();
+    file->set_name(filename);
+    file->set_insertion_point(insertion_point);
+    return new io::StringOutputStream(file->mutable_content());
+  }
+
+  void ListParsedFiles(vector<const FileDescriptor*>* output) {
+    *output = parsed_files_;
+  }
+
+ private:
+  CodeGeneratorResponse* response_;
+  const vector<const FileDescriptor*>& parsed_files_;
+};
+
+int PluginMain(int argc, char* argv[], const CodeGenerator* generator) {
+
+  if (argc > 1) {
+    cerr << argv[0] << ": Unknown option: " << argv[1] << endl;
+    return 1;
+  }
+
+#ifdef _WIN32
+  _setmode(STDIN_FILENO, _O_BINARY);
+  _setmode(STDOUT_FILENO, _O_BINARY);
+#endif
+
+  CodeGeneratorRequest request;
+  if (!request.ParseFromFileDescriptor(STDIN_FILENO)) {
+    cerr << argv[0] << ": protoc sent unparseable request to plugin." << endl;
+    return 1;
+  }
+
+  DescriptorPool pool;
+  for (int i = 0; i < request.proto_file_size(); i++) {
+    const FileDescriptor* file = pool.BuildFile(request.proto_file(i));
+    if (file == NULL) {
+      // BuildFile() already wrote an error message.
+      return 1;
+    }
+  }
+
+  vector<const FileDescriptor*> parsed_files;
+  for (int i = 0; i < request.file_to_generate_size(); i++) {
+    parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i)));
+    if (parsed_files.back() == NULL) {
+      cerr << argv[0] << ": protoc asked plugin to generate a file but "
+              "did not provide a descriptor for the file: "
+           << request.file_to_generate(i) << endl;
+      return 1;
+    }
+  }
+
+  CodeGeneratorResponse response;
+  GeneratorResponseContext context(&response, parsed_files);
+
+  for (int i = 0; i < parsed_files.size(); i++) {
+    const FileDescriptor* file = parsed_files[i];
+
+    string error;
+    bool succeeded = generator->Generate(
+        file, request.parameter(), &context, &error);
+
+    if (!succeeded && error.empty()) {
+      error = "Code generator returned false but provided no error "
+              "description.";
+    }
+    if (!error.empty()) {
+      response.set_error(file->name() + ": " + error);
+      break;
+    }
+  }
+
+  if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) {
+    cerr << argv[0] << ": Error writing to stdout." << endl;
+    return 1;
+  }
+
+  return 0;
+}
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/plugin.h b/protobuf/src/google/protobuf/compiler/plugin.h
new file mode 100644
index 0000000..679f9bd
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/plugin.h
@@ -0,0 +1,72 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// Front-end for protoc code generator plugins written in C++.
+//
+// To implement a protoc plugin in C++, simply write an implementation of
+// CodeGenerator, then create a main() function like:
+//   int main(int argc, char* argv[]) {
+//     MyCodeGenerator generator;
+//     return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+//   }
+// You must link your plugin against libprotobuf and libprotoc.
+//
+// To get protoc to use the plugin, do one of the following:
+// * Place the plugin binary somewhere in the PATH and give it the name
+//   "protoc-gen-NAME" (replacing "NAME" with the name of your plugin).  If you
+//   then invoke protoc with the parameter --NAME_out=OUT_DIR (again, replace
+//   "NAME" with your plugin's name), protoc will invoke your plugin to generate
+//   the output, which will be placed in OUT_DIR.
+// * Place the plugin binary anywhere, with any name, and pass the --plugin
+//   parameter to protoc to direct it to your plugin like so:
+//     protoc --plugin=protoc-gen-NAME=path/to/mybinary --NAME_out=OUT_DIR
+//   On Windows, make sure to include the .exe suffix:
+//     protoc --plugin=protoc-gen-NAME=path/to/mybinary.exe --NAME_out=OUT_DIR
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
+#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
+
+#include <google/protobuf/stubs/common.h>
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+class CodeGenerator;    // code_generator.h
+
+// Implements main() for a protoc plugin exposing the given code generator.
+LIBPROTOC_EXPORT int PluginMain(int argc, char* argv[], const CodeGenerator* generator);
+
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
diff --git a/protobuf/src/google/protobuf/compiler/plugin.pb.cc b/protobuf/src/google/protobuf/compiler/plugin.pb.cc
new file mode 100644
index 0000000..b5cd01b
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/plugin.pb.cc
@@ -0,0 +1,1148 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/compiler/plugin.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "google/protobuf/compiler/plugin.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+namespace {
+
+const ::google::protobuf::Descriptor* CodeGeneratorRequest_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  CodeGeneratorRequest_reflection_ = NULL;
+const ::google::protobuf::Descriptor* CodeGeneratorResponse_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  CodeGeneratorResponse_reflection_ = NULL;
+const ::google::protobuf::Descriptor* CodeGeneratorResponse_File_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  CodeGeneratorResponse_File_reflection_ = NULL;
+
+}  // namespace
+
+
+void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
+  protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  const ::google::protobuf::FileDescriptor* file =
+    ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+      "google/protobuf/compiler/plugin.proto");
+  GOOGLE_CHECK(file != NULL);
+  CodeGeneratorRequest_descriptor_ = file->message_type(0);
+  static const int CodeGeneratorRequest_offsets_[3] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, file_to_generate_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, parameter_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, proto_file_),
+  };
+  CodeGeneratorRequest_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      CodeGeneratorRequest_descriptor_,
+      CodeGeneratorRequest::default_instance_,
+      CodeGeneratorRequest_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(CodeGeneratorRequest));
+  CodeGeneratorResponse_descriptor_ = file->message_type(1);
+  static const int CodeGeneratorResponse_offsets_[2] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, error_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, file_),
+  };
+  CodeGeneratorResponse_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      CodeGeneratorResponse_descriptor_,
+      CodeGeneratorResponse::default_instance_,
+      CodeGeneratorResponse_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(CodeGeneratorResponse));
+  CodeGeneratorResponse_File_descriptor_ = CodeGeneratorResponse_descriptor_->nested_type(0);
+  static const int CodeGeneratorResponse_File_offsets_[3] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, name_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, insertion_point_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, content_),
+  };
+  CodeGeneratorResponse_File_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      CodeGeneratorResponse_File_descriptor_,
+      CodeGeneratorResponse_File::default_instance_,
+      CodeGeneratorResponse_File_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(CodeGeneratorResponse_File));
+}
+
+namespace {
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
+inline void protobuf_AssignDescriptorsOnce() {
+  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
+                 &protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    CodeGeneratorRequest_descriptor_, &CodeGeneratorRequest::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    CodeGeneratorResponse_descriptor_, &CodeGeneratorResponse::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    CodeGeneratorResponse_File_descriptor_, &CodeGeneratorResponse_File::default_instance());
+}
+
+}  // namespace
+
+void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
+  delete CodeGeneratorRequest::default_instance_;
+  delete CodeGeneratorRequest_reflection_;
+  delete CodeGeneratorResponse::default_instance_;
+  delete CodeGeneratorResponse_reflection_;
+  delete CodeGeneratorResponse_File::default_instance_;
+  delete CodeGeneratorResponse_File_reflection_;
+}
+
+void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
+  static bool already_here = false;
+  if (already_here) return;
+  already_here = true;
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+    "\n%google/protobuf/compiler/plugin.proto\022"
+    "\030google.protobuf.compiler\032 google/protob"
+    "uf/descriptor.proto\"}\n\024CodeGeneratorRequ"
+    "est\022\030\n\020file_to_generate\030\001 \003(\t\022\021\n\tparamet"
+    "er\030\002 \001(\t\0228\n\nproto_file\030\017 \003(\0132$.google.pr"
+    "otobuf.FileDescriptorProto\"\252\001\n\025CodeGener"
+    "atorResponse\022\r\n\005error\030\001 \001(\t\022B\n\004file\030\017 \003("
+    "\01324.google.protobuf.compiler.CodeGenerat"
+    "orResponse.File\032>\n\004File\022\014\n\004name\030\001 \001(\t\022\027\n"
+    "\017insertion_point\030\002 \001(\t\022\017\n\007content\030\017 \001(\tB"
+    ",\n\034com.google.protobuf.compilerB\014PluginP"
+    "rotos", 445);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+    "google/protobuf/compiler/plugin.proto", &protobuf_RegisterTypes);
+  CodeGeneratorRequest::default_instance_ = new CodeGeneratorRequest();
+  CodeGeneratorResponse::default_instance_ = new CodeGeneratorResponse();
+  CodeGeneratorResponse_File::default_instance_ = new CodeGeneratorResponse_File();
+  CodeGeneratorRequest::default_instance_->InitAsDefaultInstance();
+  CodeGeneratorResponse::default_instance_->InitAsDefaultInstance();
+  CodeGeneratorResponse_File::default_instance_->InitAsDefaultInstance();
+  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto {
+  StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
+    protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  }
+} static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_;
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int CodeGeneratorRequest::kFileToGenerateFieldNumber;
+const int CodeGeneratorRequest::kParameterFieldNumber;
+const int CodeGeneratorRequest::kProtoFileFieldNumber;
+#endif  // !_MSC_VER
+
+CodeGeneratorRequest::CodeGeneratorRequest()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorRequest)
+}
+
+void CodeGeneratorRequest::InitAsDefaultInstance() {
+}
+
+CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorRequest)
+}
+
+void CodeGeneratorRequest::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+CodeGeneratorRequest::~CodeGeneratorRequest() {
+  // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorRequest)
+  SharedDtor();
+}
+
+void CodeGeneratorRequest::SharedDtor() {
+  if (parameter_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete parameter_;
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void CodeGeneratorRequest::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return CodeGeneratorRequest_descriptor_;
+}
+
+const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  return *default_instance_;
+}
+
+CodeGeneratorRequest* CodeGeneratorRequest::default_instance_ = NULL;
+
+CodeGeneratorRequest* CodeGeneratorRequest::New() const {
+  return new CodeGeneratorRequest;
+}
+
+void CodeGeneratorRequest::Clear() {
+  if (has_parameter()) {
+    if (parameter_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+      parameter_->clear();
+    }
+  }
+  file_to_generate_.Clear();
+  proto_file_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool CodeGeneratorRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorRequest)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated string file_to_generate = 1;
+      case 1: {
+        if (tag == 10) {
+         parse_file_to_generate:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->add_file_to_generate()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->file_to_generate(this->file_to_generate_size() - 1).data(),
+            this->file_to_generate(this->file_to_generate_size() - 1).length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "file_to_generate");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(10)) goto parse_file_to_generate;
+        if (input->ExpectTag(18)) goto parse_parameter;
+        break;
+      }
+
+      // optional string parameter = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_parameter:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_parameter()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->parameter().data(), this->parameter().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "parameter");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(122)) goto parse_proto_file;
+        break;
+      }
+
+      // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+      case 15: {
+        if (tag == 122) {
+         parse_proto_file:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_proto_file()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(122)) goto parse_proto_file;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.compiler.CodeGeneratorRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.CodeGeneratorRequest)
+  return false;
+#undef DO_
+}
+
+void CodeGeneratorRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorRequest)
+  // repeated string file_to_generate = 1;
+  for (int i = 0; i < this->file_to_generate_size(); i++) {
+  ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+    this->file_to_generate(i).data(), this->file_to_generate(i).length(),
+    ::google::protobuf::internal::WireFormat::SERIALIZE,
+    "file_to_generate");
+    ::google::protobuf::internal::WireFormatLite::WriteString(
+      1, this->file_to_generate(i), output);
+  }
+
+  // optional string parameter = 2;
+  if (has_parameter()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->parameter().data(), this->parameter().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "parameter");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->parameter(), output);
+  }
+
+  // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+  for (int i = 0; i < this->proto_file_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      15, this->proto_file(i), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorRequest)
+}
+
+::google::protobuf::uint8* CodeGeneratorRequest::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorRequest)
+  // repeated string file_to_generate = 1;
+  for (int i = 0; i < this->file_to_generate_size(); i++) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->file_to_generate(i).data(), this->file_to_generate(i).length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "file_to_generate");
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteStringToArray(1, this->file_to_generate(i), target);
+  }
+
+  // optional string parameter = 2;
+  if (has_parameter()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->parameter().data(), this->parameter().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "parameter");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->parameter(), target);
+  }
+
+  // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+  for (int i = 0; i < this->proto_file_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        15, this->proto_file(i), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorRequest)
+  return target;
+}
+
+int CodeGeneratorRequest::ByteSize() const {
+  int total_size = 0;
+
+  if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+    // optional string parameter = 2;
+    if (has_parameter()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->parameter());
+    }
+
+  }
+  // repeated string file_to_generate = 1;
+  total_size += 1 * this->file_to_generate_size();
+  for (int i = 0; i < this->file_to_generate_size(); i++) {
+    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
+      this->file_to_generate(i));
+  }
+
+  // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+  total_size += 1 * this->proto_file_size();
+  for (int i = 0; i < this->proto_file_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->proto_file(i));
+  }
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const CodeGeneratorRequest* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorRequest*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  file_to_generate_.MergeFrom(from.file_to_generate_);
+  proto_file_.MergeFrom(from.proto_file_);
+  if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+    if (from.has_parameter()) {
+      set_parameter(from.parameter());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void CodeGeneratorRequest::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void CodeGeneratorRequest::CopyFrom(const CodeGeneratorRequest& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool CodeGeneratorRequest::IsInitialized() const {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->proto_file())) return false;
+  return true;
+}
+
+void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) {
+  if (other != this) {
+    file_to_generate_.Swap(&other->file_to_generate_);
+    std::swap(parameter_, other->parameter_);
+    proto_file_.Swap(&other->proto_file_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = CodeGeneratorRequest_descriptor_;
+  metadata.reflection = CodeGeneratorRequest_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int CodeGeneratorResponse_File::kNameFieldNumber;
+const int CodeGeneratorResponse_File::kInsertionPointFieldNumber;
+const int CodeGeneratorResponse_File::kContentFieldNumber;
+#endif  // !_MSC_VER
+
+CodeGeneratorResponse_File::CodeGeneratorResponse_File()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
+}
+
+void CodeGeneratorResponse_File::InitAsDefaultInstance() {
+}
+
+CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse.File)
+}
+
+void CodeGeneratorResponse_File::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  content_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+CodeGeneratorResponse_File::~CodeGeneratorResponse_File() {
+  // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse.File)
+  SharedDtor();
+}
+
+void CodeGeneratorResponse_File::SharedDtor() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (insertion_point_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete insertion_point_;
+  }
+  if (content_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete content_;
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void CodeGeneratorResponse_File::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return CodeGeneratorResponse_File_descriptor_;
+}
+
+const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  return *default_instance_;
+}
+
+CodeGeneratorResponse_File* CodeGeneratorResponse_File::default_instance_ = NULL;
+
+CodeGeneratorResponse_File* CodeGeneratorResponse_File::New() const {
+  return new CodeGeneratorResponse_File;
+}
+
+void CodeGeneratorResponse_File::Clear() {
+  if (_has_bits_[0 / 32] & 7) {
+    if (has_name()) {
+      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        name_->clear();
+      }
+    }
+    if (has_insertion_point()) {
+      if (insertion_point_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        insertion_point_->clear();
+      }
+    }
+    if (has_content()) {
+      if (content_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        content_->clear();
+      }
+    }
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool CodeGeneratorResponse_File::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_insertion_point;
+        break;
+      }
+
+      // optional string insertion_point = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_insertion_point:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_insertion_point()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->insertion_point().data(), this->insertion_point().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "insertion_point");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(122)) goto parse_content;
+        break;
+      }
+
+      // optional string content = 15;
+      case 15: {
+        if (tag == 122) {
+         parse_content:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_content()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->content().data(), this->content().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "content");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.compiler.CodeGeneratorResponse.File)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.CodeGeneratorResponse.File)
+  return false;
+#undef DO_
+}
+
+void CodeGeneratorResponse_File::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // optional string insertion_point = 2;
+  if (has_insertion_point()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->insertion_point().data(), this->insertion_point().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "insertion_point");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->insertion_point(), output);
+  }
+
+  // optional string content = 15;
+  if (has_content()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->content().data(), this->content().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "content");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      15, this->content(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse.File)
+}
+
+::google::protobuf::uint8* CodeGeneratorResponse_File::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse.File)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // optional string insertion_point = 2;
+  if (has_insertion_point()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->insertion_point().data(), this->insertion_point().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "insertion_point");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->insertion_point(), target);
+  }
+
+  // optional string content = 15;
+  if (has_content()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->content().data(), this->content().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "content");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        15, this->content(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse.File)
+  return target;
+}
+
+int CodeGeneratorResponse_File::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::WireFormatLite::StringSize(
+          this->name());
+    }
+
+    // optional string insertion_point = 2;
+    if (has_insertion_point()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->insertion_point());
+    }
+
+    // optional string content = 15;
+    if (has_content()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->content());
+    }
+
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const CodeGeneratorResponse_File* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorResponse_File*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_name()) {
+      set_name(from.name());
+    }
+    if (from.has_insertion_point()) {
+      set_insertion_point(from.insertion_point());
+    }
+    if (from.has_content()) {
+      set_content(from.content());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void CodeGeneratorResponse_File::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void CodeGeneratorResponse_File::CopyFrom(const CodeGeneratorResponse_File& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool CodeGeneratorResponse_File::IsInitialized() const {
+
+  return true;
+}
+
+void CodeGeneratorResponse_File::Swap(CodeGeneratorResponse_File* other) {
+  if (other != this) {
+    std::swap(name_, other->name_);
+    std::swap(insertion_point_, other->insertion_point_);
+    std::swap(content_, other->content_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = CodeGeneratorResponse_File_descriptor_;
+  metadata.reflection = CodeGeneratorResponse_File_reflection_;
+  return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int CodeGeneratorResponse::kErrorFieldNumber;
+const int CodeGeneratorResponse::kFileFieldNumber;
+#endif  // !_MSC_VER
+
+CodeGeneratorResponse::CodeGeneratorResponse()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse)
+}
+
+void CodeGeneratorResponse::InitAsDefaultInstance() {
+}
+
+CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.CodeGeneratorResponse)
+}
+
+void CodeGeneratorResponse::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  error_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+CodeGeneratorResponse::~CodeGeneratorResponse() {
+  // @@protoc_insertion_point(destructor:google.protobuf.compiler.CodeGeneratorResponse)
+  SharedDtor();
+}
+
+void CodeGeneratorResponse::SharedDtor() {
+  if (error_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete error_;
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void CodeGeneratorResponse::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return CodeGeneratorResponse_descriptor_;
+}
+
+const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  return *default_instance_;
+}
+
+CodeGeneratorResponse* CodeGeneratorResponse::default_instance_ = NULL;
+
+CodeGeneratorResponse* CodeGeneratorResponse::New() const {
+  return new CodeGeneratorResponse;
+}
+
+void CodeGeneratorResponse::Clear() {
+  if (has_error()) {
+    if (error_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+      error_->clear();
+    }
+  }
+  file_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool CodeGeneratorResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.compiler.CodeGeneratorResponse)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string error = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_error()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->error().data(), this->error().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "error");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(122)) goto parse_file;
+        break;
+      }
+
+      // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+      case 15: {
+        if (tag == 122) {
+         parse_file:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_file()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(122)) goto parse_file;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.compiler.CodeGeneratorResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.CodeGeneratorResponse)
+  return false;
+#undef DO_
+}
+
+void CodeGeneratorResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorResponse)
+  // optional string error = 1;
+  if (has_error()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->error().data(), this->error().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "error");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->error(), output);
+  }
+
+  // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+  for (int i = 0; i < this->file_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      15, this->file(i), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.CodeGeneratorResponse)
+}
+
+::google::protobuf::uint8* CodeGeneratorResponse::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse)
+  // optional string error = 1;
+  if (has_error()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->error().data(), this->error().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "error");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->error(), target);
+  }
+
+  // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+  for (int i = 0; i < this->file_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        15, this->file(i), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.CodeGeneratorResponse)
+  return target;
+}
+
+int CodeGeneratorResponse::ByteSize() const {
+  int total_size = 0;
+
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional string error = 1;
+    if (has_error()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->error());
+    }
+
+  }
+  // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+  total_size += 1 * this->file_size();
+  for (int i = 0; i < this->file_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->file(i));
+  }
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const CodeGeneratorResponse* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorResponse*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  file_.MergeFrom(from.file_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_error()) {
+      set_error(from.error());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void CodeGeneratorResponse::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void CodeGeneratorResponse::CopyFrom(const CodeGeneratorResponse& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool CodeGeneratorResponse::IsInitialized() const {
+
+  return true;
+}
+
+void CodeGeneratorResponse::Swap(CodeGeneratorResponse* other) {
+  if (other != this) {
+    std::swap(error_, other->error_);
+    file_.Swap(&other->file_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = CodeGeneratorResponse_descriptor_;
+  metadata.reflection = CodeGeneratorResponse_reflection_;
+  return metadata;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
diff --git a/protobuf/src/google/protobuf/compiler/plugin.pb.h b/protobuf/src/google/protobuf/compiler/plugin.pb.h
new file mode 100644
index 0000000..65634da
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/plugin.pb.h
@@ -0,0 +1,897 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/compiler/plugin.proto
+
+#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED
+#define PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 2006000
+#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 2006001 < 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_util.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/unknown_field_set.h>
+#include "google/protobuf/descriptor.pb.h"
+// @@protoc_insertion_point(includes)
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+// Internal implementation detail -- do not call these.
+void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+
+class CodeGeneratorRequest;
+class CodeGeneratorResponse;
+class CodeGeneratorResponse_File;
+
+// ===================================================================
+
+class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message {
+ public:
+  CodeGeneratorRequest();
+  virtual ~CodeGeneratorRequest();
+
+  CodeGeneratorRequest(const CodeGeneratorRequest& from);
+
+  inline CodeGeneratorRequest& operator=(const CodeGeneratorRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const CodeGeneratorRequest& default_instance();
+
+  void Swap(CodeGeneratorRequest* other);
+
+  // implements Message ----------------------------------------------
+
+  CodeGeneratorRequest* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const CodeGeneratorRequest& from);
+  void MergeFrom(const CodeGeneratorRequest& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated string file_to_generate = 1;
+  inline int file_to_generate_size() const;
+  inline void clear_file_to_generate();
+  static const int kFileToGenerateFieldNumber = 1;
+  inline const ::std::string& file_to_generate(int index) const;
+  inline ::std::string* mutable_file_to_generate(int index);
+  inline void set_file_to_generate(int index, const ::std::string& value);
+  inline void set_file_to_generate(int index, const char* value);
+  inline void set_file_to_generate(int index, const char* value, size_t size);
+  inline ::std::string* add_file_to_generate();
+  inline void add_file_to_generate(const ::std::string& value);
+  inline void add_file_to_generate(const char* value);
+  inline void add_file_to_generate(const char* value, size_t size);
+  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const;
+  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_to_generate();
+
+  // optional string parameter = 2;
+  inline bool has_parameter() const;
+  inline void clear_parameter();
+  static const int kParameterFieldNumber = 2;
+  inline const ::std::string& parameter() const;
+  inline void set_parameter(const ::std::string& value);
+  inline void set_parameter(const char* value);
+  inline void set_parameter(const char* value, size_t size);
+  inline ::std::string* mutable_parameter();
+  inline ::std::string* release_parameter();
+  inline void set_allocated_parameter(::std::string* parameter);
+
+  // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+  inline int proto_file_size() const;
+  inline void clear_proto_file();
+  static const int kProtoFileFieldNumber = 15;
+  inline const ::google::protobuf::FileDescriptorProto& proto_file(int index) const;
+  inline ::google::protobuf::FileDescriptorProto* mutable_proto_file(int index);
+  inline ::google::protobuf::FileDescriptorProto* add_proto_file();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+      proto_file() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+      mutable_proto_file();
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
+ private:
+  inline void set_has_parameter();
+  inline void clear_has_parameter();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::std::string> file_to_generate_;
+  ::std::string* parameter_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > proto_file_;
+  friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+
+  void InitAsDefaultInstance();
+  static CodeGeneratorRequest* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::Message {
+ public:
+  CodeGeneratorResponse_File();
+  virtual ~CodeGeneratorResponse_File();
+
+  CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from);
+
+  inline CodeGeneratorResponse_File& operator=(const CodeGeneratorResponse_File& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const CodeGeneratorResponse_File& default_instance();
+
+  void Swap(CodeGeneratorResponse_File* other);
+
+  // implements Message ----------------------------------------------
+
+  CodeGeneratorResponse_File* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const CodeGeneratorResponse_File& from);
+  void MergeFrom(const CodeGeneratorResponse_File& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  static const int kNameFieldNumber = 1;
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline void set_name(const char* value, size_t size);
+  inline ::std::string* mutable_name();
+  inline ::std::string* release_name();
+  inline void set_allocated_name(::std::string* name);
+
+  // optional string insertion_point = 2;
+  inline bool has_insertion_point() const;
+  inline void clear_insertion_point();
+  static const int kInsertionPointFieldNumber = 2;
+  inline const ::std::string& insertion_point() const;
+  inline void set_insertion_point(const ::std::string& value);
+  inline void set_insertion_point(const char* value);
+  inline void set_insertion_point(const char* value, size_t size);
+  inline ::std::string* mutable_insertion_point();
+  inline ::std::string* release_insertion_point();
+  inline void set_allocated_insertion_point(::std::string* insertion_point);
+
+  // optional string content = 15;
+  inline bool has_content() const;
+  inline void clear_content();
+  static const int kContentFieldNumber = 15;
+  inline const ::std::string& content() const;
+  inline void set_content(const ::std::string& value);
+  inline void set_content(const char* value);
+  inline void set_content(const char* value, size_t size);
+  inline ::std::string* mutable_content();
+  inline ::std::string* release_content();
+  inline void set_allocated_content(::std::string* content);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse.File)
+ private:
+  inline void set_has_name();
+  inline void clear_has_name();
+  inline void set_has_insertion_point();
+  inline void clear_has_insertion_point();
+  inline void set_has_content();
+  inline void clear_has_content();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* name_;
+  ::std::string* insertion_point_;
+  ::std::string* content_;
+  friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+
+  void InitAsDefaultInstance();
+  static CodeGeneratorResponse_File* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Message {
+ public:
+  CodeGeneratorResponse();
+  virtual ~CodeGeneratorResponse();
+
+  CodeGeneratorResponse(const CodeGeneratorResponse& from);
+
+  inline CodeGeneratorResponse& operator=(const CodeGeneratorResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const CodeGeneratorResponse& default_instance();
+
+  void Swap(CodeGeneratorResponse* other);
+
+  // implements Message ----------------------------------------------
+
+  CodeGeneratorResponse* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const CodeGeneratorResponse& from);
+  void MergeFrom(const CodeGeneratorResponse& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  typedef CodeGeneratorResponse_File File;
+
+  // accessors -------------------------------------------------------
+
+  // optional string error = 1;
+  inline bool has_error() const;
+  inline void clear_error();
+  static const int kErrorFieldNumber = 1;
+  inline const ::std::string& error() const;
+  inline void set_error(const ::std::string& value);
+  inline void set_error(const char* value);
+  inline void set_error(const char* value, size_t size);
+  inline ::std::string* mutable_error();
+  inline ::std::string* release_error();
+  inline void set_allocated_error(::std::string* error);
+
+  // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+  inline int file_size() const;
+  inline void clear_file();
+  static const int kFileFieldNumber = 15;
+  inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const;
+  inline ::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index);
+  inline ::google::protobuf::compiler::CodeGeneratorResponse_File* add_file();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+      file() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
+      mutable_file();
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
+ private:
+  inline void set_has_error();
+  inline void clear_has_error();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* error_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File > file_;
+  friend void LIBPROTOC_EXPORT protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
+
+  void InitAsDefaultInstance();
+  static CodeGeneratorResponse* default_instance_;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+// CodeGeneratorRequest
+
+// repeated string file_to_generate = 1;
+inline int CodeGeneratorRequest::file_to_generate_size() const {
+  return file_to_generate_.size();
+}
+inline void CodeGeneratorRequest::clear_file_to_generate() {
+  file_to_generate_.Clear();
+}
+inline const ::std::string& CodeGeneratorRequest::file_to_generate(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  return file_to_generate_.Get(index);
+}
+inline ::std::string* CodeGeneratorRequest::mutable_file_to_generate(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  return file_to_generate_.Mutable(index);
+}
+inline void CodeGeneratorRequest::set_file_to_generate(int index, const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  file_to_generate_.Mutable(index)->assign(value);
+}
+inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
+  file_to_generate_.Mutable(index)->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value, size_t size) {
+  file_to_generate_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline ::std::string* CodeGeneratorRequest::add_file_to_generate() {
+  return file_to_generate_.Add();
+}
+inline void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) {
+  file_to_generate_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline void CodeGeneratorRequest::add_file_to_generate(const char* value) {
+  file_to_generate_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline void CodeGeneratorRequest::add_file_to_generate(const char* value, size_t size) {
+  file_to_generate_.Add()->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_add_pointer:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+CodeGeneratorRequest::file_to_generate() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  return file_to_generate_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+CodeGeneratorRequest::mutable_file_to_generate() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  return &file_to_generate_;
+}
+
+// optional string parameter = 2;
+inline bool CodeGeneratorRequest::has_parameter() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void CodeGeneratorRequest::set_has_parameter() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void CodeGeneratorRequest::clear_has_parameter() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void CodeGeneratorRequest::clear_parameter() {
+  if (parameter_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    parameter_->clear();
+  }
+  clear_has_parameter();
+}
+inline const ::std::string& CodeGeneratorRequest::parameter() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+  return *parameter_;
+}
+inline void CodeGeneratorRequest::set_parameter(const ::std::string& value) {
+  set_has_parameter();
+  if (parameter_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    parameter_ = new ::std::string;
+  }
+  parameter_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
+inline void CodeGeneratorRequest::set_parameter(const char* value) {
+  set_has_parameter();
+  if (parameter_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    parameter_ = new ::std::string;
+  }
+  parameter_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
+inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) {
+  set_has_parameter();
+  if (parameter_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    parameter_ = new ::std::string;
+  }
+  parameter_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
+inline ::std::string* CodeGeneratorRequest::mutable_parameter() {
+  set_has_parameter();
+  if (parameter_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    parameter_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+  return parameter_;
+}
+inline ::std::string* CodeGeneratorRequest::release_parameter() {
+  clear_has_parameter();
+  if (parameter_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = parameter_;
+    parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void CodeGeneratorRequest::set_allocated_parameter(::std::string* parameter) {
+  if (parameter_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete parameter_;
+  }
+  if (parameter) {
+    set_has_parameter();
+    parameter_ = parameter;
+  } else {
+    clear_has_parameter();
+    parameter_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorRequest.parameter)
+}
+
+// repeated .google.protobuf.FileDescriptorProto proto_file = 15;
+inline int CodeGeneratorRequest::proto_file_size() const {
+  return proto_file_.size();
+}
+inline void CodeGeneratorRequest::clear_proto_file() {
+  proto_file_.Clear();
+}
+inline const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+  return proto_file_.Get(index);
+}
+inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+  return proto_file_.Mutable(index);
+}
+inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+  return proto_file_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+CodeGeneratorRequest::proto_file() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+  return proto_file_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+CodeGeneratorRequest::mutable_proto_file() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+  return &proto_file_;
+}
+
+// -------------------------------------------------------------------
+
+// CodeGeneratorResponse_File
+
+// optional string name = 1;
+inline bool CodeGeneratorResponse_File::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void CodeGeneratorResponse_File::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void CodeGeneratorResponse_File::clear_name() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_->clear();
+  }
+  clear_has_name();
+}
+inline const ::std::string& CodeGeneratorResponse_File::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+  return *name_;
+}
+inline void CodeGeneratorResponse_File::set_name(const ::std::string& value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
+inline void CodeGeneratorResponse_File::set_name(const char* value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
+inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
+inline ::std::string* CodeGeneratorResponse_File::mutable_name() {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+  return name_;
+}
+inline ::std::string* CodeGeneratorResponse_File::release_name() {
+  clear_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = name_;
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void CodeGeneratorResponse_File::set_allocated_name(::std::string* name) {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (name) {
+    set_has_name();
+    name_ = name;
+  } else {
+    clear_has_name();
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.name)
+}
+
+// optional string insertion_point = 2;
+inline bool CodeGeneratorResponse_File::has_insertion_point() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_insertion_point() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void CodeGeneratorResponse_File::clear_has_insertion_point() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void CodeGeneratorResponse_File::clear_insertion_point() {
+  if (insertion_point_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    insertion_point_->clear();
+  }
+  clear_has_insertion_point();
+}
+inline const ::std::string& CodeGeneratorResponse_File::insertion_point() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+  return *insertion_point_;
+}
+inline void CodeGeneratorResponse_File::set_insertion_point(const ::std::string& value) {
+  set_has_insertion_point();
+  if (insertion_point_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    insertion_point_ = new ::std::string;
+  }
+  insertion_point_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
+inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) {
+  set_has_insertion_point();
+  if (insertion_point_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    insertion_point_ = new ::std::string;
+  }
+  insertion_point_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
+inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) {
+  set_has_insertion_point();
+  if (insertion_point_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    insertion_point_ = new ::std::string;
+  }
+  insertion_point_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
+inline ::std::string* CodeGeneratorResponse_File::mutable_insertion_point() {
+  set_has_insertion_point();
+  if (insertion_point_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    insertion_point_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+  return insertion_point_;
+}
+inline ::std::string* CodeGeneratorResponse_File::release_insertion_point() {
+  clear_has_insertion_point();
+  if (insertion_point_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = insertion_point_;
+    insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void CodeGeneratorResponse_File::set_allocated_insertion_point(::std::string* insertion_point) {
+  if (insertion_point_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete insertion_point_;
+  }
+  if (insertion_point) {
+    set_has_insertion_point();
+    insertion_point_ = insertion_point;
+  } else {
+    clear_has_insertion_point();
+    insertion_point_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point)
+}
+
+// optional string content = 15;
+inline bool CodeGeneratorResponse_File::has_content() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void CodeGeneratorResponse_File::set_has_content() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void CodeGeneratorResponse_File::clear_has_content() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void CodeGeneratorResponse_File::clear_content() {
+  if (content_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    content_->clear();
+  }
+  clear_has_content();
+}
+inline const ::std::string& CodeGeneratorResponse_File::content() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+  return *content_;
+}
+inline void CodeGeneratorResponse_File::set_content(const ::std::string& value) {
+  set_has_content();
+  if (content_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    content_ = new ::std::string;
+  }
+  content_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
+inline void CodeGeneratorResponse_File::set_content(const char* value) {
+  set_has_content();
+  if (content_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    content_ = new ::std::string;
+  }
+  content_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
+inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) {
+  set_has_content();
+  if (content_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    content_ = new ::std::string;
+  }
+  content_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
+inline ::std::string* CodeGeneratorResponse_File::mutable_content() {
+  set_has_content();
+  if (content_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    content_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+  return content_;
+}
+inline ::std::string* CodeGeneratorResponse_File::release_content() {
+  clear_has_content();
+  if (content_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = content_;
+    content_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void CodeGeneratorResponse_File::set_allocated_content(::std::string* content) {
+  if (content_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete content_;
+  }
+  if (content) {
+    set_has_content();
+    content_ = content;
+  } else {
+    clear_has_content();
+    content_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.File.content)
+}
+
+// -------------------------------------------------------------------
+
+// CodeGeneratorResponse
+
+// optional string error = 1;
+inline bool CodeGeneratorResponse::has_error() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void CodeGeneratorResponse::set_has_error() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void CodeGeneratorResponse::clear_has_error() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void CodeGeneratorResponse::clear_error() {
+  if (error_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    error_->clear();
+  }
+  clear_has_error();
+}
+inline const ::std::string& CodeGeneratorResponse::error() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.error)
+  return *error_;
+}
+inline void CodeGeneratorResponse::set_error(const ::std::string& value) {
+  set_has_error();
+  if (error_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    error_ = new ::std::string;
+  }
+  error_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
+inline void CodeGeneratorResponse::set_error(const char* value) {
+  set_has_error();
+  if (error_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    error_ = new ::std::string;
+  }
+  error_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
+inline void CodeGeneratorResponse::set_error(const char* value, size_t size) {
+  set_has_error();
+  if (error_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    error_ = new ::std::string;
+  }
+  error_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
+inline ::std::string* CodeGeneratorResponse::mutable_error() {
+  set_has_error();
+  if (error_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    error_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.error)
+  return error_;
+}
+inline ::std::string* CodeGeneratorResponse::release_error() {
+  clear_has_error();
+  if (error_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = error_;
+    error_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void CodeGeneratorResponse::set_allocated_error(::std::string* error) {
+  if (error_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete error_;
+  }
+  if (error) {
+    set_has_error();
+    error_ = error;
+  } else {
+    clear_has_error();
+    error_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.CodeGeneratorResponse.error)
+}
+
+// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15;
+inline int CodeGeneratorResponse::file_size() const {
+  return file_.size();
+}
+inline void CodeGeneratorResponse::clear_file() {
+  file_.Clear();
+}
+inline const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.file)
+  return file_.Get(index);
+}
+inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file)
+  return file_.Mutable(index);
+}
+inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file)
+  return file_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+CodeGeneratorResponse::file() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
+  return file_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
+CodeGeneratorResponse::mutable_file() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file)
+  return &file_;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
+
+#ifndef SWIG
+namespace google {
+namespace protobuf {
+
+
+}  // namespace google
+}  // namespace protobuf
+#endif  // SWIG
+
+// @@protoc_insertion_point(global_scope)
+
+#endif  // PROTOBUF_google_2fprotobuf_2fcompiler_2fplugin_2eproto__INCLUDED
diff --git a/protobuf/src/google/protobuf/compiler/plugin.proto b/protobuf/src/google/protobuf/compiler/plugin.proto
new file mode 100644
index 0000000..b65379d
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/plugin.proto
@@ -0,0 +1,147 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// WARNING:  The plugin interface is currently EXPERIMENTAL and is subject to
+//   change.
+//
+// protoc (aka the Protocol Compiler) can be extended via plugins.  A plugin is
+// just a program that reads a CodeGeneratorRequest from stdin and writes a
+// CodeGeneratorResponse to stdout.
+//
+// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
+// of dealing with the raw protocol defined here.
+//
+// A plugin executable needs only to be placed somewhere in the path.  The
+// plugin should be named "protoc-gen-$NAME", and will then be used when the
+// flag "--${NAME}_out" is passed to protoc.
+
+package google.protobuf.compiler;
+option java_package = "com.google.protobuf.compiler";
+option java_outer_classname = "PluginProtos";
+
+import "google/protobuf/descriptor.proto";
+
+// An encoded CodeGeneratorRequest is written to the plugin's stdin.
+message CodeGeneratorRequest {
+  // The .proto files that were explicitly listed on the command-line.  The
+  // code generator should generate code only for these files.  Each file's
+  // descriptor will be included in proto_file, below.
+  repeated string file_to_generate = 1;
+
+  // The generator parameter passed on the command-line.
+  optional string parameter = 2;
+
+  // FileDescriptorProtos for all files in files_to_generate and everything
+  // they import.  The files will appear in topological order, so each file
+  // appears before any file that imports it.
+  //
+  // protoc guarantees that all proto_files will be written after
+  // the fields above, even though this is not technically guaranteed by the
+  // protobuf wire format.  This theoretically could allow a plugin to stream
+  // in the FileDescriptorProtos and handle them one by one rather than read
+  // the entire set into memory at once.  However, as of this writing, this
+  // is not similarly optimized on protoc's end -- it will store all fields in
+  // memory at once before sending them to the plugin.
+  repeated FileDescriptorProto proto_file = 15;
+}
+
+// The plugin writes an encoded CodeGeneratorResponse to stdout.
+message CodeGeneratorResponse {
+  // Error message.  If non-empty, code generation failed.  The plugin process
+  // should exit with status code zero even if it reports an error in this way.
+  //
+  // This should be used to indicate errors in .proto files which prevent the
+  // code generator from generating correct code.  Errors which indicate a
+  // problem in protoc itself -- such as the input CodeGeneratorRequest being
+  // unparseable -- should be reported by writing a message to stderr and
+  // exiting with a non-zero status code.
+  optional string error = 1;
+
+  // Represents a single generated file.
+  message File {
+    // The file name, relative to the output directory.  The name must not
+    // contain "." or ".." components and must be relative, not be absolute (so,
+    // the file cannot lie outside the output directory).  "/" must be used as
+    // the path separator, not "\".
+    //
+    // If the name is omitted, the content will be appended to the previous
+    // file.  This allows the generator to break large files into small chunks,
+    // and allows the generated text to be streamed back to protoc so that large
+    // files need not reside completely in memory at one time.  Note that as of
+    // this writing protoc does not optimize for this -- it will read the entire
+    // CodeGeneratorResponse before writing files to disk.
+    optional string name = 1;
+
+    // If non-empty, indicates that the named file should already exist, and the
+    // content here is to be inserted into that file at a defined insertion
+    // point.  This feature allows a code generator to extend the output
+    // produced by another code generator.  The original generator may provide
+    // insertion points by placing special annotations in the file that look
+    // like:
+    //   @@protoc_insertion_point(NAME)
+    // The annotation can have arbitrary text before and after it on the line,
+    // which allows it to be placed in a comment.  NAME should be replaced with
+    // an identifier naming the point -- this is what other generators will use
+    // as the insertion_point.  Code inserted at this point will be placed
+    // immediately above the line containing the insertion point (thus multiple
+    // insertions to the same point will come out in the order they were added).
+    // The double-@ is intended to make it unlikely that the generated code
+    // could contain things that look like insertion points by accident.
+    //
+    // For example, the C++ code generator places the following line in the
+    // .pb.h files that it generates:
+    //   // @@protoc_insertion_point(namespace_scope)
+    // This line appears within the scope of the file's package namespace, but
+    // outside of any particular class.  Another plugin can then specify the
+    // insertion_point "namespace_scope" to generate additional classes or
+    // other declarations that should be placed in this scope.
+    //
+    // Note that if the line containing the insertion point begins with
+    // whitespace, the same whitespace will be added to every line of the
+    // inserted text.  This is useful for languages like Python, where
+    // indentation matters.  In these languages, the insertion point comment
+    // should be indented the same amount as any inserted code will need to be
+    // in order to work correctly in that context.
+    //
+    // The code generator that generates the initial file and the one which
+    // inserts into it must both run as part of a single invocation of protoc.
+    // Code generators are executed in the order in which they appear on the
+    // command line.
+    //
+    // If |insertion_point| is present, |name| must also be present.
+    optional string insertion_point = 2;
+
+    // The file contents.
+    optional string content = 15;
+  }
+  repeated File file = 15;
+}
diff --git a/protobuf/src/google/protobuf/compiler/python/python_generator.cc b/protobuf/src/google/protobuf/compiler/python/python_generator.cc
new file mode 100644
index 0000000..15e05da
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/python/python_generator.cc
@@ -0,0 +1,1262 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+//#PY25 compatible generated code for GAE.
+// Copyright 2007 Google Inc. All Rights Reserved.
+// 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 <limits>
+#include <map>
+#include <utility>
+#include <memory>
+#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/stubs/stringprintf.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";
+
+
+// Does the file have top-level enums?
+inline bool HasTopLevelEnums(const FileDescriptor *file) {
+  return file->enum_type_count() > 0;
+}
+
+
+// Should we generate generic services for this file?
+inline bool HasGenericServices(const FileDescriptor *file) {
+  return file->service_count() > 0 &&
+         file->options().py_generic_services();
+}
+
+
+// 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(
+      "# Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
+      "# source: $filename$\n"
+      "\nimport sys\n_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))"  //##PY25
+      "\n",
+      "filename", file->name());
+  if (HasTopLevelEnums(file)) {
+    printer->Print(
+        "from google.protobuf.internal import enum_type_wrapper\n");
+  }
+  printer->Print(
+      "from google.protobuf import descriptor as _descriptor\n"
+      "from google.protobuf import message as _message\n"
+      "from google.protobuf import reflection as _reflection\n"
+      "from google.protobuf import symbol_database as "
+      "_symbol_database\n");
+  if (HasGenericServices(file)) {
+    printer->Print(
+        "from google.protobuf import service as _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");
+  }
+  printer->Print(
+      "# @@protoc_insertion_point(imports)\n\n"
+      "_sym_db = _symbol_database.Default()\n");
+  printer->Print("\n\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: {
+      double value = field.default_value_double();
+      if (value == numeric_limits<double>::infinity()) {
+        // Python pre-2.6 on Windows does not parse "inf" correctly.  However,
+        // a numeric literal that is too big for a double will become infinity.
+        return "1e10000";
+      } else if (value == -numeric_limits<double>::infinity()) {
+        // See above.
+        return "-1e10000";
+      } else if (value != value) {
+        // infinity * 0 = nan
+        return "(1e10000 * 0)";
+      } else {
+        return SimpleDtoa(value);
+      }
+    }
+    case FieldDescriptor::CPPTYPE_FLOAT: {
+      float value = field.default_value_float();
+      if (value == numeric_limits<float>::infinity()) {
+        // Python pre-2.6 on Windows does not parse "inf" correctly.  However,
+        // a numeric literal that is too big for a double will become infinity.
+        return "1e10000";
+      } else if (value == -numeric_limits<float>::infinity()) {
+        // See above.
+        return "-1e10000";
+      } else if (value != value) {
+        // infinity - infinity = nan
+        return "(1e10000 * 0)";
+      } else {
+        return SimpleFtoa(value);
+      }
+    }
+    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:
+//##!PY25      return "b\"" + CEscape(field.default_value_string()) +
+//##!PY25             (field.type() != FieldDescriptor::TYPE_STRING ? "\"" :
+//##!PY25               "\".decode('utf-8')");
+      return "_b(\"" + CEscape(field.default_value_string()) +  //##PY25
+             (field.type() != FieldDescriptor::TYPE_STRING ? "\")" :  //##PY25
+               "\").decode('utf-8')");  //##PY25
+    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,
+                         GeneratorContext* context,
+                         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";
+
+  FileDescriptorProto fdp;
+  file_->CopyTo(&fdp);
+  fdp.SerializeToString(&file_descriptor_serialized_);
+
+
+  scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
+  GOOGLE_CHECK(output.get());
+  io::Printer printer(output.get(), '$');
+  printer_ = &printer;
+
+  PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
+  PrintImports();
+  PrintFileDescriptor();
+  PrintTopLevelEnums();
+  PrintTopLevelExtensions();
+  PrintAllNestedEnumsInFile();
+  PrintMessageDescriptors();
+  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();
+  // Descriptor options may have custom extensions. These custom options
+  // can only be successfully parsed after we register corresponding
+  // extensions. Therefore we parse all options again here to recognize
+  // custom options that may be unknown when we define the descriptors.
+  FixAllDescriptorOptions();
+  if (HasGenericServices(file)) {
+    PrintServices();
+  }
+
+  printer.Print(
+    "# @@protoc_insertion_point(module_scope)\n");
+
+  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");
+
+  // Print public imports.
+  for (int i = 0; i < file_->public_dependency_count(); ++i) {
+    string module_name = ModuleName(file_->public_dependency(i)->name());
+    printer_->Print("from $module$ import *\n", "module", module_name);
+  }
+  printer_->Print("\n");
+}
+
+// Prints the single file descriptor for this file.
+void Generator::PrintFileDescriptor() const {
+  map<string, string> m;
+  m["descriptor_name"] = kDescriptorKey;
+  m["name"] = file_->name();
+  m["package"] = file_->package();
+  const char file_descriptor_template[] =
+      "$descriptor_name$ = _descriptor.FileDescriptor(\n"
+      "  name='$name$',\n"
+      "  package='$package$',\n";
+  printer_->Print(m, file_descriptor_template);
+  printer_->Indent();
+  printer_->Print(
+//##!PY25      "serialized_pb=b'$value$'\n",
+      "serialized_pb=_b('$value$')\n",  //##PY25
+      "value", strings::CHexEscape(file_descriptor_serialized_));
+  if (file_->dependency_count() != 0) {
+    printer_->Print(",\ndependencies=[");
+    for (int i = 0; i < file_->dependency_count(); ++i) {
+      string module_name = ModuleName(file_->dependency(i)->name());
+      printer_->Print("$module_name$.DESCRIPTOR,", "module_name", module_name);
+    }
+    printer_->Print("]");
+  }
+
+  // TODO(falk): Also print options and fix the message_type, enum_type,
+  //             service and extension later in the generation.
+
+  printer_->Outdent();
+  printer_->Print(")\n");
+  printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name",
+                  kDescriptorKey);
+  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("$name$ = "
+                    "enum_type_wrapper.EnumTypeWrapper($descriptor_name$)",
+                    "name", enum_descriptor.name(),
+                    "descriptor_name",
+                    ModuleLevelDescriptorName(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;
+  string module_level_descriptor_name =
+      ModuleLevelDescriptorName(enum_descriptor);
+  m["descriptor_name"] = module_level_descriptor_name;
+  m["name"] = enum_descriptor.name();
+  m["full_name"] = enum_descriptor.full_name();
+  m["file"] = kDescriptorKey;
+  const char enum_descriptor_template[] =
+      "$descriptor_name$ = _descriptor.EnumDescriptor(\n"
+      "  name='$name$',\n"
+      "  full_name='$full_name$',\n"
+      "  filename=None,\n"
+      "  file=$file$,\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("containing_type=None,\n");
+  printer_->Print("options=$options_value$,\n",
+                  "options_value",
+                  OptionsValue("EnumOptions", options_string));
+  EnumDescriptorProto edp;
+  PrintSerializedPbInterval(enum_descriptor, edp);
+  printer_->Outdent();
+  printer_->Print(")\n");
+  printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
+                  module_level_descriptor_name);
+  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);
+    string constant_name = extension_field.name() + "_FIELD_NUMBER";
+    UpperString(&constant_name);
+    printer_->Print("$constant_name$ = $number$\n",
+      "constant_name", constant_name,
+      "number", SimpleItoa(extension_field.number()));
+    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["file"] = kDescriptorKey;
+  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"
+      "file=$file$,\n"
+      "index=$index$,\n"
+      "options=$options_value$,\n";
+  printer_->Print(m, required_function_arguments);
+
+  ServiceDescriptorProto sdp;
+  PrintSerializedPbInterval(descriptor, sdp);
+
+  printer_->Print("methods=[\n");
+  for (int i = 0; i < descriptor.method_count(); ++i) {
+    const MethodDescriptor* method = descriptor.method(i);
+    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_name$ = service_reflection.GeneratedServiceType("
+                  "'$class_name$', (_service.Service,), dict(\n",
+                  "class_name", descriptor.name());
+  printer_->Indent();
+  printer_->Print(
+      "$descriptor_key$ = $descriptor_name$,\n",
+      "descriptor_key", kDescriptorKey,
+      "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
+  printer_->Print(
+      "__module__ = '$module_name$'\n",
+      "module_name", ModuleName(file_->name()));
+  printer_->Print("))\n\n");
+  printer_->Outdent();
+}
+
+void Generator::PrintServiceStub(const ServiceDescriptor& descriptor) const {
+  // Print the service stub.
+  printer_->Print("$class_name$_Stub = "
+                  "service_reflection.GeneratedServiceStubType("
+                  "'$class_name$_Stub', ($class_name$,), dict(\n",
+                  "class_name", descriptor.name());
+  printer_->Indent();
+  printer_->Print(
+      "$descriptor_key$ = $descriptor_name$,\n",
+      "descriptor_key", kDescriptorKey,
+      "descriptor_name", ModuleLevelServiceDescriptorName(descriptor));
+  printer_->Print(
+      "__module__ = '$module_name$'\n",
+      "module_name", ModuleName(file_->name()));
+  printer_->Print("))\n\n");
+  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["file"] = kDescriptorKey;
+  const char required_function_arguments[] =
+      "name='$name$',\n"
+      "full_name='$full_name$',\n"
+      "filename=None,\n"
+      "file=$file$,\n"
+      "containing_type=None,\n";
+  printer_->Print(m, required_function_arguments);
+  PrintFieldsInDescriptor(message_descriptor);
+  PrintExtensionsInDescriptor(message_descriptor);
+
+  // Nested types
+  printer_->Print("nested_types=[");
+  for (int i = 0; i < message_descriptor.nested_type_count(); ++i) {
+    const string nested_name = ModuleLevelDescriptorName(
+        *message_descriptor.nested_type(i));
+    printer_->Print("$name$, ", "name", nested_name);
+  }
+  printer_->Print("],\n");
+
+  // Enum types
+  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$,\n"
+      "is_extendable=$extendable$",
+      "options_value", OptionsValue("MessageOptions", options_string),
+      "extendable", message_descriptor.extension_range_count() > 0 ?
+                      "True" : "False");
+  printer_->Print(",\n");
+
+  // Extension ranges
+  printer_->Print("extension_ranges=[");
+  for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
+    const Descriptor::ExtensionRange* range =
+        message_descriptor.extension_range(i);
+    printer_->Print("($start$, $end$), ",
+                    "start", SimpleItoa(range->start),
+                    "end", SimpleItoa(range->end));
+  }
+  printer_->Print("],\n");
+  printer_->Print("oneofs=[\n");
+  printer_->Indent();
+  for (int i = 0; i < message_descriptor.oneof_decl_count(); ++i) {
+    const OneofDescriptor* desc = message_descriptor.oneof_decl(i);
+    map<string, string> m;
+    m["name"] = desc->name();
+    m["full_name"] = desc->full_name();
+    m["index"] = SimpleItoa(desc->index());
+    printer_->Print(
+        m,
+        "_descriptor.OneofDescriptor(\n"
+        "  name='$name$', full_name='$full_name$',\n"
+        "  index=$index$, containing_type=None, fields=[]),\n");
+  }
+  printer_->Outdent();
+  printer_->Print("],\n");
+  // Serialization of proto
+  DescriptorProto edp;
+  PrintSerializedPbInterval(message_descriptor, edp);
+
+  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) {
+    vector<string> to_register;
+    PrintMessage(*file_->message_type(i), "", &to_register);
+    for (int j = 0; j < to_register.size(); ++j) {
+      printer_->Print("_sym_db.RegisterMessage($name$)\n", "name",
+                      to_register[j]);
+    }
+    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().
+// Collect nested message names to_register for the symbol_database.
+void Generator::PrintMessage(const Descriptor& message_descriptor,
+                             const string& prefix,
+                             vector<string>* to_register) const {
+  string qualified_name(prefix + message_descriptor.name());
+  to_register->push_back(qualified_name);
+  printer_->Print(
+      "$name$ = _reflection.GeneratedProtocolMessageType('$name$', "
+      "(_message.Message,), dict(\n",
+      "name", message_descriptor.name());
+  printer_->Indent();
+
+  PrintNestedMessages(message_descriptor, qualified_name + ".", to_register);
+  map<string, string> m;
+  m["descriptor_key"] = kDescriptorKey;
+  m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
+  printer_->Print(m, "$descriptor_key$ = $descriptor_name$,\n");
+  printer_->Print("__module__ = '$module_name$'\n",
+                  "module_name", ModuleName(file_->name()));
+  printer_->Print("# @@protoc_insertion_point(class_scope:$full_name$)\n",
+                  "full_name", message_descriptor.full_name());
+  printer_->Print("))\n");
+  printer_->Outdent();
+}
+
+// Prints all nested messages within |containing_descriptor|.
+// Mutually recursive with PrintMessage().
+void Generator::PrintNestedMessages(const Descriptor& containing_descriptor,
+                                    const string& prefix,
+                                    vector<string>* to_register) const {
+  for (int i = 0; i < containing_descriptor.nested_type_count(); ++i) {
+    printer_->Print("\n");
+    PrintMessage(*containing_descriptor.nested_type(i), prefix, to_register);
+    printer_->Print(",\n");
+  }
+}
+
+// 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.
+// Args:
+//   descriptor: descriptor to print fields for.
+//   containing_descriptor: if descriptor is a nested type, this is its
+//       containing type, or NULL if this is a root/top-level type.
+void Generator::FixForeignFieldsInDescriptor(
+    const Descriptor& descriptor,
+    const Descriptor* containing_descriptor) const {
+  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+    FixForeignFieldsInDescriptor(*descriptor.nested_type(i), &descriptor);
+  }
+
+  for (int i = 0; i < descriptor.field_count(); ++i) {
+    const FieldDescriptor& field_descriptor = *descriptor.field(i);
+    FixForeignFieldsInField(&descriptor, field_descriptor, "fields_by_name");
+  }
+
+  FixContainingTypeInDescriptor(descriptor, containing_descriptor);
+  for (int i = 0; i < descriptor.enum_type_count(); ++i) {
+    const EnumDescriptor& enum_descriptor = *descriptor.enum_type(i);
+    FixContainingTypeInDescriptor(enum_descriptor, &descriptor);
+  }
+  for (int i = 0; i < descriptor.oneof_decl_count(); ++i) {
+    map<string, string> m;
+    const OneofDescriptor* oneof = descriptor.oneof_decl(i);
+    m["descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+    m["oneof_name"] = oneof->name();
+    for (int j = 0; j < oneof->field_count(); ++j) {
+      m["field_name"] = oneof->field(j)->name();
+      printer_->Print(
+          m,
+          "$descriptor_name$.oneofs_by_name['$oneof_name$'].fields.append(\n"
+          "  $descriptor_name$.fields_by_name['$field_name$'])\n");
+      printer_->Print(
+          m,
+          "$descriptor_name$.fields_by_name['$field_name$'].containing_oneof = "
+          "$descriptor_name$.oneofs_by_name['$oneof_name$']\n");
+    }
+  }
+}
+
+void Generator::AddMessageToFileDescriptor(const Descriptor& descriptor) const {
+  map<string, string> m;
+  m["descriptor_name"] = kDescriptorKey;
+  m["message_name"] = descriptor.name();
+  m["message_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+  const char file_descriptor_template[] =
+      "$descriptor_name$.message_types_by_name['$message_name$'] = "
+      "$message_descriptor_name$\n";
+  printer_->Print(m, file_descriptor_template);
+}
+
+void Generator::AddEnumToFileDescriptor(
+    const EnumDescriptor& descriptor) const {
+  map<string, string> m;
+  m["descriptor_name"] = kDescriptorKey;
+  m["enum_name"] = descriptor.name();
+  m["enum_descriptor_name"] = ModuleLevelDescriptorName(descriptor);
+  const char file_descriptor_template[] =
+      "$descriptor_name$.enum_types_by_name['$enum_name$'] = "
+      "$enum_descriptor_name$\n";
+  printer_->Print(m, file_descriptor_template);
+}
+
+void Generator::AddExtensionToFileDescriptor(
+    const FieldDescriptor& descriptor) const {
+  map<string, string> m;
+  m["descriptor_name"] = kDescriptorKey;
+  m["field_name"] = descriptor.name();
+  const char file_descriptor_template[] =
+      "$descriptor_name$.extensions_by_name['$field_name$'] = "
+      "$field_name$\n";
+  printer_->Print(m, file_descriptor_template);
+}
+
+// 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 containing_type for nested descriptors or enum descriptors.
+template <typename DescriptorT>
+void Generator::FixContainingTypeInDescriptor(
+    const DescriptorT& descriptor,
+    const Descriptor* containing_descriptor) const {
+  if (containing_descriptor != NULL) {
+    const string nested_name = ModuleLevelDescriptorName(descriptor);
+    const string parent_name = ModuleLevelDescriptorName(
+        *containing_descriptor);
+    printer_->Print(
+        "$nested_name$.containing_type = $parent_name$\n",
+        "nested_name", nested_name,
+        "parent_name", parent_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), NULL);
+  }
+  for (int i = 0; i < file_->message_type_count(); ++i) {
+    AddMessageToFileDescriptor(*file_->message_type(i));
+  }
+  for (int i = 0; i < file_->enum_type_count(); ++i) {
+    AddEnumToFileDescriptor(*file_->enum_type(i));
+  }
+  for (int i = 0; i < file_->extension_count(); ++i) {
+    AddExtensionToFileDescriptor(*file_->extension(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));
+  }
+  printer_->Print("\n");
+}
+
+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)");
+}
+
+// Returns a Python expression that calls descriptor._ParseOptions using
+// the given descriptor class name and serialized options protobuf string.
+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;
+//##!PY25    return "_descriptor._ParseOptions(" + full_class_name + "(), b'"
+//##!PY25        + CEscape(serialized_options)+ "')";
+    return "_descriptor._ParseOptions(" + full_class_name + "(), _b('"  //##PY25
+        + CEscape(serialized_options)+ "'))";  //##PY25
+  }
+}
+
+// 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["has_default_value"] = field.has_default_value() ? "True" : "False";
+  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"
+    "  has_default_value=$has_default_value$, 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;
+}
+
+// Prints standard constructor arguments serialized_start and serialized_end.
+// Args:
+//   descriptor: The cpp descriptor to have a serialized reference.
+//   proto: A proto
+// Example printer output:
+// serialized_start=41,
+// serialized_end=43,
+//
+template <typename DescriptorT, typename DescriptorProtoT>
+void Generator::PrintSerializedPbInterval(
+    const DescriptorT& descriptor, DescriptorProtoT& proto) const {
+  descriptor.CopyTo(&proto);
+  string sp;
+  proto.SerializeToString(&sp);
+  int offset = file_descriptor_serialized_.find(sp);
+  GOOGLE_CHECK_GE(offset, 0);
+
+  printer_->Print("serialized_start=$serialized_start$,\n"
+                  "serialized_end=$serialized_end$,\n",
+                  "serialized_start", SimpleItoa(offset),
+                  "serialized_end", SimpleItoa(offset + sp.size()));
+}
+
+namespace {
+void PrintDescriptorOptionsFixingCode(const string& descriptor,
+                                      const string& options,
+                                      io::Printer* printer) {
+  // TODO(xiaofeng): I have added a method _SetOptions() to DescriptorBase
+  // in proto2 python runtime but it couldn't be used here because appengine
+  // uses a snapshot version of the library in which the new method is not
+  // yet present. After appengine has synced their runtime library, the code
+  // below should be cleaned up to use _SetOptions().
+  printer->Print(
+      "$descriptor$.has_options = True\n"
+      "$descriptor$._options = $options$\n",
+      "descriptor", descriptor, "options", options);
+}
+}  // namespace
+
+// Prints expressions that set the options field of all descriptors.
+void Generator::FixAllDescriptorOptions() const {
+  // Prints an expression that sets the file descriptor's options.
+  string file_options = OptionsValue(
+      "FileOptions", file_->options().SerializeAsString());
+  if (file_options != "None") {
+    PrintDescriptorOptionsFixingCode(kDescriptorKey, file_options, printer_);
+  }
+  // Prints expressions that set the options for all top level enums.
+  for (int i = 0; i < file_->enum_type_count(); ++i) {
+    const EnumDescriptor& enum_descriptor = *file_->enum_type(i);
+    FixOptionsForEnum(enum_descriptor);
+  }
+  // Prints expressions that set the options for all top level extensions.
+  for (int i = 0; i < file_->extension_count(); ++i) {
+    const FieldDescriptor& field = *file_->extension(i);
+    FixOptionsForField(field);
+  }
+  // Prints expressions that set the options for all messages, nested enums,
+  // nested extensions and message fields.
+  for (int i = 0; i < file_->message_type_count(); ++i) {
+    FixOptionsForMessage(*file_->message_type(i));
+  }
+}
+
+// Prints expressions that set the options for an enum descriptor and its
+// value descriptors.
+void Generator::FixOptionsForEnum(const EnumDescriptor& enum_descriptor) const {
+  string descriptor_name = ModuleLevelDescriptorName(enum_descriptor);
+  string enum_options = OptionsValue(
+      "EnumOptions", enum_descriptor.options().SerializeAsString());
+  if (enum_options != "None") {
+    PrintDescriptorOptionsFixingCode(descriptor_name, enum_options, printer_);
+  }
+  for (int i = 0; i < enum_descriptor.value_count(); ++i) {
+    const EnumValueDescriptor& value_descriptor = *enum_descriptor.value(i);
+    string value_options = OptionsValue(
+        "EnumValueOptions", value_descriptor.options().SerializeAsString());
+    if (value_options != "None") {
+      PrintDescriptorOptionsFixingCode(
+          StringPrintf("%s.values_by_name[\"%s\"]", descriptor_name.c_str(),
+                       value_descriptor.name().c_str()),
+          value_options, printer_);
+    }
+  }
+}
+
+// Prints expressions that set the options for field descriptors (including
+// extensions).
+void Generator::FixOptionsForField(
+    const FieldDescriptor& field) const {
+  string field_options = OptionsValue(
+      "FieldOptions", field.options().SerializeAsString());
+  if (field_options != "None") {
+    string field_name;
+    if (field.is_extension()) {
+      if (field.extension_scope() == NULL) {
+        // Top level extensions.
+        field_name = field.name();
+      } else {
+        field_name = FieldReferencingExpression(
+            field.extension_scope(), field, "extensions_by_name");
+      }
+    } else {
+      field_name = FieldReferencingExpression(
+          field.containing_type(), field, "fields_by_name");
+    }
+    PrintDescriptorOptionsFixingCode(field_name, field_options, printer_);
+  }
+}
+
+// Prints expressions that set the options for a message and all its inner
+// types (nested messages, nested enums, extensions, fields).
+void Generator::FixOptionsForMessage(const Descriptor& descriptor) const {
+  // Nested messages.
+  for (int i = 0; i < descriptor.nested_type_count(); ++i) {
+    FixOptionsForMessage(*descriptor.nested_type(i));
+  }
+  // Enums.
+  for (int i = 0; i < descriptor.enum_type_count(); ++i) {
+    FixOptionsForEnum(*descriptor.enum_type(i));
+  }
+  // Fields.
+  for (int i = 0; i < descriptor.field_count(); ++i) {
+    const FieldDescriptor& field = *descriptor.field(i);
+    FixOptionsForField(field);
+  }
+  // Extensions.
+  for (int i = 0; i < descriptor.extension_count(); ++i) {
+    const FieldDescriptor& field = *descriptor.extension(i);
+    FixOptionsForField(field);
+  }
+  // Message option for this message.
+  string message_options = OptionsValue(
+      "MessageOptions", descriptor.options().SerializeAsString());
+  if (message_options != "None") {
+    string descriptor_name = ModuleLevelDescriptorName(descriptor);
+    PrintDescriptorOptionsFixingCode(descriptor_name,
+                                     message_options,
+                                     printer_);
+  }
+}
+
+}  // namespace python
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/python/python_generator.h b/protobuf/src/google/protobuf/compiler/python/python_generator.h
new file mode 100644
index 0000000..f86e9ea
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/python/python_generator.h
@@ -0,0 +1,166 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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,
+                        GeneratorContext* generator_context,
+                        string* error) const;
+
+ private:
+  void PrintImports() const;
+  void PrintFileDescriptor() 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 string& prefix,
+                    vector<string>* to_register) const;
+  void PrintNestedMessages(const Descriptor& containing_descriptor,
+                           const string& prefix,
+                           vector<string>* to_register) const;
+
+  void FixForeignFieldsInDescriptors() const;
+  void FixForeignFieldsInDescriptor(
+      const Descriptor& descriptor,
+      const Descriptor* containing_descriptor) const;
+  void FixForeignFieldsInField(const Descriptor* containing_type,
+                               const FieldDescriptor& field,
+                               const string& python_dict_name) const;
+  void AddMessageToFileDescriptor(const Descriptor& descriptor) const;
+  void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const;
+  void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const;
+  string FieldReferencingExpression(const Descriptor* containing_type,
+                                    const FieldDescriptor& field,
+                                    const string& python_dict_name) const;
+  template <typename DescriptorT>
+  void FixContainingTypeInDescriptor(
+      const DescriptorT& descriptor,
+      const Descriptor* containing_descriptor) 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;
+
+  template <typename DescriptorT, typename DescriptorProtoT>
+  void PrintSerializedPbInterval(
+      const DescriptorT& descriptor, DescriptorProtoT& proto) const;
+
+  void FixAllDescriptorOptions() const;
+  void FixOptionsForField(const FieldDescriptor& field) const;
+  void FixOptionsForEnum(const EnumDescriptor& descriptor) const;
+  void FixOptionsForMessage(const Descriptor& descriptor) const;
+
+  // Very coarse-grained lock to ensure that Generate() is reentrant.
+  // Guards file_, printer_ and file_descriptor_serialized_.
+  mutable Mutex mutex_;
+  mutable const FileDescriptor* file_;  // Set in Generate().  Under mutex_.
+  mutable string file_descriptor_serialized_;
+  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/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc
new file mode 100644
index 0000000..09dbc65
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/python/python_plugin_unittest.cc
@@ -0,0 +1,118 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// TODO(kenton):  Share code with the versions of this test in other languages?
+//   It seemed like parameterizing it would add more complexity than it is
+//   worth.
+
+#include <memory>
+
+#include <google/protobuf/compiler/python/python_generator.h>
+#include <google/protobuf/compiler/command_line_interface.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/printer.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/testing/file.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace python {
+namespace {
+
+class TestGenerator : public CodeGenerator {
+ public:
+  TestGenerator() {}
+  ~TestGenerator() {}
+
+  virtual bool Generate(const FileDescriptor* file,
+                        const string& parameter,
+                        GeneratorContext* context,
+                        string* error) const {
+    TryInsert("test_pb2.py", "imports", context);
+    TryInsert("test_pb2.py", "module_scope", context);
+    TryInsert("test_pb2.py", "class_scope:foo.Bar", context);
+    TryInsert("test_pb2.py", "class_scope:foo.Bar.Baz", context);
+    return true;
+  }
+
+  void TryInsert(const string& filename, const string& insertion_point,
+                 GeneratorContext* context) const {
+    scoped_ptr<io::ZeroCopyOutputStream> output(
+        context->OpenForInsert(filename, insertion_point));
+    io::Printer printer(output.get(), '$');
+    printer.Print("// inserted $name$\n", "name", insertion_point);
+  }
+};
+
+// This test verifies that all the expected insertion points exist.  It does
+// not verify that they are correctly-placed; that would require actually
+// compiling the output which is a bit more than I care to do for this test.
+TEST(PythonPluginTest, PluginTest) {
+  GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto",
+                             "syntax = \"proto2\";\n"
+                             "package foo;\n"
+                             "message Bar {\n"
+                             "  message Baz {}\n"
+                             "}\n",
+                             true));
+
+  google::protobuf::compiler::CommandLineInterface cli;
+  cli.SetInputsAreProtoPathRelative(true);
+
+  python::Generator python_generator;
+  TestGenerator test_generator;
+  cli.RegisterGenerator("--python_out", &python_generator, "");
+  cli.RegisterGenerator("--test_out", &test_generator, "");
+
+  string proto_path = "-I" + TestTempDir();
+  string python_out = "--python_out=" + TestTempDir();
+  string test_out = "--test_out=" + TestTempDir();
+
+  const char* argv[] = {
+    "protoc",
+    proto_path.c_str(),
+    python_out.c_str(),
+    test_out.c_str(),
+    "test.proto"
+  };
+
+  EXPECT_EQ(0, cli.Run(5, argv));
+}
+
+}  // namespace
+}  // namespace python
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/subprocess.cc b/protobuf/src/google/protobuf/compiler/subprocess.cc
new file mode 100644
index 0000000..61ae438
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/subprocess.cc
@@ -0,0 +1,463 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/compiler/subprocess.h>
+
+#include <algorithm>
+#include <iostream>
+
+#ifndef _WIN32
+#include <errno.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#include <signal.h>
+#endif
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/stubs/substitute.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+#ifdef _WIN32
+
+static void CloseHandleOrDie(HANDLE handle) {
+  if (!CloseHandle(handle)) {
+    GOOGLE_LOG(FATAL) << "CloseHandle: "
+                      << Subprocess::Win32ErrorMessage(GetLastError());
+  }
+}
+
+Subprocess::Subprocess()
+    : process_start_error_(ERROR_SUCCESS),
+      child_handle_(NULL), child_stdin_(NULL), child_stdout_(NULL) {}
+
+Subprocess::~Subprocess() {
+  if (child_stdin_ != NULL) {
+    CloseHandleOrDie(child_stdin_);
+  }
+  if (child_stdout_ != NULL) {
+    CloseHandleOrDie(child_stdout_);
+  }
+}
+
+void Subprocess::Start(const string& program, SearchMode search_mode) {
+  // Create the pipes.
+  HANDLE stdin_pipe_read;
+  HANDLE stdin_pipe_write;
+  HANDLE stdout_pipe_read;
+  HANDLE stdout_pipe_write;
+
+  if (!CreatePipe(&stdin_pipe_read, &stdin_pipe_write, NULL, 0)) {
+    GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError());
+  }
+  if (!CreatePipe(&stdout_pipe_read, &stdout_pipe_write, NULL, 0)) {
+    GOOGLE_LOG(FATAL) << "CreatePipe: " << Win32ErrorMessage(GetLastError());
+  }
+
+  // Make child side of the pipes inheritable.
+  if (!SetHandleInformation(stdin_pipe_read,
+                            HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
+    GOOGLE_LOG(FATAL) << "SetHandleInformation: "
+                      << Win32ErrorMessage(GetLastError());
+  }
+  if (!SetHandleInformation(stdout_pipe_write,
+                            HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) {
+    GOOGLE_LOG(FATAL) << "SetHandleInformation: "
+                      << Win32ErrorMessage(GetLastError());
+  }
+
+  // Setup STARTUPINFO to redirect handles.
+  STARTUPINFOA startup_info;
+  ZeroMemory(&startup_info, sizeof(startup_info));
+  startup_info.cb = sizeof(startup_info);
+  startup_info.dwFlags = STARTF_USESTDHANDLES;
+  startup_info.hStdInput = stdin_pipe_read;
+  startup_info.hStdOutput = stdout_pipe_write;
+  startup_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+
+  if (startup_info.hStdError == INVALID_HANDLE_VALUE) {
+    GOOGLE_LOG(FATAL) << "GetStdHandle: "
+                      << Win32ErrorMessage(GetLastError());
+  }
+
+  // CreateProcess() mutates its second parameter.  WTF?
+  char* name_copy = strdup(program.c_str());
+
+  // Create the process.
+  PROCESS_INFORMATION process_info;
+
+  if (CreateProcessA((search_mode == SEARCH_PATH) ? NULL : program.c_str(),
+                     (search_mode == SEARCH_PATH) ? name_copy : NULL,
+                     NULL,  // process security attributes
+                     NULL,  // thread security attributes
+                     TRUE,  // inherit handles?
+                     0,     // obscure creation flags
+                     NULL,  // environment (inherit from parent)
+                     NULL,  // current directory (inherit from parent)
+                     &startup_info,
+                     &process_info)) {
+    child_handle_ = process_info.hProcess;
+    CloseHandleOrDie(process_info.hThread);
+    child_stdin_ = stdin_pipe_write;
+    child_stdout_ = stdout_pipe_read;
+  } else {
+    process_start_error_ = GetLastError();
+    CloseHandleOrDie(stdin_pipe_write);
+    CloseHandleOrDie(stdout_pipe_read);
+  }
+
+  CloseHandleOrDie(stdin_pipe_read);
+  CloseHandleOrDie(stdout_pipe_write);
+  free(name_copy);
+}
+
+bool Subprocess::Communicate(const Message& input, Message* output,
+                             string* error) {
+  if (process_start_error_ != ERROR_SUCCESS) {
+    *error = Win32ErrorMessage(process_start_error_);
+    return false;
+  }
+
+  GOOGLE_CHECK(child_handle_ != NULL) << "Must call Start() first.";
+
+  string input_data = input.SerializeAsString();
+  string output_data;
+
+  int input_pos = 0;
+
+  while (child_stdout_ != NULL) {
+    HANDLE handles[2];
+    int handle_count = 0;
+
+    if (child_stdin_ != NULL) {
+      handles[handle_count++] = child_stdin_;
+    }
+    if (child_stdout_ != NULL) {
+      handles[handle_count++] = child_stdout_;
+    }
+
+    DWORD wait_result =
+        WaitForMultipleObjects(handle_count, handles, FALSE, INFINITE);
+
+    HANDLE signaled_handle;
+    if (wait_result >= WAIT_OBJECT_0 &&
+        wait_result < WAIT_OBJECT_0 + handle_count) {
+      signaled_handle = handles[wait_result - WAIT_OBJECT_0];
+    } else if (wait_result == WAIT_FAILED) {
+      GOOGLE_LOG(FATAL) << "WaitForMultipleObjects: "
+                        << Win32ErrorMessage(GetLastError());
+    } else {
+      GOOGLE_LOG(FATAL) << "WaitForMultipleObjects: Unexpected return code: "
+                        << wait_result;
+    }
+
+    if (signaled_handle == child_stdin_) {
+      DWORD n;
+      if (!WriteFile(child_stdin_,
+                     input_data.data() + input_pos,
+                     input_data.size() - input_pos,
+                     &n, NULL)) {
+        // Child closed pipe.  Presumably it will report an error later.
+        // Pretend we're done for now.
+        input_pos = input_data.size();
+      } else {
+        input_pos += n;
+      }
+
+      if (input_pos == input_data.size()) {
+        // We're done writing.  Close.
+        CloseHandleOrDie(child_stdin_);
+        child_stdin_ = NULL;
+      }
+    } else if (signaled_handle == child_stdout_) {
+      char buffer[4096];
+      DWORD n;
+
+      if (!ReadFile(child_stdout_, buffer, sizeof(buffer), &n, NULL)) {
+        // We're done reading.  Close.
+        CloseHandleOrDie(child_stdout_);
+        child_stdout_ = NULL;
+      } else {
+        output_data.append(buffer, n);
+      }
+    }
+  }
+
+  if (child_stdin_ != NULL) {
+    // Child did not finish reading input before it closed the output.
+    // Presumably it exited with an error.
+    CloseHandleOrDie(child_stdin_);
+    child_stdin_ = NULL;
+  }
+
+  DWORD wait_result = WaitForSingleObject(child_handle_, INFINITE);
+
+  if (wait_result == WAIT_FAILED) {
+    GOOGLE_LOG(FATAL) << "WaitForSingleObject: "
+                      << Win32ErrorMessage(GetLastError());
+  } else if (wait_result != WAIT_OBJECT_0) {
+    GOOGLE_LOG(FATAL) << "WaitForSingleObject: Unexpected return code: "
+                      << wait_result;
+  }
+
+  DWORD exit_code;
+  if (!GetExitCodeProcess(child_handle_, &exit_code)) {
+    GOOGLE_LOG(FATAL) << "GetExitCodeProcess: "
+                      << Win32ErrorMessage(GetLastError());
+  }
+
+  CloseHandleOrDie(child_handle_);
+  child_handle_ = NULL;
+
+  if (exit_code != 0) {
+    *error = strings::Substitute(
+        "Plugin failed with status code $0.", exit_code);
+    return false;
+  }
+
+  if (!output->ParseFromString(output_data)) {
+    *error = "Plugin output is unparseable: " + CEscape(output_data);
+    return false;
+  }
+
+  return true;
+}
+
+string Subprocess::Win32ErrorMessage(DWORD error_code) {
+  char* message;
+
+  // WTF?
+  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                FORMAT_MESSAGE_FROM_SYSTEM |
+                FORMAT_MESSAGE_IGNORE_INSERTS,
+                NULL, error_code, 0,
+                (LPTSTR)&message,  // NOT A BUG!
+                0, NULL);
+
+  string result = message;
+  LocalFree(message);
+  return result;
+}
+
+// ===================================================================
+
+#else  // _WIN32
+
+Subprocess::Subprocess()
+    : child_pid_(-1), child_stdin_(-1), child_stdout_(-1) {}
+
+Subprocess::~Subprocess() {
+  if (child_stdin_ != -1) {
+    close(child_stdin_);
+  }
+  if (child_stdout_ != -1) {
+    close(child_stdout_);
+  }
+}
+
+void Subprocess::Start(const string& program, SearchMode search_mode) {
+  // Note that we assume that there are no other threads, thus we don't have to
+  // do crazy stuff like using socket pairs or avoiding libc locks.
+
+  // [0] is read end, [1] is write end.
+  int stdin_pipe[2];
+  int stdout_pipe[2];
+
+  GOOGLE_CHECK(pipe(stdin_pipe) != -1);
+  GOOGLE_CHECK(pipe(stdout_pipe) != -1);
+
+  char* argv[2] = { strdup(program.c_str()), NULL };
+
+  child_pid_ = fork();
+  if (child_pid_ == -1) {
+    GOOGLE_LOG(FATAL) << "fork: " << strerror(errno);
+  } else if (child_pid_ == 0) {
+    // We are the child.
+    dup2(stdin_pipe[0], STDIN_FILENO);
+    dup2(stdout_pipe[1], STDOUT_FILENO);
+
+    close(stdin_pipe[0]);
+    close(stdin_pipe[1]);
+    close(stdout_pipe[0]);
+    close(stdout_pipe[1]);
+
+    switch (search_mode) {
+      case SEARCH_PATH:
+        execvp(argv[0], argv);
+        break;
+      case EXACT_NAME:
+        execv(argv[0], argv);
+        break;
+    }
+
+    // Write directly to STDERR_FILENO to avoid stdio code paths that may do
+    // stuff that is unsafe here.
+    int ignored;
+    ignored = write(STDERR_FILENO, argv[0], strlen(argv[0]));
+    const char* message = ": program not found or is not executable\n";
+    ignored = write(STDERR_FILENO, message, strlen(message));
+    (void) ignored;
+
+    // Must use _exit() rather than exit() to avoid flushing output buffers
+    // that will also be flushed by the parent.
+    _exit(1);
+  } else {
+    free(argv[0]);
+
+    close(stdin_pipe[0]);
+    close(stdout_pipe[1]);
+
+    child_stdin_ = stdin_pipe[1];
+    child_stdout_ = stdout_pipe[0];
+  }
+}
+
+bool Subprocess::Communicate(const Message& input, Message* output,
+                             string* error) {
+
+  GOOGLE_CHECK_NE(child_stdin_, -1) << "Must call Start() first.";
+
+  // The "sighandler_t" typedef is GNU-specific, so define our own.
+  typedef void SignalHandler(int);
+
+  // Make sure SIGPIPE is disabled so that if the child dies it doesn't kill us.
+  SignalHandler* old_pipe_handler = signal(SIGPIPE, SIG_IGN);
+
+  string input_data = input.SerializeAsString();
+  string output_data;
+
+  int input_pos = 0;
+  int max_fd = max(child_stdin_, child_stdout_);
+
+  while (child_stdout_ != -1) {
+    fd_set read_fds;
+    fd_set write_fds;
+    FD_ZERO(&read_fds);
+    FD_ZERO(&write_fds);
+    if (child_stdout_ != -1) {
+      FD_SET(child_stdout_, &read_fds);
+    }
+    if (child_stdin_ != -1) {
+      FD_SET(child_stdin_, &write_fds);
+    }
+
+    if (select(max_fd + 1, &read_fds, &write_fds, NULL, NULL) < 0) {
+      if (errno == EINTR) {
+        // Interrupted by signal.  Try again.
+        continue;
+      } else {
+        GOOGLE_LOG(FATAL) << "select: " << strerror(errno);
+      }
+    }
+
+    if (child_stdin_ != -1 && FD_ISSET(child_stdin_, &write_fds)) {
+      int n = write(child_stdin_, input_data.data() + input_pos,
+                                  input_data.size() - input_pos);
+      if (n < 0) {
+        // Child closed pipe.  Presumably it will report an error later.
+        // Pretend we're done for now.
+        input_pos = input_data.size();
+      } else {
+        input_pos += n;
+      }
+
+      if (input_pos == input_data.size()) {
+        // We're done writing.  Close.
+        close(child_stdin_);
+        child_stdin_ = -1;
+      }
+    }
+
+    if (child_stdout_ != -1 && FD_ISSET(child_stdout_, &read_fds)) {
+      char buffer[4096];
+      int n = read(child_stdout_, buffer, sizeof(buffer));
+
+      if (n > 0) {
+        output_data.append(buffer, n);
+      } else {
+        // We're done reading.  Close.
+        close(child_stdout_);
+        child_stdout_ = -1;
+      }
+    }
+  }
+
+  if (child_stdin_ != -1) {
+    // Child did not finish reading input before it closed the output.
+    // Presumably it exited with an error.
+    close(child_stdin_);
+    child_stdin_ = -1;
+  }
+
+  int status;
+  while (waitpid(child_pid_, &status, 0) == -1) {
+    if (errno != EINTR) {
+      GOOGLE_LOG(FATAL) << "waitpid: " << strerror(errno);
+    }
+  }
+
+  // Restore SIGPIPE handling.
+  signal(SIGPIPE, old_pipe_handler);
+
+  if (WIFEXITED(status)) {
+    if (WEXITSTATUS(status) != 0) {
+      int error_code = WEXITSTATUS(status);
+      *error = strings::Substitute(
+          "Plugin failed with status code $0.", error_code);
+      return false;
+    }
+  } else if (WIFSIGNALED(status)) {
+    int signal = WTERMSIG(status);
+    *error = strings::Substitute(
+        "Plugin killed by signal $0.", signal);
+    return false;
+  } else {
+    *error = "Neither WEXITSTATUS nor WTERMSIG is true?";
+    return false;
+  }
+
+  if (!output->ParseFromString(output_data)) {
+    *error = "Plugin output is unparseable: " + CEscape(output_data);
+    return false;
+  }
+
+  return true;
+}
+
+#endif  // !_WIN32
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/subprocess.h b/protobuf/src/google/protobuf/compiler/subprocess.h
new file mode 100644
index 0000000..2513863
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/subprocess.h
@@ -0,0 +1,108 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
+#define GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN   // right...
+#include <windows.h>
+#else  // _WIN32
+#include <sys/types.h>
+#include <unistd.h>
+#endif  // !_WIN32
+#include <google/protobuf/stubs/common.h>
+
+#include <string>
+
+
+namespace google {
+namespace protobuf {
+
+class Message;
+
+namespace compiler {
+
+// Utility class for launching sub-processes.
+class LIBPROTOC_EXPORT Subprocess {
+ public:
+  Subprocess();
+  ~Subprocess();
+
+  enum SearchMode {
+    SEARCH_PATH,   // Use PATH environment variable.
+    EXACT_NAME     // Program is an exact file name; don't use the PATH.
+  };
+
+  // Start the subprocess.  Currently we don't provide a way to specify
+  // arguments as protoc plugins don't have any.
+  void Start(const string& program, SearchMode search_mode);
+
+  // Serialize the input message and pipe it to the subprocess's stdin, then
+  // close the pipe.  Meanwhile, read from the subprocess's stdout and parse
+  // the data into *output.  All this is done carefully to avoid deadlocks.
+  // Returns true if successful.  On any sort of error, returns false and sets
+  // *error to a description of the problem.
+  bool Communicate(const Message& input, Message* output, string* error);
+
+#ifdef _WIN32
+  // Given an error code, returns a human-readable error message.  This is
+  // defined here so that CommandLineInterface can share it.
+  static string Win32ErrorMessage(DWORD error_code);
+#endif
+
+ private:
+#ifdef _WIN32
+  DWORD process_start_error_;
+  HANDLE child_handle_;
+
+  // The file handles for our end of the child's pipes.  We close each and
+  // set it to NULL when no longer needed.
+  HANDLE child_stdin_;
+  HANDLE child_stdout_;
+
+#else  // _WIN32
+  pid_t child_pid_;
+
+  // The file descriptors for our end of the child's pipes.  We close each and
+  // set it to -1 when no longer needed.
+  int child_stdin_;
+  int child_stdout_;
+
+#endif  // !_WIN32
+};
+
+}  // namespace compiler
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
diff --git a/protobuf/src/google/protobuf/compiler/test_plugin.cc b/protobuf/src/google/protobuf/compiler/test_plugin.cc
new file mode 100644
index 0000000..4830fd7
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/test_plugin.cc
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is a dummy code generator plugin used by
+// command_line_interface_unittest.
+
+#include <string>
+#include <stdlib.h>
+#include <google/protobuf/compiler/plugin.h>
+#include <google/protobuf/compiler/mock_code_generator.h>
+#include <google/protobuf/stubs/strutil.h>
+
+int main(int argc, char* argv[]) {
+#ifdef _MSC_VER
+  // Don't print a silly message or stick a modal dialog box in my face,
+  // please.
+  _set_abort_behavior(0, ~0);
+#endif  // !_MSC_VER
+
+  google::protobuf::compiler::MockCodeGenerator generator("test_plugin");
+  return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+}
diff --git a/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh b/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh
new file mode 100755
index 0000000..6fc7136
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/zip_output_unittest.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2009 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Author: kenton@google.com (Kenton Varda)
+#
+# Test protoc's zip output mode.
+
+fail() {
+  echo "$@" >&2
+  exit 1
+}
+
+TEST_TMPDIR=.
+PROTOC=./protoc
+
+echo '
+  syntax = "proto2";
+  option java_multiple_files = true;
+  option java_package = "test.jar";
+  option java_outer_classname = "Outer";
+  message Foo {}
+  message Bar {}
+' > $TEST_TMPDIR/testzip.proto
+
+$PROTOC \
+    --cpp_out=$TEST_TMPDIR/testzip.zip --python_out=$TEST_TMPDIR/testzip.zip \
+    --java_out=$TEST_TMPDIR/testzip.jar -I$TEST_TMPDIR testzip.proto \
+    || fail 'protoc failed.'
+
+echo "Testing output to zip..."
+if unzip -h > /dev/null; then
+  unzip -t $TEST_TMPDIR/testzip.zip > $TEST_TMPDIR/testzip.list || fail 'unzip failed.'
+
+  grep 'testing: testzip\.pb\.cc *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
+    || fail 'testzip.pb.cc not found in output zip.'
+  grep 'testing: testzip\.pb\.h *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
+    || fail 'testzip.pb.h not found in output zip.'
+  grep 'testing: testzip_pb2\.py *OK$' $TEST_TMPDIR/testzip.list > /dev/null \
+    || fail 'testzip_pb2.py not found in output zip.'
+  grep -i 'manifest' $TEST_TMPDIR/testzip.list > /dev/null \
+    && fail 'Zip file contained manifest.'
+else
+  echo "Warning:  'unzip' command not available.  Skipping test."
+fi
+
+echo "Testing output to jar..."
+if jar c $TEST_TMPDIR/testzip.proto > /dev/null; then
+  jar tf $TEST_TMPDIR/testzip.jar > $TEST_TMPDIR/testzip.list || fail 'jar failed.'
+
+  grep '^test/jar/Foo\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
+    || fail 'Foo.java not found in output jar.'
+  grep '^test/jar/Bar\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
+    || fail 'Bar.java not found in output jar.'
+  grep '^test/jar/Outer\.java$' $TEST_TMPDIR/testzip.list > /dev/null \
+    || fail 'Outer.java not found in output jar.'
+  grep '^META-INF/MANIFEST\.MF$' $TEST_TMPDIR/testzip.list > /dev/null \
+    || fail 'Manifest not found in output jar.'
+else
+  echo "Warning:  'jar' command not available.  Skipping test."
+fi
+
+echo PASS
diff --git a/protobuf/src/google/protobuf/compiler/zip_writer.cc b/protobuf/src/google/protobuf/compiler/zip_writer.cc
new file mode 100644
index 0000000..458cced
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/zip_writer.cc
@@ -0,0 +1,218 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: ambrose@google.com (Ambrose Feinstein),
+//         kenton@google.com (Kenton Varda)
+//
+// Based on http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+
+#include <google/protobuf/compiler/zip_writer.h>
+#include <google/protobuf/io/coded_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+static const uint32 kCRC32Table[256] = {
+  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+  0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+  0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+  0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+  0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+  0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+  0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+  0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+  0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+  0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+  0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+  0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+  0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+  0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+  0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+  0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+  0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+  0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+static uint32 ComputeCRC32(const string &buf) {
+  uint32 x = ~0U;
+  for (int i = 0; i < buf.size(); ++i) {
+    unsigned char c = buf[i];
+    x = kCRC32Table[(x ^ c) & 0xff] ^ (x >> 8);
+  }
+  return ~x;
+}
+
+static void WriteShort(io::CodedOutputStream *out, uint16 val) {
+  uint8 p[2];
+  p[0] = static_cast<uint8>(val);
+  p[1] = static_cast<uint8>(val >> 8);
+  out->WriteRaw(p, 2);
+}
+
+ZipWriter::ZipWriter(io::ZeroCopyOutputStream* raw_output)
+  : raw_output_(raw_output) {}
+ZipWriter::~ZipWriter() {}
+
+bool ZipWriter::Write(const string& filename, const string& contents) {
+  FileInfo info;
+
+  info.name = filename;
+  uint16 filename_size = filename.size();
+  info.offset = raw_output_->ByteCount();
+  info.size = contents.size();
+  info.crc32 = ComputeCRC32(contents);
+
+  files_.push_back(info);
+
+  // write file header
+  io::CodedOutputStream output(raw_output_);
+  output.WriteLittleEndian32(0x04034b50);  // magic
+  WriteShort(&output, 10);  // version needed to extract
+  WriteShort(&output, 0);  // flags
+  WriteShort(&output, 0);  // compression method: stored
+  WriteShort(&output, 0);  // last modified time
+  WriteShort(&output, 0);  // last modified date
+  output.WriteLittleEndian32(info.crc32);  // crc-32
+  output.WriteLittleEndian32(info.size);  // compressed size
+  output.WriteLittleEndian32(info.size);  // uncompressed size
+  WriteShort(&output, filename_size);  // file name length
+  WriteShort(&output, 0);   // extra field length
+  output.WriteString(filename);  // file name
+  output.WriteString(contents);  // file data
+
+  return !output.HadError();
+}
+
+bool ZipWriter::WriteDirectory() {
+  uint16 num_entries = files_.size();
+  uint32 dir_ofs = raw_output_->ByteCount();
+
+  // write central directory
+  io::CodedOutputStream output(raw_output_);
+  for (int i = 0; i < num_entries; ++i) {
+    const string &filename = files_[i].name;
+    uint16 filename_size = filename.size();
+    uint32 crc32 = files_[i].crc32;
+    uint32 size = files_[i].size;
+    uint32 offset = files_[i].offset;
+
+    output.WriteLittleEndian32(0x02014b50);  // magic
+    WriteShort(&output, 10);  // version made by
+    WriteShort(&output, 10);  // version needed to extract
+    WriteShort(&output, 0);  // flags
+    WriteShort(&output, 0);  // compression method: stored
+    WriteShort(&output, 0);  // last modified time
+    WriteShort(&output, 0);  // last modified date
+    output.WriteLittleEndian32(crc32);  // crc-32
+    output.WriteLittleEndian32(size);  // compressed size
+    output.WriteLittleEndian32(size);  // uncompressed size
+    WriteShort(&output, filename_size);  // file name length
+    WriteShort(&output, 0);   // extra field length
+    WriteShort(&output, 0);   // file comment length
+    WriteShort(&output, 0);   // starting disk number
+    WriteShort(&output, 0);   // internal file attributes
+    output.WriteLittleEndian32(0);  // external file attributes
+    output.WriteLittleEndian32(offset);  // local header offset
+    output.WriteString(filename);  // file name
+  }
+  uint32 dir_len = output.ByteCount();
+
+  // write end of central directory marker
+  output.WriteLittleEndian32(0x06054b50);  // magic
+  WriteShort(&output, 0);  // disk number
+  WriteShort(&output, 0);  // disk with start of central directory
+  WriteShort(&output, num_entries);  // central directory entries (this disk)
+  WriteShort(&output, num_entries);  // central directory entries (total)
+  output.WriteLittleEndian32(dir_len);  // central directory byte size
+  output.WriteLittleEndian32(dir_ofs);  // central directory offset
+  WriteShort(&output, 0);   // comment length
+
+  return output.HadError();
+}
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/compiler/zip_writer.h b/protobuf/src/google/protobuf/compiler/zip_writer.h
new file mode 100644
index 0000000..602e508
--- /dev/null
+++ b/protobuf/src/google/protobuf/compiler/zip_writer.h
@@ -0,0 +1,93 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+
+class ZipWriter {
+ public:
+  ZipWriter(io::ZeroCopyOutputStream* raw_output);
+  ~ZipWriter();
+
+  bool Write(const string& filename, const string& contents);
+  bool WriteDirectory();
+
+ private:
+  struct FileInfo {
+    string name;
+    uint32 offset;
+    uint32 size;
+    uint32 crc32;
+  };
+
+  io::ZeroCopyOutputStream* raw_output_;
+  vector<FileInfo> files_;
+};
+
+}  // namespace compiler
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/descriptor.cc b/protobuf/src/google/protobuf/descriptor.cc
new file mode 100644
index 0000000..21dda59
--- /dev/null
+++ b/protobuf/src/google/protobuf/descriptor.cc
@@ -0,0 +1,5420 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <string>
+#include <vector>
+#include <algorithm>
+#include <limits>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/strtod.h>
+#include <google/protobuf/io/coded_stream.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/once.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.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::kCppTypeToName[MAX_CPPTYPE + 1] = {
+  "ERROR",     // 0 is reserved for errors
+
+  "int32",     // CPPTYPE_INT32
+  "int64",     // CPPTYPE_INT64
+  "uint32",    // CPPTYPE_UINT32
+  "uint64",    // CPPTYPE_UINT64
+  "double",    // CPPTYPE_DOUBLE
+  "float",     // CPPTYPE_FLOAT
+  "bool",      // CPPTYPE_BOOL
+  "enum",      // CPPTYPE_ENUM
+  "string",    // CPPTYPE_STRING
+  "message",   // CPPTYPE_MESSAGE
+};
+
+const char * const FieldDescriptor::kLabelToName[MAX_LABEL + 1] = {
+  "ERROR",     // 0 is reserved for errors
+
+  "optional",  // LABEL_OPTIONAL
+  "required",  // LABEL_REQUIRED
+  "repeated",  // LABEL_REPEATED
+};
+
+static const char * const kNonLinkedWeakMessageReplacementName = "google.protobuf.Empty";
+
+#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 {
+
+string ToCamelCase(const string& input) {
+  bool capitalize_next = false;
+  string result;
+  result.reserve(input.size());
+
+  for (int i = 0; i < input.size(); i++) {
+    if (input[i] == '_') {
+      capitalize_next = true;
+    } else if (capitalize_next) {
+      // Note:  I distrust ctype.h due to locales.
+      if ('a' <= input[i] && input[i] <= 'z') {
+        result.push_back(input[i] - 'a' + 'A');
+      } else {
+        result.push_back(input[i]);
+      }
+      capitalize_next = false;
+    } else {
+      result.push_back(input[i]);
+    }
+  }
+
+  // Lower-case the first letter.
+  if (!result.empty() && 'A' <= result[0] && result[0] <= 'Z') {
+    result[0] = result[0] - 'A' + 'a';
+  }
+
+  return result;
+}
+
+// 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;
+
+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;
+  }
+
+#ifdef _MSC_VER
+  // 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;
+#endif
+  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);
+  }
+
+#ifdef _MSC_VER
+  // 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;
+#endif
+  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, ONEOF, ENUM, ENUM_VALUE, SERVICE, METHOD,
+    PACKAGE
+  };
+  Type type;
+  union {
+    const Descriptor* descriptor;
+    const FieldDescriptor* field_descriptor;
+    const OneofDescriptor* oneof_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; }
+  inline bool IsType() const {
+    return type == MESSAGE || type == ENUM;
+  }
+  inline bool IsAggregate() const {
+    return type == MESSAGE || type == PACKAGE
+        || type == ENUM || type == SERVICE;
+  }
+
+#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(OneofDescriptor    , ONEOF     , oneof_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 ONEOF      : return oneof_descriptor     ->containing_type()->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*>, streq>
+  SymbolsByNameMap;
+typedef hash_map<PointerStringPair, Symbol,
+                 PointerStringPairHash, PointerStringPairEqual>
+  SymbolsByParentMap;
+typedef hash_map<const char*, const FileDescriptor*,
+                 hash<const char*>, streq>
+  FilesByNameMap;
+typedef hash_map<PointerStringPair, const FieldDescriptor*,
+                 PointerStringPairHash, PointerStringPairEqual>
+  FieldsByNameMap;
+typedef hash_map<DescriptorIntPair, const FieldDescriptor*,
+                 PointerIntegerPairHash<DescriptorIntPair> >
+  FieldsByNumberMap;
+typedef hash_map<EnumIntPair, const EnumValueDescriptor*,
+                 PointerIntegerPairHash<EnumIntPair> >
+  EnumValuesByNumberMap;
+// This is a map rather than a hash_map, since we use it to iterate
+// through all the extensions that extend a given Descriptor, and an
+// ordered data structure that implements lower_bound is convenient
+// for that.
+typedef map<DescriptorIntPair, const FieldDescriptor*>
+  ExtensionsGroupedByDescriptorMap;
+typedef hash_map<string, const SourceCodeInfo_Location*> LocationsByPathMap;
+}  // anonymous namespace
+
+// ===================================================================
+// DescriptorPool::Tables
+
+class DescriptorPool::Tables {
+ public:
+  Tables();
+  ~Tables();
+
+  // Record the current state of the tables to the stack of checkpoints.
+  // Each call to AddCheckpoint() must be paired with exactly one call to either
+  // ClearLastCheckpoint() or RollbackToLastCheckpoint().
+  //
+  // 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.
+  //
+  // This supports recursive checkpoints, since building a file may trigger
+  // recursive building of other files. Note that recursive checkpoints are not
+  // normally necessary; explicit dependencies are built prior to checkpointing.
+  // So although we recursively build transitive imports, there is at most one
+  // checkpoint in the stack during dependency building.
+  //
+  // Recursive checkpoints only arise during cross-linking of the descriptors.
+  // Symbol references must be resolved, via DescriptorBuilder::FindSymbol and
+  // friends. If the pending file references an unknown symbol
+  // (e.g., it is not defined in the pending file's explicit dependencies), and
+  // the pool is using a fallback database, and that database contains a file
+  // defining that symbol, and that file has not yet been built by the pool,
+  // the pool builds the file during cross-linking, leading to another
+  // checkpoint.
+  void AddCheckpoint();
+
+  // Mark the last checkpoint as having cleared successfully, removing it from
+  // the stack. If the stack is empty, all pending symbols will be committed.
+  //
+  // Note that this does not guarantee that the symbols added since the last
+  // checkpoint won't be rolled back: if a checkpoint gets rolled back,
+  // everything past that point gets rolled back, including symbols added after
+  // checkpoints that were pushed onto the stack after it and marked as cleared.
+  void ClearLastCheckpoint();
+
+  // Roll back the Tables to the state of the checkpoint at the top of the
+  // stack, removing everything that was added after that point.
+  void RollbackToLastCheckpoint();
+
+  // 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 during
+  // execution of the current public API call, but for compatibility with
+  // legacy clients, this is cleared at the beginning of each public API call.
+  // Not used when fallback_database_ == NULL.
+  hash_set<string> known_bad_files_;
+
+  // A set of symbols which we have tried to load from the fallback database
+  // and encountered errors. We will not attempt to load them again during
+  // execution of the current public API call, but for compatibility with
+  // legacy clients, this is cleared at the beginning of each public API call.
+  hash_set<string> known_bad_symbols_;
+
+  // The set of descriptors for which we've already loaded the full
+  // set of extensions numbers from fallback_database_.
+  hash_set<const Descriptor*> extensions_loaded_from_db_;
+
+  // -----------------------------------------------------------------
+  // Finding items.
+
+  // Find symbols.  This returns a null Symbol (symbol.IsNull() is true)
+  // if not found.
+  inline Symbol FindSymbol(const string& key) const;
+
+  // This implements the body of DescriptorPool::Find*ByName().  It should
+  // really be a private method of DescriptorPool, but that would require
+  // declaring Symbol in descriptor.h, which would drag all kinds of other
+  // stuff into the header.  Yay C++.
+  Symbol FindByNameHelper(
+    const DescriptorPool* pool, const string& name);
+
+  // These return NULL if not found.
+  inline const FileDescriptor* FindFile(const string& key) const;
+  inline const FieldDescriptor* FindExtension(const Descriptor* extendee,
+                                              int number);
+  inline void FindAllExtensions(const Descriptor* extendee,
+                                vector<const FieldDescriptor*>* out) const;
+
+  // -----------------------------------------------------------------
+  // Adding items.
+
+  // These add items to the corresponding tables.  They return false if
+  // the key already exists in the table.  For AddSymbol(), the string passed
+  // in must be one that was constructed using AllocateString(), as it will
+  // be used as a key in the symbols_by_name_ map without copying.
+  bool AddSymbol(const string& full_name, Symbol symbol);
+  bool AddFile(const FileDescriptor* file);
+  bool AddExtension(const FieldDescriptor* field);
+
+  // -----------------------------------------------------------------
+  // 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.  Some older versions of GCC have
+  // trouble understanding explicit template instantiations in some cases, so
+  // in those cases we have to pass a dummy pointer of the right type as the
+  // parameter instead of specifying the type explicitly.
+  template<typename Type> Type* AllocateMessage(Type* dummy = NULL);
+
+  // Allocate a FileDescriptorTables object.
+  FileDescriptorTables* AllocateFileTables();
+
+ private:
+  vector<string*> strings_;    // All strings in the pool.
+  vector<Message*> messages_;  // All messages in the pool.
+  vector<FileDescriptorTables*> file_tables_;  // All file tables in the pool.
+  vector<void*> allocations_;  // All other memory allocated in the pool.
+
+  SymbolsByNameMap      symbols_by_name_;
+  FilesByNameMap        files_by_name_;
+  ExtensionsGroupedByDescriptorMap extensions_;
+
+  struct CheckPoint {
+    explicit CheckPoint(const Tables* tables)
+      : strings_before_checkpoint(tables->strings_.size()),
+        messages_before_checkpoint(tables->messages_.size()),
+        file_tables_before_checkpoint(tables->file_tables_.size()),
+        allocations_before_checkpoint(tables->allocations_.size()),
+        pending_symbols_before_checkpoint(
+            tables->symbols_after_checkpoint_.size()),
+        pending_files_before_checkpoint(
+            tables->files_after_checkpoint_.size()),
+        pending_extensions_before_checkpoint(
+            tables->extensions_after_checkpoint_.size()) {
+    }
+    int strings_before_checkpoint;
+    int messages_before_checkpoint;
+    int file_tables_before_checkpoint;
+    int allocations_before_checkpoint;
+    int pending_symbols_before_checkpoint;
+    int pending_files_before_checkpoint;
+    int pending_extensions_before_checkpoint;
+  };
+  vector<CheckPoint> checkpoints_;
+  vector<const char*      > symbols_after_checkpoint_;
+  vector<const char*      > files_after_checkpoint_;
+  vector<DescriptorIntPair> extensions_after_checkpoint_;
+
+  // Allocate some bytes which will be reclaimed when the pool is
+  // destroyed.
+  void* AllocateBytes(int size);
+};
+
+// Contains tables specific to a particular file.  These tables are not
+// modified once the file has been constructed, so they need not be
+// protected by a mutex.  This makes operations that depend only on the
+// contents of a single file -- e.g. Descriptor::FindFieldByName() --
+// lock-free.
+//
+// For historical reasons, the definitions of the methods of
+// FileDescriptorTables and DescriptorPool::Tables are interleaved below.
+// These used to be a single class.
+class FileDescriptorTables {
+ public:
+  FileDescriptorTables();
+  ~FileDescriptorTables();
+
+  // Empty table, used with placeholder files.
+  static const FileDescriptorTables kEmpty;
+
+  // -----------------------------------------------------------------
+  // Finding items.
+
+  // Find symbols.  These return a null Symbol (symbol.IsNull() is true)
+  // if not found.
+  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 FieldDescriptor* FindFieldByNumber(
+    const Descriptor* parent, int number) const;
+  inline const FieldDescriptor* FindFieldByLowercaseName(
+    const void* parent, const string& lowercase_name) const;
+  inline const FieldDescriptor* FindFieldByCamelcaseName(
+    const void* parent, const string& camelcase_name) 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 AddAliasUnderParent(), the
+  // string passed in must be one that was constructed using AllocateString(),
+  // as it will be used as a key in the symbols_by_parent_ map without copying.
+  bool AddAliasUnderParent(const void* parent, const string& name,
+                           Symbol symbol);
+  bool AddFieldByNumber(const FieldDescriptor* field);
+  bool AddEnumValueByNumber(const EnumValueDescriptor* value);
+
+  // Adds the field to the lowercase_name and camelcase_name maps.  Never
+  // fails because we allow duplicates; the first field by the name wins.
+  void AddFieldByStylizedNames(const FieldDescriptor* field);
+
+  // Populates p->first->locations_by_path_ from p->second.
+  // Unusual signature dictated by GoogleOnceDynamic.
+  static void BuildLocationsByPath(
+      pair<const FileDescriptorTables*, const SourceCodeInfo*>* p);
+
+  // Returns the location denoted by the specified path through info,
+  // or NULL if not found.
+  // The value of info must be that of the corresponding FileDescriptor.
+  // (Conceptually a pure function, but stateful as an optimisation.)
+  const SourceCodeInfo_Location* GetSourceLocation(
+      const vector<int>& path, const SourceCodeInfo* info) const;
+
+ private:
+  SymbolsByParentMap    symbols_by_parent_;
+  FieldsByNameMap       fields_by_lowercase_name_;
+  FieldsByNameMap       fields_by_camelcase_name_;
+  FieldsByNumberMap     fields_by_number_;       // Not including extensions.
+  EnumValuesByNumberMap enum_values_by_number_;
+
+  // Populated on first request to save space, hence constness games.
+  mutable GoogleOnceDynamic locations_by_path_once_;
+  mutable LocationsByPathMap locations_by_path_;
+};
+
+DescriptorPool::Tables::Tables()
+    // Start some hash_map and hash_set objects with a small # of buckets
+    : known_bad_files_(3),
+      known_bad_symbols_(3),
+      extensions_loaded_from_db_(3),
+      symbols_by_name_(3),
+      files_by_name_(3) {}
+
+
+DescriptorPool::Tables::~Tables() {
+  GOOGLE_DCHECK(checkpoints_.empty());
+  // Note that the deletion order is important, since the destructors of some
+  // messages may refer to objects in allocations_.
+  STLDeleteElements(&messages_);
+  for (int i = 0; i < allocations_.size(); i++) {
+    operator delete(allocations_[i]);
+  }
+  STLDeleteElements(&strings_);
+  STLDeleteElements(&file_tables_);
+}
+
+FileDescriptorTables::FileDescriptorTables()
+    // Initialize all the hash tables to start out with a small # of buckets
+    : symbols_by_parent_(3),
+      fields_by_lowercase_name_(3),
+      fields_by_camelcase_name_(3),
+      fields_by_number_(3),
+      enum_values_by_number_(3) {
+}
+
+FileDescriptorTables::~FileDescriptorTables() {}
+
+const FileDescriptorTables FileDescriptorTables::kEmpty;
+
+void DescriptorPool::Tables::AddCheckpoint() {
+  checkpoints_.push_back(CheckPoint(this));
+}
+
+void DescriptorPool::Tables::ClearLastCheckpoint() {
+  GOOGLE_DCHECK(!checkpoints_.empty());
+  checkpoints_.pop_back();
+  if (checkpoints_.empty()) {
+    // All checkpoints have been cleared: we can now commit all of the pending
+    // data.
+    symbols_after_checkpoint_.clear();
+    files_after_checkpoint_.clear();
+    extensions_after_checkpoint_.clear();
+  }
+}
+
+void DescriptorPool::Tables::RollbackToLastCheckpoint() {
+  GOOGLE_DCHECK(!checkpoints_.empty());
+  const CheckPoint& checkpoint = checkpoints_.back();
+
+  for (int i = checkpoint.pending_symbols_before_checkpoint;
+       i < symbols_after_checkpoint_.size();
+       i++) {
+    symbols_by_name_.erase(symbols_after_checkpoint_[i]);
+  }
+  for (int i = checkpoint.pending_files_before_checkpoint;
+       i < files_after_checkpoint_.size();
+       i++) {
+    files_by_name_.erase(files_after_checkpoint_[i]);
+  }
+  for (int i = checkpoint.pending_extensions_before_checkpoint;
+       i < extensions_after_checkpoint_.size();
+       i++) {
+    extensions_.erase(extensions_after_checkpoint_[i]);
+  }
+
+  symbols_after_checkpoint_.resize(
+      checkpoint.pending_symbols_before_checkpoint);
+  files_after_checkpoint_.resize(checkpoint.pending_files_before_checkpoint);
+  extensions_after_checkpoint_.resize(
+      checkpoint.pending_extensions_before_checkpoint);
+
+  STLDeleteContainerPointers(
+      strings_.begin() + checkpoint.strings_before_checkpoint, strings_.end());
+  STLDeleteContainerPointers(
+      messages_.begin() + checkpoint.messages_before_checkpoint,
+      messages_.end());
+  STLDeleteContainerPointers(
+      file_tables_.begin() + checkpoint.file_tables_before_checkpoint,
+      file_tables_.end());
+  for (int i = checkpoint.allocations_before_checkpoint;
+       i < allocations_.size();
+       i++) {
+    operator delete(allocations_[i]);
+  }
+
+  strings_.resize(checkpoint.strings_before_checkpoint);
+  messages_.resize(checkpoint.messages_before_checkpoint);
+  file_tables_.resize(checkpoint.file_tables_before_checkpoint);
+  allocations_.resize(checkpoint.allocations_before_checkpoint);
+  checkpoints_.pop_back();
+}
+
+// -------------------------------------------------------------------
+
+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 FileDescriptorTables::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 FileDescriptorTables::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;
+}
+
+Symbol DescriptorPool::Tables::FindByNameHelper(
+    const DescriptorPool* pool, const string& name) {
+  MutexLockMaybe lock(pool->mutex_);
+  known_bad_symbols_.clear();
+  known_bad_files_.clear();
+  Symbol result = FindSymbol(name);
+
+  if (result.IsNull() && pool->underlay_ != NULL) {
+    // Symbol not found; check the underlay.
+    result =
+      pool->underlay_->tables_->FindByNameHelper(pool->underlay_, name);
+  }
+
+  if (result.IsNull()) {
+    // Symbol still not found, so check fallback database.
+    if (pool->TryFindSymbolInFallbackDatabase(name)) {
+      result = FindSymbol(name);
+    }
+  }
+
+  return result;
+}
+
+inline const FileDescriptor* DescriptorPool::Tables::FindFile(
+    const string& key) const {
+  return FindPtrOrNull(files_by_name_, key.c_str());
+}
+
+inline const FieldDescriptor* FileDescriptorTables::FindFieldByNumber(
+    const Descriptor* parent, int number) const {
+  return FindPtrOrNull(fields_by_number_, make_pair(parent, number));
+}
+
+inline const FieldDescriptor* FileDescriptorTables::FindFieldByLowercaseName(
+    const void* parent, const string& lowercase_name) const {
+  return FindPtrOrNull(fields_by_lowercase_name_,
+                       PointerStringPair(parent, lowercase_name.c_str()));
+}
+
+inline const FieldDescriptor* FileDescriptorTables::FindFieldByCamelcaseName(
+    const void* parent, const string& camelcase_name) const {
+  return FindPtrOrNull(fields_by_camelcase_name_,
+                       PointerStringPair(parent, camelcase_name.c_str()));
+}
+
+inline const EnumValueDescriptor* FileDescriptorTables::FindEnumValueByNumber(
+    const EnumDescriptor* parent, int number) const {
+  return FindPtrOrNull(enum_values_by_number_, make_pair(parent, number));
+}
+
+inline const FieldDescriptor* DescriptorPool::Tables::FindExtension(
+    const Descriptor* extendee, int number) {
+  return FindPtrOrNull(extensions_, make_pair(extendee, number));
+}
+
+inline void DescriptorPool::Tables::FindAllExtensions(
+    const Descriptor* extendee, vector<const FieldDescriptor*>* out) const {
+  ExtensionsGroupedByDescriptorMap::const_iterator it =
+      extensions_.lower_bound(make_pair(extendee, 0));
+  for (; it != extensions_.end() && it->first.first == extendee; ++it) {
+    out->push_back(it->second);
+  }
+}
+
+// -------------------------------------------------------------------
+
+bool DescriptorPool::Tables::AddSymbol(
+    const string& full_name, Symbol symbol) {
+  if (InsertIfNotPresent(&symbols_by_name_, full_name.c_str(), symbol)) {
+    symbols_after_checkpoint_.push_back(full_name.c_str());
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool FileDescriptorTables::AddAliasUnderParent(
+    const void* parent, const string& name, Symbol symbol) {
+  PointerStringPair by_parent_key(parent, name.c_str());
+  return InsertIfNotPresent(&symbols_by_parent_, by_parent_key, symbol);
+}
+
+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;
+  }
+}
+
+void FileDescriptorTables::AddFieldByStylizedNames(
+    const FieldDescriptor* field) {
+  const void* parent;
+  if (field->is_extension()) {
+    if (field->extension_scope() == NULL) {
+      parent = field->file();
+    } else {
+      parent = field->extension_scope();
+    }
+  } else {
+    parent = field->containing_type();
+  }
+
+  PointerStringPair lowercase_key(parent, field->lowercase_name().c_str());
+  InsertIfNotPresent(&fields_by_lowercase_name_, lowercase_key, field);
+
+  PointerStringPair camelcase_key(parent, field->camelcase_name().c_str());
+  InsertIfNotPresent(&fields_by_camelcase_name_, camelcase_key, field);
+}
+
+bool FileDescriptorTables::AddFieldByNumber(const FieldDescriptor* field) {
+  DescriptorIntPair key(field->containing_type(), field->number());
+  return InsertIfNotPresent(&fields_by_number_, key, field);
+}
+
+bool FileDescriptorTables::AddEnumValueByNumber(
+    const EnumValueDescriptor* value) {
+  EnumIntPair key(value->type(), value->number());
+  return InsertIfNotPresent(&enum_values_by_number_, key, value);
+}
+
+bool DescriptorPool::Tables::AddExtension(const FieldDescriptor* field) {
+  DescriptorIntPair key(field->containing_type(), field->number());
+  if (InsertIfNotPresent(&extensions_, key, field)) {
+    extensions_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* /* dummy */) {
+  Type* result = new Type;
+  messages_.push_back(result);
+  return result;
+}
+
+FileDescriptorTables* DescriptorPool::Tables::AllocateFileTables() {
+  FileDescriptorTables* result = new FileDescriptorTables;
+  file_tables_.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;
+}
+
+void FileDescriptorTables::BuildLocationsByPath(
+    pair<const FileDescriptorTables*, const SourceCodeInfo*>* p) {
+  for (int i = 0, len = p->second->location_size(); i < len; ++i) {
+    const SourceCodeInfo_Location* loc = &p->second->location().Get(i);
+    p->first->locations_by_path_[Join(loc->path(), ",")] = loc;
+  }
+}
+
+const SourceCodeInfo_Location* FileDescriptorTables::GetSourceLocation(
+    const vector<int>& path, const SourceCodeInfo* info) const {
+  pair<const FileDescriptorTables*, const SourceCodeInfo*> p(
+      make_pair(this, info));
+  locations_by_path_once_.Init(&FileDescriptorTables::BuildLocationsByPath, &p);
+  return FindPtrOrNull(locations_by_path_, Join(path, ","));
+}
+
+// ===================================================================
+// DescriptorPool
+
+DescriptorPool::ErrorCollector::~ErrorCollector() {}
+
+DescriptorPool::DescriptorPool()
+  : mutex_(NULL),
+    fallback_database_(NULL),
+    default_error_collector_(NULL),
+    underlay_(NULL),
+    tables_(new Tables),
+    enforce_dependencies_(true),
+    allow_unknown_(false),
+    enforce_weak_(false) {}
+
+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),
+    allow_unknown_(false),
+    enforce_weak_(false) {
+}
+
+DescriptorPool::DescriptorPool(const DescriptorPool* underlay)
+  : mutex_(NULL),
+    fallback_database_(NULL),
+    default_error_collector_(NULL),
+    underlay_(underlay),
+    tables_(new Tables),
+    enforce_dependencies_(true),
+    allow_unknown_(false),
+    enforce_weak_(false) {}
+
+DescriptorPool::~DescriptorPool() {
+  if (mutex_ != NULL) delete mutex_;
+}
+
+// DescriptorPool::BuildFile() defined later.
+// DescriptorPool::BuildFileCollectingErrors() defined later.
+
+void DescriptorPool::InternalDontEnforceDependencies() {
+  enforce_dependencies_ = false;
+}
+
+void DescriptorPool::AddUnusedImportTrackFile(const string& file_name) {
+  unused_import_track_files_.insert(file_name);
+}
+
+void DescriptorPool::ClearUnusedImportTrackFiles() {
+  unused_import_track_files_.clear();
+}
+
+bool DescriptorPool::InternalIsFileLoaded(const string& filename) const {
+  MutexLockMaybe lock(mutex_);
+  return tables_->FindFile(filename) != NULL;
+}
+
+// generated_pool ====================================================
+
+namespace {
+
+
+EncodedDescriptorDatabase* generated_database_ = NULL;
+DescriptorPool* generated_pool_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(generated_pool_init_);
+
+void DeleteGeneratedPool() {
+  delete generated_database_;
+  generated_database_ = NULL;
+  delete generated_pool_;
+  generated_pool_ = NULL;
+}
+
+static void InitGeneratedPool() {
+  generated_database_ = new EncodedDescriptorDatabase;
+  generated_pool_ = new DescriptorPool(generated_database_);
+
+  internal::OnShutdown(&DeleteGeneratedPool);
+}
+
+inline void InitGeneratedPoolOnce() {
+  ::google::protobuf::GoogleOnceInit(&generated_pool_init_, &InitGeneratedPool);
+}
+
+}  // anonymous namespace
+
+const DescriptorPool* DescriptorPool::generated_pool() {
+  InitGeneratedPoolOnce();
+  return generated_pool_;
+}
+
+DescriptorPool* DescriptorPool::internal_generated_pool() {
+  InitGeneratedPoolOnce();
+  return generated_pool_;
+}
+
+void DescriptorPool::InternalAddGeneratedFile(
+    const void* encoded_file_descriptor, 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 AddDescriptors() which is called at
+  // process startup, and that function calls this one in order to register
+  // the raw bytes of the FileDescriptorProto representing the file.
+  //
+  // We do not actually construct the descriptor objects right away.  We just
+  // hang on to the bytes until they are actually needed.  We actually construct
+  // the descriptor the first time one of the following things happens:
+  // * Someone calls a method like descriptor(), GetDescriptor(), or
+  //   GetReflection() on the generated types, which requires returning the
+  //   descriptor or an object based on it.
+  // * Someone looks up the descriptor in DescriptorPool::generated_pool().
+  //
+  // Once one of these happens, the DescriptorPool actually parses the
+  // FileDescriptorProto and generates a FileDescriptor (and all its children)
+  // based on it.
+  //
+  // Note that FileDescriptorProto is itself a generated protocol message.
+  // Therefore, when we parse one, we have to be very careful to avoid using
+  // any descriptor-based operations, since this might cause infinite recursion
+  // or deadlock.
+  InitGeneratedPoolOnce();
+  GOOGLE_CHECK(generated_database_->Add(encoded_file_descriptor, size));
+}
+
+
+// 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_);
+  tables_->known_bad_symbols_.clear();
+  tables_->known_bad_files_.clear();
+  const FileDescriptor* result = tables_->FindFile(name);
+  if (result != NULL) return result;
+  if (underlay_ != NULL) {
+    result = underlay_->FindFileByName(name);
+    if (result != NULL) return result;
+  }
+  if (TryFindFileInFallbackDatabase(name)) {
+    result = tables_->FindFile(name);
+    if (result != NULL) return result;
+  }
+  return NULL;
+}
+
+const FileDescriptor* DescriptorPool::FindFileContainingSymbol(
+    const string& symbol_name) const {
+  MutexLockMaybe lock(mutex_);
+  tables_->known_bad_symbols_.clear();
+  tables_->known_bad_files_.clear();
+  Symbol result = tables_->FindSymbol(symbol_name);
+  if (!result.IsNull()) return result.GetFile();
+  if (underlay_ != NULL) {
+    const FileDescriptor* file_result =
+      underlay_->FindFileContainingSymbol(symbol_name);
+    if (file_result != NULL) return file_result;
+  }
+  if (TryFindSymbolInFallbackDatabase(symbol_name)) {
+    result = tables_->FindSymbol(symbol_name);
+    if (!result.IsNull()) return result.GetFile();
+  }
+  return NULL;
+}
+
+const Descriptor* DescriptorPool::FindMessageTypeByName(
+    const string& name) const {
+  Symbol result = tables_->FindByNameHelper(this, name);
+  return (result.type == Symbol::MESSAGE) ? result.descriptor : NULL;
+}
+
+const FieldDescriptor* DescriptorPool::FindFieldByName(
+    const string& name) const {
+  Symbol result = tables_->FindByNameHelper(this, name);
+  if (result.type == Symbol::FIELD &&
+      !result.field_descriptor->is_extension()) {
+    return result.field_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const FieldDescriptor* DescriptorPool::FindExtensionByName(
+    const string& name) const {
+  Symbol result = tables_->FindByNameHelper(this, name);
+  if (result.type == Symbol::FIELD &&
+      result.field_descriptor->is_extension()) {
+    return result.field_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const OneofDescriptor* DescriptorPool::FindOneofByName(
+    const string& name) const {
+  Symbol result = tables_->FindByNameHelper(this, name);
+  return (result.type == Symbol::ONEOF) ? result.oneof_descriptor : NULL;
+}
+
+const EnumDescriptor* DescriptorPool::FindEnumTypeByName(
+    const string& name) const {
+  Symbol result = tables_->FindByNameHelper(this, name);
+  return (result.type == Symbol::ENUM) ? result.enum_descriptor : NULL;
+}
+
+const EnumValueDescriptor* DescriptorPool::FindEnumValueByName(
+    const string& name) const {
+  Symbol result = tables_->FindByNameHelper(this, name);
+  return (result.type == Symbol::ENUM_VALUE) ?
+    result.enum_value_descriptor : NULL;
+}
+
+const ServiceDescriptor* DescriptorPool::FindServiceByName(
+    const string& name) const {
+  Symbol result = tables_->FindByNameHelper(this, name);
+  return (result.type == Symbol::SERVICE) ? result.service_descriptor : NULL;
+}
+
+const MethodDescriptor* DescriptorPool::FindMethodByName(
+    const string& name) const {
+  Symbol result = tables_->FindByNameHelper(this, name);
+  return (result.type == Symbol::METHOD) ? result.method_descriptor : NULL;
+}
+
+const FieldDescriptor* DescriptorPool::FindExtensionByNumber(
+    const Descriptor* extendee, int number) const {
+  MutexLockMaybe lock(mutex_);
+  tables_->known_bad_symbols_.clear();
+  tables_->known_bad_files_.clear();
+  const FieldDescriptor* result = tables_->FindExtension(extendee, number);
+  if (result != NULL) {
+    return result;
+  }
+  if (underlay_ != NULL) {
+    result = underlay_->FindExtensionByNumber(extendee, number);
+    if (result != NULL) return result;
+  }
+  if (TryFindExtensionInFallbackDatabase(extendee, number)) {
+    result = tables_->FindExtension(extendee, number);
+    if (result != NULL) {
+      return result;
+    }
+  }
+  return NULL;
+}
+
+void DescriptorPool::FindAllExtensions(
+    const Descriptor* extendee, vector<const FieldDescriptor*>* out) const {
+  MutexLockMaybe lock(mutex_);
+  tables_->known_bad_symbols_.clear();
+  tables_->known_bad_files_.clear();
+
+  // Initialize tables_->extensions_ from the fallback database first
+  // (but do this only once per descriptor).
+  if (fallback_database_ != NULL &&
+      tables_->extensions_loaded_from_db_.count(extendee) == 0) {
+    vector<int> numbers;
+    if (fallback_database_->FindAllExtensionNumbers(extendee->full_name(),
+                                                    &numbers)) {
+      for (int i = 0; i < numbers.size(); ++i) {
+        int number = numbers[i];
+        if (tables_->FindExtension(extendee, number) == NULL) {
+          TryFindExtensionInFallbackDatabase(extendee, number);
+        }
+      }
+      tables_->extensions_loaded_from_db_.insert(extendee);
+    }
+  }
+
+  tables_->FindAllExtensions(extendee, out);
+  if (underlay_ != NULL) {
+    underlay_->FindAllExtensions(extendee, out);
+  }
+}
+
+
+// -------------------------------------------------------------------
+
+const FieldDescriptor*
+Descriptor::FindFieldByNumber(int key) const {
+  const FieldDescriptor* result =
+    file()->tables_->FindFieldByNumber(this, key);
+  if (result == NULL || result->is_extension()) {
+    return NULL;
+  } else {
+    return result;
+  }
+}
+
+const FieldDescriptor*
+Descriptor::FindFieldByLowercaseName(const string& key) const {
+  const FieldDescriptor* result =
+    file()->tables_->FindFieldByLowercaseName(this, key);
+  if (result == NULL || result->is_extension()) {
+    return NULL;
+  } else {
+    return result;
+  }
+}
+
+const FieldDescriptor*
+Descriptor::FindFieldByCamelcaseName(const string& key) const {
+  const FieldDescriptor* result =
+    file()->tables_->FindFieldByCamelcaseName(this, key);
+  if (result == NULL || result->is_extension()) {
+    return NULL;
+  } else {
+    return result;
+  }
+}
+
+const FieldDescriptor*
+Descriptor::FindFieldByName(const string& key) const {
+  Symbol result =
+    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
+  if (!result.IsNull() && !result.field_descriptor->is_extension()) {
+    return result.field_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const OneofDescriptor*
+Descriptor::FindOneofByName(const string& key) const {
+  Symbol result =
+    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ONEOF);
+  if (!result.IsNull()) {
+    return result.oneof_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const FieldDescriptor*
+Descriptor::FindExtensionByName(const string& key) const {
+  Symbol result =
+    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
+  if (!result.IsNull() && result.field_descriptor->is_extension()) {
+    return result.field_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const FieldDescriptor*
+Descriptor::FindExtensionByLowercaseName(const string& key) const {
+  const FieldDescriptor* result =
+    file()->tables_->FindFieldByLowercaseName(this, key);
+  if (result == NULL || !result->is_extension()) {
+    return NULL;
+  } else {
+    return result;
+  }
+}
+
+const FieldDescriptor*
+Descriptor::FindExtensionByCamelcaseName(const string& key) const {
+  const FieldDescriptor* result =
+    file()->tables_->FindFieldByCamelcaseName(this, key);
+  if (result == NULL || !result->is_extension()) {
+    return NULL;
+  } else {
+    return result;
+  }
+}
+
+const Descriptor*
+Descriptor::FindNestedTypeByName(const string& key) const {
+  Symbol result =
+    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE);
+  if (!result.IsNull()) {
+    return result.descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const EnumDescriptor*
+Descriptor::FindEnumTypeByName(const string& key) const {
+  Symbol result =
+    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM);
+  if (!result.IsNull()) {
+    return result.enum_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const EnumValueDescriptor*
+Descriptor::FindEnumValueByName(const string& key) const {
+  Symbol result =
+    file()->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 {
+  Symbol result =
+    file()->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 {
+  return file()->tables_->FindEnumValueByNumber(this, key);
+}
+
+const MethodDescriptor*
+ServiceDescriptor::FindMethodByName(const string& key) const {
+  Symbol result =
+    file()->tables_->FindNestedSymbolOfType(this, key, Symbol::METHOD);
+  if (!result.IsNull()) {
+    return result.method_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const Descriptor*
+FileDescriptor::FindMessageTypeByName(const string& key) const {
+  Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::MESSAGE);
+  if (!result.IsNull()) {
+    return result.descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const EnumDescriptor*
+FileDescriptor::FindEnumTypeByName(const string& key) const {
+  Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::ENUM);
+  if (!result.IsNull()) {
+    return result.enum_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const EnumValueDescriptor*
+FileDescriptor::FindEnumValueByName(const string& key) const {
+  Symbol result =
+    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 {
+  Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::SERVICE);
+  if (!result.IsNull()) {
+    return result.service_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const FieldDescriptor*
+FileDescriptor::FindExtensionByName(const string& key) const {
+  Symbol result = tables_->FindNestedSymbolOfType(this, key, Symbol::FIELD);
+  if (!result.IsNull() && result.field_descriptor->is_extension()) {
+    return result.field_descriptor;
+  } else {
+    return NULL;
+  }
+}
+
+const FieldDescriptor*
+FileDescriptor::FindExtensionByLowercaseName(const string& key) const {
+  const FieldDescriptor* result = tables_->FindFieldByLowercaseName(this, key);
+  if (result == NULL || !result->is_extension()) {
+    return NULL;
+  } else {
+    return result;
+  }
+}
+
+const FieldDescriptor*
+FileDescriptor::FindExtensionByCamelcaseName(const string& key) const {
+  const FieldDescriptor* result = tables_->FindFieldByCamelcaseName(this, key);
+  if (result == NULL || !result->is_extension()) {
+    return NULL;
+  } else {
+    return result;
+  }
+}
+
+const Descriptor::ExtensionRange*
+Descriptor::FindExtensionRangeContainingNumber(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 extension_range(i);
+    }
+  }
+  return NULL;
+}
+
+// -------------------------------------------------------------------
+
+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::IsSubSymbolOfBuiltType(const string& name) const {
+  string prefix = name;
+  for (;;) {
+    string::size_type dot_pos = prefix.find_last_of('.');
+    if (dot_pos == string::npos) {
+      break;
+    }
+    prefix = prefix.substr(0, dot_pos);
+    Symbol symbol = tables_->FindSymbol(prefix);
+    // If the symbol type is anything other than PACKAGE, then its complete
+    // definition is already known.
+    if (!symbol.IsNull() && symbol.type != Symbol::PACKAGE) {
+      return true;
+    }
+  }
+  if (underlay_ != NULL) {
+    // Check to see if any prefix of this symbol exists in the underlay.
+    return underlay_->IsSubSymbolOfBuiltType(name);
+  }
+  return false;
+}
+
+bool DescriptorPool::TryFindSymbolInFallbackDatabase(const string& name) const {
+  if (fallback_database_ == NULL) return false;
+
+  if (tables_->known_bad_symbols_.count(name) > 0) return false;
+
+  FileDescriptorProto file_proto;
+  if (// We skip looking in the fallback database if the name is a sub-symbol
+      // of any descriptor that already exists in the descriptor pool (except
+      // for package descriptors).  This is valid because all symbols except
+      // for packages are defined in a single file, so if the symbol exists
+      // then we should already have its definition.
+      //
+      // The other reason to do this is to support "overriding" type
+      // definitions by merging two databases that define the same type.  (Yes,
+      // people do this.)  The main difficulty with making this work is that
+      // FindFileContainingSymbol() is allowed to return both false positives
+      // (e.g., SimpleDescriptorDatabase, UpgradedDescriptorDatabase) and false
+      // negatives (e.g. ProtoFileParser, SourceTreeDescriptorDatabase).
+      // When two such databases are merged, looking up a non-existent
+      // sub-symbol of a type that already exists in the descriptor pool can
+      // result in an attempt to load multiple definitions of the same type.
+      // The check below avoids this.
+      IsSubSymbolOfBuiltType(name)
+
+      // Look up file containing this symbol in fallback database.
+      || !fallback_database_->FindFileContainingSymbol(name, &file_proto)
+
+      // Check if we've already built this file. If so, it apparently doesn't
+      // contain the symbol we're looking for.  Some DescriptorDatabases
+      // return false positives.
+      || tables_->FindFile(file_proto.name()) != NULL
+
+      // Build the file.
+      || BuildFileFromDatabase(file_proto) == NULL) {
+    tables_->known_bad_symbols_.insert(name);
+    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 < public_dependency_count(); i++) {
+    proto->add_public_dependency(public_dependencies_[i]);
+  }
+
+  for (int i = 0; i < weak_dependency_count(); i++) {
+    proto->add_weak_dependency(weak_dependencies_[i]);
+  }
+
+  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 FileDescriptor::CopySourceCodeInfoTo(FileDescriptorProto* proto) const {
+  if (source_code_info_ != &SourceCodeInfo::default_instance()) {
+    proto->mutable_source_code_info()->CopyFrom(*source_code_info_);
+  }
+}
+
+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 < oneof_decl_count(); i++) {
+    oneof_decl(i)->CopyTo(proto->add_oneof_decl());
+  }
+  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());
+
+  // Some compilers do not allow static_cast directly between two enum types,
+  // so we must cast to int first.
+  proto->set_label(static_cast<FieldDescriptorProto::Label>(
+                     implicit_cast<int>(label())));
+  proto->set_type(static_cast<FieldDescriptorProto::Type>(
+                    implicit_cast<int>(type())));
+
+  if (is_extension()) {
+    if (!containing_type()->is_unqualified_placeholder_) {
+      proto->set_extendee(".");
+    }
+    proto->mutable_extendee()->append(containing_type()->full_name());
+  }
+
+  if (cpp_type() == CPPTYPE_MESSAGE) {
+    if (message_type()->is_placeholder_) {
+      // We don't actually know if the type is a message type.  It could be
+      // an enum.
+      proto->clear_type();
+    }
+
+    if (!message_type()->is_unqualified_placeholder_) {
+      proto->set_type_name(".");
+    }
+    proto->mutable_type_name()->append(message_type()->full_name());
+  } else if (cpp_type() == CPPTYPE_ENUM) {
+    if (!enum_type()->is_unqualified_placeholder_) {
+      proto->set_type_name(".");
+    }
+    proto->mutable_type_name()->append(enum_type()->full_name());
+  }
+
+  if (has_default_value()) {
+    proto->set_default_value(DefaultValueAsString(false));
+  }
+
+  if (containing_oneof() != NULL && !is_extension()) {
+    proto->set_oneof_index(containing_oneof()->index());
+  }
+
+  if (&options() != &FieldOptions::default_instance()) {
+    proto->mutable_options()->CopyFrom(options());
+  }
+}
+
+void OneofDescriptor::CopyTo(OneofDescriptorProto* proto) const {
+  proto->set_name(name());
+}
+
+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());
+
+  if (!input_type()->is_unqualified_placeholder_) {
+    proto->set_input_type(".");
+  }
+  proto->mutable_input_type()->append(input_type()->full_name());
+
+  if (!output_type()->is_unqualified_placeholder_) {
+    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(int depth,
+                     const Message &options,
+                     vector<string> *option_entries) {
+  option_entries->clear();
+  const Reflection* reflection = options.GetReflection();
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(options, &fields);
+  for (int i = 0; i < fields.size(); i++) {
+    int count = 1;
+    bool repeated = false;
+    if (fields[i]->is_repeated()) {
+      count = reflection->FieldSize(options, fields[i]);
+      repeated = true;
+    }
+    for (int j = 0; j < count; j++) {
+      string fieldval;
+      if (fields[i]->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+        string tmp;
+        TextFormat::Printer printer;
+        printer.SetInitialIndentLevel(depth + 1);
+        printer.PrintFieldValueToString(options, fields[i],
+                                        repeated ? j : -1, &tmp);
+        fieldval.append("{\n");
+        fieldval.append(tmp);
+        fieldval.append(depth * 2, ' ');
+        fieldval.append("}");
+      } else {
+        TextFormat::PrintFieldValueToString(options, fields[i],
+                                            repeated ? j : -1, &fieldval);
+      }
+      string name;
+      if (fields[i]->is_extension()) {
+        name = "(." + fields[i]->full_name() + ")";
+      } else {
+        name = fields[i]->name();
+      }
+      option_entries->push_back(name + " = " + fieldval);
+    }
+  }
+  return !option_entries->empty();
+}
+
+// Formats options that all appear together in brackets. Does not include
+// brackets.
+bool FormatBracketedOptions(int depth, const Message &options, string *output) {
+  vector<string> all_options;
+  if (RetrieveOptions(depth, options, &all_options)) {
+    output->append(Join(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(depth, 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";
+
+  set<int> public_dependencies;
+  set<int> weak_dependencies;
+  public_dependencies.insert(public_dependencies_,
+                             public_dependencies_ + public_dependency_count_);
+  weak_dependencies.insert(weak_dependencies_,
+                           weak_dependencies_ + weak_dependency_count_);
+
+  for (int i = 0; i < dependency_count(); i++) {
+    if (public_dependencies.count(i) > 0) {
+      strings::SubstituteAndAppend(&contents, "import public \"$0\";\n",
+                                   dependency(i)->name());
+    } else if (weak_dependencies.count(i) > 0) {
+      strings::SubstituteAndAppend(&contents, "import weak \"$0\";\n",
+                                   dependency(i)->name());
+    } else {
+      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, FieldDescriptor::PRINT_LABEL, &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++) {
+    if (field(i)->containing_oneof() == NULL) {
+      field(i)->DebugString(depth, FieldDescriptor::PRINT_LABEL, contents);
+    } else if (field(i)->containing_oneof()->field(0) == field(i)) {
+      // This is the first field in this oneof, so print the whole oneof.
+      field(i)->containing_oneof()->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, FieldDescriptor::PRINT_LABEL, 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, PRINT_LABEL, &contents);
+  if (is_extension()) {
+    contents.append("}\n");
+  }
+  return contents;
+}
+
+void FieldDescriptor::DebugString(int depth,
+                                  PrintLabelFlag print_label_flag,
+                                  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()];
+  }
+
+  string label;
+  if (print_label_flag == PRINT_LABEL) {
+    label = kLabelToName[this->label()];
+    label.push_back(' ');
+  }
+
+  strings::SubstituteAndAppend(contents, "$0$1$2 $3 = $4",
+                               prefix,
+                               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(depth, 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 OneofDescriptor::DebugString() const {
+  string contents;
+  DebugString(0, &contents);
+  return contents;
+}
+
+void OneofDescriptor::DebugString(int depth, string* contents) const {
+  string prefix(depth * 2, ' ');
+  ++depth;
+  strings::SubstituteAndAppend(
+      contents, "$0 oneof $1 {\n", prefix, name());
+  for (int i = 0; i < field_count(); i++) {
+    field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents);
+  }
+  strings::SubstituteAndAppend(contents, "$0}\n", prefix);
+}
+
+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(depth, 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");
+  }
+}
+
+
+// Location methods ===============================================
+
+bool FileDescriptor::GetSourceLocation(const vector<int>& path,
+                                       SourceLocation* out_location) const {
+  GOOGLE_CHECK_NOTNULL(out_location);
+  if (source_code_info_) {
+    if (const SourceCodeInfo_Location* loc =
+        tables_->GetSourceLocation(path, source_code_info_)) {
+      const RepeatedField<int32>& span = loc->span();
+      if (span.size() == 3 || span.size() == 4) {
+        out_location->start_line   = span.Get(0);
+        out_location->start_column = span.Get(1);
+        out_location->end_line     = span.Get(span.size() == 3 ? 0 : 2);
+        out_location->end_column   = span.Get(span.size() - 1);
+
+        out_location->leading_comments = loc->leading_comments();
+        out_location->trailing_comments = loc->trailing_comments();
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+bool FieldDescriptor::is_packed() const {
+  return is_packable() && (options_ != NULL) && options_->packed();
+}
+
+bool Descriptor::GetSourceLocation(SourceLocation* out_location) const {
+  vector<int> path;
+  GetLocationPath(&path);
+  return file()->GetSourceLocation(path, out_location);
+}
+
+bool FieldDescriptor::GetSourceLocation(SourceLocation* out_location) const {
+  vector<int> path;
+  GetLocationPath(&path);
+  return file()->GetSourceLocation(path, out_location);
+}
+
+bool OneofDescriptor::GetSourceLocation(SourceLocation* out_location) const {
+  vector<int> path;
+  GetLocationPath(&path);
+  return containing_type()->file()->GetSourceLocation(path, out_location);
+}
+
+bool EnumDescriptor::GetSourceLocation(SourceLocation* out_location) const {
+  vector<int> path;
+  GetLocationPath(&path);
+  return file()->GetSourceLocation(path, out_location);
+}
+
+bool MethodDescriptor::GetSourceLocation(SourceLocation* out_location) const {
+  vector<int> path;
+  GetLocationPath(&path);
+  return service()->file()->GetSourceLocation(path, out_location);
+}
+
+bool ServiceDescriptor::GetSourceLocation(SourceLocation* out_location) const {
+  vector<int> path;
+  GetLocationPath(&path);
+  return file()->GetSourceLocation(path, out_location);
+}
+
+bool EnumValueDescriptor::GetSourceLocation(
+    SourceLocation* out_location) const {
+  vector<int> path;
+  GetLocationPath(&path);
+  return type()->file()->GetSourceLocation(path, out_location);
+}
+
+void Descriptor::GetLocationPath(vector<int>* output) const {
+  if (containing_type()) {
+    containing_type()->GetLocationPath(output);
+    output->push_back(DescriptorProto::kNestedTypeFieldNumber);
+    output->push_back(index());
+  } else {
+    output->push_back(FileDescriptorProto::kMessageTypeFieldNumber);
+    output->push_back(index());
+  }
+}
+
+void FieldDescriptor::GetLocationPath(vector<int>* output) const {
+  if (is_extension()) {
+    if (extension_scope() == NULL) {
+      output->push_back(FileDescriptorProto::kExtensionFieldNumber);
+      output->push_back(index());
+    } else {
+      extension_scope()->GetLocationPath(output);
+      output->push_back(DescriptorProto::kExtensionFieldNumber);
+      output->push_back(index());
+    }
+  } else {
+    containing_type()->GetLocationPath(output);
+    output->push_back(DescriptorProto::kFieldFieldNumber);
+    output->push_back(index());
+  }
+}
+
+void OneofDescriptor::GetLocationPath(vector<int>* output) const {
+  containing_type()->GetLocationPath(output);
+  output->push_back(DescriptorProto::kOneofDeclFieldNumber);
+  output->push_back(index());
+}
+
+void EnumDescriptor::GetLocationPath(vector<int>* output) const {
+  if (containing_type()) {
+    containing_type()->GetLocationPath(output);
+    output->push_back(DescriptorProto::kEnumTypeFieldNumber);
+    output->push_back(index());
+  } else {
+    output->push_back(FileDescriptorProto::kEnumTypeFieldNumber);
+    output->push_back(index());
+  }
+}
+
+void EnumValueDescriptor::GetLocationPath(vector<int>* output) const {
+  type()->GetLocationPath(output);
+  output->push_back(EnumDescriptorProto::kValueFieldNumber);
+  output->push_back(index());
+}
+
+void ServiceDescriptor::GetLocationPath(vector<int>* output) const {
+  output->push_back(FileDescriptorProto::kServiceFieldNumber);
+  output->push_back(index());
+}
+
+void MethodDescriptor::GetLocationPath(vector<int>* output) const {
+  service()->GetLocationPath(output);
+  output->push_back(ServiceDescriptorProto::kMethodFieldNumber);
+  output->push_back(index());
+}
+
+// ===================================================================
+
+namespace {
+
+// Represents an options message to interpret. Extension names in the option
+// name are respolved relative to name_scope. element_name and orig_opt are
+// used only for error reporting (since the parser records locations against
+// pointers in the original options, not the mutable copy). The Message must be
+// one of the Options messages in descriptor.proto.
+struct OptionsToInterpret {
+  OptionsToInterpret(const string& ns,
+                     const string& el,
+                     const Message* orig_opt,
+                     Message* opt)
+      : name_scope(ns),
+        element_name(el),
+        original_options(orig_opt),
+        options(opt) {
+  }
+  string name_scope;
+  string element_name;
+  const Message* original_options;
+  Message* options;
+};
+
+}  // namespace
+
+class DescriptorBuilder {
+ public:
+  DescriptorBuilder(const DescriptorPool* pool,
+                    DescriptorPool::Tables* tables,
+                    DescriptorPool::ErrorCollector* error_collector);
+  ~DescriptorBuilder();
+
+  const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
+
+ private:
+  friend class OptionInterpreter;
+
+  const DescriptorPool* pool_;
+  DescriptorPool::Tables* tables_;  // for convenience
+  DescriptorPool::ErrorCollector* error_collector_;
+
+  // As we build descriptors we store copies of the options messages in
+  // them. We put pointers to those copies in this vector, as we build, so we
+  // can later (after cross-linking) interpret those options.
+  vector<OptionsToInterpret> options_to_interpret_;
+
+  bool had_errors_;
+  string filename_;
+  FileDescriptor* file_;
+  FileDescriptorTables* file_tables_;
+  set<const FileDescriptor*> dependencies_;
+
+  // unused_dependency_ is used to record the unused imported files.
+  // Note: public import is not considered.
+  set<const FileDescriptor*> unused_dependency_;
+
+  // 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.
+  // possible_undeclared_dependency_name_ is the name of the symbol that was
+  // actually found in possible_undeclared_dependency_, which may be a parent
+  // of the symbol actually looked for.
+  const FileDescriptor* possible_undeclared_dependency_;
+  string possible_undeclared_dependency_name_;
+
+  // If LookupSymbol() could resolve a symbol which is not defined,
+  // record the resolved name.  This is only used by AddNotDefinedError()
+  // to report a more useful error message.
+  string undefine_resolved_name_;
+
+  void AddError(const string& element_name,
+                const Message& descriptor,
+                DescriptorPool::ErrorCollector::ErrorLocation location,
+                const string& error);
+  void AddError(const string& element_name,
+                const Message& descriptor,
+                DescriptorPool::ErrorCollector::ErrorLocation location,
+                const char* error);
+  void AddRecursiveImportError(const FileDescriptorProto& proto, int from_here);
+  void AddTwiceListedError(const FileDescriptorProto& proto, int index);
+  void AddImportError(const FileDescriptorProto& proto, int index);
+
+  // 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);
+
+  void AddWarning(const string& element_name, const Message& descriptor,
+                  DescriptorPool::ErrorCollector::ErrorLocation location,
+                  const string& error);
+
+  // 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);
+
+  // Helper function which finds all public dependencies of the given file, and
+  // stores the them in the dependencies_ set in the builder.
+  void RecordPublicDependencies(const FileDescriptor* file);
+
+  // 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 does not require that the symbol is in one of the
+  // file's declared dependencies.
+  Symbol FindSymbolNotEnforcingDeps(const string& name);
+
+  // This implements the body of FindSymbolNotEnforcingDeps().
+  Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool,
+                                          const string& name);
+
+  // Like FindSymbol(), but looks up the name relative to some other symbol
+  // name.  This first searches siblings 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").  If AllowUnknownDependencies() has been called
+  // on the DescriptorPool, this will generate a placeholder type if
+  // the name is not found (unless the name itself is malformed).  The
+  // placeholder_type parameter indicates what kind of placeholder should be
+  // constructed in this case.  The resolve_mode parameter determines whether
+  // any symbol is returned, or only symbols that are types.  Note, however,
+  // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode,
+  // if it believes that's all it could refer to.  The caller should always
+  // check that it receives the type of symbol it was expecting.
+  enum PlaceholderType {
+    PLACEHOLDER_MESSAGE,
+    PLACEHOLDER_ENUM,
+    PLACEHOLDER_EXTENDABLE_MESSAGE
+  };
+  enum ResolveMode {
+    LOOKUP_ALL, LOOKUP_TYPES
+  };
+  Symbol LookupSymbol(const string& name, const string& relative_to,
+                      PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE,
+                      ResolveMode resolve_mode = LOOKUP_ALL);
+
+  // Like LookupSymbol() but will not return a placeholder even if
+  // AllowUnknownDependencies() has been used.
+  Symbol LookupSymbolNoPlaceholder(const string& name,
+                                   const string& relative_to,
+                                   ResolveMode resolve_mode = LOOKUP_ALL);
+
+  // Creates a placeholder type suitable for return from LookupSymbol().  May
+  // return kNullSymbol if the name is not a valid type name.
+  Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type);
+
+  // Creates a placeholder file.  Never returns NULL.  This is used when an
+  // import is not found and AllowUnknownDependencies() is enabled.
+  const FileDescriptor* NewPlaceholderFile(const string& name);
+
+  // Calls tables_->AddSymbol() and records an error if it fails.  Returns
+  // true if successful or false if failed, though most callers can ignore
+  // the return value since an error has already been recorded.
+  bool 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);
+
+  // Like ValidateSymbolName(), but the name is allowed to contain periods and
+  // an error is indicated by returning false (not recording the error).
+  bool ValidateQualifiedName(const string& name);
+
+  // 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);
+  }
+
+  // Allocates a copy of orig_options in tables_ and stores it in the
+  // descriptor. Remembers its uninterpreted options, to be interpreted
+  // later. DescriptorT must be one of the Descriptor messages from
+  // descriptor.proto.
+  template<class DescriptorT> void AllocateOptions(
+      const typename DescriptorT::OptionsType& orig_options,
+      DescriptorT* descriptor);
+  // Specialization for FileOptions.
+  void AllocateOptions(const FileOptions& orig_options,
+                       FileDescriptor* descriptor);
+
+  // Implementation for AllocateOptions(). Don't call this directly.
+  template<class DescriptorT> void AllocateOptionsImpl(
+      const string& name_scope,
+      const string& element_name,
+      const typename DescriptorT::OptionsType& orig_options,
+      DescriptorT* descriptor);
+
+  // 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 BuildOneof(const OneofDescriptorProto& proto,
+                  Descriptor* parent,
+                  OneofDescriptor* 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 LogUnusedDependency(const FileDescriptor* result);
+
+  // Must be run only after building.
+  //
+  // NOTE: Options will not be available during cross-linking, as they
+  // have not yet been interpreted. Defer any handling of options to the
+  // Validate*Options methods.
+  void CrossLinkFile(FileDescriptor* file, const FileDescriptorProto& proto);
+  void CrossLinkMessage(Descriptor* message, const DescriptorProto& proto);
+  void CrossLinkField(FieldDescriptor* field,
+                      const FieldDescriptorProto& proto);
+  void CrossLinkEnum(EnumDescriptor* enum_type,
+                     const EnumDescriptorProto& proto);
+  void CrossLinkEnumValue(EnumValueDescriptor* enum_value,
+                          const EnumValueDescriptorProto& proto);
+  void CrossLinkService(ServiceDescriptor* service,
+                        const ServiceDescriptorProto& proto);
+  void CrossLinkMethod(MethodDescriptor* method,
+                       const MethodDescriptorProto& proto);
+
+  // Must be run only after cross-linking.
+  void InterpretOptions();
+
+  // A helper class for interpreting options.
+  class OptionInterpreter {
+   public:
+    // Creates an interpreter that operates in the context of the pool of the
+    // specified builder, which must not be NULL. We don't take ownership of the
+    // builder.
+    explicit OptionInterpreter(DescriptorBuilder* builder);
+
+    ~OptionInterpreter();
+
+    // Interprets the uninterpreted options in the specified Options message.
+    // On error, calls AddError() on the underlying builder and returns false.
+    // Otherwise returns true.
+    bool InterpretOptions(OptionsToInterpret* options_to_interpret);
+
+    class AggregateOptionFinder;
+
+   private:
+    // Interprets uninterpreted_option_ on the specified message, which
+    // must be the mutable copy of the original options message to which
+    // uninterpreted_option_ belongs.
+    bool InterpretSingleOption(Message* options);
+
+    // Adds the uninterpreted_option to the given options message verbatim.
+    // Used when AllowUnknownDependencies() is in effect and we can't find
+    // the option's definition.
+    void AddWithoutInterpreting(const UninterpretedOption& uninterpreted_option,
+                                Message* options);
+
+    // A recursive helper function that drills into the intermediate fields
+    // in unknown_fields to check if field innermost_field is set on the
+    // innermost message. Returns false and sets an error if so.
+    bool ExamineIfOptionIsSet(
+        vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter,
+        vector<const FieldDescriptor*>::const_iterator intermediate_fields_end,
+        const FieldDescriptor* innermost_field, const string& debug_msg_name,
+        const UnknownFieldSet& unknown_fields);
+
+    // Validates the value for the option field of the currently interpreted
+    // option and then sets it on the unknown_field.
+    bool SetOptionValue(const FieldDescriptor* option_field,
+                        UnknownFieldSet* unknown_fields);
+
+    // Parses an aggregate value for a CPPTYPE_MESSAGE option and
+    // saves it into *unknown_fields.
+    bool SetAggregateOption(const FieldDescriptor* option_field,
+                            UnknownFieldSet* unknown_fields);
+
+    // Convenience functions to set an int field the right way, depending on
+    // its wire type (a single int CppType can represent multiple wire types).
+    void SetInt32(int number, int32 value, FieldDescriptor::Type type,
+                  UnknownFieldSet* unknown_fields);
+    void SetInt64(int number, int64 value, FieldDescriptor::Type type,
+                  UnknownFieldSet* unknown_fields);
+    void SetUInt32(int number, uint32 value, FieldDescriptor::Type type,
+                   UnknownFieldSet* unknown_fields);
+    void SetUInt64(int number, uint64 value, FieldDescriptor::Type type,
+                   UnknownFieldSet* unknown_fields);
+
+    // A helper function that adds an error at the specified location of the
+    // option we're currently interpreting, and returns false.
+    bool AddOptionError(DescriptorPool::ErrorCollector::ErrorLocation location,
+                        const string& msg) {
+      builder_->AddError(options_to_interpret_->element_name,
+                         *uninterpreted_option_, location, msg);
+      return false;
+    }
+
+    // A helper function that adds an error at the location of the option name
+    // and returns false.
+    bool AddNameError(const string& msg) {
+      return AddOptionError(DescriptorPool::ErrorCollector::OPTION_NAME, msg);
+    }
+
+    // A helper function that adds an error at the location of the option name
+    // and returns false.
+    bool AddValueError(const string& msg) {
+      return AddOptionError(DescriptorPool::ErrorCollector::OPTION_VALUE, msg);
+    }
+
+    // We interpret against this builder's pool. Is never NULL. We don't own
+    // this pointer.
+    DescriptorBuilder* builder_;
+
+    // The options we're currently interpreting, or NULL if we're not in a call
+    // to InterpretOptions.
+    const OptionsToInterpret* options_to_interpret_;
+
+    // The option we're currently interpreting within options_to_interpret_, or
+    // NULL if we're not in a call to InterpretOptions(). This points to a
+    // submessage of the original option, not the mutable copy. Therefore we
+    // can use it to find locations recorded by the parser.
+    const UninterpretedOption* uninterpreted_option_;
+
+    // Factory used to create the dynamic messages we need to parse
+    // any aggregate option values we encounter.
+    DynamicMessageFactory dynamic_factory_;
+
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OptionInterpreter);
+  };
+
+  // Work-around for broken compilers:  According to the C++ standard,
+  // OptionInterpreter should have access to the private members of any class
+  // which has declared DescriptorBuilder as a friend.  Unfortunately some old
+  // versions of GCC and other compilers do not implement this correctly.  So,
+  // we have to have these intermediate methods to provide access.  We also
+  // redundantly declare OptionInterpreter a friend just to make things extra
+  // clear for these bad compilers.
+  friend class OptionInterpreter;
+  friend class OptionInterpreter::AggregateOptionFinder;
+
+  static inline bool get_allow_unknown(const DescriptorPool* pool) {
+    return pool->allow_unknown_;
+  }
+  static inline bool get_enforce_weak(const DescriptorPool* pool) {
+    return pool->enforce_weak_;
+  }
+  static inline bool get_is_placeholder(const Descriptor* descriptor) {
+    return descriptor->is_placeholder_;
+  }
+  static inline void assert_mutex_held(const DescriptorPool* pool) {
+    if (pool->mutex_ != NULL) {
+      pool->mutex_->AssertHeld();
+    }
+  }
+
+  // Must be run only after options have been interpreted.
+  //
+  // NOTE: Validation code must only reference the options in the mutable
+  // descriptors, which are the ones that have been interpreted. The const
+  // proto references are passed in only so they can be provided to calls to
+  // AddError(). Do not look at their options, which have not been interpreted.
+  void ValidateFileOptions(FileDescriptor* file,
+                           const FileDescriptorProto& proto);
+  void ValidateMessageOptions(Descriptor* message,
+                              const DescriptorProto& proto);
+  void ValidateFieldOptions(FieldDescriptor* field,
+                            const FieldDescriptorProto& proto);
+  void ValidateEnumOptions(EnumDescriptor* enm,
+                           const EnumDescriptorProto& proto);
+  void ValidateEnumValueOptions(EnumValueDescriptor* enum_value,
+                                const EnumValueDescriptorProto& proto);
+  void ValidateServiceOptions(ServiceDescriptor* service,
+                              const ServiceDescriptorProto& proto);
+  void ValidateMethodOptions(MethodDescriptor* method,
+                             const MethodDescriptorProto& proto);
+
+  void ValidateMapKey(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.
+  tables_->known_bad_symbols_.clear();
+  tables_->known_bad_files_.clear();
+  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.
+  tables_->known_bad_symbols_.clear();
+  tables_->known_bad_files_.clear();
+  return DescriptorBuilder(this, tables_.get(),
+                           error_collector).BuildFile(proto);
+}
+
+const FileDescriptor* DescriptorPool::BuildFileFromDatabase(
+    const FileDescriptorProto& proto) const {
+  mutex_->AssertHeld();
+  if (tables_->known_bad_files_.count(proto.name()) > 0) {
+    return NULL;
+  }
+  const FileDescriptor* result =
+      DescriptorBuilder(this, tables_.get(),
+                        default_error_collector_).BuildFile(proto);
+  if (result == NULL) {
+    tables_->known_bad_files_.insert(proto.name());
+  }
+  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),
+    undefine_resolved_name_("") {}
+
+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::AddError(
+    const string& element_name,
+    const Message& descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location,
+    const char* error) {
+  AddError(element_name, descriptor, location, string(error));
+}
+
+void DescriptorBuilder::AddNotDefinedError(
+    const string& element_name,
+    const Message& descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location,
+    const string& undefined_symbol) {
+  if (possible_undeclared_dependency_ == NULL &&
+      undefine_resolved_name_.empty()) {
+    AddError(element_name, descriptor, location,
+             "\"" + undefined_symbol + "\" is not defined.");
+  } else {
+    if (possible_undeclared_dependency_ != NULL) {
+      AddError(element_name, descriptor, location,
+               "\"" + possible_undeclared_dependency_name_ +
+               "\" seems to be defined in \"" +
+               possible_undeclared_dependency_->name() + "\", which is not "
+               "imported by \"" + filename_ + "\".  To use it here, please "
+               "add the necessary import.");
+    }
+    if (!undefine_resolved_name_.empty()) {
+      AddError(element_name, descriptor, location,
+               "\"" + undefined_symbol + "\" is resolved to \"" +
+               undefine_resolved_name_ + "\", which is not defined. "
+               "The innermost scope is searched first in name resolution. "
+               "Consider using a leading '.'(i.e., \"."
+               + undefined_symbol +
+               "\") to start from the outermost scope.");
+    }
+  }
+}
+
+void DescriptorBuilder::AddWarning(
+    const string& element_name, const Message& descriptor,
+    DescriptorPool::ErrorCollector::ErrorLocation location,
+    const string& error) {
+  if (error_collector_ == NULL) {
+    GOOGLE_LOG(WARNING) << filename_ << " " << element_name << ": " << error;
+  } else {
+    error_collector_->AddWarning(filename_, element_name, &descriptor, location,
+                                 error);
+  }
+}
+
+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()] == '.');
+}
+
+void DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) {
+  if (file == NULL || !dependencies_.insert(file).second) return;
+  for (int i = 0; file != NULL && i < file->public_dependency_count(); i++) {
+    RecordPublicDependencies(file->public_dependency(i));
+  }
+}
+
+Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper(
+    const DescriptorPool* pool, const string& name) {
+  // If we are looking at an underlay, we must lock its mutex_, since we are
+  // accessing the underlay's tables_ directly.
+  MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_);
+
+  Symbol result = pool->tables_->FindSymbol(name);
+  if (result.IsNull() && pool->underlay_ != NULL) {
+    // Symbol not found; check the underlay.
+    result = FindSymbolNotEnforcingDepsHelper(pool->underlay_, name);
+  }
+
+  if (result.IsNull()) {
+    // In theory, we shouldn't need to check fallback_database_ because the
+    // symbol should be in one of its file's direct dependencies, and we have
+    // already loaded those by the time we get here.  But we check anyway so
+    // that we can generate better error message when dependencies are missing
+    // (i.e., "missing dependency" rather than "type is not defined").
+    if (pool->TryFindSymbolInFallbackDatabase(name)) {
+      result = pool->tables_->FindSymbol(name);
+    }
+  }
+
+  return result;
+}
+
+Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) {
+  return FindSymbolNotEnforcingDepsHelper(pool_, name);
+}
+
+Symbol DescriptorBuilder::FindSymbol(const string& name) {
+  Symbol result = FindSymbolNotEnforcingDeps(name);
+
+  if (result.IsNull()) return result;
+
+  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_ || dependencies_.count(file) > 0) {
+    unused_dependency_.erase(file);
+    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 (set<const FileDescriptor*>::const_iterator it = dependencies_.begin();
+         it != dependencies_.end(); ++it) {
+      // Note:  A dependency may be NULL if it was not found or had errors.
+      if (*it != NULL && IsInPackage(*it, name)) return result;
+    }
+  }
+
+  possible_undeclared_dependency_ = file;
+  possible_undeclared_dependency_name_ = name;
+  return kNullSymbol;
+}
+
+Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(
+    const string& name, const string& relative_to, ResolveMode resolve_mode) {
+  possible_undeclared_dependency_ = NULL;
+  undefine_resolved_name_.clear();
+
+  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.
+  string::size_type 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.
+        if (result.IsAggregate()) {
+          scope_to_try.append(name, first_part_of_name.size(),
+                              name.size() - first_part_of_name.size());
+          result = FindSymbol(scope_to_try);
+          if (result.IsNull()) {
+            undefine_resolved_name_ = scope_to_try;
+          }
+          return result;
+        } else {
+          // We found a symbol but it's not an aggregate.  Continue the loop.
+        }
+      } else {
+        if (resolve_mode == LOOKUP_TYPES && !result.IsType()) {
+          // We found a symbol but it's not a type.  Continue the loop.
+        } else {
+          return result;
+        }
+      }
+    }
+
+    // Not found.  Remove the name so we can try again.
+    scope_to_try.erase(old_size);
+  }
+}
+
+Symbol DescriptorBuilder::LookupSymbol(
+    const string& name, const string& relative_to,
+    PlaceholderType placeholder_type, ResolveMode resolve_mode) {
+  Symbol result = LookupSymbolNoPlaceholder(
+      name, relative_to, resolve_mode);
+  if (result.IsNull() && pool_->allow_unknown_) {
+    // Not found, but AllowUnknownDependencies() is enabled.  Return a
+    // placeholder instead.
+    result = NewPlaceholder(name, placeholder_type);
+  }
+  return result;
+}
+
+Symbol DescriptorBuilder::NewPlaceholder(const string& name,
+                                         PlaceholderType placeholder_type) {
+  // Compute names.
+  const string* placeholder_full_name;
+  const string* placeholder_name;
+  const string* placeholder_package;
+
+  if (!ValidateQualifiedName(name)) return kNullSymbol;
+  if (name[0] == '.') {
+    // Fully-qualified.
+    placeholder_full_name = tables_->AllocateString(name.substr(1));
+  } else {
+    placeholder_full_name = tables_->AllocateString(name);
+  }
+
+  string::size_type dotpos = placeholder_full_name->find_last_of('.');
+  if (dotpos != string::npos) {
+    placeholder_package = tables_->AllocateString(
+      placeholder_full_name->substr(0, dotpos));
+    placeholder_name = tables_->AllocateString(
+      placeholder_full_name->substr(dotpos + 1));
+  } else {
+    placeholder_package = &internal::GetEmptyString();
+    placeholder_name = placeholder_full_name;
+  }
+
+  // Create the placeholders.
+  FileDescriptor* placeholder_file = tables_->Allocate<FileDescriptor>();
+  memset(placeholder_file, 0, sizeof(*placeholder_file));
+
+  placeholder_file->source_code_info_ = &SourceCodeInfo::default_instance();
+
+  placeholder_file->name_ =
+    tables_->AllocateString(*placeholder_full_name + ".placeholder.proto");
+  placeholder_file->package_ = placeholder_package;
+  placeholder_file->pool_ = pool_;
+  placeholder_file->options_ = &FileOptions::default_instance();
+  placeholder_file->tables_ = &FileDescriptorTables::kEmpty;
+  placeholder_file->is_placeholder_ = true;
+  // All other fields are zero or NULL.
+
+  if (placeholder_type == PLACEHOLDER_ENUM) {
+    placeholder_file->enum_type_count_ = 1;
+    placeholder_file->enum_types_ =
+      tables_->AllocateArray<EnumDescriptor>(1);
+
+    EnumDescriptor* placeholder_enum = &placeholder_file->enum_types_[0];
+    memset(placeholder_enum, 0, sizeof(*placeholder_enum));
+
+    placeholder_enum->full_name_ = placeholder_full_name;
+    placeholder_enum->name_ = placeholder_name;
+    placeholder_enum->file_ = placeholder_file;
+    placeholder_enum->options_ = &EnumOptions::default_instance();
+    placeholder_enum->is_placeholder_ = true;
+    placeholder_enum->is_unqualified_placeholder_ = (name[0] != '.');
+
+    // Enums must have at least one value.
+    placeholder_enum->value_count_ = 1;
+    placeholder_enum->values_ = tables_->AllocateArray<EnumValueDescriptor>(1);
+
+    EnumValueDescriptor* placeholder_value = &placeholder_enum->values_[0];
+    memset(placeholder_value, 0, sizeof(*placeholder_value));
+
+    placeholder_value->name_ = tables_->AllocateString("PLACEHOLDER_VALUE");
+    // Note that enum value names are siblings of their type, not children.
+    placeholder_value->full_name_ =
+      placeholder_package->empty() ? placeholder_value->name_ :
+        tables_->AllocateString(*placeholder_package + ".PLACEHOLDER_VALUE");
+
+    placeholder_value->number_ = 0;
+    placeholder_value->type_ = placeholder_enum;
+    placeholder_value->options_ = &EnumValueOptions::default_instance();
+
+    return Symbol(placeholder_enum);
+  } else {
+    placeholder_file->message_type_count_ = 1;
+    placeholder_file->message_types_ =
+      tables_->AllocateArray<Descriptor>(1);
+
+    Descriptor* placeholder_message = &placeholder_file->message_types_[0];
+    memset(placeholder_message, 0, sizeof(*placeholder_message));
+
+    placeholder_message->full_name_ = placeholder_full_name;
+    placeholder_message->name_ = placeholder_name;
+    placeholder_message->file_ = placeholder_file;
+    placeholder_message->options_ = &MessageOptions::default_instance();
+    placeholder_message->is_placeholder_ = true;
+    placeholder_message->is_unqualified_placeholder_ = (name[0] != '.');
+
+    if (placeholder_type == PLACEHOLDER_EXTENDABLE_MESSAGE) {
+      placeholder_message->extension_range_count_ = 1;
+      placeholder_message->extension_ranges_ =
+        tables_->AllocateArray<Descriptor::ExtensionRange>(1);
+      placeholder_message->extension_ranges_->start = 1;
+      // kMaxNumber + 1 because ExtensionRange::end is exclusive.
+      placeholder_message->extension_ranges_->end =
+        FieldDescriptor::kMaxNumber + 1;
+    }
+
+    return Symbol(placeholder_message);
+  }
+}
+
+const FileDescriptor* DescriptorBuilder::NewPlaceholderFile(
+    const string& name) {
+  FileDescriptor* placeholder = tables_->Allocate<FileDescriptor>();
+  memset(placeholder, 0, sizeof(*placeholder));
+
+  placeholder->name_ = tables_->AllocateString(name);
+  placeholder->package_ = &internal::GetEmptyString();
+  placeholder->pool_ = pool_;
+  placeholder->options_ = &FileOptions::default_instance();
+  placeholder->tables_ = &FileDescriptorTables::kEmpty;
+  placeholder->is_placeholder_ = true;
+  // All other fields are zero or NULL.
+
+  return placeholder;
+}
+
+bool 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, symbol)) {
+    if (!file_tables_->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 {
+    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() + "\".");
+    }
+    return false;
+  }
+}
+
+void DescriptorBuilder::AddPackage(
+    const string& name, const Message& proto, const FileDescriptor* file) {
+  if (tables_->AddSymbol(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.");
+      }
+    }
+  }
+}
+
+bool DescriptorBuilder::ValidateQualifiedName(const string& name) {
+  bool last_was_period = false;
+
+  for (int i = 0; i < name.size(); i++) {
+    // I don't trust isalnum() due to locales.  :(
+    if (('a' <= name[i] && name[i] <= 'z') ||
+        ('A' <= name[i] && name[i] <= 'Z') ||
+        ('0' <= name[i] && name[i] <= '9') ||
+        (name[i] == '_')) {
+      last_was_period = false;
+    } else if (name[i] == '.') {
+      if (last_was_period) return false;
+      last_was_period = true;
+    } else {
+      return false;
+    }
+  }
+
+  return !name.empty() && !last_was_period;
+}
+
+// -------------------------------------------------------------------
+
+// This generic implementation is good for all descriptors except
+// FileDescriptor.
+template<class DescriptorT> void DescriptorBuilder::AllocateOptions(
+    const typename DescriptorT::OptionsType& orig_options,
+    DescriptorT* descriptor) {
+  AllocateOptionsImpl(descriptor->full_name(), descriptor->full_name(),
+                      orig_options, descriptor);
+}
+
+// We specialize for FileDescriptor.
+void DescriptorBuilder::AllocateOptions(const FileOptions& orig_options,
+                                        FileDescriptor* descriptor) {
+  // We add the dummy token so that LookupSymbol does the right thing.
+  AllocateOptionsImpl(descriptor->package() + ".dummy", descriptor->name(),
+                      orig_options, descriptor);
+}
+
+template<class DescriptorT> void DescriptorBuilder::AllocateOptionsImpl(
+    const string& name_scope,
+    const string& element_name,
+    const typename DescriptorT::OptionsType& orig_options,
+    DescriptorT* descriptor) {
+  // We need to use a dummy pointer to work around a bug in older versions of
+  // GCC.  Otherwise, the following two lines could be replaced with:
+  //   typename DescriptorT::OptionsType* options =
+  //       tables_->AllocateMessage<typename DescriptorT::OptionsType>();
+  typename DescriptorT::OptionsType* const dummy = NULL;
+  typename DescriptorT::OptionsType* options = tables_->AllocateMessage(dummy);
+  // Avoid using MergeFrom()/CopyFrom() in this class to make it -fno-rtti
+  // friendly. Without RTTI, MergeFrom() and CopyFrom() will fallback to the
+  // reflection based method, which requires the Descriptor. However, we are in
+  // the middle of building the descriptors, thus the deadlock.
+  options->ParseFromString(orig_options.SerializeAsString());
+  descriptor->options_ = options;
+
+  // Don't add to options_to_interpret_ unless there were uninterpreted
+  // options.  This not only avoids unnecessary work, but prevents a
+  // bootstrapping problem when building descriptors for descriptor.proto.
+  // descriptor.proto does not contain any uninterpreted options, but
+  // attempting to interpret options anyway will cause
+  // OptionsType::GetDescriptor() to be called which may then deadlock since
+  // we're still trying to build it.
+  if (options->uninterpreted_option_size() > 0) {
+    options_to_interpret_.push_back(
+        OptionsToInterpret(name_scope, element_name, &orig_options, options));
+  }
+}
+
+
+// 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);             \
+  }
+
+void DescriptorBuilder::AddRecursiveImportError(
+    const FileDescriptorProto& proto, int from_here) {
+  string error_message("File recursively imports itself: ");
+  for (int i = from_here; 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);
+}
+
+void DescriptorBuilder::AddTwiceListedError(const FileDescriptorProto& proto,
+                                            int index) {
+  AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER,
+           "Import \"" + proto.dependency(index) + "\" was listed twice.");
+}
+
+void DescriptorBuilder::AddImportError(const FileDescriptorProto& proto,
+                                       int index) {
+  string message;
+  if (pool_->fallback_database_ == NULL) {
+    message = "Import \"" + proto.dependency(index) +
+              "\" has not been loaded.";
+  } else {
+    message = "Import \"" + proto.dependency(index) +
+              "\" was not found or had errors.";
+  }
+  AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, message);
+}
+
+static bool ExistingFileMatchesProto(const FileDescriptor* existing_file,
+                                     const FileDescriptorProto& proto) {
+  FileDescriptorProto existing_proto;
+  existing_file->CopyTo(&existing_proto);
+  return existing_proto.SerializeAsString() == proto.SerializeAsString();
+}
+
+const FileDescriptor* DescriptorBuilder::BuildFile(
+    const FileDescriptorProto& proto) {
+  filename_ = proto.name();
+
+  // Check if the file already exists and is identical to the one being built.
+  // Note:  This only works if the input is canonical -- that is, it
+  //   fully-qualifies all type names, has no UninterpretedOptions, etc.
+  //   This is fine, because this idempotency "feature" really only exists to
+  //   accomodate one hack in the proto1->proto2 migration layer.
+  const FileDescriptor* existing_file = tables_->FindFile(filename_);
+  if (existing_file != NULL) {
+    // File already in pool.  Compare the existing one to the input.
+    if (ExistingFileMatchesProto(existing_file, proto)) {
+      // They're identical.  Return the existing descriptor.
+      return existing_file;
+    }
+
+    // Not a match.  The error will be detected and handled later.
+  }
+
+  // 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()) {
+      AddRecursiveImportError(proto, i);
+      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_->AddCheckpoint();
+
+  FileDescriptor* result = tables_->Allocate<FileDescriptor>();
+  file_ = result;
+
+  result->is_placeholder_ = false;
+  if (proto.has_source_code_info()) {
+    SourceCodeInfo *info = tables_->AllocateMessage<SourceCodeInfo>();
+    info->CopyFrom(proto.source_code_info());
+    result->source_code_info_ = info;
+  } else {
+    result->source_code_info_ = &SourceCodeInfo::default_instance();
+  }
+
+  file_tables_ = tables_->AllocateFileTables();
+  file_->tables_ = file_tables_;
+
+  if (!proto.has_name()) {
+    AddError("", proto, DescriptorPool::ErrorCollector::OTHER,
+             "Missing field: FileDescriptorProto.name.");
+  }
+
+  result->name_ = tables_->AllocateString(proto.name());
+  if (proto.has_package()) {
+    result->package_ = tables_->AllocateString(proto.package());
+  } else {
+    // We cannot rely on proto.package() returning a valid string if
+    // proto.has_package() is false, because we might be running at static
+    // initialization time, in which case default values have not yet been
+    // initialized.
+    result->package_ = tables_->AllocateString("");
+  }
+  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_->RollbackToLastCheckpoint();
+    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());
+  unused_dependency_.clear();
+  set<int> weak_deps;
+  for (int i = 0; i < proto.weak_dependency_size(); ++i) {
+    weak_deps.insert(proto.weak_dependency(i));
+  }
+  for (int i = 0; i < proto.dependency_size(); i++) {
+    if (!seen_dependencies.insert(proto.dependency(i)).second) {
+      AddTwiceListedError(proto, i);
+    }
+
+    const FileDescriptor* dependency = tables_->FindFile(proto.dependency(i));
+    if (dependency == NULL && pool_->underlay_ != NULL) {
+      dependency = pool_->underlay_->FindFileByName(proto.dependency(i));
+    }
+
+    if (dependency == NULL) {
+      if (pool_->allow_unknown_ ||
+          (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) {
+        dependency = NewPlaceholderFile(proto.dependency(i));
+      } else {
+        AddImportError(proto, i);
+      }
+    } else {
+      // Add to unused_dependency_ to track unused imported files.
+      // Note: do not track unused imported files for public import.
+      if (pool_->enforce_dependencies_ &&
+          (pool_->unused_import_track_files_.find(proto.name()) !=
+           pool_->unused_import_track_files_.end()) &&
+          (dependency->public_dependency_count() == 0)) {
+        unused_dependency_.insert(dependency);
+      }
+    }
+
+    result->dependencies_[i] = dependency;
+  }
+
+  // Check public dependencies.
+  int public_dependency_count = 0;
+  result->public_dependencies_ = tables_->AllocateArray<int>(
+      proto.public_dependency_size());
+  for (int i = 0; i < proto.public_dependency_size(); i++) {
+    // Only put valid public dependency indexes.
+    int index = proto.public_dependency(i);
+    if (index >= 0 && index < proto.dependency_size()) {
+      result->public_dependencies_[public_dependency_count++] = index;
+      // Do not track unused imported files for public import.
+      unused_dependency_.erase(result->dependency(index));
+    } else {
+      AddError(proto.name(), proto,
+               DescriptorPool::ErrorCollector::OTHER,
+               "Invalid public dependency index.");
+    }
+  }
+  result->public_dependency_count_ = public_dependency_count;
+
+  // Build dependency set
+  dependencies_.clear();
+  for (int i = 0; i < result->dependency_count(); i++) {
+    RecordPublicDependencies(result->dependency(i));
+  }
+
+  // Check weak dependencies.
+  int weak_dependency_count = 0;
+  result->weak_dependencies_ = tables_->AllocateArray<int>(
+      proto.weak_dependency_size());
+  for (int i = 0; i < proto.weak_dependency_size(); i++) {
+    int index = proto.weak_dependency(i);
+    if (index >= 0 && index < proto.dependency_size()) {
+      result->weak_dependencies_[weak_dependency_count++] = index;
+    } else {
+      AddError(proto.name(), proto,
+               DescriptorPool::ErrorCollector::OTHER,
+               "Invalid weak dependency index.");
+    }
+  }
+  result->weak_dependency_count_ = weak_dependency_count;
+
+  // 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_ = NULL;  // Will set to default_instance later.
+  } else {
+    AllocateOptions(proto.options(), result);
+  }
+
+  // Note that the following steps must occur in exactly the specified order.
+
+  // Cross-link.
+  CrossLinkFile(result, proto);
+
+  // Interpret any remaining uninterpreted options gathered into
+  // options_to_interpret_ during descriptor building.  Cross-linking has made
+  // extension options known, so all interpretations should now succeed.
+  if (!had_errors_) {
+    OptionInterpreter option_interpreter(this);
+    for (vector<OptionsToInterpret>::iterator iter =
+             options_to_interpret_.begin();
+         iter != options_to_interpret_.end(); ++iter) {
+      option_interpreter.InterpretOptions(&(*iter));
+    }
+    options_to_interpret_.clear();
+  }
+
+  // Validate options.
+  if (!had_errors_) {
+    ValidateFileOptions(result, proto);
+  }
+
+
+  if (!unused_dependency_.empty()) {
+    LogUnusedDependency(result);
+  }
+
+  if (had_errors_) {
+    tables_->RollbackToLastCheckpoint();
+    return NULL;
+  } else {
+    tables_->ClearLastCheckpoint();
+    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;
+  result->is_placeholder_  = false;
+  result->is_unqualified_placeholder_ = false;
+
+  // Build oneofs first so that fields and extension ranges can refer to them.
+  BUILD_ARRAY(proto, result, oneof_decl     , BuildOneof         , result);
+  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_ = NULL;  // Will set to default_instance later.
+  } else {
+    AllocateOptions(proto.options(), result);
+  }
+
+  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->is_extension_ = is_extension;
+
+  // If .proto files follow the style guide then the name should already be
+  // lower-cased.  If that's the case we can just reuse the string we already
+  // allocated rather than allocate a new one.
+  string lowercase_name(proto.name());
+  LowerString(&lowercase_name);
+  if (lowercase_name == proto.name()) {
+    result->lowercase_name_ = result->name_;
+  } else {
+    result->lowercase_name_ = tables_->AllocateString(lowercase_name);
+  }
+
+  // Don't bother with the above optimization for camel-case names since
+  // .proto files that follow the guide shouldn't be using names in this
+  // format, so the optimization wouldn't help much.
+  result->camelcase_name_ = tables_->AllocateString(ToCamelCase(proto.name()));
+
+  // Some compilers do not allow static_cast directly between two enum types,
+  // so we must cast to int first.
+  result->type_  = static_cast<FieldDescriptor::Type>(
+                     implicit_cast<int>(proto.type()));
+  result->label_ = static_cast<FieldDescriptor::Label>(
+                     implicit_cast<int>(proto.label()));
+
+  // An extension cannot have a required field (b/13365836).
+  if (result->is_extension_ &&
+      result->label_ == FieldDescriptor::LABEL_REQUIRED) {
+    AddError(result->full_name(), proto,
+             // Error location `TYPE`: we would really like to indicate
+             // `LABEL`, but the `ErrorLocation` enum has no entry for this, and
+             // we don't necessarily know about all implementations of the
+             // `ErrorCollector` interface to extend them to handle the new
+             // error location type properly.
+             DescriptorPool::ErrorCollector::TYPE,
+             "Message extensions cannot have required fields.");
+  }
+
+  // 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_default_value() && result->is_repeated()) {
+    AddError(result->full_name(), proto,
+             DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+             "Repeated fields can't have default values.");
+  }
+
+  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:
+          if (proto.default_value() == "inf") {
+            result->default_value_float_ = numeric_limits<float>::infinity();
+          } else if (proto.default_value() == "-inf") {
+            result->default_value_float_ = -numeric_limits<float>::infinity();
+          } else if (proto.default_value() == "nan") {
+            result->default_value_float_ = numeric_limits<float>::quiet_NaN();
+          } else  {
+            result->default_value_float_ =
+              io::NoLocaleStrtod(proto.default_value().c_str(), &end_pos);
+          }
+          break;
+        case FieldDescriptor::CPPTYPE_DOUBLE:
+          if (proto.default_value() == "inf") {
+            result->default_value_double_ = numeric_limits<double>::infinity();
+          } else if (proto.default_value() == "-inf") {
+            result->default_value_double_ = -numeric_limits<double>::infinity();
+          } else if (proto.default_value() == "nan") {
+            result->default_value_double_ = numeric_limits<double>::quiet_NaN();
+          } else  {
+            result->default_value_double_ =
+                io::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 \"" + proto.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_ = &internal::GetEmptyString();
+          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 (!is_extension && result->number() > FieldDescriptor::kMaxNumber) {
+    // Only validate that the number is within the valid field range if it is
+    // not an extension. Since extension numbers are validated with the
+    // extendee's valid set of extension numbers, and those are in turn
+    // validated against the max allowed number, the check is unnecessary for
+    // extension fields.
+    // This avoids cross-linking issues that arise when attempting to check if
+    // the extendee is a message_set_wire_format message, which has a higher max
+    // on extension numbers.
+    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;
+
+    if (proto.has_oneof_index()) {
+      AddError(result->full_name(), proto,
+               DescriptorPool::ErrorCollector::OTHER,
+               "FieldDescriptorProto.oneof_index should not be set for "
+               "extensions.");
+    }
+
+    // Fill in later (maybe).
+    result->containing_oneof_ = NULL;
+  } else {
+    if (proto.has_extendee()) {
+      AddError(result->full_name(), proto,
+               DescriptorPool::ErrorCollector::EXTENDEE,
+               "FieldDescriptorProto.extendee set for non-extension field.");
+    }
+
+    result->containing_type_ = parent;
+
+    if (proto.has_oneof_index()) {
+      if (proto.oneof_index() < 0 ||
+          proto.oneof_index() >= parent->oneof_decl_count()) {
+        AddError(result->full_name(), proto,
+                 DescriptorPool::ErrorCollector::OTHER,
+                 strings::Substitute("FieldDescriptorProto.oneof_index $0 is "
+                                     "out of range for type \"$1\".",
+                                     proto.oneof_index(),
+                                     parent->name()));
+        result->containing_oneof_ = NULL;
+      } else {
+        result->containing_oneof_ = parent->oneof_decl(proto.oneof_index());
+      }
+    } else {
+      result->containing_oneof_ = NULL;
+    }
+  }
+
+  // Copy options.
+  if (!proto.has_options()) {
+    result->options_ = NULL;  // Will set to default_instance later.
+  } else {
+    AllocateOptions(proto.options(), result);
+  }
+
+  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.");
+  }
+
+  // Checking of the upper bound of the extension range is deferred until after
+  // options interpreting. This allows messages with message_set_wire_format to
+  // have extensions beyond FieldDescriptor::kMaxNumber, since the extension
+  // numbers are actually used as int32s in the message_set_wire_format.
+
+  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::BuildOneof(const OneofDescriptorProto& proto,
+                                   Descriptor* parent,
+                                   OneofDescriptor* result) {
+  string* full_name = tables_->AllocateString(parent->full_name());
+  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->containing_type_ = parent;
+
+  // We need to fill these in later.
+  result->field_count_ = 0;
+  result->fields_ = NULL;
+
+  AddSymbol(result->full_name(), parent, result->name(),
+            proto, Symbol(result));
+}
+
+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;
+  result->is_placeholder_  = false;
+  result->is_unqualified_placeholder_ = false;
+
+  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_ = NULL;  // Will set to default_instance later.
+  } else {
+    AllocateOptions(proto.options(), result);
+  }
+
+  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_ = NULL;  // Will set to default_instance later.
+  } else {
+    AllocateOptions(proto.options(), result);
+  }
+
+  // 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.
+  bool added_to_outer_scope =
+    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.
+  bool added_to_inner_scope =
+    file_tables_->AddAliasUnderParent(parent, result->name(), Symbol(result));
+
+  if (added_to_inner_scope && !added_to_outer_scope) {
+    // This value did not conflict with any values defined in the same enum,
+    // but it did conflict with some other symbol defined in the enum type's
+    // scope.  Let's print an additional error to explain this.
+    string outer_scope;
+    if (parent->containing_type() == NULL) {
+      outer_scope = file_->package();
+    } else {
+      outer_scope = parent->containing_type()->full_name();
+    }
+
+    if (outer_scope.empty()) {
+      outer_scope = "the global scope";
+    } else {
+      outer_scope = "\"" + outer_scope + "\"";
+    }
+
+    AddError(result->full_name(), proto,
+             DescriptorPool::ErrorCollector::NAME,
+             "Note that enum values use C++ scoping rules, meaning that "
+             "enum values are siblings of their type, not children of it.  "
+             "Therefore, \"" + result->name() + "\" must be unique within "
+             + outer_scope + ", not just within \"" + parent->name() + "\".");
+  }
+
+  // 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.
+  file_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_ = NULL;  // Will set to default_instance later.
+  } else {
+    AllocateOptions(proto.options(), result);
+  }
+
+  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_ = NULL;  // Will set to default_instance later.
+  } else {
+    AllocateOptions(proto.options(), result);
+  }
+
+  AddSymbol(result->full_name(), parent, result->name(),
+            proto, Symbol(result));
+}
+
+#undef BUILD_ARRAY
+
+// -------------------------------------------------------------------
+
+void DescriptorBuilder::CrossLinkFile(
+    FileDescriptor* file, const FileDescriptorProto& proto) {
+  if (file->options_ == NULL) {
+    file->options_ = &FileOptions::default_instance();
+  }
+
+  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->enum_type_count(); i++) {
+    CrossLinkEnum(&file->enum_types_[i], proto.enum_type(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) {
+  if (message->options_ == NULL) {
+    message->options_ = &MessageOptions::default_instance();
+  }
+
+  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->enum_type_count(); i++) {
+    CrossLinkEnum(&message->enum_types_[i], proto.enum_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));
+  }
+
+  // Set up field array for each oneof.
+
+  // First count the number of fields per oneof.
+  for (int i = 0; i < message->field_count(); i++) {
+    const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
+    if (oneof_decl != NULL) {
+      // Must go through oneof_decls_ array to get a non-const version of the
+      // OneofDescriptor.
+      ++message->oneof_decls_[oneof_decl->index()].field_count_;
+    }
+  }
+
+  // Then allocate the arrays.
+  for (int i = 0; i < message->oneof_decl_count(); i++) {
+    OneofDescriptor* oneof_decl = &message->oneof_decls_[i];
+
+    if (oneof_decl->field_count() == 0) {
+      AddError(message->full_name() + "." + oneof_decl->name(),
+               proto.oneof_decl(i),
+               DescriptorPool::ErrorCollector::NAME,
+               "Oneof must have at least one field.");
+    }
+
+    oneof_decl->fields_ =
+      tables_->AllocateArray<const FieldDescriptor*>(oneof_decl->field_count_);
+    oneof_decl->field_count_ = 0;
+  }
+
+  // Then fill them in.
+  for (int i = 0; i < message->field_count(); i++) {
+    const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof();
+    if (oneof_decl != NULL) {
+      OneofDescriptor* mutable_oneof_decl =
+          &message->oneof_decls_[oneof_decl->index()];
+      message->fields_[i].index_in_oneof_ = mutable_oneof_decl->field_count_;
+      mutable_oneof_decl->fields_[mutable_oneof_decl->field_count_++] =
+          message->field(i);
+    }
+  }
+}
+
+void DescriptorBuilder::CrossLinkField(
+    FieldDescriptor* field, const FieldDescriptorProto& proto) {
+  if (field->options_ == NULL) {
+    field->options_ = &FieldOptions::default_instance();
+  }
+
+  if (proto.has_extendee()) {
+    Symbol extendee = LookupSymbol(proto.extendee(), field->full_name(),
+                                   PLACEHOLDER_EXTENDABLE_MESSAGE);
+    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;
+
+    const Descriptor::ExtensionRange* extension_range = field->containing_type()
+        ->FindExtensionRangeContainingNumber(field->number());
+
+    if (extension_range == NULL) {
+      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 (field->containing_oneof() != NULL) {
+    if (field->label() != FieldDescriptor::LABEL_OPTIONAL) {
+      // Note that this error will never happen when parsing .proto files.
+      // It can only happen if you manually construct a FileDescriptorProto
+      // that is incorrect.
+      AddError(field->full_name(), proto,
+               DescriptorPool::ErrorCollector::NAME,
+               "Fields of oneofs must themselves have label LABEL_OPTIONAL.");
+    }
+  }
+
+  if (proto.has_type_name()) {
+    // Assume we are expecting a message type unless the proto contains some
+    // evidence that it expects an enum type.  This only makes a difference if
+    // we end up creating a placeholder.
+    bool expecting_enum = (proto.type() == FieldDescriptorProto::TYPE_ENUM) ||
+                          proto.has_default_value();
+
+    Symbol type =
+      LookupSymbol(proto.type_name(), field->full_name(),
+                   expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE,
+                   LOOKUP_TYPES);
+
+    // If the type is a weak type, we change the type to a google.protobuf.Empty field.
+    if (type.IsNull() && !pool_->enforce_weak_ && proto.options().weak()) {
+      type = FindSymbol(kNonLinkedWeakMessageReplacementName);
+    }
+
+    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->enum_type()->is_placeholder_) {
+        // We can't look up default values for placeholder types.  We'll have
+        // to just drop them.
+        field->has_default_value_ = false;
+      }
+
+      if (field->has_default_value()) {
+        // Ensure that the default value is an identifier. Parser cannot always
+        // verify this because it does not have complete type information.
+        // N.B. that this check yields better error messages but is not
+        // necessary for correctness (an enum symbol must be a valid identifier
+        // anyway), only for better errors.
+        if (!io::Tokenizer::IsIdentifier(proto.default_value())) {
+          AddError(field->full_name(), proto,
+                   DescriptorPool::ErrorCollector::DEFAULT_VALUE,
+                   "Default value for an enum field must be an identifier.");
+        } else {
+          // 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 =
+            LookupSymbolNoPlaceholder(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.");
+    }
+  }
+
+  // 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 (!file_tables_->AddFieldByNumber(field)) {
+    const FieldDescriptor* conflicting_field =
+      file_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()));
+    }
+  } else {
+    if (field->is_extension()) {
+      if (!tables_->AddExtension(field)) {
+        const FieldDescriptor* conflicting_field =
+            tables_->FindExtension(field->containing_type(), field->number());
+        string error_msg = strings::Substitute(
+            "Extension number $0 has already been used in \"$1\" by extension "
+            "\"$2\" defined in $3.",
+            field->number(),
+            field->containing_type()->full_name(),
+            conflicting_field->full_name(),
+            conflicting_field->file()->name());
+        // Conflicting extension numbers should be an error. However, before
+        // turning this into an error we need to fix all existing broken
+        // protos first.
+        // TODO(xiaofeng): Change this to an error.
+        AddWarning(field->full_name(), proto,
+                   DescriptorPool::ErrorCollector::NUMBER, error_msg);
+      }
+    }
+  }
+
+  // Add the field to the lowercase-name and camelcase-name tables.
+  file_tables_->AddFieldByStylizedNames(field);
+}
+
+void DescriptorBuilder::CrossLinkEnum(
+    EnumDescriptor* enum_type, const EnumDescriptorProto& proto) {
+  if (enum_type->options_ == NULL) {
+    enum_type->options_ = &EnumOptions::default_instance();
+  }
+
+  for (int i = 0; i < enum_type->value_count(); i++) {
+    CrossLinkEnumValue(&enum_type->values_[i], proto.value(i));
+  }
+}
+
+void DescriptorBuilder::CrossLinkEnumValue(
+    EnumValueDescriptor* enum_value,
+    const EnumValueDescriptorProto& /* proto */) {
+  if (enum_value->options_ == NULL) {
+    enum_value->options_ = &EnumValueOptions::default_instance();
+  }
+}
+
+void DescriptorBuilder::CrossLinkService(
+    ServiceDescriptor* service, const ServiceDescriptorProto& proto) {
+  if (service->options_ == NULL) {
+    service->options_ = &ServiceOptions::default_instance();
+  }
+
+  for (int i = 0; i < service->method_count(); i++) {
+    CrossLinkMethod(&service->methods_[i], proto.method(i));
+  }
+}
+
+void DescriptorBuilder::CrossLinkMethod(
+    MethodDescriptor* method, const MethodDescriptorProto& proto) {
+  if (method->options_ == NULL) {
+    method->options_ = &MethodOptions::default_instance();
+  }
+
+  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;
+  }
+}
+
+// -------------------------------------------------------------------
+
+#define VALIDATE_OPTIONS_FROM_ARRAY(descriptor, array_name, type)  \
+  for (int i = 0; i < descriptor->array_name##_count(); ++i) {     \
+    Validate##type##Options(descriptor->array_name##s_ + i,        \
+                            proto.array_name(i));                  \
+  }
+
+// Determine if the file uses optimize_for = LITE_RUNTIME, being careful to
+// avoid problems that exist at init time.
+static bool IsLite(const FileDescriptor* file) {
+  // TODO(kenton):  I don't even remember how many of these conditions are
+  //   actually possible.  I'm just being super-safe.
+  return file != NULL &&
+         &file->options() != &FileOptions::default_instance() &&
+         file->options().optimize_for() == FileOptions::LITE_RUNTIME;
+}
+
+void DescriptorBuilder::ValidateFileOptions(FileDescriptor* file,
+                                            const FileDescriptorProto& proto) {
+  VALIDATE_OPTIONS_FROM_ARRAY(file, message_type, Message);
+  VALIDATE_OPTIONS_FROM_ARRAY(file, enum_type, Enum);
+  VALIDATE_OPTIONS_FROM_ARRAY(file, service, Service);
+  VALIDATE_OPTIONS_FROM_ARRAY(file, extension, Field);
+
+  // Lite files can only be imported by other Lite files.
+  if (!IsLite(file)) {
+    for (int i = 0; i < file->dependency_count(); i++) {
+      if (IsLite(file->dependency(i))) {
+        AddError(
+          file->name(), proto,
+          DescriptorPool::ErrorCollector::OTHER,
+          "Files that do not use optimize_for = LITE_RUNTIME cannot import "
+          "files which do use this option.  This file is not lite, but it "
+          "imports \"" + file->dependency(i)->name() + "\" which is.");
+        break;
+      }
+    }
+  }
+}
+
+
+void DescriptorBuilder::ValidateMessageOptions(Descriptor* message,
+                                               const DescriptorProto& proto) {
+  VALIDATE_OPTIONS_FROM_ARRAY(message, field, Field);
+  VALIDATE_OPTIONS_FROM_ARRAY(message, nested_type, Message);
+  VALIDATE_OPTIONS_FROM_ARRAY(message, enum_type, Enum);
+  VALIDATE_OPTIONS_FROM_ARRAY(message, extension, Field);
+
+  const int64 max_extension_range =
+      static_cast<int64>(message->options().message_set_wire_format() ?
+                         kint32max :
+                         FieldDescriptor::kMaxNumber);
+  for (int i = 0; i < message->extension_range_count(); ++i) {
+    if (message->extension_range(i)->end > max_extension_range + 1) {
+      AddError(
+          message->full_name(), proto.extension_range(i),
+          DescriptorPool::ErrorCollector::NUMBER,
+          strings::Substitute("Extension numbers cannot be greater than $0.",
+                              max_extension_range));
+    }
+  }
+}
+
+void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field,
+    const FieldDescriptorProto& proto) {
+  if (field->options().has_experimental_map_key()) {
+    ValidateMapKey(field, proto);
+  }
+
+  // Only message type fields may be lazy.
+  if (field->options().lazy()) {
+    if (field->type() != FieldDescriptor::TYPE_MESSAGE) {
+      AddError(field->full_name(), proto,
+               DescriptorPool::ErrorCollector::TYPE,
+               "[lazy = true] can only be specified for submessage fields.");
+    }
+  }
+
+  // Only repeated primitive fields may be packed.
+  if (field->options().packed() && !field->is_packable()) {
+    AddError(
+      field->full_name(), proto,
+      DescriptorPool::ErrorCollector::TYPE,
+      "[packed = true] can only be specified for repeated primitive fields.");
+  }
+
+  // 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.");
+    }
+  }
+
+  // Lite extensions can only be of Lite types.
+  if (IsLite(field->file()) &&
+      field->containing_type_ != NULL &&
+      !IsLite(field->containing_type()->file())) {
+    AddError(field->full_name(), proto,
+             DescriptorPool::ErrorCollector::EXTENDEE,
+             "Extensions to non-lite types can only be declared in non-lite "
+             "files.  Note that you cannot extend a non-lite type to contain "
+             "a lite type, but the reverse is allowed.");
+  }
+
+}
+
+void DescriptorBuilder::ValidateEnumOptions(EnumDescriptor* enm,
+                                            const EnumDescriptorProto& proto) {
+  VALIDATE_OPTIONS_FROM_ARRAY(enm, value, EnumValue);
+  if (!enm->options().has_allow_alias() || !enm->options().allow_alias()) {
+    map<int, string> used_values;
+    for (int i = 0; i < enm->value_count(); ++i) {
+      const EnumValueDescriptor* enum_value = enm->value(i);
+      if (used_values.find(enum_value->number()) != used_values.end()) {
+        string error =
+            "\"" + enum_value->full_name() +
+            "\" uses the same enum value as \"" +
+            used_values[enum_value->number()] + "\". If this is intended, set "
+            "'option allow_alias = true;' to the enum definition.";
+        if (!enm->options().allow_alias()) {
+          // Generate error if duplicated enum values are explicitly disallowed.
+          AddError(enm->full_name(), proto,
+                   DescriptorPool::ErrorCollector::NUMBER,
+                   error);
+        } else {
+          // Generate warning if duplicated values are found but the option
+          // isn't set.
+          GOOGLE_LOG(ERROR) << error;
+        }
+      } else {
+        used_values[enum_value->number()] = enum_value->full_name();
+      }
+    }
+  }
+}
+
+void DescriptorBuilder::ValidateEnumValueOptions(
+    EnumValueDescriptor* /* enum_value */,
+    const EnumValueDescriptorProto& /* proto */) {
+  // Nothing to do so far.
+}
+void DescriptorBuilder::ValidateServiceOptions(ServiceDescriptor* service,
+    const ServiceDescriptorProto& proto) {
+  if (IsLite(service->file()) &&
+      (service->file()->options().cc_generic_services() ||
+       service->file()->options().java_generic_services())) {
+    AddError(service->full_name(), proto,
+             DescriptorPool::ErrorCollector::NAME,
+             "Files with optimize_for = LITE_RUNTIME cannot define services "
+             "unless you set both options cc_generic_services and "
+             "java_generic_sevices to false.");
+  }
+
+  VALIDATE_OPTIONS_FROM_ARRAY(service, method, Method);
+}
+
+void DescriptorBuilder::ValidateMethodOptions(MethodDescriptor* /* method */,
+    const MethodDescriptorProto& /* proto */) {
+  // Nothing to do so far.
+}
+
+void DescriptorBuilder::ValidateMapKey(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 = field->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;
+}
+
+
+#undef VALIDATE_OPTIONS_FROM_ARRAY
+
+// -------------------------------------------------------------------
+
+DescriptorBuilder::OptionInterpreter::OptionInterpreter(
+    DescriptorBuilder* builder) : builder_(builder) {
+  GOOGLE_CHECK(builder_);
+}
+
+DescriptorBuilder::OptionInterpreter::~OptionInterpreter() {
+}
+
+bool DescriptorBuilder::OptionInterpreter::InterpretOptions(
+    OptionsToInterpret* options_to_interpret) {
+  // Note that these may be in different pools, so we can't use the same
+  // descriptor and reflection objects on both.
+  Message* options = options_to_interpret->options;
+  const Message* original_options = options_to_interpret->original_options;
+
+  bool failed = false;
+  options_to_interpret_ = options_to_interpret;
+
+  // Find the uninterpreted_option field in the mutable copy of the options
+  // and clear them, since we're about to interpret them.
+  const FieldDescriptor* uninterpreted_options_field =
+      options->GetDescriptor()->FindFieldByName("uninterpreted_option");
+  GOOGLE_CHECK(uninterpreted_options_field != NULL)
+      << "No field named \"uninterpreted_option\" in the Options proto.";
+  options->GetReflection()->ClearField(options, uninterpreted_options_field);
+
+  // Find the uninterpreted_option field in the original options.
+  const FieldDescriptor* original_uninterpreted_options_field =
+      original_options->GetDescriptor()->
+          FindFieldByName("uninterpreted_option");
+  GOOGLE_CHECK(original_uninterpreted_options_field != NULL)
+      << "No field named \"uninterpreted_option\" in the Options proto.";
+
+  const int num_uninterpreted_options = original_options->GetReflection()->
+      FieldSize(*original_options, original_uninterpreted_options_field);
+  for (int i = 0; i < num_uninterpreted_options; ++i) {
+    uninterpreted_option_ = down_cast<const UninterpretedOption*>(
+        &original_options->GetReflection()->GetRepeatedMessage(
+            *original_options, original_uninterpreted_options_field, i));
+    if (!InterpretSingleOption(options)) {
+      // Error already added by InterpretSingleOption().
+      failed = true;
+      break;
+    }
+  }
+  // Reset these, so we don't have any dangling pointers.
+  uninterpreted_option_ = NULL;
+  options_to_interpret_ = NULL;
+
+  if (!failed) {
+    // InterpretSingleOption() added the interpreted options in the
+    // UnknownFieldSet, in case the option isn't yet known to us.  Now we
+    // serialize the options message and deserialize it back.  That way, any
+    // option fields that we do happen to know about will get moved from the
+    // UnknownFieldSet into the real fields, and thus be available right away.
+    // If they are not known, that's OK too. They will get reparsed into the
+    // UnknownFieldSet and wait there until the message is parsed by something
+    // that does know about the options.
+    string buf;
+    options->AppendToString(&buf);
+    GOOGLE_CHECK(options->ParseFromString(buf))
+        << "Protocol message serialized itself in invalid fashion.";
+  }
+
+  return !failed;
+}
+
+bool DescriptorBuilder::OptionInterpreter::InterpretSingleOption(
+    Message* options) {
+  // First do some basic validation.
+  if (uninterpreted_option_->name_size() == 0) {
+    // This should never happen unless the parser has gone seriously awry or
+    // someone has manually created the uninterpreted option badly.
+    return AddNameError("Option must have a name.");
+  }
+  if (uninterpreted_option_->name(0).name_part() == "uninterpreted_option") {
+    return AddNameError("Option must not use reserved name "
+                        "\"uninterpreted_option\".");
+  }
+
+  const Descriptor* options_descriptor = NULL;
+  // Get the options message's descriptor from the builder's pool, so that we
+  // get the version that knows about any extension options declared in the
+  // file we're currently building. The descriptor should be there as long as
+  // the file we're building imported "google/protobuf/descriptors.proto".
+
+  // Note that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
+  // DescriptorPool::FindMessageTypeByName() because we're already holding the
+  // pool's mutex, and the latter method locks it again.  We don't use
+  // FindSymbol() because files that use custom options only need to depend on
+  // the file that defines the option, not descriptor.proto itself.
+  Symbol symbol = builder_->FindSymbolNotEnforcingDeps(
+    options->GetDescriptor()->full_name());
+  if (!symbol.IsNull() && symbol.type == Symbol::MESSAGE) {
+    options_descriptor = symbol.descriptor;
+  } else {
+    // The options message's descriptor was not in the builder's pool, so use
+    // the standard version from the generated pool. We're not holding the
+    // generated pool's mutex, so we can search it the straightforward way.
+    options_descriptor = options->GetDescriptor();
+  }
+  GOOGLE_CHECK(options_descriptor);
+
+  // We iterate over the name parts to drill into the submessages until we find
+  // the leaf field for the option. As we drill down we remember the current
+  // submessage's descriptor in |descriptor| and the next field in that
+  // submessage in |field|. We also track the fields we're drilling down
+  // through in |intermediate_fields|. As we go, we reconstruct the full option
+  // name in |debug_msg_name|, for use in error messages.
+  const Descriptor* descriptor = options_descriptor;
+  const FieldDescriptor* field = NULL;
+  vector<const FieldDescriptor*> intermediate_fields;
+  string debug_msg_name = "";
+
+  for (int i = 0; i < uninterpreted_option_->name_size(); ++i) {
+    const string& name_part = uninterpreted_option_->name(i).name_part();
+    if (debug_msg_name.size() > 0) {
+      debug_msg_name += ".";
+    }
+    if (uninterpreted_option_->name(i).is_extension()) {
+      debug_msg_name += "(" + name_part + ")";
+      // Search for the extension's descriptor as an extension in the builder's
+      // pool. Note that we use DescriptorBuilder::LookupSymbol(), not
+      // DescriptorPool::FindExtensionByName(), for two reasons: 1) It allows
+      // relative lookups, and 2) because we're already holding the pool's
+      // mutex, and the latter method locks it again.
+      symbol = builder_->LookupSymbol(name_part,
+                                      options_to_interpret_->name_scope);
+      if (!symbol.IsNull() && symbol.type == Symbol::FIELD) {
+        field = symbol.field_descriptor;
+      }
+      // If we don't find the field then the field's descriptor was not in the
+      // builder's pool, but there's no point in looking in the generated
+      // pool. We require that you import the file that defines any extensions
+      // you use, so they must be present in the builder's pool.
+    } else {
+      debug_msg_name += name_part;
+      // Search for the field's descriptor as a regular field.
+      field = descriptor->FindFieldByName(name_part);
+    }
+
+    if (field == NULL) {
+      if (get_allow_unknown(builder_->pool_)) {
+        // We can't find the option, but AllowUnknownDependencies() is enabled,
+        // so we will just leave it as uninterpreted.
+        AddWithoutInterpreting(*uninterpreted_option_, options);
+        return true;
+      } else if (!(builder_->undefine_resolved_name_).empty()) {
+        // Option is resolved to a name which is not defined.
+        return AddNameError(
+            "Option \"" + debug_msg_name + "\" is resolved to \"(" +
+            builder_->undefine_resolved_name_ +
+            ")\", which is not defined. The innermost scope is searched first "
+            "in name resolution. Consider using a leading '.'(i.e., \"(." +
+            debug_msg_name.substr(1) +
+            "\") to start from the outermost scope.");
+      } else {
+        return AddNameError("Option \"" + debug_msg_name + "\" unknown.");
+      }
+    } else if (field->containing_type() != descriptor) {
+      if (get_is_placeholder(field->containing_type())) {
+        // The field is an extension of a placeholder type, so we can't
+        // reliably verify whether it is a valid extension to use here (e.g.
+        // we don't know if it is an extension of the correct *Options message,
+        // or if it has a valid field number, etc.).  Just leave it as
+        // uninterpreted instead.
+        AddWithoutInterpreting(*uninterpreted_option_, options);
+        return true;
+      } else {
+        // This can only happen if, due to some insane misconfiguration of the
+        // pools, we find the options message in one pool but the field in
+        // another. This would probably imply a hefty bug somewhere.
+        return AddNameError("Option field \"" + debug_msg_name +
+                            "\" is not a field or extension of message \"" +
+                            descriptor->name() + "\".");
+      }
+    } else if (i < uninterpreted_option_->name_size() - 1) {
+      if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+        return AddNameError("Option \"" +  debug_msg_name +
+                            "\" is an atomic type, not a message.");
+      } else if (field->is_repeated()) {
+        return AddNameError("Option field \"" + debug_msg_name +
+                            "\" is a repeated message. Repeated message "
+                            "options must be initialized using an "
+                            "aggregate value.");
+      } else {
+        // Drill down into the submessage.
+        intermediate_fields.push_back(field);
+        descriptor = field->message_type();
+      }
+    }
+  }
+
+  // We've found the leaf field. Now we use UnknownFieldSets to set its value
+  // on the options message. We do so because the message may not yet know
+  // about its extension fields, so we may not be able to set the fields
+  // directly. But the UnknownFieldSets will serialize to the same wire-format
+  // message, so reading that message back in once the extension fields are
+  // known will populate them correctly.
+
+  // First see if the option is already set.
+  if (!field->is_repeated() && !ExamineIfOptionIsSet(
+          intermediate_fields.begin(),
+          intermediate_fields.end(),
+          field, debug_msg_name,
+          options->GetReflection()->GetUnknownFields(*options))) {
+    return false;  // ExamineIfOptionIsSet() already added the error.
+  }
+
+
+  // First set the value on the UnknownFieldSet corresponding to the
+  // innermost message.
+  scoped_ptr<UnknownFieldSet> unknown_fields(new UnknownFieldSet());
+  if (!SetOptionValue(field, unknown_fields.get())) {
+    return false;  // SetOptionValue() already added the error.
+  }
+
+  // Now wrap the UnknownFieldSet with UnknownFieldSets corresponding to all
+  // the intermediate messages.
+  for (vector<const FieldDescriptor*>::reverse_iterator iter =
+           intermediate_fields.rbegin();
+       iter != intermediate_fields.rend(); ++iter) {
+    scoped_ptr<UnknownFieldSet> parent_unknown_fields(new UnknownFieldSet());
+    switch ((*iter)->type()) {
+      case FieldDescriptor::TYPE_MESSAGE: {
+        io::StringOutputStream outstr(
+            parent_unknown_fields->AddLengthDelimited((*iter)->number()));
+        io::CodedOutputStream out(&outstr);
+        internal::WireFormat::SerializeUnknownFields(*unknown_fields, &out);
+        GOOGLE_CHECK(!out.HadError())
+            << "Unexpected failure while serializing option submessage "
+            << debug_msg_name << "\".";
+        break;
+      }
+
+      case FieldDescriptor::TYPE_GROUP: {
+         parent_unknown_fields->AddGroup((*iter)->number())
+                              ->MergeFrom(*unknown_fields);
+        break;
+      }
+
+      default:
+        GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: "
+                   << (*iter)->type();
+        return false;
+    }
+    unknown_fields.reset(parent_unknown_fields.release());
+  }
+
+  // Now merge the UnknownFieldSet corresponding to the top-level message into
+  // the options message.
+  options->GetReflection()->MutableUnknownFields(options)->MergeFrom(
+      *unknown_fields);
+
+  return true;
+}
+
+void DescriptorBuilder::OptionInterpreter::AddWithoutInterpreting(
+    const UninterpretedOption& uninterpreted_option, Message* options) {
+  const FieldDescriptor* field =
+    options->GetDescriptor()->FindFieldByName("uninterpreted_option");
+  GOOGLE_CHECK(field != NULL);
+
+  options->GetReflection()->AddMessage(options, field)
+    ->CopyFrom(uninterpreted_option);
+}
+
+bool DescriptorBuilder::OptionInterpreter::ExamineIfOptionIsSet(
+    vector<const FieldDescriptor*>::const_iterator intermediate_fields_iter,
+    vector<const FieldDescriptor*>::const_iterator intermediate_fields_end,
+    const FieldDescriptor* innermost_field, const string& debug_msg_name,
+    const UnknownFieldSet& unknown_fields) {
+  // We do linear searches of the UnknownFieldSet and its sub-groups.  This
+  // should be fine since it's unlikely that any one options structure will
+  // contain more than a handful of options.
+
+  if (intermediate_fields_iter == intermediate_fields_end) {
+    // We're at the innermost submessage.
+    for (int i = 0; i < unknown_fields.field_count(); i++) {
+      if (unknown_fields.field(i).number() == innermost_field->number()) {
+        return AddNameError("Option \"" + debug_msg_name +
+                            "\" was already set.");
+      }
+    }
+    return true;
+  }
+
+  for (int i = 0; i < unknown_fields.field_count(); i++) {
+    if (unknown_fields.field(i).number() ==
+        (*intermediate_fields_iter)->number()) {
+      const UnknownField* unknown_field = &unknown_fields.field(i);
+      FieldDescriptor::Type type = (*intermediate_fields_iter)->type();
+      // Recurse into the next submessage.
+      switch (type) {
+        case FieldDescriptor::TYPE_MESSAGE:
+          if (unknown_field->type() == UnknownField::TYPE_LENGTH_DELIMITED) {
+            UnknownFieldSet intermediate_unknown_fields;
+            if (intermediate_unknown_fields.ParseFromString(
+                    unknown_field->length_delimited()) &&
+                !ExamineIfOptionIsSet(intermediate_fields_iter + 1,
+                                      intermediate_fields_end,
+                                      innermost_field, debug_msg_name,
+                                      intermediate_unknown_fields)) {
+              return false;  // Error already added.
+            }
+          }
+          break;
+
+        case FieldDescriptor::TYPE_GROUP:
+          if (unknown_field->type() == UnknownField::TYPE_GROUP) {
+            if (!ExamineIfOptionIsSet(intermediate_fields_iter + 1,
+                                      intermediate_fields_end,
+                                      innermost_field, debug_msg_name,
+                                      unknown_field->group())) {
+              return false;  // Error already added.
+            }
+          }
+          break;
+
+        default:
+          GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_MESSAGE: " << type;
+          return false;
+      }
+    }
+  }
+  return true;
+}
+
+bool DescriptorBuilder::OptionInterpreter::SetOptionValue(
+    const FieldDescriptor* option_field,
+    UnknownFieldSet* unknown_fields) {
+  // We switch on the CppType to validate.
+  switch (option_field->cpp_type()) {
+
+    case FieldDescriptor::CPPTYPE_INT32:
+      if (uninterpreted_option_->has_positive_int_value()) {
+        if (uninterpreted_option_->positive_int_value() >
+            static_cast<uint64>(kint32max)) {
+          return AddValueError("Value out of range for int32 option \"" +
+                               option_field->full_name() + "\".");
+        } else {
+          SetInt32(option_field->number(),
+                   uninterpreted_option_->positive_int_value(),
+                   option_field->type(), unknown_fields);
+        }
+      } else if (uninterpreted_option_->has_negative_int_value()) {
+        if (uninterpreted_option_->negative_int_value() <
+            static_cast<int64>(kint32min)) {
+          return AddValueError("Value out of range for int32 option \"" +
+                               option_field->full_name() + "\".");
+        } else {
+          SetInt32(option_field->number(),
+                   uninterpreted_option_->negative_int_value(),
+                   option_field->type(), unknown_fields);
+        }
+      } else {
+        return AddValueError("Value must be integer for int32 option \"" +
+                             option_field->full_name() + "\".");
+      }
+      break;
+
+    case FieldDescriptor::CPPTYPE_INT64:
+      if (uninterpreted_option_->has_positive_int_value()) {
+        if (uninterpreted_option_->positive_int_value() >
+            static_cast<uint64>(kint64max)) {
+          return AddValueError("Value out of range for int64 option \"" +
+                               option_field->full_name() + "\".");
+        } else {
+          SetInt64(option_field->number(),
+                   uninterpreted_option_->positive_int_value(),
+                   option_field->type(), unknown_fields);
+        }
+      } else if (uninterpreted_option_->has_negative_int_value()) {
+        SetInt64(option_field->number(),
+                 uninterpreted_option_->negative_int_value(),
+                 option_field->type(), unknown_fields);
+      } else {
+        return AddValueError("Value must be integer for int64 option \"" +
+                             option_field->full_name() + "\".");
+      }
+      break;
+
+    case FieldDescriptor::CPPTYPE_UINT32:
+      if (uninterpreted_option_->has_positive_int_value()) {
+        if (uninterpreted_option_->positive_int_value() > kuint32max) {
+          return AddValueError("Value out of range for uint32 option \"" +
+                               option_field->name() + "\".");
+        } else {
+          SetUInt32(option_field->number(),
+                    uninterpreted_option_->positive_int_value(),
+                    option_field->type(), unknown_fields);
+        }
+      } else {
+        return AddValueError("Value must be non-negative integer for uint32 "
+                             "option \"" + option_field->full_name() + "\".");
+      }
+      break;
+
+    case FieldDescriptor::CPPTYPE_UINT64:
+      if (uninterpreted_option_->has_positive_int_value()) {
+        SetUInt64(option_field->number(),
+                  uninterpreted_option_->positive_int_value(),
+                  option_field->type(), unknown_fields);
+      } else {
+        return AddValueError("Value must be non-negative integer for uint64 "
+                             "option \"" + option_field->full_name() + "\".");
+      }
+      break;
+
+    case FieldDescriptor::CPPTYPE_FLOAT: {
+      float value;
+      if (uninterpreted_option_->has_double_value()) {
+        value = uninterpreted_option_->double_value();
+      } else if (uninterpreted_option_->has_positive_int_value()) {
+        value = uninterpreted_option_->positive_int_value();
+      } else if (uninterpreted_option_->has_negative_int_value()) {
+        value = uninterpreted_option_->negative_int_value();
+      } else {
+        return AddValueError("Value must be number for float option \"" +
+                             option_field->full_name() + "\".");
+      }
+      unknown_fields->AddFixed32(option_field->number(),
+          google::protobuf::internal::WireFormatLite::EncodeFloat(value));
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_DOUBLE: {
+      double value;
+      if (uninterpreted_option_->has_double_value()) {
+        value = uninterpreted_option_->double_value();
+      } else if (uninterpreted_option_->has_positive_int_value()) {
+        value = uninterpreted_option_->positive_int_value();
+      } else if (uninterpreted_option_->has_negative_int_value()) {
+        value = uninterpreted_option_->negative_int_value();
+      } else {
+        return AddValueError("Value must be number for double option \"" +
+                             option_field->full_name() + "\".");
+      }
+      unknown_fields->AddFixed64(option_field->number(),
+          google::protobuf::internal::WireFormatLite::EncodeDouble(value));
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_BOOL:
+      uint64 value;
+      if (!uninterpreted_option_->has_identifier_value()) {
+        return AddValueError("Value must be identifier for boolean option "
+                             "\"" + option_field->full_name() + "\".");
+      }
+      if (uninterpreted_option_->identifier_value() == "true") {
+        value = 1;
+      } else if (uninterpreted_option_->identifier_value() == "false") {
+        value = 0;
+      } else {
+        return AddValueError("Value must be \"true\" or \"false\" for boolean "
+                             "option \"" + option_field->full_name() + "\".");
+      }
+      unknown_fields->AddVarint(option_field->number(), value);
+      break;
+
+    case FieldDescriptor::CPPTYPE_ENUM: {
+      if (!uninterpreted_option_->has_identifier_value()) {
+        return AddValueError("Value must be identifier for enum-valued option "
+                             "\"" + option_field->full_name() + "\".");
+      }
+      const EnumDescriptor* enum_type = option_field->enum_type();
+      const string& value_name = uninterpreted_option_->identifier_value();
+      const EnumValueDescriptor* enum_value = NULL;
+
+      if (enum_type->file()->pool() != DescriptorPool::generated_pool()) {
+        // Note that the enum value's fully-qualified name is a sibling of the
+        // enum's name, not a child of it.
+        string fully_qualified_name = enum_type->full_name();
+        fully_qualified_name.resize(fully_qualified_name.size() -
+                                    enum_type->name().size());
+        fully_qualified_name += value_name;
+
+        // Search for the enum value's descriptor in the builder's pool. Note
+        // that we use DescriptorBuilder::FindSymbolNotEnforcingDeps(), not
+        // DescriptorPool::FindEnumValueByName() because we're already holding
+        // the pool's mutex, and the latter method locks it again.
+        Symbol symbol =
+          builder_->FindSymbolNotEnforcingDeps(fully_qualified_name);
+        if (!symbol.IsNull() && symbol.type == Symbol::ENUM_VALUE) {
+          if (symbol.enum_value_descriptor->type() != enum_type) {
+            return AddValueError("Enum type \"" + enum_type->full_name() +
+                "\" has no value named \"" + value_name + "\" for option \"" +
+                option_field->full_name() +
+                "\". This appears to be a value from a sibling type.");
+          } else {
+            enum_value = symbol.enum_value_descriptor;
+          }
+        }
+      } else {
+        // The enum type is in the generated pool, so we can search for the
+        // value there.
+        enum_value = enum_type->FindValueByName(value_name);
+      }
+
+      if (enum_value == NULL) {
+        return AddValueError("Enum type \"" +
+                             option_field->enum_type()->full_name() +
+                             "\" has no value named \"" + value_name + "\" for "
+                             "option \"" + option_field->full_name() + "\".");
+      } else {
+        // Sign-extension is not a problem, since we cast directly from int32 to
+        // uint64, without first going through uint32.
+        unknown_fields->AddVarint(option_field->number(),
+          static_cast<uint64>(static_cast<int64>(enum_value->number())));
+      }
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_STRING:
+      if (!uninterpreted_option_->has_string_value()) {
+        return AddValueError("Value must be quoted string for string option "
+                             "\"" + option_field->full_name() + "\".");
+      }
+      // The string has already been unquoted and unescaped by the parser.
+      unknown_fields->AddLengthDelimited(option_field->number(),
+          uninterpreted_option_->string_value());
+      break;
+
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      if (!SetAggregateOption(option_field, unknown_fields)) {
+        return false;
+      }
+      break;
+  }
+
+  return true;
+}
+
+class DescriptorBuilder::OptionInterpreter::AggregateOptionFinder
+    : public TextFormat::Finder {
+ public:
+  DescriptorBuilder* builder_;
+
+  virtual const FieldDescriptor* FindExtension(
+      Message* message, const string& name) const {
+    assert_mutex_held(builder_->pool_);
+    const Descriptor* descriptor = message->GetDescriptor();
+    Symbol result = builder_->LookupSymbolNoPlaceholder(
+        name, descriptor->full_name());
+    if (result.type == Symbol::FIELD &&
+        result.field_descriptor->is_extension()) {
+      return result.field_descriptor;
+    } else if (result.type == Symbol::MESSAGE &&
+               descriptor->options().message_set_wire_format()) {
+      const Descriptor* foreign_type = result.descriptor;
+      // The text format allows MessageSet items to be specified using
+      // the type name, rather than the extension identifier. If the symbol
+      // lookup returned a Message, and the enclosing Message has
+      // message_set_wire_format = true, then return the message set
+      // extension, if one exists.
+      for (int i = 0; i < foreign_type->extension_count(); i++) {
+        const FieldDescriptor* extension = foreign_type->extension(i);
+        if (extension->containing_type() == descriptor &&
+            extension->type() == FieldDescriptor::TYPE_MESSAGE &&
+            extension->is_optional() &&
+            extension->message_type() == foreign_type) {
+          // Found it.
+          return extension;
+        }
+      }
+    }
+    return NULL;
+  }
+};
+
+// A custom error collector to record any text-format parsing errors
+namespace {
+class AggregateErrorCollector : public io::ErrorCollector {
+ public:
+  string error_;
+
+  virtual void AddError(int /* line */, int /* column */,
+                        const string& message) {
+    if (!error_.empty()) {
+      error_ += "; ";
+    }
+    error_ += message;
+  }
+
+  virtual void AddWarning(int /* line */, int /* column */,
+                          const string& /* message */) {
+    // Ignore warnings
+  }
+};
+}
+
+// We construct a dynamic message of the type corresponding to
+// option_field, parse the supplied text-format string into this
+// message, and serialize the resulting message to produce the value.
+bool DescriptorBuilder::OptionInterpreter::SetAggregateOption(
+    const FieldDescriptor* option_field,
+    UnknownFieldSet* unknown_fields) {
+  if (!uninterpreted_option_->has_aggregate_value()) {
+    return AddValueError("Option \"" + option_field->full_name() +
+                         "\" is a message. To set the entire message, use "
+                         "syntax like \"" + option_field->name() +
+                         " = { <proto text format> }\". "
+                         "To set fields within it, use "
+                         "syntax like \"" + option_field->name() +
+                         ".foo = value\".");
+  }
+
+  const Descriptor* type = option_field->message_type();
+  scoped_ptr<Message> dynamic(dynamic_factory_.GetPrototype(type)->New());
+  GOOGLE_CHECK(dynamic.get() != NULL)
+      << "Could not create an instance of " << option_field->DebugString();
+
+  AggregateErrorCollector collector;
+  AggregateOptionFinder finder;
+  finder.builder_ = builder_;
+  TextFormat::Parser parser;
+  parser.RecordErrorsTo(&collector);
+  parser.SetFinder(&finder);
+  if (!parser.ParseFromString(uninterpreted_option_->aggregate_value(),
+                              dynamic.get())) {
+    AddValueError("Error while parsing option value for \"" +
+                  option_field->name() + "\": " + collector.error_);
+    return false;
+  } else {
+    string serial;
+    dynamic->SerializeToString(&serial);  // Never fails
+    if (option_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+      unknown_fields->AddLengthDelimited(option_field->number(), serial);
+    } else {
+      GOOGLE_CHECK_EQ(option_field->type(),  FieldDescriptor::TYPE_GROUP);
+      UnknownFieldSet* group = unknown_fields->AddGroup(option_field->number());
+      group->ParseFromString(serial);
+    }
+    return true;
+  }
+}
+
+void DescriptorBuilder::OptionInterpreter::SetInt32(int number, int32 value,
+    FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
+  switch (type) {
+    case FieldDescriptor::TYPE_INT32:
+      unknown_fields->AddVarint(number,
+        static_cast<uint64>(static_cast<int64>(value)));
+      break;
+
+    case FieldDescriptor::TYPE_SFIXED32:
+      unknown_fields->AddFixed32(number, static_cast<uint32>(value));
+      break;
+
+    case FieldDescriptor::TYPE_SINT32:
+      unknown_fields->AddVarint(number,
+          google::protobuf::internal::WireFormatLite::ZigZagEncode32(value));
+      break;
+
+    default:
+      GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT32: " << type;
+      break;
+  }
+}
+
+void DescriptorBuilder::OptionInterpreter::SetInt64(int number, int64 value,
+    FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
+  switch (type) {
+    case FieldDescriptor::TYPE_INT64:
+      unknown_fields->AddVarint(number, static_cast<uint64>(value));
+      break;
+
+    case FieldDescriptor::TYPE_SFIXED64:
+      unknown_fields->AddFixed64(number, static_cast<uint64>(value));
+      break;
+
+    case FieldDescriptor::TYPE_SINT64:
+      unknown_fields->AddVarint(number,
+          google::protobuf::internal::WireFormatLite::ZigZagEncode64(value));
+      break;
+
+    default:
+      GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_INT64: " << type;
+      break;
+  }
+}
+
+void DescriptorBuilder::OptionInterpreter::SetUInt32(int number, uint32 value,
+    FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
+  switch (type) {
+    case FieldDescriptor::TYPE_UINT32:
+      unknown_fields->AddVarint(number, static_cast<uint64>(value));
+      break;
+
+    case FieldDescriptor::TYPE_FIXED32:
+      unknown_fields->AddFixed32(number, static_cast<uint32>(value));
+      break;
+
+    default:
+      GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT32: " << type;
+      break;
+  }
+}
+
+void DescriptorBuilder::OptionInterpreter::SetUInt64(int number, uint64 value,
+    FieldDescriptor::Type type, UnknownFieldSet* unknown_fields) {
+  switch (type) {
+    case FieldDescriptor::TYPE_UINT64:
+      unknown_fields->AddVarint(number, value);
+      break;
+
+    case FieldDescriptor::TYPE_FIXED64:
+      unknown_fields->AddFixed64(number, value);
+      break;
+
+    default:
+      GOOGLE_LOG(FATAL) << "Invalid wire type for CPPTYPE_UINT64: " << type;
+      break;
+  }
+}
+
+void DescriptorBuilder::LogUnusedDependency(const FileDescriptor* result) {
+
+  if (!unused_dependency_.empty()) {
+    std::set<string> annotation_extensions;
+    annotation_extensions.insert("google.protobuf.MessageOptions");
+    annotation_extensions.insert("google.protobuf.FileOptions");
+    annotation_extensions.insert("google.protobuf.FieldOptions");
+    annotation_extensions.insert("google.protobuf.EnumOptions");
+    annotation_extensions.insert("google.protobuf.EnumValueOptions");
+    annotation_extensions.insert("google.protobuf.ServiceOptions");
+    annotation_extensions.insert("google.protobuf.MethodOptions");
+    annotation_extensions.insert("google.protobuf.StreamOptions");
+    for (set<const FileDescriptor*>::const_iterator
+             it = unused_dependency_.begin();
+         it != unused_dependency_.end(); ++it) {
+      // Do not log warnings for proto files which extend annotations.
+      int i;
+      for (i = 0 ; i < (*it)->extension_count(); ++i) {
+        if (annotation_extensions.find(
+                (*it)->extension(i)->containing_type()->full_name())
+            != annotation_extensions.end()) {
+          break;
+        }
+      }
+      // Log warnings for unused imported files.
+      if (i == (*it)->extension_count()) {
+        GOOGLE_LOG(WARNING) << "Warning: Unused import: \"" << result->name()
+                     << "\" imports \"" << (*it)->name()
+                     << "\" which is not used.";
+      }
+    }
+  }
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/descriptor.h b/protobuf/src/google/protobuf/descriptor.h
new file mode 100644
index 0000000..fef4780
--- /dev/null
+++ b/protobuf/src/google/protobuf/descriptor.h
@@ -0,0 +1,1691 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <set>
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+
+namespace google {
+namespace protobuf {
+
+// Defined in this file.
+class Descriptor;
+class FieldDescriptor;
+class OneofDescriptor;
+class EnumDescriptor;
+class EnumValueDescriptor;
+class ServiceDescriptor;
+class MethodDescriptor;
+class FileDescriptor;
+class DescriptorDatabase;
+class DescriptorPool;
+
+// Defined in descriptor.proto
+class DescriptorProto;
+class FieldDescriptorProto;
+class OneofDescriptorProto;
+class EnumDescriptorProto;
+class EnumValueDescriptorProto;
+class ServiceDescriptorProto;
+class MethodDescriptorProto;
+class FileDescriptorProto;
+class MessageOptions;
+class FieldOptions;
+class EnumOptions;
+class EnumValueOptions;
+class ServiceOptions;
+class MethodOptions;
+class FileOptions;
+class UninterpretedOption;
+class SourceCodeInfo;
+
+// Defined in message.h
+class Message;
+
+// Defined in descriptor.cc
+class DescriptorBuilder;
+class FileDescriptorTables;
+
+// Defined in unknown_field_set.h.
+class UnknownField;
+
+// NB, all indices are zero-based.
+struct SourceLocation {
+  int start_line;
+  int end_line;
+  int start_column;
+  int end_column;
+
+  // Doc comments found at the source location.
+  // TODO(kenton):  Maybe this struct should have been named SourceInfo or
+  //   something instead.  Oh well.
+  string leading_comments;
+  string trailing_comments;
+};
+
+// 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.
+  // Allowed options are defined by MessageOptions in
+  // google/protobuf/descriptor.proto, and any available extensions of that
+  // message.
+  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;
+
+  // Returns true if this is a placeholder for an unknown type. This will
+  // only be the case if this descriptor comes from a DescriptorPool
+  // with AllowUnknownDependencies() set.
+  bool is_placeholder() 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().
+  // These are returned in the order they were defined in the .proto file.
+  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;
+
+  // Looks up a field by lowercased name (as returned by lowercase_name()).
+  // This lookup may be ambiguous if multiple field names differ only by case,
+  // in which case the field returned is chosen arbitrarily from the matches.
+  const FieldDescriptor* FindFieldByLowercaseName(
+      const string& lowercase_name) const;
+
+  // Looks up a field by camel-case name (as returned by camelcase_name()).
+  // This lookup may be ambiguous if multiple field names differ in a way that
+  // leads them to have identical camel-case names, in which case the field
+  // returned is chosen arbitrarily from the matches.
+  const FieldDescriptor* FindFieldByCamelcaseName(
+      const string& camelcase_name) const;
+
+  // The number of oneofs in this message type.
+  int oneof_decl_count() const;
+  // Get a oneof by index, where 0 <= index < oneof_decl_count().
+  // These are returned in the order they were defined in the .proto file.
+  const OneofDescriptor* oneof_decl(int index) const;
+
+  // Looks up a oneof by name.  Returns NULL if no such oneof exists.
+  const OneofDescriptor* FindOneofByName(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().
+  // These are returned in the order they were defined in the .proto file.
+  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().
+  // These are returned in the order they were defined in the .proto file.
+  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(). These are returned in the order they were defined
+  // in the .proto file.
+  const ExtensionRange* extension_range(int index) const;
+
+  // Returns true if the number is in one of the extension ranges.
+  bool IsExtensionNumber(int number) const;
+
+  // Returns NULL if no extension range contains the given number.
+  const ExtensionRange* FindExtensionRangeContainingNumber(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().
+  // These are returned in the order they were defined in the .proto file.
+  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;
+
+  // Similar to FindFieldByLowercaseName(), but finds extensions defined within
+  // this message type's scope.
+  const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const;
+
+  // Similar to FindFieldByCamelcaseName(), but finds extensions defined within
+  // this message type's scope.
+  const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
+
+  // Source Location ---------------------------------------------------
+
+  // Updates |*out_location| to the source location of the complete
+  // extent of this message declaration.  Returns false and leaves
+  // |*out_location| unchanged iff location information was not available.
+  bool GetSourceLocation(SourceLocation* out_location) const;
+
+ private:
+  typedef MessageOptions OptionsType;
+
+  // Internal version of DebugString; controls the level of indenting for
+  // correct depth
+  void DebugString(int depth, string *contents) const;
+
+  // Walks up the descriptor tree to generate the source location path
+  // to this descriptor from the file root.
+  void GetLocationPath(std::vector<int>* output) const;
+
+  const string* name_;
+  const string* full_name_;
+  const FileDescriptor* file_;
+  const Descriptor* containing_type_;
+  const MessageOptions* options_;
+
+  // True if this is a placeholder for an unknown type.
+  bool is_placeholder_;
+  // True if this is a placeholder and the type name wasn't fully-qualified.
+  bool is_unqualified_placeholder_;
+
+  int field_count_;
+  FieldDescriptor* fields_;
+  int oneof_decl_count_;
+  OneofDescriptor* oneof_decls_;
+  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_;
+  // IMPORTANT:  If you add a new field, make sure to search for all instances
+  // of Allocate<Descriptor>() and AllocateArray<Descriptor>() in descriptor.cc
+  // and update them to initialize the field.
+
+  // Must be constructed using DescriptorPool.
+  Descriptor() {}
+  friend class DescriptorBuilder;
+  friend class EnumDescriptor;
+  friend class FieldDescriptor;
+  friend class OneofDescriptor;
+  friend class MethodDescriptor;
+  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 Reflection for a message object, call
+//   Reflection::FindKnownExtensionByName() or
+//   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.
+
+  // Same as name() except converted to lower-case.  This (and especially the
+  // FindFieldByLowercaseName() method) can be useful when parsing formats
+  // which prefer to use lowercase naming style.  (Although, technically
+  // field names should be lowercased anyway according to the protobuf style
+  // guide, so this only makes a difference when dealing with old .proto files
+  // which do not follow the guide.)
+  const string& lowercase_name() const;
+
+  // Same as name() except converted to camel-case.  In this conversion, any
+  // time an underscore appears in the name, it is removed and the next
+  // letter is capitalized.  Furthermore, the first letter of the name is
+  // lower-cased.  Examples:
+  //   FooBar -> fooBar
+  //   foo_bar -> fooBar
+  //   fooBar -> fooBar
+  // This (and especially the FindFieldByCamelcaseName() method) can be useful
+  // when parsing formats which prefer to use camel-case naming style.
+  const string& camelcase_name() const;
+
+  Type type() const;                  // Declared type of this field.
+  const char* type_name() const;      // Name of the declared type.
+  CppType cpp_type() const;           // C++ type of this field.
+  const char* cpp_type_name() const;  // Name of the C++ type.
+  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
+  bool is_packable() const;      // shorthand for is_repeated() &&
+                                 //               IsTypePackable(type())
+  bool is_packed() const;        // shorthand for is_packable() &&
+                                 //               options().packed()
+
+  // 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;
+
+  // If the field is a member of a oneof, this is the one, otherwise this is
+  // NULL.
+  const OneofDescriptor* containing_oneof() const;
+
+  // If the field is a member of a oneof, returns the index in that oneof.
+  int index_in_oneof() 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, returns null.
+  const Descriptor* message_type() const;
+  // If type is TYPE_ENUM, returns a descriptor for the enum.  Otherwise,
+  // returns null.
+  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.  Allowed options are defined by FieldOptions
+  // in google/protobuf/descriptor.proto, and any available extensions of that
+  // message.
+  const FieldOptions& options() const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(FieldDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+  // Helper method to get the CppType for a particular Type.
+  static CppType TypeToCppType(Type type);
+
+  // Helper method to get the name of a Type.
+  static const char* TypeName(Type type);
+
+  // Helper method to get the name of a CppType.
+  static const char* CppTypeName(CppType cpp_type);
+
+  // Return true iff [packed = true] is valid for fields of this type.
+  static inline bool IsTypePackable(Type field_type);
+
+  // Source Location ---------------------------------------------------
+
+  // Updates |*out_location| to the source location of the complete
+  // extent of this field declaration.  Returns false and leaves
+  // |*out_location| unchanged iff location information was not available.
+  bool GetSourceLocation(SourceLocation* out_location) const;
+
+ private:
+  typedef FieldOptions OptionsType;
+
+  // See Descriptor::DebugString().
+  enum PrintLabelFlag { PRINT_LABEL, OMIT_LABEL };
+  void DebugString(int depth, PrintLabelFlag print_label_flag,
+                   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;
+
+  // Walks up the descriptor tree to generate the source location path
+  // to this descriptor from the file root.
+  void GetLocationPath(std::vector<int>* output) const;
+
+  const string* name_;
+  const string* full_name_;
+  const string* lowercase_name_;
+  const string* camelcase_name_;
+  const FileDescriptor* file_;
+  int number_;
+  Type type_;
+  Label label_;
+  bool is_extension_;
+  int index_in_oneof_;
+  const Descriptor* containing_type_;
+  const OneofDescriptor* containing_oneof_;
+  const Descriptor* extension_scope_;
+  const Descriptor* message_type_;
+  const EnumDescriptor* enum_type_;
+  const FieldDescriptor* experimental_map_key_;
+  const FieldOptions* options_;
+  // IMPORTANT:  If you add a new field, make sure to search for all instances
+  // of Allocate<FieldDescriptor>() and AllocateArray<FieldDescriptor>() in
+  // descriptor.cc and update them to initialize the field.
+
+  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 kCppTypeToName[MAX_CPPTYPE + 1];
+
+  static const char * const kLabelToName[MAX_LABEL + 1];
+
+  // Must be constructed using DescriptorPool.
+  FieldDescriptor() {}
+  friend class DescriptorBuilder;
+  friend class FileDescriptor;
+  friend class Descriptor;
+  friend class OneofDescriptor;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldDescriptor);
+};
+
+// Describes a oneof defined in a message type.
+class LIBPROTOBUF_EXPORT OneofDescriptor {
+ public:
+  const string& name() const;       // Name of this oneof.
+  const string& full_name() const;  // Fully-qualified name of the oneof.
+
+  // Index of this oneof within the message's oneof array.
+  int index() const;
+
+  // The Descriptor for the message containing this oneof.
+  const Descriptor* containing_type() const;
+
+  // The number of (non-extension) fields which are members of this oneof.
+  int field_count() const;
+  // Get a member of this oneof, in the order in which they were declared in the
+  // .proto file.  Does not include extensions.
+  const FieldDescriptor* field(int index) const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(OneofDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+  // Source Location ---------------------------------------------------
+
+  // Updates |*out_location| to the source location of the complete
+  // extent of this oneof declaration.  Returns false and leaves
+  // |*out_location| unchanged iff location information was not available.
+  bool GetSourceLocation(SourceLocation* out_location) const;
+
+ private:
+  // See Descriptor::DebugString().
+  void DebugString(int depth, string* contents) const;
+
+  // Walks up the descriptor tree to generate the source location path
+  // to this descriptor from the file root.
+  void GetLocationPath(std::vector<int>* output) const;
+
+  const string* name_;
+  const string* full_name_;
+  const Descriptor* containing_type_;
+  bool is_extendable_;
+  int field_count_;
+  const FieldDescriptor** fields_;
+  // IMPORTANT:  If you add a new field, make sure to search for all instances
+  // of Allocate<OneofDescriptor>() and AllocateArray<OneofDescriptor>()
+  // in descriptor.cc and update them to initialize the field.
+
+  // Must be constructed using DescriptorPool.
+  OneofDescriptor() {}
+  friend class DescriptorBuilder;
+  friend class Descriptor;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OneofDescriptor);
+};
+
+// 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().
+  // These are returned in the order they were defined in the .proto file.
+  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.  Allowed
+  // options are defined by EnumOptions in google/protobuf/descriptor.proto,
+  // and any available extensions of that message.
+  const EnumOptions& options() const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(EnumDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+  // Returns true if this is a placeholder for an unknown enum. This will
+  // only be the case if this descriptor comes from a DescriptorPool
+  // with AllowUnknownDependencies() set.
+  bool is_placeholder() const;
+
+  // Source Location ---------------------------------------------------
+
+  // Updates |*out_location| to the source location of the complete
+  // extent of this enum declaration.  Returns false and leaves
+  // |*out_location| unchanged iff location information was not available.
+  bool GetSourceLocation(SourceLocation* out_location) const;
+
+ private:
+  typedef EnumOptions OptionsType;
+
+  // See Descriptor::DebugString().
+  void DebugString(int depth, string *contents) const;
+
+  // Walks up the descriptor tree to generate the source location path
+  // to this descriptor from the file root.
+  void GetLocationPath(std::vector<int>* output) const;
+
+  const string* name_;
+  const string* full_name_;
+  const FileDescriptor* file_;
+  const Descriptor* containing_type_;
+  const EnumOptions* options_;
+
+  // True if this is a placeholder for an unknown type.
+  bool is_placeholder_;
+  // True if this is a placeholder and the type name wasn't fully-qualified.
+  bool is_unqualified_placeholder_;
+
+  int value_count_;
+  EnumValueDescriptor* values_;
+  // IMPORTANT:  If you add a new field, make sure to search for all instances
+  // of Allocate<EnumDescriptor>() and AllocateArray<EnumDescriptor>() in
+  // descriptor.cc and update them to initialize the field.
+
+  // Must be constructed using DescriptorPool.
+  EnumDescriptor() {}
+  friend class DescriptorBuilder;
+  friend class Descriptor;
+  friend class FieldDescriptor;
+  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.
+  // Allowed options are defined by EnumValueOptions in
+  // google/protobuf/descriptor.proto, and any available extensions of that
+  // message.
+  const EnumValueOptions& options() const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(EnumValueDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+  // Source Location ---------------------------------------------------
+
+  // Updates |*out_location| to the source location of the complete
+  // extent of this enum value declaration.  Returns false and leaves
+  // |*out_location| unchanged iff location information was not available.
+  bool GetSourceLocation(SourceLocation* out_location) const;
+
+ private:
+  typedef EnumValueOptions OptionsType;
+
+  // See Descriptor::DebugString().
+  void DebugString(int depth, string *contents) const;
+
+  // Walks up the descriptor tree to generate the source location path
+  // to this descriptor from the file root.
+  void GetLocationPath(std::vector<int>* output) const;
+
+  const string* name_;
+  const string* full_name_;
+  int number_;
+  const EnumDescriptor* type_;
+  const EnumValueOptions* options_;
+  // IMPORTANT:  If you add a new field, make sure to search for all instances
+  // of Allocate<EnumValueDescriptor>() and AllocateArray<EnumValueDescriptor>()
+  // in descriptor.cc and update them to initialize the field.
+
+  // 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.
+  // Allowed options are defined by ServiceOptions in
+  // google/protobuf/descriptor.proto, and any available extensions of that
+  // message.
+  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().
+  // These are returned in the order they were defined in the .proto file.
+  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;
+
+  // Source Location ---------------------------------------------------
+
+  // Updates |*out_location| to the source location of the complete
+  // extent of this service declaration.  Returns false and leaves
+  // |*out_location| unchanged iff location information was not available.
+  bool GetSourceLocation(SourceLocation* out_location) const;
+
+ private:
+  typedef ServiceOptions OptionsType;
+
+  // See Descriptor::DebugString().
+  void DebugString(string *contents) const;
+
+  // Walks up the descriptor tree to generate the source location path
+  // to this descriptor from the file root.
+  void GetLocationPath(std::vector<int>* output) const;
+
+  const string* name_;
+  const string* full_name_;
+  const FileDescriptor* file_;
+  const ServiceOptions* options_;
+  int method_count_;
+  MethodDescriptor* methods_;
+  // IMPORTANT:  If you add a new field, make sure to search for all instances
+  // of Allocate<ServiceDescriptor>() and AllocateArray<ServiceDescriptor>() in
+  // descriptor.cc and update them to initialize the field.
+
+  // 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.  Allowed options are defined by MethodOptions in
+  // google/protobuf/descriptor.proto, and any available extensions of that
+  // message.
+  const MethodOptions& options() const;
+
+  // See Descriptor::CopyTo().
+  void CopyTo(MethodDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+  // Source Location ---------------------------------------------------
+
+  // Updates |*out_location| to the source location of the complete
+  // extent of this method declaration.  Returns false and leaves
+  // |*out_location| unchanged iff location information was not available.
+  bool GetSourceLocation(SourceLocation* out_location) const;
+
+ private:
+  typedef MethodOptions OptionsType;
+
+  // See Descriptor::DebugString().
+  void DebugString(int depth, string *contents) const;
+
+  // Walks up the descriptor tree to generate the source location path
+  // to this descriptor from the file root.
+  void GetLocationPath(std::vector<int>* output) const;
+
+  const string* name_;
+  const string* full_name_;
+  const ServiceDescriptor* service_;
+  const Descriptor* input_type_;
+  const Descriptor* output_type_;
+  const MethodOptions* options_;
+  // IMPORTANT:  If you add a new field, make sure to search for all instances
+  // of Allocate<MethodDescriptor>() and AllocateArray<MethodDescriptor>() in
+  // descriptor.cc and update them to initialize the field.
+
+  // 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().
+  // These are returned in the order they were defined in the .proto file.
+  const FileDescriptor* dependency(int index) const;
+
+  // The number of files public imported by this one.
+  // The public dependency list is a subset of the dependency list.
+  int public_dependency_count() const;
+  // Gets a public imported file by index, where 0 <= index <
+  // public_dependency_count().
+  // These are returned in the order they were defined in the .proto file.
+  const FileDescriptor* public_dependency(int index) const;
+
+  // The number of files that are imported for weak fields.
+  // The weak dependency list is a subset of the dependency list.
+  int weak_dependency_count() const;
+  // Gets a weak imported file by index, where 0 <= index <
+  // weak_dependency_count().
+  // These are returned in the order they were defined in the .proto file.
+  const FileDescriptor* weak_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().
+  // These are returned in the order they were defined in the .proto file.
+  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().
+  // These are returned in the order they were defined in the .proto file.
+  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().
+  // These are returned in the order they were defined in the .proto file.
+  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().
+  // These are returned in the order they were defined in the .proto file.
+  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.  Allowed options are defined by FileOptions in
+  // google/protobuf/descriptor.proto, and any available extensions of that
+  // message.
+  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;
+  // Similar to FindExtensionByName(), but searches by lowercased-name.  See
+  // Descriptor::FindFieldByLowercaseName().
+  const FieldDescriptor* FindExtensionByLowercaseName(const string& name) const;
+  // Similar to FindExtensionByName(), but searches by camelcased-name.  See
+  // Descriptor::FindFieldByCamelcaseName().
+  const FieldDescriptor* FindExtensionByCamelcaseName(const string& name) const;
+
+  // See Descriptor::CopyTo().
+  // Notes:
+  // - This method does NOT copy source code information since it is relatively
+  //   large and rarely needed.  See CopySourceCodeInfoTo() below.
+  void CopyTo(FileDescriptorProto* proto) const;
+  // Write the source code information of this FileDescriptor into the given
+  // FileDescriptorProto.  See CopyTo() above.
+  void CopySourceCodeInfoTo(FileDescriptorProto* proto) const;
+
+  // See Descriptor::DebugString().
+  string DebugString() const;
+
+  // Returns true if this is a placeholder for an unknown file. This will
+  // only be the case if this descriptor comes from a DescriptorPool
+  // with AllowUnknownDependencies() set.
+  bool is_placeholder() const;
+
+ private:
+  // Source Location ---------------------------------------------------
+
+  // Updates |*out_location| to the source location of the complete
+  // extent of the declaration or declaration-part denoted by |path|.
+  // Returns false and leaves |*out_location| unchanged iff location
+  // information was not available.  (See SourceCodeInfo for
+  // description of path encoding.)
+  bool GetSourceLocation(const std::vector<int>& path,
+                         SourceLocation* out_location) const;
+
+  typedef FileOptions OptionsType;
+
+  const string* name_;
+  const string* package_;
+  const DescriptorPool* pool_;
+  int dependency_count_;
+  const FileDescriptor** dependencies_;
+  int public_dependency_count_;
+  int* public_dependencies_;
+  int weak_dependency_count_;
+  int* weak_dependencies_;
+  int message_type_count_;
+  Descriptor* message_types_;
+  int enum_type_count_;
+  EnumDescriptor* enum_types_;
+  int service_count_;
+  ServiceDescriptor* services_;
+  int extension_count_;
+  bool is_placeholder_;
+  FieldDescriptor* extensions_;
+  const FileOptions* options_;
+
+  const FileDescriptorTables* tables_;
+  const SourceCodeInfo* source_code_info_;
+  // IMPORTANT:  If you add a new field, make sure to search for all instances
+  // of Allocate<FileDescriptor>() and AllocateArray<FileDescriptor>() in
+  // descriptor.cc and update them to initialize the field.
+
+  FileDescriptor() {}
+  friend class DescriptorBuilder;
+  friend class Descriptor;
+  friend class FieldDescriptor;
+  friend class OneofDescriptor;
+  friend class EnumDescriptor;
+  friend class EnumValueDescriptor;
+  friend class MethodDescriptor;
+  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.
+  // - The DescriptorDatabase must not be mutated during the lifetime of
+  //   the DescriptorPool. Even if the client takes care to avoid data races,
+  //   changes to the content of the DescriptorDatabase may not be reflected
+  //   in subsequent lookups in the DescriptorPool.
+  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 OneofDescriptor* FindOneofByName(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;
+
+  // Finds extensions of extendee. The extensions will be appended to
+  // out in an undefined order. Only extensions defined directly in
+  // this DescriptorPool or one of its underlays are guaranteed to be
+  // found: extensions defined in the fallback database might not be found
+  // depending on the database implementation.
+  void FindAllExtensions(const Descriptor* extendee,
+                         std::vector<const FieldDescriptor*>* out) 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
+      OPTION_NAME,       // name in assignment
+      OPTION_VALUE,      // value in option assignment
+      OTHER              // some other problem
+    };
+
+    // Reports an error in the FileDescriptorProto. Use this function if the
+    // problem occured should interrupt building 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;
+
+    // Reports a warning in the FileDescriptorProto. Use this function if the
+    // problem occured should NOT interrupt building the FileDescriptorProto.
+    virtual void AddWarning(
+      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.
+      ) {}
+
+   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);
+
+  // By default, it is an error if a FileDescriptorProto contains references
+  // to types or other files that are not found in the DescriptorPool (or its
+  // backing DescriptorDatabase, if any).  If you call
+  // AllowUnknownDependencies(), however, then unknown types and files
+  // will be replaced by placeholder descriptors (which can be identified by
+  // the is_placeholder() method).  This can allow you to
+  // perform some useful operations with a .proto file even if you do not
+  // have access to other .proto files on which it depends.  However, some
+  // heuristics must be used to fill in the gaps in information, and these
+  // can lead to descriptors which are inaccurate.  For example, the
+  // DescriptorPool may be forced to guess whether an unknown type is a message
+  // or an enum, as well as what package it resides in.  Furthermore,
+  // placeholder types will not be discoverable via FindMessageTypeByName()
+  // and similar methods, which could confuse some descriptor-based algorithms.
+  // Generally, the results of this option should be handled with extreme care.
+  void AllowUnknownDependencies() { allow_unknown_ = true; }
+
+  // By default, weak imports are allowed to be missing, in which case we will
+  // use a placeholder for the dependency and convert the field to be an Empty
+  // message field. If you call EnforceWeakDependencies(true), however, the
+  // DescriptorPool will report a import not found error.
+  void EnforceWeakDependencies(bool enforce) { enforce_weak_ = enforce; }
+
+  // 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.
+
+  // 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.
+  //
+  // WARNING:  Use of underlays can lead to many subtle gotchas.  Instead,
+  //   try to formulate what you want to do in terms of DescriptorDatabases.
+  explicit DescriptorPool(const DescriptorPool* underlay);
+
+  // Called by generated classes at init time to add their descriptors to
+  // generated_pool.  Do NOT call this in your own code!  filename must be a
+  // permanent string (e.g. a string literal).
+  static void InternalAddGeneratedFile(
+      const void* encoded_file_descriptor, 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 underlay 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;
+  }
+
+  // For internal (unit test) use only:  Returns true if a FileDescriptor has
+  // been constructed for the given file, false otherwise.  Useful for testing
+  // lazy descriptor initialization behavior.
+  bool InternalIsFileLoaded(const string& filename) const;
+
+
+  // Add a file to unused_import_track_files_. DescriptorBuilder will log
+  // warnings for those files if there is any unused import.
+  void AddUnusedImportTrackFile(const string& file_name);
+  void ClearUnusedImportTrackFiles();
+
+ private:
+  friend class Descriptor;
+  friend class FieldDescriptor;
+  friend class EnumDescriptor;
+  friend class ServiceDescriptor;
+  friend class FileDescriptor;
+  friend class DescriptorBuilder;
+
+  // Return true if the given name is a sub-symbol of any non-package
+  // descriptor that already exists in the descriptor pool.  (The full
+  // definition of such types is already known.)
+  bool IsSubSymbolOfBuiltType(const string& name) const;
+
+  // 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_;
+  bool allow_unknown_;
+  bool enforce_weak_;
+  std::set<string> unused_import_track_files_;
+
+  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, oneof_decl_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, oneof_decl, const OneofDescriptor*)
+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_ACCESSOR(Descriptor, is_placeholder, bool)
+
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, full_name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, lowercase_name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, camelcase_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, containing_oneof,
+                         const OneofDescriptor*)
+PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, index_in_oneof, int)
+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(OneofDescriptor, name)
+PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, full_name)
+PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, containing_type, const Descriptor*)
+PROTOBUF_DEFINE_ACCESSOR(OneofDescriptor, field_count, int)
+
+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_ACCESSOR(EnumDescriptor, is_placeholder, bool)
+
+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, public_dependency_count, int)
+PROTOBUF_DEFINE_ACCESSOR(FileDescriptor, weak_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_ACCESSOR(FileDescriptor, is_placeholder, bool)
+
+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 Descriptor::IsExtensionNumber(int number) const {
+  return FindExtensionRangeContainingNumber(number) != NULL;
+}
+
+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;
+}
+
+inline bool FieldDescriptor::is_packable() const {
+  return is_repeated() && IsTypePackable(type());
+}
+
+// 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 static_cast<int>(this - containing_type_->fields_);
+  } else if (extension_scope_ != NULL) {
+    return static_cast<int>(this - extension_scope_->extensions_);
+  } else {
+    return static_cast<int>(this - file_->extensions_);
+  }
+}
+
+inline int Descriptor::index() const {
+  if (containing_type_ == NULL) {
+    return static_cast<int>(this - file_->message_types_);
+  } else {
+    return static_cast<int>(this - containing_type_->nested_types_);
+  }
+}
+
+inline int OneofDescriptor::index() const {
+  return static_cast<int>(this - containing_type_->oneof_decls_);
+}
+
+inline int EnumDescriptor::index() const {
+  if (containing_type_ == NULL) {
+    return static_cast<int>(this - file_->enum_types_);
+  } else {
+    return static_cast<int>(this - containing_type_->enum_types_);
+  }
+}
+
+inline int EnumValueDescriptor::index() const {
+  return static_cast<int>(this - type_->values_);
+}
+
+inline int ServiceDescriptor::index() const {
+  return static_cast<int>(this - file_->services_);
+}
+
+inline int MethodDescriptor::index() const {
+  return static_cast<int>(this - service_->methods_);
+}
+
+inline const char* FieldDescriptor::type_name() const {
+  return kTypeToName[type_];
+}
+
+inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const {
+  return kTypeToCppTypeMap[type_];
+}
+
+inline const char* FieldDescriptor::cpp_type_name() const {
+  return kCppTypeToName[kTypeToCppTypeMap[type_]];
+}
+
+inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) {
+  return kTypeToCppTypeMap[type];
+}
+
+inline const char* FieldDescriptor::TypeName(Type type) {
+  return kTypeToName[type];
+}
+
+inline const char* FieldDescriptor::CppTypeName(CppType cpp_type) {
+  return kCppTypeToName[cpp_type];
+}
+
+inline bool FieldDescriptor::IsTypePackable(Type field_type) {
+  return (field_type != FieldDescriptor::TYPE_STRING &&
+          field_type != FieldDescriptor::TYPE_GROUP &&
+          field_type != FieldDescriptor::TYPE_MESSAGE &&
+          field_type != FieldDescriptor::TYPE_BYTES);
+}
+
+inline const FileDescriptor* FileDescriptor::dependency(int index) const {
+  return dependencies_[index];
+}
+
+inline const FileDescriptor* FileDescriptor::public_dependency(
+    int index) const {
+  return dependencies_[public_dependencies_[index]];
+}
+
+inline const FileDescriptor* FileDescriptor::weak_dependency(
+    int index) const {
+  return dependencies_[weak_dependencies_[index]];
+}
+
+// Can't use PROTOBUF_DEFINE_ARRAY_ACCESSOR because fields_ is actually an array
+// of pointers rather than the usual array of objects.
+inline const FieldDescriptor* OneofDescriptor::field(int index) const {
+  return fields_[index];
+}
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_DESCRIPTOR_H__
diff --git a/protobuf/src/google/protobuf/descriptor.pb.cc b/protobuf/src/google/protobuf/descriptor.pb.cc
new file mode 100644
index 0000000..242e3c0
--- /dev/null
+++ b/protobuf/src/google/protobuf/descriptor.pb.cc
@@ -0,0 +1,9173 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/descriptor.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "google/protobuf/descriptor.pb.h"
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+const ::google::protobuf::Descriptor* FileDescriptorSet_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FileDescriptorSet_reflection_ = NULL;
+const ::google::protobuf::Descriptor* FileDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FileDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* DescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  DescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  DescriptorProto_ExtensionRange_reflection_ = NULL;
+const ::google::protobuf::Descriptor* FieldDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FieldDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor_ = NULL;
+const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* OneofDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  OneofDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* EnumDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  EnumDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* EnumValueDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  EnumValueDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ServiceDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ServiceDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* MethodDescriptorProto_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  MethodDescriptorProto_reflection_ = NULL;
+const ::google::protobuf::Descriptor* FileOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FileOptions_reflection_ = NULL;
+const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* MessageOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  MessageOptions_reflection_ = NULL;
+const ::google::protobuf::Descriptor* FieldOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FieldOptions_reflection_ = NULL;
+const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL;
+const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  EnumOptions_reflection_ = NULL;
+const ::google::protobuf::Descriptor* EnumValueOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  EnumValueOptions_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ServiceOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ServiceOptions_reflection_ = NULL;
+const ::google::protobuf::Descriptor* MethodOptions_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  MethodOptions_reflection_ = NULL;
+const ::google::protobuf::Descriptor* UninterpretedOption_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  UninterpretedOption_reflection_ = NULL;
+const ::google::protobuf::Descriptor* UninterpretedOption_NamePart_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  UninterpretedOption_NamePart_reflection_ = NULL;
+const ::google::protobuf::Descriptor* SourceCodeInfo_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  SourceCodeInfo_reflection_ = NULL;
+const ::google::protobuf::Descriptor* SourceCodeInfo_Location_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  SourceCodeInfo_Location_reflection_ = NULL;
+
+}  // namespace
+
+
+void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
+  protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  const ::google::protobuf::FileDescriptor* file =
+    ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+      "google/protobuf/descriptor.proto");
+  GOOGLE_CHECK(file != NULL);
+  FileDescriptorSet_descriptor_ = file->message_type(0);
+  static const int FileDescriptorSet_offsets_[1] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, file_),
+  };
+  FileDescriptorSet_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      FileDescriptorSet_descriptor_,
+      FileDescriptorSet::default_instance_,
+      FileDescriptorSet_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(FileDescriptorSet));
+  FileDescriptorProto_descriptor_ = file->message_type(1);
+  static const int FileDescriptorProto_offsets_[11] = {
+    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, public_dependency_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, weak_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_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, source_code_info_),
+  };
+  FileDescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      FileDescriptorProto_descriptor_,
+      FileDescriptorProto::default_instance_,
+      FileDescriptorProto_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(FileDescriptorProto));
+  DescriptorProto_descriptor_ = file->message_type(2);
+  static const int DescriptorProto_offsets_[8] = {
+    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, oneof_decl_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, options_),
+  };
+  DescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      DescriptorProto_descriptor_,
+      DescriptorProto::default_instance_,
+      DescriptorProto_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(DescriptorProto));
+  DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0);
+  static 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_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      DescriptorProto_ExtensionRange_descriptor_,
+      DescriptorProto_ExtensionRange::default_instance_,
+      DescriptorProto_ExtensionRange_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(DescriptorProto_ExtensionRange));
+  FieldDescriptorProto_descriptor_ = file->message_type(3);
+  static const int FieldDescriptorProto_offsets_[9] = {
+    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, oneof_index_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, options_),
+  };
+  FieldDescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      FieldDescriptorProto_descriptor_,
+      FieldDescriptorProto::default_instance_,
+      FieldDescriptorProto_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(FieldDescriptorProto));
+  FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0);
+  FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1);
+  OneofDescriptorProto_descriptor_ = file->message_type(4);
+  static const int OneofDescriptorProto_offsets_[1] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, name_),
+  };
+  OneofDescriptorProto_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      OneofDescriptorProto_descriptor_,
+      OneofDescriptorProto::default_instance_,
+      OneofDescriptorProto_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(OneofDescriptorProto));
+  EnumDescriptorProto_descriptor_ = file->message_type(5);
+  static 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_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      EnumDescriptorProto_descriptor_,
+      EnumDescriptorProto::default_instance_,
+      EnumDescriptorProto_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(EnumDescriptorProto));
+  EnumValueDescriptorProto_descriptor_ = file->message_type(6);
+  static 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_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      EnumValueDescriptorProto_descriptor_,
+      EnumValueDescriptorProto::default_instance_,
+      EnumValueDescriptorProto_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(EnumValueDescriptorProto));
+  ServiceDescriptorProto_descriptor_ = file->message_type(7);
+  static 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_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      ServiceDescriptorProto_descriptor_,
+      ServiceDescriptorProto::default_instance_,
+      ServiceDescriptorProto_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(ServiceDescriptorProto));
+  MethodDescriptorProto_descriptor_ = file->message_type(8);
+  static 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_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      MethodDescriptorProto_descriptor_,
+      MethodDescriptorProto::default_instance_,
+      MethodDescriptorProto_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(MethodDescriptorProto));
+  FileOptions_descriptor_ = file->message_type(9);
+  static const int FileOptions_offsets_[13] = {
+    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, java_generate_equals_and_hash_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_string_check_utf8_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, go_package_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, py_generic_services_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, deprecated_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, javanano_use_deprecated_package_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
+  };
+  FileOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      FileOptions_descriptor_,
+      FileOptions::default_instance_,
+      FileOptions_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _unknown_fields_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _extensions_),
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(FileOptions));
+  FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0);
+  MessageOptions_descriptor_ = file->message_type(10);
+  static const int MessageOptions_offsets_[4] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, no_standard_descriptor_accessor_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, deprecated_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, uninterpreted_option_),
+  };
+  MessageOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      MessageOptions_descriptor_,
+      MessageOptions::default_instance_,
+      MessageOptions_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _unknown_fields_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _extensions_),
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(MessageOptions));
+  FieldOptions_descriptor_ = file->message_type(11);
+  static const int FieldOptions_offsets_[7] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, lazy_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, deprecated_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, experimental_map_key_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, weak_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, uninterpreted_option_),
+  };
+  FieldOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      FieldOptions_descriptor_,
+      FieldOptions::default_instance_,
+      FieldOptions_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _unknown_fields_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _extensions_),
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(FieldOptions));
+  FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0);
+  EnumOptions_descriptor_ = file->message_type(12);
+  static const int EnumOptions_offsets_[3] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, allow_alias_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, deprecated_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, uninterpreted_option_),
+  };
+  EnumOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      EnumOptions_descriptor_,
+      EnumOptions::default_instance_,
+      EnumOptions_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _unknown_fields_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _extensions_),
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(EnumOptions));
+  EnumValueOptions_descriptor_ = file->message_type(13);
+  static const int EnumValueOptions_offsets_[2] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, deprecated_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_),
+  };
+  EnumValueOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      EnumValueOptions_descriptor_,
+      EnumValueOptions::default_instance_,
+      EnumValueOptions_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _unknown_fields_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _extensions_),
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(EnumValueOptions));
+  ServiceOptions_descriptor_ = file->message_type(14);
+  static const int ServiceOptions_offsets_[2] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, deprecated_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_),
+  };
+  ServiceOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      ServiceOptions_descriptor_,
+      ServiceOptions::default_instance_,
+      ServiceOptions_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _unknown_fields_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _extensions_),
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(ServiceOptions));
+  MethodOptions_descriptor_ = file->message_type(15);
+  static const int MethodOptions_offsets_[2] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, deprecated_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_),
+  };
+  MethodOptions_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      MethodOptions_descriptor_,
+      MethodOptions::default_instance_,
+      MethodOptions_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _unknown_fields_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _extensions_),
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(MethodOptions));
+  UninterpretedOption_descriptor_ = file->message_type(16);
+  static const int UninterpretedOption_offsets_[7] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, negative_int_value_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, double_value_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, string_value_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, aggregate_value_),
+  };
+  UninterpretedOption_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      UninterpretedOption_descriptor_,
+      UninterpretedOption::default_instance_,
+      UninterpretedOption_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(UninterpretedOption));
+  UninterpretedOption_NamePart_descriptor_ = UninterpretedOption_descriptor_->nested_type(0);
+  static const int UninterpretedOption_NamePart_offsets_[2] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, name_part_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, is_extension_),
+  };
+  UninterpretedOption_NamePart_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      UninterpretedOption_NamePart_descriptor_,
+      UninterpretedOption_NamePart::default_instance_,
+      UninterpretedOption_NamePart_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(UninterpretedOption_NamePart));
+  SourceCodeInfo_descriptor_ = file->message_type(17);
+  static const int SourceCodeInfo_offsets_[1] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_),
+  };
+  SourceCodeInfo_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      SourceCodeInfo_descriptor_,
+      SourceCodeInfo::default_instance_,
+      SourceCodeInfo_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(SourceCodeInfo));
+  SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0);
+  static const int SourceCodeInfo_Location_offsets_[4] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, leading_comments_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, trailing_comments_),
+  };
+  SourceCodeInfo_Location_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      SourceCodeInfo_Location_descriptor_,
+      SourceCodeInfo_Location::default_instance_,
+      SourceCodeInfo_Location_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(SourceCodeInfo_Location));
+}
+
+namespace {
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
+inline void protobuf_AssignDescriptorsOnce() {
+  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
+                 &protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    FileDescriptorSet_descriptor_, &FileDescriptorSet::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    FileDescriptorProto_descriptor_, &FileDescriptorProto::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    DescriptorProto_descriptor_, &DescriptorProto::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    DescriptorProto_ExtensionRange_descriptor_, &DescriptorProto_ExtensionRange::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    FieldDescriptorProto_descriptor_, &FieldDescriptorProto::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    OneofDescriptorProto_descriptor_, &OneofDescriptorProto::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    EnumDescriptorProto_descriptor_, &EnumDescriptorProto::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    EnumValueDescriptorProto_descriptor_, &EnumValueDescriptorProto::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    ServiceDescriptorProto_descriptor_, &ServiceDescriptorProto::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    MethodDescriptorProto_descriptor_, &MethodDescriptorProto::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    FileOptions_descriptor_, &FileOptions::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    MessageOptions_descriptor_, &MessageOptions::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    FieldOptions_descriptor_, &FieldOptions::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    EnumOptions_descriptor_, &EnumOptions::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    EnumValueOptions_descriptor_, &EnumValueOptions::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    ServiceOptions_descriptor_, &ServiceOptions::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    MethodOptions_descriptor_, &MethodOptions::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    UninterpretedOption_descriptor_, &UninterpretedOption::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    UninterpretedOption_NamePart_descriptor_, &UninterpretedOption_NamePart::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    SourceCodeInfo_descriptor_, &SourceCodeInfo::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    SourceCodeInfo_Location_descriptor_, &SourceCodeInfo_Location::default_instance());
+}
+
+}  // namespace
+
+void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
+  delete FileDescriptorSet::default_instance_;
+  delete FileDescriptorSet_reflection_;
+  delete FileDescriptorProto::default_instance_;
+  delete FileDescriptorProto_reflection_;
+  delete DescriptorProto::default_instance_;
+  delete DescriptorProto_reflection_;
+  delete DescriptorProto_ExtensionRange::default_instance_;
+  delete DescriptorProto_ExtensionRange_reflection_;
+  delete FieldDescriptorProto::default_instance_;
+  delete FieldDescriptorProto_reflection_;
+  delete OneofDescriptorProto::default_instance_;
+  delete OneofDescriptorProto_reflection_;
+  delete EnumDescriptorProto::default_instance_;
+  delete EnumDescriptorProto_reflection_;
+  delete EnumValueDescriptorProto::default_instance_;
+  delete EnumValueDescriptorProto_reflection_;
+  delete ServiceDescriptorProto::default_instance_;
+  delete ServiceDescriptorProto_reflection_;
+  delete MethodDescriptorProto::default_instance_;
+  delete MethodDescriptorProto_reflection_;
+  delete FileOptions::default_instance_;
+  delete FileOptions_reflection_;
+  delete MessageOptions::default_instance_;
+  delete MessageOptions_reflection_;
+  delete FieldOptions::default_instance_;
+  delete FieldOptions_reflection_;
+  delete EnumOptions::default_instance_;
+  delete EnumOptions_reflection_;
+  delete EnumValueOptions::default_instance_;
+  delete EnumValueOptions_reflection_;
+  delete ServiceOptions::default_instance_;
+  delete ServiceOptions_reflection_;
+  delete MethodOptions::default_instance_;
+  delete MethodOptions_reflection_;
+  delete UninterpretedOption::default_instance_;
+  delete UninterpretedOption_reflection_;
+  delete UninterpretedOption_NamePart::default_instance_;
+  delete UninterpretedOption_NamePart_reflection_;
+  delete SourceCodeInfo::default_instance_;
+  delete SourceCodeInfo_reflection_;
+  delete SourceCodeInfo_Location::default_instance_;
+  delete SourceCodeInfo_Location_reflection_;
+}
+
+void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
+  static bool already_here = false;
+  if (already_here) return;
+  already_here = true;
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+    "\n google/protobuf/descriptor.proto\022\017goog"
+    "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
+    "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
+    "roto\"\313\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
+    "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
+    "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen"
+    "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog"
+    "le.protobuf.DescriptorProto\0227\n\tenum_type"
+    "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP"
+    "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf."
+    "ServiceDescriptorProto\0228\n\textension\030\007 \003("
+    "\0132%.google.protobuf.FieldDescriptorProto"
+    "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File"
+    "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog"
+    "le.protobuf.SourceCodeInfo\"\344\003\n\017Descripto"
+    "rProto\022\014\n\004name\030\001 \001(\t\0224\n\005field\030\002 \003(\0132%.go"
+    "ogle.protobuf.FieldDescriptorProto\0228\n\tex"
+    "tension\030\006 \003(\0132%.google.protobuf.FieldDes"
+    "criptorProto\0225\n\013nested_type\030\003 \003(\0132 .goog"
+    "le.protobuf.DescriptorProto\0227\n\tenum_type"
+    "\030\004 \003(\0132$.google.protobuf.EnumDescriptorP"
+    "roto\022H\n\017extension_range\030\005 \003(\0132/.google.p"
+    "rotobuf.DescriptorProto.ExtensionRange\0229"
+    "\n\noneof_decl\030\010 \003(\0132%.google.protobuf.One"
+    "ofDescriptorProto\0220\n\007options\030\007 \001(\0132\037.goo"
+    "gle.protobuf.MessageOptions\032,\n\016Extension"
+    "Range\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\251\005\n\024Fi"
+    "eldDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006numb"
+    "er\030\003 \001(\005\022:\n\005label\030\004 \001(\0162+.google.protobu"
+    "f.FieldDescriptorProto.Label\0228\n\004type\030\005 \001"
+    "(\0162*.google.protobuf.FieldDescriptorProt"
+    "o.Type\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\023\n\013oneof_inde"
+    "x\030\t \001(\005\022.\n\007options\030\010 \001(\0132\035.google.protob"
+    "uf.FieldOptions\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020"
+    "\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYP"
+    "E_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED"
+    "64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n"
+    "\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_M"
+    "ESSAGE\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\rT"
+    "YPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_"
+    "SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n"
+    "\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPEATED\020\003\"$\n"
+    "\024OneofDescriptorProto\022\014\n\004name\030\001 \001(\t\"\214\001\n\023"
+    "EnumDescriptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005val"
+    "ue\030\002 \003(\0132).google.protobuf.EnumValueDesc"
+    "riptorProto\022-\n\007options\030\003 \001(\0132\034.google.pr"
+    "otobuf.EnumOptions\"l\n\030EnumValueDescripto"
+    "rProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007"
+    "options\030\003 \001(\0132!.google.protobuf.EnumValu"
+    "eOptions\"\220\001\n\026ServiceDescriptorProto\022\014\n\004n"
+    "ame\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.google.proto"
+    "buf.MethodDescriptorProto\0220\n\007options\030\003 \001"
+    "(\0132\037.google.protobuf.ServiceOptions\"\177\n\025M"
+    "ethodDescriptorProto\022\014\n\004name\030\001 \001(\t\022\022\n\nin"
+    "put_type\030\002 \001(\t\022\023\n\013output_type\030\003 \001(\t\022/\n\007o"
+    "ptions\030\004 \001(\0132\036.google.protobuf.MethodOpt"
+    "ions\"\324\004\n\013FileOptions\022\024\n\014java_package\030\001 \001"
+    "(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023java"
+    "_multiple_files\030\n \001(\010:\005false\022,\n\035java_gen"
+    "erate_equals_and_hash\030\024 \001(\010:\005false\022%\n\026ja"
+    "va_string_check_utf8\030\033 \001(\010:\005false\022F\n\014opt"
+    "imize_for\030\t \001(\0162).google.protobuf.FileOp"
+    "tions.OptimizeMode:\005SPEED\022\022\n\ngo_package\030"
+    "\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005fals"
+    "e\022$\n\025java_generic_services\030\021 \001(\010:\005false\022"
+    "\"\n\023py_generic_services\030\022 \001(\010:\005false\022\031\n\nd"
+    "eprecated\030\027 \001(\010:\005false\022\'\n\037javanano_use_d"
+    "eprecated_package\030& \001(\010\022C\n\024uninterpreted"
+    "_option\030\347\007 \003(\0132$.google.protobuf.Uninter"
+    "pretedOption\":\n\014OptimizeMode\022\t\n\005SPEED\020\001\022"
+    "\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200"
+    "\200\200\002\"\323\001\n\016MessageOptions\022&\n\027message_set_wi"
+    "re_format\030\001 \001(\010:\005false\022.\n\037no_standard_de"
+    "scriptor_accessor\030\002 \001(\010:\005false\022\031\n\ndeprec"
+    "ated\030\003 \001(\010:\005false\022C\n\024uninterpreted_optio"
+    "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted"
+    "Option*\t\010\350\007\020\200\200\200\200\002\"\276\002\n\014FieldOptions\022:\n\005ct"
+    "ype\030\001 \001(\0162#.google.protobuf.FieldOptions"
+    ".CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030\005"
+    " \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\034"
+    "\n\024experimental_map_key\030\t \001(\t\022\023\n\004weak\030\n \001"
+    "(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\013"
+    "2$.google.protobuf.UninterpretedOption\"/"
+    "\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_"
+    "PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOptions\022\023\n\013al"
+    "low_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005fal"
+    "se\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goog"
+    "le.protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200"
+    "\200\002\"}\n\020EnumValueOptions\022\031\n\ndeprecated\030\001 \001"
+    "(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\013"
+    "2$.google.protobuf.UninterpretedOption*\t"
+    "\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprecate"
+    "d\030! \001(\010:\005false\022C\n\024uninterpreted_option\030\347"
+    "\007 \003(\0132$.google.protobuf.UninterpretedOpt"
+    "ion*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptions\022\031\n\ndepre"
+    "cated\030! \001(\010:\005false\022C\n\024uninterpreted_opti"
+    "on\030\347\007 \003(\0132$.google.protobuf.Uninterprete"
+    "dOption*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023UninterpretedOpti"
+    "on\022;\n\004name\030\002 \003(\0132-.google.protobuf.Unint"
+    "erpretedOption.NamePart\022\030\n\020identifier_va"
+    "lue\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n"
+    "\022negative_int_value\030\005 \001(\003\022\024\n\014double_valu"
+    "e\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017aggrega"
+    "te_value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname_part\030"
+    "\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\261\001\n\016SourceCo"
+    "deInfo\022:\n\010location\030\001 \003(\0132(.google.protob"
+    "uf.SourceCodeInfo.Location\032c\n\010Location\022\020"
+    "\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020le"
+    "ading_comments\030\003 \001(\t\022\031\n\021trailing_comment"
+    "s\030\004 \001(\tB)\n\023com.google.protobufB\020Descript"
+    "orProtosH\001", 4490);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+    "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
+  FileDescriptorSet::default_instance_ = new FileDescriptorSet();
+  FileDescriptorProto::default_instance_ = new FileDescriptorProto();
+  DescriptorProto::default_instance_ = new DescriptorProto();
+  DescriptorProto_ExtensionRange::default_instance_ = new DescriptorProto_ExtensionRange();
+  FieldDescriptorProto::default_instance_ = new FieldDescriptorProto();
+  OneofDescriptorProto::default_instance_ = new OneofDescriptorProto();
+  EnumDescriptorProto::default_instance_ = new EnumDescriptorProto();
+  EnumValueDescriptorProto::default_instance_ = new EnumValueDescriptorProto();
+  ServiceDescriptorProto::default_instance_ = new ServiceDescriptorProto();
+  MethodDescriptorProto::default_instance_ = new MethodDescriptorProto();
+  FileOptions::default_instance_ = new FileOptions();
+  MessageOptions::default_instance_ = new MessageOptions();
+  FieldOptions::default_instance_ = new FieldOptions();
+  EnumOptions::default_instance_ = new EnumOptions();
+  EnumValueOptions::default_instance_ = new EnumValueOptions();
+  ServiceOptions::default_instance_ = new ServiceOptions();
+  MethodOptions::default_instance_ = new MethodOptions();
+  UninterpretedOption::default_instance_ = new UninterpretedOption();
+  UninterpretedOption_NamePart::default_instance_ = new UninterpretedOption_NamePart();
+  SourceCodeInfo::default_instance_ = new SourceCodeInfo();
+  SourceCodeInfo_Location::default_instance_ = new SourceCodeInfo_Location();
+  FileDescriptorSet::default_instance_->InitAsDefaultInstance();
+  FileDescriptorProto::default_instance_->InitAsDefaultInstance();
+  DescriptorProto::default_instance_->InitAsDefaultInstance();
+  DescriptorProto_ExtensionRange::default_instance_->InitAsDefaultInstance();
+  FieldDescriptorProto::default_instance_->InitAsDefaultInstance();
+  OneofDescriptorProto::default_instance_->InitAsDefaultInstance();
+  EnumDescriptorProto::default_instance_->InitAsDefaultInstance();
+  EnumValueDescriptorProto::default_instance_->InitAsDefaultInstance();
+  ServiceDescriptorProto::default_instance_->InitAsDefaultInstance();
+  MethodDescriptorProto::default_instance_->InitAsDefaultInstance();
+  FileOptions::default_instance_->InitAsDefaultInstance();
+  MessageOptions::default_instance_->InitAsDefaultInstance();
+  FieldOptions::default_instance_->InitAsDefaultInstance();
+  EnumOptions::default_instance_->InitAsDefaultInstance();
+  EnumValueOptions::default_instance_->InitAsDefaultInstance();
+  ServiceOptions::default_instance_->InitAsDefaultInstance();
+  MethodOptions::default_instance_->InitAsDefaultInstance();
+  UninterpretedOption::default_instance_->InitAsDefaultInstance();
+  UninterpretedOption_NamePart::default_instance_->InitAsDefaultInstance();
+  SourceCodeInfo::default_instance_->InitAsDefaultInstance();
+  SourceCodeInfo_Location::default_instance_->InitAsDefaultInstance();
+  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto {
+  StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto() {
+    protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  }
+} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_;
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int FileDescriptorSet::kFileFieldNumber;
+#endif  // !_MSC_VER
+
+FileDescriptorSet::FileDescriptorSet()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorSet)
+}
+
+void FileDescriptorSet::InitAsDefaultInstance() {
+}
+
+FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorSet)
+}
+
+void FileDescriptorSet::SharedCtor() {
+  _cached_size_ = 0;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+FileDescriptorSet::~FileDescriptorSet() {
+  // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorSet)
+  SharedDtor();
+}
+
+void FileDescriptorSet::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void FileDescriptorSet::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return FileDescriptorSet_descriptor_;
+}
+
+const FileDescriptorSet& FileDescriptorSet::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+FileDescriptorSet* FileDescriptorSet::default_instance_ = NULL;
+
+FileDescriptorSet* FileDescriptorSet::New() const {
+  return new FileDescriptorSet;
+}
+
+void FileDescriptorSet::Clear() {
+  file_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool FileDescriptorSet::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.FileDescriptorSet)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated .google.protobuf.FileDescriptorProto file = 1;
+      case 1: {
+        if (tag == 10) {
+         parse_file:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_file()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(10)) goto parse_file;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.FileDescriptorSet)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.FileDescriptorSet)
+  return false;
+#undef DO_
+}
+
+void FileDescriptorSet::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.FileDescriptorSet)
+  // repeated .google.protobuf.FileDescriptorProto file = 1;
+  for (int i = 0; i < this->file_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, this->file(i), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorSet)
+}
+
+::google::protobuf::uint8* FileDescriptorSet::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorSet)
+  // repeated .google.protobuf.FileDescriptorProto file = 1;
+  for (int i = 0; i < this->file_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        1, this->file(i), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorSet)
+  return target;
+}
+
+int FileDescriptorSet::ByteSize() const {
+  int total_size = 0;
+
+  // repeated .google.protobuf.FileDescriptorProto file = 1;
+  total_size += 1 * this->file_size();
+  for (int i = 0; i < this->file_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->file(i));
+  }
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const FileDescriptorSet* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorSet*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  file_.MergeFrom(from.file_);
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void FileDescriptorSet::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool FileDescriptorSet::IsInitialized() const {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->file())) return false;
+  return true;
+}
+
+void FileDescriptorSet::Swap(FileDescriptorSet* other) {
+  if (other != this) {
+    file_.Swap(&other->file_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = FileDescriptorSet_descriptor_;
+  metadata.reflection = FileDescriptorSet_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int FileDescriptorProto::kNameFieldNumber;
+const int FileDescriptorProto::kPackageFieldNumber;
+const int FileDescriptorProto::kDependencyFieldNumber;
+const int FileDescriptorProto::kPublicDependencyFieldNumber;
+const int FileDescriptorProto::kWeakDependencyFieldNumber;
+const int FileDescriptorProto::kMessageTypeFieldNumber;
+const int FileDescriptorProto::kEnumTypeFieldNumber;
+const int FileDescriptorProto::kServiceFieldNumber;
+const int FileDescriptorProto::kExtensionFieldNumber;
+const int FileDescriptorProto::kOptionsFieldNumber;
+const int FileDescriptorProto::kSourceCodeInfoFieldNumber;
+#endif  // !_MSC_VER
+
+FileDescriptorProto::FileDescriptorProto()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorProto)
+}
+
+void FileDescriptorProto::InitAsDefaultInstance() {
+  options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance());
+  source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>(&::google::protobuf::SourceCodeInfo::default_instance());
+}
+
+FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileDescriptorProto)
+}
+
+void FileDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  options_ = NULL;
+  source_code_info_ = NULL;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+FileDescriptorProto::~FileDescriptorProto() {
+  // @@protoc_insertion_point(destructor:google.protobuf.FileDescriptorProto)
+  SharedDtor();
+}
+
+void FileDescriptorProto::SharedDtor() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete package_;
+  }
+  if (this != default_instance_) {
+    delete options_;
+    delete source_code_info_;
+  }
+}
+
+void FileDescriptorProto::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return FileDescriptorProto_descriptor_;
+}
+
+const FileDescriptorProto& FileDescriptorProto::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+FileDescriptorProto* FileDescriptorProto::default_instance_ = NULL;
+
+FileDescriptorProto* FileDescriptorProto::New() const {
+  return new FileDescriptorProto;
+}
+
+void FileDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & 3) {
+    if (has_name()) {
+      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        name_->clear();
+      }
+    }
+    if (has_package()) {
+      if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        package_->clear();
+      }
+    }
+  }
+  if (_has_bits_[8 / 32] & 1536) {
+    if (has_options()) {
+      if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
+    }
+    if (has_source_code_info()) {
+      if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
+    }
+  }
+  dependency_.Clear();
+  public_dependency_.Clear();
+  weak_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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.FileDescriptorProto)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_package;
+        break;
+      }
+
+      // optional string package = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_package:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_package()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->package().data(), this->package().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "package");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(26)) goto parse_dependency;
+        break;
+      }
+
+      // repeated string dependency = 3;
+      case 3: {
+        if (tag == 26) {
+         parse_dependency:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->add_dependency()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->dependency(this->dependency_size() - 1).data(),
+            this->dependency(this->dependency_size() - 1).length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "dependency");
+        } else {
+          goto handle_unusual;
+        }
+        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 (tag == 34) {
+         parse_message_type:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_message_type()));
+        } else {
+          goto handle_unusual;
+        }
+        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 (tag == 42) {
+         parse_enum_type:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_enum_type()));
+        } else {
+          goto handle_unusual;
+        }
+        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 (tag == 50) {
+         parse_service:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_service()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(50)) goto parse_service;
+        if (input->ExpectTag(58)) goto parse_extension;
+        break;
+      }
+
+      // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+      case 7: {
+        if (tag == 58) {
+         parse_extension:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_extension()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(58)) goto parse_extension;
+        if (input->ExpectTag(66)) goto parse_options;
+        break;
+      }
+
+      // optional .google.protobuf.FileOptions options = 8;
+      case 8: {
+        if (tag == 66) {
+         parse_options:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_options()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(74)) goto parse_source_code_info;
+        break;
+      }
+
+      // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+      case 9: {
+        if (tag == 74) {
+         parse_source_code_info:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_source_code_info()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(80)) goto parse_public_dependency;
+        break;
+      }
+
+      // repeated int32 public_dependency = 10;
+      case 10: {
+        if (tag == 80) {
+         parse_public_dependency:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 1, 80, input, this->mutable_public_dependency())));
+        } else if (tag == 82) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, this->mutable_public_dependency())));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(80)) goto parse_public_dependency;
+        if (input->ExpectTag(88)) goto parse_weak_dependency;
+        break;
+      }
+
+      // repeated int32 weak_dependency = 11;
+      case 11: {
+        if (tag == 88) {
+         parse_weak_dependency:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 1, 88, input, this->mutable_weak_dependency())));
+        } else if (tag == 90) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, this->mutable_weak_dependency())));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(88)) goto parse_weak_dependency;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.FileDescriptorProto)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.FileDescriptorProto)
+  return false;
+#undef DO_
+}
+
+void FileDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.FileDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // optional string package = 2;
+  if (has_package()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->package().data(), this->package().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "package");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->package(), output);
+  }
+
+  // repeated string dependency = 3;
+  for (int i = 0; i < this->dependency_size(); i++) {
+  ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+    this->dependency(i).data(), this->dependency(i).length(),
+    ::google::protobuf::internal::WireFormat::SERIALIZE,
+    "dependency");
+    ::google::protobuf::internal::WireFormatLite::WriteString(
+      3, this->dependency(i), output);
+  }
+
+  // repeated .google.protobuf.DescriptorProto message_type = 4;
+  for (int i = 0; i < this->message_type_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      4, this->message_type(i), output);
+  }
+
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+  for (int i = 0; i < this->enum_type_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      5, this->enum_type(i), output);
+  }
+
+  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+  for (int i = 0; i < this->service_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      6, this->service(i), output);
+  }
+
+  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+  for (int i = 0; i < this->extension_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      7, this->extension(i), output);
+  }
+
+  // optional .google.protobuf.FileOptions options = 8;
+  if (has_options()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      8, this->options(), output);
+  }
+
+  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+  if (has_source_code_info()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      9, this->source_code_info(), output);
+  }
+
+  // repeated int32 public_dependency = 10;
+  for (int i = 0; i < this->public_dependency_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(
+      10, this->public_dependency(i), output);
+  }
+
+  // repeated int32 weak_dependency = 11;
+  for (int i = 0; i < this->weak_dependency_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(
+      11, this->weak_dependency(i), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.FileDescriptorProto)
+}
+
+::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // optional string package = 2;
+  if (has_package()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->package().data(), this->package().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "package");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->package(), target);
+  }
+
+  // repeated string dependency = 3;
+  for (int i = 0; i < this->dependency_size(); i++) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->dependency(i).data(), this->dependency(i).length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "dependency");
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteStringToArray(3, this->dependency(i), target);
+  }
+
+  // repeated .google.protobuf.DescriptorProto message_type = 4;
+  for (int i = 0; i < this->message_type_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        4, this->message_type(i), target);
+  }
+
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+  for (int i = 0; i < this->enum_type_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        5, this->enum_type(i), target);
+  }
+
+  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+  for (int i = 0; i < this->service_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        6, this->service(i), target);
+  }
+
+  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+  for (int i = 0; i < this->extension_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        7, this->extension(i), target);
+  }
+
+  // optional .google.protobuf.FileOptions options = 8;
+  if (has_options()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        8, this->options(), target);
+  }
+
+  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+  if (has_source_code_info()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        9, this->source_code_info(), target);
+  }
+
+  // repeated int32 public_dependency = 10;
+  for (int i = 0; i < this->public_dependency_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteInt32ToArray(10, this->public_dependency(i), target);
+  }
+
+  // repeated int32 weak_dependency = 11;
+  for (int i = 0; i < this->weak_dependency_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteInt32ToArray(11, this->weak_dependency(i), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileDescriptorProto)
+  return target;
+}
+
+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::WireFormatLite::StringSize(
+          this->name());
+    }
+
+    // optional string package = 2;
+    if (has_package()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->package());
+    }
+
+  }
+  if (_has_bits_[9 / 32] & (0xffu << (9 % 32))) {
+    // optional .google.protobuf.FileOptions options = 8;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->options());
+    }
+
+    // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+    if (has_source_code_info()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->source_code_info());
+    }
+
+  }
+  // repeated string dependency = 3;
+  total_size += 1 * this->dependency_size();
+  for (int i = 0; i < this->dependency_size(); i++) {
+    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
+      this->dependency(i));
+  }
+
+  // repeated int32 public_dependency = 10;
+  {
+    int data_size = 0;
+    for (int i = 0; i < this->public_dependency_size(); i++) {
+      data_size += ::google::protobuf::internal::WireFormatLite::
+        Int32Size(this->public_dependency(i));
+    }
+    total_size += 1 * this->public_dependency_size() + data_size;
+  }
+
+  // repeated int32 weak_dependency = 11;
+  {
+    int data_size = 0;
+    for (int i = 0; i < this->weak_dependency_size(); i++) {
+      data_size += ::google::protobuf::internal::WireFormatLite::
+        Int32Size(this->weak_dependency(i));
+    }
+    total_size += 1 * this->weak_dependency_size() + data_size;
+  }
+
+  // repeated .google.protobuf.DescriptorProto message_type = 4;
+  total_size += 1 * this->message_type_size();
+  for (int i = 0; i < this->message_type_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->message_type(i));
+  }
+
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+  total_size += 1 * this->enum_type_size();
+  for (int i = 0; i < this->enum_type_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->enum_type(i));
+  }
+
+  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+  total_size += 1 * this->service_size();
+  for (int i = 0; i < this->service_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->service(i));
+  }
+
+  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+  total_size += 1 * this->extension_size();
+  for (int i = 0; i < this->extension_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->extension(i));
+  }
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  dependency_.MergeFrom(from.dependency_);
+  public_dependency_.MergeFrom(from.public_dependency_);
+  weak_dependency_.MergeFrom(from.weak_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_name()) {
+      set_name(from.name());
+    }
+    if (from.has_package()) {
+      set_package(from.package());
+    }
+  }
+  if (from._has_bits_[9 / 32] & (0xffu << (9 % 32))) {
+    if (from.has_options()) {
+      mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options());
+    }
+    if (from.has_source_code_info()) {
+      mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info());
+    }
+  }
+  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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->message_type())) return false;
+  if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false;
+  if (!::google::protobuf::internal::AllAreInitialized(this->service())) return false;
+  if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false;
+  if (has_options()) {
+    if (!this->options().IsInitialized()) return false;
+  }
+  return true;
+}
+
+void FileDescriptorProto::Swap(FileDescriptorProto* other) {
+  if (other != this) {
+    std::swap(name_, other->name_);
+    std::swap(package_, other->package_);
+    dependency_.Swap(&other->dependency_);
+    public_dependency_.Swap(&other->public_dependency_);
+    weak_dependency_.Swap(&other->weak_dependency_);
+    message_type_.Swap(&other->message_type_);
+    enum_type_.Swap(&other->enum_type_);
+    service_.Swap(&other->service_);
+    extension_.Swap(&other->extension_);
+    std::swap(options_, other->options_);
+    std::swap(source_code_info_, other->source_code_info_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = FileDescriptorProto_descriptor_;
+  metadata.reflection = FileDescriptorProto_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int DescriptorProto_ExtensionRange::kStartFieldNumber;
+const int DescriptorProto_ExtensionRange::kEndFieldNumber;
+#endif  // !_MSC_VER
+
+DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ExtensionRange)
+}
+
+void DescriptorProto_ExtensionRange::InitAsDefaultInstance() {
+}
+
+DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ExtensionRange)
+}
+
+void DescriptorProto_ExtensionRange::SharedCtor() {
+  _cached_size_ = 0;
+  start_ = 0;
+  end_ = 0;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
+  // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ExtensionRange)
+  SharedDtor();
+}
+
+void DescriptorProto_ExtensionRange::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void DescriptorProto_ExtensionRange::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return DescriptorProto_ExtensionRange_descriptor_;
+}
+
+const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::default_instance_ = NULL;
+
+DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New() const {
+  return new DescriptorProto_ExtensionRange;
+}
+
+void DescriptorProto_ExtensionRange::Clear() {
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
+  &reinterpret_cast<DescriptorProto_ExtensionRange*>(16)->f) - \
+   reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do {                              \
+    size_t f = OFFSET_OF_FIELD_(first);                    \
+    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
+    ::memset(&first, 0, n);                                \
+  } while (0)
+
+  ZR_(start_, end_);
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
+  ::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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto.ExtensionRange)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional int32 start = 1;
+      case 1: {
+        if (tag == 8) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &start_)));
+          set_has_start();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(16)) goto parse_end;
+        break;
+      }
+
+      // optional int32 end = 2;
+      case 2: {
+        if (tag == 16) {
+         parse_end:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &end_)));
+          set_has_end();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.DescriptorProto.ExtensionRange)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.DescriptorProto.ExtensionRange)
+  return false;
+#undef DO_
+}
+
+void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto.ExtensionRange)
+  // optional int32 start = 1;
+  if (has_start()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
+  }
+
+  // optional int32 end = 2;
+  if (has_end()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ExtensionRange)
+}
+
+::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ExtensionRange)
+  // optional int32 start = 1;
+  if (has_start()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
+  }
+
+  // optional int32 end = 2;
+  if (has_end()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ExtensionRange)
+  return target;
+}
+
+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::WireFormatLite::Int32Size(
+          this->start());
+    }
+
+    // optional int32 end = 2;
+    if (has_end()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->end());
+    }
+
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } 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_start()) {
+      set_start(from.start());
+    }
+    if (from.has_end()) {
+      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;
+}
+
+void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other) {
+  if (other != this) {
+    std::swap(start_, other->start_);
+    std::swap(end_, other->end_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = DescriptorProto_ExtensionRange_descriptor_;
+  metadata.reflection = DescriptorProto_ExtensionRange_reflection_;
+  return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int DescriptorProto::kNameFieldNumber;
+const int DescriptorProto::kFieldFieldNumber;
+const int DescriptorProto::kExtensionFieldNumber;
+const int DescriptorProto::kNestedTypeFieldNumber;
+const int DescriptorProto::kEnumTypeFieldNumber;
+const int DescriptorProto::kExtensionRangeFieldNumber;
+const int DescriptorProto::kOneofDeclFieldNumber;
+const int DescriptorProto::kOptionsFieldNumber;
+#endif  // !_MSC_VER
+
+DescriptorProto::DescriptorProto()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto)
+}
+
+void DescriptorProto::InitAsDefaultInstance() {
+  options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance());
+}
+
+DescriptorProto::DescriptorProto(const DescriptorProto& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto)
+}
+
+void DescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  options_ = NULL;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+DescriptorProto::~DescriptorProto() {
+  // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto)
+  SharedDtor();
+}
+
+void DescriptorProto::SharedDtor() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (this != default_instance_) {
+    delete options_;
+  }
+}
+
+void DescriptorProto::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* DescriptorProto::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return DescriptorProto_descriptor_;
+}
+
+const DescriptorProto& DescriptorProto::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+DescriptorProto* DescriptorProto::default_instance_ = NULL;
+
+DescriptorProto* DescriptorProto::New() const {
+  return new DescriptorProto;
+}
+
+void DescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & 129) {
+    if (has_name()) {
+      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        name_->clear();
+      }
+    }
+    if (has_options()) {
+      if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
+    }
+  }
+  field_.Clear();
+  extension_.Clear();
+  nested_type_.Clear();
+  enum_type_.Clear();
+  extension_range_.Clear();
+  oneof_decl_.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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_field;
+        break;
+      }
+
+      // repeated .google.protobuf.FieldDescriptorProto field = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_field:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_field()));
+        } else {
+          goto handle_unusual;
+        }
+        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 (tag == 26) {
+         parse_nested_type:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_nested_type()));
+        } else {
+          goto handle_unusual;
+        }
+        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 (tag == 34) {
+         parse_enum_type:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_enum_type()));
+        } else {
+          goto handle_unusual;
+        }
+        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 (tag == 42) {
+         parse_extension_range:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_extension_range()));
+        } else {
+          goto handle_unusual;
+        }
+        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 (tag == 50) {
+         parse_extension:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_extension()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(50)) goto parse_extension;
+        if (input->ExpectTag(58)) goto parse_options;
+        break;
+      }
+
+      // optional .google.protobuf.MessageOptions options = 7;
+      case 7: {
+        if (tag == 58) {
+         parse_options:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_options()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(66)) goto parse_oneof_decl;
+        break;
+      }
+
+      // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+      case 8: {
+        if (tag == 66) {
+         parse_oneof_decl:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_oneof_decl()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(66)) goto parse_oneof_decl;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.DescriptorProto)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.DescriptorProto)
+  return false;
+#undef DO_
+}
+
+void DescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // repeated .google.protobuf.FieldDescriptorProto field = 2;
+  for (int i = 0; i < this->field_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, this->field(i), output);
+  }
+
+  // repeated .google.protobuf.DescriptorProto nested_type = 3;
+  for (int i = 0; i < this->nested_type_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, this->nested_type(i), output);
+  }
+
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+  for (int i = 0; i < this->enum_type_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      4, this->enum_type(i), output);
+  }
+
+  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+  for (int i = 0; i < this->extension_range_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      5, this->extension_range(i), output);
+  }
+
+  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+  for (int i = 0; i < this->extension_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      6, this->extension(i), output);
+  }
+
+  // optional .google.protobuf.MessageOptions options = 7;
+  if (has_options()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      7, this->options(), output);
+  }
+
+  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+  for (int i = 0; i < this->oneof_decl_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      8, this->oneof_decl(i), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto)
+}
+
+::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // repeated .google.protobuf.FieldDescriptorProto field = 2;
+  for (int i = 0; i < this->field_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        2, this->field(i), target);
+  }
+
+  // repeated .google.protobuf.DescriptorProto nested_type = 3;
+  for (int i = 0; i < this->nested_type_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        3, this->nested_type(i), target);
+  }
+
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+  for (int i = 0; i < this->enum_type_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        4, this->enum_type(i), target);
+  }
+
+  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+  for (int i = 0; i < this->extension_range_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        5, this->extension_range(i), target);
+  }
+
+  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+  for (int i = 0; i < this->extension_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        6, this->extension(i), target);
+  }
+
+  // optional .google.protobuf.MessageOptions options = 7;
+  if (has_options()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        7, this->options(), target);
+  }
+
+  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+  for (int i = 0; i < this->oneof_decl_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        8, this->oneof_decl(i), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto)
+  return target;
+}
+
+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::WireFormatLite::StringSize(
+          this->name());
+    }
+
+    // optional .google.protobuf.MessageOptions options = 7;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->options());
+    }
+
+  }
+  // repeated .google.protobuf.FieldDescriptorProto field = 2;
+  total_size += 1 * this->field_size();
+  for (int i = 0; i < this->field_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->field(i));
+  }
+
+  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+  total_size += 1 * this->extension_size();
+  for (int i = 0; i < this->extension_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->extension(i));
+  }
+
+  // repeated .google.protobuf.DescriptorProto nested_type = 3;
+  total_size += 1 * this->nested_type_size();
+  for (int i = 0; i < this->nested_type_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->nested_type(i));
+  }
+
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+  total_size += 1 * this->enum_type_size();
+  for (int i = 0; i < this->enum_type_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->enum_type(i));
+  }
+
+  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+  total_size += 1 * this->extension_range_size();
+  for (int i = 0; i < this->extension_range_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->extension_range(i));
+  }
+
+  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+  total_size += 1 * this->oneof_decl_size();
+  for (int i = 0; i < this->oneof_decl_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->oneof_decl(i));
+  }
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } 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_);
+  oneof_decl_.MergeFrom(from.oneof_decl_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_name()) {
+      set_name(from.name());
+    }
+    if (from.has_options()) {
+      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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->field())) return false;
+  if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false;
+  if (!::google::protobuf::internal::AllAreInitialized(this->nested_type())) return false;
+  if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false;
+  if (has_options()) {
+    if (!this->options().IsInitialized()) return false;
+  }
+  return true;
+}
+
+void DescriptorProto::Swap(DescriptorProto* other) {
+  if (other != this) {
+    std::swap(name_, other->name_);
+    field_.Swap(&other->field_);
+    extension_.Swap(&other->extension_);
+    nested_type_.Swap(&other->nested_type_);
+    enum_type_.Swap(&other->enum_type_);
+    extension_range_.Swap(&other->extension_range_);
+    oneof_decl_.Swap(&other->oneof_decl_);
+    std::swap(options_, other->options_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata DescriptorProto::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = DescriptorProto_descriptor_;
+  metadata.reflection = DescriptorProto_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  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;
+const int FieldDescriptorProto::Type_ARRAYSIZE;
+#endif  // _MSC_VER
+const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  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;
+const int FieldDescriptorProto::Label_ARRAYSIZE;
+#endif  // _MSC_VER
+#ifndef _MSC_VER
+const int FieldDescriptorProto::kNameFieldNumber;
+const int FieldDescriptorProto::kNumberFieldNumber;
+const int FieldDescriptorProto::kLabelFieldNumber;
+const int FieldDescriptorProto::kTypeFieldNumber;
+const int FieldDescriptorProto::kTypeNameFieldNumber;
+const int FieldDescriptorProto::kExtendeeFieldNumber;
+const int FieldDescriptorProto::kDefaultValueFieldNumber;
+const int FieldDescriptorProto::kOneofIndexFieldNumber;
+const int FieldDescriptorProto::kOptionsFieldNumber;
+#endif  // !_MSC_VER
+
+FieldDescriptorProto::FieldDescriptorProto()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.FieldDescriptorProto)
+}
+
+void FieldDescriptorProto::InitAsDefaultInstance() {
+  options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance());
+}
+
+FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldDescriptorProto)
+}
+
+void FieldDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  number_ = 0;
+  label_ = 1;
+  type_ = 1;
+  type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  oneof_index_ = 0;
+  options_ = NULL;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+FieldDescriptorProto::~FieldDescriptorProto() {
+  // @@protoc_insertion_point(destructor:google.protobuf.FieldDescriptorProto)
+  SharedDtor();
+}
+
+void FieldDescriptorProto::SharedDtor() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete type_name_;
+  }
+  if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete extendee_;
+  }
+  if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete default_value_;
+  }
+  if (this != default_instance_) {
+    delete options_;
+  }
+}
+
+void FieldDescriptorProto::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return FieldDescriptorProto_descriptor_;
+}
+
+const FieldDescriptorProto& FieldDescriptorProto::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+FieldDescriptorProto* FieldDescriptorProto::default_instance_ = NULL;
+
+FieldDescriptorProto* FieldDescriptorProto::New() const {
+  return new FieldDescriptorProto;
+}
+
+void FieldDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & 255) {
+    if (has_name()) {
+      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        name_->clear();
+      }
+    }
+    number_ = 0;
+    label_ = 1;
+    type_ = 1;
+    if (has_type_name()) {
+      if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        type_name_->clear();
+      }
+    }
+    if (has_extendee()) {
+      if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        extendee_->clear();
+      }
+    }
+    if (has_default_value()) {
+      if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        default_value_->clear();
+      }
+    }
+    oneof_index_ = 0;
+  }
+  if (has_options()) {
+    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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.FieldDescriptorProto)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_extendee;
+        break;
+      }
+
+      // optional string extendee = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_extendee:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_extendee()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->extendee().data(), this->extendee().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "extendee");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(24)) goto parse_number;
+        break;
+      }
+
+      // optional int32 number = 3;
+      case 3: {
+        if (tag == 24) {
+         parse_number:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &number_)));
+          set_has_number();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(32)) goto parse_label;
+        break;
+      }
+
+      // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+      case 4: {
+        if (tag == 32) {
+         parse_label:
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) {
+            set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value));
+          } else {
+            mutable_unknown_fields()->AddVarint(4, value);
+          }
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(40)) goto parse_type;
+        break;
+      }
+
+      // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+      case 5: {
+        if (tag == 40) {
+         parse_type:
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) {
+            set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value));
+          } else {
+            mutable_unknown_fields()->AddVarint(5, value);
+          }
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(50)) goto parse_type_name;
+        break;
+      }
+
+      // optional string type_name = 6;
+      case 6: {
+        if (tag == 50) {
+         parse_type_name:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_type_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->type_name().data(), this->type_name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "type_name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(58)) goto parse_default_value;
+        break;
+      }
+
+      // optional string default_value = 7;
+      case 7: {
+        if (tag == 58) {
+         parse_default_value:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_default_value()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->default_value().data(), this->default_value().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "default_value");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(66)) goto parse_options;
+        break;
+      }
+
+      // optional .google.protobuf.FieldOptions options = 8;
+      case 8: {
+        if (tag == 66) {
+         parse_options:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_options()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(72)) goto parse_oneof_index;
+        break;
+      }
+
+      // optional int32 oneof_index = 9;
+      case 9: {
+        if (tag == 72) {
+         parse_oneof_index:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &oneof_index_)));
+          set_has_oneof_index();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.FieldDescriptorProto)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.FieldDescriptorProto)
+  return false;
+#undef DO_
+}
+
+void FieldDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.FieldDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // optional string extendee = 2;
+  if (has_extendee()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->extendee().data(), this->extendee().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "extendee");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->extendee(), output);
+  }
+
+  // optional int32 number = 3;
+  if (has_number()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output);
+  }
+
+  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+  if (has_label()) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      4, this->label(), output);
+  }
+
+  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+  if (has_type()) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      5, this->type(), output);
+  }
+
+  // optional string type_name = 6;
+  if (has_type_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->type_name().data(), this->type_name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "type_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      6, this->type_name(), output);
+  }
+
+  // optional string default_value = 7;
+  if (has_default_value()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->default_value().data(), this->default_value().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "default_value");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      7, this->default_value(), output);
+  }
+
+  // optional .google.protobuf.FieldOptions options = 8;
+  if (has_options()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      8, this->options(), output);
+  }
+
+  // optional int32 oneof_index = 9;
+  if (has_oneof_index()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->oneof_index(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.FieldDescriptorProto)
+}
+
+::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // optional string extendee = 2;
+  if (has_extendee()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->extendee().data(), this->extendee().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "extendee");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->extendee(), target);
+  }
+
+  // optional int32 number = 3;
+  if (has_number()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target);
+  }
+
+  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+  if (has_label()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      4, this->label(), target);
+  }
+
+  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+  if (has_type()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      5, this->type(), target);
+  }
+
+  // optional string type_name = 6;
+  if (has_type_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->type_name().data(), this->type_name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "type_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        6, this->type_name(), target);
+  }
+
+  // optional string default_value = 7;
+  if (has_default_value()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->default_value().data(), this->default_value().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "default_value");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        7, this->default_value(), target);
+  }
+
+  // optional .google.protobuf.FieldOptions options = 8;
+  if (has_options()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        8, this->options(), target);
+  }
+
+  // optional int32 oneof_index = 9;
+  if (has_oneof_index()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(9, this->oneof_index(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldDescriptorProto)
+  return target;
+}
+
+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::WireFormatLite::StringSize(
+          this->name());
+    }
+
+    // optional int32 number = 3;
+    if (has_number()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->number());
+    }
+
+    // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+    if (has_label()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::EnumSize(this->label());
+    }
+
+    // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+    if (has_type()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
+    }
+
+    // optional string type_name = 6;
+    if (has_type_name()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->type_name());
+    }
+
+    // optional string extendee = 2;
+    if (has_extendee()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->extendee());
+    }
+
+    // optional string default_value = 7;
+    if (has_default_value()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->default_value());
+    }
+
+    // optional int32 oneof_index = 9;
+    if (has_oneof_index()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->oneof_index());
+    }
+
+  }
+  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+    // optional .google.protobuf.FieldOptions options = 8;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->options());
+    }
+
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } 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_name()) {
+      set_name(from.name());
+    }
+    if (from.has_number()) {
+      set_number(from.number());
+    }
+    if (from.has_label()) {
+      set_label(from.label());
+    }
+    if (from.has_type()) {
+      set_type(from.type());
+    }
+    if (from.has_type_name()) {
+      set_type_name(from.type_name());
+    }
+    if (from.has_extendee()) {
+      set_extendee(from.extendee());
+    }
+    if (from.has_default_value()) {
+      set_default_value(from.default_value());
+    }
+    if (from.has_oneof_index()) {
+      set_oneof_index(from.oneof_index());
+    }
+  }
+  if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+    if (from.has_options()) {
+      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 {
+
+  if (has_options()) {
+    if (!this->options().IsInitialized()) return false;
+  }
+  return true;
+}
+
+void FieldDescriptorProto::Swap(FieldDescriptorProto* other) {
+  if (other != this) {
+    std::swap(name_, other->name_);
+    std::swap(number_, other->number_);
+    std::swap(label_, other->label_);
+    std::swap(type_, other->type_);
+    std::swap(type_name_, other->type_name_);
+    std::swap(extendee_, other->extendee_);
+    std::swap(default_value_, other->default_value_);
+    std::swap(oneof_index_, other->oneof_index_);
+    std::swap(options_, other->options_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = FieldDescriptorProto_descriptor_;
+  metadata.reflection = FieldDescriptorProto_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int OneofDescriptorProto::kNameFieldNumber;
+#endif  // !_MSC_VER
+
+OneofDescriptorProto::OneofDescriptorProto()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.OneofDescriptorProto)
+}
+
+void OneofDescriptorProto::InitAsDefaultInstance() {
+}
+
+OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.OneofDescriptorProto)
+}
+
+void OneofDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+OneofDescriptorProto::~OneofDescriptorProto() {
+  // @@protoc_insertion_point(destructor:google.protobuf.OneofDescriptorProto)
+  SharedDtor();
+}
+
+void OneofDescriptorProto::SharedDtor() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void OneofDescriptorProto::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* OneofDescriptorProto::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return OneofDescriptorProto_descriptor_;
+}
+
+const OneofDescriptorProto& OneofDescriptorProto::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+OneofDescriptorProto* OneofDescriptorProto::default_instance_ = NULL;
+
+OneofDescriptorProto* OneofDescriptorProto::New() const {
+  return new OneofDescriptorProto;
+}
+
+void OneofDescriptorProto::Clear() {
+  if (has_name()) {
+    if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+      name_->clear();
+    }
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool OneofDescriptorProto::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.OneofDescriptorProto)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.OneofDescriptorProto)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.OneofDescriptorProto)
+  return false;
+#undef DO_
+}
+
+void OneofDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.OneofDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.OneofDescriptorProto)
+}
+
+::google::protobuf::uint8* OneofDescriptorProto::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.OneofDescriptorProto)
+  return target;
+}
+
+int OneofDescriptorProto::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::WireFormatLite::StringSize(
+          this->name());
+    }
+
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void OneofDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const OneofDescriptorProto* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const OneofDescriptorProto*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_name()) {
+      set_name(from.name());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void OneofDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void OneofDescriptorProto::CopyFrom(const OneofDescriptorProto& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool OneofDescriptorProto::IsInitialized() const {
+
+  return true;
+}
+
+void OneofDescriptorProto::Swap(OneofDescriptorProto* other) {
+  if (other != this) {
+    std::swap(name_, other->name_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata OneofDescriptorProto::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = OneofDescriptorProto_descriptor_;
+  metadata.reflection = OneofDescriptorProto_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int EnumDescriptorProto::kNameFieldNumber;
+const int EnumDescriptorProto::kValueFieldNumber;
+const int EnumDescriptorProto::kOptionsFieldNumber;
+#endif  // !_MSC_VER
+
+EnumDescriptorProto::EnumDescriptorProto()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.EnumDescriptorProto)
+}
+
+void EnumDescriptorProto::InitAsDefaultInstance() {
+  options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance());
+}
+
+EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumDescriptorProto)
+}
+
+void EnumDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  options_ = NULL;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+EnumDescriptorProto::~EnumDescriptorProto() {
+  // @@protoc_insertion_point(destructor:google.protobuf.EnumDescriptorProto)
+  SharedDtor();
+}
+
+void EnumDescriptorProto::SharedDtor() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (this != default_instance_) {
+    delete options_;
+  }
+}
+
+void EnumDescriptorProto::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return EnumDescriptorProto_descriptor_;
+}
+
+const EnumDescriptorProto& EnumDescriptorProto::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+EnumDescriptorProto* EnumDescriptorProto::default_instance_ = NULL;
+
+EnumDescriptorProto* EnumDescriptorProto::New() const {
+  return new EnumDescriptorProto;
+}
+
+void EnumDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & 5) {
+    if (has_name()) {
+      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        name_->clear();
+      }
+    }
+    if (has_options()) {
+      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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.EnumDescriptorProto)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_value;
+        break;
+      }
+
+      // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_value:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_value()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_value;
+        if (input->ExpectTag(26)) goto parse_options;
+        break;
+      }
+
+      // optional .google.protobuf.EnumOptions options = 3;
+      case 3: {
+        if (tag == 26) {
+         parse_options:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_options()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.EnumDescriptorProto)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumDescriptorProto)
+  return false;
+#undef DO_
+}
+
+void EnumDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.EnumDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+  for (int i = 0; i < this->value_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, this->value(i), output);
+  }
+
+  // optional .google.protobuf.EnumOptions options = 3;
+  if (has_options()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, this->options(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumDescriptorProto)
+}
+
+::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+  for (int i = 0; i < this->value_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        2, this->value(i), target);
+  }
+
+  // optional .google.protobuf.EnumOptions options = 3;
+  if (has_options()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        3, this->options(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumDescriptorProto)
+  return target;
+}
+
+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::WireFormatLite::StringSize(
+          this->name());
+    }
+
+    // optional .google.protobuf.EnumOptions options = 3;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->options());
+    }
+
+  }
+  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+  total_size += 1 * this->value_size();
+  for (int i = 0; i < this->value_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->value(i));
+  }
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } 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_name()) {
+      set_name(from.name());
+    }
+    if (from.has_options()) {
+      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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->value())) return false;
+  if (has_options()) {
+    if (!this->options().IsInitialized()) return false;
+  }
+  return true;
+}
+
+void EnumDescriptorProto::Swap(EnumDescriptorProto* other) {
+  if (other != this) {
+    std::swap(name_, other->name_);
+    value_.Swap(&other->value_);
+    std::swap(options_, other->options_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = EnumDescriptorProto_descriptor_;
+  metadata.reflection = EnumDescriptorProto_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int EnumValueDescriptorProto::kNameFieldNumber;
+const int EnumValueDescriptorProto::kNumberFieldNumber;
+const int EnumValueDescriptorProto::kOptionsFieldNumber;
+#endif  // !_MSC_VER
+
+EnumValueDescriptorProto::EnumValueDescriptorProto()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.EnumValueDescriptorProto)
+}
+
+void EnumValueDescriptorProto::InitAsDefaultInstance() {
+  options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance());
+}
+
+EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueDescriptorProto)
+}
+
+void EnumValueDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  number_ = 0;
+  options_ = NULL;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+EnumValueDescriptorProto::~EnumValueDescriptorProto() {
+  // @@protoc_insertion_point(destructor:google.protobuf.EnumValueDescriptorProto)
+  SharedDtor();
+}
+
+void EnumValueDescriptorProto::SharedDtor() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (this != default_instance_) {
+    delete options_;
+  }
+}
+
+void EnumValueDescriptorProto::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return EnumValueDescriptorProto_descriptor_;
+}
+
+const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+EnumValueDescriptorProto* EnumValueDescriptorProto::default_instance_ = NULL;
+
+EnumValueDescriptorProto* EnumValueDescriptorProto::New() const {
+  return new EnumValueDescriptorProto;
+}
+
+void EnumValueDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & 7) {
+    if (has_name()) {
+      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        name_->clear();
+      }
+    }
+    number_ = 0;
+    if (has_options()) {
+      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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.EnumValueDescriptorProto)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(16)) goto parse_number;
+        break;
+      }
+
+      // optional int32 number = 2;
+      case 2: {
+        if (tag == 16) {
+         parse_number:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &number_)));
+          set_has_number();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(26)) goto parse_options;
+        break;
+      }
+
+      // optional .google.protobuf.EnumValueOptions options = 3;
+      case 3: {
+        if (tag == 26) {
+         parse_options:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_options()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.EnumValueDescriptorProto)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumValueDescriptorProto)
+  return false;
+#undef DO_
+}
+
+void EnumValueDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValueDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // optional int32 number = 2;
+  if (has_number()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output);
+  }
+
+  // optional .google.protobuf.EnumValueOptions options = 3;
+  if (has_options()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, this->options(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueDescriptorProto)
+}
+
+::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // optional int32 number = 2;
+  if (has_number()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target);
+  }
+
+  // optional .google.protobuf.EnumValueOptions options = 3;
+  if (has_options()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        3, this->options(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueDescriptorProto)
+  return target;
+}
+
+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::WireFormatLite::StringSize(
+          this->name());
+    }
+
+    // optional int32 number = 2;
+    if (has_number()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(
+          this->number());
+    }
+
+    // optional .google.protobuf.EnumValueOptions options = 3;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->options());
+    }
+
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } 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_name()) {
+      set_name(from.name());
+    }
+    if (from.has_number()) {
+      set_number(from.number());
+    }
+    if (from.has_options()) {
+      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 {
+
+  if (has_options()) {
+    if (!this->options().IsInitialized()) return false;
+  }
+  return true;
+}
+
+void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) {
+  if (other != this) {
+    std::swap(name_, other->name_);
+    std::swap(number_, other->number_);
+    std::swap(options_, other->options_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = EnumValueDescriptorProto_descriptor_;
+  metadata.reflection = EnumValueDescriptorProto_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int ServiceDescriptorProto::kNameFieldNumber;
+const int ServiceDescriptorProto::kMethodFieldNumber;
+const int ServiceDescriptorProto::kOptionsFieldNumber;
+#endif  // !_MSC_VER
+
+ServiceDescriptorProto::ServiceDescriptorProto()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.ServiceDescriptorProto)
+}
+
+void ServiceDescriptorProto::InitAsDefaultInstance() {
+  options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance());
+}
+
+ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceDescriptorProto)
+}
+
+void ServiceDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  options_ = NULL;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+ServiceDescriptorProto::~ServiceDescriptorProto() {
+  // @@protoc_insertion_point(destructor:google.protobuf.ServiceDescriptorProto)
+  SharedDtor();
+}
+
+void ServiceDescriptorProto::SharedDtor() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (this != default_instance_) {
+    delete options_;
+  }
+}
+
+void ServiceDescriptorProto::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ServiceDescriptorProto_descriptor_;
+}
+
+const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+ServiceDescriptorProto* ServiceDescriptorProto::default_instance_ = NULL;
+
+ServiceDescriptorProto* ServiceDescriptorProto::New() const {
+  return new ServiceDescriptorProto;
+}
+
+void ServiceDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & 5) {
+    if (has_name()) {
+      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        name_->clear();
+      }
+    }
+    if (has_options()) {
+      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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.ServiceDescriptorProto)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_method;
+        break;
+      }
+
+      // repeated .google.protobuf.MethodDescriptorProto method = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_method:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_method()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_method;
+        if (input->ExpectTag(26)) goto parse_options;
+        break;
+      }
+
+      // optional .google.protobuf.ServiceOptions options = 3;
+      case 3: {
+        if (tag == 26) {
+         parse_options:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_options()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.ServiceDescriptorProto)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.ServiceDescriptorProto)
+  return false;
+#undef DO_
+}
+
+void ServiceDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.ServiceDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // repeated .google.protobuf.MethodDescriptorProto method = 2;
+  for (int i = 0; i < this->method_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, this->method(i), output);
+  }
+
+  // optional .google.protobuf.ServiceOptions options = 3;
+  if (has_options()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, this->options(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceDescriptorProto)
+}
+
+::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // repeated .google.protobuf.MethodDescriptorProto method = 2;
+  for (int i = 0; i < this->method_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        2, this->method(i), target);
+  }
+
+  // optional .google.protobuf.ServiceOptions options = 3;
+  if (has_options()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        3, this->options(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceDescriptorProto)
+  return target;
+}
+
+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::WireFormatLite::StringSize(
+          this->name());
+    }
+
+    // optional .google.protobuf.ServiceOptions options = 3;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->options());
+    }
+
+  }
+  // repeated .google.protobuf.MethodDescriptorProto method = 2;
+  total_size += 1 * this->method_size();
+  for (int i = 0; i < this->method_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->method(i));
+  }
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } 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_name()) {
+      set_name(from.name());
+    }
+    if (from.has_options()) {
+      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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->method())) return false;
+  if (has_options()) {
+    if (!this->options().IsInitialized()) return false;
+  }
+  return true;
+}
+
+void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) {
+  if (other != this) {
+    std::swap(name_, other->name_);
+    method_.Swap(&other->method_);
+    std::swap(options_, other->options_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ServiceDescriptorProto_descriptor_;
+  metadata.reflection = ServiceDescriptorProto_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int MethodDescriptorProto::kNameFieldNumber;
+const int MethodDescriptorProto::kInputTypeFieldNumber;
+const int MethodDescriptorProto::kOutputTypeFieldNumber;
+const int MethodDescriptorProto::kOptionsFieldNumber;
+#endif  // !_MSC_VER
+
+MethodDescriptorProto::MethodDescriptorProto()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.MethodDescriptorProto)
+}
+
+void MethodDescriptorProto::InitAsDefaultInstance() {
+  options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance());
+}
+
+MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodDescriptorProto)
+}
+
+void MethodDescriptorProto::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  options_ = NULL;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+MethodDescriptorProto::~MethodDescriptorProto() {
+  // @@protoc_insertion_point(destructor:google.protobuf.MethodDescriptorProto)
+  SharedDtor();
+}
+
+void MethodDescriptorProto::SharedDtor() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete input_type_;
+  }
+  if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete output_type_;
+  }
+  if (this != default_instance_) {
+    delete options_;
+  }
+}
+
+void MethodDescriptorProto::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return MethodDescriptorProto_descriptor_;
+}
+
+const MethodDescriptorProto& MethodDescriptorProto::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+MethodDescriptorProto* MethodDescriptorProto::default_instance_ = NULL;
+
+MethodDescriptorProto* MethodDescriptorProto::New() const {
+  return new MethodDescriptorProto;
+}
+
+void MethodDescriptorProto::Clear() {
+  if (_has_bits_[0 / 32] & 15) {
+    if (has_name()) {
+      if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        name_->clear();
+      }
+    }
+    if (has_input_type()) {
+      if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        input_type_->clear();
+      }
+    }
+    if (has_output_type()) {
+      if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        output_type_->clear();
+      }
+    }
+    if (has_options()) {
+      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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.MethodDescriptorProto)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "name");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_input_type;
+        break;
+      }
+
+      // optional string input_type = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_input_type:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_input_type()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->input_type().data(), this->input_type().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "input_type");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(26)) goto parse_output_type;
+        break;
+      }
+
+      // optional string output_type = 3;
+      case 3: {
+        if (tag == 26) {
+         parse_output_type:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_output_type()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->output_type().data(), this->output_type().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "output_type");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(34)) goto parse_options;
+        break;
+      }
+
+      // optional .google.protobuf.MethodOptions options = 4;
+      case 4: {
+        if (tag == 34) {
+         parse_options:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_options()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.MethodDescriptorProto)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.MethodDescriptorProto)
+  return false;
+#undef DO_
+}
+
+void MethodDescriptorProto::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.MethodDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // optional string input_type = 2;
+  if (has_input_type()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->input_type().data(), this->input_type().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "input_type");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->input_type(), output);
+  }
+
+  // optional string output_type = 3;
+  if (has_output_type()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->output_type().data(), this->output_type().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "output_type");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->output_type(), output);
+  }
+
+  // optional .google.protobuf.MethodOptions options = 4;
+  if (has_options()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      4, this->options(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.MethodDescriptorProto)
+}
+
+::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodDescriptorProto)
+  // optional string name = 1;
+  if (has_name()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // optional string input_type = 2;
+  if (has_input_type()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->input_type().data(), this->input_type().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "input_type");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->input_type(), target);
+  }
+
+  // optional string output_type = 3;
+  if (has_output_type()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->output_type().data(), this->output_type().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "output_type");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->output_type(), target);
+  }
+
+  // optional .google.protobuf.MethodOptions options = 4;
+  if (has_options()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        4, this->options(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodDescriptorProto)
+  return target;
+}
+
+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::WireFormatLite::StringSize(
+          this->name());
+    }
+
+    // optional string input_type = 2;
+    if (has_input_type()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->input_type());
+    }
+
+    // optional string output_type = 3;
+    if (has_output_type()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->output_type());
+    }
+
+    // optional .google.protobuf.MethodOptions options = 4;
+    if (has_options()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->options());
+    }
+
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } 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_name()) {
+      set_name(from.name());
+    }
+    if (from.has_input_type()) {
+      set_input_type(from.input_type());
+    }
+    if (from.has_output_type()) {
+      set_output_type(from.output_type());
+    }
+    if (from.has_options()) {
+      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 {
+
+  if (has_options()) {
+    if (!this->options().IsInitialized()) return false;
+  }
+  return true;
+}
+
+void MethodDescriptorProto::Swap(MethodDescriptorProto* other) {
+  if (other != this) {
+    std::swap(name_, other->name_);
+    std::swap(input_type_, other->input_type_);
+    std::swap(output_type_, other->output_type_);
+    std::swap(options_, other->options_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = MethodDescriptorProto_descriptor_;
+  metadata.reflection = MethodDescriptorProto_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return FileOptions_OptimizeMode_descriptor_;
+}
+bool FileOptions_OptimizeMode_IsValid(int value) {
+  switch(value) {
+    case 1:
+    case 2:
+    case 3:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#ifndef _MSC_VER
+const FileOptions_OptimizeMode FileOptions::SPEED;
+const FileOptions_OptimizeMode FileOptions::CODE_SIZE;
+const FileOptions_OptimizeMode FileOptions::LITE_RUNTIME;
+const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
+const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
+const int FileOptions::OptimizeMode_ARRAYSIZE;
+#endif  // _MSC_VER
+#ifndef _MSC_VER
+const int FileOptions::kJavaPackageFieldNumber;
+const int FileOptions::kJavaOuterClassnameFieldNumber;
+const int FileOptions::kJavaMultipleFilesFieldNumber;
+const int FileOptions::kJavaGenerateEqualsAndHashFieldNumber;
+const int FileOptions::kJavaStringCheckUtf8FieldNumber;
+const int FileOptions::kOptimizeForFieldNumber;
+const int FileOptions::kGoPackageFieldNumber;
+const int FileOptions::kCcGenericServicesFieldNumber;
+const int FileOptions::kJavaGenericServicesFieldNumber;
+const int FileOptions::kPyGenericServicesFieldNumber;
+const int FileOptions::kDeprecatedFieldNumber;
+const int FileOptions::kJavananoUseDeprecatedPackageFieldNumber;
+const int FileOptions::kUninterpretedOptionFieldNumber;
+#endif  // !_MSC_VER
+
+FileOptions::FileOptions()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.FileOptions)
+}
+
+void FileOptions::InitAsDefaultInstance() {
+}
+
+FileOptions::FileOptions(const FileOptions& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.FileOptions)
+}
+
+void FileOptions::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  java_multiple_files_ = false;
+  java_generate_equals_and_hash_ = false;
+  java_string_check_utf8_ = false;
+  optimize_for_ = 1;
+  go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  cc_generic_services_ = false;
+  java_generic_services_ = false;
+  py_generic_services_ = false;
+  deprecated_ = false;
+  javanano_use_deprecated_package_ = false;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+FileOptions::~FileOptions() {
+  // @@protoc_insertion_point(destructor:google.protobuf.FileOptions)
+  SharedDtor();
+}
+
+void FileOptions::SharedDtor() {
+  if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete java_package_;
+  }
+  if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete java_outer_classname_;
+  }
+  if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete go_package_;
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void FileOptions::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FileOptions::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return FileOptions_descriptor_;
+}
+
+const FileOptions& FileOptions::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+FileOptions* FileOptions::default_instance_ = NULL;
+
+FileOptions* FileOptions::New() const {
+  return new FileOptions;
+}
+
+void FileOptions::Clear() {
+  _extensions_.Clear();
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
+  &reinterpret_cast<FileOptions*>(16)->f) - \
+   reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do {                              \
+    size_t f = OFFSET_OF_FIELD_(first);                    \
+    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
+    ::memset(&first, 0, n);                                \
+  } while (0)
+
+  if (_has_bits_[0 / 32] & 255) {
+    ZR_(java_multiple_files_, cc_generic_services_);
+    if (has_java_package()) {
+      if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        java_package_->clear();
+      }
+    }
+    if (has_java_outer_classname()) {
+      if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        java_outer_classname_->clear();
+      }
+    }
+    optimize_for_ = 1;
+    if (has_go_package()) {
+      if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        go_package_->clear();
+      }
+    }
+  }
+  ZR_(java_generic_services_, javanano_use_deprecated_package_);
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
+  uninterpreted_option_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool FileOptions::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.FileOptions)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string java_package = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_java_package()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->java_package().data(), this->java_package().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "java_package");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(66)) goto parse_java_outer_classname;
+        break;
+      }
+
+      // optional string java_outer_classname = 8;
+      case 8: {
+        if (tag == 66) {
+         parse_java_outer_classname:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_java_outer_classname()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->java_outer_classname().data(), this->java_outer_classname().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "java_outer_classname");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(72)) goto parse_optimize_for;
+        break;
+      }
+
+      // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+      case 9: {
+        if (tag == 72) {
+         parse_optimize_for:
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) {
+            set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value));
+          } else {
+            mutable_unknown_fields()->AddVarint(9, value);
+          }
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(80)) goto parse_java_multiple_files;
+        break;
+      }
+
+      // optional bool java_multiple_files = 10 [default = false];
+      case 10: {
+        if (tag == 80) {
+         parse_java_multiple_files:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &java_multiple_files_)));
+          set_has_java_multiple_files();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(90)) goto parse_go_package;
+        break;
+      }
+
+      // optional string go_package = 11;
+      case 11: {
+        if (tag == 90) {
+         parse_go_package:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_go_package()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->go_package().data(), this->go_package().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "go_package");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(128)) goto parse_cc_generic_services;
+        break;
+      }
+
+      // optional bool cc_generic_services = 16 [default = false];
+      case 16: {
+        if (tag == 128) {
+         parse_cc_generic_services:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &cc_generic_services_)));
+          set_has_cc_generic_services();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(136)) goto parse_java_generic_services;
+        break;
+      }
+
+      // optional bool java_generic_services = 17 [default = false];
+      case 17: {
+        if (tag == 136) {
+         parse_java_generic_services:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &java_generic_services_)));
+          set_has_java_generic_services();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(144)) goto parse_py_generic_services;
+        break;
+      }
+
+      // optional bool py_generic_services = 18 [default = false];
+      case 18: {
+        if (tag == 144) {
+         parse_py_generic_services:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &py_generic_services_)));
+          set_has_py_generic_services();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(160)) goto parse_java_generate_equals_and_hash;
+        break;
+      }
+
+      // optional bool java_generate_equals_and_hash = 20 [default = false];
+      case 20: {
+        if (tag == 160) {
+         parse_java_generate_equals_and_hash:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &java_generate_equals_and_hash_)));
+          set_has_java_generate_equals_and_hash();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(184)) goto parse_deprecated;
+        break;
+      }
+
+      // optional bool deprecated = 23 [default = false];
+      case 23: {
+        if (tag == 184) {
+         parse_deprecated:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &deprecated_)));
+          set_has_deprecated();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(216)) goto parse_java_string_check_utf8;
+        break;
+      }
+
+      // optional bool java_string_check_utf8 = 27 [default = false];
+      case 27: {
+        if (tag == 216) {
+         parse_java_string_check_utf8:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &java_string_check_utf8_)));
+          set_has_java_string_check_utf8();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(304)) goto parse_javanano_use_deprecated_package;
+        break;
+      }
+
+      // optional bool javanano_use_deprecated_package = 38;
+      case 38: {
+        if (tag == 304) {
+         parse_javanano_use_deprecated_package:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &javanano_use_deprecated_package_)));
+          set_has_javanano_use_deprecated_package();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        break;
+      }
+
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (tag == 7994) {
+         parse_uninterpreted_option:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_uninterpreted_option()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        if ((8000u <= tag)) {
+          DO_(_extensions_.ParseField(tag, input, default_instance_,
+                                      mutable_unknown_fields()));
+          continue;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.FileOptions)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.FileOptions)
+  return false;
+#undef DO_
+}
+
+void FileOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.FileOptions)
+  // optional string java_package = 1;
+  if (has_java_package()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->java_package().data(), this->java_package().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "java_package");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->java_package(), output);
+  }
+
+  // optional string java_outer_classname = 8;
+  if (has_java_outer_classname()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->java_outer_classname().data(), this->java_outer_classname().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "java_outer_classname");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      8, this->java_outer_classname(), output);
+  }
+
+  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+  if (has_optimize_for()) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      9, this->optimize_for(), output);
+  }
+
+  // optional bool java_multiple_files = 10 [default = false];
+  if (has_java_multiple_files()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output);
+  }
+
+  // optional string go_package = 11;
+  if (has_go_package()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->go_package().data(), this->go_package().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "go_package");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      11, this->go_package(), output);
+  }
+
+  // optional bool cc_generic_services = 16 [default = false];
+  if (has_cc_generic_services()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output);
+  }
+
+  // optional bool java_generic_services = 17 [default = false];
+  if (has_java_generic_services()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output);
+  }
+
+  // optional bool py_generic_services = 18 [default = false];
+  if (has_py_generic_services()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output);
+  }
+
+  // optional bool java_generate_equals_and_hash = 20 [default = false];
+  if (has_java_generate_equals_and_hash()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output);
+  }
+
+  // optional bool deprecated = 23 [default = false];
+  if (has_deprecated()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(23, this->deprecated(), output);
+  }
+
+  // optional bool java_string_check_utf8 = 27 [default = false];
+  if (has_java_string_check_utf8()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(27, this->java_string_check_utf8(), output);
+  }
+
+  // optional bool javanano_use_deprecated_package = 38;
+  if (has_javanano_use_deprecated_package()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(38, this->javanano_use_deprecated_package(), output);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      999, this->uninterpreted_option(i), output);
+  }
+
+  // Extension range [1000, 536870912)
+  _extensions_.SerializeWithCachedSizes(
+      1000, 536870912, output);
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.FileOptions)
+}
+
+::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileOptions)
+  // optional string java_package = 1;
+  if (has_java_package()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->java_package().data(), this->java_package().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "java_package");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->java_package(), target);
+  }
+
+  // optional string java_outer_classname = 8;
+  if (has_java_outer_classname()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->java_outer_classname().data(), this->java_outer_classname().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "java_outer_classname");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        8, this->java_outer_classname(), target);
+  }
+
+  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+  if (has_optimize_for()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      9, this->optimize_for(), target);
+  }
+
+  // optional bool java_multiple_files = 10 [default = false];
+  if (has_java_multiple_files()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target);
+  }
+
+  // optional string go_package = 11;
+  if (has_go_package()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->go_package().data(), this->go_package().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "go_package");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        11, this->go_package(), target);
+  }
+
+  // optional bool cc_generic_services = 16 [default = false];
+  if (has_cc_generic_services()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target);
+  }
+
+  // optional bool java_generic_services = 17 [default = false];
+  if (has_java_generic_services()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target);
+  }
+
+  // optional bool py_generic_services = 18 [default = false];
+  if (has_py_generic_services()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target);
+  }
+
+  // optional bool java_generate_equals_and_hash = 20 [default = false];
+  if (has_java_generate_equals_and_hash()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target);
+  }
+
+  // optional bool deprecated = 23 [default = false];
+  if (has_deprecated()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(23, this->deprecated(), target);
+  }
+
+  // optional bool java_string_check_utf8 = 27 [default = false];
+  if (has_java_string_check_utf8()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(27, this->java_string_check_utf8(), target);
+  }
+
+  // optional bool javanano_use_deprecated_package = 38;
+  if (has_javanano_use_deprecated_package()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(38, this->javanano_use_deprecated_package(), target);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        999, this->uninterpreted_option(i), target);
+  }
+
+  // Extension range [1000, 536870912)
+  target = _extensions_.SerializeWithCachedSizesToArray(
+      1000, 536870912, target);
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FileOptions)
+  return target;
+}
+
+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::WireFormatLite::StringSize(
+          this->java_package());
+    }
+
+    // optional string java_outer_classname = 8;
+    if (has_java_outer_classname()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->java_outer_classname());
+    }
+
+    // optional bool java_multiple_files = 10 [default = false];
+    if (has_java_multiple_files()) {
+      total_size += 1 + 1;
+    }
+
+    // optional bool java_generate_equals_and_hash = 20 [default = false];
+    if (has_java_generate_equals_and_hash()) {
+      total_size += 2 + 1;
+    }
+
+    // optional bool java_string_check_utf8 = 27 [default = false];
+    if (has_java_string_check_utf8()) {
+      total_size += 2 + 1;
+    }
+
+    // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+    if (has_optimize_for()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for());
+    }
+
+    // optional string go_package = 11;
+    if (has_go_package()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->go_package());
+    }
+
+    // optional bool cc_generic_services = 16 [default = false];
+    if (has_cc_generic_services()) {
+      total_size += 2 + 1;
+    }
+
+  }
+  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+    // optional bool java_generic_services = 17 [default = false];
+    if (has_java_generic_services()) {
+      total_size += 2 + 1;
+    }
+
+    // optional bool py_generic_services = 18 [default = false];
+    if (has_py_generic_services()) {
+      total_size += 2 + 1;
+    }
+
+    // optional bool deprecated = 23 [default = false];
+    if (has_deprecated()) {
+      total_size += 2 + 1;
+    }
+
+    // optional bool javanano_use_deprecated_package = 38;
+    if (has_javanano_use_deprecated_package()) {
+      total_size += 2 + 1;
+    }
+
+  }
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  total_size += 2 * this->uninterpreted_option_size();
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->uninterpreted_option(i));
+  }
+
+  total_size += _extensions_.ByteSize();
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FileOptions::MergeFrom(const FileOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_java_package()) {
+      set_java_package(from.java_package());
+    }
+    if (from.has_java_outer_classname()) {
+      set_java_outer_classname(from.java_outer_classname());
+    }
+    if (from.has_java_multiple_files()) {
+      set_java_multiple_files(from.java_multiple_files());
+    }
+    if (from.has_java_generate_equals_and_hash()) {
+      set_java_generate_equals_and_hash(from.java_generate_equals_and_hash());
+    }
+    if (from.has_java_string_check_utf8()) {
+      set_java_string_check_utf8(from.java_string_check_utf8());
+    }
+    if (from.has_optimize_for()) {
+      set_optimize_for(from.optimize_for());
+    }
+    if (from.has_go_package()) {
+      set_go_package(from.go_package());
+    }
+    if (from.has_cc_generic_services()) {
+      set_cc_generic_services(from.cc_generic_services());
+    }
+  }
+  if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
+    if (from.has_java_generic_services()) {
+      set_java_generic_services(from.java_generic_services());
+    }
+    if (from.has_py_generic_services()) {
+      set_py_generic_services(from.py_generic_services());
+    }
+    if (from.has_deprecated()) {
+      set_deprecated(from.deprecated());
+    }
+    if (from.has_javanano_use_deprecated_package()) {
+      set_javanano_use_deprecated_package(from.javanano_use_deprecated_package());
+    }
+  }
+  _extensions_.MergeFrom(from._extensions_);
+  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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
+  if (!_extensions_.IsInitialized()) return false;  return true;
+}
+
+void FileOptions::Swap(FileOptions* other) {
+  if (other != this) {
+    std::swap(java_package_, other->java_package_);
+    std::swap(java_outer_classname_, other->java_outer_classname_);
+    std::swap(java_multiple_files_, other->java_multiple_files_);
+    std::swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_);
+    std::swap(java_string_check_utf8_, other->java_string_check_utf8_);
+    std::swap(optimize_for_, other->optimize_for_);
+    std::swap(go_package_, other->go_package_);
+    std::swap(cc_generic_services_, other->cc_generic_services_);
+    std::swap(java_generic_services_, other->java_generic_services_);
+    std::swap(py_generic_services_, other->py_generic_services_);
+    std::swap(deprecated_, other->deprecated_);
+    std::swap(javanano_use_deprecated_package_, other->javanano_use_deprecated_package_);
+    uninterpreted_option_.Swap(&other->uninterpreted_option_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+    _extensions_.Swap(&other->_extensions_);
+  }
+}
+
+::google::protobuf::Metadata FileOptions::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = FileOptions_descriptor_;
+  metadata.reflection = FileOptions_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int MessageOptions::kMessageSetWireFormatFieldNumber;
+const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber;
+const int MessageOptions::kDeprecatedFieldNumber;
+const int MessageOptions::kUninterpretedOptionFieldNumber;
+#endif  // !_MSC_VER
+
+MessageOptions::MessageOptions()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.MessageOptions)
+}
+
+void MessageOptions::InitAsDefaultInstance() {
+}
+
+MessageOptions::MessageOptions(const MessageOptions& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.MessageOptions)
+}
+
+void MessageOptions::SharedCtor() {
+  _cached_size_ = 0;
+  message_set_wire_format_ = false;
+  no_standard_descriptor_accessor_ = false;
+  deprecated_ = false;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+MessageOptions::~MessageOptions() {
+  // @@protoc_insertion_point(destructor:google.protobuf.MessageOptions)
+  SharedDtor();
+}
+
+void MessageOptions::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void MessageOptions::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* MessageOptions::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return MessageOptions_descriptor_;
+}
+
+const MessageOptions& MessageOptions::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+MessageOptions* MessageOptions::default_instance_ = NULL;
+
+MessageOptions* MessageOptions::New() const {
+  return new MessageOptions;
+}
+
+void MessageOptions::Clear() {
+  _extensions_.Clear();
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
+  &reinterpret_cast<MessageOptions*>(16)->f) - \
+   reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do {                              \
+    size_t f = OFFSET_OF_FIELD_(first);                    \
+    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
+    ::memset(&first, 0, n);                                \
+  } while (0)
+
+  ZR_(message_set_wire_format_, deprecated_);
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
+  uninterpreted_option_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool MessageOptions::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.MessageOptions)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional bool message_set_wire_format = 1 [default = false];
+      case 1: {
+        if (tag == 8) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &message_set_wire_format_)));
+          set_has_message_set_wire_format();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(16)) goto parse_no_standard_descriptor_accessor;
+        break;
+      }
+
+      // optional bool no_standard_descriptor_accessor = 2 [default = false];
+      case 2: {
+        if (tag == 16) {
+         parse_no_standard_descriptor_accessor:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &no_standard_descriptor_accessor_)));
+          set_has_no_standard_descriptor_accessor();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(24)) goto parse_deprecated;
+        break;
+      }
+
+      // optional bool deprecated = 3 [default = false];
+      case 3: {
+        if (tag == 24) {
+         parse_deprecated:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &deprecated_)));
+          set_has_deprecated();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        break;
+      }
+
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (tag == 7994) {
+         parse_uninterpreted_option:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_uninterpreted_option()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        if ((8000u <= tag)) {
+          DO_(_extensions_.ParseField(tag, input, default_instance_,
+                                      mutable_unknown_fields()));
+          continue;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.MessageOptions)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.MessageOptions)
+  return false;
+#undef DO_
+}
+
+void MessageOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.MessageOptions)
+  // optional bool message_set_wire_format = 1 [default = false];
+  if (has_message_set_wire_format()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output);
+  }
+
+  // optional bool no_standard_descriptor_accessor = 2 [default = false];
+  if (has_no_standard_descriptor_accessor()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output);
+  }
+
+  // optional bool deprecated = 3 [default = false];
+  if (has_deprecated()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      999, this->uninterpreted_option(i), output);
+  }
+
+  // Extension range [1000, 536870912)
+  _extensions_.SerializeWithCachedSizes(
+      1000, 536870912, output);
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.MessageOptions)
+}
+
+::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MessageOptions)
+  // optional bool message_set_wire_format = 1 [default = false];
+  if (has_message_set_wire_format()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target);
+  }
+
+  // optional bool no_standard_descriptor_accessor = 2 [default = false];
+  if (has_no_standard_descriptor_accessor()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target);
+  }
+
+  // optional bool deprecated = 3 [default = false];
+  if (has_deprecated()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        999, this->uninterpreted_option(i), target);
+  }
+
+  // Extension range [1000, 536870912)
+  target = _extensions_.SerializeWithCachedSizesToArray(
+      1000, 536870912, target);
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MessageOptions)
+  return target;
+}
+
+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;
+    }
+
+    // optional bool no_standard_descriptor_accessor = 2 [default = false];
+    if (has_no_standard_descriptor_accessor()) {
+      total_size += 1 + 1;
+    }
+
+    // optional bool deprecated = 3 [default = false];
+    if (has_deprecated()) {
+      total_size += 1 + 1;
+    }
+
+  }
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  total_size += 2 * this->uninterpreted_option_size();
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->uninterpreted_option(i));
+  }
+
+  total_size += _extensions_.ByteSize();
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void MessageOptions::MergeFrom(const MessageOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_message_set_wire_format()) {
+      set_message_set_wire_format(from.message_set_wire_format());
+    }
+    if (from.has_no_standard_descriptor_accessor()) {
+      set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor());
+    }
+    if (from.has_deprecated()) {
+      set_deprecated(from.deprecated());
+    }
+  }
+  _extensions_.MergeFrom(from._extensions_);
+  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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
+  if (!_extensions_.IsInitialized()) return false;  return true;
+}
+
+void MessageOptions::Swap(MessageOptions* other) {
+  if (other != this) {
+    std::swap(message_set_wire_format_, other->message_set_wire_format_);
+    std::swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_);
+    std::swap(deprecated_, other->deprecated_);
+    uninterpreted_option_.Swap(&other->uninterpreted_option_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+    _extensions_.Swap(&other->_extensions_);
+  }
+}
+
+::google::protobuf::Metadata MessageOptions::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = MessageOptions_descriptor_;
+  metadata.reflection = MessageOptions_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return FieldOptions_CType_descriptor_;
+}
+bool FieldOptions_CType_IsValid(int value) {
+  switch(value) {
+    case 0:
+    case 1:
+    case 2:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#ifndef _MSC_VER
+const FieldOptions_CType FieldOptions::STRING;
+const FieldOptions_CType FieldOptions::CORD;
+const FieldOptions_CType FieldOptions::STRING_PIECE;
+const FieldOptions_CType FieldOptions::CType_MIN;
+const FieldOptions_CType FieldOptions::CType_MAX;
+const int FieldOptions::CType_ARRAYSIZE;
+#endif  // _MSC_VER
+#ifndef _MSC_VER
+const int FieldOptions::kCtypeFieldNumber;
+const int FieldOptions::kPackedFieldNumber;
+const int FieldOptions::kLazyFieldNumber;
+const int FieldOptions::kDeprecatedFieldNumber;
+const int FieldOptions::kExperimentalMapKeyFieldNumber;
+const int FieldOptions::kWeakFieldNumber;
+const int FieldOptions::kUninterpretedOptionFieldNumber;
+#endif  // !_MSC_VER
+
+FieldOptions::FieldOptions()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.FieldOptions)
+}
+
+void FieldOptions::InitAsDefaultInstance() {
+}
+
+FieldOptions::FieldOptions(const FieldOptions& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions)
+}
+
+void FieldOptions::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  ctype_ = 0;
+  packed_ = false;
+  lazy_ = false;
+  deprecated_ = false;
+  experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  weak_ = false;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+FieldOptions::~FieldOptions() {
+  // @@protoc_insertion_point(destructor:google.protobuf.FieldOptions)
+  SharedDtor();
+}
+
+void FieldOptions::SharedDtor() {
+  if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete experimental_map_key_;
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void FieldOptions::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FieldOptions::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return FieldOptions_descriptor_;
+}
+
+const FieldOptions& FieldOptions::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+FieldOptions* FieldOptions::default_instance_ = NULL;
+
+FieldOptions* FieldOptions::New() const {
+  return new FieldOptions;
+}
+
+void FieldOptions::Clear() {
+  _extensions_.Clear();
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
+  &reinterpret_cast<FieldOptions*>(16)->f) - \
+   reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do {                              \
+    size_t f = OFFSET_OF_FIELD_(first);                    \
+    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
+    ::memset(&first, 0, n);                                \
+  } while (0)
+
+  if (_has_bits_[0 / 32] & 63) {
+    ZR_(ctype_, weak_);
+    if (has_experimental_map_key()) {
+      if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        experimental_map_key_->clear();
+      }
+    }
+  }
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
+  uninterpreted_option_.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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.FieldOptions)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+      case 1: {
+        if (tag == 8) {
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          if (::google::protobuf::FieldOptions_CType_IsValid(value)) {
+            set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value));
+          } else {
+            mutable_unknown_fields()->AddVarint(1, value);
+          }
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(16)) goto parse_packed;
+        break;
+      }
+
+      // optional bool packed = 2;
+      case 2: {
+        if (tag == 16) {
+         parse_packed:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &packed_)));
+          set_has_packed();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(24)) goto parse_deprecated;
+        break;
+      }
+
+      // optional bool deprecated = 3 [default = false];
+      case 3: {
+        if (tag == 24) {
+         parse_deprecated:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &deprecated_)));
+          set_has_deprecated();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(40)) goto parse_lazy;
+        break;
+      }
+
+      // optional bool lazy = 5 [default = false];
+      case 5: {
+        if (tag == 40) {
+         parse_lazy:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &lazy_)));
+          set_has_lazy();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(74)) goto parse_experimental_map_key;
+        break;
+      }
+
+      // optional string experimental_map_key = 9;
+      case 9: {
+        if (tag == 74) {
+         parse_experimental_map_key:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_experimental_map_key()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->experimental_map_key().data(), this->experimental_map_key().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "experimental_map_key");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(80)) goto parse_weak;
+        break;
+      }
+
+      // optional bool weak = 10 [default = false];
+      case 10: {
+        if (tag == 80) {
+         parse_weak:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &weak_)));
+          set_has_weak();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        break;
+      }
+
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (tag == 7994) {
+         parse_uninterpreted_option:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_uninterpreted_option()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        if ((8000u <= tag)) {
+          DO_(_extensions_.ParseField(tag, input, default_instance_,
+                                      mutable_unknown_fields()));
+          continue;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.FieldOptions)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.FieldOptions)
+  return false;
+#undef DO_
+}
+
+void FieldOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.FieldOptions)
+  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+  if (has_ctype()) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->ctype(), output);
+  }
+
+  // optional bool packed = 2;
+  if (has_packed()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output);
+  }
+
+  // optional bool deprecated = 3 [default = false];
+  if (has_deprecated()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
+  }
+
+  // optional bool lazy = 5 [default = false];
+  if (has_lazy()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->lazy(), output);
+  }
+
+  // optional string experimental_map_key = 9;
+  if (has_experimental_map_key()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->experimental_map_key().data(), this->experimental_map_key().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "experimental_map_key");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      9, this->experimental_map_key(), output);
+  }
+
+  // optional bool weak = 10 [default = false];
+  if (has_weak()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->weak(), output);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      999, this->uninterpreted_option(i), output);
+  }
+
+  // Extension range [1000, 536870912)
+  _extensions_.SerializeWithCachedSizes(
+      1000, 536870912, output);
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.FieldOptions)
+}
+
+::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldOptions)
+  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+  if (has_ctype()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->ctype(), target);
+  }
+
+  // optional bool packed = 2;
+  if (has_packed()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target);
+  }
+
+  // optional bool deprecated = 3 [default = false];
+  if (has_deprecated()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
+  }
+
+  // optional bool lazy = 5 [default = false];
+  if (has_lazy()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->lazy(), target);
+  }
+
+  // optional string experimental_map_key = 9;
+  if (has_experimental_map_key()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->experimental_map_key().data(), this->experimental_map_key().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "experimental_map_key");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        9, this->experimental_map_key(), target);
+  }
+
+  // optional bool weak = 10 [default = false];
+  if (has_weak()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->weak(), target);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        999, this->uninterpreted_option(i), target);
+  }
+
+  // Extension range [1000, 536870912)
+  target = _extensions_.SerializeWithCachedSizesToArray(
+      1000, 536870912, target);
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldOptions)
+  return target;
+}
+
+int FieldOptions::ByteSize() const {
+  int total_size = 0;
+
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+    if (has_ctype()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype());
+    }
+
+    // optional bool packed = 2;
+    if (has_packed()) {
+      total_size += 1 + 1;
+    }
+
+    // optional bool lazy = 5 [default = false];
+    if (has_lazy()) {
+      total_size += 1 + 1;
+    }
+
+    // optional bool deprecated = 3 [default = false];
+    if (has_deprecated()) {
+      total_size += 1 + 1;
+    }
+
+    // optional string experimental_map_key = 9;
+    if (has_experimental_map_key()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->experimental_map_key());
+    }
+
+    // optional bool weak = 10 [default = false];
+    if (has_weak()) {
+      total_size += 1 + 1;
+    }
+
+  }
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  total_size += 2 * this->uninterpreted_option_size();
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->uninterpreted_option(i));
+  }
+
+  total_size += _extensions_.ByteSize();
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  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(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void FieldOptions::MergeFrom(const FieldOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_ctype()) {
+      set_ctype(from.ctype());
+    }
+    if (from.has_packed()) {
+      set_packed(from.packed());
+    }
+    if (from.has_lazy()) {
+      set_lazy(from.lazy());
+    }
+    if (from.has_deprecated()) {
+      set_deprecated(from.deprecated());
+    }
+    if (from.has_experimental_map_key()) {
+      set_experimental_map_key(from.experimental_map_key());
+    }
+    if (from.has_weak()) {
+      set_weak(from.weak());
+    }
+  }
+  _extensions_.MergeFrom(from._extensions_);
+  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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
+  if (!_extensions_.IsInitialized()) return false;  return true;
+}
+
+void FieldOptions::Swap(FieldOptions* other) {
+  if (other != this) {
+    std::swap(ctype_, other->ctype_);
+    std::swap(packed_, other->packed_);
+    std::swap(lazy_, other->lazy_);
+    std::swap(deprecated_, other->deprecated_);
+    std::swap(experimental_map_key_, other->experimental_map_key_);
+    std::swap(weak_, other->weak_);
+    uninterpreted_option_.Swap(&other->uninterpreted_option_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+    _extensions_.Swap(&other->_extensions_);
+  }
+}
+
+::google::protobuf::Metadata FieldOptions::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = FieldOptions_descriptor_;
+  metadata.reflection = FieldOptions_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int EnumOptions::kAllowAliasFieldNumber;
+const int EnumOptions::kDeprecatedFieldNumber;
+const int EnumOptions::kUninterpretedOptionFieldNumber;
+#endif  // !_MSC_VER
+
+EnumOptions::EnumOptions()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.EnumOptions)
+}
+
+void EnumOptions::InitAsDefaultInstance() {
+}
+
+EnumOptions::EnumOptions(const EnumOptions& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumOptions)
+}
+
+void EnumOptions::SharedCtor() {
+  _cached_size_ = 0;
+  allow_alias_ = false;
+  deprecated_ = false;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+EnumOptions::~EnumOptions() {
+  // @@protoc_insertion_point(destructor:google.protobuf.EnumOptions)
+  SharedDtor();
+}
+
+void EnumOptions::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void EnumOptions::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* EnumOptions::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return EnumOptions_descriptor_;
+}
+
+const EnumOptions& EnumOptions::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+EnumOptions* EnumOptions::default_instance_ = NULL;
+
+EnumOptions* EnumOptions::New() const {
+  return new EnumOptions;
+}
+
+void EnumOptions::Clear() {
+  _extensions_.Clear();
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
+  &reinterpret_cast<EnumOptions*>(16)->f) - \
+   reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do {                              \
+    size_t f = OFFSET_OF_FIELD_(first);                    \
+    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
+    ::memset(&first, 0, n);                                \
+  } while (0)
+
+  ZR_(allow_alias_, deprecated_);
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
+  uninterpreted_option_.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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.EnumOptions)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional bool allow_alias = 2;
+      case 2: {
+        if (tag == 16) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &allow_alias_)));
+          set_has_allow_alias();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(24)) goto parse_deprecated;
+        break;
+      }
+
+      // optional bool deprecated = 3 [default = false];
+      case 3: {
+        if (tag == 24) {
+         parse_deprecated:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &deprecated_)));
+          set_has_deprecated();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        break;
+      }
+
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (tag == 7994) {
+         parse_uninterpreted_option:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_uninterpreted_option()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        if ((8000u <= tag)) {
+          DO_(_extensions_.ParseField(tag, input, default_instance_,
+                                      mutable_unknown_fields()));
+          continue;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.EnumOptions)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumOptions)
+  return false;
+#undef DO_
+}
+
+void EnumOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.EnumOptions)
+  // optional bool allow_alias = 2;
+  if (has_allow_alias()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->allow_alias(), output);
+  }
+
+  // optional bool deprecated = 3 [default = false];
+  if (has_deprecated()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      999, this->uninterpreted_option(i), output);
+  }
+
+  // Extension range [1000, 536870912)
+  _extensions_.SerializeWithCachedSizes(
+      1000, 536870912, output);
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumOptions)
+}
+
+::google::protobuf::uint8* EnumOptions::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumOptions)
+  // optional bool allow_alias = 2;
+  if (has_allow_alias()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->allow_alias(), target);
+  }
+
+  // optional bool deprecated = 3 [default = false];
+  if (has_deprecated()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        999, this->uninterpreted_option(i), target);
+  }
+
+  // Extension range [1000, 536870912)
+  target = _extensions_.SerializeWithCachedSizesToArray(
+      1000, 536870912, target);
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumOptions)
+  return target;
+}
+
+int EnumOptions::ByteSize() const {
+  int total_size = 0;
+
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional bool allow_alias = 2;
+    if (has_allow_alias()) {
+      total_size += 1 + 1;
+    }
+
+    // optional bool deprecated = 3 [default = false];
+    if (has_deprecated()) {
+      total_size += 1 + 1;
+    }
+
+  }
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  total_size += 2 * this->uninterpreted_option_size();
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->uninterpreted_option(i));
+  }
+
+  total_size += _extensions_.ByteSize();
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const EnumOptions* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const EnumOptions*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void EnumOptions::MergeFrom(const EnumOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_allow_alias()) {
+      set_allow_alias(from.allow_alias());
+    }
+    if (from.has_deprecated()) {
+      set_deprecated(from.deprecated());
+    }
+  }
+  _extensions_.MergeFrom(from._extensions_);
+  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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
+  if (!_extensions_.IsInitialized()) return false;  return true;
+}
+
+void EnumOptions::Swap(EnumOptions* other) {
+  if (other != this) {
+    std::swap(allow_alias_, other->allow_alias_);
+    std::swap(deprecated_, other->deprecated_);
+    uninterpreted_option_.Swap(&other->uninterpreted_option_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+    _extensions_.Swap(&other->_extensions_);
+  }
+}
+
+::google::protobuf::Metadata EnumOptions::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = EnumOptions_descriptor_;
+  metadata.reflection = EnumOptions_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int EnumValueOptions::kDeprecatedFieldNumber;
+const int EnumValueOptions::kUninterpretedOptionFieldNumber;
+#endif  // !_MSC_VER
+
+EnumValueOptions::EnumValueOptions()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.EnumValueOptions)
+}
+
+void EnumValueOptions::InitAsDefaultInstance() {
+}
+
+EnumValueOptions::EnumValueOptions(const EnumValueOptions& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValueOptions)
+}
+
+void EnumValueOptions::SharedCtor() {
+  _cached_size_ = 0;
+  deprecated_ = false;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+EnumValueOptions::~EnumValueOptions() {
+  // @@protoc_insertion_point(destructor:google.protobuf.EnumValueOptions)
+  SharedDtor();
+}
+
+void EnumValueOptions::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void EnumValueOptions::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return EnumValueOptions_descriptor_;
+}
+
+const EnumValueOptions& EnumValueOptions::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+EnumValueOptions* EnumValueOptions::default_instance_ = NULL;
+
+EnumValueOptions* EnumValueOptions::New() const {
+  return new EnumValueOptions;
+}
+
+void EnumValueOptions::Clear() {
+  _extensions_.Clear();
+  deprecated_ = false;
+  uninterpreted_option_.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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.EnumValueOptions)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional bool deprecated = 1 [default = false];
+      case 1: {
+        if (tag == 8) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &deprecated_)));
+          set_has_deprecated();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        break;
+      }
+
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (tag == 7994) {
+         parse_uninterpreted_option:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_uninterpreted_option()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        if ((8000u <= tag)) {
+          DO_(_extensions_.ParseField(tag, input, default_instance_,
+                                      mutable_unknown_fields()));
+          continue;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.EnumValueOptions)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.EnumValueOptions)
+  return false;
+#undef DO_
+}
+
+void EnumValueOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValueOptions)
+  // optional bool deprecated = 1 [default = false];
+  if (has_deprecated()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->deprecated(), output);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      999, this->uninterpreted_option(i), output);
+  }
+
+  // Extension range [1000, 536870912)
+  _extensions_.SerializeWithCachedSizes(
+      1000, 536870912, output);
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValueOptions)
+}
+
+::google::protobuf::uint8* EnumValueOptions::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueOptions)
+  // optional bool deprecated = 1 [default = false];
+  if (has_deprecated()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->deprecated(), target);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        999, this->uninterpreted_option(i), target);
+  }
+
+  // Extension range [1000, 536870912)
+  target = _extensions_.SerializeWithCachedSizesToArray(
+      1000, 536870912, target);
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValueOptions)
+  return target;
+}
+
+int EnumValueOptions::ByteSize() const {
+  int total_size = 0;
+
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional bool deprecated = 1 [default = false];
+    if (has_deprecated()) {
+      total_size += 1 + 1;
+    }
+
+  }
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  total_size += 2 * this->uninterpreted_option_size();
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->uninterpreted_option(i));
+  }
+
+  total_size += _extensions_.ByteSize();
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const EnumValueOptions* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const EnumValueOptions*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_deprecated()) {
+      set_deprecated(from.deprecated());
+    }
+  }
+  _extensions_.MergeFrom(from._extensions_);
+  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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
+  if (!_extensions_.IsInitialized()) return false;  return true;
+}
+
+void EnumValueOptions::Swap(EnumValueOptions* other) {
+  if (other != this) {
+    std::swap(deprecated_, other->deprecated_);
+    uninterpreted_option_.Swap(&other->uninterpreted_option_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+    _extensions_.Swap(&other->_extensions_);
+  }
+}
+
+::google::protobuf::Metadata EnumValueOptions::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = EnumValueOptions_descriptor_;
+  metadata.reflection = EnumValueOptions_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int ServiceOptions::kDeprecatedFieldNumber;
+const int ServiceOptions::kUninterpretedOptionFieldNumber;
+#endif  // !_MSC_VER
+
+ServiceOptions::ServiceOptions()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.ServiceOptions)
+}
+
+void ServiceOptions::InitAsDefaultInstance() {
+}
+
+ServiceOptions::ServiceOptions(const ServiceOptions& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.ServiceOptions)
+}
+
+void ServiceOptions::SharedCtor() {
+  _cached_size_ = 0;
+  deprecated_ = false;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+ServiceOptions::~ServiceOptions() {
+  // @@protoc_insertion_point(destructor:google.protobuf.ServiceOptions)
+  SharedDtor();
+}
+
+void ServiceOptions::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void ServiceOptions::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ServiceOptions::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ServiceOptions_descriptor_;
+}
+
+const ServiceOptions& ServiceOptions::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+ServiceOptions* ServiceOptions::default_instance_ = NULL;
+
+ServiceOptions* ServiceOptions::New() const {
+  return new ServiceOptions;
+}
+
+void ServiceOptions::Clear() {
+  _extensions_.Clear();
+  deprecated_ = false;
+  uninterpreted_option_.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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.ServiceOptions)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional bool deprecated = 33 [default = false];
+      case 33: {
+        if (tag == 264) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &deprecated_)));
+          set_has_deprecated();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        break;
+      }
+
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (tag == 7994) {
+         parse_uninterpreted_option:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_uninterpreted_option()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        if ((8000u <= tag)) {
+          DO_(_extensions_.ParseField(tag, input, default_instance_,
+                                      mutable_unknown_fields()));
+          continue;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.ServiceOptions)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.ServiceOptions)
+  return false;
+#undef DO_
+}
+
+void ServiceOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.ServiceOptions)
+  // optional bool deprecated = 33 [default = false];
+  if (has_deprecated()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      999, this->uninterpreted_option(i), output);
+  }
+
+  // Extension range [1000, 536870912)
+  _extensions_.SerializeWithCachedSizes(
+      1000, 536870912, output);
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.ServiceOptions)
+}
+
+::google::protobuf::uint8* ServiceOptions::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceOptions)
+  // optional bool deprecated = 33 [default = false];
+  if (has_deprecated()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        999, this->uninterpreted_option(i), target);
+  }
+
+  // Extension range [1000, 536870912)
+  target = _extensions_.SerializeWithCachedSizesToArray(
+      1000, 536870912, target);
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ServiceOptions)
+  return target;
+}
+
+int ServiceOptions::ByteSize() const {
+  int total_size = 0;
+
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional bool deprecated = 33 [default = false];
+    if (has_deprecated()) {
+      total_size += 2 + 1;
+    }
+
+  }
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  total_size += 2 * this->uninterpreted_option_size();
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->uninterpreted_option(i));
+  }
+
+  total_size += _extensions_.ByteSize();
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const ServiceOptions* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const ServiceOptions*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void ServiceOptions::MergeFrom(const ServiceOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_deprecated()) {
+      set_deprecated(from.deprecated());
+    }
+  }
+  _extensions_.MergeFrom(from._extensions_);
+  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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
+  if (!_extensions_.IsInitialized()) return false;  return true;
+}
+
+void ServiceOptions::Swap(ServiceOptions* other) {
+  if (other != this) {
+    std::swap(deprecated_, other->deprecated_);
+    uninterpreted_option_.Swap(&other->uninterpreted_option_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+    _extensions_.Swap(&other->_extensions_);
+  }
+}
+
+::google::protobuf::Metadata ServiceOptions::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ServiceOptions_descriptor_;
+  metadata.reflection = ServiceOptions_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int MethodOptions::kDeprecatedFieldNumber;
+const int MethodOptions::kUninterpretedOptionFieldNumber;
+#endif  // !_MSC_VER
+
+MethodOptions::MethodOptions()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.MethodOptions)
+}
+
+void MethodOptions::InitAsDefaultInstance() {
+}
+
+MethodOptions::MethodOptions(const MethodOptions& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.MethodOptions)
+}
+
+void MethodOptions::SharedCtor() {
+  _cached_size_ = 0;
+  deprecated_ = false;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+MethodOptions::~MethodOptions() {
+  // @@protoc_insertion_point(destructor:google.protobuf.MethodOptions)
+  SharedDtor();
+}
+
+void MethodOptions::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void MethodOptions::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* MethodOptions::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return MethodOptions_descriptor_;
+}
+
+const MethodOptions& MethodOptions::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+MethodOptions* MethodOptions::default_instance_ = NULL;
+
+MethodOptions* MethodOptions::New() const {
+  return new MethodOptions;
+}
+
+void MethodOptions::Clear() {
+  _extensions_.Clear();
+  deprecated_ = false;
+  uninterpreted_option_.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)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.MethodOptions)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional bool deprecated = 33 [default = false];
+      case 33: {
+        if (tag == 264) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &deprecated_)));
+          set_has_deprecated();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        break;
+      }
+
+      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+      case 999: {
+        if (tag == 7994) {
+         parse_uninterpreted_option:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_uninterpreted_option()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        if ((8000u <= tag)) {
+          DO_(_extensions_.ParseField(tag, input, default_instance_,
+                                      mutable_unknown_fields()));
+          continue;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.MethodOptions)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.MethodOptions)
+  return false;
+#undef DO_
+}
+
+void MethodOptions::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.MethodOptions)
+  // optional bool deprecated = 33 [default = false];
+  if (has_deprecated()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      999, this->uninterpreted_option(i), output);
+  }
+
+  // Extension range [1000, 536870912)
+  _extensions_.SerializeWithCachedSizes(
+      1000, 536870912, output);
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.MethodOptions)
+}
+
+::google::protobuf::uint8* MethodOptions::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodOptions)
+  // optional bool deprecated = 33 [default = false];
+  if (has_deprecated()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target);
+  }
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        999, this->uninterpreted_option(i), target);
+  }
+
+  // Extension range [1000, 536870912)
+  target = _extensions_.SerializeWithCachedSizesToArray(
+      1000, 536870912, target);
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.MethodOptions)
+  return target;
+}
+
+int MethodOptions::ByteSize() const {
+  int total_size = 0;
+
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // optional bool deprecated = 33 [default = false];
+    if (has_deprecated()) {
+      total_size += 2 + 1;
+    }
+
+  }
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  total_size += 2 * this->uninterpreted_option_size();
+  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->uninterpreted_option(i));
+  }
+
+  total_size += _extensions_.ByteSize();
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const MethodOptions* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const MethodOptions*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void MethodOptions::MergeFrom(const MethodOptions& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_deprecated()) {
+      set_deprecated(from.deprecated());
+    }
+  }
+  _extensions_.MergeFrom(from._extensions_);
+  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 {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->uninterpreted_option())) return false;
+
+  if (!_extensions_.IsInitialized()) return false;  return true;
+}
+
+void MethodOptions::Swap(MethodOptions* other) {
+  if (other != this) {
+    std::swap(deprecated_, other->deprecated_);
+    uninterpreted_option_.Swap(&other->uninterpreted_option_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+    _extensions_.Swap(&other->_extensions_);
+  }
+}
+
+::google::protobuf::Metadata MethodOptions::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = MethodOptions_descriptor_;
+  metadata.reflection = MethodOptions_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int UninterpretedOption_NamePart::kNamePartFieldNumber;
+const int UninterpretedOption_NamePart::kIsExtensionFieldNumber;
+#endif  // !_MSC_VER
+
+UninterpretedOption_NamePart::UninterpretedOption_NamePart()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption.NamePart)
+}
+
+void UninterpretedOption_NamePart::InitAsDefaultInstance() {
+}
+
+UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption.NamePart)
+}
+
+void UninterpretedOption_NamePart::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  is_extension_ = false;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+UninterpretedOption_NamePart::~UninterpretedOption_NamePart() {
+  // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption.NamePart)
+  SharedDtor();
+}
+
+void UninterpretedOption_NamePart::SharedDtor() {
+  if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_part_;
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void UninterpretedOption_NamePart::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return UninterpretedOption_NamePart_descriptor_;
+}
+
+const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+UninterpretedOption_NamePart* UninterpretedOption_NamePart::default_instance_ = NULL;
+
+UninterpretedOption_NamePart* UninterpretedOption_NamePart::New() const {
+  return new UninterpretedOption_NamePart;
+}
+
+void UninterpretedOption_NamePart::Clear() {
+  if (_has_bits_[0 / 32] & 3) {
+    if (has_name_part()) {
+      if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        name_part_->clear();
+      }
+    }
+    is_extension_ = false;
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.UninterpretedOption.NamePart)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // required string name_part = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name_part()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->name_part().data(), this->name_part().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "name_part");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(16)) goto parse_is_extension;
+        break;
+      }
+
+      // required bool is_extension = 2;
+      case 2: {
+        if (tag == 16) {
+         parse_is_extension:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &is_extension_)));
+          set_has_is_extension();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.UninterpretedOption.NamePart)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.UninterpretedOption.NamePart)
+  return false;
+#undef DO_
+}
+
+void UninterpretedOption_NamePart::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.UninterpretedOption.NamePart)
+  // required string name_part = 1;
+  if (has_name_part()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name_part().data(), this->name_part().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name_part");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name_part(), output);
+  }
+
+  // required bool is_extension = 2;
+  if (has_is_extension()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption.NamePart)
+}
+
+::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption.NamePart)
+  // required string name_part = 1;
+  if (has_name_part()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->name_part().data(), this->name_part().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "name_part");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name_part(), target);
+  }
+
+  // required bool is_extension = 2;
+  if (has_is_extension()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption.NamePart)
+  return target;
+}
+
+int UninterpretedOption_NamePart::ByteSize() const {
+  int total_size = 0;
+
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // required string name_part = 1;
+    if (has_name_part()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->name_part());
+    }
+
+    // required bool is_extension = 2;
+    if (has_is_extension()) {
+      total_size += 1 + 1;
+    }
+
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const UninterpretedOption_NamePart* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const UninterpretedOption_NamePart*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_name_part()) {
+      set_name_part(from.name_part());
+    }
+    if (from.has_is_extension()) {
+      set_is_extension(from.is_extension());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void UninterpretedOption_NamePart::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool UninterpretedOption_NamePart::IsInitialized() const {
+  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;
+
+  return true;
+}
+
+void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) {
+  if (other != this) {
+    std::swap(name_part_, other->name_part_);
+    std::swap(is_extension_, other->is_extension_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = UninterpretedOption_NamePart_descriptor_;
+  metadata.reflection = UninterpretedOption_NamePart_reflection_;
+  return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int UninterpretedOption::kNameFieldNumber;
+const int UninterpretedOption::kIdentifierValueFieldNumber;
+const int UninterpretedOption::kPositiveIntValueFieldNumber;
+const int UninterpretedOption::kNegativeIntValueFieldNumber;
+const int UninterpretedOption::kDoubleValueFieldNumber;
+const int UninterpretedOption::kStringValueFieldNumber;
+const int UninterpretedOption::kAggregateValueFieldNumber;
+#endif  // !_MSC_VER
+
+UninterpretedOption::UninterpretedOption()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption)
+}
+
+void UninterpretedOption::InitAsDefaultInstance() {
+}
+
+UninterpretedOption::UninterpretedOption(const UninterpretedOption& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.UninterpretedOption)
+}
+
+void UninterpretedOption::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  positive_int_value_ = GOOGLE_ULONGLONG(0);
+  negative_int_value_ = GOOGLE_LONGLONG(0);
+  double_value_ = 0;
+  string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+UninterpretedOption::~UninterpretedOption() {
+  // @@protoc_insertion_point(destructor:google.protobuf.UninterpretedOption)
+  SharedDtor();
+}
+
+void UninterpretedOption::SharedDtor() {
+  if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete identifier_value_;
+  }
+  if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete string_value_;
+  }
+  if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete aggregate_value_;
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void UninterpretedOption::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return UninterpretedOption_descriptor_;
+}
+
+const UninterpretedOption& UninterpretedOption::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+UninterpretedOption* UninterpretedOption::default_instance_ = NULL;
+
+UninterpretedOption* UninterpretedOption::New() const {
+  return new UninterpretedOption;
+}
+
+void UninterpretedOption::Clear() {
+#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>(      \
+  &reinterpret_cast<UninterpretedOption*>(16)->f) - \
+   reinterpret_cast<char*>(16))
+
+#define ZR_(first, last) do {                              \
+    size_t f = OFFSET_OF_FIELD_(first);                    \
+    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last);  \
+    ::memset(&first, 0, n);                                \
+  } while (0)
+
+  if (_has_bits_[0 / 32] & 126) {
+    ZR_(positive_int_value_, double_value_);
+    if (has_identifier_value()) {
+      if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        identifier_value_->clear();
+      }
+    }
+    if (has_string_value()) {
+      if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        string_value_->clear();
+      }
+    }
+    if (has_aggregate_value()) {
+      if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        aggregate_value_->clear();
+      }
+    }
+  }
+
+#undef OFFSET_OF_FIELD_
+#undef ZR_
+
+  name_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool UninterpretedOption::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.UninterpretedOption)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_name:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_name()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_name;
+        if (input->ExpectTag(26)) goto parse_identifier_value;
+        break;
+      }
+
+      // optional string identifier_value = 3;
+      case 3: {
+        if (tag == 26) {
+         parse_identifier_value:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_identifier_value()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->identifier_value().data(), this->identifier_value().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "identifier_value");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(32)) goto parse_positive_int_value;
+        break;
+      }
+
+      // optional uint64 positive_int_value = 4;
+      case 4: {
+        if (tag == 32) {
+         parse_positive_int_value:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
+                 input, &positive_int_value_)));
+          set_has_positive_int_value();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(40)) goto parse_negative_int_value;
+        break;
+      }
+
+      // optional int64 negative_int_value = 5;
+      case 5: {
+        if (tag == 40) {
+         parse_negative_int_value:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
+                 input, &negative_int_value_)));
+          set_has_negative_int_value();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(49)) goto parse_double_value;
+        break;
+      }
+
+      // optional double double_value = 6;
+      case 6: {
+        if (tag == 49) {
+         parse_double_value:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
+                 input, &double_value_)));
+          set_has_double_value();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(58)) goto parse_string_value;
+        break;
+      }
+
+      // optional bytes string_value = 7;
+      case 7: {
+        if (tag == 58) {
+         parse_string_value:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
+                input, this->mutable_string_value()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(66)) goto parse_aggregate_value;
+        break;
+      }
+
+      // optional string aggregate_value = 8;
+      case 8: {
+        if (tag == 66) {
+         parse_aggregate_value:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_aggregate_value()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->aggregate_value().data(), this->aggregate_value().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "aggregate_value");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.UninterpretedOption)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.UninterpretedOption)
+  return false;
+#undef DO_
+}
+
+void UninterpretedOption::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.UninterpretedOption)
+  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+  for (int i = 0; i < this->name_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, this->name(i), output);
+  }
+
+  // optional string identifier_value = 3;
+  if (has_identifier_value()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->identifier_value().data(), this->identifier_value().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "identifier_value");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->identifier_value(), output);
+  }
+
+  // optional uint64 positive_int_value = 4;
+  if (has_positive_int_value()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output);
+  }
+
+  // optional int64 negative_int_value = 5;
+  if (has_negative_int_value()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output);
+  }
+
+  // optional double double_value = 6;
+  if (has_double_value()) {
+    ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output);
+  }
+
+  // optional bytes string_value = 7;
+  if (has_string_value()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(
+      7, this->string_value(), output);
+  }
+
+  // optional string aggregate_value = 8;
+  if (has_aggregate_value()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->aggregate_value().data(), this->aggregate_value().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "aggregate_value");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      8, this->aggregate_value(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.UninterpretedOption)
+}
+
+::google::protobuf::uint8* UninterpretedOption::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption)
+  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+  for (int i = 0; i < this->name_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        2, this->name(i), target);
+  }
+
+  // optional string identifier_value = 3;
+  if (has_identifier_value()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->identifier_value().data(), this->identifier_value().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "identifier_value");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->identifier_value(), target);
+  }
+
+  // optional uint64 positive_int_value = 4;
+  if (has_positive_int_value()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target);
+  }
+
+  // optional int64 negative_int_value = 5;
+  if (has_negative_int_value()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target);
+  }
+
+  // optional double double_value = 6;
+  if (has_double_value()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target);
+  }
+
+  // optional bytes string_value = 7;
+  if (has_string_value()) {
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
+        7, this->string_value(), target);
+  }
+
+  // optional string aggregate_value = 8;
+  if (has_aggregate_value()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->aggregate_value().data(), this->aggregate_value().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "aggregate_value");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        8, this->aggregate_value(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UninterpretedOption)
+  return target;
+}
+
+int UninterpretedOption::ByteSize() const {
+  int total_size = 0;
+
+  if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+    // optional string identifier_value = 3;
+    if (has_identifier_value()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->identifier_value());
+    }
+
+    // optional uint64 positive_int_value = 4;
+    if (has_positive_int_value()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt64Size(
+          this->positive_int_value());
+    }
+
+    // optional int64 negative_int_value = 5;
+    if (has_negative_int_value()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int64Size(
+          this->negative_int_value());
+    }
+
+    // optional double double_value = 6;
+    if (has_double_value()) {
+      total_size += 1 + 8;
+    }
+
+    // optional bytes string_value = 7;
+    if (has_string_value()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::BytesSize(
+          this->string_value());
+    }
+
+    // optional string aggregate_value = 8;
+    if (has_aggregate_value()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->aggregate_value());
+    }
+
+  }
+  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+  total_size += 1 * this->name_size();
+  for (int i = 0; i < this->name_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->name(i));
+  }
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const UninterpretedOption* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const UninterpretedOption*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  name_.MergeFrom(from.name_);
+  if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
+    if (from.has_identifier_value()) {
+      set_identifier_value(from.identifier_value());
+    }
+    if (from.has_positive_int_value()) {
+      set_positive_int_value(from.positive_int_value());
+    }
+    if (from.has_negative_int_value()) {
+      set_negative_int_value(from.negative_int_value());
+    }
+    if (from.has_double_value()) {
+      set_double_value(from.double_value());
+    }
+    if (from.has_string_value()) {
+      set_string_value(from.string_value());
+    }
+    if (from.has_aggregate_value()) {
+      set_aggregate_value(from.aggregate_value());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void UninterpretedOption::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void UninterpretedOption::CopyFrom(const UninterpretedOption& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool UninterpretedOption::IsInitialized() const {
+
+  if (!::google::protobuf::internal::AllAreInitialized(this->name())) return false;
+  return true;
+}
+
+void UninterpretedOption::Swap(UninterpretedOption* other) {
+  if (other != this) {
+    name_.Swap(&other->name_);
+    std::swap(identifier_value_, other->identifier_value_);
+    std::swap(positive_int_value_, other->positive_int_value_);
+    std::swap(negative_int_value_, other->negative_int_value_);
+    std::swap(double_value_, other->double_value_);
+    std::swap(string_value_, other->string_value_);
+    std::swap(aggregate_value_, other->aggregate_value_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata UninterpretedOption::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = UninterpretedOption_descriptor_;
+  metadata.reflection = UninterpretedOption_reflection_;
+  return metadata;
+}
+
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int SourceCodeInfo_Location::kPathFieldNumber;
+const int SourceCodeInfo_Location::kSpanFieldNumber;
+const int SourceCodeInfo_Location::kLeadingCommentsFieldNumber;
+const int SourceCodeInfo_Location::kTrailingCommentsFieldNumber;
+#endif  // !_MSC_VER
+
+SourceCodeInfo_Location::SourceCodeInfo_Location()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo.Location)
+}
+
+void SourceCodeInfo_Location::InitAsDefaultInstance() {
+}
+
+SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location)
+}
+
+void SourceCodeInfo_Location::SharedCtor() {
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SourceCodeInfo_Location::~SourceCodeInfo_Location() {
+  // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo.Location)
+  SharedDtor();
+}
+
+void SourceCodeInfo_Location::SharedDtor() {
+  if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete leading_comments_;
+  }
+  if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete trailing_comments_;
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void SourceCodeInfo_Location::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return SourceCodeInfo_Location_descriptor_;
+}
+
+const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+SourceCodeInfo_Location* SourceCodeInfo_Location::default_instance_ = NULL;
+
+SourceCodeInfo_Location* SourceCodeInfo_Location::New() const {
+  return new SourceCodeInfo_Location;
+}
+
+void SourceCodeInfo_Location::Clear() {
+  if (_has_bits_[0 / 32] & 12) {
+    if (has_leading_comments()) {
+      if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        leading_comments_->clear();
+      }
+    }
+    if (has_trailing_comments()) {
+      if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+        trailing_comments_->clear();
+      }
+    }
+  }
+  path_.Clear();
+  span_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool SourceCodeInfo_Location::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.SourceCodeInfo.Location)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated int32 path = 1 [packed = true];
+      case 1: {
+        if (tag == 10) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, this->mutable_path())));
+        } else if (tag == 8) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 1, 10, input, this->mutable_path())));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_span;
+        break;
+      }
+
+      // repeated int32 span = 2 [packed = true];
+      case 2: {
+        if (tag == 18) {
+         parse_span:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, this->mutable_span())));
+        } else if (tag == 16) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 1, 18, input, this->mutable_span())));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(26)) goto parse_leading_comments;
+        break;
+      }
+
+      // optional string leading_comments = 3;
+      case 3: {
+        if (tag == 26) {
+         parse_leading_comments:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_leading_comments()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->leading_comments().data(), this->leading_comments().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "leading_comments");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(34)) goto parse_trailing_comments;
+        break;
+      }
+
+      // optional string trailing_comments = 4;
+      case 4: {
+        if (tag == 34) {
+         parse_trailing_comments:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_trailing_comments()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->trailing_comments().data(), this->trailing_comments().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "trailing_comments");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.SourceCodeInfo.Location)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.SourceCodeInfo.Location)
+  return false;
+#undef DO_
+}
+
+void SourceCodeInfo_Location::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.SourceCodeInfo.Location)
+  // repeated int32 path = 1 [packed = true];
+  if (this->path_size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+    output->WriteVarint32(_path_cached_byte_size_);
+  }
+  for (int i = 0; i < this->path_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
+      this->path(i), output);
+  }
+
+  // repeated int32 span = 2 [packed = true];
+  if (this->span_size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+    output->WriteVarint32(_span_cached_byte_size_);
+  }
+  for (int i = 0; i < this->span_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
+      this->span(i), output);
+  }
+
+  // optional string leading_comments = 3;
+  if (has_leading_comments()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->leading_comments().data(), this->leading_comments().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "leading_comments");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->leading_comments(), output);
+  }
+
+  // optional string trailing_comments = 4;
+  if (has_trailing_comments()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->trailing_comments().data(), this->trailing_comments().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "trailing_comments");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->trailing_comments(), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo.Location)
+}
+
+::google::protobuf::uint8* SourceCodeInfo_Location::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo.Location)
+  // repeated int32 path = 1 [packed = true];
+  if (this->path_size() > 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+      1,
+      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+      target);
+    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+      _path_cached_byte_size_, target);
+  }
+  for (int i = 0; i < this->path_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteInt32NoTagToArray(this->path(i), target);
+  }
+
+  // repeated int32 span = 2 [packed = true];
+  if (this->span_size() > 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+      2,
+      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+      target);
+    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+      _span_cached_byte_size_, target);
+  }
+  for (int i = 0; i < this->span_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteInt32NoTagToArray(this->span(i), target);
+  }
+
+  // optional string leading_comments = 3;
+  if (has_leading_comments()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->leading_comments().data(), this->leading_comments().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "leading_comments");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->leading_comments(), target);
+  }
+
+  // optional string trailing_comments = 4;
+  if (has_trailing_comments()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->trailing_comments().data(), this->trailing_comments().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "trailing_comments");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->trailing_comments(), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo.Location)
+  return target;
+}
+
+int SourceCodeInfo_Location::ByteSize() const {
+  int total_size = 0;
+
+  if (_has_bits_[2 / 32] & (0xffu << (2 % 32))) {
+    // optional string leading_comments = 3;
+    if (has_leading_comments()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->leading_comments());
+    }
+
+    // optional string trailing_comments = 4;
+    if (has_trailing_comments()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->trailing_comments());
+    }
+
+  }
+  // repeated int32 path = 1 [packed = true];
+  {
+    int data_size = 0;
+    for (int i = 0; i < this->path_size(); i++) {
+      data_size += ::google::protobuf::internal::WireFormatLite::
+        Int32Size(this->path(i));
+    }
+    if (data_size > 0) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+    }
+    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+    _path_cached_byte_size_ = data_size;
+    GOOGLE_SAFE_CONCURRENT_WRITES_END();
+    total_size += data_size;
+  }
+
+  // repeated int32 span = 2 [packed = true];
+  {
+    int data_size = 0;
+    for (int i = 0; i < this->span_size(); i++) {
+      data_size += ::google::protobuf::internal::WireFormatLite::
+        Int32Size(this->span(i));
+    }
+    if (data_size > 0) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+    }
+    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+    _span_cached_byte_size_ = data_size;
+    GOOGLE_SAFE_CONCURRENT_WRITES_END();
+    total_size += data_size;
+  }
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const SourceCodeInfo_Location* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo_Location*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  path_.MergeFrom(from.path_);
+  span_.MergeFrom(from.span_);
+  if (from._has_bits_[2 / 32] & (0xffu << (2 % 32))) {
+    if (from.has_leading_comments()) {
+      set_leading_comments(from.leading_comments());
+    }
+    if (from.has_trailing_comments()) {
+      set_trailing_comments(from.trailing_comments());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void SourceCodeInfo_Location::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool SourceCodeInfo_Location::IsInitialized() const {
+
+  return true;
+}
+
+void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) {
+  if (other != this) {
+    path_.Swap(&other->path_);
+    span_.Swap(&other->span_);
+    std::swap(leading_comments_, other->leading_comments_);
+    std::swap(trailing_comments_, other->trailing_comments_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = SourceCodeInfo_Location_descriptor_;
+  metadata.reflection = SourceCodeInfo_Location_reflection_;
+  return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
+const int SourceCodeInfo::kLocationFieldNumber;
+#endif  // !_MSC_VER
+
+SourceCodeInfo::SourceCodeInfo()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo)
+}
+
+void SourceCodeInfo::InitAsDefaultInstance() {
+}
+
+SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo)
+}
+
+void SourceCodeInfo::SharedCtor() {
+  _cached_size_ = 0;
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+SourceCodeInfo::~SourceCodeInfo() {
+  // @@protoc_insertion_point(destructor:google.protobuf.SourceCodeInfo)
+  SharedDtor();
+}
+
+void SourceCodeInfo::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void SourceCodeInfo::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return SourceCodeInfo_descriptor_;
+}
+
+const SourceCodeInfo& SourceCodeInfo::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  return *default_instance_;
+}
+
+SourceCodeInfo* SourceCodeInfo::default_instance_ = NULL;
+
+SourceCodeInfo* SourceCodeInfo::New() const {
+  return new SourceCodeInfo;
+}
+
+void SourceCodeInfo::Clear() {
+  location_.Clear();
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool SourceCodeInfo::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:google.protobuf.SourceCodeInfo)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+      case 1: {
+        if (tag == 10) {
+         parse_location:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+                input, add_location()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(10)) goto parse_location;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:google.protobuf.SourceCodeInfo)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:google.protobuf.SourceCodeInfo)
+  return false;
+#undef DO_
+}
+
+void SourceCodeInfo::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:google.protobuf.SourceCodeInfo)
+  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+  for (int i = 0; i < this->location_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, this->location(i), output);
+  }
+
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:google.protobuf.SourceCodeInfo)
+}
+
+::google::protobuf::uint8* SourceCodeInfo::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo)
+  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+  for (int i = 0; i < this->location_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        1, this->location(i), target);
+  }
+
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceCodeInfo)
+  return target;
+}
+
+int SourceCodeInfo::ByteSize() const {
+  int total_size = 0;
+
+  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+  total_size += 1 * this->location_size();
+  for (int i = 0; i < this->location_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->location(i));
+  }
+
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const SourceCodeInfo* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  location_.MergeFrom(from.location_);
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void SourceCodeInfo::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool SourceCodeInfo::IsInitialized() const {
+
+  return true;
+}
+
+void SourceCodeInfo::Swap(SourceCodeInfo* other) {
+  if (other != this) {
+    location_.Swap(&other->location_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = SourceCodeInfo_descriptor_;
+  metadata.reflection = SourceCodeInfo_reflection_;
+  return metadata;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace protobuf
+}  // namespace google
+
+// @@protoc_insertion_point(global_scope)
diff --git a/protobuf/src/google/protobuf/descriptor.pb.h b/protobuf/src/google/protobuf/descriptor.pb.h
new file mode 100644
index 0000000..91a20b8
--- /dev/null
+++ b/protobuf/src/google/protobuf/descriptor.pb.h
@@ -0,0 +1,6795 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: google/protobuf/descriptor.proto
+
+#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 < 2006000
+#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 2006001 < 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_util.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/generated_enum_reflection.h>
+#include <google/protobuf/unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+
+namespace google {
+namespace protobuf {
+
+// Internal implementation detail -- do not call these.
+void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+class FileDescriptorSet;
+class FileDescriptorProto;
+class DescriptorProto;
+class DescriptorProto_ExtensionRange;
+class FieldDescriptorProto;
+class OneofDescriptorProto;
+class EnumDescriptorProto;
+class EnumValueDescriptorProto;
+class ServiceDescriptorProto;
+class MethodDescriptorProto;
+class FileOptions;
+class MessageOptions;
+class FieldOptions;
+class EnumOptions;
+class EnumValueOptions;
+class ServiceOptions;
+class MethodOptions;
+class UninterpretedOption;
+class UninterpretedOption_NamePart;
+class SourceCodeInfo;
+class SourceCodeInfo_Location;
+
+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 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;
+const int FieldDescriptorProto_Type_Type_ARRAYSIZE = FieldDescriptorProto_Type_Type_MAX + 1;
+
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor();
+inline const ::std::string& FieldDescriptorProto_Type_Name(FieldDescriptorProto_Type value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    FieldDescriptorProto_Type_descriptor(), value);
+}
+inline bool FieldDescriptorProto_Type_Parse(
+    const ::std::string& name, FieldDescriptorProto_Type* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<FieldDescriptorProto_Type>(
+    FieldDescriptorProto_Type_descriptor(), name, value);
+}
+enum FieldDescriptorProto_Label {
+  FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
+  FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
+  FieldDescriptorProto_Label_LABEL_REPEATED = 3
+};
+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;
+const int FieldDescriptorProto_Label_Label_ARRAYSIZE = FieldDescriptorProto_Label_Label_MAX + 1;
+
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor();
+inline const ::std::string& FieldDescriptorProto_Label_Name(FieldDescriptorProto_Label value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    FieldDescriptorProto_Label_descriptor(), value);
+}
+inline bool FieldDescriptorProto_Label_Parse(
+    const ::std::string& name, FieldDescriptorProto_Label* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<FieldDescriptorProto_Label>(
+    FieldDescriptorProto_Label_descriptor(), name, value);
+}
+enum FileOptions_OptimizeMode {
+  FileOptions_OptimizeMode_SPEED = 1,
+  FileOptions_OptimizeMode_CODE_SIZE = 2,
+  FileOptions_OptimizeMode_LITE_RUNTIME = 3
+};
+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_LITE_RUNTIME;
+const int FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE = FileOptions_OptimizeMode_OptimizeMode_MAX + 1;
+
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor();
+inline const ::std::string& FileOptions_OptimizeMode_Name(FileOptions_OptimizeMode value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    FileOptions_OptimizeMode_descriptor(), value);
+}
+inline bool FileOptions_OptimizeMode_Parse(
+    const ::std::string& name, FileOptions_OptimizeMode* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<FileOptions_OptimizeMode>(
+    FileOptions_OptimizeMode_descriptor(), name, value);
+}
+enum FieldOptions_CType {
+  FieldOptions_CType_STRING = 0,
+  FieldOptions_CType_CORD = 1,
+  FieldOptions_CType_STRING_PIECE = 2
+};
+LIBPROTOBUF_EXPORT bool FieldOptions_CType_IsValid(int value);
+const FieldOptions_CType FieldOptions_CType_CType_MIN = FieldOptions_CType_STRING;
+const FieldOptions_CType FieldOptions_CType_CType_MAX = FieldOptions_CType_STRING_PIECE;
+const int FieldOptions_CType_CType_ARRAYSIZE = FieldOptions_CType_CType_MAX + 1;
+
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor();
+inline const ::std::string& FieldOptions_CType_Name(FieldOptions_CType value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    FieldOptions_CType_descriptor(), value);
+}
+inline bool FieldOptions_CType_Parse(
+    const ::std::string& name, FieldOptions_CType* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<FieldOptions_CType>(
+    FieldOptions_CType_descriptor(), name, value);
+}
+// ===================================================================
+
+class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message {
+ public:
+  FileDescriptorSet();
+  virtual ~FileDescriptorSet();
+
+  FileDescriptorSet(const FileDescriptorSet& from);
+
+  inline FileDescriptorSet& operator=(const FileDescriptorSet& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const FileDescriptorSet& default_instance();
+
+  void Swap(FileDescriptorSet* other);
+
+  // implements Message ----------------------------------------------
+
+  FileDescriptorSet* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const FileDescriptorSet& from);
+  void MergeFrom(const FileDescriptorSet& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated .google.protobuf.FileDescriptorProto file = 1;
+  inline int file_size() const;
+  inline void clear_file();
+  static const int kFileFieldNumber = 1;
+  inline const ::google::protobuf::FileDescriptorProto& file(int index) const;
+  inline ::google::protobuf::FileDescriptorProto* mutable_file(int index);
+  inline ::google::protobuf::FileDescriptorProto* add_file();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+      file() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+      mutable_file();
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
+ private:
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto > file_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static FileDescriptorSet* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const FileDescriptorProto& default_instance();
+
+  void Swap(FileDescriptorProto* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  static const int kNameFieldNumber = 1;
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline void set_name(const char* value, size_t size);
+  inline ::std::string* mutable_name();
+  inline ::std::string* release_name();
+  inline void set_allocated_name(::std::string* name);
+
+  // optional string package = 2;
+  inline bool has_package() const;
+  inline void clear_package();
+  static const int kPackageFieldNumber = 2;
+  inline const ::std::string& package() const;
+  inline void set_package(const ::std::string& value);
+  inline void set_package(const char* value);
+  inline void set_package(const char* value, size_t size);
+  inline ::std::string* mutable_package();
+  inline ::std::string* release_package();
+  inline void set_allocated_package(::std::string* package);
+
+  // repeated string dependency = 3;
+  inline int dependency_size() const;
+  inline void clear_dependency();
+  static const int kDependencyFieldNumber = 3;
+  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 void set_dependency(int index, const char* value, size_t size);
+  inline ::std::string* add_dependency();
+  inline void add_dependency(const ::std::string& value);
+  inline void add_dependency(const char* value);
+  inline void add_dependency(const char* value, size_t size);
+  inline const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
+  inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency();
+
+  // repeated int32 public_dependency = 10;
+  inline int public_dependency_size() const;
+  inline void clear_public_dependency();
+  static const int kPublicDependencyFieldNumber = 10;
+  inline ::google::protobuf::int32 public_dependency(int index) const;
+  inline void set_public_dependency(int index, ::google::protobuf::int32 value);
+  inline void add_public_dependency(::google::protobuf::int32 value);
+  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+      public_dependency() const;
+  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+      mutable_public_dependency();
+
+  // repeated int32 weak_dependency = 11;
+  inline int weak_dependency_size() const;
+  inline void clear_weak_dependency();
+  static const int kWeakDependencyFieldNumber = 11;
+  inline ::google::protobuf::int32 weak_dependency(int index) const;
+  inline void set_weak_dependency(int index, ::google::protobuf::int32 value);
+  inline void add_weak_dependency(::google::protobuf::int32 value);
+  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+      weak_dependency() const;
+  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+      mutable_weak_dependency();
+
+  // repeated .google.protobuf.DescriptorProto message_type = 4;
+  inline int message_type_size() const;
+  inline void clear_message_type();
+  static const int kMessageTypeFieldNumber = 4;
+  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();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+      message_type() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+      mutable_message_type();
+
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
+  inline int enum_type_size() const;
+  inline void clear_enum_type();
+  static const int kEnumTypeFieldNumber = 5;
+  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();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+      enum_type() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+      mutable_enum_type();
+
+  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
+  inline int service_size() const;
+  inline void clear_service();
+  static const int kServiceFieldNumber = 6;
+  inline const ::google::protobuf::ServiceDescriptorProto& service(int index) const;
+  inline ::google::protobuf::ServiceDescriptorProto* mutable_service(int index);
+  inline ::google::protobuf::ServiceDescriptorProto* add_service();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
+      service() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
+      mutable_service();
+
+  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
+  inline int extension_size() const;
+  inline void clear_extension();
+  static const int kExtensionFieldNumber = 7;
+  inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
+  inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
+  inline ::google::protobuf::FieldDescriptorProto* add_extension();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+      extension() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+      mutable_extension();
+
+  // optional .google.protobuf.FileOptions options = 8;
+  inline bool has_options() const;
+  inline void clear_options();
+  static const int kOptionsFieldNumber = 8;
+  inline const ::google::protobuf::FileOptions& options() const;
+  inline ::google::protobuf::FileOptions* mutable_options();
+  inline ::google::protobuf::FileOptions* release_options();
+  inline void set_allocated_options(::google::protobuf::FileOptions* options);
+
+  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+  inline bool has_source_code_info() const;
+  inline void clear_source_code_info();
+  static const int kSourceCodeInfoFieldNumber = 9;
+  inline const ::google::protobuf::SourceCodeInfo& source_code_info() const;
+  inline ::google::protobuf::SourceCodeInfo* mutable_source_code_info();
+  inline ::google::protobuf::SourceCodeInfo* release_source_code_info();
+  inline void set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorProto)
+ private:
+  inline void set_has_name();
+  inline void clear_has_name();
+  inline void set_has_package();
+  inline void clear_has_package();
+  inline void set_has_options();
+  inline void clear_has_options();
+  inline void set_has_source_code_info();
+  inline void clear_has_source_code_info();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* name_;
+  ::std::string* package_;
+  ::google::protobuf::RepeatedPtrField< ::std::string> dependency_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_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_;
+  ::google::protobuf::SourceCodeInfo* source_code_info_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static FileDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const DescriptorProto_ExtensionRange& default_instance();
+
+  void Swap(DescriptorProto_ExtensionRange* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional int32 start = 1;
+  inline bool has_start() const;
+  inline void clear_start();
+  static const int kStartFieldNumber = 1;
+  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();
+  static const int kEndFieldNumber = 2;
+  inline ::google::protobuf::int32 end() const;
+  inline void set_end(::google::protobuf::int32 value);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ExtensionRange)
+ private:
+  inline void set_has_start();
+  inline void clear_has_start();
+  inline void set_has_end();
+  inline void clear_has_end();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::int32 start_;
+  ::google::protobuf::int32 end_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static DescriptorProto_ExtensionRange* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const DescriptorProto& default_instance();
+
+  void Swap(DescriptorProto* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  typedef DescriptorProto_ExtensionRange ExtensionRange;
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  static const int kNameFieldNumber = 1;
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline void set_name(const char* value, size_t size);
+  inline ::std::string* mutable_name();
+  inline ::std::string* release_name();
+  inline void set_allocated_name(::std::string* name);
+
+  // repeated .google.protobuf.FieldDescriptorProto field = 2;
+  inline int field_size() const;
+  inline void clear_field();
+  static const int kFieldFieldNumber = 2;
+  inline const ::google::protobuf::FieldDescriptorProto& field(int index) const;
+  inline ::google::protobuf::FieldDescriptorProto* mutable_field(int index);
+  inline ::google::protobuf::FieldDescriptorProto* add_field();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+      field() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+      mutable_field();
+
+  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
+  inline int extension_size() const;
+  inline void clear_extension();
+  static const int kExtensionFieldNumber = 6;
+  inline const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
+  inline ::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
+  inline ::google::protobuf::FieldDescriptorProto* add_extension();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+      extension() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+      mutable_extension();
+
+  // repeated .google.protobuf.DescriptorProto nested_type = 3;
+  inline int nested_type_size() const;
+  inline void clear_nested_type();
+  static const int kNestedTypeFieldNumber = 3;
+  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();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+      nested_type() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+      mutable_nested_type();
+
+  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
+  inline int enum_type_size() const;
+  inline void clear_enum_type();
+  static const int kEnumTypeFieldNumber = 4;
+  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();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+      enum_type() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+      mutable_enum_type();
+
+  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
+  inline int extension_range_size() const;
+  inline void clear_extension_range();
+  static const int kExtensionRangeFieldNumber = 5;
+  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();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
+      extension_range() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
+      mutable_extension_range();
+
+  // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+  inline int oneof_decl_size() const;
+  inline void clear_oneof_decl();
+  static const int kOneofDeclFieldNumber = 8;
+  inline const ::google::protobuf::OneofDescriptorProto& oneof_decl(int index) const;
+  inline ::google::protobuf::OneofDescriptorProto* mutable_oneof_decl(int index);
+  inline ::google::protobuf::OneofDescriptorProto* add_oneof_decl();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
+      oneof_decl() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
+      mutable_oneof_decl();
+
+  // optional .google.protobuf.MessageOptions options = 7;
+  inline bool has_options() const;
+  inline void clear_options();
+  static const int kOptionsFieldNumber = 7;
+  inline const ::google::protobuf::MessageOptions& options() const;
+  inline ::google::protobuf::MessageOptions* mutable_options();
+  inline ::google::protobuf::MessageOptions* release_options();
+  inline void set_allocated_options(::google::protobuf::MessageOptions* options);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto)
+ private:
+  inline void set_has_name();
+  inline void clear_has_name();
+  inline void set_has_options();
+  inline void clear_has_options();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* 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::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_;
+  ::google::protobuf::MessageOptions* options_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static DescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const FieldDescriptorProto& default_instance();
+
+  void Swap(FieldDescriptorProto* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // 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 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;
+  static const int Type_ARRAYSIZE =
+    FieldDescriptorProto_Type_Type_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Type_descriptor() {
+    return FieldDescriptorProto_Type_descriptor();
+  }
+  static inline const ::std::string& Type_Name(Type value) {
+    return FieldDescriptorProto_Type_Name(value);
+  }
+  static inline bool Type_Parse(const ::std::string& name,
+      Type* value) {
+    return FieldDescriptorProto_Type_Parse(name, value);
+  }
+
+  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 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;
+  static const int Label_ARRAYSIZE =
+    FieldDescriptorProto_Label_Label_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Label_descriptor() {
+    return FieldDescriptorProto_Label_descriptor();
+  }
+  static inline const ::std::string& Label_Name(Label value) {
+    return FieldDescriptorProto_Label_Name(value);
+  }
+  static inline bool Label_Parse(const ::std::string& name,
+      Label* value) {
+    return FieldDescriptorProto_Label_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  static const int kNameFieldNumber = 1;
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline void set_name(const char* value, size_t size);
+  inline ::std::string* mutable_name();
+  inline ::std::string* release_name();
+  inline void set_allocated_name(::std::string* name);
+
+  // optional int32 number = 3;
+  inline bool has_number() const;
+  inline void clear_number();
+  static const int kNumberFieldNumber = 3;
+  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();
+  static const int kLabelFieldNumber = 4;
+  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();
+  static const int kTypeFieldNumber = 5;
+  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();
+  static const int kTypeNameFieldNumber = 6;
+  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 void set_type_name(const char* value, size_t size);
+  inline ::std::string* mutable_type_name();
+  inline ::std::string* release_type_name();
+  inline void set_allocated_type_name(::std::string* type_name);
+
+  // optional string extendee = 2;
+  inline bool has_extendee() const;
+  inline void clear_extendee();
+  static const int kExtendeeFieldNumber = 2;
+  inline const ::std::string& extendee() const;
+  inline void set_extendee(const ::std::string& value);
+  inline void set_extendee(const char* value);
+  inline void set_extendee(const char* value, size_t size);
+  inline ::std::string* mutable_extendee();
+  inline ::std::string* release_extendee();
+  inline void set_allocated_extendee(::std::string* extendee);
+
+  // optional string default_value = 7;
+  inline bool has_default_value() const;
+  inline void clear_default_value();
+  static const int kDefaultValueFieldNumber = 7;
+  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 void set_default_value(const char* value, size_t size);
+  inline ::std::string* mutable_default_value();
+  inline ::std::string* release_default_value();
+  inline void set_allocated_default_value(::std::string* default_value);
+
+  // optional int32 oneof_index = 9;
+  inline bool has_oneof_index() const;
+  inline void clear_oneof_index();
+  static const int kOneofIndexFieldNumber = 9;
+  inline ::google::protobuf::int32 oneof_index() const;
+  inline void set_oneof_index(::google::protobuf::int32 value);
+
+  // optional .google.protobuf.FieldOptions options = 8;
+  inline bool has_options() const;
+  inline void clear_options();
+  static const int kOptionsFieldNumber = 8;
+  inline const ::google::protobuf::FieldOptions& options() const;
+  inline ::google::protobuf::FieldOptions* mutable_options();
+  inline ::google::protobuf::FieldOptions* release_options();
+  inline void set_allocated_options(::google::protobuf::FieldOptions* options);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.FieldDescriptorProto)
+ private:
+  inline void set_has_name();
+  inline void clear_has_name();
+  inline void set_has_number();
+  inline void clear_has_number();
+  inline void set_has_label();
+  inline void clear_has_label();
+  inline void set_has_type();
+  inline void clear_has_type();
+  inline void set_has_type_name();
+  inline void clear_has_type_name();
+  inline void set_has_extendee();
+  inline void clear_has_extendee();
+  inline void set_has_default_value();
+  inline void clear_has_default_value();
+  inline void set_has_oneof_index();
+  inline void clear_has_oneof_index();
+  inline void set_has_options();
+  inline void clear_has_options();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* name_;
+  ::google::protobuf::int32 number_;
+  int label_;
+  ::std::string* type_name_;
+  ::std::string* extendee_;
+  int type_;
+  ::google::protobuf::int32 oneof_index_;
+  ::std::string* default_value_;
+  ::google::protobuf::FieldOptions* options_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static FieldDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Message {
+ public:
+  OneofDescriptorProto();
+  virtual ~OneofDescriptorProto();
+
+  OneofDescriptorProto(const OneofDescriptorProto& from);
+
+  inline OneofDescriptorProto& operator=(const OneofDescriptorProto& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const OneofDescriptorProto& default_instance();
+
+  void Swap(OneofDescriptorProto* other);
+
+  // implements Message ----------------------------------------------
+
+  OneofDescriptorProto* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const OneofDescriptorProto& from);
+  void MergeFrom(const OneofDescriptorProto& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  static const int kNameFieldNumber = 1;
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline void set_name(const char* value, size_t size);
+  inline ::std::string* mutable_name();
+  inline ::std::string* release_name();
+  inline void set_allocated_name(::std::string* name);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.OneofDescriptorProto)
+ private:
+  inline void set_has_name();
+  inline void clear_has_name();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* name_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static OneofDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const EnumDescriptorProto& default_instance();
+
+  void Swap(EnumDescriptorProto* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  static const int kNameFieldNumber = 1;
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline void set_name(const char* value, size_t size);
+  inline ::std::string* mutable_name();
+  inline ::std::string* release_name();
+  inline void set_allocated_name(::std::string* name);
+
+  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
+  inline int value_size() const;
+  inline void clear_value();
+  static const int kValueFieldNumber = 2;
+  inline const ::google::protobuf::EnumValueDescriptorProto& value(int index) const;
+  inline ::google::protobuf::EnumValueDescriptorProto* mutable_value(int index);
+  inline ::google::protobuf::EnumValueDescriptorProto* add_value();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
+      value() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
+      mutable_value();
+
+  // optional .google.protobuf.EnumOptions options = 3;
+  inline bool has_options() const;
+  inline void clear_options();
+  static const int kOptionsFieldNumber = 3;
+  inline const ::google::protobuf::EnumOptions& options() const;
+  inline ::google::protobuf::EnumOptions* mutable_options();
+  inline ::google::protobuf::EnumOptions* release_options();
+  inline void set_allocated_options(::google::protobuf::EnumOptions* options);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.EnumDescriptorProto)
+ private:
+  inline void set_has_name();
+  inline void clear_has_name();
+  inline void set_has_options();
+  inline void clear_has_options();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* name_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto > value_;
+  ::google::protobuf::EnumOptions* options_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static EnumDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const EnumValueDescriptorProto& default_instance();
+
+  void Swap(EnumValueDescriptorProto* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  static const int kNameFieldNumber = 1;
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline void set_name(const char* value, size_t size);
+  inline ::std::string* mutable_name();
+  inline ::std::string* release_name();
+  inline void set_allocated_name(::std::string* name);
+
+  // optional int32 number = 2;
+  inline bool has_number() const;
+  inline void clear_number();
+  static const int kNumberFieldNumber = 2;
+  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();
+  static const int kOptionsFieldNumber = 3;
+  inline const ::google::protobuf::EnumValueOptions& options() const;
+  inline ::google::protobuf::EnumValueOptions* mutable_options();
+  inline ::google::protobuf::EnumValueOptions* release_options();
+  inline void set_allocated_options(::google::protobuf::EnumValueOptions* options);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueDescriptorProto)
+ private:
+  inline void set_has_name();
+  inline void clear_has_name();
+  inline void set_has_number();
+  inline void clear_has_number();
+  inline void set_has_options();
+  inline void clear_has_options();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* name_;
+  ::google::protobuf::EnumValueOptions* options_;
+  ::google::protobuf::int32 number_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static EnumValueDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ServiceDescriptorProto& default_instance();
+
+  void Swap(ServiceDescriptorProto* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  static const int kNameFieldNumber = 1;
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline void set_name(const char* value, size_t size);
+  inline ::std::string* mutable_name();
+  inline ::std::string* release_name();
+  inline void set_allocated_name(::std::string* name);
+
+  // repeated .google.protobuf.MethodDescriptorProto method = 2;
+  inline int method_size() const;
+  inline void clear_method();
+  static const int kMethodFieldNumber = 2;
+  inline const ::google::protobuf::MethodDescriptorProto& method(int index) const;
+  inline ::google::protobuf::MethodDescriptorProto* mutable_method(int index);
+  inline ::google::protobuf::MethodDescriptorProto* add_method();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
+      method() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
+      mutable_method();
+
+  // optional .google.protobuf.ServiceOptions options = 3;
+  inline bool has_options() const;
+  inline void clear_options();
+  static const int kOptionsFieldNumber = 3;
+  inline const ::google::protobuf::ServiceOptions& options() const;
+  inline ::google::protobuf::ServiceOptions* mutable_options();
+  inline ::google::protobuf::ServiceOptions* release_options();
+  inline void set_allocated_options(::google::protobuf::ServiceOptions* options);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.ServiceDescriptorProto)
+ private:
+  inline void set_has_name();
+  inline void clear_has_name();
+  inline void set_has_options();
+  inline void clear_has_options();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* name_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto > method_;
+  ::google::protobuf::ServiceOptions* options_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static ServiceDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const MethodDescriptorProto& default_instance();
+
+  void Swap(MethodDescriptorProto* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  inline bool has_name() const;
+  inline void clear_name();
+  static const int kNameFieldNumber = 1;
+  inline const ::std::string& name() const;
+  inline void set_name(const ::std::string& value);
+  inline void set_name(const char* value);
+  inline void set_name(const char* value, size_t size);
+  inline ::std::string* mutable_name();
+  inline ::std::string* release_name();
+  inline void set_allocated_name(::std::string* name);
+
+  // optional string input_type = 2;
+  inline bool has_input_type() const;
+  inline void clear_input_type();
+  static const int kInputTypeFieldNumber = 2;
+  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 void set_input_type(const char* value, size_t size);
+  inline ::std::string* mutable_input_type();
+  inline ::std::string* release_input_type();
+  inline void set_allocated_input_type(::std::string* input_type);
+
+  // optional string output_type = 3;
+  inline bool has_output_type() const;
+  inline void clear_output_type();
+  static const int kOutputTypeFieldNumber = 3;
+  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 void set_output_type(const char* value, size_t size);
+  inline ::std::string* mutable_output_type();
+  inline ::std::string* release_output_type();
+  inline void set_allocated_output_type(::std::string* output_type);
+
+  // optional .google.protobuf.MethodOptions options = 4;
+  inline bool has_options() const;
+  inline void clear_options();
+  static const int kOptionsFieldNumber = 4;
+  inline const ::google::protobuf::MethodOptions& options() const;
+  inline ::google::protobuf::MethodOptions* mutable_options();
+  inline ::google::protobuf::MethodOptions* release_options();
+  inline void set_allocated_options(::google::protobuf::MethodOptions* options);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.MethodDescriptorProto)
+ private:
+  inline void set_has_name();
+  inline void clear_has_name();
+  inline void set_has_input_type();
+  inline void clear_has_input_type();
+  inline void set_has_output_type();
+  inline void clear_has_output_type();
+  inline void set_has_options();
+  inline void clear_has_options();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* name_;
+  ::std::string* input_type_;
+  ::std::string* output_type_;
+  ::google::protobuf::MethodOptions* options_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static MethodDescriptorProto* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const FileOptions& default_instance();
+
+  void Swap(FileOptions* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  typedef FileOptions_OptimizeMode OptimizeMode;
+  static const OptimizeMode SPEED = FileOptions_OptimizeMode_SPEED;
+  static const OptimizeMode CODE_SIZE = FileOptions_OptimizeMode_CODE_SIZE;
+  static const OptimizeMode LITE_RUNTIME = FileOptions_OptimizeMode_LITE_RUNTIME;
+  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;
+  static const int OptimizeMode_ARRAYSIZE =
+    FileOptions_OptimizeMode_OptimizeMode_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  OptimizeMode_descriptor() {
+    return FileOptions_OptimizeMode_descriptor();
+  }
+  static inline const ::std::string& OptimizeMode_Name(OptimizeMode value) {
+    return FileOptions_OptimizeMode_Name(value);
+  }
+  static inline bool OptimizeMode_Parse(const ::std::string& name,
+      OptimizeMode* value) {
+    return FileOptions_OptimizeMode_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // optional string java_package = 1;
+  inline bool has_java_package() const;
+  inline void clear_java_package();
+  static const int kJavaPackageFieldNumber = 1;
+  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 void set_java_package(const char* value, size_t size);
+  inline ::std::string* mutable_java_package();
+  inline ::std::string* release_java_package();
+  inline void set_allocated_java_package(::std::string* java_package);
+
+  // optional string java_outer_classname = 8;
+  inline bool has_java_outer_classname() const;
+  inline void clear_java_outer_classname();
+  static const int kJavaOuterClassnameFieldNumber = 8;
+  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 void set_java_outer_classname(const char* value, size_t size);
+  inline ::std::string* mutable_java_outer_classname();
+  inline ::std::string* release_java_outer_classname();
+  inline void set_allocated_java_outer_classname(::std::string* java_outer_classname);
+
+  // optional bool java_multiple_files = 10 [default = false];
+  inline bool has_java_multiple_files() const;
+  inline void clear_java_multiple_files();
+  static const int kJavaMultipleFilesFieldNumber = 10;
+  inline bool java_multiple_files() const;
+  inline void set_java_multiple_files(bool value);
+
+  // optional bool java_generate_equals_and_hash = 20 [default = false];
+  inline bool has_java_generate_equals_and_hash() const;
+  inline void clear_java_generate_equals_and_hash();
+  static const int kJavaGenerateEqualsAndHashFieldNumber = 20;
+  inline bool java_generate_equals_and_hash() const;
+  inline void set_java_generate_equals_and_hash(bool value);
+
+  // optional bool java_string_check_utf8 = 27 [default = false];
+  inline bool has_java_string_check_utf8() const;
+  inline void clear_java_string_check_utf8();
+  static const int kJavaStringCheckUtf8FieldNumber = 27;
+  inline bool java_string_check_utf8() const;
+  inline void set_java_string_check_utf8(bool value);
+
+  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+  inline bool has_optimize_for() const;
+  inline void clear_optimize_for();
+  static const int kOptimizeForFieldNumber = 9;
+  inline ::google::protobuf::FileOptions_OptimizeMode optimize_for() const;
+  inline void set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value);
+
+  // optional string go_package = 11;
+  inline bool has_go_package() const;
+  inline void clear_go_package();
+  static const int kGoPackageFieldNumber = 11;
+  inline const ::std::string& go_package() const;
+  inline void set_go_package(const ::std::string& value);
+  inline void set_go_package(const char* value);
+  inline void set_go_package(const char* value, size_t size);
+  inline ::std::string* mutable_go_package();
+  inline ::std::string* release_go_package();
+  inline void set_allocated_go_package(::std::string* go_package);
+
+  // optional bool cc_generic_services = 16 [default = false];
+  inline bool has_cc_generic_services() const;
+  inline void clear_cc_generic_services();
+  static const int kCcGenericServicesFieldNumber = 16;
+  inline bool cc_generic_services() const;
+  inline void set_cc_generic_services(bool value);
+
+  // optional bool java_generic_services = 17 [default = false];
+  inline bool has_java_generic_services() const;
+  inline void clear_java_generic_services();
+  static const int kJavaGenericServicesFieldNumber = 17;
+  inline bool java_generic_services() const;
+  inline void set_java_generic_services(bool value);
+
+  // optional bool py_generic_services = 18 [default = false];
+  inline bool has_py_generic_services() const;
+  inline void clear_py_generic_services();
+  static const int kPyGenericServicesFieldNumber = 18;
+  inline bool py_generic_services() const;
+  inline void set_py_generic_services(bool value);
+
+  // optional bool deprecated = 23 [default = false];
+  inline bool has_deprecated() const;
+  inline void clear_deprecated();
+  static const int kDeprecatedFieldNumber = 23;
+  inline bool deprecated() const;
+  inline void set_deprecated(bool value);
+
+  // optional bool javanano_use_deprecated_package = 38;
+  inline bool has_javanano_use_deprecated_package() const;
+  inline void clear_javanano_use_deprecated_package();
+  static const int kJavananoUseDeprecatedPackageFieldNumber = 38;
+  inline bool javanano_use_deprecated_package() const;
+  inline void set_javanano_use_deprecated_package(bool value);
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  inline int uninterpreted_option_size() const;
+  inline void clear_uninterpreted_option();
+  static const int kUninterpretedOptionFieldNumber = 999;
+  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+      uninterpreted_option() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+      mutable_uninterpreted_option();
+
+  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions)
+  // @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
+ private:
+  inline void set_has_java_package();
+  inline void clear_has_java_package();
+  inline void set_has_java_outer_classname();
+  inline void clear_has_java_outer_classname();
+  inline void set_has_java_multiple_files();
+  inline void clear_has_java_multiple_files();
+  inline void set_has_java_generate_equals_and_hash();
+  inline void clear_has_java_generate_equals_and_hash();
+  inline void set_has_java_string_check_utf8();
+  inline void clear_has_java_string_check_utf8();
+  inline void set_has_optimize_for();
+  inline void clear_has_optimize_for();
+  inline void set_has_go_package();
+  inline void clear_has_go_package();
+  inline void set_has_cc_generic_services();
+  inline void clear_has_cc_generic_services();
+  inline void set_has_java_generic_services();
+  inline void clear_has_java_generic_services();
+  inline void set_has_py_generic_services();
+  inline void clear_has_py_generic_services();
+  inline void set_has_deprecated();
+  inline void clear_has_deprecated();
+  inline void set_has_javanano_use_deprecated_package();
+  inline void clear_has_javanano_use_deprecated_package();
+
+  ::google::protobuf::internal::ExtensionSet _extensions_;
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* java_package_;
+  ::std::string* java_outer_classname_;
+  bool java_multiple_files_;
+  bool java_generate_equals_and_hash_;
+  bool java_string_check_utf8_;
+  bool cc_generic_services_;
+  int optimize_for_;
+  ::std::string* go_package_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+  bool java_generic_services_;
+  bool py_generic_services_;
+  bool deprecated_;
+  bool javanano_use_deprecated_package_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static FileOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const MessageOptions& default_instance();
+
+  void Swap(MessageOptions* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // 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();
+  static const int kMessageSetWireFormatFieldNumber = 1;
+  inline bool message_set_wire_format() const;
+  inline void set_message_set_wire_format(bool value);
+
+  // optional bool no_standard_descriptor_accessor = 2 [default = false];
+  inline bool has_no_standard_descriptor_accessor() const;
+  inline void clear_no_standard_descriptor_accessor();
+  static const int kNoStandardDescriptorAccessorFieldNumber = 2;
+  inline bool no_standard_descriptor_accessor() const;
+  inline void set_no_standard_descriptor_accessor(bool value);
+
+  // optional bool deprecated = 3 [default = false];
+  inline bool has_deprecated() const;
+  inline void clear_deprecated();
+  static const int kDeprecatedFieldNumber = 3;
+  inline bool deprecated() const;
+  inline void set_deprecated(bool value);
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  inline int uninterpreted_option_size() const;
+  inline void clear_uninterpreted_option();
+  static const int kUninterpretedOptionFieldNumber = 999;
+  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+      uninterpreted_option() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+      mutable_uninterpreted_option();
+
+  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions)
+  // @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
+ private:
+  inline void set_has_message_set_wire_format();
+  inline void clear_has_message_set_wire_format();
+  inline void set_has_no_standard_descriptor_accessor();
+  inline void clear_has_no_standard_descriptor_accessor();
+  inline void set_has_deprecated();
+  inline void clear_has_deprecated();
+
+  ::google::protobuf::internal::ExtensionSet _extensions_;
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+  bool message_set_wire_format_;
+  bool no_standard_descriptor_accessor_;
+  bool deprecated_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static MessageOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const FieldOptions& default_instance();
+
+  void Swap(FieldOptions* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  typedef FieldOptions_CType CType;
+  static const CType STRING = FieldOptions_CType_STRING;
+  static const CType CORD = FieldOptions_CType_CORD;
+  static const CType STRING_PIECE = FieldOptions_CType_STRING_PIECE;
+  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;
+  static const int CType_ARRAYSIZE =
+    FieldOptions_CType_CType_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  CType_descriptor() {
+    return FieldOptions_CType_descriptor();
+  }
+  static inline const ::std::string& CType_Name(CType value) {
+    return FieldOptions_CType_Name(value);
+  }
+  static inline bool CType_Parse(const ::std::string& name,
+      CType* value) {
+    return FieldOptions_CType_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+  inline bool has_ctype() const;
+  inline void clear_ctype();
+  static const int kCtypeFieldNumber = 1;
+  inline ::google::protobuf::FieldOptions_CType ctype() const;
+  inline void set_ctype(::google::protobuf::FieldOptions_CType value);
+
+  // optional bool packed = 2;
+  inline bool has_packed() const;
+  inline void clear_packed();
+  static const int kPackedFieldNumber = 2;
+  inline bool packed() const;
+  inline void set_packed(bool value);
+
+  // optional bool lazy = 5 [default = false];
+  inline bool has_lazy() const;
+  inline void clear_lazy();
+  static const int kLazyFieldNumber = 5;
+  inline bool lazy() const;
+  inline void set_lazy(bool value);
+
+  // optional bool deprecated = 3 [default = false];
+  inline bool has_deprecated() const;
+  inline void clear_deprecated();
+  static const int kDeprecatedFieldNumber = 3;
+  inline bool deprecated() const;
+  inline void set_deprecated(bool value);
+
+  // optional string experimental_map_key = 9;
+  inline bool has_experimental_map_key() const;
+  inline void clear_experimental_map_key();
+  static const int kExperimentalMapKeyFieldNumber = 9;
+  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 void set_experimental_map_key(const char* value, size_t size);
+  inline ::std::string* mutable_experimental_map_key();
+  inline ::std::string* release_experimental_map_key();
+  inline void set_allocated_experimental_map_key(::std::string* experimental_map_key);
+
+  // optional bool weak = 10 [default = false];
+  inline bool has_weak() const;
+  inline void clear_weak();
+  static const int kWeakFieldNumber = 10;
+  inline bool weak() const;
+  inline void set_weak(bool value);
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  inline int uninterpreted_option_size() const;
+  inline void clear_uninterpreted_option();
+  static const int kUninterpretedOptionFieldNumber = 999;
+  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+      uninterpreted_option() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+      mutable_uninterpreted_option();
+
+  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions)
+  // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
+ private:
+  inline void set_has_ctype();
+  inline void clear_has_ctype();
+  inline void set_has_packed();
+  inline void clear_has_packed();
+  inline void set_has_lazy();
+  inline void clear_has_lazy();
+  inline void set_has_deprecated();
+  inline void clear_has_deprecated();
+  inline void set_has_experimental_map_key();
+  inline void clear_has_experimental_map_key();
+  inline void set_has_weak();
+  inline void clear_has_weak();
+
+  ::google::protobuf::internal::ExtensionSet _extensions_;
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  int ctype_;
+  bool packed_;
+  bool lazy_;
+  bool deprecated_;
+  bool weak_;
+  ::std::string* experimental_map_key_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static FieldOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const EnumOptions& default_instance();
+
+  void Swap(EnumOptions* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional bool allow_alias = 2;
+  inline bool has_allow_alias() const;
+  inline void clear_allow_alias();
+  static const int kAllowAliasFieldNumber = 2;
+  inline bool allow_alias() const;
+  inline void set_allow_alias(bool value);
+
+  // optional bool deprecated = 3 [default = false];
+  inline bool has_deprecated() const;
+  inline void clear_deprecated();
+  static const int kDeprecatedFieldNumber = 3;
+  inline bool deprecated() const;
+  inline void set_deprecated(bool value);
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  inline int uninterpreted_option_size() const;
+  inline void clear_uninterpreted_option();
+  static const int kUninterpretedOptionFieldNumber = 999;
+  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+      uninterpreted_option() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+      mutable_uninterpreted_option();
+
+  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions)
+  // @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
+ private:
+  inline void set_has_allow_alias();
+  inline void clear_has_allow_alias();
+  inline void set_has_deprecated();
+  inline void clear_has_deprecated();
+
+  ::google::protobuf::internal::ExtensionSet _extensions_;
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+  bool allow_alias_;
+  bool deprecated_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static EnumOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const EnumValueOptions& default_instance();
+
+  void Swap(EnumValueOptions* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional bool deprecated = 1 [default = false];
+  inline bool has_deprecated() const;
+  inline void clear_deprecated();
+  static const int kDeprecatedFieldNumber = 1;
+  inline bool deprecated() const;
+  inline void set_deprecated(bool value);
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  inline int uninterpreted_option_size() const;
+  inline void clear_uninterpreted_option();
+  static const int kUninterpretedOptionFieldNumber = 999;
+  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+      uninterpreted_option() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+      mutable_uninterpreted_option();
+
+  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions)
+  // @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
+ private:
+  inline void set_has_deprecated();
+  inline void clear_has_deprecated();
+
+  ::google::protobuf::internal::ExtensionSet _extensions_;
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+  bool deprecated_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static EnumValueOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ServiceOptions& default_instance();
+
+  void Swap(ServiceOptions* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional bool deprecated = 33 [default = false];
+  inline bool has_deprecated() const;
+  inline void clear_deprecated();
+  static const int kDeprecatedFieldNumber = 33;
+  inline bool deprecated() const;
+  inline void set_deprecated(bool value);
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  inline int uninterpreted_option_size() const;
+  inline void clear_uninterpreted_option();
+  static const int kUninterpretedOptionFieldNumber = 999;
+  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+      uninterpreted_option() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+      mutable_uninterpreted_option();
+
+  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions)
+  // @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
+ private:
+  inline void set_has_deprecated();
+  inline void clear_has_deprecated();
+
+  ::google::protobuf::internal::ExtensionSet _extensions_;
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+  bool deprecated_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static ServiceOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+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 const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const MethodOptions& default_instance();
+
+  void Swap(MethodOptions* other);
+
+  // 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);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional bool deprecated = 33 [default = false];
+  inline bool has_deprecated() const;
+  inline void clear_deprecated();
+  static const int kDeprecatedFieldNumber = 33;
+  inline bool deprecated() const;
+  inline void set_deprecated(bool value);
+
+  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+  inline int uninterpreted_option_size() const;
+  inline void clear_uninterpreted_option();
+  static const int kUninterpretedOptionFieldNumber = 999;
+  inline const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
+  inline ::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
+  inline ::google::protobuf::UninterpretedOption* add_uninterpreted_option();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+      uninterpreted_option() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+      mutable_uninterpreted_option();
+
+  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions)
+  // @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
+ private:
+  inline void set_has_deprecated();
+  inline void clear_has_deprecated();
+
+  ::google::protobuf::internal::ExtensionSet _extensions_;
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
+  bool deprecated_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static MethodOptions* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobuf::Message {
+ public:
+  UninterpretedOption_NamePart();
+  virtual ~UninterpretedOption_NamePart();
+
+  UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from);
+
+  inline UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const UninterpretedOption_NamePart& default_instance();
+
+  void Swap(UninterpretedOption_NamePart* other);
+
+  // implements Message ----------------------------------------------
+
+  UninterpretedOption_NamePart* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const UninterpretedOption_NamePart& from);
+  void MergeFrom(const UninterpretedOption_NamePart& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // required string name_part = 1;
+  inline bool has_name_part() const;
+  inline void clear_name_part();
+  static const int kNamePartFieldNumber = 1;
+  inline const ::std::string& name_part() const;
+  inline void set_name_part(const ::std::string& value);
+  inline void set_name_part(const char* value);
+  inline void set_name_part(const char* value, size_t size);
+  inline ::std::string* mutable_name_part();
+  inline ::std::string* release_name_part();
+  inline void set_allocated_name_part(::std::string* name_part);
+
+  // required bool is_extension = 2;
+  inline bool has_is_extension() const;
+  inline void clear_is_extension();
+  static const int kIsExtensionFieldNumber = 2;
+  inline bool is_extension() const;
+  inline void set_is_extension(bool value);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption.NamePart)
+ private:
+  inline void set_has_name_part();
+  inline void clear_has_name_part();
+  inline void set_has_is_extension();
+  inline void clear_has_is_extension();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::std::string* name_part_;
+  bool is_extension_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static UninterpretedOption_NamePart* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Message {
+ public:
+  UninterpretedOption();
+  virtual ~UninterpretedOption();
+
+  UninterpretedOption(const UninterpretedOption& from);
+
+  inline UninterpretedOption& operator=(const UninterpretedOption& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const UninterpretedOption& default_instance();
+
+  void Swap(UninterpretedOption* other);
+
+  // implements Message ----------------------------------------------
+
+  UninterpretedOption* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const UninterpretedOption& from);
+  void MergeFrom(const UninterpretedOption& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  typedef UninterpretedOption_NamePart NamePart;
+
+  // accessors -------------------------------------------------------
+
+  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+  inline int name_size() const;
+  inline void clear_name();
+  static const int kNameFieldNumber = 2;
+  inline const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const;
+  inline ::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index);
+  inline ::google::protobuf::UninterpretedOption_NamePart* add_name();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
+      name() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
+      mutable_name();
+
+  // optional string identifier_value = 3;
+  inline bool has_identifier_value() const;
+  inline void clear_identifier_value();
+  static const int kIdentifierValueFieldNumber = 3;
+  inline const ::std::string& identifier_value() const;
+  inline void set_identifier_value(const ::std::string& value);
+  inline void set_identifier_value(const char* value);
+  inline void set_identifier_value(const char* value, size_t size);
+  inline ::std::string* mutable_identifier_value();
+  inline ::std::string* release_identifier_value();
+  inline void set_allocated_identifier_value(::std::string* identifier_value);
+
+  // optional uint64 positive_int_value = 4;
+  inline bool has_positive_int_value() const;
+  inline void clear_positive_int_value();
+  static const int kPositiveIntValueFieldNumber = 4;
+  inline ::google::protobuf::uint64 positive_int_value() const;
+  inline void set_positive_int_value(::google::protobuf::uint64 value);
+
+  // optional int64 negative_int_value = 5;
+  inline bool has_negative_int_value() const;
+  inline void clear_negative_int_value();
+  static const int kNegativeIntValueFieldNumber = 5;
+  inline ::google::protobuf::int64 negative_int_value() const;
+  inline void set_negative_int_value(::google::protobuf::int64 value);
+
+  // optional double double_value = 6;
+  inline bool has_double_value() const;
+  inline void clear_double_value();
+  static const int kDoubleValueFieldNumber = 6;
+  inline double double_value() const;
+  inline void set_double_value(double value);
+
+  // optional bytes string_value = 7;
+  inline bool has_string_value() const;
+  inline void clear_string_value();
+  static const int kStringValueFieldNumber = 7;
+  inline const ::std::string& string_value() const;
+  inline void set_string_value(const ::std::string& value);
+  inline void set_string_value(const char* value);
+  inline void set_string_value(const void* value, size_t size);
+  inline ::std::string* mutable_string_value();
+  inline ::std::string* release_string_value();
+  inline void set_allocated_string_value(::std::string* string_value);
+
+  // optional string aggregate_value = 8;
+  inline bool has_aggregate_value() const;
+  inline void clear_aggregate_value();
+  static const int kAggregateValueFieldNumber = 8;
+  inline const ::std::string& aggregate_value() const;
+  inline void set_aggregate_value(const ::std::string& value);
+  inline void set_aggregate_value(const char* value);
+  inline void set_aggregate_value(const char* value, size_t size);
+  inline ::std::string* mutable_aggregate_value();
+  inline ::std::string* release_aggregate_value();
+  inline void set_allocated_aggregate_value(::std::string* aggregate_value);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.UninterpretedOption)
+ private:
+  inline void set_has_identifier_value();
+  inline void clear_has_identifier_value();
+  inline void set_has_positive_int_value();
+  inline void clear_has_positive_int_value();
+  inline void set_has_negative_int_value();
+  inline void clear_has_negative_int_value();
+  inline void set_has_double_value();
+  inline void clear_has_double_value();
+  inline void set_has_string_value();
+  inline void clear_has_string_value();
+  inline void set_has_aggregate_value();
+  inline void clear_has_aggregate_value();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart > name_;
+  ::std::string* identifier_value_;
+  ::google::protobuf::uint64 positive_int_value_;
+  ::google::protobuf::int64 negative_int_value_;
+  double double_value_;
+  ::std::string* string_value_;
+  ::std::string* aggregate_value_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static UninterpretedOption* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Message {
+ public:
+  SourceCodeInfo_Location();
+  virtual ~SourceCodeInfo_Location();
+
+  SourceCodeInfo_Location(const SourceCodeInfo_Location& from);
+
+  inline SourceCodeInfo_Location& operator=(const SourceCodeInfo_Location& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const SourceCodeInfo_Location& default_instance();
+
+  void Swap(SourceCodeInfo_Location* other);
+
+  // implements Message ----------------------------------------------
+
+  SourceCodeInfo_Location* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const SourceCodeInfo_Location& from);
+  void MergeFrom(const SourceCodeInfo_Location& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated int32 path = 1 [packed = true];
+  inline int path_size() const;
+  inline void clear_path();
+  static const int kPathFieldNumber = 1;
+  inline ::google::protobuf::int32 path(int index) const;
+  inline void set_path(int index, ::google::protobuf::int32 value);
+  inline void add_path(::google::protobuf::int32 value);
+  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+      path() const;
+  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+      mutable_path();
+
+  // repeated int32 span = 2 [packed = true];
+  inline int span_size() const;
+  inline void clear_span();
+  static const int kSpanFieldNumber = 2;
+  inline ::google::protobuf::int32 span(int index) const;
+  inline void set_span(int index, ::google::protobuf::int32 value);
+  inline void add_span(::google::protobuf::int32 value);
+  inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+      span() const;
+  inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+      mutable_span();
+
+  // optional string leading_comments = 3;
+  inline bool has_leading_comments() const;
+  inline void clear_leading_comments();
+  static const int kLeadingCommentsFieldNumber = 3;
+  inline const ::std::string& leading_comments() const;
+  inline void set_leading_comments(const ::std::string& value);
+  inline void set_leading_comments(const char* value);
+  inline void set_leading_comments(const char* value, size_t size);
+  inline ::std::string* mutable_leading_comments();
+  inline ::std::string* release_leading_comments();
+  inline void set_allocated_leading_comments(::std::string* leading_comments);
+
+  // optional string trailing_comments = 4;
+  inline bool has_trailing_comments() const;
+  inline void clear_trailing_comments();
+  static const int kTrailingCommentsFieldNumber = 4;
+  inline const ::std::string& trailing_comments() const;
+  inline void set_trailing_comments(const ::std::string& value);
+  inline void set_trailing_comments(const char* value);
+  inline void set_trailing_comments(const char* value, size_t size);
+  inline ::std::string* mutable_trailing_comments();
+  inline ::std::string* release_trailing_comments();
+  inline void set_allocated_trailing_comments(::std::string* trailing_comments);
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo.Location)
+ private:
+  inline void set_has_leading_comments();
+  inline void clear_has_leading_comments();
+  inline void set_has_trailing_comments();
+  inline void clear_has_trailing_comments();
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > path_;
+  mutable int _path_cached_byte_size_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > span_;
+  mutable int _span_cached_byte_size_;
+  ::std::string* leading_comments_;
+  ::std::string* trailing_comments_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static SourceCodeInfo_Location* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message {
+ public:
+  SourceCodeInfo();
+  virtual ~SourceCodeInfo();
+
+  SourceCodeInfo(const SourceCodeInfo& from);
+
+  inline SourceCodeInfo& operator=(const SourceCodeInfo& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const SourceCodeInfo& default_instance();
+
+  void Swap(SourceCodeInfo* other);
+
+  // implements Message ----------------------------------------------
+
+  SourceCodeInfo* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const SourceCodeInfo& from);
+  void MergeFrom(const SourceCodeInfo& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  typedef SourceCodeInfo_Location Location;
+
+  // accessors -------------------------------------------------------
+
+  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+  inline int location_size() const;
+  inline void clear_location();
+  static const int kLocationFieldNumber = 1;
+  inline const ::google::protobuf::SourceCodeInfo_Location& location(int index) const;
+  inline ::google::protobuf::SourceCodeInfo_Location* mutable_location(int index);
+  inline ::google::protobuf::SourceCodeInfo_Location* add_location();
+  inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+      location() const;
+  inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+      mutable_location();
+
+  // @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
+ private:
+
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+
+  ::google::protobuf::uint32 _has_bits_[1];
+  mutable int _cached_size_;
+  ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location > location_;
+  friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
+  friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
+
+  void InitAsDefaultInstance();
+  static SourceCodeInfo* default_instance_;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+// FileDescriptorSet
+
+// repeated .google.protobuf.FileDescriptorProto file = 1;
+inline int FileDescriptorSet::file_size() const {
+  return file_.size();
+}
+inline void FileDescriptorSet::clear_file() {
+  file_.Clear();
+}
+inline const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorSet.file)
+  return file_.Get(index);
+}
+inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file)
+  return file_.Mutable(index);
+}
+inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file)
+  return file_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+FileDescriptorSet::file() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
+  return file_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+FileDescriptorSet::mutable_file() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file)
+  return &file_;
+}
+
+// -------------------------------------------------------------------
+
+// FileDescriptorProto
+
+// optional string name = 1;
+inline bool FileDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FileDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void FileDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void FileDescriptorProto::clear_name() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_->clear();
+  }
+  clear_has_name();
+}
+inline const ::std::string& FileDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.name)
+  return *name_;
+}
+inline void FileDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.name)
+}
+inline void FileDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name)
+}
+inline void FileDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.name)
+}
+inline ::std::string* FileDescriptorProto::mutable_name() {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.name)
+  return name_;
+}
+inline ::std::string* FileDescriptorProto::release_name() {
+  clear_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = name_;
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void FileDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (name) {
+    set_has_name();
+    name_ = name;
+  } else {
+    clear_has_name();
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.name)
+}
+
+// optional string package = 2;
+inline bool FileDescriptorProto::has_package() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FileDescriptorProto::set_has_package() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void FileDescriptorProto::clear_has_package() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void FileDescriptorProto::clear_package() {
+  if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    package_->clear();
+  }
+  clear_has_package();
+}
+inline const ::std::string& FileDescriptorProto::package() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.package)
+  return *package_;
+}
+inline void FileDescriptorProto::set_package(const ::std::string& value) {
+  set_has_package();
+  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    package_ = new ::std::string;
+  }
+  package_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.package)
+}
+inline void FileDescriptorProto::set_package(const char* value) {
+  set_has_package();
+  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    package_ = new ::std::string;
+  }
+  package_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package)
+}
+inline void FileDescriptorProto::set_package(const char* value, size_t size) {
+  set_has_package();
+  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    package_ = new ::std::string;
+  }
+  package_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.package)
+}
+inline ::std::string* FileDescriptorProto::mutable_package() {
+  set_has_package();
+  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    package_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.package)
+  return package_;
+}
+inline ::std::string* FileDescriptorProto::release_package() {
+  clear_has_package();
+  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = package_;
+    package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void FileDescriptorProto::set_allocated_package(::std::string* package) {
+  if (package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete package_;
+  }
+  if (package) {
+    set_has_package();
+    package_ = package;
+  } else {
+    clear_has_package();
+    package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.package)
+}
+
+// repeated string dependency = 3;
+inline int FileDescriptorProto::dependency_size() const {
+  return dependency_.size();
+}
+inline void FileDescriptorProto::clear_dependency() {
+  dependency_.Clear();
+}
+inline const ::std::string& FileDescriptorProto::dependency(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.dependency)
+  return dependency_.Get(index);
+}
+inline ::std::string* FileDescriptorProto::mutable_dependency(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.dependency)
+  return dependency_.Mutable(index);
+}
+inline void FileDescriptorProto::set_dependency(int index, const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
+  dependency_.Mutable(index)->assign(value);
+}
+inline void FileDescriptorProto::set_dependency(int index, const char* value) {
+  dependency_.Mutable(index)->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::set_dependency(int index, const char* value, size_t size) {
+  dependency_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.dependency)
+}
+inline ::std::string* FileDescriptorProto::add_dependency() {
+  return dependency_.Add();
+}
+inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
+  dependency_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::add_dependency(const char* value) {
+  dependency_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency)
+}
+inline void FileDescriptorProto::add_dependency(const char* value, size_t size) {
+  dependency_.Add()->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_add_pointer:google.protobuf.FileDescriptorProto.dependency)
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+FileDescriptorProto::dependency() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.dependency)
+  return dependency_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+FileDescriptorProto::mutable_dependency() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.dependency)
+  return &dependency_;
+}
+
+// repeated int32 public_dependency = 10;
+inline int FileDescriptorProto::public_dependency_size() const {
+  return public_dependency_.size();
+}
+inline void FileDescriptorProto::clear_public_dependency() {
+  public_dependency_.Clear();
+}
+inline ::google::protobuf::int32 FileDescriptorProto::public_dependency(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.public_dependency)
+  return public_dependency_.Get(index);
+}
+inline void FileDescriptorProto::set_public_dependency(int index, ::google::protobuf::int32 value) {
+  public_dependency_.Set(index, value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.public_dependency)
+}
+inline void FileDescriptorProto::add_public_dependency(::google::protobuf::int32 value) {
+  public_dependency_.Add(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.public_dependency)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+FileDescriptorProto::public_dependency() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.public_dependency)
+  return public_dependency_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+FileDescriptorProto::mutable_public_dependency() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.public_dependency)
+  return &public_dependency_;
+}
+
+// repeated int32 weak_dependency = 11;
+inline int FileDescriptorProto::weak_dependency_size() const {
+  return weak_dependency_.size();
+}
+inline void FileDescriptorProto::clear_weak_dependency() {
+  weak_dependency_.Clear();
+}
+inline ::google::protobuf::int32 FileDescriptorProto::weak_dependency(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.weak_dependency)
+  return weak_dependency_.Get(index);
+}
+inline void FileDescriptorProto::set_weak_dependency(int index, ::google::protobuf::int32 value) {
+  weak_dependency_.Set(index, value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.weak_dependency)
+}
+inline void FileDescriptorProto::add_weak_dependency(::google::protobuf::int32 value) {
+  weak_dependency_.Add(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.weak_dependency)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+FileDescriptorProto::weak_dependency() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.weak_dependency)
+  return weak_dependency_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+FileDescriptorProto::mutable_weak_dependency() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.weak_dependency)
+  return &weak_dependency_;
+}
+
+// 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::DescriptorProto& FileDescriptorProto::message_type(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.message_type)
+  return message_type_.Get(index);
+}
+inline ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.message_type)
+  return message_type_.Mutable(index);
+}
+inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.message_type)
+  return message_type_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+FileDescriptorProto::message_type() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type)
+  return message_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+FileDescriptorProto::mutable_message_type() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.message_type)
+  return &message_type_;
+}
+
+// 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::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.enum_type)
+  return enum_type_.Get(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.enum_type)
+  return enum_type_.Mutable(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.enum_type)
+  return enum_type_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+FileDescriptorProto::enum_type() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type)
+  return enum_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+FileDescriptorProto::mutable_enum_type() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.enum_type)
+  return &enum_type_;
+}
+
+// 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::ServiceDescriptorProto& FileDescriptorProto::service(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.service)
+  return service_.Get(index);
+}
+inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.service)
+  return service_.Mutable(index);
+}
+inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.service)
+  return service_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
+FileDescriptorProto::service() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service)
+  return service_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
+FileDescriptorProto::mutable_service() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.service)
+  return &service_;
+}
+
+// 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::FieldDescriptorProto& FileDescriptorProto::extension(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.extension)
+  return extension_.Get(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.extension)
+  return extension_.Mutable(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.extension)
+  return extension_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+FileDescriptorProto::extension() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension)
+  return extension_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+FileDescriptorProto::mutable_extension() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.extension)
+  return &extension_;
+}
+
+// optional .google.protobuf.FileOptions options = 8;
+inline bool FileDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000200u) != 0;
+}
+inline void FileDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000200u;
+}
+inline void FileDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000200u;
+}
+inline void FileDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
+  clear_has_options();
+}
+inline const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) options_ = new ::google::protobuf::FileOptions;
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options)
+  return options_;
+}
+inline ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::FileOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+inline void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.options)
+}
+
+// optional .google.protobuf.SourceCodeInfo source_code_info = 9;
+inline bool FileDescriptorProto::has_source_code_info() const {
+  return (_has_bits_[0] & 0x00000400u) != 0;
+}
+inline void FileDescriptorProto::set_has_source_code_info() {
+  _has_bits_[0] |= 0x00000400u;
+}
+inline void FileDescriptorProto::clear_has_source_code_info() {
+  _has_bits_[0] &= ~0x00000400u;
+}
+inline void FileDescriptorProto::clear_source_code_info() {
+  if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
+  clear_has_source_code_info();
+}
+inline const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info)
+  return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_;
+}
+inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
+  set_has_source_code_info();
+  if (source_code_info_ == NULL) source_code_info_ = new ::google::protobuf::SourceCodeInfo;
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info)
+  return source_code_info_;
+}
+inline ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
+  clear_has_source_code_info();
+  ::google::protobuf::SourceCodeInfo* temp = source_code_info_;
+  source_code_info_ = NULL;
+  return temp;
+}
+inline void FileDescriptorProto::set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info) {
+  delete source_code_info_;
+  source_code_info_ = source_code_info;
+  if (source_code_info) {
+    set_has_source_code_info();
+  } else {
+    clear_has_source_code_info();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileDescriptorProto.source_code_info)
+}
+
+// -------------------------------------------------------------------
+
+// DescriptorProto_ExtensionRange
+
+// optional int32 start = 1;
+inline bool DescriptorProto_ExtensionRange::has_start() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void DescriptorProto_ExtensionRange::set_has_start() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void DescriptorProto_ExtensionRange::clear_has_start() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void DescriptorProto_ExtensionRange::clear_start() {
+  start_ = 0;
+  clear_has_start();
+}
+inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::start() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.start)
+  return start_;
+}
+inline void DescriptorProto_ExtensionRange::set_start(::google::protobuf::int32 value) {
+  set_has_start();
+  start_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.start)
+}
+
+// optional int32 end = 2;
+inline bool DescriptorProto_ExtensionRange::has_end() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void DescriptorProto_ExtensionRange::set_has_end() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void DescriptorProto_ExtensionRange::clear_has_end() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void DescriptorProto_ExtensionRange::clear_end() {
+  end_ = 0;
+  clear_has_end();
+}
+inline ::google::protobuf::int32 DescriptorProto_ExtensionRange::end() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ExtensionRange.end)
+  return end_;
+}
+inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 value) {
+  set_has_end();
+  end_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ExtensionRange.end)
+}
+
+// -------------------------------------------------------------------
+
+// DescriptorProto
+
+// optional string name = 1;
+inline bool DescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void DescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void DescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void DescriptorProto::clear_name() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_->clear();
+  }
+  clear_has_name();
+}
+inline const ::std::string& DescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.name)
+  return *name_;
+}
+inline void DescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.name)
+}
+inline void DescriptorProto::set_name(const char* value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name)
+}
+inline void DescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.name)
+}
+inline ::std::string* DescriptorProto::mutable_name() {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.name)
+  return name_;
+}
+inline ::std::string* DescriptorProto::release_name() {
+  clear_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = name_;
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void DescriptorProto::set_allocated_name(::std::string* name) {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (name) {
+    set_has_name();
+    name_ = name;
+  } else {
+    clear_has_name();
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.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::FieldDescriptorProto& DescriptorProto::field(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.field)
+  return field_.Get(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field)
+  return field_.Mutable(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field)
+  return field_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::field() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
+  return field_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+DescriptorProto::mutable_field() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field)
+  return &field_;
+}
+
+// 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::FieldDescriptorProto& DescriptorProto::extension(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension)
+  return extension_.Get(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension)
+  return extension_.Mutable(index);
+}
+inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension)
+  return extension_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::extension() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension)
+  return extension_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+DescriptorProto::mutable_extension() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension)
+  return &extension_;
+}
+
+// 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::DescriptorProto& DescriptorProto::nested_type(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.nested_type)
+  return nested_type_.Get(index);
+}
+inline ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.nested_type)
+  return nested_type_.Mutable(index);
+}
+inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.nested_type)
+  return nested_type_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+DescriptorProto::nested_type() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type)
+  return nested_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+DescriptorProto::mutable_nested_type() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.nested_type)
+  return &nested_type_;
+}
+
+// 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::EnumDescriptorProto& DescriptorProto::enum_type(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.enum_type)
+  return enum_type_.Get(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.enum_type)
+  return enum_type_.Mutable(index);
+}
+inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.enum_type)
+  return enum_type_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+DescriptorProto::enum_type() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type)
+  return enum_type_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+DescriptorProto::mutable_enum_type() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.enum_type)
+  return &enum_type_;
+}
+
+// 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::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension_range)
+  return extension_range_.Get(index);
+}
+inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension_range)
+  return extension_range_.Mutable(index);
+}
+inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension_range)
+  return extension_range_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
+DescriptorProto::extension_range() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range)
+  return extension_range_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
+DescriptorProto::mutable_extension_range() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension_range)
+  return &extension_range_;
+}
+
+// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
+inline int DescriptorProto::oneof_decl_size() const {
+  return oneof_decl_.size();
+}
+inline void DescriptorProto::clear_oneof_decl() {
+  oneof_decl_.Clear();
+}
+inline const ::google::protobuf::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.oneof_decl)
+  return oneof_decl_.Get(index);
+}
+inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.oneof_decl)
+  return oneof_decl_.Mutable(index);
+}
+inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::add_oneof_decl() {
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl)
+  return oneof_decl_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
+DescriptorProto::oneof_decl() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
+  return oneof_decl_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
+DescriptorProto::mutable_oneof_decl() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl)
+  return &oneof_decl_;
+}
+
+// optional .google.protobuf.MessageOptions options = 7;
+inline bool DescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void DescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000080u;
+}
+inline void DescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000080u;
+}
+inline void DescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
+  clear_has_options();
+}
+inline const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) options_ = new ::google::protobuf::MessageOptions;
+  // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options)
+  return options_;
+}
+inline ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::MessageOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options)
+}
+
+// -------------------------------------------------------------------
+
+// FieldDescriptorProto
+
+// optional string name = 1;
+inline bool FieldDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FieldDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void FieldDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void FieldDescriptorProto::clear_name() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_->clear();
+  }
+  clear_has_name();
+}
+inline const ::std::string& FieldDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.name)
+  return *name_;
+}
+inline void FieldDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.name)
+}
+inline void FieldDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name)
+}
+inline void FieldDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.name)
+}
+inline ::std::string* FieldDescriptorProto::mutable_name() {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.name)
+  return name_;
+}
+inline ::std::string* FieldDescriptorProto::release_name() {
+  clear_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = name_;
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void FieldDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (name) {
+    set_has_name();
+    name_ = name;
+  } else {
+    clear_has_name();
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.name)
+}
+
+// optional int32 number = 3;
+inline bool FieldDescriptorProto::has_number() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FieldDescriptorProto::set_has_number() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void FieldDescriptorProto::clear_has_number() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void FieldDescriptorProto::clear_number() {
+  number_ = 0;
+  clear_has_number();
+}
+inline ::google::protobuf::int32 FieldDescriptorProto::number() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.number)
+  return number_;
+}
+inline void FieldDescriptorProto::set_number(::google::protobuf::int32 value) {
+  set_has_number();
+  number_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.number)
+}
+
+// optional .google.protobuf.FieldDescriptorProto.Label label = 4;
+inline bool FieldDescriptorProto::has_label() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FieldDescriptorProto::set_has_label() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void FieldDescriptorProto::clear_has_label() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void FieldDescriptorProto::clear_label() {
+  label_ = 1;
+  clear_has_label();
+}
+inline ::google::protobuf::FieldDescriptorProto_Label FieldDescriptorProto::label() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.label)
+  return static_cast< ::google::protobuf::FieldDescriptorProto_Label >(label_);
+}
+inline void FieldDescriptorProto::set_label(::google::protobuf::FieldDescriptorProto_Label value) {
+  assert(::google::protobuf::FieldDescriptorProto_Label_IsValid(value));
+  set_has_label();
+  label_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.label)
+}
+
+// optional .google.protobuf.FieldDescriptorProto.Type type = 5;
+inline bool FieldDescriptorProto::has_type() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FieldDescriptorProto::set_has_type() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void FieldDescriptorProto::clear_has_type() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void FieldDescriptorProto::clear_type() {
+  type_ = 1;
+  clear_has_type();
+}
+inline ::google::protobuf::FieldDescriptorProto_Type FieldDescriptorProto::type() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type)
+  return static_cast< ::google::protobuf::FieldDescriptorProto_Type >(type_);
+}
+inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Type value) {
+  assert(::google::protobuf::FieldDescriptorProto_Type_IsValid(value));
+  set_has_type();
+  type_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type)
+}
+
+// optional string type_name = 6;
+inline bool FieldDescriptorProto::has_type_name() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void FieldDescriptorProto::set_has_type_name() {
+  _has_bits_[0] |= 0x00000010u;
+}
+inline void FieldDescriptorProto::clear_has_type_name() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+inline void FieldDescriptorProto::clear_type_name() {
+  if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    type_name_->clear();
+  }
+  clear_has_type_name();
+}
+inline const ::std::string& FieldDescriptorProto::type_name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.type_name)
+  return *type_name_;
+}
+inline void FieldDescriptorProto::set_type_name(const ::std::string& value) {
+  set_has_type_name();
+  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    type_name_ = new ::std::string;
+  }
+  type_name_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.type_name)
+}
+inline void FieldDescriptorProto::set_type_name(const char* value) {
+  set_has_type_name();
+  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    type_name_ = new ::std::string;
+  }
+  type_name_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name)
+}
+inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) {
+  set_has_type_name();
+  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    type_name_ = new ::std::string;
+  }
+  type_name_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.type_name)
+}
+inline ::std::string* FieldDescriptorProto::mutable_type_name() {
+  set_has_type_name();
+  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    type_name_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.type_name)
+  return type_name_;
+}
+inline ::std::string* FieldDescriptorProto::release_type_name() {
+  clear_has_type_name();
+  if (type_name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = type_name_;
+    type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void FieldDescriptorProto::set_allocated_type_name(::std::string* type_name) {
+  if (type_name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete type_name_;
+  }
+  if (type_name) {
+    set_has_type_name();
+    type_name_ = type_name;
+  } else {
+    clear_has_type_name();
+    type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.type_name)
+}
+
+// optional string extendee = 2;
+inline bool FieldDescriptorProto::has_extendee() const {
+  return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void FieldDescriptorProto::set_has_extendee() {
+  _has_bits_[0] |= 0x00000020u;
+}
+inline void FieldDescriptorProto::clear_has_extendee() {
+  _has_bits_[0] &= ~0x00000020u;
+}
+inline void FieldDescriptorProto::clear_extendee() {
+  if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    extendee_->clear();
+  }
+  clear_has_extendee();
+}
+inline const ::std::string& FieldDescriptorProto::extendee() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.extendee)
+  return *extendee_;
+}
+inline void FieldDescriptorProto::set_extendee(const ::std::string& value) {
+  set_has_extendee();
+  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    extendee_ = new ::std::string;
+  }
+  extendee_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.extendee)
+}
+inline void FieldDescriptorProto::set_extendee(const char* value) {
+  set_has_extendee();
+  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    extendee_ = new ::std::string;
+  }
+  extendee_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee)
+}
+inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) {
+  set_has_extendee();
+  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    extendee_ = new ::std::string;
+  }
+  extendee_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.extendee)
+}
+inline ::std::string* FieldDescriptorProto::mutable_extendee() {
+  set_has_extendee();
+  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    extendee_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.extendee)
+  return extendee_;
+}
+inline ::std::string* FieldDescriptorProto::release_extendee() {
+  clear_has_extendee();
+  if (extendee_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = extendee_;
+    extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void FieldDescriptorProto::set_allocated_extendee(::std::string* extendee) {
+  if (extendee_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete extendee_;
+  }
+  if (extendee) {
+    set_has_extendee();
+    extendee_ = extendee;
+  } else {
+    clear_has_extendee();
+    extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.extendee)
+}
+
+// optional string default_value = 7;
+inline bool FieldDescriptorProto::has_default_value() const {
+  return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void FieldDescriptorProto::set_has_default_value() {
+  _has_bits_[0] |= 0x00000040u;
+}
+inline void FieldDescriptorProto::clear_has_default_value() {
+  _has_bits_[0] &= ~0x00000040u;
+}
+inline void FieldDescriptorProto::clear_default_value() {
+  if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    default_value_->clear();
+  }
+  clear_has_default_value();
+}
+inline const ::std::string& FieldDescriptorProto::default_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.default_value)
+  return *default_value_;
+}
+inline void FieldDescriptorProto::set_default_value(const ::std::string& value) {
+  set_has_default_value();
+  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    default_value_ = new ::std::string;
+  }
+  default_value_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.default_value)
+}
+inline void FieldDescriptorProto::set_default_value(const char* value) {
+  set_has_default_value();
+  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    default_value_ = new ::std::string;
+  }
+  default_value_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value)
+}
+inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) {
+  set_has_default_value();
+  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    default_value_ = new ::std::string;
+  }
+  default_value_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.default_value)
+}
+inline ::std::string* FieldDescriptorProto::mutable_default_value() {
+  set_has_default_value();
+  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    default_value_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.default_value)
+  return default_value_;
+}
+inline ::std::string* FieldDescriptorProto::release_default_value() {
+  clear_has_default_value();
+  if (default_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = default_value_;
+    default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void FieldDescriptorProto::set_allocated_default_value(::std::string* default_value) {
+  if (default_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete default_value_;
+  }
+  if (default_value) {
+    set_has_default_value();
+    default_value_ = default_value;
+  } else {
+    clear_has_default_value();
+    default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.default_value)
+}
+
+// optional int32 oneof_index = 9;
+inline bool FieldDescriptorProto::has_oneof_index() const {
+  return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FieldDescriptorProto::set_has_oneof_index() {
+  _has_bits_[0] |= 0x00000080u;
+}
+inline void FieldDescriptorProto::clear_has_oneof_index() {
+  _has_bits_[0] &= ~0x00000080u;
+}
+inline void FieldDescriptorProto::clear_oneof_index() {
+  oneof_index_ = 0;
+  clear_has_oneof_index();
+}
+inline ::google::protobuf::int32 FieldDescriptorProto::oneof_index() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.oneof_index)
+  return oneof_index_;
+}
+inline void FieldDescriptorProto::set_oneof_index(::google::protobuf::int32 value) {
+  set_has_oneof_index();
+  oneof_index_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldDescriptorProto.oneof_index)
+}
+
+// optional .google.protobuf.FieldOptions options = 8;
+inline bool FieldDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000100u) != 0;
+}
+inline void FieldDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000100u;
+}
+inline void FieldDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000100u;
+}
+inline void FieldDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
+  clear_has_options();
+}
+inline const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) options_ = new ::google::protobuf::FieldOptions;
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options)
+  return options_;
+}
+inline ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::FieldOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+inline void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldDescriptorProto.options)
+}
+
+// -------------------------------------------------------------------
+
+// OneofDescriptorProto
+
+// optional string name = 1;
+inline bool OneofDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void OneofDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void OneofDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void OneofDescriptorProto::clear_name() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_->clear();
+  }
+  clear_has_name();
+}
+inline const ::std::string& OneofDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.OneofDescriptorProto.name)
+  return *name_;
+}
+inline void OneofDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.OneofDescriptorProto.name)
+}
+inline void OneofDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name)
+}
+inline void OneofDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.OneofDescriptorProto.name)
+}
+inline ::std::string* OneofDescriptorProto::mutable_name() {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.OneofDescriptorProto.name)
+  return name_;
+}
+inline ::std::string* OneofDescriptorProto::release_name() {
+  clear_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = name_;
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void OneofDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (name) {
+    set_has_name();
+    name_ = name;
+  } else {
+    clear_has_name();
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.OneofDescriptorProto.name)
+}
+
+// -------------------------------------------------------------------
+
+// EnumDescriptorProto
+
+// optional string name = 1;
+inline bool EnumDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void EnumDescriptorProto::clear_name() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_->clear();
+  }
+  clear_has_name();
+}
+inline const ::std::string& EnumDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.name)
+  return *name_;
+}
+inline void EnumDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumDescriptorProto.name)
+}
+inline void EnumDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name)
+}
+inline void EnumDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.name)
+}
+inline ::std::string* EnumDescriptorProto::mutable_name() {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.name)
+  return name_;
+}
+inline ::std::string* EnumDescriptorProto::release_name() {
+  clear_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = name_;
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void EnumDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (name) {
+    set_has_name();
+    name_ = name;
+  } else {
+    clear_has_name();
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.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::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.value)
+  return value_.Get(index);
+}
+inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value)
+  return value_.Mutable(index);
+}
+inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
+  // @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value)
+  return value_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
+EnumDescriptorProto::value() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
+  return value_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
+EnumDescriptorProto::mutable_value() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value)
+  return &value_;
+}
+
+// optional .google.protobuf.EnumOptions options = 3;
+inline bool EnumDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void EnumDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void EnumDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void EnumDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
+  clear_has_options();
+}
+inline const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) options_ = new ::google::protobuf::EnumOptions;
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options)
+  return options_;
+}
+inline ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::EnumOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+inline void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumDescriptorProto.options)
+}
+
+// -------------------------------------------------------------------
+
+// EnumValueDescriptorProto
+
+// optional string name = 1;
+inline bool EnumValueDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumValueDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void EnumValueDescriptorProto::clear_name() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_->clear();
+  }
+  clear_has_name();
+}
+inline const ::std::string& EnumValueDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.name)
+  return *name_;
+}
+inline void EnumValueDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.name)
+}
+inline void EnumValueDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name)
+}
+inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValueDescriptorProto.name)
+}
+inline ::std::string* EnumValueDescriptorProto::mutable_name() {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.name)
+  return name_;
+}
+inline ::std::string* EnumValueDescriptorProto::release_name() {
+  clear_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = name_;
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void EnumValueDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (name) {
+    set_has_name();
+    name_ = name;
+  } else {
+    clear_has_name();
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.name)
+}
+
+// optional int32 number = 2;
+inline bool EnumValueDescriptorProto::has_number() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_number() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void EnumValueDescriptorProto::clear_has_number() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void EnumValueDescriptorProto::clear_number() {
+  number_ = 0;
+  clear_has_number();
+}
+inline ::google::protobuf::int32 EnumValueDescriptorProto::number() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.number)
+  return number_;
+}
+inline void EnumValueDescriptorProto::set_number(::google::protobuf::int32 value) {
+  set_has_number();
+  number_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueDescriptorProto.number)
+}
+
+// optional .google.protobuf.EnumValueOptions options = 3;
+inline bool EnumValueDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void EnumValueDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void EnumValueDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void EnumValueDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
+  clear_has_options();
+}
+inline const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) options_ = new ::google::protobuf::EnumValueOptions;
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options)
+  return options_;
+}
+inline ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::EnumValueOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+inline void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValueDescriptorProto.options)
+}
+
+// -------------------------------------------------------------------
+
+// ServiceDescriptorProto
+
+// optional string name = 1;
+inline bool ServiceDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void ServiceDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void ServiceDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void ServiceDescriptorProto::clear_name() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_->clear();
+  }
+  clear_has_name();
+}
+inline const ::std::string& ServiceDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.name)
+  return *name_;
+}
+inline void ServiceDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.ServiceDescriptorProto.name)
+}
+inline void ServiceDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name)
+}
+inline void ServiceDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.ServiceDescriptorProto.name)
+}
+inline ::std::string* ServiceDescriptorProto::mutable_name() {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.name)
+  return name_;
+}
+inline ::std::string* ServiceDescriptorProto::release_name() {
+  clear_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = name_;
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void ServiceDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (name) {
+    set_has_name();
+    name_ = name;
+  } else {
+    clear_has_name();
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.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::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.method)
+  return method_.Get(index);
+}
+inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method)
+  return method_.Mutable(index);
+}
+inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
+  // @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method)
+  return method_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
+ServiceDescriptorProto::method() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
+  return method_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
+ServiceDescriptorProto::mutable_method() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method)
+  return &method_;
+}
+
+// optional .google.protobuf.ServiceOptions options = 3;
+inline bool ServiceDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void ServiceDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void ServiceDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void ServiceDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
+  clear_has_options();
+}
+inline const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) options_ = new ::google::protobuf::ServiceOptions;
+  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options)
+  return options_;
+}
+inline ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::ServiceOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+inline void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.ServiceDescriptorProto.options)
+}
+
+// -------------------------------------------------------------------
+
+// MethodDescriptorProto
+
+// optional string name = 1;
+inline bool MethodDescriptorProto::has_name() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MethodDescriptorProto::set_has_name() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void MethodDescriptorProto::clear_has_name() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void MethodDescriptorProto::clear_name() {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_->clear();
+  }
+  clear_has_name();
+}
+inline const ::std::string& MethodDescriptorProto::name() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.name)
+  return *name_;
+}
+inline void MethodDescriptorProto::set_name(const ::std::string& value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.name)
+}
+inline void MethodDescriptorProto::set_name(const char* value) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name)
+}
+inline void MethodDescriptorProto::set_name(const char* value, size_t size) {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  name_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.name)
+}
+inline ::std::string* MethodDescriptorProto::mutable_name() {
+  set_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.name)
+  return name_;
+}
+inline ::std::string* MethodDescriptorProto::release_name() {
+  clear_has_name();
+  if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = name_;
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void MethodDescriptorProto::set_allocated_name(::std::string* name) {
+  if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_;
+  }
+  if (name) {
+    set_has_name();
+    name_ = name;
+  } else {
+    clear_has_name();
+    name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.name)
+}
+
+// optional string input_type = 2;
+inline bool MethodDescriptorProto::has_input_type() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void MethodDescriptorProto::set_has_input_type() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void MethodDescriptorProto::clear_has_input_type() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void MethodDescriptorProto::clear_input_type() {
+  if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    input_type_->clear();
+  }
+  clear_has_input_type();
+}
+inline const ::std::string& MethodDescriptorProto::input_type() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.input_type)
+  return *input_type_;
+}
+inline void MethodDescriptorProto::set_input_type(const ::std::string& value) {
+  set_has_input_type();
+  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    input_type_ = new ::std::string;
+  }
+  input_type_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.input_type)
+}
+inline void MethodDescriptorProto::set_input_type(const char* value) {
+  set_has_input_type();
+  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    input_type_ = new ::std::string;
+  }
+  input_type_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type)
+}
+inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) {
+  set_has_input_type();
+  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    input_type_ = new ::std::string;
+  }
+  input_type_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.input_type)
+}
+inline ::std::string* MethodDescriptorProto::mutable_input_type() {
+  set_has_input_type();
+  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    input_type_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.input_type)
+  return input_type_;
+}
+inline ::std::string* MethodDescriptorProto::release_input_type() {
+  clear_has_input_type();
+  if (input_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = input_type_;
+    input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void MethodDescriptorProto::set_allocated_input_type(::std::string* input_type) {
+  if (input_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete input_type_;
+  }
+  if (input_type) {
+    set_has_input_type();
+    input_type_ = input_type;
+  } else {
+    clear_has_input_type();
+    input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.input_type)
+}
+
+// optional string output_type = 3;
+inline bool MethodDescriptorProto::has_output_type() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void MethodDescriptorProto::set_has_output_type() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void MethodDescriptorProto::clear_has_output_type() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void MethodDescriptorProto::clear_output_type() {
+  if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    output_type_->clear();
+  }
+  clear_has_output_type();
+}
+inline const ::std::string& MethodDescriptorProto::output_type() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.output_type)
+  return *output_type_;
+}
+inline void MethodDescriptorProto::set_output_type(const ::std::string& value) {
+  set_has_output_type();
+  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    output_type_ = new ::std::string;
+  }
+  output_type_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.MethodDescriptorProto.output_type)
+}
+inline void MethodDescriptorProto::set_output_type(const char* value) {
+  set_has_output_type();
+  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    output_type_ = new ::std::string;
+  }
+  output_type_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type)
+}
+inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) {
+  set_has_output_type();
+  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    output_type_ = new ::std::string;
+  }
+  output_type_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.output_type)
+}
+inline ::std::string* MethodDescriptorProto::mutable_output_type() {
+  set_has_output_type();
+  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    output_type_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.output_type)
+  return output_type_;
+}
+inline ::std::string* MethodDescriptorProto::release_output_type() {
+  clear_has_output_type();
+  if (output_type_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = output_type_;
+    output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void MethodDescriptorProto::set_allocated_output_type(::std::string* output_type) {
+  if (output_type_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete output_type_;
+  }
+  if (output_type) {
+    set_has_output_type();
+    output_type_ = output_type;
+  } else {
+    clear_has_output_type();
+    output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.output_type)
+}
+
+// optional .google.protobuf.MethodOptions options = 4;
+inline bool MethodDescriptorProto::has_options() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void MethodDescriptorProto::set_has_options() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void MethodDescriptorProto::clear_has_options() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void MethodDescriptorProto::clear_options() {
+  if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
+  clear_has_options();
+}
+inline const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options)
+  return options_ != NULL ? *options_ : *default_instance_->options_;
+}
+inline ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
+  set_has_options();
+  if (options_ == NULL) options_ = new ::google::protobuf::MethodOptions;
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options)
+  return options_;
+}
+inline ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
+  clear_has_options();
+  ::google::protobuf::MethodOptions* temp = options_;
+  options_ = NULL;
+  return temp;
+}
+inline void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* options) {
+  delete options_;
+  options_ = options;
+  if (options) {
+    set_has_options();
+  } else {
+    clear_has_options();
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.MethodDescriptorProto.options)
+}
+
+// -------------------------------------------------------------------
+
+// FileOptions
+
+// optional string java_package = 1;
+inline bool FileOptions::has_java_package() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FileOptions::set_has_java_package() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void FileOptions::clear_has_java_package() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void FileOptions::clear_java_package() {
+  if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    java_package_->clear();
+  }
+  clear_has_java_package();
+}
+inline const ::std::string& FileOptions::java_package() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_package)
+  return *java_package_;
+}
+inline void FileOptions::set_java_package(const ::std::string& value) {
+  set_has_java_package();
+  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    java_package_ = new ::std::string;
+  }
+  java_package_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_package)
+}
+inline void FileOptions::set_java_package(const char* value) {
+  set_has_java_package();
+  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    java_package_ = new ::std::string;
+  }
+  java_package_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package)
+}
+inline void FileOptions::set_java_package(const char* value, size_t size) {
+  set_has_java_package();
+  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    java_package_ = new ::std::string;
+  }
+  java_package_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_package)
+}
+inline ::std::string* FileOptions::mutable_java_package() {
+  set_has_java_package();
+  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    java_package_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_package)
+  return java_package_;
+}
+inline ::std::string* FileOptions::release_java_package() {
+  clear_has_java_package();
+  if (java_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = java_package_;
+    java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void FileOptions::set_allocated_java_package(::std::string* java_package) {
+  if (java_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete java_package_;
+  }
+  if (java_package) {
+    set_has_java_package();
+    java_package_ = java_package;
+  } else {
+    clear_has_java_package();
+    java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_package)
+}
+
+// optional string java_outer_classname = 8;
+inline bool FileOptions::has_java_outer_classname() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FileOptions::set_has_java_outer_classname() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void FileOptions::clear_has_java_outer_classname() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void FileOptions::clear_java_outer_classname() {
+  if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    java_outer_classname_->clear();
+  }
+  clear_has_java_outer_classname();
+}
+inline const ::std::string& FileOptions::java_outer_classname() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_outer_classname)
+  return *java_outer_classname_;
+}
+inline void FileOptions::set_java_outer_classname(const ::std::string& value) {
+  set_has_java_outer_classname();
+  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    java_outer_classname_ = new ::std::string;
+  }
+  java_outer_classname_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_outer_classname)
+}
+inline void FileOptions::set_java_outer_classname(const char* value) {
+  set_has_java_outer_classname();
+  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    java_outer_classname_ = new ::std::string;
+  }
+  java_outer_classname_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname)
+}
+inline void FileOptions::set_java_outer_classname(const char* value, size_t size) {
+  set_has_java_outer_classname();
+  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    java_outer_classname_ = new ::std::string;
+  }
+  java_outer_classname_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_outer_classname)
+}
+inline ::std::string* FileOptions::mutable_java_outer_classname() {
+  set_has_java_outer_classname();
+  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    java_outer_classname_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.java_outer_classname)
+  return java_outer_classname_;
+}
+inline ::std::string* FileOptions::release_java_outer_classname() {
+  clear_has_java_outer_classname();
+  if (java_outer_classname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = java_outer_classname_;
+    java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void FileOptions::set_allocated_java_outer_classname(::std::string* java_outer_classname) {
+  if (java_outer_classname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete java_outer_classname_;
+  }
+  if (java_outer_classname) {
+    set_has_java_outer_classname();
+    java_outer_classname_ = java_outer_classname;
+  } else {
+    clear_has_java_outer_classname();
+    java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.java_outer_classname)
+}
+
+// optional bool java_multiple_files = 10 [default = false];
+inline bool FileOptions::has_java_multiple_files() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FileOptions::set_has_java_multiple_files() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void FileOptions::clear_has_java_multiple_files() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void FileOptions::clear_java_multiple_files() {
+  java_multiple_files_ = false;
+  clear_has_java_multiple_files();
+}
+inline bool FileOptions::java_multiple_files() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_multiple_files)
+  return java_multiple_files_;
+}
+inline void FileOptions::set_java_multiple_files(bool value) {
+  set_has_java_multiple_files();
+  java_multiple_files_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_multiple_files)
+}
+
+// optional bool java_generate_equals_and_hash = 20 [default = false];
+inline bool FileOptions::has_java_generate_equals_and_hash() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FileOptions::set_has_java_generate_equals_and_hash() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void FileOptions::clear_has_java_generate_equals_and_hash() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void FileOptions::clear_java_generate_equals_and_hash() {
+  java_generate_equals_and_hash_ = false;
+  clear_has_java_generate_equals_and_hash();
+}
+inline bool FileOptions::java_generate_equals_and_hash() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generate_equals_and_hash)
+  return java_generate_equals_and_hash_;
+}
+inline void FileOptions::set_java_generate_equals_and_hash(bool value) {
+  set_has_java_generate_equals_and_hash();
+  java_generate_equals_and_hash_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generate_equals_and_hash)
+}
+
+// optional bool java_string_check_utf8 = 27 [default = false];
+inline bool FileOptions::has_java_string_check_utf8() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void FileOptions::set_has_java_string_check_utf8() {
+  _has_bits_[0] |= 0x00000010u;
+}
+inline void FileOptions::clear_has_java_string_check_utf8() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+inline void FileOptions::clear_java_string_check_utf8() {
+  java_string_check_utf8_ = false;
+  clear_has_java_string_check_utf8();
+}
+inline bool FileOptions::java_string_check_utf8() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_string_check_utf8)
+  return java_string_check_utf8_;
+}
+inline void FileOptions::set_java_string_check_utf8(bool value) {
+  set_has_java_string_check_utf8();
+  java_string_check_utf8_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_string_check_utf8)
+}
+
+// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
+inline bool FileOptions::has_optimize_for() const {
+  return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void FileOptions::set_has_optimize_for() {
+  _has_bits_[0] |= 0x00000020u;
+}
+inline void FileOptions::clear_has_optimize_for() {
+  _has_bits_[0] &= ~0x00000020u;
+}
+inline void FileOptions::clear_optimize_for() {
+  optimize_for_ = 1;
+  clear_has_optimize_for();
+}
+inline ::google::protobuf::FileOptions_OptimizeMode FileOptions::optimize_for() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.optimize_for)
+  return static_cast< ::google::protobuf::FileOptions_OptimizeMode >(optimize_for_);
+}
+inline void FileOptions::set_optimize_for(::google::protobuf::FileOptions_OptimizeMode value) {
+  assert(::google::protobuf::FileOptions_OptimizeMode_IsValid(value));
+  set_has_optimize_for();
+  optimize_for_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.optimize_for)
+}
+
+// optional string go_package = 11;
+inline bool FileOptions::has_go_package() const {
+  return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void FileOptions::set_has_go_package() {
+  _has_bits_[0] |= 0x00000040u;
+}
+inline void FileOptions::clear_has_go_package() {
+  _has_bits_[0] &= ~0x00000040u;
+}
+inline void FileOptions::clear_go_package() {
+  if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    go_package_->clear();
+  }
+  clear_has_go_package();
+}
+inline const ::std::string& FileOptions::go_package() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.go_package)
+  return *go_package_;
+}
+inline void FileOptions::set_go_package(const ::std::string& value) {
+  set_has_go_package();
+  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    go_package_ = new ::std::string;
+  }
+  go_package_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.go_package)
+}
+inline void FileOptions::set_go_package(const char* value) {
+  set_has_go_package();
+  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    go_package_ = new ::std::string;
+  }
+  go_package_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package)
+}
+inline void FileOptions::set_go_package(const char* value, size_t size) {
+  set_has_go_package();
+  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    go_package_ = new ::std::string;
+  }
+  go_package_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.go_package)
+}
+inline ::std::string* FileOptions::mutable_go_package() {
+  set_has_go_package();
+  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    go_package_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.go_package)
+  return go_package_;
+}
+inline ::std::string* FileOptions::release_go_package() {
+  clear_has_go_package();
+  if (go_package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = go_package_;
+    go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void FileOptions::set_allocated_go_package(::std::string* go_package) {
+  if (go_package_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete go_package_;
+  }
+  if (go_package) {
+    set_has_go_package();
+    go_package_ = go_package;
+  } else {
+    clear_has_go_package();
+    go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.go_package)
+}
+
+// optional bool cc_generic_services = 16 [default = false];
+inline bool FileOptions::has_cc_generic_services() const {
+  return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void FileOptions::set_has_cc_generic_services() {
+  _has_bits_[0] |= 0x00000080u;
+}
+inline void FileOptions::clear_has_cc_generic_services() {
+  _has_bits_[0] &= ~0x00000080u;
+}
+inline void FileOptions::clear_cc_generic_services() {
+  cc_generic_services_ = false;
+  clear_has_cc_generic_services();
+}
+inline bool FileOptions::cc_generic_services() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.cc_generic_services)
+  return cc_generic_services_;
+}
+inline void FileOptions::set_cc_generic_services(bool value) {
+  set_has_cc_generic_services();
+  cc_generic_services_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.cc_generic_services)
+}
+
+// optional bool java_generic_services = 17 [default = false];
+inline bool FileOptions::has_java_generic_services() const {
+  return (_has_bits_[0] & 0x00000100u) != 0;
+}
+inline void FileOptions::set_has_java_generic_services() {
+  _has_bits_[0] |= 0x00000100u;
+}
+inline void FileOptions::clear_has_java_generic_services() {
+  _has_bits_[0] &= ~0x00000100u;
+}
+inline void FileOptions::clear_java_generic_services() {
+  java_generic_services_ = false;
+  clear_has_java_generic_services();
+}
+inline bool FileOptions::java_generic_services() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.java_generic_services)
+  return java_generic_services_;
+}
+inline void FileOptions::set_java_generic_services(bool value) {
+  set_has_java_generic_services();
+  java_generic_services_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.java_generic_services)
+}
+
+// optional bool py_generic_services = 18 [default = false];
+inline bool FileOptions::has_py_generic_services() const {
+  return (_has_bits_[0] & 0x00000200u) != 0;
+}
+inline void FileOptions::set_has_py_generic_services() {
+  _has_bits_[0] |= 0x00000200u;
+}
+inline void FileOptions::clear_has_py_generic_services() {
+  _has_bits_[0] &= ~0x00000200u;
+}
+inline void FileOptions::clear_py_generic_services() {
+  py_generic_services_ = false;
+  clear_has_py_generic_services();
+}
+inline bool FileOptions::py_generic_services() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.py_generic_services)
+  return py_generic_services_;
+}
+inline void FileOptions::set_py_generic_services(bool value) {
+  set_has_py_generic_services();
+  py_generic_services_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.py_generic_services)
+}
+
+// optional bool deprecated = 23 [default = false];
+inline bool FileOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000400u) != 0;
+}
+inline void FileOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000400u;
+}
+inline void FileOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000400u;
+}
+inline void FileOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+inline bool FileOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.deprecated)
+  return deprecated_;
+}
+inline void FileOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.deprecated)
+}
+
+// optional bool javanano_use_deprecated_package = 38;
+inline bool FileOptions::has_javanano_use_deprecated_package() const {
+  return (_has_bits_[0] & 0x00000800u) != 0;
+}
+inline void FileOptions::set_has_javanano_use_deprecated_package() {
+  _has_bits_[0] |= 0x00000800u;
+}
+inline void FileOptions::clear_has_javanano_use_deprecated_package() {
+  _has_bits_[0] &= ~0x00000800u;
+}
+inline void FileOptions::clear_javanano_use_deprecated_package() {
+  javanano_use_deprecated_package_ = false;
+  clear_has_javanano_use_deprecated_package();
+}
+inline bool FileOptions::javanano_use_deprecated_package() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.javanano_use_deprecated_package)
+  return javanano_use_deprecated_package_;
+}
+inline void FileOptions::set_javanano_use_deprecated_package(bool value) {
+  set_has_javanano_use_deprecated_package();
+  javanano_use_deprecated_package_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.javanano_use_deprecated_package)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int FileOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+inline void FileOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+FileOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+FileOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// MessageOptions
+
+// optional bool message_set_wire_format = 1 [default = false];
+inline bool MessageOptions::has_message_set_wire_format() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MessageOptions::set_has_message_set_wire_format() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void MessageOptions::clear_has_message_set_wire_format() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void MessageOptions::clear_message_set_wire_format() {
+  message_set_wire_format_ = false;
+  clear_has_message_set_wire_format();
+}
+inline bool MessageOptions::message_set_wire_format() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.message_set_wire_format)
+  return message_set_wire_format_;
+}
+inline void MessageOptions::set_message_set_wire_format(bool value) {
+  set_has_message_set_wire_format();
+  message_set_wire_format_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.message_set_wire_format)
+}
+
+// optional bool no_standard_descriptor_accessor = 2 [default = false];
+inline bool MessageOptions::has_no_standard_descriptor_accessor() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void MessageOptions::set_has_no_standard_descriptor_accessor() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void MessageOptions::clear_has_no_standard_descriptor_accessor() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void MessageOptions::clear_no_standard_descriptor_accessor() {
+  no_standard_descriptor_accessor_ = false;
+  clear_has_no_standard_descriptor_accessor();
+}
+inline bool MessageOptions::no_standard_descriptor_accessor() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
+  return no_standard_descriptor_accessor_;
+}
+inline void MessageOptions::set_no_standard_descriptor_accessor(bool value) {
+  set_has_no_standard_descriptor_accessor();
+  no_standard_descriptor_accessor_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.no_standard_descriptor_accessor)
+}
+
+// optional bool deprecated = 3 [default = false];
+inline bool MessageOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void MessageOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void MessageOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void MessageOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+inline bool MessageOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.deprecated)
+  return deprecated_;
+}
+inline void MessageOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MessageOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int MessageOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+inline void MessageOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.MessageOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+MessageOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+MessageOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.MessageOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// FieldOptions
+
+// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
+inline bool FieldOptions::has_ctype() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void FieldOptions::set_has_ctype() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void FieldOptions::clear_has_ctype() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void FieldOptions::clear_ctype() {
+  ctype_ = 0;
+  clear_has_ctype();
+}
+inline ::google::protobuf::FieldOptions_CType FieldOptions::ctype() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.ctype)
+  return static_cast< ::google::protobuf::FieldOptions_CType >(ctype_);
+}
+inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) {
+  assert(::google::protobuf::FieldOptions_CType_IsValid(value));
+  set_has_ctype();
+  ctype_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.ctype)
+}
+
+// optional bool packed = 2;
+inline bool FieldOptions::has_packed() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void FieldOptions::set_has_packed() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void FieldOptions::clear_has_packed() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void FieldOptions::clear_packed() {
+  packed_ = false;
+  clear_has_packed();
+}
+inline bool FieldOptions::packed() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.packed)
+  return packed_;
+}
+inline void FieldOptions::set_packed(bool value) {
+  set_has_packed();
+  packed_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed)
+}
+
+// optional bool lazy = 5 [default = false];
+inline bool FieldOptions::has_lazy() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void FieldOptions::set_has_lazy() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void FieldOptions::clear_has_lazy() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void FieldOptions::clear_lazy() {
+  lazy_ = false;
+  clear_has_lazy();
+}
+inline bool FieldOptions::lazy() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.lazy)
+  return lazy_;
+}
+inline void FieldOptions::set_lazy(bool value) {
+  set_has_lazy();
+  lazy_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.lazy)
+}
+
+// optional bool deprecated = 3 [default = false];
+inline bool FieldOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void FieldOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void FieldOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void FieldOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+inline bool FieldOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.deprecated)
+  return deprecated_;
+}
+inline void FieldOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.deprecated)
+}
+
+// optional string experimental_map_key = 9;
+inline bool FieldOptions::has_experimental_map_key() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void FieldOptions::set_has_experimental_map_key() {
+  _has_bits_[0] |= 0x00000010u;
+}
+inline void FieldOptions::clear_has_experimental_map_key() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+inline void FieldOptions::clear_experimental_map_key() {
+  if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    experimental_map_key_->clear();
+  }
+  clear_has_experimental_map_key();
+}
+inline const ::std::string& FieldOptions::experimental_map_key() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.experimental_map_key)
+  return *experimental_map_key_;
+}
+inline void FieldOptions::set_experimental_map_key(const ::std::string& value) {
+  set_has_experimental_map_key();
+  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    experimental_map_key_ = new ::std::string;
+  }
+  experimental_map_key_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.experimental_map_key)
+}
+inline void FieldOptions::set_experimental_map_key(const char* value) {
+  set_has_experimental_map_key();
+  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    experimental_map_key_ = new ::std::string;
+  }
+  experimental_map_key_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FieldOptions.experimental_map_key)
+}
+inline void FieldOptions::set_experimental_map_key(const char* value, size_t size) {
+  set_has_experimental_map_key();
+  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    experimental_map_key_ = new ::std::string;
+  }
+  experimental_map_key_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldOptions.experimental_map_key)
+}
+inline ::std::string* FieldOptions::mutable_experimental_map_key() {
+  set_has_experimental_map_key();
+  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    experimental_map_key_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.experimental_map_key)
+  return experimental_map_key_;
+}
+inline ::std::string* FieldOptions::release_experimental_map_key() {
+  clear_has_experimental_map_key();
+  if (experimental_map_key_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = experimental_map_key_;
+    experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void FieldOptions::set_allocated_experimental_map_key(::std::string* experimental_map_key) {
+  if (experimental_map_key_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete experimental_map_key_;
+  }
+  if (experimental_map_key) {
+    set_has_experimental_map_key();
+    experimental_map_key_ = experimental_map_key;
+  } else {
+    clear_has_experimental_map_key();
+    experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FieldOptions.experimental_map_key)
+}
+
+// optional bool weak = 10 [default = false];
+inline bool FieldOptions::has_weak() const {
+  return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void FieldOptions::set_has_weak() {
+  _has_bits_[0] |= 0x00000020u;
+}
+inline void FieldOptions::clear_has_weak() {
+  _has_bits_[0] &= ~0x00000020u;
+}
+inline void FieldOptions::clear_weak() {
+  weak_ = false;
+  clear_has_weak();
+}
+inline bool FieldOptions::weak() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.weak)
+  return weak_;
+}
+inline void FieldOptions::set_weak(bool value) {
+  set_has_weak();
+  weak_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.weak)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int FieldOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+inline void FieldOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+FieldOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+FieldOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumOptions
+
+// optional bool allow_alias = 2;
+inline bool EnumOptions::has_allow_alias() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumOptions::set_has_allow_alias() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumOptions::clear_has_allow_alias() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void EnumOptions::clear_allow_alias() {
+  allow_alias_ = false;
+  clear_has_allow_alias();
+}
+inline bool EnumOptions::allow_alias() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.allow_alias)
+  return allow_alias_;
+}
+inline void EnumOptions::set_allow_alias(bool value) {
+  set_has_allow_alias();
+  allow_alias_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.allow_alias)
+}
+
+// optional bool deprecated = 3 [default = false];
+inline bool EnumOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void EnumOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void EnumOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void EnumOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+inline bool EnumOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.deprecated)
+  return deprecated_;
+}
+inline void EnumOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int EnumOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+inline void EnumOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.EnumOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+EnumOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+EnumOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// EnumValueOptions
+
+// optional bool deprecated = 1 [default = false];
+inline bool EnumValueOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void EnumValueOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void EnumValueOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void EnumValueOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+inline bool EnumValueOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.deprecated)
+  return deprecated_;
+}
+inline void EnumValueOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.EnumValueOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int EnumValueOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+inline void EnumValueOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.EnumValueOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+EnumValueOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+EnumValueOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValueOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// ServiceOptions
+
+// optional bool deprecated = 33 [default = false];
+inline bool ServiceOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void ServiceOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void ServiceOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void ServiceOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+inline bool ServiceOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.deprecated)
+  return deprecated_;
+}
+inline void ServiceOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.ServiceOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int ServiceOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+inline void ServiceOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.ServiceOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ServiceOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+ServiceOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// MethodOptions
+
+// optional bool deprecated = 33 [default = false];
+inline bool MethodOptions::has_deprecated() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void MethodOptions::set_has_deprecated() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void MethodOptions::clear_has_deprecated() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void MethodOptions::clear_deprecated() {
+  deprecated_ = false;
+  clear_has_deprecated();
+}
+inline bool MethodOptions::deprecated() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.deprecated)
+  return deprecated_;
+}
+inline void MethodOptions::set_deprecated(bool value) {
+  set_has_deprecated();
+  deprecated_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.MethodOptions.deprecated)
+}
+
+// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
+inline int MethodOptions::uninterpreted_option_size() const {
+  return uninterpreted_option_.size();
+}
+inline void MethodOptions::clear_uninterpreted_option() {
+  uninterpreted_option_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.uninterpreted_option)
+  return uninterpreted_option_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.uninterpreted_option)
+  return uninterpreted_option_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() {
+  // @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option)
+  return uninterpreted_option_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+MethodOptions::uninterpreted_option() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
+  return uninterpreted_option_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+MethodOptions::mutable_uninterpreted_option() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option)
+  return &uninterpreted_option_;
+}
+
+// -------------------------------------------------------------------
+
+// UninterpretedOption_NamePart
+
+// required string name_part = 1;
+inline bool UninterpretedOption_NamePart::has_name_part() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void UninterpretedOption_NamePart::set_has_name_part() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void UninterpretedOption_NamePart::clear_has_name_part() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void UninterpretedOption_NamePart::clear_name_part() {
+  if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_part_->clear();
+  }
+  clear_has_name_part();
+}
+inline const ::std::string& UninterpretedOption_NamePart::name_part() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.name_part)
+  return *name_part_;
+}
+inline void UninterpretedOption_NamePart::set_name_part(const ::std::string& value) {
+  set_has_name_part();
+  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_part_ = new ::std::string;
+  }
+  name_part_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+inline void UninterpretedOption_NamePart::set_name_part(const char* value) {
+  set_has_name_part();
+  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_part_ = new ::std::string;
+  }
+  name_part_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) {
+  set_has_name_part();
+  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_part_ = new ::std::string;
+  }
+  name_part_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+inline ::std::string* UninterpretedOption_NamePart::mutable_name_part() {
+  set_has_name_part();
+  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    name_part_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.NamePart.name_part)
+  return name_part_;
+}
+inline ::std::string* UninterpretedOption_NamePart::release_name_part() {
+  clear_has_name_part();
+  if (name_part_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = name_part_;
+    name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void UninterpretedOption_NamePart::set_allocated_name_part(::std::string* name_part) {
+  if (name_part_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete name_part_;
+  }
+  if (name_part) {
+    set_has_name_part();
+    name_part_ = name_part;
+  } else {
+    clear_has_name_part();
+    name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.NamePart.name_part)
+}
+
+// required bool is_extension = 2;
+inline bool UninterpretedOption_NamePart::has_is_extension() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void UninterpretedOption_NamePart::set_has_is_extension() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void UninterpretedOption_NamePart::clear_has_is_extension() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void UninterpretedOption_NamePart::clear_is_extension() {
+  is_extension_ = false;
+  clear_has_is_extension();
+}
+inline bool UninterpretedOption_NamePart::is_extension() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.NamePart.is_extension)
+  return is_extension_;
+}
+inline void UninterpretedOption_NamePart::set_is_extension(bool value) {
+  set_has_is_extension();
+  is_extension_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.NamePart.is_extension)
+}
+
+// -------------------------------------------------------------------
+
+// UninterpretedOption
+
+// repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
+inline int UninterpretedOption::name_size() const {
+  return name_.size();
+}
+inline void UninterpretedOption::clear_name() {
+  name_.Clear();
+}
+inline const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name)
+  return name_.Get(index);
+}
+inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name)
+  return name_.Mutable(index);
+}
+inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
+  // @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name)
+  return name_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
+UninterpretedOption::name() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
+  return name_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
+UninterpretedOption::mutable_name() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name)
+  return &name_;
+}
+
+// optional string identifier_value = 3;
+inline bool UninterpretedOption::has_identifier_value() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void UninterpretedOption::set_has_identifier_value() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void UninterpretedOption::clear_has_identifier_value() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void UninterpretedOption::clear_identifier_value() {
+  if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    identifier_value_->clear();
+  }
+  clear_has_identifier_value();
+}
+inline const ::std::string& UninterpretedOption::identifier_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.identifier_value)
+  return *identifier_value_;
+}
+inline void UninterpretedOption::set_identifier_value(const ::std::string& value) {
+  set_has_identifier_value();
+  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    identifier_value_ = new ::std::string;
+  }
+  identifier_value_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.identifier_value)
+}
+inline void UninterpretedOption::set_identifier_value(const char* value) {
+  set_has_identifier_value();
+  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    identifier_value_ = new ::std::string;
+  }
+  identifier_value_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value)
+}
+inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) {
+  set_has_identifier_value();
+  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    identifier_value_ = new ::std::string;
+  }
+  identifier_value_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.identifier_value)
+}
+inline ::std::string* UninterpretedOption::mutable_identifier_value() {
+  set_has_identifier_value();
+  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    identifier_value_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.identifier_value)
+  return identifier_value_;
+}
+inline ::std::string* UninterpretedOption::release_identifier_value() {
+  clear_has_identifier_value();
+  if (identifier_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = identifier_value_;
+    identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void UninterpretedOption::set_allocated_identifier_value(::std::string* identifier_value) {
+  if (identifier_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete identifier_value_;
+  }
+  if (identifier_value) {
+    set_has_identifier_value();
+    identifier_value_ = identifier_value;
+  } else {
+    clear_has_identifier_value();
+    identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.identifier_value)
+}
+
+// optional uint64 positive_int_value = 4;
+inline bool UninterpretedOption::has_positive_int_value() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void UninterpretedOption::set_has_positive_int_value() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void UninterpretedOption::clear_has_positive_int_value() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void UninterpretedOption::clear_positive_int_value() {
+  positive_int_value_ = GOOGLE_ULONGLONG(0);
+  clear_has_positive_int_value();
+}
+inline ::google::protobuf::uint64 UninterpretedOption::positive_int_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.positive_int_value)
+  return positive_int_value_;
+}
+inline void UninterpretedOption::set_positive_int_value(::google::protobuf::uint64 value) {
+  set_has_positive_int_value();
+  positive_int_value_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.positive_int_value)
+}
+
+// optional int64 negative_int_value = 5;
+inline bool UninterpretedOption::has_negative_int_value() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void UninterpretedOption::set_has_negative_int_value() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void UninterpretedOption::clear_has_negative_int_value() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void UninterpretedOption::clear_negative_int_value() {
+  negative_int_value_ = GOOGLE_LONGLONG(0);
+  clear_has_negative_int_value();
+}
+inline ::google::protobuf::int64 UninterpretedOption::negative_int_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.negative_int_value)
+  return negative_int_value_;
+}
+inline void UninterpretedOption::set_negative_int_value(::google::protobuf::int64 value) {
+  set_has_negative_int_value();
+  negative_int_value_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.negative_int_value)
+}
+
+// optional double double_value = 6;
+inline bool UninterpretedOption::has_double_value() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void UninterpretedOption::set_has_double_value() {
+  _has_bits_[0] |= 0x00000010u;
+}
+inline void UninterpretedOption::clear_has_double_value() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+inline void UninterpretedOption::clear_double_value() {
+  double_value_ = 0;
+  clear_has_double_value();
+}
+inline double UninterpretedOption::double_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.double_value)
+  return double_value_;
+}
+inline void UninterpretedOption::set_double_value(double value) {
+  set_has_double_value();
+  double_value_ = value;
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.double_value)
+}
+
+// optional bytes string_value = 7;
+inline bool UninterpretedOption::has_string_value() const {
+  return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void UninterpretedOption::set_has_string_value() {
+  _has_bits_[0] |= 0x00000020u;
+}
+inline void UninterpretedOption::clear_has_string_value() {
+  _has_bits_[0] &= ~0x00000020u;
+}
+inline void UninterpretedOption::clear_string_value() {
+  if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    string_value_->clear();
+  }
+  clear_has_string_value();
+}
+inline const ::std::string& UninterpretedOption::string_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.string_value)
+  return *string_value_;
+}
+inline void UninterpretedOption::set_string_value(const ::std::string& value) {
+  set_has_string_value();
+  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    string_value_ = new ::std::string;
+  }
+  string_value_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.string_value)
+}
+inline void UninterpretedOption::set_string_value(const char* value) {
+  set_has_string_value();
+  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    string_value_ = new ::std::string;
+  }
+  string_value_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value)
+}
+inline void UninterpretedOption::set_string_value(const void* value, size_t size) {
+  set_has_string_value();
+  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    string_value_ = new ::std::string;
+  }
+  string_value_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.string_value)
+}
+inline ::std::string* UninterpretedOption::mutable_string_value() {
+  set_has_string_value();
+  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    string_value_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.string_value)
+  return string_value_;
+}
+inline ::std::string* UninterpretedOption::release_string_value() {
+  clear_has_string_value();
+  if (string_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = string_value_;
+    string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void UninterpretedOption::set_allocated_string_value(::std::string* string_value) {
+  if (string_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete string_value_;
+  }
+  if (string_value) {
+    set_has_string_value();
+    string_value_ = string_value;
+  } else {
+    clear_has_string_value();
+    string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.string_value)
+}
+
+// optional string aggregate_value = 8;
+inline bool UninterpretedOption::has_aggregate_value() const {
+  return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void UninterpretedOption::set_has_aggregate_value() {
+  _has_bits_[0] |= 0x00000040u;
+}
+inline void UninterpretedOption::clear_has_aggregate_value() {
+  _has_bits_[0] &= ~0x00000040u;
+}
+inline void UninterpretedOption::clear_aggregate_value() {
+  if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    aggregate_value_->clear();
+  }
+  clear_has_aggregate_value();
+}
+inline const ::std::string& UninterpretedOption::aggregate_value() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.aggregate_value)
+  return *aggregate_value_;
+}
+inline void UninterpretedOption::set_aggregate_value(const ::std::string& value) {
+  set_has_aggregate_value();
+  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    aggregate_value_ = new ::std::string;
+  }
+  aggregate_value_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.UninterpretedOption.aggregate_value)
+}
+inline void UninterpretedOption::set_aggregate_value(const char* value) {
+  set_has_aggregate_value();
+  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    aggregate_value_ = new ::std::string;
+  }
+  aggregate_value_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value)
+}
+inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) {
+  set_has_aggregate_value();
+  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    aggregate_value_ = new ::std::string;
+  }
+  aggregate_value_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.aggregate_value)
+}
+inline ::std::string* UninterpretedOption::mutable_aggregate_value() {
+  set_has_aggregate_value();
+  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    aggregate_value_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.aggregate_value)
+  return aggregate_value_;
+}
+inline ::std::string* UninterpretedOption::release_aggregate_value() {
+  clear_has_aggregate_value();
+  if (aggregate_value_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = aggregate_value_;
+    aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void UninterpretedOption::set_allocated_aggregate_value(::std::string* aggregate_value) {
+  if (aggregate_value_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete aggregate_value_;
+  }
+  if (aggregate_value) {
+    set_has_aggregate_value();
+    aggregate_value_ = aggregate_value;
+  } else {
+    clear_has_aggregate_value();
+    aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.UninterpretedOption.aggregate_value)
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo_Location
+
+// repeated int32 path = 1 [packed = true];
+inline int SourceCodeInfo_Location::path_size() const {
+  return path_.size();
+}
+inline void SourceCodeInfo_Location::clear_path() {
+  path_.Clear();
+}
+inline ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.path)
+  return path_.Get(index);
+}
+inline void SourceCodeInfo_Location::set_path(int index, ::google::protobuf::int32 value) {
+  path_.Set(index, value);
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.path)
+}
+inline void SourceCodeInfo_Location::add_path(::google::protobuf::int32 value) {
+  path_.Add(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.path)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+SourceCodeInfo_Location::path() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.path)
+  return path_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+SourceCodeInfo_Location::mutable_path() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.path)
+  return &path_;
+}
+
+// repeated int32 span = 2 [packed = true];
+inline int SourceCodeInfo_Location::span_size() const {
+  return span_.size();
+}
+inline void SourceCodeInfo_Location::clear_span() {
+  span_.Clear();
+}
+inline ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.span)
+  return span_.Get(index);
+}
+inline void SourceCodeInfo_Location::set_span(int index, ::google::protobuf::int32 value) {
+  span_.Set(index, value);
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.span)
+}
+inline void SourceCodeInfo_Location::add_span(::google::protobuf::int32 value) {
+  span_.Add(value);
+  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.span)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+SourceCodeInfo_Location::span() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.Location.span)
+  return span_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+SourceCodeInfo_Location::mutable_span() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.Location.span)
+  return &span_;
+}
+
+// optional string leading_comments = 3;
+inline bool SourceCodeInfo_Location::has_leading_comments() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void SourceCodeInfo_Location::set_has_leading_comments() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void SourceCodeInfo_Location::clear_has_leading_comments() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void SourceCodeInfo_Location::clear_leading_comments() {
+  if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    leading_comments_->clear();
+  }
+  clear_has_leading_comments();
+}
+inline const ::std::string& SourceCodeInfo_Location::leading_comments() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.leading_comments)
+  return *leading_comments_;
+}
+inline void SourceCodeInfo_Location::set_leading_comments(const ::std::string& value) {
+  set_has_leading_comments();
+  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    leading_comments_ = new ::std::string;
+  }
+  leading_comments_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+inline void SourceCodeInfo_Location::set_leading_comments(const char* value) {
+  set_has_leading_comments();
+  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    leading_comments_ = new ::std::string;
+  }
+  leading_comments_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+inline void SourceCodeInfo_Location::set_leading_comments(const char* value, size_t size) {
+  set_has_leading_comments();
+  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    leading_comments_ = new ::std::string;
+  }
+  leading_comments_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+inline ::std::string* SourceCodeInfo_Location::mutable_leading_comments() {
+  set_has_leading_comments();
+  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    leading_comments_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.leading_comments)
+  return leading_comments_;
+}
+inline ::std::string* SourceCodeInfo_Location::release_leading_comments() {
+  clear_has_leading_comments();
+  if (leading_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = leading_comments_;
+    leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void SourceCodeInfo_Location::set_allocated_leading_comments(::std::string* leading_comments) {
+  if (leading_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete leading_comments_;
+  }
+  if (leading_comments) {
+    set_has_leading_comments();
+    leading_comments_ = leading_comments;
+  } else {
+    clear_has_leading_comments();
+    leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.leading_comments)
+}
+
+// optional string trailing_comments = 4;
+inline bool SourceCodeInfo_Location::has_trailing_comments() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void SourceCodeInfo_Location::set_has_trailing_comments() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void SourceCodeInfo_Location::clear_has_trailing_comments() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void SourceCodeInfo_Location::clear_trailing_comments() {
+  if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    trailing_comments_->clear();
+  }
+  clear_has_trailing_comments();
+}
+inline const ::std::string& SourceCodeInfo_Location::trailing_comments() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+  return *trailing_comments_;
+}
+inline void SourceCodeInfo_Location::set_trailing_comments(const ::std::string& value) {
+  set_has_trailing_comments();
+  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    trailing_comments_ = new ::std::string;
+  }
+  trailing_comments_->assign(value);
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) {
+  set_has_trailing_comments();
+  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    trailing_comments_ = new ::std::string;
+  }
+  trailing_comments_->assign(value);
+  // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+inline void SourceCodeInfo_Location::set_trailing_comments(const char* value, size_t size) {
+  set_has_trailing_comments();
+  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    trailing_comments_ = new ::std::string;
+  }
+  trailing_comments_->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+inline ::std::string* SourceCodeInfo_Location::mutable_trailing_comments() {
+  set_has_trailing_comments();
+  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    trailing_comments_ = new ::std::string;
+  }
+  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+  return trailing_comments_;
+}
+inline ::std::string* SourceCodeInfo_Location::release_trailing_comments() {
+  clear_has_trailing_comments();
+  if (trailing_comments_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    return NULL;
+  } else {
+    ::std::string* temp = trailing_comments_;
+    trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    return temp;
+  }
+}
+inline void SourceCodeInfo_Location::set_allocated_trailing_comments(::std::string* trailing_comments) {
+  if (trailing_comments_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
+    delete trailing_comments_;
+  }
+  if (trailing_comments) {
+    set_has_trailing_comments();
+    trailing_comments_ = trailing_comments;
+  } else {
+    clear_has_trailing_comments();
+    trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceCodeInfo.Location.trailing_comments)
+}
+
+// -------------------------------------------------------------------
+
+// SourceCodeInfo
+
+// repeated .google.protobuf.SourceCodeInfo.Location location = 1;
+inline int SourceCodeInfo::location_size() const {
+  return location_.size();
+}
+inline void SourceCodeInfo::clear_location() {
+  location_.Clear();
+}
+inline const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const {
+  // @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.location)
+  return location_.Get(index);
+}
+inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
+  // @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.location)
+  return location_.Mutable(index);
+}
+inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
+  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.location)
+  return location_.Add();
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+SourceCodeInfo::location() const {
+  // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location)
+  return location_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+SourceCodeInfo::mutable_location() {
+  // @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.location)
+  return &location_;
+}
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace protobuf
+}  // namespace google
+
+#ifndef SWIG
+namespace google {
+namespace protobuf {
+
+template <> struct is_proto_enum< ::google::protobuf::FieldDescriptorProto_Type> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Type>() {
+  return ::google::protobuf::FieldDescriptorProto_Type_descriptor();
+}
+template <> struct is_proto_enum< ::google::protobuf::FieldDescriptorProto_Label> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldDescriptorProto_Label>() {
+  return ::google::protobuf::FieldDescriptorProto_Label_descriptor();
+}
+template <> struct is_proto_enum< ::google::protobuf::FileOptions_OptimizeMode> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FileOptions_OptimizeMode>() {
+  return ::google::protobuf::FileOptions_OptimizeMode_descriptor();
+}
+template <> struct is_proto_enum< ::google::protobuf::FieldOptions_CType> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_CType>() {
+  return ::google::protobuf::FieldOptions_CType_descriptor();
+}
+
+}  // namespace google
+}  // namespace protobuf
+#endif  // SWIG
+
+// @@protoc_insertion_point(global_scope)
+
+#endif  // PROTOBUF_google_2fprotobuf_2fdescriptor_2eproto__INCLUDED
diff --git a/protobuf/src/google/protobuf/descriptor.proto b/protobuf/src/google/protobuf/descriptor.proto
new file mode 100644
index 0000000..eb8fe28
--- /dev/null
+++ b/protobuf/src/google/protobuf/descriptor.proto
@@ -0,0 +1,690 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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;
+
+// The protocol compiler can output a FileDescriptorSet containing the .proto
+// files it parses.
+message FileDescriptorSet {
+  repeated FileDescriptorProto file = 1;
+}
+
+// Describes a complete .proto file.
+message FileDescriptorProto {
+  optional string name = 1;       // file name, relative to root of source tree
+  optional string package = 2;    // e.g. "foo", "foo.bar", etc.
+
+  // Names of files imported by this file.
+  repeated string dependency = 3;
+  // Indexes of the public imported files in the dependency list above.
+  repeated int32 public_dependency = 10;
+  // Indexes of the weak imported files in the dependency list.
+  // For Google-internal migration only. Do not use.
+  repeated int32 weak_dependency = 11;
+
+  // 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;
+
+  // This field contains optional information about the original source code.
+  // You may safely remove this entire field whithout harming runtime
+  // functionality of the descriptors -- the information is needed only by
+  // development tools.
+  optional SourceCodeInfo source_code_info = 9;
+}
+
+// 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;
+
+  repeated OneofDescriptorProto oneof_decl = 8;
+
+  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;
+    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT64 if
+    // negative values are likely.
+    TYPE_INT64          = 3;
+    TYPE_UINT64         = 4;
+    // Not ZigZag encoded.  Negative numbers take 10 bytes.  Use TYPE_SINT32 if
+    // negative values are likely.
+    TYPE_INT32          = 5;
+    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 one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
+  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;
+
+  // If set, gives the index of a oneof in the containing type's oneof_decl
+  // list.  This field is a member of that oneof.  Extensions of a oneof should
+  // not set this since the oneof to which they belong will be inferred based
+  // on the extension range containing the extension's field number.
+  optional int32 oneof_index = 9;
+
+  optional FieldOptions options = 8;
+}
+
+// Describes a oneof.
+message OneofDescriptorProto {
+  optional string name = 1;
+}
+
+// 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.
+//
+// Clients may define custom options as extensions of the *Options messages.
+// These extensions may not yet be known at parsing time, so the parser cannot
+// store the values in them.  Instead it stores them in a field in the *Options
+// message called uninterpreted_option. This field must have the same name
+// across all *Options messages. We then use this field to populate the
+// extensions when we build a descriptor, at which point all protos have been
+// parsed and so all extensions are known.
+//
+// Extension numbers for custom options may be chosen as follows:
+// * For options which will only be used within a single application or
+//   organization, or for experimental options, use field numbers 50000
+//   through 99999.  It is up to you to ensure that you do not use the
+//   same number for multiple options.
+// * For options which will be published and used publicly by multiple
+//   independent entities, e-mail protobuf-global-extension-registry@google.com
+//   to reserve extension numbers. Simply provide your project name (e.g.
+//   Object-C plugin) and your porject website (if available) -- there's no need
+//   to explain how you intend to use them. Usually you only need one extension
+//   number. You can declare multiple options with only one extension number by
+//   putting them in a sub-message. See the Custom Options section of the docs
+//   for examples:
+//   https://developers.google.com/protocol-buffers/docs/proto#options
+//   If this turns out to be popular, a web service will be set up
+//   to automatically assign option numbers.
+
+
+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];
+
+  // If set true, then the Java code generator will generate equals() and
+  // hashCode() methods for all messages defined in the .proto file.
+  // - In the full runtime, this is purely a speed optimization, as the
+  // AbstractMessage base class includes reflection-based implementations of
+  // these methods.
+  //- In the lite runtime, setting this option changes the semantics of
+  // equals() and hashCode() to more closely match those of the full runtime;
+  // the generated methods compute their results based on field values rather
+  // than object identity. (Implementations should not assume that hashcodes
+  // will be consistent across runtimes or versions of the protocol compiler.)
+  optional bool java_generate_equals_and_hash = 20 [default=false];
+
+  // If set true, then the Java2 code generator will generate code that
+  // throws an exception whenever an attempt is made to assign a non-UTF-8
+  // byte sequence to a string field.
+  // Message reflection will do the same.
+  // However, an extension field still accepts non-UTF-8 byte sequences.
+  // This option has no effect on when used with the lite runtime.
+  optional bool java_string_check_utf8 = 27 [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.
+    LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
+  }
+  optional OptimizeMode optimize_for = 9 [default=SPEED];
+
+  // Sets the Go package where structs generated from this .proto will be
+  // placed.  There is no default.
+  optional string go_package = 11;
+
+
+
+  // Should generic services be generated in each language?  "Generic" services
+  // are not specific to any particular RPC system.  They are generated by the
+  // main code generators in each language (without additional plugins).
+  // Generic services were the only kind of service generation supported by
+  // early versions of proto2.
+  //
+  // Generic services are now considered deprecated in favor of using plugins
+  // that generate code specific to your particular RPC system.  Therefore,
+  // these default to false.  Old code which depends on generic services should
+  // explicitly set them to true.
+  optional bool cc_generic_services = 16 [default=false];
+  optional bool java_generic_services = 17 [default=false];
+  optional bool py_generic_services = 18 [default=false];
+
+  // Is this file deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for everything in the file, or it will be completely ignored; in the very
+  // least, this is a formalization for deprecating files.
+  optional bool deprecated = 23 [default=false];
+
+  // Whether the nano proto compiler should generate in the deprecated non-nano
+  // suffixed package.
+  optional bool javanano_use_deprecated_package = 38;
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+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];
+
+  // Disables the generation of the standard "descriptor()" accessor, which can
+  // conflict with a field of the same name.  This is meant to make migration
+  // from proto1 easier; new code should avoid fields named "descriptor".
+  optional bool no_standard_descriptor_accessor = 2 [default=false];
+
+  // Is this message deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the message, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating messages.
+  optional bool deprecated = 3 [default=false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+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 [default = STRING];
+  enum CType {
+    // Default mode.
+    STRING = 0;
+
+    CORD = 1;
+
+    STRING_PIECE = 2;
+  }
+  // The packed option can be enabled for repeated primitive fields to enable
+  // a more efficient representation on the wire. Rather than repeatedly
+  // writing the tag and type for each element, the entire array is encoded as
+  // a single length-delimited blob.
+  optional bool packed = 2;
+
+
+
+  // Should this field be parsed lazily?  Lazy applies only to message-type
+  // fields.  It means that when the outer message is initially parsed, the
+  // inner message's contents will not be parsed but instead stored in encoded
+  // form.  The inner message will actually be parsed when it is first accessed.
+  //
+  // This is only a hint.  Implementations are free to choose whether to use
+  // eager or lazy parsing regardless of the value of this option.  However,
+  // setting this option true suggests that the protocol author believes that
+  // using lazy parsing on this field is worth the additional bookkeeping
+  // overhead typically needed to implement it.
+  //
+  // This option does not affect the public interface of any generated code;
+  // all method signatures remain the same.  Furthermore, thread-safety of the
+  // interface is not affected by this option; const methods remain safe to
+  // call from multiple threads concurrently, while non-const methods continue
+  // to require exclusive access.
+  //
+  //
+  // Note that implementations may choose not to check required fields within
+  // a lazy sub-message.  That is, calling IsInitialized() on the outher message
+  // may return true even if the inner message has missing required fields.
+  // This is necessary because otherwise the inner message would have to be
+  // parsed in order to perform the check, defeating the purpose of lazy
+  // parsing.  An implementation which chooses not to check required fields
+  // must be consistent about it.  That is, for any particular sub-message, the
+  // implementation must either *always* check its required fields, or *never*
+  // check its required fields, regardless of whether or not the message has
+  // been parsed.
+  optional bool lazy = 5 [default=false];
+
+  // Is this field deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for accessors, or it will be completely ignored; in the very least, this
+  // is a formalization for deprecating fields.
+  optional bool deprecated = 3 [default=false];
+
+  // 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;
+
+  // For Google-internal migration only. Do not use.
+  optional bool weak = 10 [default=false];
+
+
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message EnumOptions {
+
+  // Set this option to true to allow mapping different tag names to the same
+  // value.
+  optional bool allow_alias = 2;
+
+  // Is this enum deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the enum, or it will be completely ignored; in the very least, this
+  // is a formalization for deprecating enums.
+  optional bool deprecated = 3 [default=false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+message EnumValueOptions {
+  // Is this enum value deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the enum value, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating enum values.
+  optional bool deprecated = 1 [default=false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+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.
+
+  // Is this service deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the service, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating services.
+  optional bool deprecated = 33 [default=false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+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.
+
+  // Is this method deprecated?
+  // Depending on the target platform, this can emit Deprecated annotations
+  // for the method, or it will be completely ignored; in the very least,
+  // this is a formalization for deprecating methods.
+  optional bool deprecated = 33 [default=false];
+
+  // The parser stores options it doesn't recognize here. See above.
+  repeated UninterpretedOption uninterpreted_option = 999;
+
+  // Clients can define custom options in extensions of this message. See above.
+  extensions 1000 to max;
+}
+
+
+// A message representing a option the parser does not recognize. This only
+// appears in options protos created by the compiler::Parser class.
+// DescriptorPool resolves these when building Descriptor objects. Therefore,
+// options protos in descriptor objects (e.g. returned by Descriptor::options(),
+// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
+// in them.
+message UninterpretedOption {
+  // The name of the uninterpreted option.  Each string represents a segment in
+  // a dot-separated name.  is_extension is true iff a segment represents an
+  // extension (denoted with parentheses in options specs in .proto files).
+  // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
+  // "foo.(bar.baz).qux".
+  message NamePart {
+    required string name_part = 1;
+    required bool is_extension = 2;
+  }
+  repeated NamePart name = 2;
+
+  // The value of the uninterpreted option, in whatever type the tokenizer
+  // identified it as during parsing. Exactly one of these should be set.
+  optional string identifier_value = 3;
+  optional uint64 positive_int_value = 4;
+  optional int64 negative_int_value = 5;
+  optional double double_value = 6;
+  optional bytes string_value = 7;
+  optional string aggregate_value = 8;
+}
+
+// ===================================================================
+// Optional source code info
+
+// Encapsulates information about the original source file from which a
+// FileDescriptorProto was generated.
+message SourceCodeInfo {
+  // A Location identifies a piece of source code in a .proto file which
+  // corresponds to a particular definition.  This information is intended
+  // to be useful to IDEs, code indexers, documentation generators, and similar
+  // tools.
+  //
+  // For example, say we have a file like:
+  //   message Foo {
+  //     optional string foo = 1;
+  //   }
+  // Let's look at just the field definition:
+  //   optional string foo = 1;
+  //   ^       ^^     ^^  ^  ^^^
+  //   a       bc     de  f  ghi
+  // We have the following locations:
+  //   span   path               represents
+  //   [a,i)  [ 4, 0, 2, 0 ]     The whole field definition.
+  //   [a,b)  [ 4, 0, 2, 0, 4 ]  The label (optional).
+  //   [c,d)  [ 4, 0, 2, 0, 5 ]  The type (string).
+  //   [e,f)  [ 4, 0, 2, 0, 1 ]  The name (foo).
+  //   [g,h)  [ 4, 0, 2, 0, 3 ]  The number (1).
+  //
+  // Notes:
+  // - A location may refer to a repeated field itself (i.e. not to any
+  //   particular index within it).  This is used whenever a set of elements are
+  //   logically enclosed in a single code segment.  For example, an entire
+  //   extend block (possibly containing multiple extension definitions) will
+  //   have an outer location whose path refers to the "extensions" repeated
+  //   field without an index.
+  // - Multiple locations may have the same path.  This happens when a single
+  //   logical declaration is spread out across multiple places.  The most
+  //   obvious example is the "extend" block again -- there may be multiple
+  //   extend blocks in the same scope, each of which will have the same path.
+  // - A location's span is not always a subset of its parent's span.  For
+  //   example, the "extendee" of an extension declaration appears at the
+  //   beginning of the "extend" block and is shared by all extensions within
+  //   the block.
+  // - Just because a location's span is a subset of some other location's span
+  //   does not mean that it is a descendent.  For example, a "group" defines
+  //   both a type and a field in a single declaration.  Thus, the locations
+  //   corresponding to the type and field and their components will overlap.
+  // - Code which tries to interpret locations should probably be designed to
+  //   ignore those that it doesn't understand, as more types of locations could
+  //   be recorded in the future.
+  repeated Location location = 1;
+  message Location {
+    // Identifies which part of the FileDescriptorProto was defined at this
+    // location.
+    //
+    // Each element is a field number or an index.  They form a path from
+    // the root FileDescriptorProto to the place where the definition.  For
+    // example, this path:
+    //   [ 4, 3, 2, 7, 1 ]
+    // refers to:
+    //   file.message_type(3)  // 4, 3
+    //       .field(7)         // 2, 7
+    //       .name()           // 1
+    // This is because FileDescriptorProto.message_type has field number 4:
+    //   repeated DescriptorProto message_type = 4;
+    // and DescriptorProto.field has field number 2:
+    //   repeated FieldDescriptorProto field = 2;
+    // and FieldDescriptorProto.name has field number 1:
+    //   optional string name = 1;
+    //
+    // Thus, the above path gives the location of a field name.  If we removed
+    // the last element:
+    //   [ 4, 3, 2, 7 ]
+    // this path refers to the whole field declaration (from the beginning
+    // of the label to the terminating semicolon).
+    repeated int32 path = 1 [packed=true];
+
+    // Always has exactly three or four elements: start line, start column,
+    // end line (optional, otherwise assumed same as start line), end column.
+    // These are packed into a single field for efficiency.  Note that line
+    // and column numbers are zero-based -- typically you will want to add
+    // 1 to each before displaying to a user.
+    repeated int32 span = 2 [packed=true];
+
+    // If this SourceCodeInfo represents a complete declaration, these are any
+    // comments appearing before and after the declaration which appear to be
+    // attached to the declaration.
+    //
+    // A series of line comments appearing on consecutive lines, with no other
+    // tokens appearing on those lines, will be treated as a single comment.
+    //
+    // Only the comment content is provided; comment markers (e.g. //) are
+    // stripped out.  For block comments, leading whitespace and an asterisk
+    // will be stripped from the beginning of each line other than the first.
+    // Newlines are included in the output.
+    //
+    // Examples:
+    //
+    //   optional int32 foo = 1;  // Comment attached to foo.
+    //   // Comment attached to bar.
+    //   optional int32 bar = 2;
+    //
+    //   optional string baz = 3;
+    //   // Comment attached to baz.
+    //   // Another line attached to baz.
+    //
+    //   // Comment attached to qux.
+    //   //
+    //   // Another line attached to qux.
+    //   optional double qux = 4;
+    //
+    //   optional string corge = 5;
+    //   /* Block comment attached
+    //    * to corge.  Leading asterisks
+    //    * will be removed. */
+    //   /* Block comment attached to
+    //    * grault. */
+    //   optional int32 grault = 6;
+    optional string leading_comments = 3;
+    optional string trailing_comments = 4;
+  }
+}
diff --git a/protobuf/src/google/protobuf/descriptor_database.cc b/protobuf/src/google/protobuf/descriptor_database.cc
new file mode 100644
index 0000000..d024eab
--- /dev/null
+++ b/protobuf/src/google/protobuf/descriptor_database.cc
@@ -0,0 +1,543 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <set>
+
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stl_util.h>
+#include <google/protobuf/stubs/map_util.h>
+
+namespace google {
+namespace protobuf {
+
+DescriptorDatabase::~DescriptorDatabase() {}
+
+// ===================================================================
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddFile(
+    const FileDescriptorProto& file,
+    Value value) {
+  if (!InsertIfNotPresent(&by_name_, file.name(), value)) {
+    GOOGLE_LOG(ERROR) << "File already exists in database: " << file.name();
+    return false;
+  }
+
+  // We must be careful here -- calling file.package() if file.has_package() is
+  // false could access an uninitialized static-storage variable if we are being
+  // run at startup time.
+  string path = file.has_package() ? file.package() : string();
+  if (!path.empty()) path += '.';
+
+  for (int i = 0; i < file.message_type_size(); i++) {
+    if (!AddSymbol(path + file.message_type(i).name(), value)) return false;
+    if (!AddNestedExtensions(file.message_type(i), value)) return false;
+  }
+  for (int i = 0; i < file.enum_type_size(); i++) {
+    if (!AddSymbol(path + file.enum_type(i).name(), value)) return false;
+  }
+  for (int i = 0; i < file.extension_size(); i++) {
+    if (!AddSymbol(path + file.extension(i).name(), value)) return false;
+    if (!AddExtension(file.extension(i), value)) return false;
+  }
+  for (int i = 0; i < file.service_size(); i++) {
+    if (!AddSymbol(path + file.service(i).name(), value)) return false;
+  }
+
+  return true;
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddSymbol(
+    const string& name, Value value) {
+  // We need to make sure not to violate our map invariant.
+
+  // If the symbol name is invalid it could break our lookup algorithm (which
+  // relies on the fact that '.' sorts before all other characters that are
+  // valid in symbol names).
+  if (!ValidateSymbolName(name)) {
+    GOOGLE_LOG(ERROR) << "Invalid symbol name: " << name;
+    return false;
+  }
+
+  // Try to look up the symbol to make sure a super-symbol doesn't already
+  // exist.
+  typename map<string, Value>::iterator iter = FindLastLessOrEqual(name);
+
+  if (iter == by_symbol_.end()) {
+    // Apparently the map is currently empty.  Just insert and be done with it.
+    by_symbol_.insert(typename map<string, Value>::value_type(name, value));
+    return true;
+  }
+
+  if (IsSubSymbol(iter->first, name)) {
+    GOOGLE_LOG(ERROR) << "Symbol name \"" << name << "\" conflicts with the existing "
+                  "symbol \"" << iter->first << "\".";
+    return false;
+  }
+
+  // OK, that worked.  Now we have to make sure that no symbol in the map is
+  // a sub-symbol of the one we are inserting.  The only symbol which could
+  // be so is the first symbol that is greater than the new symbol.  Since
+  // |iter| points at the last symbol that is less than or equal, we just have
+  // to increment it.
+  ++iter;
+
+  if (iter != by_symbol_.end() && IsSubSymbol(name, iter->first)) {
+    GOOGLE_LOG(ERROR) << "Symbol name \"" << name << "\" conflicts with the existing "
+                  "symbol \"" << iter->first << "\".";
+    return false;
+  }
+
+  // OK, no conflicts.
+
+  // Insert the new symbol using the iterator as a hint, the new entry will
+  // appear immediately before the one the iterator is pointing at.
+  by_symbol_.insert(iter, typename map<string, Value>::value_type(name, value));
+
+  return true;
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddNestedExtensions(
+    const DescriptorProto& message_type,
+    Value value) {
+  for (int i = 0; i < message_type.nested_type_size(); i++) {
+    if (!AddNestedExtensions(message_type.nested_type(i), value)) return false;
+  }
+  for (int i = 0; i < message_type.extension_size(); i++) {
+    if (!AddExtension(message_type.extension(i), value)) return false;
+  }
+  return true;
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::AddExtension(
+    const FieldDescriptorProto& field,
+    Value value) {
+  if (!field.extendee().empty() && field.extendee()[0] == '.') {
+    // The extension is fully-qualified.  We can use it as a lookup key in
+    // the by_symbol_ table.
+    if (!InsertIfNotPresent(&by_extension_,
+                            make_pair(field.extendee().substr(1),
+                                      field.number()),
+                            value)) {
+      GOOGLE_LOG(ERROR) << "Extension conflicts with extension already in database: "
+                    "extend " << field.extendee() << " { "
+                 << field.name() << " = " << field.number() << " }";
+      return false;
+    }
+  } else {
+    // Not fully-qualified.  We can't really do anything here, unfortunately.
+    // We don't consider this an error, though, because the descriptor is
+    // valid.
+  }
+  return true;
+}
+
+template <typename Value>
+Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindFile(
+    const string& filename) {
+  return FindWithDefault(by_name_, filename, Value());
+}
+
+template <typename Value>
+Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindSymbol(
+    const string& name) {
+  typename map<string, Value>::iterator iter = FindLastLessOrEqual(name);
+
+  return (iter != by_symbol_.end() && IsSubSymbol(iter->first, name)) ?
+         iter->second : Value();
+}
+
+template <typename Value>
+Value SimpleDescriptorDatabase::DescriptorIndex<Value>::FindExtension(
+    const string& containing_type,
+    int field_number) {
+  return FindWithDefault(by_extension_,
+                         make_pair(containing_type, field_number),
+                         Value());
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::FindAllExtensionNumbers(
+    const string& containing_type,
+    vector<int>* output) {
+  typename map<pair<string, int>, Value >::const_iterator it =
+      by_extension_.lower_bound(make_pair(containing_type, 0));
+  bool success = false;
+
+  for (; it != by_extension_.end() && it->first.first == containing_type;
+       ++it) {
+    output->push_back(it->first.second);
+    success = true;
+  }
+
+  return success;
+}
+
+template <typename Value>
+typename map<string, Value>::iterator
+SimpleDescriptorDatabase::DescriptorIndex<Value>::FindLastLessOrEqual(
+    const string& name) {
+  // Find the last key in the map which sorts less than or equal to the
+  // symbol name.  Since upper_bound() returns the *first* key that sorts
+  // *greater* than the input, we want the element immediately before that.
+  typename map<string, Value>::iterator iter = by_symbol_.upper_bound(name);
+  if (iter != by_symbol_.begin()) --iter;
+  return iter;
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::IsSubSymbol(
+    const string& sub_symbol, const string& super_symbol) {
+  return sub_symbol == super_symbol ||
+         (HasPrefixString(super_symbol, sub_symbol) &&
+             super_symbol[sub_symbol.size()] == '.');
+}
+
+template <typename Value>
+bool SimpleDescriptorDatabase::DescriptorIndex<Value>::ValidateSymbolName(
+    const string& name) {
+  for (int i = 0; i < name.size(); i++) {
+    // I don't trust ctype.h due to locales.  :(
+    if (name[i] != '.' && name[i] != '_' &&
+        (name[i] < '0' || name[i] > '9') &&
+        (name[i] < 'A' || name[i] > 'Z') &&
+        (name[i] < 'a' || name[i] > 'z')) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// -------------------------------------------------------------------
+
+SimpleDescriptorDatabase::SimpleDescriptorDatabase() {}
+SimpleDescriptorDatabase::~SimpleDescriptorDatabase() {
+  STLDeleteElements(&files_to_delete_);
+}
+
+bool SimpleDescriptorDatabase::Add(const FileDescriptorProto& file) {
+  FileDescriptorProto* new_file = new FileDescriptorProto;
+  new_file->CopyFrom(file);
+  return AddAndOwn(new_file);
+}
+
+bool SimpleDescriptorDatabase::AddAndOwn(const FileDescriptorProto* file) {
+  files_to_delete_.push_back(file);
+  return index_.AddFile(*file, file);
+}
+
+bool SimpleDescriptorDatabase::FindFileByName(
+    const string& filename,
+    FileDescriptorProto* output) {
+  return MaybeCopy(index_.FindFile(filename), output);
+}
+
+bool SimpleDescriptorDatabase::FindFileContainingSymbol(
+    const string& symbol_name,
+    FileDescriptorProto* output) {
+  return MaybeCopy(index_.FindSymbol(symbol_name), output);
+}
+
+bool SimpleDescriptorDatabase::FindFileContainingExtension(
+    const string& containing_type,
+    int field_number,
+    FileDescriptorProto* output) {
+  return MaybeCopy(index_.FindExtension(containing_type, field_number), output);
+}
+
+bool SimpleDescriptorDatabase::FindAllExtensionNumbers(
+    const string& extendee_type,
+    vector<int>* output) {
+  return index_.FindAllExtensionNumbers(extendee_type, output);
+}
+
+
+bool SimpleDescriptorDatabase::MaybeCopy(const FileDescriptorProto* file,
+                                         FileDescriptorProto* output) {
+  if (file == NULL) return false;
+  output->CopyFrom(*file);
+  return true;
+}
+
+// -------------------------------------------------------------------
+
+EncodedDescriptorDatabase::EncodedDescriptorDatabase() {}
+EncodedDescriptorDatabase::~EncodedDescriptorDatabase() {
+  for (int i = 0; i < files_to_delete_.size(); i++) {
+    operator delete(files_to_delete_[i]);
+  }
+}
+
+bool EncodedDescriptorDatabase::Add(
+    const void* encoded_file_descriptor, int size) {
+  FileDescriptorProto file;
+  if (file.ParseFromArray(encoded_file_descriptor, size)) {
+    return index_.AddFile(file, make_pair(encoded_file_descriptor, size));
+  } else {
+    GOOGLE_LOG(ERROR) << "Invalid file descriptor data passed to "
+                  "EncodedDescriptorDatabase::Add().";
+    return false;
+  }
+}
+
+bool EncodedDescriptorDatabase::AddCopy(
+    const void* encoded_file_descriptor, int size) {
+  void* copy = operator new(size);
+  memcpy(copy, encoded_file_descriptor, size);
+  files_to_delete_.push_back(copy);
+  return Add(copy, size);
+}
+
+bool EncodedDescriptorDatabase::FindFileByName(
+    const string& filename,
+    FileDescriptorProto* output) {
+  return MaybeParse(index_.FindFile(filename), output);
+}
+
+bool EncodedDescriptorDatabase::FindFileContainingSymbol(
+    const string& symbol_name,
+    FileDescriptorProto* output) {
+  return MaybeParse(index_.FindSymbol(symbol_name), output);
+}
+
+bool EncodedDescriptorDatabase::FindNameOfFileContainingSymbol(
+    const string& symbol_name,
+    string* output) {
+  pair<const void*, int> encoded_file = index_.FindSymbol(symbol_name);
+  if (encoded_file.first == NULL) return false;
+
+  // Optimization:  The name should be the first field in the encoded message.
+  //   Try to just read it directly.
+  io::CodedInputStream input(reinterpret_cast<const uint8*>(encoded_file.first),
+                             encoded_file.second);
+
+  const uint32 kNameTag = internal::WireFormatLite::MakeTag(
+      FileDescriptorProto::kNameFieldNumber,
+      internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+
+  if (input.ReadTag() == kNameTag) {
+    // Success!
+    return internal::WireFormatLite::ReadString(&input, output);
+  } else {
+    // Slow path.  Parse whole message.
+    FileDescriptorProto file_proto;
+    if (!file_proto.ParseFromArray(encoded_file.first, encoded_file.second)) {
+      return false;
+    }
+    *output = file_proto.name();
+    return true;
+  }
+}
+
+bool EncodedDescriptorDatabase::FindFileContainingExtension(
+    const string& containing_type,
+    int field_number,
+    FileDescriptorProto* output) {
+  return MaybeParse(index_.FindExtension(containing_type, field_number),
+                    output);
+}
+
+bool EncodedDescriptorDatabase::FindAllExtensionNumbers(
+    const string& extendee_type,
+    vector<int>* output) {
+  return index_.FindAllExtensionNumbers(extendee_type, output);
+}
+
+bool EncodedDescriptorDatabase::MaybeParse(
+    pair<const void*, int> encoded_file,
+    FileDescriptorProto* output) {
+  if (encoded_file.first == NULL) return false;
+  return output->ParseFromArray(encoded_file.first, encoded_file.second);
+}
+
+// ===================================================================
+
+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;
+}
+
+bool DescriptorPoolDatabase::FindAllExtensionNumbers(
+    const string& extendee_type,
+    vector<int>* output) {
+  const Descriptor* extendee = pool_.FindMessageTypeByName(extendee_type);
+  if (extendee == NULL) return false;
+
+  vector<const FieldDescriptor*> extensions;
+  pool_.FindAllExtensions(extendee, &extensions);
+
+  for (int i = 0; i < extensions.size(); ++i) {
+    output->push_back(extensions[i]->number());
+  }
+
+  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;
+}
+
+bool MergedDescriptorDatabase::FindAllExtensionNumbers(
+    const string& extendee_type,
+    vector<int>* output) {
+  set<int> merged_results;
+  vector<int> results;
+  bool success = false;
+
+  for (int i = 0; i < sources_.size(); i++) {
+    if (sources_[i]->FindAllExtensionNumbers(extendee_type, &results)) {
+      copy(results.begin(), results.end(),
+           insert_iterator<set<int> >(merged_results, merged_results.begin()));
+      success = true;
+    }
+    results.clear();
+  }
+
+  copy(merged_results.begin(), merged_results.end(),
+       insert_iterator<vector<int> >(*output, output->end()));
+
+  return success;
+}
+
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/descriptor_database.h b/protobuf/src/google/protobuf/descriptor_database.h
new file mode 100644
index 0000000..934e402
--- /dev/null
+++ b/protobuf/src/google/protobuf/descriptor_database.h
@@ -0,0 +1,369 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+
+// Defined in this file.
+class DescriptorDatabase;
+class SimpleDescriptorDatabase;
+class EncodedDescriptorDatabase;
+class DescriptorPoolDatabase;
+class MergedDescriptorDatabase;
+
+// 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;
+
+  // Finds the tag numbers used by all known extensions of
+  // extendee_type, and appends them to output in an undefined
+  // order. This method is best-effort: it's not guaranteed that the
+  // database will find all extensions, and it's not guaranteed that
+  // FindFileContainingExtension will return true on all of the found
+  // numbers. Returns true if the search was successful, otherwise
+  // returns false and leaves output unchanged.
+  //
+  // This method has a default implementation that always returns
+  // false.
+  virtual bool FindAllExtensionNumbers(const string& /* extendee_type */,
+                                       vector<int>* /* output */) {
+    return false;
+  }
+
+
+ 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.  Note that the implementation
+// may return false positives, but only if it isn't possible for the symbol
+// to be defined in any other file.  In particular, if a file defines a symbol
+// "Foo", then searching for "Foo.[anything]" will match that file.  This way,
+// the database does not need to aggressively index all children of a symbol.
+//
+// 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.  Returns false if the file conflicted
+  // with a file already in the database, in which case an error will have
+  // been written to GOOGLE_LOG(ERROR).
+  bool Add(const FileDescriptorProto& file);
+
+  // Adds the FileDescriptorProto to the database and takes ownership of it.
+  bool 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);
+  bool FindAllExtensionNumbers(const string& extendee_type,
+                               vector<int>* output);
+
+ private:
+  // So that it can use DescriptorIndex.
+  friend class EncodedDescriptorDatabase;
+
+  // An index mapping file names, symbol names, and extension numbers to
+  // some sort of values.
+  template <typename Value>
+  class DescriptorIndex {
+   public:
+    // Helpers to recursively add particular descriptors and all their contents
+    // to the index.
+    bool AddFile(const FileDescriptorProto& file,
+                 Value value);
+    bool AddSymbol(const string& name, Value value);
+    bool AddNestedExtensions(const DescriptorProto& message_type,
+                             Value value);
+    bool AddExtension(const FieldDescriptorProto& field,
+                      Value value);
+
+    Value FindFile(const string& filename);
+    Value FindSymbol(const string& name);
+    Value FindExtension(const string& containing_type, int field_number);
+    bool FindAllExtensionNumbers(const string& containing_type,
+                                 vector<int>* output);
+
+   private:
+    map<string, Value> by_name_;
+    map<string, Value> by_symbol_;
+    map<pair<string, int>, Value> by_extension_;
+
+    // Invariant:  The by_symbol_ map does not contain any symbols which are
+    // prefixes of other symbols in the map.  For example, "foo.bar" is a
+    // prefix of "foo.bar.baz" (but is not a prefix of "foo.barbaz").
+    //
+    // This invariant is important because it means that given a symbol name,
+    // we can find a key in the map which is a prefix of the symbol in O(lg n)
+    // time, and we know that there is at most one such key.
+    //
+    // The prefix lookup algorithm works like so:
+    // 1) Find the last key in the map which is less than or equal to the
+    //    search key.
+    // 2) If the found key is a prefix of the search key, then return it.
+    //    Otherwise, there is no match.
+    //
+    // I am sure this algorithm has been described elsewhere, but since I
+    // wasn't able to find it quickly I will instead prove that it works
+    // myself.  The key to the algorithm is that if a match exists, step (1)
+    // will find it.  Proof:
+    // 1) Define the "search key" to be the key we are looking for, the "found
+    //    key" to be the key found in step (1), and the "match key" to be the
+    //    key which actually matches the serach key (i.e. the key we're trying
+    //    to find).
+    // 2) The found key must be less than or equal to the search key by
+    //    definition.
+    // 3) The match key must also be less than or equal to the search key
+    //    (because it is a prefix).
+    // 4) The match key cannot be greater than the found key, because if it
+    //    were, then step (1) of the algorithm would have returned the match
+    //    key instead (since it finds the *greatest* key which is less than or
+    //    equal to the search key).
+    // 5) Therefore, the found key must be between the match key and the search
+    //    key, inclusive.
+    // 6) Since the search key must be a sub-symbol of the match key, if it is
+    //    not equal to the match key, then search_key[match_key.size()] must
+    //    be '.'.
+    // 7) Since '.' sorts before any other character that is valid in a symbol
+    //    name, then if the found key is not equal to the match key, then
+    //    found_key[match_key.size()] must also be '.', because any other value
+    //    would make it sort after the search key.
+    // 8) Therefore, if the found key is not equal to the match key, then the
+    //    found key must be a sub-symbol of the match key.  However, this would
+    //    contradict our map invariant which says that no symbol in the map is
+    //    a sub-symbol of any other.
+    // 9) Therefore, the found key must match the match key.
+    //
+    // The above proof assumes the match key exists.  In the case that the
+    // match key does not exist, then step (1) will return some other symbol.
+    // That symbol cannot be a super-symbol of the search key since if it were,
+    // then it would be a match, and we're assuming the match key doesn't exist.
+    // Therefore, step 2 will correctly return no match.
+
+    // Find the last entry in the by_symbol_ map whose key is less than or
+    // equal to the given name.
+    typename map<string, Value>::iterator FindLastLessOrEqual(
+        const string& name);
+
+    // True if either the arguments are equal or super_symbol identifies a
+    // parent symbol of sub_symbol (e.g. "foo.bar" is a parent of
+    // "foo.bar.baz", but not a parent of "foo.barbaz").
+    bool IsSubSymbol(const string& sub_symbol, const string& super_symbol);
+
+    // Returns true if and only if all characters in the name are alphanumerics,
+    // underscores, or periods.
+    bool ValidateSymbolName(const string& name);
+  };
+
+
+  DescriptorIndex<const FileDescriptorProto*> index_;
+  vector<const FileDescriptorProto*> files_to_delete_;
+
+  // If file is non-NULL, copy it into *output and return true, otherwise
+  // return false.
+  bool MaybeCopy(const FileDescriptorProto* file,
+                 FileDescriptorProto* output);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SimpleDescriptorDatabase);
+};
+
+// Very similar to SimpleDescriptorDatabase, but stores all the descriptors
+// as raw bytes and generally tries to use as little memory as possible.
+//
+// The same caveats regarding FindFileContainingExtension() apply as with
+// SimpleDescriptorDatabase.
+class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase {
+ public:
+  EncodedDescriptorDatabase();
+  ~EncodedDescriptorDatabase();
+
+  // Adds the FileDescriptorProto to the database.  The descriptor is provided
+  // in encoded form.  The database does not make a copy of the bytes, nor
+  // does it take ownership; it's up to the caller to make sure the bytes
+  // remain valid for the life of the database.  Returns false and logs an error
+  // if the bytes are not a valid FileDescriptorProto or if the file conflicted
+  // with a file already in the database.
+  bool Add(const void* encoded_file_descriptor, int size);
+
+  // Like Add(), but makes a copy of the data, so that the caller does not
+  // need to keep it around.
+  bool AddCopy(const void* encoded_file_descriptor, int size);
+
+  // Like FindFileContainingSymbol but returns only the name of the file.
+  bool FindNameOfFileContainingSymbol(const string& symbol_name,
+                                      string* output);
+
+  // 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);
+  bool FindAllExtensionNumbers(const string& extendee_type,
+                               vector<int>* output);
+
+ private:
+  SimpleDescriptorDatabase::DescriptorIndex<pair<const void*, int> > index_;
+  vector<void*> files_to_delete_;
+
+  // If encoded_file.first is non-NULL, parse the data into *output and return
+  // true, otherwise return false.
+  bool MaybeParse(pair<const void*, int> encoded_file,
+                  FileDescriptorProto* output);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EncodedDescriptorDatabase);
+};
+
+// 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);
+  bool FindAllExtensionNumbers(const string& extendee_type,
+                               vector<int>* 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);
+  // Merges the results of calling all databases. Returns true iff any
+  // of the databases returned true.
+  bool FindAllExtensionNumbers(const string& extendee_type,
+                               vector<int>* output);
+
+
+ private:
+  vector<DescriptorDatabase*> sources_;
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MergedDescriptorDatabase);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_DESCRIPTOR_DATABASE_H__
diff --git a/protobuf/src/google/protobuf/descriptor_database_unittest.cc b/protobuf/src/google/protobuf/descriptor_database_unittest.cc
new file mode 100644
index 0000000..6642d71
--- /dev/null
+++ b/protobuf/src/google/protobuf/descriptor_database_unittest.cc
@@ -0,0 +1,748 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <algorithm>
+
+#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 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 << "\".";
+}
+
+// ===================================================================
+
+#if GTEST_HAS_PARAM_TEST
+
+// SimpleDescriptorDatabase, EncodedDescriptorDatabase, and
+// DescriptorPoolDatabase call for very similar tests.  Instead of writing
+// three nearly-identical sets of tests, we use parameterized tests to apply
+// the same code to all three.
+
+// The parameterized test runs against a DescriptarDatabaseTestCase.  We have
+// implementations for each of the three classes we want to test.
+class DescriptorDatabaseTestCase {
+ public:
+  virtual ~DescriptorDatabaseTestCase() {}
+
+  virtual DescriptorDatabase* GetDatabase() = 0;
+  virtual bool AddToDatabase(const FileDescriptorProto& file) = 0;
+};
+
+// Factory function type.
+typedef DescriptorDatabaseTestCase* DescriptorDatabaseTestCaseFactory();
+
+// Specialization for SimpleDescriptorDatabase.
+class SimpleDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase {
+ public:
+  static DescriptorDatabaseTestCase* New() {
+    return new SimpleDescriptorDatabaseTestCase;
+  }
+
+  virtual ~SimpleDescriptorDatabaseTestCase() {}
+
+  virtual DescriptorDatabase* GetDatabase() {
+    return &database_;
+  }
+  virtual bool AddToDatabase(const FileDescriptorProto& file) {
+    return database_.Add(file);
+  }
+
+ private:
+  SimpleDescriptorDatabase database_;
+};
+
+// Specialization for EncodedDescriptorDatabase.
+class EncodedDescriptorDatabaseTestCase : public DescriptorDatabaseTestCase {
+ public:
+  static DescriptorDatabaseTestCase* New() {
+    return new EncodedDescriptorDatabaseTestCase;
+  }
+
+  virtual ~EncodedDescriptorDatabaseTestCase() {}
+
+  virtual DescriptorDatabase* GetDatabase() {
+    return &database_;
+  }
+  virtual bool AddToDatabase(const FileDescriptorProto& file) {
+    string data;
+    file.SerializeToString(&data);
+    return database_.AddCopy(data.data(), data.size());
+  }
+
+ private:
+  EncodedDescriptorDatabase database_;
+};
+
+// Specialization for DescriptorPoolDatabase.
+class DescriptorPoolDatabaseTestCase : public DescriptorDatabaseTestCase {
+ public:
+  static DescriptorDatabaseTestCase* New() {
+    return new EncodedDescriptorDatabaseTestCase;
+  }
+
+  DescriptorPoolDatabaseTestCase() : database_(pool_) {}
+  virtual ~DescriptorPoolDatabaseTestCase() {}
+
+  virtual DescriptorDatabase* GetDatabase() {
+    return &database_;
+  }
+  virtual bool AddToDatabase(const FileDescriptorProto& file) {
+    return pool_.BuildFile(file);
+  }
+
+ private:
+  DescriptorPool pool_;
+  DescriptorPoolDatabase database_;
+};
+
+// -------------------------------------------------------------------
+
+class DescriptorDatabaseTest
+    : public testing::TestWithParam<DescriptorDatabaseTestCaseFactory*> {
+ protected:
+  virtual void SetUp() {
+    test_case_.reset(GetParam()());
+    database_ = test_case_->GetDatabase();
+  }
+
+  void AddToDatabase(const char* file_descriptor_text) {
+    FileDescriptorProto file_proto;
+    EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto));
+    EXPECT_TRUE(test_case_->AddToDatabase(file_proto));
+  }
+
+  void AddToDatabaseWithError(const char* file_descriptor_text) {
+    FileDescriptorProto file_proto;
+    EXPECT_TRUE(TextFormat::ParseFromString(file_descriptor_text, &file_proto));
+    EXPECT_FALSE(test_case_->AddToDatabase(file_proto));
+  }
+
+  scoped_ptr<DescriptorDatabaseTestCase> test_case_;
+  DescriptorDatabase* database_;
+};
+
+TEST_P(DescriptorDatabaseTest, FindFileByName) {
+  AddToDatabase(
+    "name: \"foo.proto\" "
+    "message_type { name:\"Foo\" }");
+  AddToDatabase(
+    "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_P(DescriptorDatabaseTest, FindFileContainingSymbol) {
+  AddToDatabase(
+    "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(
+    "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_P(DescriptorDatabaseTest, FindFileContainingExtension) {
+  AddToDatabase(
+    "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(
+    "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_P(DescriptorDatabaseTest, FindAllExtensionNumbers) {
+  AddToDatabase(
+    "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(
+    "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 } ");
+
+  {
+    vector<int> numbers;
+    EXPECT_TRUE(database_->FindAllExtensionNumbers("Foo", &numbers));
+    ASSERT_EQ(2, numbers.size());
+    sort(numbers.begin(), numbers.end());
+    EXPECT_EQ(5, numbers[0]);
+    EXPECT_EQ(32, numbers[1]);
+  }
+
+  {
+    vector<int> numbers;
+    EXPECT_TRUE(database_->FindAllExtensionNumbers("corge.Bar", &numbers));
+    // Note: won't find extension 56 due to the name not being fully qualified.
+    ASSERT_EQ(1, numbers.size());
+    EXPECT_EQ(70, numbers[0]);
+  }
+
+  {
+    // Can't find extensions for non-existent types.
+    vector<int> numbers;
+    EXPECT_FALSE(database_->FindAllExtensionNumbers("NoSuchType", &numbers));
+  }
+
+  {
+    // Can't find extensions for unqualified types.
+    vector<int> numbers;
+    EXPECT_FALSE(database_->FindAllExtensionNumbers("Bar", &numbers));
+  }
+}
+
+TEST_P(DescriptorDatabaseTest, ConflictingFileError) {
+  AddToDatabase(
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"Foo\" "
+    "}");
+  AddToDatabaseWithError(
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"Bar\" "
+    "}");
+}
+
+TEST_P(DescriptorDatabaseTest, ConflictingTypeError) {
+  AddToDatabase(
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"Foo\" "
+    "}");
+  AddToDatabaseWithError(
+    "name: \"bar.proto\" "
+    "message_type { "
+    "  name: \"Foo\" "
+    "}");
+}
+
+TEST_P(DescriptorDatabaseTest, ConflictingExtensionError) {
+  AddToDatabase(
+    "name: \"foo.proto\" "
+    "extension { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
+    "            extendee: \".Foo\" }");
+  AddToDatabaseWithError(
+    "name: \"bar.proto\" "
+    "extension { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:5 "
+    "            extendee: \".Foo\" }");
+}
+
+INSTANTIATE_TEST_CASE_P(Simple, DescriptorDatabaseTest,
+    testing::Values(&SimpleDescriptorDatabaseTestCase::New));
+INSTANTIATE_TEST_CASE_P(MemoryConserving, DescriptorDatabaseTest,
+    testing::Values(&EncodedDescriptorDatabaseTestCase::New));
+INSTANTIATE_TEST_CASE_P(Pool, DescriptorDatabaseTest,
+    testing::Values(&DescriptorPoolDatabaseTestCase::New));
+
+#endif  // GTEST_HAS_PARAM_TEST
+
+TEST(EncodedDescriptorDatabaseExtraTest, FindNameOfFileContainingSymbol) {
+  // Create two files, one of which is in two parts.
+  FileDescriptorProto file1, file2a, file2b;
+  file1.set_name("foo.proto");
+  file1.set_package("foo");
+  file1.add_message_type()->set_name("Foo");
+  file2a.set_name("bar.proto");
+  file2b.set_package("bar");
+  file2b.add_message_type()->set_name("Bar");
+
+  // Normal serialization allows our optimization to kick in.
+  string data1 = file1.SerializeAsString();
+
+  // Force out-of-order serialization to test slow path.
+  string data2 = file2b.SerializeAsString() + file2a.SerializeAsString();
+
+  // Create EncodedDescriptorDatabase containing both files.
+  EncodedDescriptorDatabase db;
+  db.Add(data1.data(), data1.size());
+  db.Add(data2.data(), data2.size());
+
+  // Test!
+  string filename;
+  EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo", &filename));
+  EXPECT_EQ("foo.proto", filename);
+  EXPECT_TRUE(db.FindNameOfFileContainingSymbol("foo.Foo.Blah", &filename));
+  EXPECT_EQ("foo.proto", filename);
+  EXPECT_TRUE(db.FindNameOfFileContainingSymbol("bar.Bar", &filename));
+  EXPECT_EQ("bar.proto", filename);
+  EXPECT_FALSE(db.FindNameOfFileContainingSymbol("foo", &filename));
+  EXPECT_FALSE(db.FindNameOfFileContainingSymbol("bar", &filename));
+  EXPECT_FALSE(db.FindNameOfFileContainingSymbol("baz.Baz", &filename));
+}
+
+// ===================================================================
+
+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));
+  }
+}
+
+TEST_F(MergedDescriptorDatabaseTest, FindAllExtensionNumbers) {
+  {
+    // Message only has extension in database1_
+    vector<int> numbers;
+    EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Foo", &numbers));
+    ASSERT_EQ(1, numbers.size());
+    EXPECT_EQ(3, numbers[0]);
+  }
+
+  {
+    // Message only has extension in database2_
+    vector<int> numbers;
+    EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Bar", &numbers));
+    ASSERT_EQ(1, numbers.size());
+    EXPECT_EQ(5, numbers[0]);
+  }
+
+  {
+    // Merge results from the two databases.
+    vector<int> numbers;
+    EXPECT_TRUE(forward_merged_.FindAllExtensionNumbers("Baz", &numbers));
+    ASSERT_EQ(2, numbers.size());
+    sort(numbers.begin(), numbers.end());
+    EXPECT_EQ(12, numbers[0]);
+    EXPECT_EQ(13, numbers[1]);
+  }
+
+  {
+    vector<int> numbers;
+    EXPECT_TRUE(reverse_merged_.FindAllExtensionNumbers("Baz", &numbers));
+    ASSERT_EQ(2, numbers.size());
+    sort(numbers.begin(), numbers.end());
+    EXPECT_EQ(12, numbers[0]);
+    EXPECT_EQ(13, numbers[1]);
+  }
+
+  {
+    // Can't find extensions for a non-existent message.
+    vector<int> numbers;
+    EXPECT_FALSE(reverse_merged_.FindAllExtensionNumbers("Blah", &numbers));
+  }
+}
+
+}  // anonymous namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/descriptor_pb2_test.py b/protobuf/src/google/protobuf/descriptor_pb2_test.py
new file mode 100644
index 0000000..48a0d48
--- /dev/null
+++ b/protobuf/src/google/protobuf/descriptor_pb2_test.py
@@ -0,0 +1,54 @@
+#! /usr/bin/python
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2008 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Verify that prebuild and checkedin version of descriptor_pb2.py is up to date.
+
+from google3.pyglib import resources
+import unittest
+
+_DESC = 'google3/net/proto2/proto/descriptor_pb2.'
+_OLD = _DESC + 'py-prebuilt'
+_NEW = _DESC + 'compiled'
+
+
+class PregeneratedFileChanged(unittest.TestCase):
+
+  def testSameText(self):
+    generated = resources.GetResource(_NEW)
+    checkedin = resources.GetResource(_OLD)
+    self.assertMultiLineEqual(
+        generated, checkedin, 'It seems that protoc _pb2 generator changed. '
+        'Please run google/protobuf/generate_descriptor_proto.sh to '
+        'regnerate a new version of %s and add it to your CL' % _OLD)
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/protobuf/src/google/protobuf/descriptor_unittest.cc b/protobuf/src/google/protobuf/descriptor_unittest.cc
new file mode 100644
index 0000000..ac96160
--- /dev/null
+++ b/protobuf/src/google/protobuf/descriptor_unittest.cc
@@ -0,0 +1,5501 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/compiler/importer.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/unittest_custom_options.pb.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/text_format.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 {
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace descriptor_unittest {
+
+// 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_F(FileDescriptorTest, BuildAgain) {
+  // Test that if te call BuildFile again on the same input we get the same
+  // FileDescriptor back.
+  FileDescriptorProto file;
+  foo_file_->CopyTo(&file);
+  EXPECT_EQ(foo_file_, pool_.BuildFile(file));
+
+  // But if we change the file then it won't work.
+  file.set_package("some.other.package");
+  EXPECT_TRUE(pool_.BuildFile(file) == 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 simple flat messages and fields.
+class OneofDescriptorTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    // Build descriptors for the following definitions:
+    //
+    //   package garply;
+    //   message TestOneof {
+    //     optional int32 a = 1;
+    //     oneof foo {
+    //       string b = 2;
+    //       TestOneof c = 3;
+    //     }
+    //     oneof bar {
+    //       float d = 4;
+    //     }
+    //   }
+
+    FileDescriptorProto baz_file;
+    baz_file.set_name("baz.proto");
+    baz_file.set_package("garply");
+
+    DescriptorProto* oneof_message = AddMessage(&baz_file, "TestOneof");
+    oneof_message->add_oneof_decl()->set_name("foo");
+    oneof_message->add_oneof_decl()->set_name("bar");
+
+    AddField(oneof_message, "a", 1,
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_INT32);
+    AddField(oneof_message, "b", 2,
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_STRING);
+    oneof_message->mutable_field(1)->set_oneof_index(0);
+    AddField(oneof_message, "c", 3,
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_MESSAGE);
+    oneof_message->mutable_field(2)->set_oneof_index(0);
+    oneof_message->mutable_field(2)->set_type_name("TestOneof");
+
+    AddField(oneof_message, "d", 4,
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_FLOAT);
+    oneof_message->mutable_field(3)->set_oneof_index(1);
+
+    // Build the descriptors and get the pointers.
+    baz_file_ = pool_.BuildFile(baz_file);
+    ASSERT_TRUE(baz_file_ != NULL);
+
+    ASSERT_EQ(1, baz_file_->message_type_count());
+    oneof_message_ = baz_file_->message_type(0);
+
+    ASSERT_EQ(2, oneof_message_->oneof_decl_count());
+    oneof_ = oneof_message_->oneof_decl(0);
+    oneof2_ = oneof_message_->oneof_decl(1);
+
+    ASSERT_EQ(4, oneof_message_->field_count());
+    a_ = oneof_message_->field(0);
+    b_ = oneof_message_->field(1);
+    c_ = oneof_message_->field(2);
+    d_ = oneof_message_->field(3);
+  }
+
+  DescriptorPool pool_;
+
+  const FileDescriptor* baz_file_;
+
+  const Descriptor* oneof_message_;
+
+  const OneofDescriptor* oneof_;
+  const OneofDescriptor* oneof2_;
+  const FieldDescriptor* a_;
+  const FieldDescriptor* b_;
+  const FieldDescriptor* c_;
+  const FieldDescriptor* d_;
+  const FieldDescriptor* e_;
+  const FieldDescriptor* f_;
+};
+
+TEST_F(OneofDescriptorTest, Normal) {
+  EXPECT_EQ("foo", oneof_->name());
+  EXPECT_EQ("garply.TestOneof.foo", oneof_->full_name());
+  EXPECT_EQ(0, oneof_->index());
+  ASSERT_EQ(2, oneof_->field_count());
+  EXPECT_EQ(b_, oneof_->field(0));
+  EXPECT_EQ(c_, oneof_->field(1));
+  EXPECT_TRUE(a_->containing_oneof() == NULL);
+  EXPECT_EQ(oneof_, b_->containing_oneof());
+  EXPECT_EQ(oneof_, c_->containing_oneof());
+}
+
+TEST_F(OneofDescriptorTest, FindByName) {
+  EXPECT_EQ(oneof_, oneof_message_->FindOneofByName("foo"));
+  EXPECT_EQ(oneof2_, oneof_message_->FindOneofByName("bar"));
+  EXPECT_TRUE(oneof_message_->FindOneofByName("no_such_oneof") == NULL);
+}
+
+// ===================================================================
+
+class StylizedFieldNamesTest : public testing::Test {
+ protected:
+  void SetUp() {
+    FileDescriptorProto file;
+    file.set_name("foo.proto");
+
+    AddExtensionRange(AddMessage(&file, "ExtendableMessage"), 1, 1000);
+
+    DescriptorProto* message = AddMessage(&file, "TestMessage");
+    AddField(message, "foo_foo", 1,
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_INT32);
+    AddField(message, "FooBar", 2,
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_INT32);
+    AddField(message, "fooBaz", 3,
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_INT32);
+    AddField(message, "fooFoo", 4,  // Camel-case conflict with foo_foo.
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_INT32);
+    AddField(message, "foobar", 5,  // Lower-case conflict with FooBar.
+             FieldDescriptorProto::LABEL_OPTIONAL,
+             FieldDescriptorProto::TYPE_INT32);
+
+    AddNestedExtension(message, "ExtendableMessage", "bar_foo", 1,
+                       FieldDescriptorProto::LABEL_OPTIONAL,
+                       FieldDescriptorProto::TYPE_INT32);
+    AddNestedExtension(message, "ExtendableMessage", "BarBar", 2,
+                       FieldDescriptorProto::LABEL_OPTIONAL,
+                       FieldDescriptorProto::TYPE_INT32);
+    AddNestedExtension(message, "ExtendableMessage", "BarBaz", 3,
+                       FieldDescriptorProto::LABEL_OPTIONAL,
+                       FieldDescriptorProto::TYPE_INT32);
+    AddNestedExtension(message, "ExtendableMessage", "barFoo", 4,  // Conflict
+                       FieldDescriptorProto::LABEL_OPTIONAL,
+                       FieldDescriptorProto::TYPE_INT32);
+    AddNestedExtension(message, "ExtendableMessage", "barbar", 5,  // Conflict
+                       FieldDescriptorProto::LABEL_OPTIONAL,
+                       FieldDescriptorProto::TYPE_INT32);
+
+    AddExtension(&file, "ExtendableMessage", "baz_foo", 11,
+                 FieldDescriptorProto::LABEL_OPTIONAL,
+                 FieldDescriptorProto::TYPE_INT32);
+    AddExtension(&file, "ExtendableMessage", "BazBar", 12,
+                 FieldDescriptorProto::LABEL_OPTIONAL,
+                 FieldDescriptorProto::TYPE_INT32);
+    AddExtension(&file, "ExtendableMessage", "BazBaz", 13,
+                 FieldDescriptorProto::LABEL_OPTIONAL,
+                 FieldDescriptorProto::TYPE_INT32);
+    AddExtension(&file, "ExtendableMessage", "bazFoo", 14,  // Conflict
+                 FieldDescriptorProto::LABEL_OPTIONAL,
+                 FieldDescriptorProto::TYPE_INT32);
+    AddExtension(&file, "ExtendableMessage", "bazbar", 15,  // Conflict
+                 FieldDescriptorProto::LABEL_OPTIONAL,
+                 FieldDescriptorProto::TYPE_INT32);
+
+    file_ = pool_.BuildFile(file);
+    ASSERT_TRUE(file_ != NULL);
+    ASSERT_EQ(2, file_->message_type_count());
+    message_ = file_->message_type(1);
+    ASSERT_EQ("TestMessage", message_->name());
+    ASSERT_EQ(5, message_->field_count());
+    ASSERT_EQ(5, message_->extension_count());
+    ASSERT_EQ(5, file_->extension_count());
+  }
+
+  DescriptorPool pool_;
+  const FileDescriptor* file_;
+  const Descriptor* message_;
+};
+
+TEST_F(StylizedFieldNamesTest, LowercaseName) {
+  EXPECT_EQ("foo_foo", message_->field(0)->lowercase_name());
+  EXPECT_EQ("foobar" , message_->field(1)->lowercase_name());
+  EXPECT_EQ("foobaz" , message_->field(2)->lowercase_name());
+  EXPECT_EQ("foofoo" , message_->field(3)->lowercase_name());
+  EXPECT_EQ("foobar" , message_->field(4)->lowercase_name());
+
+  EXPECT_EQ("bar_foo", message_->extension(0)->lowercase_name());
+  EXPECT_EQ("barbar" , message_->extension(1)->lowercase_name());
+  EXPECT_EQ("barbaz" , message_->extension(2)->lowercase_name());
+  EXPECT_EQ("barfoo" , message_->extension(3)->lowercase_name());
+  EXPECT_EQ("barbar" , message_->extension(4)->lowercase_name());
+
+  EXPECT_EQ("baz_foo", file_->extension(0)->lowercase_name());
+  EXPECT_EQ("bazbar" , file_->extension(1)->lowercase_name());
+  EXPECT_EQ("bazbaz" , file_->extension(2)->lowercase_name());
+  EXPECT_EQ("bazfoo" , file_->extension(3)->lowercase_name());
+  EXPECT_EQ("bazbar" , file_->extension(4)->lowercase_name());
+}
+
+TEST_F(StylizedFieldNamesTest, CamelcaseName) {
+  EXPECT_EQ("fooFoo", message_->field(0)->camelcase_name());
+  EXPECT_EQ("fooBar", message_->field(1)->camelcase_name());
+  EXPECT_EQ("fooBaz", message_->field(2)->camelcase_name());
+  EXPECT_EQ("fooFoo", message_->field(3)->camelcase_name());
+  EXPECT_EQ("foobar", message_->field(4)->camelcase_name());
+
+  EXPECT_EQ("barFoo", message_->extension(0)->camelcase_name());
+  EXPECT_EQ("barBar", message_->extension(1)->camelcase_name());
+  EXPECT_EQ("barBaz", message_->extension(2)->camelcase_name());
+  EXPECT_EQ("barFoo", message_->extension(3)->camelcase_name());
+  EXPECT_EQ("barbar", message_->extension(4)->camelcase_name());
+
+  EXPECT_EQ("bazFoo", file_->extension(0)->camelcase_name());
+  EXPECT_EQ("bazBar", file_->extension(1)->camelcase_name());
+  EXPECT_EQ("bazBaz", file_->extension(2)->camelcase_name());
+  EXPECT_EQ("bazFoo", file_->extension(3)->camelcase_name());
+  EXPECT_EQ("bazbar", file_->extension(4)->camelcase_name());
+}
+
+TEST_F(StylizedFieldNamesTest, FindByLowercaseName) {
+  EXPECT_EQ(message_->field(0),
+            message_->FindFieldByLowercaseName("foo_foo"));
+  EXPECT_EQ(message_->field(1),
+            message_->FindFieldByLowercaseName("foobar"));
+  EXPECT_EQ(message_->field(2),
+            message_->FindFieldByLowercaseName("foobaz"));
+  EXPECT_TRUE(message_->FindFieldByLowercaseName("FooBar") == NULL);
+  EXPECT_TRUE(message_->FindFieldByLowercaseName("fooBaz") == NULL);
+  EXPECT_TRUE(message_->FindFieldByLowercaseName("bar_foo") == NULL);
+  EXPECT_TRUE(message_->FindFieldByLowercaseName("nosuchfield") == NULL);
+
+  EXPECT_EQ(message_->extension(0),
+            message_->FindExtensionByLowercaseName("bar_foo"));
+  EXPECT_EQ(message_->extension(1),
+            message_->FindExtensionByLowercaseName("barbar"));
+  EXPECT_EQ(message_->extension(2),
+            message_->FindExtensionByLowercaseName("barbaz"));
+  EXPECT_TRUE(message_->FindExtensionByLowercaseName("BarBar") == NULL);
+  EXPECT_TRUE(message_->FindExtensionByLowercaseName("barBaz") == NULL);
+  EXPECT_TRUE(message_->FindExtensionByLowercaseName("foo_foo") == NULL);
+  EXPECT_TRUE(message_->FindExtensionByLowercaseName("nosuchfield") == NULL);
+
+  EXPECT_EQ(file_->extension(0),
+            file_->FindExtensionByLowercaseName("baz_foo"));
+  EXPECT_EQ(file_->extension(1),
+            file_->FindExtensionByLowercaseName("bazbar"));
+  EXPECT_EQ(file_->extension(2),
+            file_->FindExtensionByLowercaseName("bazbaz"));
+  EXPECT_TRUE(file_->FindExtensionByLowercaseName("BazBar") == NULL);
+  EXPECT_TRUE(file_->FindExtensionByLowercaseName("bazBaz") == NULL);
+  EXPECT_TRUE(file_->FindExtensionByLowercaseName("nosuchfield") == NULL);
+}
+
+TEST_F(StylizedFieldNamesTest, FindByCamelcaseName) {
+  EXPECT_EQ(message_->field(0),
+            message_->FindFieldByCamelcaseName("fooFoo"));
+  EXPECT_EQ(message_->field(1),
+            message_->FindFieldByCamelcaseName("fooBar"));
+  EXPECT_EQ(message_->field(2),
+            message_->FindFieldByCamelcaseName("fooBaz"));
+  EXPECT_TRUE(message_->FindFieldByCamelcaseName("foo_foo") == NULL);
+  EXPECT_TRUE(message_->FindFieldByCamelcaseName("FooBar") == NULL);
+  EXPECT_TRUE(message_->FindFieldByCamelcaseName("barFoo") == NULL);
+  EXPECT_TRUE(message_->FindFieldByCamelcaseName("nosuchfield") == NULL);
+
+  EXPECT_EQ(message_->extension(0),
+            message_->FindExtensionByCamelcaseName("barFoo"));
+  EXPECT_EQ(message_->extension(1),
+            message_->FindExtensionByCamelcaseName("barBar"));
+  EXPECT_EQ(message_->extension(2),
+            message_->FindExtensionByCamelcaseName("barBaz"));
+  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("bar_foo") == NULL);
+  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("BarBar") == NULL);
+  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("fooFoo") == NULL);
+  EXPECT_TRUE(message_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
+
+  EXPECT_EQ(file_->extension(0),
+            file_->FindExtensionByCamelcaseName("bazFoo"));
+  EXPECT_EQ(file_->extension(1),
+            file_->FindExtensionByCamelcaseName("bazBar"));
+  EXPECT_EQ(file_->extension(2),
+            file_->FindExtensionByCamelcaseName("bazBaz"));
+  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("baz_foo") == NULL);
+  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("BazBar") == NULL);
+  EXPECT_TRUE(file_->FindExtensionByCamelcaseName("nosuchfield") == NULL);
+}
+
+// ===================================================================
+
+// 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);
+}
+
+TEST_F(ExtensionDescriptorTest, FindAllExtensions) {
+  vector<const FieldDescriptor*> extensions;
+  pool_.FindAllExtensions(foo_, &extensions);
+  ASSERT_EQ(4, extensions.size());
+  EXPECT_EQ(10, extensions[0]->number());
+  EXPECT_EQ(19, extensions[1]->number());
+  EXPECT_EQ(30, extensions[2]->number());
+  EXPECT_EQ(39, extensions[3]->number());
+}
+
+TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) {
+  DescriptorPool pool;
+  FileDescriptorProto file_proto;
+  // Add "google/protobuf/descriptor.proto".
+  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+  // Add "foo.proto":
+  //   import "google/protobuf/descriptor.proto";
+  //   extend google.protobuf.FieldOptions {
+  //     optional int32 option1 = 1000;
+  //   }
+  file_proto.Clear();
+  file_proto.set_name("foo.proto");
+  file_proto.add_dependency("google/protobuf/descriptor.proto");
+  AddExtension(&file_proto, "google.protobuf.FieldOptions", "option1", 1000,
+               FieldDescriptorProto::LABEL_OPTIONAL,
+               FieldDescriptorProto::TYPE_INT32);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+  // Add "bar.proto":
+  //   import "google/protobuf/descriptor.proto";
+  //   extend google.protobuf.FieldOptions {
+  //     optional int32 option2 = 1000;
+  //   }
+  file_proto.Clear();
+  file_proto.set_name("bar.proto");
+  file_proto.add_dependency("google/protobuf/descriptor.proto");
+  AddExtension(&file_proto, "google.protobuf.FieldOptions", "option2", 1000,
+               FieldDescriptorProto::LABEL_OPTIONAL,
+               FieldDescriptorProto::TYPE_INT32);
+  // Currently we only generate a warning for conflicting extension numbers.
+  // TODO(xiaofeng): Change it to an error.
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+}
+
+// ===================================================================
+
+class MiscTest : public testing::Test {
+ protected:
+  // Function which makes a field descriptor of the given type.
+  const FieldDescriptor* GetFieldDescriptorOfType(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>(static_cast<int>(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.
+    pool_.reset(new DescriptorPool());
+    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);
+    } else {
+      return NULL;
+    }
+  }
+
+  const char* GetTypeNameForFieldType(FieldDescriptor::Type type) {
+    const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+    return field != NULL ? field->type_name() : "";
+  }
+
+  FieldDescriptor::CppType GetCppTypeForFieldType(FieldDescriptor::Type type) {
+    const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+    return field != NULL ? field->cpp_type() :
+        static_cast<FieldDescriptor::CppType>(0);
+  }
+
+  const char* GetCppTypeNameForFieldType(FieldDescriptor::Type type) {
+    const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+    return field != NULL ? field->cpp_type_name() : "";
+  }
+
+  const Descriptor* GetMessageDescriptorForFieldType(
+      FieldDescriptor::Type type) {
+    const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+    return field != NULL ? field->message_type() : NULL;
+  }
+
+  const EnumDescriptor* GetEnumDescriptorForFieldType(
+    FieldDescriptor::Type type) {
+    const FieldDescriptor* field = GetFieldDescriptorOfType(type);
+    return field != NULL ? field->enum_type() : NULL;
+  }
+
+  scoped_ptr<DescriptorPool> pool_;
+};
+
+TEST_F(MiscTest, TypeNames) {
+  // Test that correct type names are returned.
+
+  typedef FieldDescriptor FD;  // avoid ugly line wrapping
+
+  EXPECT_STREQ("double"  , GetTypeNameForFieldType(FD::TYPE_DOUBLE  ));
+  EXPECT_STREQ("float"   , GetTypeNameForFieldType(FD::TYPE_FLOAT   ));
+  EXPECT_STREQ("int64"   , GetTypeNameForFieldType(FD::TYPE_INT64   ));
+  EXPECT_STREQ("uint64"  , GetTypeNameForFieldType(FD::TYPE_UINT64  ));
+  EXPECT_STREQ("int32"   , GetTypeNameForFieldType(FD::TYPE_INT32   ));
+  EXPECT_STREQ("fixed64" , GetTypeNameForFieldType(FD::TYPE_FIXED64 ));
+  EXPECT_STREQ("fixed32" , GetTypeNameForFieldType(FD::TYPE_FIXED32 ));
+  EXPECT_STREQ("bool"    , GetTypeNameForFieldType(FD::TYPE_BOOL    ));
+  EXPECT_STREQ("string"  , GetTypeNameForFieldType(FD::TYPE_STRING  ));
+  EXPECT_STREQ("group"   , GetTypeNameForFieldType(FD::TYPE_GROUP   ));
+  EXPECT_STREQ("message" , GetTypeNameForFieldType(FD::TYPE_MESSAGE ));
+  EXPECT_STREQ("bytes"   , GetTypeNameForFieldType(FD::TYPE_BYTES   ));
+  EXPECT_STREQ("uint32"  , GetTypeNameForFieldType(FD::TYPE_UINT32  ));
+  EXPECT_STREQ("enum"    , GetTypeNameForFieldType(FD::TYPE_ENUM    ));
+  EXPECT_STREQ("sfixed32", GetTypeNameForFieldType(FD::TYPE_SFIXED32));
+  EXPECT_STREQ("sfixed64", GetTypeNameForFieldType(FD::TYPE_SFIXED64));
+  EXPECT_STREQ("sint32"  , GetTypeNameForFieldType(FD::TYPE_SINT32  ));
+  EXPECT_STREQ("sint64"  , GetTypeNameForFieldType(FD::TYPE_SINT64  ));
+}
+
+TEST_F(MiscTest, StaticTypeNames) {
+  // Test that correct type names are returned.
+
+  typedef FieldDescriptor FD;  // avoid ugly line wrapping
+
+  EXPECT_STREQ("double"  , FD::TypeName(FD::TYPE_DOUBLE  ));
+  EXPECT_STREQ("float"   , FD::TypeName(FD::TYPE_FLOAT   ));
+  EXPECT_STREQ("int64"   , FD::TypeName(FD::TYPE_INT64   ));
+  EXPECT_STREQ("uint64"  , FD::TypeName(FD::TYPE_UINT64  ));
+  EXPECT_STREQ("int32"   , FD::TypeName(FD::TYPE_INT32   ));
+  EXPECT_STREQ("fixed64" , FD::TypeName(FD::TYPE_FIXED64 ));
+  EXPECT_STREQ("fixed32" , FD::TypeName(FD::TYPE_FIXED32 ));
+  EXPECT_STREQ("bool"    , FD::TypeName(FD::TYPE_BOOL    ));
+  EXPECT_STREQ("string"  , FD::TypeName(FD::TYPE_STRING  ));
+  EXPECT_STREQ("group"   , FD::TypeName(FD::TYPE_GROUP   ));
+  EXPECT_STREQ("message" , FD::TypeName(FD::TYPE_MESSAGE ));
+  EXPECT_STREQ("bytes"   , FD::TypeName(FD::TYPE_BYTES   ));
+  EXPECT_STREQ("uint32"  , FD::TypeName(FD::TYPE_UINT32  ));
+  EXPECT_STREQ("enum"    , FD::TypeName(FD::TYPE_ENUM    ));
+  EXPECT_STREQ("sfixed32", FD::TypeName(FD::TYPE_SFIXED32));
+  EXPECT_STREQ("sfixed64", FD::TypeName(FD::TYPE_SFIXED64));
+  EXPECT_STREQ("sint32"  , FD::TypeName(FD::TYPE_SINT32  ));
+  EXPECT_STREQ("sint64"  , FD::TypeName(FD::TYPE_SINT64  ));
+}
+
+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, CppTypeNames) {
+  // Test that correct CPP type names are returned.
+
+  typedef FieldDescriptor FD;  // avoid ugly line wrapping
+
+  EXPECT_STREQ("double" , GetCppTypeNameForFieldType(FD::TYPE_DOUBLE  ));
+  EXPECT_STREQ("float"  , GetCppTypeNameForFieldType(FD::TYPE_FLOAT   ));
+  EXPECT_STREQ("int64"  , GetCppTypeNameForFieldType(FD::TYPE_INT64   ));
+  EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_UINT64  ));
+  EXPECT_STREQ("int32"  , GetCppTypeNameForFieldType(FD::TYPE_INT32   ));
+  EXPECT_STREQ("uint64" , GetCppTypeNameForFieldType(FD::TYPE_FIXED64 ));
+  EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_FIXED32 ));
+  EXPECT_STREQ("bool"   , GetCppTypeNameForFieldType(FD::TYPE_BOOL    ));
+  EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_STRING  ));
+  EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_GROUP   ));
+  EXPECT_STREQ("message", GetCppTypeNameForFieldType(FD::TYPE_MESSAGE ));
+  EXPECT_STREQ("string" , GetCppTypeNameForFieldType(FD::TYPE_BYTES   ));
+  EXPECT_STREQ("uint32" , GetCppTypeNameForFieldType(FD::TYPE_UINT32  ));
+  EXPECT_STREQ("enum"   , GetCppTypeNameForFieldType(FD::TYPE_ENUM    ));
+  EXPECT_STREQ("int32"  , GetCppTypeNameForFieldType(FD::TYPE_SFIXED32));
+  EXPECT_STREQ("int64"  , GetCppTypeNameForFieldType(FD::TYPE_SFIXED64));
+  EXPECT_STREQ("int32"  , GetCppTypeNameForFieldType(FD::TYPE_SINT32  ));
+  EXPECT_STREQ("int64"  , GetCppTypeNameForFieldType(FD::TYPE_SINT64  ));
+}
+
+TEST_F(MiscTest, StaticCppTypeNames) {
+  // Test that correct CPP type names are returned.
+
+  typedef FieldDescriptor FD;  // avoid ugly line wrapping
+
+  EXPECT_STREQ("int32"  , FD::CppTypeName(FD::CPPTYPE_INT32  ));
+  EXPECT_STREQ("int64"  , FD::CppTypeName(FD::CPPTYPE_INT64  ));
+  EXPECT_STREQ("uint32" , FD::CppTypeName(FD::CPPTYPE_UINT32 ));
+  EXPECT_STREQ("uint64" , FD::CppTypeName(FD::CPPTYPE_UINT64 ));
+  EXPECT_STREQ("double" , FD::CppTypeName(FD::CPPTYPE_DOUBLE ));
+  EXPECT_STREQ("float"  , FD::CppTypeName(FD::CPPTYPE_FLOAT  ));
+  EXPECT_STREQ("bool"   , FD::CppTypeName(FD::CPPTYPE_BOOL   ));
+  EXPECT_STREQ("enum"   , FD::CppTypeName(FD::CPPTYPE_ENUM   ));
+  EXPECT_STREQ("string" , FD::CppTypeName(FD::CPPTYPE_STRING ));
+  EXPECT_STREQ("message", FD::CppTypeName(FD::CPPTYPE_MESSAGE));
+}
+
+TEST_F(MiscTest, MessageType) {
+  // Test that message_type() is NULL for non-aggregate fields
+
+  typedef FieldDescriptor FD;  // avoid ugly line wrapping
+
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_DOUBLE  ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_FLOAT   ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_INT64   ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_UINT64  ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_INT32   ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_FIXED64 ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_FIXED32 ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_BOOL    ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_STRING  ));
+  EXPECT_TRUE(NULL != GetMessageDescriptorForFieldType(FD::TYPE_GROUP   ));
+  EXPECT_TRUE(NULL != GetMessageDescriptorForFieldType(FD::TYPE_MESSAGE ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_BYTES   ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_UINT32  ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_ENUM    ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED32));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SFIXED64));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SINT32  ));
+  EXPECT_TRUE(NULL == GetMessageDescriptorForFieldType(FD::TYPE_SINT64  ));
+}
+
+TEST_F(MiscTest, EnumType) {
+  // Test that enum_type() is NULL for non-enum fields
+
+  typedef FieldDescriptor FD;  // avoid ugly line wrapping
+
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_DOUBLE  ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_FLOAT   ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_INT64   ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_UINT64  ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_INT32   ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_FIXED64 ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_FIXED32 ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_BOOL    ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_STRING  ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_GROUP   ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_MESSAGE ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_BYTES   ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_UINT32  ));
+  EXPECT_TRUE(NULL != GetEnumDescriptorForFieldType(FD::TYPE_ENUM    ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED32));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SFIXED64));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(FD::TYPE_SINT32  ));
+  EXPECT_TRUE(NULL == GetEnumDescriptorForFieldType(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_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_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());
+}
+
+// ===================================================================
+enum DescriptorPoolMode {
+  NO_DATABASE,
+  FALLBACK_DATABASE
+};
+
+class AllowUnknownDependenciesTest
+    : public testing::TestWithParam<DescriptorPoolMode> {
+ protected:
+  DescriptorPoolMode mode() {
+    return GetParam();
+   }
+
+  virtual void SetUp() {
+    FileDescriptorProto foo_proto, bar_proto;
+
+    switch (mode()) {
+      case NO_DATABASE:
+        pool_.reset(new DescriptorPool);
+        break;
+      case FALLBACK_DATABASE:
+        pool_.reset(new DescriptorPool(&db_));
+        break;
+    }
+
+    pool_->AllowUnknownDependencies();
+
+    ASSERT_TRUE(TextFormat::ParseFromString(
+      "name: 'foo.proto'"
+      "dependency: 'bar.proto'"
+      "dependency: 'baz.proto'"
+      "message_type {"
+      "  name: 'Foo'"
+      "  field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'Bar' }"
+      "  field { name:'baz' number:2 label:LABEL_OPTIONAL type_name:'Baz' }"
+      "  field { name:'qux' number:3 label:LABEL_OPTIONAL"
+      "    type_name: '.corge.Qux'"
+      "    type: TYPE_ENUM"
+      "    options {"
+      "      uninterpreted_option {"
+      "        name {"
+      "          name_part: 'grault'"
+      "          is_extension: true"
+      "        }"
+      "        positive_int_value: 1234"
+      "      }"
+      "    }"
+      "  }"
+      "}",
+      &foo_proto));
+    ASSERT_TRUE(TextFormat::ParseFromString(
+      "name: 'bar.proto'"
+      "message_type { name: 'Bar' }",
+      &bar_proto));
+
+    // Collect pointers to stuff.
+    bar_file_ = BuildFile(bar_proto);
+    ASSERT_TRUE(bar_file_ != NULL);
+
+    ASSERT_EQ(1, bar_file_->message_type_count());
+    bar_type_ = bar_file_->message_type(0);
+
+    foo_file_ = BuildFile(foo_proto);
+    ASSERT_TRUE(foo_file_ != NULL);
+
+    ASSERT_EQ(1, foo_file_->message_type_count());
+    foo_type_ = foo_file_->message_type(0);
+
+    ASSERT_EQ(3, foo_type_->field_count());
+    bar_field_ = foo_type_->field(0);
+    baz_field_ = foo_type_->field(1);
+    qux_field_ = foo_type_->field(2);
+  }
+
+  const FileDescriptor* BuildFile(const FileDescriptorProto& proto) {
+    switch (mode()) {
+      case NO_DATABASE:
+        return pool_->BuildFile(proto);
+        break;
+      case FALLBACK_DATABASE: {
+        EXPECT_TRUE(db_.Add(proto));
+        return pool_->FindFileByName(proto.name());
+      }
+    }
+    GOOGLE_LOG(FATAL) << "Can't get here.";
+    return NULL;
+  }
+
+  const FileDescriptor* bar_file_;
+  const Descriptor* bar_type_;
+  const FileDescriptor* foo_file_;
+  const Descriptor* foo_type_;
+  const FieldDescriptor* bar_field_;
+  const FieldDescriptor* baz_field_;
+  const FieldDescriptor* qux_field_;
+
+  SimpleDescriptorDatabase db_;        // used if in FALLBACK_DATABASE mode.
+  scoped_ptr<DescriptorPool> pool_;
+};
+
+TEST_P(AllowUnknownDependenciesTest, PlaceholderFile) {
+  ASSERT_EQ(2, foo_file_->dependency_count());
+  EXPECT_EQ(bar_file_, foo_file_->dependency(0));
+  EXPECT_FALSE(bar_file_->is_placeholder());
+
+  const FileDescriptor* baz_file = foo_file_->dependency(1);
+  EXPECT_EQ("baz.proto", baz_file->name());
+  EXPECT_EQ(0, baz_file->message_type_count());
+  EXPECT_TRUE(baz_file->is_placeholder());
+
+  // Placeholder files should not be findable.
+  EXPECT_EQ(bar_file_, pool_->FindFileByName(bar_file_->name()));
+  EXPECT_TRUE(pool_->FindFileByName(baz_file->name()) == NULL);
+}
+
+TEST_P(AllowUnknownDependenciesTest, PlaceholderTypes) {
+  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, bar_field_->type());
+  EXPECT_EQ(bar_type_, bar_field_->message_type());
+  EXPECT_FALSE(bar_type_->is_placeholder());
+
+  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, baz_field_->type());
+  const Descriptor* baz_type = baz_field_->message_type();
+  EXPECT_EQ("Baz", baz_type->name());
+  EXPECT_EQ("Baz", baz_type->full_name());
+  EXPECT_EQ(0, baz_type->extension_range_count());
+  EXPECT_TRUE(baz_type->is_placeholder());
+
+  ASSERT_EQ(FieldDescriptor::TYPE_ENUM, qux_field_->type());
+  const EnumDescriptor* qux_type = qux_field_->enum_type();
+  EXPECT_EQ("Qux", qux_type->name());
+  EXPECT_EQ("corge.Qux", qux_type->full_name());
+  EXPECT_TRUE(qux_type->is_placeholder());
+
+  // Placeholder types should not be findable.
+  EXPECT_EQ(bar_type_, pool_->FindMessageTypeByName(bar_type_->full_name()));
+  EXPECT_TRUE(pool_->FindMessageTypeByName(baz_type->full_name()) == NULL);
+  EXPECT_TRUE(pool_->FindEnumTypeByName(qux_type->full_name()) == NULL);
+}
+
+TEST_P(AllowUnknownDependenciesTest, CopyTo) {
+  // FieldDescriptor::CopyTo() should write non-fully-qualified type names
+  // for placeholder types which were not originally fully-qualified.
+  FieldDescriptorProto proto;
+
+  // Bar is not a placeholder, so it is fully-qualified.
+  bar_field_->CopyTo(&proto);
+  EXPECT_EQ(".Bar", proto.type_name());
+  EXPECT_EQ(FieldDescriptorProto::TYPE_MESSAGE, proto.type());
+
+  // Baz is an unqualified placeholder.
+  proto.Clear();
+  baz_field_->CopyTo(&proto);
+  EXPECT_EQ("Baz", proto.type_name());
+  EXPECT_FALSE(proto.has_type());
+
+  // Qux is a fully-qualified placeholder.
+  proto.Clear();
+  qux_field_->CopyTo(&proto);
+  EXPECT_EQ(".corge.Qux", proto.type_name());
+  EXPECT_EQ(FieldDescriptorProto::TYPE_ENUM, proto.type());
+}
+
+TEST_P(AllowUnknownDependenciesTest, CustomOptions) {
+  // Qux should still have the uninterpreted option attached.
+  ASSERT_EQ(1, qux_field_->options().uninterpreted_option_size());
+  const UninterpretedOption& option =
+    qux_field_->options().uninterpreted_option(0);
+  ASSERT_EQ(1, option.name_size());
+  EXPECT_EQ("grault", option.name(0).name_part());
+}
+
+TEST_P(AllowUnknownDependenciesTest, UnknownExtendee) {
+  // Test that we can extend an unknown type.  This is slightly tricky because
+  // it means that the placeholder type must have an extension range.
+
+  FileDescriptorProto extension_proto;
+
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "name: 'extension.proto'"
+    "extension { extendee: 'UnknownType' name:'some_extension' number:123"
+    "            label:LABEL_OPTIONAL type:TYPE_INT32 }",
+    &extension_proto));
+  const FileDescriptor* file = BuildFile(extension_proto);
+
+  ASSERT_TRUE(file != NULL);
+
+  ASSERT_EQ(1, file->extension_count());
+  const Descriptor* extendee = file->extension(0)->containing_type();
+  EXPECT_EQ("UnknownType", extendee->name());
+  EXPECT_TRUE(extendee->is_placeholder());
+  ASSERT_EQ(1, extendee->extension_range_count());
+  EXPECT_EQ(1, extendee->extension_range(0)->start);
+  EXPECT_EQ(FieldDescriptor::kMaxNumber + 1, extendee->extension_range(0)->end);
+}
+
+TEST_P(AllowUnknownDependenciesTest, CustomOption) {
+  // Test that we can use a custom option without having parsed
+  // descriptor.proto.
+
+  FileDescriptorProto option_proto;
+
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "name: \"unknown_custom_options.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { "
+    "  extendee: \"google.protobuf.FileOptions\" "
+    "  name: \"some_option\" "
+    "  number: 123456 "
+    "  label: LABEL_OPTIONAL "
+    "  type: TYPE_INT32 "
+    "} "
+    "options { "
+    "  uninterpreted_option { "
+    "    name { "
+    "      name_part: \"some_option\" "
+    "      is_extension: true "
+    "    } "
+    "    positive_int_value: 1234 "
+    "  } "
+    "  uninterpreted_option { "
+    "    name { "
+    "      name_part: \"unknown_option\" "
+    "      is_extension: true "
+    "    } "
+    "    positive_int_value: 1234 "
+    "  } "
+    "  uninterpreted_option { "
+    "    name { "
+    "      name_part: \"optimize_for\" "
+    "      is_extension: false "
+    "    } "
+    "    identifier_value: \"SPEED\" "
+    "  } "
+    "}",
+    &option_proto));
+
+  const FileDescriptor* file = BuildFile(option_proto);
+  ASSERT_TRUE(file != NULL);
+
+  // Verify that no extension options were set, but they were left as
+  // uninterpreted_options.
+  vector<const FieldDescriptor*> fields;
+  file->options().GetReflection()->ListFields(file->options(), &fields);
+  ASSERT_EQ(2, fields.size());
+  EXPECT_TRUE(file->options().has_optimize_for());
+  EXPECT_EQ(2, file->options().uninterpreted_option_size());
+}
+
+TEST_P(AllowUnknownDependenciesTest,
+       UndeclaredDependencyTriggersBuildOfDependency) {
+  // Crazy case: suppose foo.proto refers to a symbol without declaring the
+  // dependency that finds it. In the event that the pool is backed by a
+  // DescriptorDatabase, the pool will attempt to find the symbol in the
+  // database. If successful, it will build the undeclared dependency to verify
+  // that the file does indeed contain the symbol. If that file fails to build,
+  // then its descriptors must be rolled back. However, we still want foo.proto
+  // to build successfully, since we are allowing unknown dependencies.
+
+  FileDescriptorProto undeclared_dep_proto;
+  // We make this file fail to build by giving it two fields with tag 1.
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "name: \"invalid_file_as_undeclared_dep.proto\" "
+    "package: \"undeclared\" "
+    "message_type: {  "
+    "  name: \"Quux\"  "
+    "  field { "
+    "    name:'qux' number:1 label:LABEL_OPTIONAL type: TYPE_INT32 "
+    "  }"
+    "  field { "
+    "    name:'quux' number:1 label:LABEL_OPTIONAL type: TYPE_INT64 "
+    "  }"
+    "}",
+    &undeclared_dep_proto));
+  // We can't use the BuildFile() helper because we don't actually want to build
+  // it into the descriptor pool in the fallback database case: it just needs to
+  // be sitting in the database so that it gets built during the building of
+  // test.proto below.
+  switch (mode()) {
+    case NO_DATABASE: {
+      ASSERT_TRUE(pool_->BuildFile(undeclared_dep_proto) == NULL);
+      break;
+    }
+    case FALLBACK_DATABASE: {
+      ASSERT_TRUE(db_.Add(undeclared_dep_proto));
+    }
+  }
+
+  FileDescriptorProto test_proto;
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "name: \"test.proto\" "
+    "message_type: { "
+    "  name: \"Corge\" "
+    "  field { "
+    "    name:'quux' number:1 label: LABEL_OPTIONAL "
+    "    type_name:'undeclared.Quux' type: TYPE_MESSAGE "
+    "  }"
+    "}",
+    &test_proto));
+
+  const FileDescriptor* file = BuildFile(test_proto);
+  ASSERT_TRUE(file != NULL);
+  GOOGLE_LOG(INFO) << file->DebugString();
+
+  EXPECT_EQ(0, file->dependency_count());
+  ASSERT_EQ(1, file->message_type_count());
+  const Descriptor* corge_desc = file->message_type(0);
+  ASSERT_EQ("Corge", corge_desc->name());
+  ASSERT_EQ(1, corge_desc->field_count());
+  EXPECT_FALSE(corge_desc->is_placeholder());
+
+  const FieldDescriptor* quux_field = corge_desc->field(0);
+  ASSERT_EQ(FieldDescriptor::TYPE_MESSAGE, quux_field->type());
+  ASSERT_EQ("Quux", quux_field->message_type()->name());
+  ASSERT_EQ("undeclared.Quux", quux_field->message_type()->full_name());
+  EXPECT_TRUE(quux_field->message_type()->is_placeholder());
+  // The place holder type should not be findable.
+  ASSERT_TRUE(pool_->FindMessageTypeByName("undeclared.Quux") == NULL);
+}
+
+INSTANTIATE_TEST_CASE_P(DatabaseSource,
+                        AllowUnknownDependenciesTest,
+                        testing::Values(NO_DATABASE, FALLBACK_DATABASE));
+
+// ===================================================================
+
+TEST(CustomOptions, OptionLocations) {
+  const Descriptor* message =
+      protobuf_unittest::TestMessageWithCustomOptions::descriptor();
+  const FileDescriptor* file = message->file();
+  const FieldDescriptor* field = message->FindFieldByName("field1");
+  const EnumDescriptor* enm = message->FindEnumTypeByName("AnEnum");
+  // TODO(benjy): Support EnumValue options, once the compiler does.
+  const ServiceDescriptor* service =
+      file->FindServiceByName("TestServiceWithCustomOptions");
+  const MethodDescriptor* method = service->FindMethodByName("Foo");
+
+  EXPECT_EQ(GOOGLE_LONGLONG(9876543210),
+            file->options().GetExtension(protobuf_unittest::file_opt1));
+  EXPECT_EQ(-56,
+            message->options().GetExtension(protobuf_unittest::message_opt1));
+  EXPECT_EQ(GOOGLE_LONGLONG(8765432109),
+            field->options().GetExtension(protobuf_unittest::field_opt1));
+  EXPECT_EQ(42,  // Check that we get the default for an option we don't set.
+            field->options().GetExtension(protobuf_unittest::field_opt2));
+  EXPECT_EQ(-789,
+            enm->options().GetExtension(protobuf_unittest::enum_opt1));
+  EXPECT_EQ(123,
+            enm->value(1)->options().GetExtension(
+              protobuf_unittest::enum_value_opt1));
+  EXPECT_EQ(GOOGLE_LONGLONG(-9876543210),
+            service->options().GetExtension(protobuf_unittest::service_opt1));
+  EXPECT_EQ(protobuf_unittest::METHODOPT1_VAL2,
+            method->options().GetExtension(protobuf_unittest::method_opt1));
+
+  // See that the regular options went through unscathed.
+  EXPECT_TRUE(message->options().has_message_set_wire_format());
+  EXPECT_EQ(FieldOptions::CORD, field->options().ctype());
+}
+
+TEST(CustomOptions, OptionTypes) {
+  const MessageOptions* options = NULL;
+
+  options =
+      &protobuf_unittest::CustomOptionMinIntegerValues::descriptor()->options();
+  EXPECT_EQ(false    , options->GetExtension(protobuf_unittest::bool_opt));
+  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::int32_opt));
+  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::int64_opt));
+  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::uint32_opt));
+  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::uint64_opt));
+  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sint32_opt));
+  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sint64_opt));
+  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::fixed32_opt));
+  EXPECT_EQ(0        , options->GetExtension(protobuf_unittest::fixed64_opt));
+  EXPECT_EQ(kint32min, options->GetExtension(protobuf_unittest::sfixed32_opt));
+  EXPECT_EQ(kint64min, options->GetExtension(protobuf_unittest::sfixed64_opt));
+
+  options =
+      &protobuf_unittest::CustomOptionMaxIntegerValues::descriptor()->options();
+  EXPECT_EQ(true      , options->GetExtension(protobuf_unittest::bool_opt));
+  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::int32_opt));
+  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::int64_opt));
+  EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::uint32_opt));
+  EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::uint64_opt));
+  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sint32_opt));
+  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sint64_opt));
+  EXPECT_EQ(kuint32max, options->GetExtension(protobuf_unittest::fixed32_opt));
+  EXPECT_EQ(kuint64max, options->GetExtension(protobuf_unittest::fixed64_opt));
+  EXPECT_EQ(kint32max , options->GetExtension(protobuf_unittest::sfixed32_opt));
+  EXPECT_EQ(kint64max , options->GetExtension(protobuf_unittest::sfixed64_opt));
+
+  options =
+      &protobuf_unittest::CustomOptionOtherValues::descriptor()->options();
+  EXPECT_EQ(-100, options->GetExtension(protobuf_unittest::int32_opt));
+  EXPECT_FLOAT_EQ(12.3456789,
+                  options->GetExtension(protobuf_unittest::float_opt));
+  EXPECT_DOUBLE_EQ(1.234567890123456789,
+                   options->GetExtension(protobuf_unittest::double_opt));
+  EXPECT_EQ("Hello, \"World\"",
+            options->GetExtension(protobuf_unittest::string_opt));
+
+  EXPECT_EQ(string("Hello\0World", 11),
+            options->GetExtension(protobuf_unittest::bytes_opt));
+
+  EXPECT_EQ(protobuf_unittest::DummyMessageContainingEnum::TEST_OPTION_ENUM_TYPE2,
+            options->GetExtension(protobuf_unittest::enum_opt));
+
+  options =
+      &protobuf_unittest::SettingRealsFromPositiveInts::descriptor()->options();
+  EXPECT_FLOAT_EQ(12, options->GetExtension(protobuf_unittest::float_opt));
+  EXPECT_DOUBLE_EQ(154, options->GetExtension(protobuf_unittest::double_opt));
+
+  options =
+      &protobuf_unittest::SettingRealsFromNegativeInts::descriptor()->options();
+  EXPECT_FLOAT_EQ(-12, options->GetExtension(protobuf_unittest::float_opt));
+  EXPECT_DOUBLE_EQ(-154, options->GetExtension(protobuf_unittest::double_opt));
+}
+
+TEST(CustomOptions, ComplexExtensionOptions) {
+  const MessageOptions* options =
+      &protobuf_unittest::VariousComplexOptions::descriptor()->options();
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).foo(), 42);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
+            GetExtension(protobuf_unittest::quux), 324);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt1).
+            GetExtension(protobuf_unittest::corge).qux(), 876);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).baz(), 987);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
+            GetExtension(protobuf_unittest::grault), 654);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().foo(),
+            743);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
+            GetExtension(protobuf_unittest::quux), 1999);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).bar().
+            GetExtension(protobuf_unittest::corge).qux(), 2008);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
+            GetExtension(protobuf_unittest::garply).foo(), 741);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
+            GetExtension(protobuf_unittest::garply).
+            GetExtension(protobuf_unittest::quux), 1998);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
+            GetExtension(protobuf_unittest::garply).
+            GetExtension(protobuf_unittest::corge).qux(), 2121);
+  EXPECT_EQ(options->GetExtension(
+      protobuf_unittest::ComplexOptionType2::ComplexOptionType4::complex_opt4).
+            waldo(), 1971);
+  EXPECT_EQ(options->GetExtension(protobuf_unittest::complex_opt2).
+            fred().waldo(), 321);
+  EXPECT_EQ(9, options->GetExtension(protobuf_unittest::complex_opt3).qux());
+  EXPECT_EQ(22, options->GetExtension(protobuf_unittest::complex_opt3).
+                complexoptiontype5().plugh());
+  EXPECT_EQ(24, options->GetExtension(protobuf_unittest::complexopt6).xyzzy());
+}
+
+TEST(CustomOptions, OptionsFromOtherFile) {
+  // Test that to use a custom option, we only need to import the file
+  // defining the option; we do not also have to import descriptor.proto.
+  DescriptorPool pool;
+
+  FileDescriptorProto file_proto;
+  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+  protobuf_unittest::TestMessageWithCustomOptions::descriptor()
+    ->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "name: \"custom_options_import.proto\" "
+    "package: \"protobuf_unittest\" "
+    "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+    "options { "
+    "  uninterpreted_option { "
+    "    name { "
+    "      name_part: \"file_opt1\" "
+    "      is_extension: true "
+    "    } "
+    "    positive_int_value: 1234 "
+    "  } "
+    // Test a non-extension option too.  (At one point this failed due to a
+    // bug.)
+    "  uninterpreted_option { "
+    "    name { "
+    "      name_part: \"java_package\" "
+    "      is_extension: false "
+    "    } "
+    "    string_value: \"foo\" "
+    "  } "
+    // Test that enum-typed options still work too.  (At one point this also
+    // failed due to a bug.)
+    "  uninterpreted_option { "
+    "    name { "
+    "      name_part: \"optimize_for\" "
+    "      is_extension: false "
+    "    } "
+    "    identifier_value: \"SPEED\" "
+    "  } "
+    "}"
+    ,
+    &file_proto));
+
+  const FileDescriptor* file = pool.BuildFile(file_proto);
+  ASSERT_TRUE(file != NULL);
+  EXPECT_EQ(1234, file->options().GetExtension(protobuf_unittest::file_opt1));
+  EXPECT_TRUE(file->options().has_java_package());
+  EXPECT_EQ("foo", file->options().java_package());
+  EXPECT_TRUE(file->options().has_optimize_for());
+  EXPECT_EQ(FileOptions::SPEED, file->options().optimize_for());
+}
+
+TEST(CustomOptions, MessageOptionThreeFieldsSet) {
+  // This tests a bug which previously existed in custom options parsing.  The
+  // bug occurred when you defined a custom option with message type and then
+  // set three fields of that option on a single definition (see the example
+  // below).  The bug is a bit hard to explain, so check the change history if
+  // you want to know more.
+  DescriptorPool pool;
+
+  FileDescriptorProto file_proto;
+  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+  protobuf_unittest::TestMessageWithCustomOptions::descriptor()
+    ->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+  // The following represents the definition:
+  //
+  //   import "google/protobuf/unittest_custom_options.proto"
+  //   package protobuf_unittest;
+  //   message Foo {
+  //     option (complex_opt1).foo  = 1234;
+  //     option (complex_opt1).foo2 = 1234;
+  //     option (complex_opt1).foo3 = 1234;
+  //   }
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "name: \"custom_options_import.proto\" "
+    "package: \"protobuf_unittest\" "
+    "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+    "message_type { "
+    "  name: \"Foo\" "
+    "  options { "
+    "    uninterpreted_option { "
+    "      name { "
+    "        name_part: \"complex_opt1\" "
+    "        is_extension: true "
+    "      } "
+    "      name { "
+    "        name_part: \"foo\" "
+    "        is_extension: false "
+    "      } "
+    "      positive_int_value: 1234 "
+    "    } "
+    "    uninterpreted_option { "
+    "      name { "
+    "        name_part: \"complex_opt1\" "
+    "        is_extension: true "
+    "      } "
+    "      name { "
+    "        name_part: \"foo2\" "
+    "        is_extension: false "
+    "      } "
+    "      positive_int_value: 1234 "
+    "    } "
+    "    uninterpreted_option { "
+    "      name { "
+    "        name_part: \"complex_opt1\" "
+    "        is_extension: true "
+    "      } "
+    "      name { "
+    "        name_part: \"foo3\" "
+    "        is_extension: false "
+    "      } "
+    "      positive_int_value: 1234 "
+    "    } "
+    "  } "
+    "}",
+    &file_proto));
+
+  const FileDescriptor* file = pool.BuildFile(file_proto);
+  ASSERT_TRUE(file != NULL);
+  ASSERT_EQ(1, file->message_type_count());
+
+  const MessageOptions& options = file->message_type(0)->options();
+  EXPECT_EQ(1234, options.GetExtension(protobuf_unittest::complex_opt1).foo());
+}
+
+TEST(CustomOptions, MessageOptionRepeatedLeafFieldSet) {
+  // This test verifies that repeated fields in custom options can be
+  // given multiple values by repeating the option with a different value.
+  // This test checks repeated leaf values. Each repeated custom value
+  // appears in a different uninterpreted_option, which will be concatenated
+  // when they are merged into the final option value.
+  DescriptorPool pool;
+
+  FileDescriptorProto file_proto;
+  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+  protobuf_unittest::TestMessageWithCustomOptions::descriptor()
+    ->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+  // The following represents the definition:
+  //
+  //   import "google/protobuf/unittest_custom_options.proto"
+  //   package protobuf_unittest;
+  //   message Foo {
+  //     option (complex_opt1).foo4 = 12;
+  //     option (complex_opt1).foo4 = 34;
+  //     option (complex_opt1).foo4 = 56;
+  //   }
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "name: \"custom_options_import.proto\" "
+    "package: \"protobuf_unittest\" "
+    "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+    "message_type { "
+    "  name: \"Foo\" "
+    "  options { "
+    "    uninterpreted_option { "
+    "      name { "
+    "        name_part: \"complex_opt1\" "
+    "        is_extension: true "
+    "      } "
+    "      name { "
+    "        name_part: \"foo4\" "
+    "        is_extension: false "
+    "      } "
+    "      positive_int_value: 12 "
+    "    } "
+    "    uninterpreted_option { "
+    "      name { "
+    "        name_part: \"complex_opt1\" "
+    "        is_extension: true "
+    "      } "
+    "      name { "
+    "        name_part: \"foo4\" "
+    "        is_extension: false "
+    "      } "
+    "      positive_int_value: 34 "
+    "    } "
+    "    uninterpreted_option { "
+    "      name { "
+    "        name_part: \"complex_opt1\" "
+    "        is_extension: true "
+    "      } "
+    "      name { "
+    "        name_part: \"foo4\" "
+    "        is_extension: false "
+    "      } "
+    "      positive_int_value: 56 "
+    "    } "
+    "  } "
+    "}",
+    &file_proto));
+
+  const FileDescriptor* file = pool.BuildFile(file_proto);
+  ASSERT_TRUE(file != NULL);
+  ASSERT_EQ(1, file->message_type_count());
+
+  const MessageOptions& options = file->message_type(0)->options();
+  EXPECT_EQ(3, options.GetExtension(protobuf_unittest::complex_opt1).foo4_size());
+  EXPECT_EQ(12, options.GetExtension(protobuf_unittest::complex_opt1).foo4(0));
+  EXPECT_EQ(34, options.GetExtension(protobuf_unittest::complex_opt1).foo4(1));
+  EXPECT_EQ(56, options.GetExtension(protobuf_unittest::complex_opt1).foo4(2));
+}
+
+TEST(CustomOptions, MessageOptionRepeatedMsgFieldSet) {
+  // This test verifies that repeated fields in custom options can be
+  // given multiple values by repeating the option with a different value.
+  // This test checks repeated message values. Each repeated custom value
+  // appears in a different uninterpreted_option, which will be concatenated
+  // when they are merged into the final option value.
+  DescriptorPool pool;
+
+  FileDescriptorProto file_proto;
+  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+  protobuf_unittest::TestMessageWithCustomOptions::descriptor()
+    ->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+  // The following represents the definition:
+  //
+  //   import "google/protobuf/unittest_custom_options.proto"
+  //   package protobuf_unittest;
+  //   message Foo {
+  //     option (complex_opt2).barney = {waldo: 1};
+  //     option (complex_opt2).barney = {waldo: 10};
+  //     option (complex_opt2).barney = {waldo: 100};
+  //   }
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "name: \"custom_options_import.proto\" "
+    "package: \"protobuf_unittest\" "
+    "dependency: \"google/protobuf/unittest_custom_options.proto\" "
+    "message_type { "
+    "  name: \"Foo\" "
+    "  options { "
+    "    uninterpreted_option { "
+    "      name { "
+    "        name_part: \"complex_opt2\" "
+    "        is_extension: true "
+    "      } "
+    "      name { "
+    "        name_part: \"barney\" "
+    "        is_extension: false "
+    "      } "
+    "      aggregate_value: \"waldo: 1\" "
+    "    } "
+    "    uninterpreted_option { "
+    "      name { "
+    "        name_part: \"complex_opt2\" "
+    "        is_extension: true "
+    "      } "
+    "      name { "
+    "        name_part: \"barney\" "
+    "        is_extension: false "
+    "      } "
+    "      aggregate_value: \"waldo: 10\" "
+    "    } "
+    "    uninterpreted_option { "
+    "      name { "
+    "        name_part: \"complex_opt2\" "
+    "        is_extension: true "
+    "      } "
+    "      name { "
+    "        name_part: \"barney\" "
+    "        is_extension: false "
+    "      } "
+    "      aggregate_value: \"waldo: 100\" "
+    "    } "
+    "  } "
+    "}",
+    &file_proto));
+
+  const FileDescriptor* file = pool.BuildFile(file_proto);
+  ASSERT_TRUE(file != NULL);
+  ASSERT_EQ(1, file->message_type_count());
+
+  const MessageOptions& options = file->message_type(0)->options();
+  EXPECT_EQ(3, options.GetExtension(
+      protobuf_unittest::complex_opt2).barney_size());
+  EXPECT_EQ(1,options.GetExtension(
+      protobuf_unittest::complex_opt2).barney(0).waldo());
+  EXPECT_EQ(10, options.GetExtension(
+      protobuf_unittest::complex_opt2).barney(1).waldo());
+  EXPECT_EQ(100, options.GetExtension(
+      protobuf_unittest::complex_opt2).barney(2).waldo());
+}
+
+// Check that aggregate options were parsed and saved correctly in
+// the appropriate descriptors.
+TEST(CustomOptions, AggregateOptions) {
+  const Descriptor* msg = protobuf_unittest::AggregateMessage::descriptor();
+  const FileDescriptor* file = msg->file();
+  const FieldDescriptor* field = msg->FindFieldByName("fieldname");
+  const EnumDescriptor* enumd = file->FindEnumTypeByName("AggregateEnum");
+  const EnumValueDescriptor* enumv = enumd->FindValueByName("VALUE");
+  const ServiceDescriptor* service = file->FindServiceByName(
+      "AggregateService");
+  const MethodDescriptor* method = service->FindMethodByName("Method");
+
+  // Tests for the different types of data embedded in fileopt
+  const protobuf_unittest::Aggregate& file_options =
+      file->options().GetExtension(protobuf_unittest::fileopt);
+  EXPECT_EQ(100, file_options.i());
+  EXPECT_EQ("FileAnnotation", file_options.s());
+  EXPECT_EQ("NestedFileAnnotation", file_options.sub().s());
+  EXPECT_EQ("FileExtensionAnnotation",
+            file_options.file().GetExtension(protobuf_unittest::fileopt).s());
+  EXPECT_EQ("EmbeddedMessageSetElement",
+            file_options.mset().GetExtension(
+                protobuf_unittest::AggregateMessageSetElement
+                ::message_set_extension).s());
+
+  // Simple tests for all the other types of annotations
+  EXPECT_EQ("MessageAnnotation",
+            msg->options().GetExtension(protobuf_unittest::msgopt).s());
+  EXPECT_EQ("FieldAnnotation",
+            field->options().GetExtension(protobuf_unittest::fieldopt).s());
+  EXPECT_EQ("EnumAnnotation",
+            enumd->options().GetExtension(protobuf_unittest::enumopt).s());
+  EXPECT_EQ("EnumValueAnnotation",
+            enumv->options().GetExtension(protobuf_unittest::enumvalopt).s());
+  EXPECT_EQ("ServiceAnnotation",
+            service->options().GetExtension(protobuf_unittest::serviceopt).s());
+  EXPECT_EQ("MethodAnnotation",
+            method->options().GetExtension(protobuf_unittest::methodopt).s());
+}
+
+TEST(CustomOptions, UnusedImportWarning) {
+  DescriptorPool pool;
+
+  FileDescriptorProto file_proto;
+  FileDescriptorProto::descriptor()->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+  protobuf_unittest::TestMessageWithCustomOptions::descriptor()
+      ->file()->CopyTo(&file_proto);
+  ASSERT_TRUE(pool.BuildFile(file_proto) != NULL);
+
+
+  pool.AddUnusedImportTrackFile("custom_options_import.proto");
+  ASSERT_TRUE(TextFormat::ParseFromString(
+    "name: \"custom_options_import.proto\" "
+    "package: \"protobuf_unittest\" "
+    "dependency: \"google/protobuf/unittest_custom_options.proto\" ",
+    &file_proto));
+  pool.BuildFile(file_proto);
+}
+
+// ===================================================================
+
+// 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_;
+  string warning_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 OPTION_NAME  : location_name = "OPTION_NAME"  ; break;
+      case OPTION_VALUE : location_name = "OPTION_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);
+  }
+
+  // implements ErrorCollector ---------------------------------------
+  void AddWarning(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 OPTION_NAME  : location_name = "OPTION_NAME"  ; break;
+      case OPTION_VALUE : location_name = "OPTION_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(
+      &warning_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_);
+  }
+
+  // Parse file_text as a FileDescriptorProto in text format and add it
+  // to the DescriptorPool.  Expect errors to be produced which match the
+  // given warning text.
+  void BuildFileWithWarnings(const string& file_text,
+                             const string& expected_warnings) {
+    FileDescriptorProto file_proto;
+    ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto));
+
+    MockErrorCollector error_collector;
+    EXPECT_TRUE(pool_.BuildFileCollectingErrors(file_proto, &error_collector));
+    EXPECT_EQ(expected_warnings, error_collector.warning_text_);
+  }
+
+  // Builds some already-parsed file in our test pool.
+  void BuildFileInTestPool(const FileDescriptor* file) {
+    FileDescriptorProto file_proto;
+    file->CopyTo(&file_proto);
+    ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL);
+  }
+
+  // Build descriptor.proto in our test pool. This allows us to extend it in
+  // the test pool, so we can test custom options.
+  void BuildDescriptorMessagesInTestPool() {
+    BuildFileInTestPool(DescriptorProto::descriptor()->file());
+  }
+
+  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, EnumValueAlreadyDefinedInParent) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
+    "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
+
+    "foo.proto: FOO: NAME: \"FOO\" is already defined.\n"
+    "foo.proto: FOO: NAME: Note that enum values use C++ scoping rules, "
+      "meaning that enum values are siblings of their type, not children of "
+      "it.  Therefore, \"FOO\" must be unique within the global scope, not "
+      "just within \"Bar\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumValueAlreadyDefinedInParentNonGlobal) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "package: \"pkg\" "
+    "enum_type { name: \"Foo\" value { name: \"FOO\" number: 1 } } "
+    "enum_type { name: \"Bar\" value { name: \"FOO\" number: 1 } } ",
+
+    "foo.proto: pkg.FOO: NAME: \"FOO\" is already defined in \"pkg\".\n"
+    "foo.proto: pkg.FOO: NAME: Note that enum values use C++ scoping rules, "
+      "meaning that enum values are siblings of their type, not children of "
+      "it.  Therefore, \"FOO\" must be unique within \"pkg\", not just within "
+      "\"Bar\".\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, InvalidPublicDependencyIndex) {
+  BuildFile("name: \"foo.proto\"");
+  BuildFileWithErrors(
+    "name: \"bar.proto\" "
+    "dependency: \"foo.proto\" "
+    "public_dependency: 1",
+    "bar.proto: bar.proto: OTHER: Invalid public dependency index.\n");
+}
+
+TEST_F(ValidationErrorTest, ForeignUnimportedPackageNoCrash) {
+  // Used to crash:  If we depend on a non-existent file and then refer to a
+  // package defined in a file that we didn't import, and that package is
+  // nested within a parent package which this file is also in, and we don't
+  // include that parent package in the name (i.e. we do a relative lookup)...
+  // Yes, really.
+  BuildFile(
+    "name: 'foo.proto' "
+    "package: 'outer.foo' ");
+  BuildFileWithErrors(
+    "name: 'bar.proto' "
+    "dependency: 'baz.proto' "
+    "package: 'outer.bar' "
+    "message_type { "
+    "  name: 'Bar' "
+    "  field { name:'bar' number:1 label:LABEL_OPTIONAL type_name:'foo.Foo' }"
+    "}",
+
+    "bar.proto: bar.proto: OTHER: Import \"baz.proto\" has not been loaded.\n"
+    "bar.proto: outer.bar.Bar.bar: TYPE: \"outer.foo\" seems to be defined in "
+      "\"foo.proto\", which is not imported by \"bar.proto\".  To use it here, "
+      "please add the necessary import.\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\" } "
+    // Add another type so that the files aren't identical (in which case there
+    // would be no error).
+    "enum_type { name: \"Bar\" }",
+
+    "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\" }"
+
+    // Repeateds can't have defaults.
+    "  field { name: \"corge\" number: 6 label: LABEL_REPEATED type: TYPE_INT32"
+    "          default_value: \"1\" }"
+    "}",
+
+    "foo.proto: Foo.foo: DEFAULT_VALUE: Couldn't parse default value \"abc\".\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.corge: DEFAULT_VALUE: Repeated fields can't have default "
+      "values.\n"
+    // This ends up being reported later because the error is detected at
+    // cross-linking time.
+    "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, FieldOneofIndexTooLarge) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+    "          oneof_index: 1 }"
+    "  field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
+    "          oneof_index: 0 }"
+    "  oneof_decl { name:\"bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: OTHER: FieldDescriptorProto.oneof_index 1 is out of "
+      "range for type \"Foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, FieldOneofIndexNegative) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+    "          oneof_index: -1 }"
+    "  field { name:\"dummy\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 "
+    "          oneof_index: 0 }"
+    "  oneof_decl { name:\"bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: OTHER: FieldDescriptorProto.oneof_index -1 is out of "
+      "range for type \"Foo\".\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, RequiredExtension) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Bar\""
+    "  extension_range { start: 1000 end: 10000 }"
+    "}"
+    "message_type {"
+    "  name: \"Foo\""
+    "  extension {"
+    "    name:\"foo\""
+    "    number:1000"
+    "    label:LABEL_REQUIRED"
+    "    type:TYPE_INT32"
+    "    extendee: \"Bar\""
+    "  }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: Message extensions cannot have required "
+    "fields.\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, UndefinedFieldTypeWithDefault) {
+  // See b/12533582. Previously this failed because the default value was not
+  // accepted by the parser, which assumed an enum type, leading to an unclear
+  // error message. We want this input to yield a validation error instead,
+  // since the unknown type is the primary problem.
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"int\" "
+    "          default_value:\"1\" }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: \"int\" is not defined.\n");
+}
+
+TEST_F(ValidationErrorTest, UndefinedNestedFieldType) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  nested_type { name:\"Baz\" }"
+    "  field { name:\"foo\" number:1"
+    "          label:LABEL_OPTIONAL"
+    "          type_name:\"Foo.Baz.Bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: \"Foo.Baz.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, FieldTypeDefinedInIndirectDependency) {
+  // Test for hidden dependencies.
+  //
+  // // bar.proto
+  // message Bar{}
+  //
+  // // forward.proto
+  // import "bar.proto"
+  //
+  // // foo.proto
+  // import "forward.proto"
+  // message Foo {
+  //   optional Bar foo = 1;  // Error, needs to import bar.proto explicitly.
+  // }
+  //
+  BuildFile(
+    "name: \"bar.proto\" "
+    "message_type { name: \"Bar\" }");
+
+  BuildFile(
+    "name: \"forward.proto\""
+    "dependency: \"bar.proto\"");
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"forward.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, FieldTypeDefinedInPublicDependency) {
+  // Test for public dependencies.
+  //
+  // // bar.proto
+  // message Bar{}
+  //
+  // // forward.proto
+  // import public "bar.proto"
+  //
+  // // foo.proto
+  // import "forward.proto"
+  // message Foo {
+  //   optional Bar foo = 1;  // Correct. "bar.proto" is public imported into
+  //                          // forward.proto, so when "foo.proto" imports
+  //                          // "forward.proto", it imports "bar.proto" too.
+  // }
+  //
+  BuildFile(
+    "name: \"bar.proto\" "
+    "message_type { name: \"Bar\" }");
+
+  BuildFile(
+    "name: \"forward.proto\""
+    "dependency: \"bar.proto\" "
+    "public_dependency: 0");
+
+  BuildFile(
+    "name: \"foo.proto\" "
+    "dependency: \"forward.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+    "}");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeDefinedInTransitivePublicDependency) {
+  // Test for public dependencies.
+  //
+  // // bar.proto
+  // message Bar{}
+  //
+  // // forward.proto
+  // import public "bar.proto"
+  //
+  // // forward2.proto
+  // import public "forward.proto"
+  //
+  // // foo.proto
+  // import "forward2.proto"
+  // message Foo {
+  //   optional Bar foo = 1;  // Correct, public imports are transitive.
+  // }
+  //
+  BuildFile(
+    "name: \"bar.proto\" "
+    "message_type { name: \"Bar\" }");
+
+  BuildFile(
+    "name: \"forward.proto\""
+    "dependency: \"bar.proto\" "
+    "public_dependency: 0");
+
+  BuildFile(
+    "name: \"forward2.proto\""
+    "dependency: \"forward.proto\" "
+    "public_dependency: 0");
+
+  BuildFile(
+    "name: \"foo.proto\" "
+    "dependency: \"forward2.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+    "}");
+}
+
+TEST_F(ValidationErrorTest,
+       FieldTypeDefinedInPrivateDependencyOfPublicDependency) {
+  // Test for public dependencies.
+  //
+  // // bar.proto
+  // message Bar{}
+  //
+  // // forward.proto
+  // import "bar.proto"
+  //
+  // // forward2.proto
+  // import public "forward.proto"
+  //
+  // // foo.proto
+  // import "forward2.proto"
+  // message Foo {
+  //   optional Bar foo = 1;  // Error, the "bar.proto" is not public imported
+  //                          // into "forward.proto", so will not be imported
+  //                          // into either "forward2.proto" or "foo.proto".
+  // }
+  //
+  BuildFile(
+    "name: \"bar.proto\" "
+    "message_type { name: \"Bar\" }");
+
+  BuildFile(
+    "name: \"forward.proto\""
+    "dependency: \"bar.proto\"");
+
+  BuildFile(
+    "name: \"forward2.proto\""
+    "dependency: \"forward.proto\" "
+    "public_dependency: 0");
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"forward2.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 resolved but
+  // 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 resolved to \"Foo.Bar.Baz\","
+    " which is not defined. The innermost scope is searched first in name "
+    "resolution. Consider using a leading '.'(i.e., \".Bar.Baz\") to start "
+    "from the outermost scope.\n");
+}
+
+TEST_F(ValidationErrorTest, SearchMostLocalFirst2) {
+  // This test would find the most local "Bar" first, and does, but
+  // proceeds to find the outer one because the inner one's not an
+  // aggregate.
+  BuildFile(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Bar\""
+    "  nested_type { name: \"Baz\" }"
+    "}"
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name: \"Bar\" number:1 type:TYPE_BYTES } "
+    "  field { name:\"baz\" number:2 label:LABEL_OPTIONAL"
+    "          type_name:\"Bar.Baz\" }"
+    "}");
+}
+
+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:\".Foo.bar\" }"
+    "  field { name:\"bar\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "}",
+
+    "foo.proto: Foo.foo: TYPE: \".Foo.bar\" is not a type.\n");
+}
+
+TEST_F(ValidationErrorTest, RelativeFieldTypeNotAType) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  nested_type {"
+    "    name: \"Bar\""
+    "    field { name:\"Baz\" number:2 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+    "  }"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL "
+    "          type_name:\"Bar.Baz\" }"
+    "}",
+    "foo.proto: Foo.foo: TYPE: \"Bar.Baz\" is not a type.\n");
+}
+
+TEST_F(ValidationErrorTest, FieldTypeMayBeItsName) {
+  BuildFile(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Bar\""
+    "}"
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"Bar\" number:1 label:LABEL_OPTIONAL type_name:\"Bar\" }"
+    "}");
+}
+
+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, EnumDefaultValueIsInteger) {
+  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:\"0\" }"
+    "}",
+
+    "foo.proto: Foo.foo: DEFAULT_VALUE: Default value for an enum field must "
+    "be an identifier.\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, OneofWithNoFields) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  oneof_decl { name:\"bar\" }"
+    "}",
+
+    "foo.proto: Foo.bar: NAME: Oneof must have at least one field.\n");
+}
+
+TEST_F(ValidationErrorTest, OneofLabelMismatch) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {"
+    "  name: \"Foo\""
+    "  field { name:\"foo\" number:1 label:LABEL_REPEATED type:TYPE_INT32 "
+    "          oneof_index:0 }"
+    "  oneof_decl { name:\"bar\" }"
+    "}",
+
+    "foo.proto: Foo.foo: NAME: Fields of oneofs must themselves have label "
+      "LABEL_OPTIONAL.\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, IllegalPackedField) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type {\n"
+    "  name: \"Foo\""
+    "  field { name:\"packed_string\" number:1 label:LABEL_REPEATED "
+    "          type:TYPE_STRING "
+    "          options { uninterpreted_option {"
+    "            name { name_part: \"packed\" is_extension: false }"
+    "            identifier_value: \"true\" }}}\n"
+    "  field { name:\"packed_message\" number:3 label:LABEL_REPEATED "
+    "          type_name: \"Foo\""
+    "          options { uninterpreted_option {"
+    "            name { name_part: \"packed\" is_extension: false }"
+    "            identifier_value: \"true\" }}}\n"
+    "  field { name:\"optional_int32\" number: 4 label: LABEL_OPTIONAL "
+    "          type:TYPE_INT32 "
+    "          options { uninterpreted_option {"
+    "            name { name_part: \"packed\" is_extension: false }"
+    "            identifier_value: \"true\" }}}\n"
+    "}",
+
+    "foo.proto: Foo.packed_string: TYPE: [packed = true] can only be "
+        "specified for repeated primitive fields.\n"
+    "foo.proto: Foo.packed_message: TYPE: [packed = true] can only be "
+        "specified for repeated primitive fields.\n"
+    "foo.proto: Foo.optional_int32: TYPE: [packed = true] can only be "
+        "specified for repeated primitive fields.\n"
+        );
+}
+
+TEST_F(ValidationErrorTest, OptionWrongType) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"TestMessage\" "
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
+    "          options { uninterpreted_option { name { name_part: \"ctype\" "
+    "                                                  is_extension: false }"
+    "                                           positive_int_value: 1 }"
+    "          }"
+    "  }"
+    "}\n",
+
+    "foo.proto: TestMessage.foo: OPTION_VALUE: Value must be identifier for "
+    "enum-valued option \"google.protobuf.FieldOptions.ctype\".\n");
+}
+
+TEST_F(ValidationErrorTest, OptionExtendsAtomicType) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"TestMessage\" "
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_STRING "
+    "          options { uninterpreted_option { name { name_part: \"ctype\" "
+    "                                                  is_extension: false }"
+    "                                           name { name_part: \"foo\" "
+    "                                                  is_extension: true }"
+    "                                           positive_int_value: 1 }"
+    "          }"
+    "  }"
+    "}\n",
+
+    "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" is an "
+    "atomic type, not a message.\n");
+}
+
+TEST_F(ValidationErrorTest, DupOption) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"TestMessage\" "
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_UINT32 "
+    "          options { uninterpreted_option { name { name_part: \"ctype\" "
+    "                                                  is_extension: false }"
+    "                                           identifier_value: \"CORD\" }"
+    "                    uninterpreted_option { name { name_part: \"ctype\" "
+    "                                                  is_extension: false }"
+    "                                           identifier_value: \"CORD\" }"
+    "          }"
+    "  }"
+    "}\n",
+
+    "foo.proto: TestMessage.foo: OPTION_NAME: Option \"ctype\" was "
+    "already set.\n");
+}
+
+TEST_F(ValidationErrorTest, InvalidOptionName) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "message_type { "
+    "  name: \"TestMessage\" "
+    "  field { name:\"foo\" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL "
+    "          options { uninterpreted_option { "
+    "                      name { name_part: \"uninterpreted_option\" "
+    "                             is_extension: false }"
+    "                      positive_int_value: 1 "
+    "                    }"
+    "          }"
+    "  }"
+    "}\n",
+
+    "foo.proto: TestMessage.foo: OPTION_NAME: Option must not use "
+    "reserved name \"uninterpreted_option\".\n");
+}
+
+TEST_F(ValidationErrorTest, RepeatedMessageOption) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "message_type: { name: \"Bar\" field: { "
+    "  name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
+    "} "
+    "extension { name: \"bar\" number: 7672757 label: LABEL_REPEATED "
+    "            type: TYPE_MESSAGE type_name: \"Bar\" "
+    "            extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"bar\" "
+    "                                        is_extension: true } "
+    "                                 name { name_part: \"foo\" "
+    "                                        is_extension: false } "
+    "                                 positive_int_value: 1 } }",
+
+    "foo.proto: foo.proto: OPTION_NAME: Option field \"(bar)\" is a "
+    "repeated message. Repeated message options must be initialized "
+    "using an aggregate value.\n");
+}
+
+TEST_F(ValidationErrorTest, ResolveUndefinedOption) {
+  // The following should produce an eror that baz.bar is resolved but not
+  // defined.
+  // foo.proto:
+  //   package baz
+  //   import google/protobuf/descriptor.proto
+  //   message Bar { optional int32 foo = 1; }
+  //   extend FileOptions { optional Bar bar = 7672757; }
+  //
+  // qux.proto:
+  //   package qux.baz
+  //   option (baz.bar).foo = 1;
+  //
+  // Although "baz.bar" is already defined, the lookup code will try
+  // "qux.baz.bar", since it's the match from the innermost scope, which will
+  // cause a symbol not defined error.
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFile(
+    "name: \"foo.proto\" "
+    "package: \"baz\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "message_type: { name: \"Bar\" field: { "
+    "  name: \"foo\" number: 1 label: LABEL_OPTIONAL type: TYPE_INT32 } "
+    "} "
+    "extension { name: \"bar\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_MESSAGE type_name: \"Bar\" "
+    "            extendee: \"google.protobuf.FileOptions\" }");
+
+  BuildFileWithErrors(
+    "name: \"qux.proto\" "
+    "package: \"qux.baz\" "
+    "options { uninterpreted_option { name { name_part: \"baz.bar\" "
+    "                                        is_extension: true } "
+    "                                 name { name_part: \"foo\" "
+    "                                        is_extension: false } "
+    "                                 positive_int_value: 1 } }",
+
+    "qux.proto: qux.proto: OPTION_NAME: Option \"(baz.bar)\" is resolved to "
+    "\"(qux.baz.bar)\","
+    " which is not defined. The innermost scope is searched first in name "
+    "resolution. Consider using a leading '.'(i.e., \"(.baz.bar)\") to start "
+    "from the outermost scope.\n");
+}
+
+TEST_F(ValidationErrorTest, UnknownOption) {
+  BuildFileWithErrors(
+    "name: \"qux.proto\" "
+    "package: \"qux.baz\" "
+    "options { uninterpreted_option { name { name_part: \"baaz.bar\" "
+    "                                        is_extension: true } "
+    "                                 name { name_part: \"foo\" "
+    "                                        is_extension: false } "
+    "                                 positive_int_value: 1 } }",
+
+    "qux.proto: qux.proto: OPTION_NAME: Option \"(baaz.bar)\" unknown.\n");
+}
+
+TEST_F(ValidationErrorTest, CustomOptionConflictingFieldNumber) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo1\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }"
+    "extension { name: \"foo2\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_INT32 extendee: \"google.protobuf.FieldOptions\" }",
+
+    "foo.proto: foo2: NUMBER: Extension number 7672757 has already been used "
+    "in \"google.protobuf.FieldOptions\" by extension \"foo1\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int32OptionValueOutOfPositiveRange) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 positive_int_value: 0x80000000 } "
+    "}",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+    "for int32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int32OptionValueOutOfNegativeRange) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 negative_int_value: -0x80000001 } "
+    "}",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+    "for int32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int32OptionValueIsNotPositiveInt) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 string_value: \"5\" } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
+    "for int32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int64OptionValueOutOfRange) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 positive_int_value: 0x8000000000000000 } "
+    "}",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+    "for int64 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, Int64OptionValueIsNotPositiveInt) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_INT64 extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 identifier_value: \"5\" } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value must be integer "
+    "for int64 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, UInt32OptionValueOutOfRange) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 positive_int_value: 0x100000000 } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value out of range "
+    "for uint32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, UInt32OptionValueIsNotPositiveInt) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_UINT32 extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 double_value: -5.6 } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
+    "for uint32 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, UInt64OptionValueIsNotPositiveInt) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_UINT64 extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 negative_int_value: -5 } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value must be non-negative integer "
+    "for uint64 option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, FloatOptionValueIsNotNumber) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_FLOAT extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 string_value: \"bar\" } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
+    "for float option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, DoubleOptionValueIsNotNumber) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_DOUBLE extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 string_value: \"bar\" } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value must be number "
+    "for double option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, BoolOptionValueIsNotTrueOrFalse) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_BOOL extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 identifier_value: \"bar\" } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value must be \"true\" or \"false\" "
+    "for boolean option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumOptionValueIsNotIdentifier) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
+    "                              value { name: \"BAZ\" number: 2 } }"
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_ENUM type_name: \"FooEnum\" "
+    "            extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 string_value: \"QUUX\" } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value must be identifier for "
+    "enum-valued option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumOptionValueIsNotEnumValueName) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "enum_type { name: \"FooEnum\" value { name: \"BAR\" number: 1 } "
+    "                              value { name: \"BAZ\" number: 2 } }"
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_ENUM type_name: \"FooEnum\" "
+    "            extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 identifier_value: \"QUUX\" } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum\" has no value "
+    "named \"QUUX\" for option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, EnumOptionValueIsSiblingEnumValueName) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "enum_type { name: \"FooEnum1\" value { name: \"BAR\" number: 1 } "
+    "                               value { name: \"BAZ\" number: 2 } }"
+    "enum_type { name: \"FooEnum2\" value { name: \"QUX\" number: 1 } "
+    "                               value { name: \"QUUX\" number: 2 } }"
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_ENUM type_name: \"FooEnum1\" "
+    "            extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 identifier_value: \"QUUX\" } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Enum type \"FooEnum1\" has no value "
+    "named \"QUUX\" for option \"foo\". This appears to be a value from a "
+    "sibling type.\n");
+}
+
+TEST_F(ValidationErrorTest, StringOptionValueIsNotString) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"google/protobuf/descriptor.proto\" "
+    "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+    "            type: TYPE_STRING extendee: \"google.protobuf.FileOptions\" }"
+    "options { uninterpreted_option { name { name_part: \"foo\" "
+    "                                        is_extension: true } "
+    "                                 identifier_value: \"QUUX\" } }",
+
+    "foo.proto: foo.proto: OPTION_VALUE: Value must be quoted string for "
+    "string option \"foo\".\n");
+}
+
+TEST_F(ValidationErrorTest, DuplicateExtensionFieldNumber) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFile(
+      "name: \"foo.proto\" "
+      "dependency: \"google/protobuf/descriptor.proto\" "
+      "extension { name: \"option1\" number: 1000 label: LABEL_OPTIONAL "
+      "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }");
+
+  BuildFileWithWarnings(
+      "name: \"bar.proto\" "
+      "dependency: \"google/protobuf/descriptor.proto\" "
+      "extension { name: \"option2\" number: 1000 label: LABEL_OPTIONAL "
+      "            type: TYPE_INT32 extendee: \"google.protobuf.FileOptions\" }",
+      "bar.proto: option2: NUMBER: Extension number 1000 has already been used "
+      "in \"google.protobuf.FileOptions\" by extension \"option1\" defined in "
+      "foo.proto.\n");
+}
+
+// Helper function for tests that check for aggregate value parsing
+// errors.  The "value" argument is embedded inside the
+// "uninterpreted_option" portion of the result.
+static string EmbedAggregateValue(const char* value) {
+  return strings::Substitute(
+      "name: \"foo.proto\" "
+      "dependency: \"google/protobuf/descriptor.proto\" "
+      "message_type { name: \"Foo\" } "
+      "extension { name: \"foo\" number: 7672757 label: LABEL_OPTIONAL "
+      "            type: TYPE_MESSAGE type_name: \"Foo\" "
+      "            extendee: \"google.protobuf.FileOptions\" }"
+      "options { uninterpreted_option { name { name_part: \"foo\" "
+      "                                        is_extension: true } "
+      "                                 $0 } }",
+      value);
+}
+
+TEST_F(ValidationErrorTest, AggregateValueNotFound) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+      EmbedAggregateValue("string_value: \"\""),
+      "foo.proto: foo.proto: OPTION_VALUE: Option \"foo\" is a message. "
+      "To set the entire message, use syntax like "
+      "\"foo = { <proto text format> }\". To set fields within it, use "
+      "syntax like \"foo.foo = value\".\n");
+}
+
+TEST_F(ValidationErrorTest, AggregateValueParseError) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+      EmbedAggregateValue("aggregate_value: \"1+2\""),
+      "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
+      "value for \"foo\": Expected identifier.\n");
+}
+
+TEST_F(ValidationErrorTest, AggregateValueUnknownFields) {
+  BuildDescriptorMessagesInTestPool();
+
+  BuildFileWithErrors(
+      EmbedAggregateValue("aggregate_value: \"x:100\""),
+      "foo.proto: foo.proto: OPTION_VALUE: Error while parsing option "
+      "value for \"foo\": Message type \"Foo\" has no field named \"x\".\n");
+}
+
+TEST_F(ValidationErrorTest, NotLiteImportsLite) {
+  BuildFile(
+    "name: \"bar.proto\" "
+    "options { optimize_for: LITE_RUNTIME } ");
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"bar.proto\" ",
+
+    "foo.proto: foo.proto: OTHER: Files that do not use optimize_for = "
+      "LITE_RUNTIME cannot import files which do use this option.  This file "
+      "is not lite, but it imports \"bar.proto\" which is.\n");
+}
+
+TEST_F(ValidationErrorTest, LiteExtendsNotLite) {
+  BuildFile(
+    "name: \"bar.proto\" "
+    "message_type: {"
+    "  name: \"Bar\""
+    "  extension_range { start: 1 end: 1000 }"
+    "}");
+
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "dependency: \"bar.proto\" "
+    "options { optimize_for: LITE_RUNTIME } "
+    "extension { name: \"ext\" number: 123 label: LABEL_OPTIONAL "
+    "            type: TYPE_INT32 extendee: \"Bar\" }",
+
+    "foo.proto: ext: EXTENDEE: Extensions to non-lite types can only be "
+      "declared in non-lite files.  Note that you cannot extend a non-lite "
+      "type to contain a lite type, but the reverse is allowed.\n");
+}
+
+TEST_F(ValidationErrorTest, NoLiteServices) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "options {"
+    "  optimize_for: LITE_RUNTIME"
+    "  cc_generic_services: true"
+    "  java_generic_services: true"
+    "} "
+    "service { name: \"Foo\" }",
+
+    "foo.proto: Foo: NAME: Files with optimize_for = LITE_RUNTIME cannot "
+    "define services unless you set both options cc_generic_services and "
+    "java_generic_sevices to false.\n");
+
+  BuildFile(
+    "name: \"bar.proto\" "
+    "options {"
+    "  optimize_for: LITE_RUNTIME"
+    "  cc_generic_services: false"
+    "  java_generic_services: false"
+    "} "
+    "service { name: \"Bar\" }");
+}
+
+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]);
+}
+
+TEST_F(ValidationErrorTest, DisallowEnumAlias) {
+  BuildFileWithErrors(
+    "name: \"foo.proto\" "
+    "enum_type {"
+    "  name: \"Bar\""
+    "  value { name:\"ENUM_A\" number:0 }"
+    "  value { name:\"ENUM_B\" number:0 }"
+    "}",
+    "foo.proto: Bar: NUMBER: "
+    "\"ENUM_B\" uses the same enum value as \"ENUM_A\". "
+    "If this is intended, set 'option allow_alias = true;' to the enum "
+    "definition.\n");
+}
+
+TEST_F(ValidationErrorTest, AllowEnumAlias) {
+  BuildFile(
+    "name: \"foo.proto\" "
+    "enum_type {"
+    "  name: \"Bar\""
+    "  value { name:\"ENUM_A\" number:0 }"
+    "  value { name:\"ENUM_B\" number:0 }"
+    "  options { allow_alias: true }"
+    "}");
+}
+
+TEST_F(ValidationErrorTest, UnusedImportWarning) {
+
+  pool_.AddUnusedImportTrackFile("bar.proto");
+  BuildFile(
+    "name: \"bar.proto\" "
+    "message_type { name: \"Bar\" }");
+
+  pool_.AddUnusedImportTrackFile("base.proto");
+  BuildFile(
+    "name: \"base.proto\" "
+    "message_type { name: \"Base\" }");
+
+  pool_.AddUnusedImportTrackFile("baz.proto");
+  BuildFile(
+    "name: \"baz.proto\" "
+    "message_type { name: \"Baz\" }");
+
+  pool_.AddUnusedImportTrackFile("public.proto");
+  BuildFile(
+    "name: \"public.proto\" "
+    "dependency: \"bar.proto\""
+    "public_dependency: 0");
+
+  // // forward.proto
+  // import "base.proto"       // No warning: Base message is used.
+  // import "bar.proto"        // Will log a warning.
+  // import public "baz.proto" // No warning: Do not track import public.
+  // import "public.proto"     // No warning: public.proto has import public.
+  // message Forward {
+  //   optional Base base = 1;
+  // }
+  //
+  pool_.AddUnusedImportTrackFile("forward.proto");
+  BuildFile(
+    "name: \"forward.proto\""
+    "dependency: \"base.proto\""
+    "dependency: \"bar.proto\""
+    "dependency: \"baz.proto\""
+    "dependency: \"public.proto\""
+    "public_dependency: 2 "
+    "message_type {"
+    "  name: \"Forward\""
+    "  field { name:\"base\" number:1 label:LABEL_OPTIONAL type_name:\"Base\" }"
+    "}");
+}
+
+
+// ===================================================================
+// 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 } ");
+    // Baz has an undeclared dependency on Foo.
+    AddToDatabase(&database_,
+      "name: 'baz.proto' "
+      "message_type { "
+      "  name:'Baz' "
+      "  field { name:'foo' number:1 label:LABEL_OPTIONAL type_name:'Foo' } "
+      "}");
+  }
+
+  // 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, FindAllExtensions) {
+  DescriptorPool pool(&database_);
+
+  const Descriptor* foo = pool.FindMessageTypeByName("Foo");
+
+  for (int i = 0; i < 2; ++i) {
+    // Repeat the lookup twice, to check that we get consistent
+    // results despite the fallback database lookup mutating the pool.
+    vector<const FieldDescriptor*> extensions;
+    pool.FindAllExtensions(foo, &extensions);
+    ASSERT_EQ(1, extensions.size());
+    EXPECT_EQ(5, extensions[0]->number());
+  }
+}
+
+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, UndeclaredDependencyOnUnbuiltType) {
+  // Check that we find and report undeclared dependencies on types that exist
+  // in the descriptor database but that have not not been built yet.
+  MockErrorCollector error_collector;
+  DescriptorPool pool(&database_, &error_collector);
+  EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
+  EXPECT_EQ(
+    "baz.proto: Baz.foo: TYPE: \"Foo\" seems to be defined in \"foo.proto\", "
+    "which is not imported by \"baz.proto\".  To use it here, please add "
+    "the necessary import.\n",
+    error_collector.text_);
+}
+
+TEST_F(DatabaseBackedPoolTest, RollbackAfterError) {
+  // Make sure that all traces of bad types are removed from the pool. This used
+  // to be b/4529436, due to the fact that a symbol resolution failure could
+  // potentially cause another file to be recursively built, which would trigger
+  // a checkpoint _past_ possibly invalid symbols.
+  // Baz is defined in the database, but the file is invalid because it is
+  // missing a necessary import.
+  DescriptorPool pool(&database_);
+  EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
+  // Make sure that searching again for the file or the type fails.
+  EXPECT_TRUE(pool.FindFileByName("baz.proto") == NULL);
+  EXPECT_TRUE(pool.FindMessageTypeByName("Baz") == NULL);
+}
+
+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());
+
+  // Also verify that CopyTo() did not omit any information.
+  EXPECT_EQ(original_file->DebugString(),
+            file_from_database->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_TRUE(pool.FindFileContainingSymbol("Foo.no.such.field") == NULL);
+  EXPECT_TRUE(pool.FindFileContainingSymbol("Foo.no_such_field") == NULL);
+  EXPECT_TRUE(pool.FindMessageTypeByName("Foo.NoSuchMessageType") == NULL);
+  EXPECT_TRUE(pool.FindFieldByName("Foo.no_such_field") == NULL);
+  EXPECT_TRUE(pool.FindExtensionByName("Foo.no_such_extension") == NULL);
+  EXPECT_TRUE(pool.FindEnumTypeByName("Foo.NoSuchEnumType") == NULL);
+  EXPECT_TRUE(pool.FindEnumValueByName("Foo.NO_SUCH_VALUE") == NULL);
+  EXPECT_TRUE(pool.FindMethodByName("TestService.NoSuchMethod") == 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_);
+}
+
+// DescriptorDatabase that attempts to induce exponentially-bad performance
+// in DescriptorPool. For every positive N, the database contains a file
+// fileN.proto, which defines a message MessageN, which contains fields of
+// type MessageK for all K in [0,N). Message0 is not defined anywhere
+// (file0.proto exists, but is empty), so every other file and message type
+// will fail to build.
+//
+// If the DescriptorPool is not careful to memoize errors, an attempt to
+// build a descriptor for MessageN can require O(2^N) time.
+class ExponentialErrorDatabase : public DescriptorDatabase {
+ public:
+  ExponentialErrorDatabase() {}
+  ~ExponentialErrorDatabase() {}
+
+  // implements DescriptorDatabase ---------------------------------
+  bool FindFileByName(const string& filename,
+                      FileDescriptorProto* output) {
+    int file_num = -1;
+    FullMatch(filename, "file", ".proto", &file_num);
+    if (file_num > -1) {
+      return PopulateFile(file_num, output);
+    } else {
+      return false;
+    }
+  }
+  bool FindFileContainingSymbol(const string& symbol_name,
+                                FileDescriptorProto* output) {
+    int file_num = -1;
+    FullMatch(symbol_name, "Message", "", &file_num);
+    if (file_num > 0) {
+      return PopulateFile(file_num, output);
+    } else {
+      return false;
+    }
+  }
+  bool FindFileContainingExtension(const string& containing_type,
+                                   int field_number,
+                                   FileDescriptorProto* output) {
+    return false;
+  }
+
+ private:
+  void FullMatch(const string& name,
+                 const string& begin_with,
+                 const string& end_with,
+                 int* file_num) {
+    int begin_size = begin_with.size();
+    int end_size = end_with.size();
+    if (name.substr(0, begin_size) != begin_with ||
+        name.substr(name.size()- end_size, end_size) != end_with) {
+      return;
+    }
+    safe_strto32(name.substr(begin_size, name.size() - end_size - begin_size),
+                 file_num);
+  }
+
+  bool PopulateFile(int file_num, FileDescriptorProto* output) {
+    using strings::Substitute;
+    GOOGLE_CHECK_GE(file_num, 0);
+    output->Clear();
+    output->set_name(Substitute("file$0.proto", file_num));
+    // file0.proto doesn't define Message0
+    if (file_num > 0) {
+      DescriptorProto* message = output->add_message_type();
+      message->set_name(Substitute("Message$0", file_num));
+      for (int i = 0; i < file_num; ++i) {
+        output->add_dependency(Substitute("file$0.proto", i));
+        FieldDescriptorProto* field = message->add_field();
+        field->set_name(Substitute("field$0", i));
+        field->set_number(i);
+        field->set_label(FieldDescriptorProto::LABEL_OPTIONAL);
+        field->set_type(FieldDescriptorProto::TYPE_MESSAGE);
+        field->set_type_name(Substitute("Message$0", i));
+      }
+    }
+    return true;
+  }
+};
+
+TEST_F(DatabaseBackedPoolTest, DoesntReloadKnownBadFiles) {
+  ExponentialErrorDatabase error_database;
+  DescriptorPool pool(&error_database);
+
+  GOOGLE_LOG(INFO) << "A timeout in this test probably indicates a real bug.";
+
+  EXPECT_TRUE(pool.FindFileByName("file40.proto") == NULL);
+  EXPECT_TRUE(pool.FindMessageTypeByName("Message40") == NULL);
+}
+
+TEST_F(DatabaseBackedPoolTest, DoesntFallbackOnWrongType) {
+  // If a lookup finds a symbol of the wrong type (e.g. we pass a type name
+  // to FindFieldByName()), we should fail fast, without checking the fallback
+  // database.
+  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);
+
+  EXPECT_NE(0, call_counter.call_count_);
+  call_counter.Clear();
+
+  EXPECT_TRUE(pool.FindMessageTypeByName("TestEnum") == NULL);
+  EXPECT_TRUE(pool.FindFieldByName("Foo") == NULL);
+  EXPECT_TRUE(pool.FindExtensionByName("Foo") == NULL);
+  EXPECT_TRUE(pool.FindEnumTypeByName("Foo") == NULL);
+  EXPECT_TRUE(pool.FindEnumValueByName("Foo") == NULL);
+  EXPECT_TRUE(pool.FindServiceByName("Foo") == NULL);
+  EXPECT_TRUE(pool.FindMethodByName("Foo") == NULL);
+
+  EXPECT_EQ(0, call_counter.call_count_);
+}
+
+// ===================================================================
+
+class AbortingErrorCollector : public DescriptorPool::ErrorCollector {
+ public:
+  AbortingErrorCollector() {}
+
+  virtual void AddError(
+      const string &filename,
+      const string &element_name,
+      const Message *message,
+      ErrorLocation location,
+      const string &error_message) {
+    GOOGLE_LOG(FATAL) << "AddError() called unexpectedly: " << filename << ": "
+               << error_message;
+  }
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AbortingErrorCollector);
+};
+
+// A source tree containing only one file.
+class SingletonSourceTree : public compiler::SourceTree {
+ public:
+  SingletonSourceTree(const string& filename, const string& contents)
+      : filename_(filename), contents_(contents) {}
+
+  virtual io::ZeroCopyInputStream* Open(const string& filename) {
+    return filename == filename_ ?
+        new io::ArrayInputStream(contents_.data(), contents_.size()) : NULL;
+  }
+
+ private:
+  const string filename_;
+  const string contents_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingletonSourceTree);
+};
+
+const char *const kSourceLocationTestInput =
+  "syntax = \"proto2\";\n"
+  "message A {\n"
+  "  optional int32 a = 1;\n"
+  "  message B {\n"
+  "    required double b = 1;\n"
+  "  }\n"
+  "}\n"
+  "enum Indecision {\n"
+  "  YES   = 1;\n"
+  "  NO    = 2;\n"
+  "  MAYBE = 3;\n"
+  "}\n"
+  "service S {\n"
+  "  rpc Method(A) returns (A.B);\n"
+  // Put an empty line here to make the source location range match.
+  "\n"
+  "}\n"
+  "message MessageWithExtensions {\n"
+  "  extensions 1000 to max;\n"
+  "}\n"
+  "extend MessageWithExtensions {\n"
+  "  optional int32 int32_extension = 1001;\n"
+  "}\n"
+  "message C {\n"
+  "  extend MessageWithExtensions {\n"
+  "    optional C message_extension = 1002;\n"
+  "  }\n"
+  "}\n";
+
+class SourceLocationTest : public testing::Test {
+ public:
+  SourceLocationTest()
+      : source_tree_("/test/test.proto", kSourceLocationTestInput),
+        db_(&source_tree_),
+        pool_(&db_, &collector_) {}
+
+  static string PrintSourceLocation(const SourceLocation &loc) {
+    return strings::Substitute("$0:$1-$2:$3",
+                               1 + loc.start_line,
+                               1 + loc.start_column,
+                               1 + loc.end_line,
+                               1 + loc.end_column);
+  }
+
+ private:
+  AbortingErrorCollector collector_;
+  SingletonSourceTree source_tree_;
+  compiler::SourceTreeDescriptorDatabase db_;
+
+ protected:
+  DescriptorPool pool_;
+};
+
+// TODO(adonovan): implement support for option fields and for
+// subparts of declarations.
+
+TEST_F(SourceLocationTest, GetSourceLocation) {
+  SourceLocation loc;
+
+  const FileDescriptor *file_desc =
+      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+  const Descriptor *a_desc = file_desc->FindMessageTypeByName("A");
+  EXPECT_TRUE(a_desc->GetSourceLocation(&loc));
+  EXPECT_EQ("2:1-7:2", PrintSourceLocation(loc));
+
+  const Descriptor *a_b_desc = a_desc->FindNestedTypeByName("B");
+  EXPECT_TRUE(a_b_desc->GetSourceLocation(&loc));
+  EXPECT_EQ("4:3-6:4", PrintSourceLocation(loc));
+
+  const EnumDescriptor *e_desc = file_desc->FindEnumTypeByName("Indecision");
+  EXPECT_TRUE(e_desc->GetSourceLocation(&loc));
+  EXPECT_EQ("8:1-12:2", PrintSourceLocation(loc));
+
+  const EnumValueDescriptor *yes_desc = e_desc->FindValueByName("YES");
+  EXPECT_TRUE(yes_desc->GetSourceLocation(&loc));
+  EXPECT_EQ("9:3-9:13", PrintSourceLocation(loc));
+
+  const ServiceDescriptor *s_desc = file_desc->FindServiceByName("S");
+  EXPECT_TRUE(s_desc->GetSourceLocation(&loc));
+  EXPECT_EQ("13:1-16:2", PrintSourceLocation(loc));
+
+  const MethodDescriptor *m_desc = s_desc->FindMethodByName("Method");
+  EXPECT_TRUE(m_desc->GetSourceLocation(&loc));
+  EXPECT_EQ("14:3-14:31", PrintSourceLocation(loc));
+
+}
+
+TEST_F(SourceLocationTest, ExtensionSourceLocation) {
+  SourceLocation loc;
+
+  const FileDescriptor *file_desc =
+      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+  const FieldDescriptor *int32_extension_desc =
+      file_desc->FindExtensionByName("int32_extension");
+  EXPECT_TRUE(int32_extension_desc->GetSourceLocation(&loc));
+  EXPECT_EQ("21:3-21:41", PrintSourceLocation(loc));
+
+  const Descriptor *c_desc = file_desc->FindMessageTypeByName("C");
+  EXPECT_TRUE(c_desc->GetSourceLocation(&loc));
+  EXPECT_EQ("23:1-27:2", PrintSourceLocation(loc));
+
+  const FieldDescriptor *message_extension_desc =
+      c_desc->FindExtensionByName("message_extension");
+  EXPECT_TRUE(message_extension_desc->GetSourceLocation(&loc));
+  EXPECT_EQ("25:5-25:41", PrintSourceLocation(loc));
+}
+
+// Missing SourceCodeInfo doesn't cause crash:
+TEST_F(SourceLocationTest, GetSourceLocation_MissingSourceCodeInfo) {
+  SourceLocation loc;
+
+  const FileDescriptor *file_desc =
+      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+  FileDescriptorProto proto;
+  file_desc->CopyTo(&proto);  // Note, this discards the SourceCodeInfo.
+  EXPECT_FALSE(proto.has_source_code_info());
+
+  DescriptorPool bad1_pool(&pool_);
+  const FileDescriptor* bad1_file_desc =
+      GOOGLE_CHECK_NOTNULL(bad1_pool.BuildFile(proto));
+  const Descriptor *bad1_a_desc = bad1_file_desc->FindMessageTypeByName("A");
+  EXPECT_FALSE(bad1_a_desc->GetSourceLocation(&loc));
+}
+
+// Corrupt SourceCodeInfo doesn't cause crash:
+TEST_F(SourceLocationTest, GetSourceLocation_BogusSourceCodeInfo) {
+  SourceLocation loc;
+
+  const FileDescriptor *file_desc =
+      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+
+  FileDescriptorProto proto;
+  file_desc->CopyTo(&proto);  // Note, this discards the SourceCodeInfo.
+  EXPECT_FALSE(proto.has_source_code_info());
+  SourceCodeInfo_Location *loc_msg =
+      proto.mutable_source_code_info()->add_location();
+  loc_msg->add_path(1);
+  loc_msg->add_path(2);
+  loc_msg->add_path(3);
+  loc_msg->add_span(4);
+  loc_msg->add_span(5);
+  loc_msg->add_span(6);
+
+  DescriptorPool bad2_pool(&pool_);
+  const FileDescriptor* bad2_file_desc =
+      GOOGLE_CHECK_NOTNULL(bad2_pool.BuildFile(proto));
+  const Descriptor *bad2_a_desc = bad2_file_desc->FindMessageTypeByName("A");
+  EXPECT_FALSE(bad2_a_desc->GetSourceLocation(&loc));
+}
+
+// ===================================================================
+
+const char* const kCopySourceCodeInfoToTestInput =
+  "syntax = \"proto2\";\n"
+  "message Foo {}\n";
+
+// Required since source code information is not preserved by
+// FileDescriptorTest.
+class CopySourceCodeInfoToTest : public testing::Test {
+ public:
+  CopySourceCodeInfoToTest()
+      : source_tree_("/test/test.proto", kCopySourceCodeInfoToTestInput),
+        db_(&source_tree_),
+        pool_(&db_, &collector_) {}
+
+ private:
+  AbortingErrorCollector collector_;
+  SingletonSourceTree source_tree_;
+  compiler::SourceTreeDescriptorDatabase db_;
+
+ protected:
+  DescriptorPool pool_;
+};
+
+TEST_F(CopySourceCodeInfoToTest, CopyTo_DoesNotCopySourceCodeInfo) {
+  const FileDescriptor* file_desc =
+      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+  FileDescriptorProto file_desc_proto;
+  ASSERT_FALSE(file_desc_proto.has_source_code_info());
+
+  file_desc->CopyTo(&file_desc_proto);
+  EXPECT_FALSE(file_desc_proto.has_source_code_info());
+}
+
+TEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) {
+  const FileDescriptor* file_desc =
+      GOOGLE_CHECK_NOTNULL(pool_.FindFileByName("/test/test.proto"));
+  FileDescriptorProto file_desc_proto;
+  ASSERT_FALSE(file_desc_proto.has_source_code_info());
+
+  file_desc->CopySourceCodeInfoTo(&file_desc_proto);
+  const SourceCodeInfo& info = file_desc_proto.source_code_info();
+  ASSERT_EQ(3, info.location_size());
+  // Get the Foo message location
+  const SourceCodeInfo_Location& foo_location = info.location(1);
+  ASSERT_EQ(2, foo_location.path_size());
+  EXPECT_EQ(FileDescriptorProto::kMessageTypeFieldNumber, foo_location.path(0));
+  EXPECT_EQ(0, foo_location.path(1));      // Foo is the first message defined
+  ASSERT_EQ(3, foo_location.span_size());  // Foo spans one line
+  EXPECT_EQ(1, foo_location.span(0));      // Foo is declared on line 1
+  EXPECT_EQ(0, foo_location.span(1));      // Foo starts at column 0
+  EXPECT_EQ(14, foo_location.span(2));     // Foo ends on column 14
+}
+
+// ===================================================================
+
+
+}  // namespace descriptor_unittest
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/dynamic_message.cc b/protobuf/src/google/protobuf/dynamic_message.cc
new file mode 100644
index 0000000..4cca986
--- /dev/null
+++ b/protobuf/src/google/protobuf/dynamic_message.cc
@@ -0,0 +1,764 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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
+// 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_util.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;
+
+
+// ===================================================================
+// 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:
+        switch (field->options().ctype()) {
+          default:  // TODO(kenton):  Support other string reps.
+          case FieldOptions::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:
+        switch (field->options().ctype()) {
+          default:  // TODO(kenton):  Support other string reps.
+          case FieldOptions::STRING:
+            return sizeof(string*);
+        }
+        break;
+    }
+  }
+
+  GOOGLE_LOG(DFATAL) << "Can't get here.";
+  return 0;
+}
+
+// Compute the byte size of in-memory representation of the oneof fields
+// in default oneof instance.
+int OneofFieldSpaceUsed(const FieldDescriptor* field) {
+  typedef FieldDescriptor FD;  // avoid line wrapping
+  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:
+      switch (field->options().ctype()) {
+        default:
+        case FieldOptions::STRING:
+          return sizeof(string*);
+      }
+      break;
+  }
+
+  GOOGLE_LOG(DFATAL) << "Can't get here.";
+  return 0;
+}
+
+inline int DivideRoundingUp(int i, int j) {
+  return (i + (j - 1)) / j;
+}
+
+static const int kSafeAlignment = sizeof(uint64);
+static const int kMaxOneofUnionSize = sizeof(uint64);
+
+inline int AlignTo(int offset, int alignment) {
+  return DivideRoundingUp(offset, alignment) * alignment;
+}
+
+// Rounds the given byte offset up to the next offset aligned such that any
+// type may be stored at it.
+inline int AlignOffset(int offset) {
+  return AlignTo(offset, kSafeAlignment);
+}
+
+#define bitsizeof(T) (sizeof(T) * 8)
+
+}  // namespace
+
+// ===================================================================
+
+class DynamicMessage : public Message {
+ public:
+  struct TypeInfo {
+    int size;
+    int has_bits_offset;
+    int oneof_case_offset;
+    int unknown_fields_offset;
+    int extensions_offset;
+
+    // Not owned by the TypeInfo.
+    DynamicMessageFactory* factory;  // The factory that created this object.
+    const DescriptorPool* pool;      // The factory's DescriptorPool.
+    const Descriptor* type;          // Type of this DynamicMessage.
+
+    // Warning:  The order in which the following pointers are defined is
+    //   important (the prototype must be deleted *before* the offsets).
+    scoped_array<int> offsets;
+    scoped_ptr<const GeneratedMessageReflection> reflection;
+    // Don't use a scoped_ptr to hold the prototype: the destructor for
+    // DynamicMessage needs to know whether it is the prototype, and does so by
+    // looking back at this field. This would assume details about the
+    // implementation of scoped_ptr.
+    const DynamicMessage* prototype;
+    void* default_oneof_instance;
+
+    TypeInfo() : prototype(NULL), default_oneof_instance(NULL) {}
+
+    ~TypeInfo() {
+      delete prototype;
+      operator delete(default_oneof_instance);
+    }
+  };
+
+  DynamicMessage(const TypeInfo* type_info);
+  ~DynamicMessage();
+
+  // Called on the prototype after construction to initialize message fields.
+  void CrossLinkPrototypes();
+
+  // implements Message ----------------------------------------------
+
+  Message* New() const;
+
+  int GetCachedSize() const;
+  void SetCachedSize(int size) const;
+
+  Metadata GetMetadata() const;
+
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
+
+  inline bool is_prototype() const {
+    return type_info_->prototype == this ||
+           // If type_info_->prototype is NULL, then we must be constructing
+           // the prototype now, which means we must be the prototype.
+           type_info_->prototype == NULL;
+  }
+
+  inline void* OffsetToPointer(int offset) {
+    return reinterpret_cast<uint8*>(this) + offset;
+  }
+  inline const void* OffsetToPointer(int offset) const {
+    return reinterpret_cast<const uint8*>(this) + offset;
+  }
+
+  const TypeInfo* type_info_;
+
+  // TODO(kenton):  Make this an atomic<int> when C++ supports it.
+  mutable int cached_byte_size_;
+};
+
+DynamicMessage::DynamicMessage(const TypeInfo* type_info)
+  : type_info_(type_info),
+    cached_byte_size_(0) {
+  // We need to call constructors for various fields manually and set
+  // default values where appropriate.  We use placement new to call
+  // 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.)
+
+  const Descriptor* descriptor = type_info_->type;
+
+  // Initialize oneof cases.
+  for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) {
+    new(OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i))
+        uint32(0);
+  }
+
+  new(OffsetToPointer(type_info_->unknown_fields_offset)) UnknownFieldSet;
+
+  if (type_info_->extensions_offset != -1) {
+    new(OffsetToPointer(type_info_->extensions_offset)) ExtensionSet;
+  }
+
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    const FieldDescriptor* field = descriptor->field(i);
+    void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
+    if (field->containing_oneof()) {
+      continue;
+    }
+    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:
+        switch (field->options().ctype()) {
+          default:  // TODO(kenton):  Support other string reps.
+          case FieldOptions::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*>(
+                    type_info_->prototype->OffsetToPointer(
+                      type_info_->offsets[i]));
+                new(field_ptr) string*(default_value);
+              }
+            } else {
+              new(field_ptr) RepeatedPtrField<string>();
+            }
+            break;
+        }
+        break;
+
+      case FieldDescriptor::CPPTYPE_MESSAGE: {
+        if (!field->is_repeated()) {
+          new(field_ptr) Message*(NULL);
+        } else {
+          new(field_ptr) RepeatedPtrField<Message>();
+        }
+        break;
+      }
+    }
+  }
+}
+
+DynamicMessage::~DynamicMessage() {
+  const Descriptor* descriptor = type_info_->type;
+
+  reinterpret_cast<UnknownFieldSet*>(
+    OffsetToPointer(type_info_->unknown_fields_offset))->~UnknownFieldSet();
+
+  if (type_info_->extensions_offset != -1) {
+    reinterpret_cast<ExtensionSet*>(
+      OffsetToPointer(type_info_->extensions_offset))->~ExtensionSet();
+  }
+
+  // We need to manually run the destructors for repeated fields and strings,
+  // just as we ran their constructors in the the DynamicMessage constructor.
+  // We also need to manually delete oneof fields if it is set and is string
+  // or message.
+  // 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.
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    const FieldDescriptor* field = descriptor->field(i);
+    if (field->containing_oneof()) {
+      void* field_ptr = OffsetToPointer(
+          type_info_->oneof_case_offset
+          + sizeof(uint32) * field->containing_oneof()->index());
+      if (*(reinterpret_cast<const uint32*>(field_ptr)) ==
+          field->number()) {
+        field_ptr = OffsetToPointer(type_info_->offsets[
+            descriptor->field_count() + field->containing_oneof()->index()]);
+        if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+          switch (field->options().ctype()) {
+            default:
+            case FieldOptions::STRING:
+              delete *reinterpret_cast<string**>(field_ptr);
+              break;
+          }
+        } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+            delete *reinterpret_cast<Message**>(field_ptr);
+        }
+      }
+      continue;
+    }
+    void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
+
+    if (field->is_repeated()) {
+      switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
+        case FieldDescriptor::CPPTYPE_##UPPERCASE :                           \
+          reinterpret_cast<RepeatedField<LOWERCASE>*>(field_ptr)              \
+              ->~RepeatedField<LOWERCASE>();                                  \
+          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);
+        HANDLE_TYPE(  ENUM,    int);
+#undef HANDLE_TYPE
+
+        case FieldDescriptor::CPPTYPE_STRING:
+          switch (field->options().ctype()) {
+            default:  // TODO(kenton):  Support other string reps.
+            case FieldOptions::STRING:
+              reinterpret_cast<RepeatedPtrField<string>*>(field_ptr)
+                  ->~RepeatedPtrField<string>();
+              break;
+          }
+          break;
+
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr)
+              ->~RepeatedPtrField<Message>();
+          break;
+      }
+
+    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+      switch (field->options().ctype()) {
+        default:  // TODO(kenton):  Support other string reps.
+        case FieldOptions::STRING: {
+          string* ptr = *reinterpret_cast<string**>(field_ptr);
+          if (ptr != &field->default_value_string()) {
+            delete ptr;
+          }
+          break;
+        }
+      }
+    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (!is_prototype()) {
+        Message* message = *reinterpret_cast<Message**>(field_ptr);
+        if (message != NULL) {
+          delete message;
+        }
+      }
+    }
+  }
+}
+
+void DynamicMessage::CrossLinkPrototypes() {
+  // This should only be called on the prototype message.
+  GOOGLE_CHECK(is_prototype());
+
+  DynamicMessageFactory* factory = type_info_->factory;
+  const Descriptor* descriptor = type_info_->type;
+
+  // Cross-link default messages.
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    const FieldDescriptor* field = descriptor->field(i);
+    void* field_ptr = OffsetToPointer(type_info_->offsets[i]);
+    if (field->containing_oneof()) {
+      field_ptr = reinterpret_cast<uint8*>(
+          type_info_->default_oneof_instance) + type_info_->offsets[i];
+    }
+
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+        !field->is_repeated()) {
+      // For fields with message types, we need to cross-link with the
+      // prototype for the field's type.
+      // For singular fields, the field is just a pointer which should
+      // point to the prototype.
+      *reinterpret_cast<const Message**>(field_ptr) =
+        factory->GetPrototypeNoLock(field->message_type());
+    }
+  }
+}
+
+Message* DynamicMessage::New() const {
+  void* new_base = operator new(type_info_->size);
+  memset(new_base, 0, type_info_->size);
+  return new(new_base) DynamicMessage(type_info_);
+}
+
+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.
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  cached_byte_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+
+Metadata DynamicMessage::GetMetadata() const {
+  Metadata metadata;
+  metadata.descriptor = type_info_->type;
+  metadata.reflection = type_info_->reflection.get();
+  return metadata;
+}
+
+// ===================================================================
+
+struct DynamicMessageFactory::PrototypeMap {
+  typedef hash_map<const Descriptor*, const DynamicMessage::TypeInfo*> Map;
+  Map map_;
+};
+
+DynamicMessageFactory::DynamicMessageFactory()
+  : pool_(NULL), delegate_to_generated_factory_(false),
+    prototypes_(new PrototypeMap) {
+}
+
+DynamicMessageFactory::DynamicMessageFactory(const DescriptorPool* pool)
+  : pool_(pool), delegate_to_generated_factory_(false),
+    prototypes_(new PrototypeMap) {
+}
+
+DynamicMessageFactory::~DynamicMessageFactory() {
+  for (PrototypeMap::Map::iterator iter = prototypes_->map_.begin();
+       iter != prototypes_->map_.end(); ++iter) {
+    DeleteDefaultOneofInstance(iter->second->type,
+                               iter->second->offsets.get(),
+                               iter->second->default_oneof_instance);
+    delete iter->second;
+  }
+}
+
+const Message* DynamicMessageFactory::GetPrototype(const Descriptor* type) {
+  MutexLock lock(&prototypes_mutex_);
+  return GetPrototypeNoLock(type);
+}
+
+const Message* DynamicMessageFactory::GetPrototypeNoLock(
+    const Descriptor* type) {
+  if (delegate_to_generated_factory_ &&
+      type->file()->pool() == DescriptorPool::generated_pool()) {
+    return MessageFactory::generated_factory()->GetPrototype(type);
+  }
+
+  const DynamicMessage::TypeInfo** target = &prototypes_->map_[type];
+  if (*target != NULL) {
+    // Already exists.
+    return (*target)->prototype;
+  }
+
+  DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo;
+  *target = type_info;
+
+  type_info->type = type;
+  type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_;
+  type_info->factory = this;
+
+  // We need to construct all the structures passed to
+  // GeneratedMessageReflection's constructor.  This includes:
+  // - A block of memory that contains space for all the message's fields.
+  // - 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() + type->oneof_decl_count()];
+  type_info->offsets.reset(offsets);
+
+  // Decide all field offsets by packing in order.
+  // We place the DynamicMessage object itself at the beginning of the allocated
+  // space.
+  int size = sizeof(DynamicMessage);
+  size = AlignOffset(size);
+
+  // Next the has_bits, which is an array of uint32s.
+  type_info->has_bits_offset = size;
+  int has_bits_array_size =
+    DivideRoundingUp(type->field_count(), bitsizeof(uint32));
+  size += has_bits_array_size * sizeof(uint32);
+  size = AlignOffset(size);
+
+  // The oneof_case, if any. It is an array of uint32s.
+  if (type->oneof_decl_count() > 0) {
+    type_info->oneof_case_offset = size;
+    size += type->oneof_decl_count() * sizeof(uint32);
+    size = AlignOffset(size);
+  }
+
+  // The ExtensionSet, if any.
+  if (type->extension_range_count() > 0) {
+    type_info->extensions_offset = size;
+    size += sizeof(ExtensionSet);
+    size = AlignOffset(size);
+  } else {
+    // No extensions.
+    type_info->extensions_offset = -1;
+  }
+
+  // All the fields.
+  for (int i = 0; i < type->field_count(); i++) {
+    // Make sure field is aligned to avoid bus errors.
+    // Oneof fields do not use any space.
+    if (!type->field(i)->containing_oneof()) {
+      int field_size = FieldSpaceUsed(type->field(i));
+      size = AlignTo(size, min(kSafeAlignment, field_size));
+      offsets[i] = size;
+      size += field_size;
+    }
+  }
+
+  // The oneofs.
+  for (int i = 0; i < type->oneof_decl_count(); i++) {
+    size = AlignTo(size, kSafeAlignment);
+    offsets[type->field_count() + i] = size;
+    size += kMaxOneofUnionSize;
+  }
+
+  // Add the UnknownFieldSet to the end.
+  size = AlignOffset(size);
+  type_info->unknown_fields_offset = size;
+  size += sizeof(UnknownFieldSet);
+
+  // Align the final size to make sure no clever allocators think that
+  // alignment is not necessary.
+  size = AlignOffset(size);
+  type_info->size = size;
+
+  // Allocate the prototype.
+  void* base = operator new(size);
+  memset(base, 0, size);
+  DynamicMessage* prototype = new(base) DynamicMessage(type_info);
+  type_info->prototype = prototype;
+
+  // Construct the reflection object.
+  if (type->oneof_decl_count() > 0) {
+    // Compute the size of default oneof instance and offsets of default
+    // oneof fields.
+    int oneof_size = 0;
+    for (int i = 0; i < type->oneof_decl_count(); i++) {
+      for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
+        const FieldDescriptor* field = type->oneof_decl(i)->field(j);
+        int field_size = OneofFieldSpaceUsed(field);
+        oneof_size = AlignTo(oneof_size, min(kSafeAlignment, field_size));
+        offsets[field->index()] = oneof_size;
+        oneof_size += field_size;
+      }
+    }
+    // Construct default oneof instance.
+    type_info->default_oneof_instance = ::operator new(oneof_size);
+    ConstructDefaultOneofInstance(type_info->type,
+                                  type_info->offsets.get(),
+                                  type_info->default_oneof_instance);
+    type_info->reflection.reset(
+        new GeneratedMessageReflection(
+            type_info->type,
+            type_info->prototype,
+            type_info->offsets.get(),
+            type_info->has_bits_offset,
+            type_info->unknown_fields_offset,
+            type_info->extensions_offset,
+            type_info->default_oneof_instance,
+            type_info->oneof_case_offset,
+            type_info->pool,
+            this,
+            type_info->size));
+  } else {
+    type_info->reflection.reset(
+        new GeneratedMessageReflection(
+            type_info->type,
+            type_info->prototype,
+            type_info->offsets.get(),
+            type_info->has_bits_offset,
+            type_info->unknown_fields_offset,
+            type_info->extensions_offset,
+            type_info->pool,
+            this,
+            type_info->size));
+  }
+  // Cross link prototypes.
+  prototype->CrossLinkPrototypes();
+
+  return prototype;
+}
+
+void DynamicMessageFactory::ConstructDefaultOneofInstance(
+    const Descriptor* type,
+    const int offsets[],
+    void* default_oneof_instance) {
+  for (int i = 0; i < type->oneof_decl_count(); i++) {
+    for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
+      const FieldDescriptor* field = type->oneof_decl(i)->field(j);
+      void* field_ptr = reinterpret_cast<uint8*>(
+          default_oneof_instance) + offsets[field->index()];
+      switch (field->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, TYPE)                                      \
+        case FieldDescriptor::CPPTYPE_##CPPTYPE:                        \
+          new(field_ptr) TYPE(field->default_value_##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:
+          new(field_ptr) int(field->default_value_enum()->number());
+          break;
+        case FieldDescriptor::CPPTYPE_STRING:
+          switch (field->options().ctype()) {
+            default:
+            case FieldOptions::STRING:
+              if (field->has_default_value()) {
+                new(field_ptr) const string*(&field->default_value_string());
+              } else {
+                new(field_ptr) string*(
+                    const_cast<string*>(&internal::GetEmptyString()));
+              }
+              break;
+          }
+          break;
+
+        case FieldDescriptor::CPPTYPE_MESSAGE: {
+          new(field_ptr) Message*(NULL);
+          break;
+        }
+      }
+    }
+  }
+}
+
+void DynamicMessageFactory::DeleteDefaultOneofInstance(
+    const Descriptor* type,
+    const int offsets[],
+    void* default_oneof_instance) {
+  for (int i = 0; i < type->oneof_decl_count(); i++) {
+    for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) {
+      const FieldDescriptor* field = type->oneof_decl(i)->field(j);
+      if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+        switch (field->options().ctype()) {
+          default:
+          case FieldOptions::STRING:
+            break;
+        }
+      }
+    }
+  }
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/dynamic_message.h b/protobuf/src/google/protobuf/dynamic_message.h
new file mode 100644
index 0000000..10ed700
--- /dev/null
+++ b/protobuf/src/google/protobuf/dynamic_message.h
@@ -0,0 +1,148 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <memory>
+
+#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 extendee is defined.
+  DynamicMessageFactory();
+
+  // Construct a DynamicMessageFactory that will search for extensions in
+  // the given DescriptorPool.
+  //
+  // DEPRECATED:  Use CodedInputStream::SetExtensionRegistry() to tell the
+  //   parser to look for extensions in an alternate pool.  However, note that
+  //   this is almost never what you want to do.  Almost all users should use
+  //   the zero-arg constructor.
+  DynamicMessageFactory(const DescriptorPool* pool);
+
+  ~DynamicMessageFactory();
+
+  // Call this to tell the DynamicMessageFactory that if it is given a
+  // Descriptor d for which:
+  //   d->file()->pool() == DescriptorPool::generated_pool(),
+  // then it should delegate to MessageFactory::generated_factory() instead
+  // of constructing a dynamic implementation of the message.  In theory there
+  // is no down side to doing this, so it may become the default in the future.
+  void SetDelegateToGeneratedFactory(bool enable) {
+    delegate_to_generated_factory_ = enable;
+  }
+
+  // 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 destroyed before the DynamicMessageFactory
+  // is destroyed.
+  //
+  // The given descriptor must outlive the returned message, and hence must
+  // outlive the DynamicMessageFactory.
+  //
+  // The method is thread-safe.
+  const Message* GetPrototype(const Descriptor* type);
+
+ private:
+  const DescriptorPool* pool_;
+  bool delegate_to_generated_factory_;
+
+  // 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_;
+  mutable Mutex prototypes_mutex_;
+
+  friend class DynamicMessage;
+  const Message* GetPrototypeNoLock(const Descriptor* type);
+
+  // Construct default oneof instance for reflection usage if oneof
+  // is defined.
+  static void ConstructDefaultOneofInstance(const Descriptor* type,
+                                            const int offsets[],
+                                            void* default_oneof_instance);
+  // Delete default oneof instance. Called by ~DynamicMessageFactory.
+  static void DeleteDefaultOneofInstance(const Descriptor* type,
+                                         const int offsets[],
+                                         void* default_oneof_instance);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessageFactory);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_DYNAMIC_MESSAGE_H__
diff --git a/protobuf/src/google/protobuf/dynamic_message_unittest.cc b/protobuf/src/google/protobuf/dynamic_message_unittest.cc
new file mode 100644
index 0000000..a1c1661
--- /dev/null
+++ b/protobuf/src/google/protobuf/dynamic_message_unittest.cc
@@ -0,0 +1,230 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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_;
+  const Descriptor* packed_descriptor_;
+  const Message* packed_prototype_;
+  const Descriptor* oneof_descriptor_;
+  const Message* oneof_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;
+    FileDescriptorProto unittest_import_public_file;
+
+    unittest::TestAllTypes::descriptor()->file()->CopyTo(&unittest_file);
+    unittest_import::ImportMessage::descriptor()->file()->CopyTo(
+      &unittest_import_file);
+    unittest_import::PublicImportMessage::descriptor()->file()->CopyTo(
+      &unittest_import_public_file);
+
+    ASSERT_TRUE(pool_.BuildFile(unittest_import_public_file) != NULL);
+    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_);
+
+    packed_descriptor_ =
+      pool_.FindMessageTypeByName("protobuf_unittest.TestPackedTypes");
+    ASSERT_TRUE(packed_descriptor_ != NULL);
+    packed_prototype_ = factory_.GetPrototype(packed_descriptor_);
+
+    oneof_descriptor_ =
+      pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2");
+    ASSERT_TRUE(oneof_descriptor_ != NULL);
+    oneof_prototype_ = factory_.GetPrototype(oneof_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_);
+}
+
+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.get());
+  reflection_tester.ExpectAllFieldsSetViaReflection(*message);
+}
+
+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.get());
+  reflection_tester.ExpectAllFieldsSetViaReflection(*message);
+}
+
+TEST_F(DynamicMessageTest, PackedFields) {
+  // Check that packed fields work properly.
+  scoped_ptr<Message> message(packed_prototype_->New());
+  TestUtil::ReflectionTester reflection_tester(packed_descriptor_);
+
+  reflection_tester.SetPackedFieldsViaReflection(message.get());
+  reflection_tester.ExpectPackedFieldsSetViaReflection(*message);
+}
+
+TEST_F(DynamicMessageTest, Oneof) {
+  // Check that oneof fields work properly.
+  scoped_ptr<Message> message(oneof_prototype_->New());
+
+  // Check default values.
+  const Descriptor* descriptor = message->GetDescriptor();
+  const Reflection* reflection = message->GetReflection();
+  EXPECT_EQ(0, reflection->GetInt32(
+      *message, descriptor->FindFieldByName("foo_int")));
+  EXPECT_EQ("", reflection->GetString(
+      *message, descriptor->FindFieldByName("foo_string")));
+  EXPECT_EQ("", reflection->GetString(
+      *message, descriptor->FindFieldByName("foo_cord")));
+  EXPECT_EQ("", reflection->GetString(
+      *message, descriptor->FindFieldByName("foo_string_piece")));
+  EXPECT_EQ("", reflection->GetString(
+      *message, descriptor->FindFieldByName("foo_bytes")));
+  EXPECT_EQ(unittest::TestOneof2::FOO, reflection->GetEnum(
+      *message, descriptor->FindFieldByName("foo_enum"))->number());
+  const Descriptor* nested_descriptor;
+  const Message* nested_prototype;
+  nested_descriptor =
+      pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2.NestedMessage");
+  nested_prototype = factory_.GetPrototype(nested_descriptor);
+  EXPECT_EQ(nested_prototype,
+            &reflection->GetMessage(
+                *message, descriptor->FindFieldByName("foo_message")));
+  const Descriptor* foogroup_descriptor;
+  const Message* foogroup_prototype;
+  foogroup_descriptor =
+      pool_.FindMessageTypeByName("protobuf_unittest.TestOneof2.FooGroup");
+  foogroup_prototype = factory_.GetPrototype(foogroup_descriptor);
+  EXPECT_EQ(foogroup_prototype,
+            &reflection->GetMessage(
+                *message, descriptor->FindFieldByName("foogroup")));
+  EXPECT_NE(foogroup_prototype,
+            &reflection->GetMessage(
+                *message, descriptor->FindFieldByName("foo_lazy_message")));
+  EXPECT_EQ(5, reflection->GetInt32(
+      *message, descriptor->FindFieldByName("bar_int")));
+  EXPECT_EQ("STRING", reflection->GetString(
+      *message, descriptor->FindFieldByName("bar_string")));
+  EXPECT_EQ("CORD", reflection->GetString(
+      *message, descriptor->FindFieldByName("bar_cord")));
+  EXPECT_EQ("SPIECE", reflection->GetString(
+      *message, descriptor->FindFieldByName("bar_string_piece")));
+  EXPECT_EQ("BYTES", reflection->GetString(
+      *message, descriptor->FindFieldByName("bar_bytes")));
+  EXPECT_EQ(unittest::TestOneof2::BAR, reflection->GetEnum(
+      *message, descriptor->FindFieldByName("bar_enum"))->number());
+
+  // Check set functions.
+  TestUtil::ReflectionTester reflection_tester(oneof_descriptor_);
+  reflection_tester.SetOneofViaReflection(message.get());
+  reflection_tester.ExpectOneofSetViaReflection(*message);
+}
+
+TEST_F(DynamicMessageTest, SpaceUsed) {
+  // Test that SpaceUsed() works properly
+
+  // Since we share the implementation with generated messages, we don't need
+  // to test very much here.  Just make sure it appears to be working.
+
+  scoped_ptr<Message> message(prototype_->New());
+  TestUtil::ReflectionTester reflection_tester(descriptor_);
+
+  int initial_space_used = message->SpaceUsed();
+
+  reflection_tester.SetAllFieldsViaReflection(message.get());
+  EXPECT_LT(initial_space_used, message->SpaceUsed());
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/extension_set.cc b/protobuf/src/google/protobuf/extension_set.cc
new file mode 100644
index 0000000..274554b
--- /dev/null
+++ b/protobuf/src/google/protobuf/extension_set.cc
@@ -0,0 +1,1663 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/stubs/map_util.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+namespace {
+
+inline WireFormatLite::FieldType real_type(FieldType type) {
+  GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
+  return static_cast<WireFormatLite::FieldType>(type);
+}
+
+inline WireFormatLite::CppType cpp_type(FieldType type) {
+  return WireFormatLite::FieldTypeToCppType(real_type(type));
+}
+
+inline bool is_packable(WireFormatLite::WireType type) {
+  switch (type) {
+    case WireFormatLite::WIRETYPE_VARINT:
+    case WireFormatLite::WIRETYPE_FIXED64:
+    case WireFormatLite::WIRETYPE_FIXED32:
+      return true;
+    case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
+    case WireFormatLite::WIRETYPE_START_GROUP:
+    case WireFormatLite::WIRETYPE_END_GROUP:
+      return false;
+
+    // Do not add a default statement. Let the compiler complain when someone
+    // adds a new wire type.
+  }
+}
+
+// Registry stuff.
+typedef hash_map<pair<const MessageLite*, int>,
+                 ExtensionInfo> ExtensionRegistry;
+ExtensionRegistry* registry_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
+
+void DeleteRegistry() {
+  delete registry_;
+  registry_ = NULL;
+}
+
+void InitRegistry() {
+  registry_ = new ExtensionRegistry;
+  OnShutdown(&DeleteRegistry);
+}
+
+// This function is only called at startup, so there is no need for thread-
+// safety.
+void Register(const MessageLite* containing_type,
+              int number, ExtensionInfo info) {
+  ::google::protobuf::GoogleOnceInit(&registry_init_, &InitRegistry);
+
+  if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
+                          info)) {
+    GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
+               << containing_type->GetTypeName()
+               << "\", field number " << number << ".";
+  }
+}
+
+const ExtensionInfo* FindRegisteredExtension(
+    const MessageLite* containing_type, int number) {
+  return (registry_ == NULL) ? NULL :
+         FindOrNull(*registry_, make_pair(containing_type, number));
+}
+
+}  // namespace
+
+ExtensionFinder::~ExtensionFinder() {}
+
+bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
+  const ExtensionInfo* extension =
+      FindRegisteredExtension(containing_type_, number);
+  if (extension == NULL) {
+    return false;
+  } else {
+    *output = *extension;
+    return true;
+  }
+}
+
+void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
+                                     int number, FieldType type,
+                                     bool is_repeated, bool is_packed) {
+  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
+  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
+  GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
+  ExtensionInfo info(type, is_repeated, is_packed);
+  Register(containing_type, number, info);
+}
+
+static bool CallNoArgValidityFunc(const void* arg, int number) {
+  // Note:  Must use C-style cast here rather than reinterpret_cast because
+  //   the C++ standard at one point did not allow casts between function and
+  //   data pointers and some compilers enforce this for C++-style casts.  No
+  //   compiler enforces it for C-style casts since lots of C-style code has
+  //   relied on these kinds of casts for a long time, despite being
+  //   technically undefined.  See:
+  //     http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
+  // Also note:  Some compilers do not allow function pointers to be "const".
+  //   Which makes sense, I suppose, because it's meaningless.
+  return ((EnumValidityFunc*)arg)(number);
+}
+
+void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
+                                         int number, FieldType type,
+                                         bool is_repeated, bool is_packed,
+                                         EnumValidityFunc* is_valid) {
+  GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
+  ExtensionInfo info(type, is_repeated, is_packed);
+  info.enum_validity_check.func = CallNoArgValidityFunc;
+  // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
+  info.enum_validity_check.arg = (void*)is_valid;
+  Register(containing_type, number, info);
+}
+
+void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
+                                            int number, FieldType type,
+                                            bool is_repeated, bool is_packed,
+                                            const MessageLite* prototype) {
+  GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
+        type == WireFormatLite::TYPE_GROUP);
+  ExtensionInfo info(type, is_repeated, is_packed);
+  info.message_prototype = prototype;
+  Register(containing_type, number, info);
+}
+
+
+// ===================================================================
+// Constructors and basic methods.
+
+ExtensionSet::ExtensionSet() {}
+
+ExtensionSet::~ExtensionSet() {
+  for (map<int, Extension>::iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    iter->second.Free();
+  }
+}
+
+// Defined in extension_set_heavy.cc.
+// void ExtensionSet::AppendToList(const Descriptor* containing_type,
+//                                 const DescriptorPool* pool,
+//                                 vector<const FieldDescriptor*>* output) const
+
+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.is_repeated);
+  return !iter->second.is_cleared;
+}
+
+int ExtensionSet::NumExtensions() const {
+  int result = 0;
+  for (map<int, Extension>::const_iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    if (!iter->second.is_cleared) {
+      ++result;
+    }
+  }
+  return result;
+}
+
+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();
+}
+
+FieldType ExtensionSet::ExtensionType(int number) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) {
+    GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
+    return 0;
+  }
+  if (iter->second.is_cleared) {
+    GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
+  }
+  return iter->second.type;
+}
+
+void ExtensionSet::ClearExtension(int number) {
+  map<int, Extension>::iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) return;
+  iter->second.Clear();
+}
+
+// ===================================================================
+// Field accessors
+
+namespace {
+
+enum Cardinality {
+  REPEATED,
+  OPTIONAL
+};
+
+}  // namespace
+
+#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                             \
+  GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL);         \
+  GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
+
+// -------------------------------------------------------------------
+// Primitives
+
+#define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE)                   \
+                                                                               \
+LOWERCASE ExtensionSet::Get##CAMELCASE(int number,                             \
+                                       LOWERCASE default_value) const {        \
+  map<int, Extension>::const_iterator iter = extensions_.find(number);         \
+  if (iter == extensions_.end() || iter->second.is_cleared) {                  \
+    return default_value;                                                      \
+  } else {                                                                     \
+    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE);                            \
+    return iter->second.LOWERCASE##_value;                                     \
+  }                                                                            \
+}                                                                              \
+                                                                               \
+void ExtensionSet::Set##CAMELCASE(int number, FieldType type,                  \
+                                  LOWERCASE value,                             \
+                                  const FieldDescriptor* descriptor) {         \
+  Extension* extension;                                                        \
+  if (MaybeNewExtension(number, descriptor, &extension)) {                     \
+    extension->type = type;                                                    \
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
+    extension->is_repeated = false;                                            \
+  } else {                                                                     \
+    GOOGLE_DCHECK_TYPE(*extension, 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, 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, REPEATED, UPPERCASE);                              \
+  iter->second.repeated_##LOWERCASE##_value->Set(index, value);                \
+}                                                                              \
+                                                                               \
+void ExtensionSet::Add##CAMELCASE(int number, FieldType type,                  \
+                                  bool packed, LOWERCASE value,                \
+                                  const FieldDescriptor* descriptor) {         \
+  Extension* extension;                                                        \
+  if (MaybeNewExtension(number, descriptor, &extension)) {                     \
+    extension->type = type;                                                    \
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
+    extension->is_repeated = true;                                             \
+    extension->is_packed = packed;                                             \
+    extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>();  \
+  } else {                                                                     \
+    GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE);                              \
+    GOOGLE_DCHECK_EQ(extension->is_packed, packed);                                   \
+  }                                                                            \
+  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
+
+const void* ExtensionSet::GetRawRepeatedField(int number,
+                                              const void* default_value) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) {
+    return default_value;
+  }
+  // We assume that all the RepeatedField<>* pointers have the same
+  // size and alignment within the anonymous union in Extension.
+  return iter->second.repeated_int32_value;
+}
+
+void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
+                                            bool packed,
+                                            const FieldDescriptor* desc) {
+  Extension* extension;
+
+  // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
+  // extension.
+  if (MaybeNewExtension(number, desc, &extension)) {
+    extension->is_repeated = true;
+    extension->type = field_type;
+    extension->is_packed = packed;
+
+    switch (WireFormatLite::FieldTypeToCppType(
+        static_cast<WireFormatLite::FieldType>(field_type))) {
+      case WireFormatLite::CPPTYPE_INT32:
+        extension->repeated_int32_value = new RepeatedField<int32>();
+        break;
+      case WireFormatLite::CPPTYPE_INT64:
+        extension->repeated_int64_value = new RepeatedField<int64>();
+        break;
+      case WireFormatLite::CPPTYPE_UINT32:
+        extension->repeated_uint32_value = new RepeatedField<uint32>();
+        break;
+      case WireFormatLite::CPPTYPE_UINT64:
+        extension->repeated_uint64_value = new RepeatedField<uint64>();
+        break;
+      case WireFormatLite::CPPTYPE_DOUBLE:
+        extension->repeated_double_value = new RepeatedField<double>();
+        break;
+      case WireFormatLite::CPPTYPE_FLOAT:
+        extension->repeated_float_value = new RepeatedField<float>();
+        break;
+      case WireFormatLite::CPPTYPE_BOOL:
+        extension->repeated_bool_value = new RepeatedField<bool>();
+        break;
+      case WireFormatLite::CPPTYPE_ENUM:
+        extension->repeated_enum_value = new RepeatedField<int>();
+        break;
+      case WireFormatLite::CPPTYPE_STRING:
+        extension->repeated_string_value = new RepeatedPtrField< ::std::string>();
+        break;
+      case WireFormatLite::CPPTYPE_MESSAGE:
+        extension->repeated_message_value = new RepeatedPtrField<MessageLite>();
+        break;
+    }
+  }
+
+  // We assume that all the RepeatedField<>* pointers have the same
+  // size and alignment within the anonymous union in Extension.
+  return extension->repeated_int32_value;
+}
+
+// Compatible version using old call signature. Does not create extensions when
+// the don't already exist; instead, just GOOGLE_CHECK-fails.
+void* ExtensionSet::MutableRawRepeatedField(int number) {
+  map<int, Extension>::iterator iter = extensions_.find(number);
+  GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found.";
+  // We assume that all the RepeatedField<>* pointers have the same
+  // size and alignment within the anonymous union in Extension.
+  return iter->second.repeated_int32_value;
+}
+
+
+// -------------------------------------------------------------------
+// Enums
+
+int ExtensionSet::GetEnum(int number, int default_value) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end() || iter->second.is_cleared) {
+    // Not present.  Return the default value.
+    return default_value;
+  } else {
+    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
+    return iter->second.enum_value;
+  }
+}
+
+void ExtensionSet::SetEnum(int number, FieldType type, int value,
+                           const FieldDescriptor* descriptor) {
+  Extension* extension;
+  if (MaybeNewExtension(number, descriptor, &extension)) {
+    extension->type = type;
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
+    extension->is_repeated = false;
+  } else {
+    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
+  }
+  extension->is_cleared = false;
+  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, 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, REPEATED, ENUM);
+  iter->second.repeated_enum_value->Set(index, value);
+}
+
+void ExtensionSet::AddEnum(int number, FieldType type,
+                           bool packed, int value,
+                           const FieldDescriptor* descriptor) {
+  Extension* extension;
+  if (MaybeNewExtension(number, descriptor, &extension)) {
+    extension->type = type;
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
+    extension->is_repeated = true;
+    extension->is_packed = packed;
+    extension->repeated_enum_value = new RepeatedField<int>();
+  } else {
+    GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
+    GOOGLE_DCHECK_EQ(extension->is_packed, packed);
+  }
+  extension->repeated_enum_value->Add(value);
+}
+
+// -------------------------------------------------------------------
+// Strings
+
+const string& ExtensionSet::GetString(int number,
+                                      const string& default_value) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end() || iter->second.is_cleared) {
+    // Not present.  Return the default value.
+    return default_value;
+  } else {
+    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
+    return *iter->second.string_value;
+  }
+}
+
+string* ExtensionSet::MutableString(int number, FieldType type,
+                                    const FieldDescriptor* descriptor) {
+  Extension* extension;
+  if (MaybeNewExtension(number, descriptor, &extension)) {
+    extension->type = type;
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
+    extension->is_repeated = false;
+    extension->string_value = new string;
+  } else {
+    GOOGLE_DCHECK_TYPE(*extension, 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, 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, REPEATED, STRING);
+  return iter->second.repeated_string_value->Mutable(index);
+}
+
+string* ExtensionSet::AddString(int number, FieldType type,
+                                const FieldDescriptor* descriptor) {
+  Extension* extension;
+  if (MaybeNewExtension(number, descriptor, &extension)) {
+    extension->type = type;
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
+    extension->is_repeated = true;
+    extension->is_packed = false;
+    extension->repeated_string_value = new RepeatedPtrField<string>();
+  } else {
+    GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
+  }
+  return extension->repeated_string_value->Add();
+}
+
+// -------------------------------------------------------------------
+// Messages
+
+const MessageLite& ExtensionSet::GetMessage(
+    int number, const MessageLite& default_value) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) {
+    // Not present.  Return the default value.
+    return default_value;
+  } else {
+    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
+    if (iter->second.is_lazy) {
+      return iter->second.lazymessage_value->GetMessage(default_value);
+    } else {
+      return *iter->second.message_value;
+    }
+  }
+}
+
+// Defined in extension_set_heavy.cc.
+// const MessageLite& ExtensionSet::GetMessage(int number,
+//                                             const Descriptor* message_type,
+//                                             MessageFactory* factory) const
+
+MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
+                                          const MessageLite& prototype,
+                                          const FieldDescriptor* descriptor) {
+  Extension* extension;
+  if (MaybeNewExtension(number, descriptor, &extension)) {
+    extension->type = type;
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
+    extension->is_repeated = false;
+    extension->is_lazy = false;
+    extension->message_value = prototype.New();
+    extension->is_cleared = false;
+    return extension->message_value;
+  } else {
+    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+    extension->is_cleared = false;
+    if (extension->is_lazy) {
+      return extension->lazymessage_value->MutableMessage(prototype);
+    } else {
+      return extension->message_value;
+    }
+  }
+}
+
+// Defined in extension_set_heavy.cc.
+// MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
+//                                           const Descriptor* message_type,
+//                                           MessageFactory* factory)
+
+void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
+                                       const FieldDescriptor* descriptor,
+                                       MessageLite* message) {
+  if (message == NULL) {
+    ClearExtension(number);
+    return;
+  }
+  Extension* extension;
+  if (MaybeNewExtension(number, descriptor, &extension)) {
+    extension->type = type;
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
+    extension->is_repeated = false;
+    extension->is_lazy = false;
+    extension->message_value = message;
+  } else {
+    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+    if (extension->is_lazy) {
+      extension->lazymessage_value->SetAllocatedMessage(message);
+    } else {
+      delete extension->message_value;
+      extension->message_value = message;
+    }
+  }
+  extension->is_cleared = false;
+}
+
+MessageLite* ExtensionSet::ReleaseMessage(int number,
+                                          const MessageLite& prototype) {
+  map<int, Extension>::iterator iter = extensions_.find(number);
+  if (iter == extensions_.end()) {
+    // Not present.  Return NULL.
+    return NULL;
+  } else {
+    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
+    MessageLite* ret = NULL;
+    if (iter->second.is_lazy) {
+      ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
+      delete iter->second.lazymessage_value;
+    } else {
+      ret = iter->second.message_value;
+    }
+    extensions_.erase(number);
+    return ret;
+  }
+}
+
+// Defined in extension_set_heavy.cc.
+// MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
+//                                           MessageFactory* factory);
+
+const MessageLite& 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, REPEATED, MESSAGE);
+  return iter->second.repeated_message_value->Get(index);
+}
+
+MessageLite* 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, REPEATED, MESSAGE);
+  return iter->second.repeated_message_value->Mutable(index);
+}
+
+MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
+                                      const MessageLite& prototype,
+                                      const FieldDescriptor* descriptor) {
+  Extension* extension;
+  if (MaybeNewExtension(number, descriptor, &extension)) {
+    extension->type = type;
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
+    extension->is_repeated = true;
+    extension->repeated_message_value =
+      new RepeatedPtrField<MessageLite>();
+  } else {
+    GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
+  }
+
+  // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
+  // allocate an abstract object, so we have to be tricky.
+  MessageLite* result = extension->repeated_message_value
+      ->AddFromCleared<GenericTypeHandler<MessageLite> >();
+  if (result == NULL) {
+    result = prototype.New();
+    extension->repeated_message_value->AddAllocated(result);
+  }
+  return result;
+}
+
+// Defined in extension_set_heavy.cc.
+// MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
+//                                       const Descriptor* message_type,
+//                                       MessageFactory* factory)
+
+#undef GOOGLE_DCHECK_TYPE
+
+void ExtensionSet::RemoveLast(int number) {
+  map<int, Extension>::iterator iter = extensions_.find(number);
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+
+  Extension* extension = &iter->second;
+  GOOGLE_DCHECK(extension->is_repeated);
+
+  switch(cpp_type(extension->type)) {
+    case WireFormatLite::CPPTYPE_INT32:
+      extension->repeated_int32_value->RemoveLast();
+      break;
+    case WireFormatLite::CPPTYPE_INT64:
+      extension->repeated_int64_value->RemoveLast();
+      break;
+    case WireFormatLite::CPPTYPE_UINT32:
+      extension->repeated_uint32_value->RemoveLast();
+      break;
+    case WireFormatLite::CPPTYPE_UINT64:
+      extension->repeated_uint64_value->RemoveLast();
+      break;
+    case WireFormatLite::CPPTYPE_FLOAT:
+      extension->repeated_float_value->RemoveLast();
+      break;
+    case WireFormatLite::CPPTYPE_DOUBLE:
+      extension->repeated_double_value->RemoveLast();
+      break;
+    case WireFormatLite::CPPTYPE_BOOL:
+      extension->repeated_bool_value->RemoveLast();
+      break;
+    case WireFormatLite::CPPTYPE_ENUM:
+      extension->repeated_enum_value->RemoveLast();
+      break;
+    case WireFormatLite::CPPTYPE_STRING:
+      extension->repeated_string_value->RemoveLast();
+      break;
+    case WireFormatLite::CPPTYPE_MESSAGE:
+      extension->repeated_message_value->RemoveLast();
+      break;
+  }
+}
+
+MessageLite* ExtensionSet::ReleaseLast(int number) {
+  map<int, Extension>::iterator iter = extensions_.find(number);
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+
+  Extension* extension = &iter->second;
+  GOOGLE_DCHECK(extension->is_repeated);
+  GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
+  return extension->repeated_message_value->ReleaseLast();
+}
+
+void ExtensionSet::SwapElements(int number, int index1, int index2) {
+  map<int, Extension>::iterator iter = extensions_.find(number);
+  GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
+
+  Extension* extension = &iter->second;
+  GOOGLE_DCHECK(extension->is_repeated);
+
+  switch(cpp_type(extension->type)) {
+    case WireFormatLite::CPPTYPE_INT32:
+      extension->repeated_int32_value->SwapElements(index1, index2);
+      break;
+    case WireFormatLite::CPPTYPE_INT64:
+      extension->repeated_int64_value->SwapElements(index1, index2);
+      break;
+    case WireFormatLite::CPPTYPE_UINT32:
+      extension->repeated_uint32_value->SwapElements(index1, index2);
+      break;
+    case WireFormatLite::CPPTYPE_UINT64:
+      extension->repeated_uint64_value->SwapElements(index1, index2);
+      break;
+    case WireFormatLite::CPPTYPE_FLOAT:
+      extension->repeated_float_value->SwapElements(index1, index2);
+      break;
+    case WireFormatLite::CPPTYPE_DOUBLE:
+      extension->repeated_double_value->SwapElements(index1, index2);
+      break;
+    case WireFormatLite::CPPTYPE_BOOL:
+      extension->repeated_bool_value->SwapElements(index1, index2);
+      break;
+    case WireFormatLite::CPPTYPE_ENUM:
+      extension->repeated_enum_value->SwapElements(index1, index2);
+      break;
+    case WireFormatLite::CPPTYPE_STRING:
+      extension->repeated_string_value->SwapElements(index1, index2);
+      break;
+    case WireFormatLite::CPPTYPE_MESSAGE:
+      extension->repeated_message_value->SwapElements(index1, index2);
+      break;
+  }
+}
+
+// ===================================================================
+
+void ExtensionSet::Clear() {
+  for (map<int, Extension>::iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    iter->second.Clear();
+  }
+}
+
+void ExtensionSet::MergeFrom(const ExtensionSet& other) {
+  for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
+       iter != other.extensions_.end(); ++iter) {
+    const Extension& other_extension = iter->second;
+
+    if (other_extension.is_repeated) {
+      Extension* extension;
+      bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
+                                      &extension);
+      if (is_new) {
+        // Extension did not already exist in set.
+        extension->type = other_extension.type;
+        extension->is_packed = other_extension.is_packed;
+        extension->is_repeated = true;
+      } else {
+        GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
+        GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
+        GOOGLE_DCHECK(extension->is_repeated);
+      }
+
+      switch (cpp_type(other_extension.type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE)             \
+        case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
+          if (is_new) {                                              \
+            extension->repeated_##LOWERCASE##_value =                \
+              new REPEATED_TYPE;                                     \
+          }                                                          \
+          extension->repeated_##LOWERCASE##_value->MergeFrom(        \
+            *other_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 WireFormatLite::CPPTYPE_MESSAGE:
+          if (is_new) {
+            extension->repeated_message_value =
+              new RepeatedPtrField<MessageLite>();
+          }
+          // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
+          // it would attempt to allocate new objects.
+          RepeatedPtrField<MessageLite>* other_repeated_message =
+              other_extension.repeated_message_value;
+          for (int i = 0; i < other_repeated_message->size(); i++) {
+            const MessageLite& other_message = other_repeated_message->Get(i);
+            MessageLite* target = extension->repeated_message_value
+                     ->AddFromCleared<GenericTypeHandler<MessageLite> >();
+            if (target == NULL) {
+              target = other_message.New();
+              extension->repeated_message_value->AddAllocated(target);
+            }
+            target->CheckTypeAndMergeFrom(other_message);
+          }
+          break;
+      }
+    } else {
+      if (!other_extension.is_cleared) {
+        switch (cpp_type(other_extension.type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE)                         \
+          case WireFormatLite::CPPTYPE_##UPPERCASE:                          \
+            Set##CAMELCASE(iter->first, other_extension.type,                \
+                           other_extension.LOWERCASE##_value,                \
+                           other_extension.descriptor);                      \
+            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 WireFormatLite::CPPTYPE_STRING:
+            SetString(iter->first, other_extension.type,
+                      *other_extension.string_value,
+                      other_extension.descriptor);
+            break;
+          case WireFormatLite::CPPTYPE_MESSAGE: {
+            Extension* extension;
+            bool is_new = MaybeNewExtension(iter->first,
+                                            other_extension.descriptor,
+                                            &extension);
+            if (is_new) {
+              extension->type = other_extension.type;
+              extension->is_packed = other_extension.is_packed;
+              extension->is_repeated = false;
+              if (other_extension.is_lazy) {
+                extension->is_lazy = true;
+                extension->lazymessage_value =
+                    other_extension.lazymessage_value->New();
+                extension->lazymessage_value->MergeFrom(
+                    *other_extension.lazymessage_value);
+              } else {
+                extension->is_lazy = false;
+                extension->message_value =
+                    other_extension.message_value->New();
+                extension->message_value->CheckTypeAndMergeFrom(
+                    *other_extension.message_value);
+              }
+            } else {
+              GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
+              GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
+              GOOGLE_DCHECK(!extension->is_repeated);
+              if (other_extension.is_lazy) {
+                if (extension->is_lazy) {
+                  extension->lazymessage_value->MergeFrom(
+                      *other_extension.lazymessage_value);
+                } else {
+                  extension->message_value->CheckTypeAndMergeFrom(
+                      other_extension.lazymessage_value->GetMessage(
+                          *extension->message_value));
+                }
+              } else {
+                if (extension->is_lazy) {
+                  extension->lazymessage_value->MutableMessage(
+                      *other_extension.message_value)->CheckTypeAndMergeFrom(
+                          *other_extension.message_value);
+                } else {
+                  extension->message_value->CheckTypeAndMergeFrom(
+                      *other_extension.message_value);
+                }
+              }
+            }
+            extension->is_cleared = false;
+            break;
+          }
+        }
+      }
+    }
+  }
+}
+
+void ExtensionSet::Swap(ExtensionSet* x) {
+  extensions_.swap(x->extensions_);
+}
+
+void ExtensionSet::SwapExtension(ExtensionSet* other,
+                                 int number) {
+  if (this == other) return;
+  map<int, Extension>::iterator this_iter = extensions_.find(number);
+  map<int, Extension>::iterator other_iter = other->extensions_.find(number);
+
+  if (this_iter == extensions_.end() &&
+      other_iter == other->extensions_.end()) {
+    return;
+  }
+
+  if (this_iter != extensions_.end() &&
+      other_iter != other->extensions_.end()) {
+    std::swap(this_iter->second, other_iter->second);
+    return;
+  }
+
+  if (this_iter == extensions_.end()) {
+    extensions_.insert(make_pair(number, other_iter->second));
+    other->extensions_.erase(number);
+    return;
+  }
+
+  if (other_iter == other->extensions_.end()) {
+    other->extensions_.insert(make_pair(number, this_iter->second));
+    extensions_.erase(number);
+    return;
+  }
+}
+
+bool ExtensionSet::IsInitialized() const {
+  // Extensions are never required.  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 (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
+      if (extension.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.is_lazy) {
+            if (!extension.lazymessage_value->IsInitialized()) return false;
+          } else {
+            if (!extension.message_value->IsInitialized()) return false;
+          }
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+bool ExtensionSet::FindExtensionInfoFromTag(
+    uint32 tag, ExtensionFinder* extension_finder, int* field_number,
+    ExtensionInfo* extension, bool* was_packed_on_wire) {
+  *field_number = WireFormatLite::GetTagFieldNumber(tag);
+  WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
+  return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
+                                          extension_finder, extension,
+                                          was_packed_on_wire);
+}
+
+bool ExtensionSet::FindExtensionInfoFromFieldNumber(
+    int wire_type, int field_number, ExtensionFinder* extension_finder,
+    ExtensionInfo* extension, bool* was_packed_on_wire) {
+  if (!extension_finder->Find(field_number, extension)) {
+    return false;
+  }
+
+  WireFormatLite::WireType expected_wire_type =
+      WireFormatLite::WireTypeForFieldType(real_type(extension->type));
+
+  // Check if this is a packed field.
+  *was_packed_on_wire = false;
+  if (extension->is_repeated &&
+      wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
+      is_packable(expected_wire_type)) {
+    *was_packed_on_wire = true;
+    return true;
+  }
+  // Otherwise the wire type must match.
+  return expected_wire_type == wire_type;
+}
+
+bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+                              ExtensionFinder* extension_finder,
+                              FieldSkipper* field_skipper) {
+  int number;
+  bool was_packed_on_wire;
+  ExtensionInfo extension;
+  if (!FindExtensionInfoFromTag(
+      tag, extension_finder, &number, &extension, &was_packed_on_wire)) {
+    return field_skipper->SkipField(input, tag);
+  } else {
+    return ParseFieldWithExtensionInfo(
+        number, was_packed_on_wire, extension, input, field_skipper);
+  }
+}
+
+bool ExtensionSet::ParseFieldWithExtensionInfo(
+    int number, bool was_packed_on_wire, const ExtensionInfo& extension,
+    io::CodedInputStream* input,
+    FieldSkipper* field_skipper) {
+  // Explicitly not read extension.is_packed, instead check whether the field
+  // was encoded in packed form on the wire.
+  if (was_packed_on_wire) {
+    uint32 size;
+    if (!input->ReadVarint32(&size)) return false;
+    io::CodedInputStream::Limit limit = input->PushLimit(size);
+
+    switch (extension.type) {
+#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)        \
+      case WireFormatLite::TYPE_##UPPERCASE:                                   \
+        while (input->BytesUntilLimit() > 0) {                                 \
+          CPP_LOWERCASE value;                                                 \
+          if (!WireFormatLite::ReadPrimitive<                                  \
+                  CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(            \
+                input, &value)) return false;                                  \
+          Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
+                             extension.is_packed, value,                       \
+                             extension.descriptor);                            \
+        }                                                                      \
+        break
+
+      HANDLE_TYPE(   INT32,  Int32,   int32);
+      HANDLE_TYPE(   INT64,  Int64,   int64);
+      HANDLE_TYPE(  UINT32, UInt32,  uint32);
+      HANDLE_TYPE(  UINT64, UInt64,  uint64);
+      HANDLE_TYPE(  SINT32,  Int32,   int32);
+      HANDLE_TYPE(  SINT64,  Int64,   int64);
+      HANDLE_TYPE( FIXED32, UInt32,  uint32);
+      HANDLE_TYPE( FIXED64, UInt64,  uint64);
+      HANDLE_TYPE(SFIXED32,  Int32,   int32);
+      HANDLE_TYPE(SFIXED64,  Int64,   int64);
+      HANDLE_TYPE(   FLOAT,  Float,   float);
+      HANDLE_TYPE(  DOUBLE, Double,  double);
+      HANDLE_TYPE(    BOOL,   Bool,    bool);
+#undef HANDLE_TYPE
+
+      case WireFormatLite::TYPE_ENUM:
+        while (input->BytesUntilLimit() > 0) {
+          int value;
+          if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+                  input, &value)) return false;
+          if (extension.enum_validity_check.func(
+                  extension.enum_validity_check.arg, value)) {
+            AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
+                    value, extension.descriptor);
+          }
+        }
+        break;
+
+      case WireFormatLite::TYPE_STRING:
+      case WireFormatLite::TYPE_BYTES:
+      case WireFormatLite::TYPE_GROUP:
+      case WireFormatLite::TYPE_MESSAGE:
+        GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+        break;
+    }
+
+    input->PopLimit(limit);
+  } else {
+    switch (extension.type) {
+#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE)                   \
+      case WireFormatLite::TYPE_##UPPERCASE: {                                 \
+        CPP_LOWERCASE value;                                                   \
+        if (!WireFormatLite::ReadPrimitive<                                    \
+                CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>(              \
+               input, &value)) return false;                                   \
+        if (extension.is_repeated) {                                           \
+          Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,         \
+                             extension.is_packed, value,                       \
+                             extension.descriptor);                            \
+        } else {                                                               \
+          Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,  \
+                             extension.descriptor);                            \
+        }                                                                      \
+      } break
+
+      HANDLE_TYPE(   INT32,  Int32,   int32);
+      HANDLE_TYPE(   INT64,  Int64,   int64);
+      HANDLE_TYPE(  UINT32, UInt32,  uint32);
+      HANDLE_TYPE(  UINT64, UInt64,  uint64);
+      HANDLE_TYPE(  SINT32,  Int32,   int32);
+      HANDLE_TYPE(  SINT64,  Int64,   int64);
+      HANDLE_TYPE( FIXED32, UInt32,  uint32);
+      HANDLE_TYPE( FIXED64, UInt64,  uint64);
+      HANDLE_TYPE(SFIXED32,  Int32,   int32);
+      HANDLE_TYPE(SFIXED64,  Int64,   int64);
+      HANDLE_TYPE(   FLOAT,  Float,   float);
+      HANDLE_TYPE(  DOUBLE, Double,  double);
+      HANDLE_TYPE(    BOOL,   Bool,    bool);
+#undef HANDLE_TYPE
+
+      case WireFormatLite::TYPE_ENUM: {
+        int value;
+        if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+                input, &value)) return false;
+
+        if (!extension.enum_validity_check.func(
+                extension.enum_validity_check.arg, value)) {
+          // Invalid value.  Treat as unknown.
+          field_skipper->SkipUnknownEnum(number, value);
+        } else if (extension.is_repeated) {
+          AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
+                  extension.descriptor);
+        } else {
+          SetEnum(number, WireFormatLite::TYPE_ENUM, value,
+                  extension.descriptor);
+        }
+        break;
+      }
+
+      case WireFormatLite::TYPE_STRING:  {
+        string* value = extension.is_repeated ?
+          AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
+          MutableString(number, WireFormatLite::TYPE_STRING,
+                        extension.descriptor);
+        if (!WireFormatLite::ReadString(input, value)) return false;
+        break;
+      }
+
+      case WireFormatLite::TYPE_BYTES:  {
+        string* value = extension.is_repeated ?
+          AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
+          MutableString(number, WireFormatLite::TYPE_BYTES,
+                        extension.descriptor);
+        if (!WireFormatLite::ReadBytes(input, value)) return false;
+        break;
+      }
+
+      case WireFormatLite::TYPE_GROUP: {
+        MessageLite* value = extension.is_repeated ?
+            AddMessage(number, WireFormatLite::TYPE_GROUP,
+                       *extension.message_prototype, extension.descriptor) :
+            MutableMessage(number, WireFormatLite::TYPE_GROUP,
+                           *extension.message_prototype, extension.descriptor);
+        if (!WireFormatLite::ReadGroup(number, input, value)) return false;
+        break;
+      }
+
+      case WireFormatLite::TYPE_MESSAGE: {
+        MessageLite* value = extension.is_repeated ?
+            AddMessage(number, WireFormatLite::TYPE_MESSAGE,
+                       *extension.message_prototype, extension.descriptor) :
+            MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
+                           *extension.message_prototype, extension.descriptor);
+        if (!WireFormatLite::ReadMessage(input, value)) return false;
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+                              const MessageLite* containing_type) {
+  FieldSkipper skipper;
+  GeneratedExtensionFinder finder(containing_type);
+  return ParseField(tag, input, &finder, &skipper);
+}
+
+bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+                              const MessageLite* containing_type,
+                              io::CodedOutputStream* unknown_fields) {
+  CodedOutputStreamFieldSkipper skipper(unknown_fields);
+  GeneratedExtensionFinder finder(containing_type);
+  return ParseField(tag, input, &finder, &skipper);
+}
+
+// Defined in extension_set_heavy.cc.
+// bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+//                               const MessageLite* containing_type,
+//                               UnknownFieldSet* unknown_fields)
+
+// Defined in extension_set_heavy.cc.
+// bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+//                                    const MessageLite* containing_type,
+//                                    UnknownFieldSet* unknown_fields);
+
+void ExtensionSet::SerializeWithCachedSizes(
+    int start_field_number, int end_field_number,
+    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) {
+    iter->second.SerializeFieldWithCachedSizes(iter->first, output);
+  }
+}
+
+int ExtensionSet::ByteSize() const {
+  int total_size = 0;
+
+  for (map<int, Extension>::const_iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    total_size += iter->second.ByteSize(iter->first);
+  }
+
+  return total_size;
+}
+
+// Defined in extension_set_heavy.cc.
+// int ExtensionSet::SpaceUsedExcludingSelf() const
+
+bool ExtensionSet::MaybeNewExtension(int number,
+                                     const FieldDescriptor* descriptor,
+                                     Extension** result) {
+  pair<map<int, Extension>::iterator, bool> insert_result =
+      extensions_.insert(make_pair(number, Extension()));
+  *result = &insert_result.first->second;
+  (*result)->descriptor = descriptor;
+  return insert_result.second;
+}
+
+// ===================================================================
+// Methods of ExtensionSet::Extension
+
+void ExtensionSet::Extension::Clear() {
+  if (is_repeated) {
+    switch (cpp_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
+      case WireFormatLite::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 (cpp_type(type)) {
+        case WireFormatLite::CPPTYPE_STRING:
+          string_value->clear();
+          break;
+        case WireFormatLite::CPPTYPE_MESSAGE:
+          if (is_lazy) {
+            lazymessage_value->Clear();
+          } else {
+            message_value->Clear();
+          }
+          break;
+        default:
+          // No need to do anything.  Get*() will return the default value
+          // as long as is_cleared is true and Set*() will overwrite the
+          // previous value.
+          break;
+      }
+
+      is_cleared = true;
+    }
+  }
+}
+
+void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
+    int number,
+    io::CodedOutputStream* output) const {
+  if (is_repeated) {
+    if (is_packed) {
+      if (cached_size == 0) return;
+
+      WireFormatLite::WriteTag(number,
+          WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+      output->WriteVarint32(cached_size);
+
+      switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
+        case WireFormatLite::TYPE_##UPPERCASE:                              \
+          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
+            WireFormatLite::Write##CAMELCASE##NoTag(                        \
+              repeated_##LOWERCASE##_value->Get(i), output);                \
+          }                                                                 \
+          break
+
+        HANDLE_TYPE(   INT32,    Int32,   int32);
+        HANDLE_TYPE(   INT64,    Int64,   int64);
+        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
+        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
+        HANDLE_TYPE(  SINT32,   SInt32,   int32);
+        HANDLE_TYPE(  SINT64,   SInt64,   int64);
+        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(    ENUM,     Enum,    enum);
+#undef HANDLE_TYPE
+
+        case WireFormatLite::TYPE_STRING:
+        case WireFormatLite::TYPE_BYTES:
+        case WireFormatLite::TYPE_GROUP:
+        case WireFormatLite::TYPE_MESSAGE:
+          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+          break;
+      }
+    } else {
+      switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
+        case WireFormatLite::TYPE_##UPPERCASE:                              \
+          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
+            WireFormatLite::Write##CAMELCASE(number,                        \
+              repeated_##LOWERCASE##_value->Get(i), output);                \
+          }                                                                 \
+          break
+
+        HANDLE_TYPE(   INT32,    Int32,   int32);
+        HANDLE_TYPE(   INT64,    Int64,   int64);
+        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
+        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
+        HANDLE_TYPE(  SINT32,   SInt32,   int32);
+        HANDLE_TYPE(  SINT64,   SInt64,   int64);
+        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(  STRING,   String,  string);
+        HANDLE_TYPE(   BYTES,    Bytes,  string);
+        HANDLE_TYPE(    ENUM,     Enum,    enum);
+        HANDLE_TYPE(   GROUP,    Group, message);
+        HANDLE_TYPE( MESSAGE,  Message, message);
+#undef HANDLE_TYPE
+      }
+    }
+  } else if (!is_cleared) {
+    switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
+      case WireFormatLite::TYPE_##UPPERCASE:                     \
+        WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
+        break
+
+      HANDLE_TYPE(   INT32,    Int32,    int32_value);
+      HANDLE_TYPE(   INT64,    Int64,    int64_value);
+      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
+      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
+      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
+      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
+      HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
+      HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
+      HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
+      HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
+      HANDLE_TYPE(   FLOAT,    Float,    float_value);
+      HANDLE_TYPE(  DOUBLE,   Double,   double_value);
+      HANDLE_TYPE(    BOOL,     Bool,     bool_value);
+      HANDLE_TYPE(  STRING,   String,  *string_value);
+      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
+      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
+      HANDLE_TYPE(   GROUP,    Group, *message_value);
+#undef HANDLE_TYPE
+      case WireFormatLite::TYPE_MESSAGE:
+        if (is_lazy) {
+          lazymessage_value->WriteMessage(number, output);
+        } else {
+          WireFormatLite::WriteMessage(number, *message_value, output);
+        }
+        break;
+    }
+  }
+}
+
+int ExtensionSet::Extension::ByteSize(int number) const {
+  int result = 0;
+
+  if (is_repeated) {
+    if (is_packed) {
+      switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
+        case WireFormatLite::TYPE_##UPPERCASE:                              \
+          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
+            result += WireFormatLite::CAMELCASE##Size(                      \
+              repeated_##LOWERCASE##_value->Get(i));                        \
+          }                                                                 \
+          break
+
+        HANDLE_TYPE(   INT32,    Int32,   int32);
+        HANDLE_TYPE(   INT64,    Int64,   int64);
+        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
+        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
+        HANDLE_TYPE(  SINT32,   SInt32,   int32);
+        HANDLE_TYPE(  SINT64,   SInt64,   int64);
+        HANDLE_TYPE(    ENUM,     Enum,    enum);
+#undef HANDLE_TYPE
+
+        // Stuff with fixed size.
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
+        case WireFormatLite::TYPE_##UPPERCASE:                              \
+          result += WireFormatLite::k##CAMELCASE##Size *                    \
+                    repeated_##LOWERCASE##_value->size();                   \
+          break
+        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);
+#undef HANDLE_TYPE
+
+        case WireFormatLite::TYPE_STRING:
+        case WireFormatLite::TYPE_BYTES:
+        case WireFormatLite::TYPE_GROUP:
+        case WireFormatLite::TYPE_MESSAGE:
+          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+          break;
+      }
+
+      cached_size = result;
+      if (result > 0) {
+        result += io::CodedOutputStream::VarintSize32(result);
+        result += io::CodedOutputStream::VarintSize32(
+            WireFormatLite::MakeTag(number,
+                WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
+      }
+    } else {
+      int tag_size = WireFormatLite::TagSize(number, real_type(type));
+
+      switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
+        case WireFormatLite::TYPE_##UPPERCASE:                              \
+          result += tag_size * repeated_##LOWERCASE##_value->size();        \
+          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
+            result += WireFormatLite::CAMELCASE##Size(                      \
+              repeated_##LOWERCASE##_value->Get(i));                        \
+          }                                                                 \
+          break
+
+        HANDLE_TYPE(   INT32,    Int32,   int32);
+        HANDLE_TYPE(   INT64,    Int64,   int64);
+        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
+        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
+        HANDLE_TYPE(  SINT32,   SInt32,   int32);
+        HANDLE_TYPE(  SINT64,   SInt64,   int64);
+        HANDLE_TYPE(  STRING,   String,  string);
+        HANDLE_TYPE(   BYTES,    Bytes,  string);
+        HANDLE_TYPE(    ENUM,     Enum,    enum);
+        HANDLE_TYPE(   GROUP,    Group, message);
+        HANDLE_TYPE( MESSAGE,  Message, message);
+#undef HANDLE_TYPE
+
+        // Stuff with fixed size.
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
+        case WireFormatLite::TYPE_##UPPERCASE:                              \
+          result += (tag_size + WireFormatLite::k##CAMELCASE##Size) *       \
+                    repeated_##LOWERCASE##_value->size();                   \
+          break
+        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);
+#undef HANDLE_TYPE
+      }
+    }
+  } else if (!is_cleared) {
+    result += WireFormatLite::TagSize(number, real_type(type));
+    switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                      \
+      case WireFormatLite::TYPE_##UPPERCASE:                              \
+        result += WireFormatLite::CAMELCASE##Size(LOWERCASE);             \
+        break
+
+      HANDLE_TYPE(   INT32,    Int32,    int32_value);
+      HANDLE_TYPE(   INT64,    Int64,    int64_value);
+      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
+      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
+      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
+      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
+      HANDLE_TYPE(  STRING,   String,  *string_value);
+      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
+      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
+      HANDLE_TYPE(   GROUP,    Group, *message_value);
+#undef HANDLE_TYPE
+      case WireFormatLite::TYPE_MESSAGE: {
+        if (is_lazy) {
+          int size = lazymessage_value->ByteSize();
+          result += io::CodedOutputStream::VarintSize32(size) + size;
+        } else {
+          result += WireFormatLite::MessageSize(*message_value);
+        }
+        break;
+      }
+
+      // Stuff with fixed size.
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE)                                 \
+      case WireFormatLite::TYPE_##UPPERCASE:                              \
+        result += WireFormatLite::k##CAMELCASE##Size;                     \
+        break
+      HANDLE_TYPE( FIXED32,  Fixed32);
+      HANDLE_TYPE( FIXED64,  Fixed64);
+      HANDLE_TYPE(SFIXED32, SFixed32);
+      HANDLE_TYPE(SFIXED64, SFixed64);
+      HANDLE_TYPE(   FLOAT,    Float);
+      HANDLE_TYPE(  DOUBLE,   Double);
+      HANDLE_TYPE(    BOOL,     Bool);
+#undef HANDLE_TYPE
+    }
+  }
+
+  return result;
+}
+
+int ExtensionSet::Extension::GetSize() const {
+  GOOGLE_DCHECK(is_repeated);
+  switch (cpp_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                        \
+    case WireFormatLite::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 (is_repeated) {
+    switch (cpp_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
+      case WireFormatLite::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 (cpp_type(type)) {
+      case WireFormatLite::CPPTYPE_STRING:
+        delete string_value;
+        break;
+      case WireFormatLite::CPPTYPE_MESSAGE:
+        if (is_lazy) {
+          delete lazymessage_value;
+        } else {
+          delete message_value;
+        }
+        break;
+      default:
+        break;
+    }
+  }
+}
+
+// Defined in extension_set_heavy.cc.
+// int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
+
+// ==================================================================
+// Default repeated field instances for iterator-compatible accessors
+
+const RepeatedStringTypeTraits::RepeatedFieldType*
+RepeatedStringTypeTraits::default_repeated_field_ = NULL;
+
+const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
+RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
+
+#define PROTOBUF_DEFINE_DEFAULT_REPEATED(TYPE)                                 \
+    const RepeatedField<TYPE>*                                                 \
+    RepeatedPrimitiveGenericTypeTraits::default_repeated_field_##TYPE##_ = NULL;
+
+PROTOBUF_DEFINE_DEFAULT_REPEATED(int32)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(int64)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(uint32)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(uint64)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(double)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(float)
+PROTOBUF_DEFINE_DEFAULT_REPEATED(bool)
+
+#undef PROTOBUF_DEFINE_DEFAULT_REPEATED
+
+struct StaticDefaultRepeatedFieldsInitializer {
+  StaticDefaultRepeatedFieldsInitializer() {
+    InitializeDefaultRepeatedFields();
+    OnShutdown(&DestroyDefaultRepeatedFields);
+  }
+} static_repeated_fields_initializer;
+
+void InitializeDefaultRepeatedFields() {
+  RepeatedStringTypeTraits::default_repeated_field_ =
+      new RepeatedStringTypeTraits::RepeatedFieldType;
+  RepeatedMessageGenericTypeTraits::default_repeated_field_ =
+      new RepeatedMessageGenericTypeTraits::RepeatedFieldType;
+  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ =
+      new RepeatedField<int32>;
+  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ =
+      new RepeatedField<int64>;
+  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ =
+      new RepeatedField<uint32>;
+  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ =
+      new RepeatedField<uint64>;
+  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ =
+      new RepeatedField<double>;
+  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ =
+      new RepeatedField<float>;
+  RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ =
+      new RepeatedField<bool>;
+}
+
+void DestroyDefaultRepeatedFields() {
+  delete RepeatedStringTypeTraits::default_repeated_field_;
+  delete RepeatedMessageGenericTypeTraits::default_repeated_field_;
+  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_;
+  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_;
+  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_;
+  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_;
+  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_;
+  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_;
+  delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/extension_set.h b/protobuf/src/google/protobuf/extension_set.h
new file mode 100644
index 0000000..d6fc45d
--- /dev/null
+++ b/protobuf/src/google/protobuf/extension_set.h
@@ -0,0 +1,1234 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <map>
+#include <utility>
+#include <string>
+
+
+#include <google/protobuf/stubs/common.h>
+
+#include <google/protobuf/repeated_field.h>
+
+namespace google {
+
+namespace protobuf {
+  class Descriptor;                                    // descriptor.h
+  class FieldDescriptor;                               // descriptor.h
+  class DescriptorPool;                                // descriptor.h
+  class MessageLite;                                   // message_lite.h
+  class Message;                                       // message.h
+  class MessageFactory;                                // message.h
+  class UnknownFieldSet;                               // unknown_field_set.h
+  namespace io {
+    class CodedInputStream;                              // coded_stream.h
+    class CodedOutputStream;                             // coded_stream.h
+  }
+  namespace internal {
+    class FieldSkipper;                                  // wire_format_lite.h
+  }
+}
+
+namespace protobuf {
+namespace internal {
+
+// Used to store values of type WireFormatLite::FieldType without having to
+// #include wire_format_lite.h.  Also, ensures that we use only one byte to
+// store these values, which is important to keep the layout of
+// ExtensionSet::Extension small.
+typedef uint8 FieldType;
+
+// A function which, given an integer value, returns true if the number
+// matches one of the defined values for the corresponding enum type.  This
+// is used with RegisterEnumExtension, below.
+typedef bool EnumValidityFunc(int number);
+
+// Version of the above which takes an argument.  This is needed to deal with
+// extensions that are not compiled in.
+typedef bool EnumValidityFuncWithArg(const void* arg, int number);
+
+// Information about a registered extension.
+struct ExtensionInfo {
+  inline ExtensionInfo() {}
+  inline ExtensionInfo(FieldType type_param, bool isrepeated, bool ispacked)
+      : type(type_param), is_repeated(isrepeated), is_packed(ispacked),
+        descriptor(NULL) {}
+
+  FieldType type;
+  bool is_repeated;
+  bool is_packed;
+
+  struct EnumValidityCheck {
+    EnumValidityFuncWithArg* func;
+    const void* arg;
+  };
+
+  union {
+    EnumValidityCheck enum_validity_check;
+    const MessageLite* message_prototype;
+  };
+
+  // The descriptor for this extension, if one exists and is known.  May be
+  // NULL.  Must not be NULL if the descriptor for the extension does not
+  // live in the same pool as the descriptor for the containing type.
+  const FieldDescriptor* descriptor;
+};
+
+// Abstract interface for an object which looks up extension definitions.  Used
+// when parsing.
+class LIBPROTOBUF_EXPORT ExtensionFinder {
+ public:
+  virtual ~ExtensionFinder();
+
+  // Find the extension with the given containing type and number.
+  virtual bool Find(int number, ExtensionInfo* output) = 0;
+};
+
+// Implementation of ExtensionFinder which finds extensions defined in .proto
+// files which have been compiled into the binary.
+class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder {
+ public:
+  GeneratedExtensionFinder(const MessageLite* containing_type)
+      : containing_type_(containing_type) {}
+  virtual ~GeneratedExtensionFinder() {}
+
+  // Returns true and fills in *output if found, otherwise returns false.
+  virtual bool Find(int number, ExtensionInfo* output);
+
+ private:
+  const MessageLite* containing_type_;
+};
+
+// A FieldSkipper used for parsing MessageSet.
+class MessageSetFieldSkipper;
+
+// Note:  extension_set_heavy.cc defines DescriptorPoolExtensionFinder for
+// finding extensions from a DescriptorPool.
+
+// 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:
+  ExtensionSet();
+  ~ExtensionSet();
+
+  // These are called at startup by protocol-compiler-generated code to
+  // register known extensions.  The registrations are used by ParseField()
+  // to look up extensions for parsed field numbers.  Note that dynamic parsing
+  // does not use ParseField(); only protocol-compiler-generated parsing
+  // methods do.
+  static void RegisterExtension(const MessageLite* containing_type,
+                                int number, FieldType type,
+                                bool is_repeated, bool is_packed);
+  static void RegisterEnumExtension(const MessageLite* containing_type,
+                                    int number, FieldType type,
+                                    bool is_repeated, bool is_packed,
+                                    EnumValidityFunc* is_valid);
+  static void RegisterMessageExtension(const MessageLite* containing_type,
+                                       int number, FieldType type,
+                                       bool is_repeated, bool is_packed,
+                                       const MessageLite* prototype);
+
+  // =================================================================
+
+  // Add all fields which are currently present to the given vector.  This
+  // is useful to implement Reflection::ListFields().
+  void AppendToList(const Descriptor* containing_type,
+                    const DescriptorPool* pool,
+                    std::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 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.
+  int NumExtensions() const;  // The number of extensions
+  FieldType ExtensionType(int number) const;
+  void ClearExtension(int number);
+
+  // singular fields -------------------------------------------------
+
+  int32  GetInt32 (int number, int32  default_value) const;
+  int64  GetInt64 (int number, int64  default_value) const;
+  uint32 GetUInt32(int number, uint32 default_value) const;
+  uint64 GetUInt64(int number, uint64 default_value) const;
+  float  GetFloat (int number, float  default_value) const;
+  double GetDouble(int number, double default_value) const;
+  bool   GetBool  (int number, bool   default_value) const;
+  int    GetEnum  (int number, int    default_value) const;
+  const string & GetString (int number, const string&  default_value) const;
+  const MessageLite& GetMessage(int number,
+                                const MessageLite& default_value) const;
+  const MessageLite& GetMessage(int number, const Descriptor* message_type,
+                                MessageFactory* factory) const;
+
+  // |descriptor| may be NULL so long as it is known that the descriptor for
+  // the extension lives in the same pool as the descriptor for the containing
+  // type.
+#define desc const FieldDescriptor* descriptor  // avoid line wrapping
+  void SetInt32 (int number, FieldType type, int32  value, desc);
+  void SetInt64 (int number, FieldType type, int64  value, desc);
+  void SetUInt32(int number, FieldType type, uint32 value, desc);
+  void SetUInt64(int number, FieldType type, uint64 value, desc);
+  void SetFloat (int number, FieldType type, float  value, desc);
+  void SetDouble(int number, FieldType type, double value, desc);
+  void SetBool  (int number, FieldType type, bool   value, desc);
+  void SetEnum  (int number, FieldType type, int    value, desc);
+  void SetString(int number, FieldType type, const string& value, desc);
+  string * MutableString (int number, FieldType type, desc);
+  MessageLite* MutableMessage(int number, FieldType type,
+                              const MessageLite& prototype, desc);
+  MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
+                              MessageFactory* factory);
+  // Adds the given message to the ExtensionSet, taking ownership of the
+  // message object. Existing message with the same number will be deleted.
+  // If "message" is NULL, this is equivalent to "ClearExtension(number)".
+  void SetAllocatedMessage(int number, FieldType type,
+                           const FieldDescriptor* descriptor,
+                           MessageLite* message);
+  MessageLite* ReleaseMessage(int number, const MessageLite& prototype);
+  MessageLite* ReleaseMessage(const FieldDescriptor* descriptor,
+                              MessageFactory* factory);
+#undef desc
+
+  // repeated fields -------------------------------------------------
+
+  // Fetches a RepeatedField extension by number; returns |default_value|
+  // if no such extension exists. User should not touch this directly; it is
+  // used by the GetRepeatedExtension() method.
+  const void* GetRawRepeatedField(int number, const void* default_value) const;
+  // Fetches a mutable version of a RepeatedField extension by number,
+  // instantiating one if none exists. Similar to above, user should not use
+  // this directly; it underlies MutableRepeatedExtension().
+  void* MutableRawRepeatedField(int number, FieldType field_type,
+                                bool packed, const FieldDescriptor* desc);
+
+  // This is an overload of MutableRawRepeatedField to maintain compatibility
+  // with old code using a previous API. This version of
+  // MutableRawRepeatedField() will GOOGLE_CHECK-fail on a missing extension.
+  // (E.g.: borg/clients/internal/proto1/proto2_reflection.cc.)
+  void* MutableRawRepeatedField(int number);
+
+  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 MessageLite& 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);
+  MessageLite* MutableRepeatedMessage(int number, int index);
+
+#define desc const FieldDescriptor* descriptor  // avoid line wrapping
+  void AddInt32 (int number, FieldType type, bool packed, int32  value, desc);
+  void AddInt64 (int number, FieldType type, bool packed, int64  value, desc);
+  void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc);
+  void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc);
+  void AddFloat (int number, FieldType type, bool packed, float  value, desc);
+  void AddDouble(int number, FieldType type, bool packed, double value, desc);
+  void AddBool  (int number, FieldType type, bool packed, bool   value, desc);
+  void AddEnum  (int number, FieldType type, bool packed, int    value, desc);
+  void AddString(int number, FieldType type, const string& value, desc);
+  string * AddString (int number, FieldType type, desc);
+  MessageLite* AddMessage(int number, FieldType type,
+                          const MessageLite& prototype, desc);
+  MessageLite* AddMessage(const FieldDescriptor* descriptor,
+                          MessageFactory* factory);
+#undef desc
+
+  void RemoveLast(int number);
+  MessageLite* ReleaseLast(int number);
+  void SwapElements(int number, int index1, int index2);
+
+  // -----------------------------------------------------------------
+  // 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);
+  void Swap(ExtensionSet* other);
+  void SwapExtension(ExtensionSet* other, int number);
+  bool IsInitialized() const;
+
+  // Parses a single extension from the input. The input should start out
+  // positioned immediately after the tag.
+  bool ParseField(uint32 tag, io::CodedInputStream* input,
+                  ExtensionFinder* extension_finder,
+                  FieldSkipper* field_skipper);
+
+  // Specific versions for lite or full messages (constructs the appropriate
+  // FieldSkipper automatically).  |containing_type| is the default
+  // instance for the containing message; it is used only to look up the
+  // extension by number.  See RegisterExtension(), above.  Unlike the other
+  // methods of ExtensionSet, this only works for generated message types --
+  // it looks up extensions registered using RegisterExtension().
+  bool ParseField(uint32 tag, io::CodedInputStream* input,
+                  const MessageLite* containing_type);
+  bool ParseField(uint32 tag, io::CodedInputStream* input,
+                  const Message* containing_type,
+                  UnknownFieldSet* unknown_fields);
+  bool ParseField(uint32 tag, io::CodedInputStream* input,
+                  const MessageLite* containing_type,
+                  io::CodedOutputStream* unknown_fields);
+
+  // Parse an entire message in MessageSet format.  Such messages have no
+  // fields, only extensions.
+  bool ParseMessageSet(io::CodedInputStream* input,
+                       ExtensionFinder* extension_finder,
+                       MessageSetFieldSkipper* field_skipper);
+
+  // Specific versions for lite or full messages (constructs the appropriate
+  // FieldSkipper automatically).
+  bool ParseMessageSet(io::CodedInputStream* input,
+                       const MessageLite* containing_type);
+  bool ParseMessageSet(io::CodedInputStream* input,
+                       const Message* containing_type,
+                       UnknownFieldSet* unknown_fields);
+
+  // 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.
+  void SerializeWithCachedSizes(int start_field_number,
+                                int end_field_number,
+                                io::CodedOutputStream* output) const;
+
+  // Same as SerializeWithCachedSizes, but without any bounds checking.
+  // The caller must ensure that target has sufficient capacity for the
+  // serialized extensions.
+  //
+  // Returns a pointer past the last written byte.
+  uint8* SerializeWithCachedSizesToArray(int start_field_number,
+                                         int end_field_number,
+                                         uint8* target) const;
+
+  // Like above but serializes in MessageSet format.
+  void SerializeMessageSetWithCachedSizes(io::CodedOutputStream* output) const;
+  uint8* SerializeMessageSetWithCachedSizesToArray(uint8* target) const;
+
+  // Returns the total serialized size of all the extensions.
+  int ByteSize() const;
+
+  // Like ByteSize() but uses MessageSet format.
+  int MessageSetByteSize() const;
+
+  // Returns (an estimate of) the total number of bytes used for storing the
+  // extensions in memory, excluding sizeof(*this).  If the ExtensionSet is
+  // for a lite message (and thus possibly contains lite messages), the results
+  // are undefined (might work, might crash, might corrupt data, might not even
+  // be linked in).  It's up to the protocol compiler to avoid calling this on
+  // such ExtensionSets (easy enough since lite messages don't implement
+  // SpaceUsed()).
+  int SpaceUsedExcludingSelf() const;
+
+ private:
+
+  // Interface of a lazily parsed singular message extension.
+  class LIBPROTOBUF_EXPORT LazyMessageExtension {
+   public:
+    LazyMessageExtension() {}
+    virtual ~LazyMessageExtension() {}
+
+    virtual LazyMessageExtension* New() const = 0;
+    virtual const MessageLite& GetMessage(
+        const MessageLite& prototype) const = 0;
+    virtual MessageLite* MutableMessage(const MessageLite& prototype) = 0;
+    virtual void SetAllocatedMessage(MessageLite *message) = 0;
+    virtual MessageLite* ReleaseMessage(const MessageLite& prototype) = 0;
+
+    virtual bool IsInitialized() const = 0;
+    virtual int ByteSize() const = 0;
+    virtual int SpaceUsed() const = 0;
+
+    virtual void MergeFrom(const LazyMessageExtension& other) = 0;
+    virtual void Clear() = 0;
+
+    virtual bool ReadMessage(const MessageLite& prototype,
+                             io::CodedInputStream* input) = 0;
+    virtual void WriteMessage(int number,
+                              io::CodedOutputStream* output) const = 0;
+    virtual uint8* WriteMessageToArray(int number, uint8* target) const = 0;
+   private:
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LazyMessageExtension);
+  };
+  struct Extension {
+    // The order of these fields packs Extension into 24 bytes when using 8
+    // byte alignment. Consider this when adding or removing fields here.
+    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;
+      MessageLite*          message_value;
+      LazyMessageExtension* lazymessage_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<MessageLite>* repeated_message_value;
+    };
+
+    FieldType type;
+    bool is_repeated;
+
+    // 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 : 4;
+
+    // For singular message types, indicates whether lazy parsing is enabled
+    // for this extension. This field is only valid when type == TYPE_MESSAGE
+    // and !is_repeated because we only support lazy parsing for singular
+    // message types currently. If is_lazy = true, the extension is stored in
+    // lazymessage_value. Otherwise, the extension will be message_value.
+    bool is_lazy : 4;
+
+    // For repeated types, this indicates if the [packed=true] option is set.
+    bool is_packed;
+
+    // For packed fields, the size of the packed data is recorded here when
+    // ByteSize() is called then used during serialization.
+    // TODO(kenton):  Use atomic<int> when C++ supports it.
+    mutable int cached_size;
+
+    // The descriptor for this extension, if one exists and is known.  May be
+    // NULL.  Must not be NULL if the descriptor for the extension does not
+    // live in the same pool as the descriptor for the containing type.
+    const FieldDescriptor* descriptor;
+
+    // Some helper methods for operations on a single Extension.
+    void SerializeFieldWithCachedSizes(
+        int number,
+        io::CodedOutputStream* output) const;
+    uint8* SerializeFieldWithCachedSizesToArray(
+        int number,
+        uint8* target) const;
+    void SerializeMessageSetItemWithCachedSizes(
+        int number,
+        io::CodedOutputStream* output) const;
+    uint8* SerializeMessageSetItemWithCachedSizesToArray(
+        int number,
+        uint8* target) const;
+    int ByteSize(int number) const;
+    int MessageSetItemByteSize(int number) const;
+    void Clear();
+    int GetSize() const;
+    void Free();
+    int SpaceUsedExcludingSelf() const;
+  };
+
+
+  // Returns true and fills field_number and extension if extension is found.
+  // Note to support packed repeated field compatibility, it also fills whether
+  // the tag on wire is packed, which can be different from
+  // extension->is_packed (whether packed=true is specified).
+  bool FindExtensionInfoFromTag(uint32 tag, ExtensionFinder* extension_finder,
+                                int* field_number, ExtensionInfo* extension,
+                                bool* was_packed_on_wire);
+
+  // Returns true and fills extension if extension is found.
+  // Note to support packed repeated field compatibility, it also fills whether
+  // the tag on wire is packed, which can be different from
+  // extension->is_packed (whether packed=true is specified).
+  bool FindExtensionInfoFromFieldNumber(int wire_type, int field_number,
+                                        ExtensionFinder* extension_finder,
+                                        ExtensionInfo* extension,
+                                        bool* was_packed_on_wire);
+
+  // Parses a single extension from the input. The input should start out
+  // positioned immediately after the wire tag. This method is called in
+  // ParseField() after field number and was_packed_on_wire is extracted from
+  // the wire tag and ExtensionInfo is found by the field number.
+  bool ParseFieldWithExtensionInfo(int field_number,
+                                   bool was_packed_on_wire,
+                                   const ExtensionInfo& extension,
+                                   io::CodedInputStream* input,
+                                   FieldSkipper* field_skipper);
+
+  // Like ParseField(), but this method may parse singular message extensions
+  // lazily depending on the value of FLAGS_eagerly_parse_message_sets.
+  bool ParseFieldMaybeLazily(int wire_type, int field_number,
+                             io::CodedInputStream* input,
+                             ExtensionFinder* extension_finder,
+                             MessageSetFieldSkipper* field_skipper);
+
+  // Gets the extension with the given number, creating it if it does not
+  // already exist.  Returns true if the extension did not already exist.
+  bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
+                         Extension** result);
+
+  // Parse a single MessageSet item -- called just after the item group start
+  // tag has been read.
+  bool ParseMessageSetItem(io::CodedInputStream* input,
+                           ExtensionFinder* extension_finder,
+                           MessageSetFieldSkipper* field_skipper);
+
+
+  // Hack:  RepeatedPtrFieldBase declares ExtensionSet as a friend.  This
+  //   friendship should automatically extend to ExtensionSet::Extension, but
+  //   unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
+  //   correctly.  So, we must provide helpers for calling methods of that
+  //   class.
+
+  // Defined in extension_set_heavy.cc.
+  static inline int RepeatedMessage_SpaceUsedExcludingSelf(
+      RepeatedPtrFieldBase* field);
+
+  // 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.
+  std::map<int, Extension> extensions_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionSet);
+};
+
+// These are just for convenience...
+inline void ExtensionSet::SetString(int number, FieldType type,
+                                    const string& value,
+                                    const FieldDescriptor* descriptor) {
+  MutableString(number, type, descriptor)->assign(value);
+}
+inline void ExtensionSet::SetRepeatedString(int number, int index,
+                                            const string& value) {
+  MutableRepeatedString(number, index)->assign(value);
+}
+inline void ExtensionSet::AddString(int number, FieldType type,
+                                    const string& value,
+                                    const FieldDescriptor* descriptor) {
+  AddString(number, type, descriptor)->assign(value);
+}
+
+// ===================================================================
+// Glue for generated extension accessors
+
+// -------------------------------------------------------------------
+// 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;
+//     // TypeTraits for singular fields and repeated fields will define the
+//     // symbol "Singular" or "Repeated" respectively. These two symbols will
+//     // be used in extension accessors to distinguish between singular
+//     // extensions and repeated extensions. If the TypeTraits for the passed
+//     // in extension doesn't have the expected symbol defined, it means the
+//     // user is passing a repeated extension to a singular accessor, or the
+//     // opposite. In that case the C++ compiler will generate an error
+//     // message "no matching member function" to inform the user.
+//     typedef ? Singular
+//     typedef ? Repeated
+//
+//     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;
+  typedef Type MutableType;
+  typedef PrimitiveTypeTraits<Type> Singular;
+
+  static inline ConstType Get(int number, const ExtensionSet& set,
+                              ConstType default_value);
+  static inline void Set(int number, FieldType field_type,
+                         ConstType value, ExtensionSet* set);
+};
+
+template <typename Type>
+class RepeatedPrimitiveTypeTraits {
+ public:
+  typedef Type ConstType;
+  typedef Type MutableType;
+  typedef RepeatedPrimitiveTypeTraits<Type> Repeated;
+
+  typedef RepeatedField<Type> RepeatedFieldType;
+
+  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, FieldType field_type,
+                         bool is_packed, Type value, ExtensionSet* set);
+
+  static inline const RepeatedField<ConstType>&
+      GetRepeated(int number, const ExtensionSet& set);
+  static inline RepeatedField<Type>*
+      MutableRepeated(int number, FieldType field_type,
+                      bool is_packed, ExtensionSet* set);
+
+  static const RepeatedFieldType* GetDefaultRepeatedField();
+};
+
+// Declared here so that this can be friended below.
+void InitializeDefaultRepeatedFields();
+void DestroyDefaultRepeatedFields();
+
+class LIBPROTOBUF_EXPORT RepeatedPrimitiveGenericTypeTraits {
+ private:
+  template<typename Type> friend class RepeatedPrimitiveTypeTraits;
+  friend void InitializeDefaultRepeatedFields();
+  friend void DestroyDefaultRepeatedFields();
+  static const RepeatedField<int32>* default_repeated_field_int32_;
+  static const RepeatedField<int64>* default_repeated_field_int64_;
+  static const RepeatedField<uint32>* default_repeated_field_uint32_;
+  static const RepeatedField<uint64>* default_repeated_field_uint64_;
+  static const RepeatedField<double>* default_repeated_field_double_;
+  static const RepeatedField<float>* default_repeated_field_float_;
+  static const RepeatedField<bool>* default_repeated_field_bool_;
+};
+
+#define PROTOBUF_DEFINE_PRIMITIVE_TYPE(TYPE, METHOD)                       \
+template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get(                     \
+    int number, const ExtensionSet& set, TYPE default_value) {             \
+  return set.Get##METHOD(number, default_value);                           \
+}                                                                          \
+template<> inline void PrimitiveTypeTraits<TYPE>::Set(                     \
+    int number, FieldType field_type, TYPE value, ExtensionSet* set) {     \
+  set->Set##METHOD(number, field_type, value, NULL);                       \
+}                                                                          \
+                                                                           \
+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, TYPE value, ExtensionSet* set) {                \
+  set->SetRepeated##METHOD(number, index, value);                          \
+}                                                                          \
+template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add(             \
+    int number, FieldType field_type, bool is_packed,                      \
+    TYPE value, ExtensionSet* set) {                                       \
+  set->Add##METHOD(number, field_type, is_packed, value, NULL);            \
+}                                                                          \
+template<> inline const RepeatedField<TYPE>*                               \
+    RepeatedPrimitiveTypeTraits<TYPE>::GetDefaultRepeatedField() {         \
+  return RepeatedPrimitiveGenericTypeTraits::                              \
+      default_repeated_field_##TYPE##_;                                    \
+}                                                                          \
+template<> inline const RepeatedField<TYPE>&                               \
+    RepeatedPrimitiveTypeTraits<TYPE>::GetRepeated(int number,             \
+                                               const ExtensionSet& set) {  \
+  return *reinterpret_cast<const RepeatedField<TYPE>*>(                    \
+                            set.GetRawRepeatedField(                       \
+                                number, GetDefaultRepeatedField()));       \
+}                                                                          \
+template<> inline RepeatedField<TYPE>*                                     \
+    RepeatedPrimitiveTypeTraits<TYPE>::MutableRepeated(int number,         \
+                                                   FieldType field_type,   \
+                                                   bool is_packed,         \
+                                                   ExtensionSet* set) {    \
+  return reinterpret_cast<RepeatedField<TYPE>*>(                           \
+      set->MutableRawRepeatedField(number, field_type, is_packed, NULL));  \
+}
+
+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;
+  typedef StringTypeTraits Singular;
+
+  static inline const string& Get(int number, const ExtensionSet& set,
+                                  ConstType default_value) {
+    return set.GetString(number, default_value);
+  }
+  static inline void Set(int number, FieldType field_type,
+                         const string& value, ExtensionSet* set) {
+    set->SetString(number, field_type, value, NULL);
+  }
+  static inline string* Mutable(int number, FieldType field_type,
+                                ExtensionSet* set) {
+    return set->MutableString(number, field_type, NULL);
+  }
+};
+
+class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
+ public:
+  typedef const string& ConstType;
+  typedef string* MutableType;
+  typedef RepeatedStringTypeTraits Repeated;
+
+  typedef RepeatedPtrField<string> RepeatedFieldType;
+
+  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, FieldType field_type,
+                         bool /*is_packed*/, const string& value,
+                         ExtensionSet* set) {
+    set->AddString(number, field_type, value, NULL);
+  }
+  static inline string* Add(int number, FieldType field_type,
+                            ExtensionSet* set) {
+    return set->AddString(number, field_type, NULL);
+  }
+  static inline const RepeatedPtrField<string>&
+      GetRepeated(int number, const ExtensionSet& set) {
+    return *reinterpret_cast<const RepeatedPtrField<string>*>(
+        set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
+  }
+
+  static inline RepeatedPtrField<string>*
+      MutableRepeated(int number, FieldType field_type,
+                      bool is_packed, ExtensionSet* set) {
+    return reinterpret_cast<RepeatedPtrField<string>*>(
+        set->MutableRawRepeatedField(number, field_type,
+                                     is_packed, NULL));
+  }
+
+  static const RepeatedFieldType* GetDefaultRepeatedField() {
+    return default_repeated_field_;
+  }
+
+ private:
+  friend void InitializeDefaultRepeatedFields();
+  friend void DestroyDefaultRepeatedFields();
+  static const RepeatedFieldType *default_repeated_field_;
+};
+
+// -------------------------------------------------------------------
+// EnumTypeTraits
+
+// ExtensionSet represents enums using integers internally, so we have to
+// static_cast around.
+template <typename Type, bool IsValid(int)>
+class EnumTypeTraits {
+ public:
+  typedef Type ConstType;
+  typedef Type MutableType;
+  typedef EnumTypeTraits<Type, IsValid> Singular;
+
+  static inline ConstType Get(int number, const ExtensionSet& set,
+                              ConstType default_value) {
+    return static_cast<Type>(set.GetEnum(number, default_value));
+  }
+  static inline void Set(int number, FieldType field_type,
+                         ConstType value, ExtensionSet* set) {
+    GOOGLE_DCHECK(IsValid(value));
+    set->SetEnum(number, field_type, value, NULL);
+  }
+};
+
+template <typename Type, bool IsValid(int)>
+class RepeatedEnumTypeTraits {
+ public:
+  typedef Type ConstType;
+  typedef Type MutableType;
+  typedef RepeatedEnumTypeTraits<Type, IsValid> Repeated;
+
+  typedef RepeatedField<Type> RepeatedFieldType;
+
+  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) {
+    GOOGLE_DCHECK(IsValid(value));
+    set->SetRepeatedEnum(number, index, value);
+  }
+  static inline void Add(int number, FieldType field_type,
+                         bool is_packed, ConstType value, ExtensionSet* set) {
+    GOOGLE_DCHECK(IsValid(value));
+    set->AddEnum(number, field_type, is_packed, value, NULL);
+  }
+  static inline const RepeatedField<Type>& GetRepeated(int number,
+                                                       const ExtensionSet&
+                                                       set) {
+    // Hack: the `Extension` struct stores a RepeatedField<int> for enums.
+    // RepeatedField<int> cannot implicitly convert to RepeatedField<EnumType>
+    // so we need to do some casting magic. See message.h for similar
+    // contortions for non-extension fields.
+    return *reinterpret_cast<const RepeatedField<Type>*>(
+        set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
+  }
+
+  static inline RepeatedField<Type>* MutableRepeated(int number,
+                                                     FieldType field_type,
+                                                     bool is_packed,
+                                                     ExtensionSet* set) {
+    return reinterpret_cast<RepeatedField<Type>*>(
+        set->MutableRawRepeatedField(number, field_type, is_packed, NULL));
+  }
+
+  static const RepeatedFieldType* GetDefaultRepeatedField() {
+    // Hack: as noted above, repeated enum fields are internally stored as a
+    // RepeatedField<int>. We need to be able to instantiate global static
+    // objects to return as default (empty) repeated fields on non-existent
+    // extensions. We would not be able to know a-priori all of the enum types
+    // (values of |Type|) to instantiate all of these, so we just re-use int32's
+    // default repeated field object.
+    return reinterpret_cast<const RepeatedField<Type>*>(
+        RepeatedPrimitiveTypeTraits<int32>::GetDefaultRepeatedField());
+  }
+};
+
+// -------------------------------------------------------------------
+// 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;
+  typedef MessageTypeTraits<Type> Singular;
+
+  static inline ConstType Get(int number, const ExtensionSet& set,
+                              ConstType default_value) {
+    return static_cast<const Type&>(
+        set.GetMessage(number, default_value));
+  }
+  static inline MutableType Mutable(int number, FieldType field_type,
+                                    ExtensionSet* set) {
+    return static_cast<Type*>(
+      set->MutableMessage(number, field_type, Type::default_instance(), NULL));
+  }
+  static inline void SetAllocated(int number, FieldType field_type,
+                                  MutableType message, ExtensionSet* set) {
+    set->SetAllocatedMessage(number, field_type, NULL, message);
+  }
+  static inline MutableType Release(int number, FieldType /* field_type */,
+                                    ExtensionSet* set) {
+    return static_cast<Type*>(set->ReleaseMessage(
+        number, Type::default_instance()));
+  }
+};
+
+// forward declaration
+class RepeatedMessageGenericTypeTraits;
+
+template <typename Type>
+class RepeatedMessageTypeTraits {
+ public:
+  typedef const Type& ConstType;
+  typedef Type* MutableType;
+  typedef RepeatedMessageTypeTraits<Type> Repeated;
+
+  typedef RepeatedPtrField<Type> RepeatedFieldType;
+
+  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, FieldType field_type,
+                                ExtensionSet* set) {
+    return static_cast<Type*>(
+        set->AddMessage(number, field_type, Type::default_instance(), NULL));
+  }
+  static inline const RepeatedPtrField<Type>& GetRepeated(int number,
+                                                          const ExtensionSet&
+                                                          set) {
+    // See notes above in RepeatedEnumTypeTraits::GetRepeated(): same
+    // casting hack applies here, because a RepeatedPtrField<MessageLite>
+    // cannot naturally become a RepeatedPtrType<Type> even though Type is
+    // presumably a message. google::protobuf::Message goes through similar contortions
+    // with a reinterpret_cast<>.
+    return *reinterpret_cast<const RepeatedPtrField<Type>*>(
+        set.GetRawRepeatedField(number, GetDefaultRepeatedField()));
+  }
+  static inline RepeatedPtrField<Type>* MutableRepeated(int number,
+                                                        FieldType field_type,
+                                                        bool is_packed,
+                                                        ExtensionSet* set) {
+    return reinterpret_cast<RepeatedPtrField<Type>*>(
+        set->MutableRawRepeatedField(number, field_type, is_packed, NULL));
+  }
+
+  static const RepeatedFieldType* GetDefaultRepeatedField();
+};
+
+// This class exists only to hold a generic default empty repeated field for all
+// message-type repeated field extensions.
+class LIBPROTOBUF_EXPORT RepeatedMessageGenericTypeTraits {
+ public:
+  typedef RepeatedPtrField< ::google::protobuf::MessageLite*> RepeatedFieldType;
+ private:
+  template<typename Type> friend class RepeatedMessageTypeTraits;
+  friend void InitializeDefaultRepeatedFields();
+  friend void DestroyDefaultRepeatedFields();
+  static const RepeatedFieldType* default_repeated_field_;
+};
+
+template<typename Type> inline
+    const typename RepeatedMessageTypeTraits<Type>::RepeatedFieldType*
+    RepeatedMessageTypeTraits<Type>::GetDefaultRepeatedField() {
+  return reinterpret_cast<const RepeatedFieldType*>(
+      RepeatedMessageGenericTypeTraits::default_repeated_field_);
+}
+
+// -------------------------------------------------------------------
+// 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>, 1, false> 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,
+          FieldType field_type, bool is_packed>
+class ExtensionIdentifier {
+ public:
+  typedef TypeTraitsType TypeTraits;
+  typedef ExtendeeType Extendee;
+
+  ExtensionIdentifier(int number, typename TypeTraits::ConstType default_value)
+      : number_(number), default_value_(default_value) {}
+  inline int number() const { return number_; }
+  typename TypeTraits::ConstType default_value() const {
+    return default_value_;
+  }
+
+ private:
+  const int number_;
+  typename TypeTraits::ConstType default_value_;
+};
+
+// -------------------------------------------------------------------
+// Generated accessors
+
+// This macro should be expanded in the context of a generated type which
+// has extensions.
+//
+// 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.
+//
+// For similar reason, we use "_field_type" and "_is_packed" as parameter names
+// below, so that "field_type" and "is_packed" can be used as field names.
+#define GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(CLASSNAME)                        \
+  /* Has, Size, Clear */                                                      \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline bool HasExtension(                                                   \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
+    return _extensions_.Has(id.number());                                     \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline void ClearExtension(                                                 \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
+    _extensions_.ClearExtension(id.number());                                 \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline int ExtensionSize(                                                   \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
+    return _extensions_.ExtensionSize(id.number());                           \
+  }                                                                           \
+                                                                              \
+  /* Singular accessors */                                                    \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline typename _proto_TypeTraits::Singular::ConstType GetExtension(        \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) const {   \
+    return _proto_TypeTraits::Get(id.number(), _extensions_,                  \
+                                  id.default_value());                        \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline typename _proto_TypeTraits::Singular::MutableType MutableExtension(  \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
+    return _proto_TypeTraits::Mutable(id.number(), _field_type,               \
+                                      &_extensions_);                         \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline void SetExtension(                                                   \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      typename _proto_TypeTraits::Singular::ConstType value) {                \
+    _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_);   \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline void SetAllocatedExtension(                                          \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      typename _proto_TypeTraits::Singular::MutableType value) {              \
+    _proto_TypeTraits::SetAllocated(id.number(), _field_type,                 \
+                                    value, &_extensions_);                    \
+  }                                                                           \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline typename _proto_TypeTraits::Singular::MutableType ReleaseExtension(  \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
+    return _proto_TypeTraits::Release(id.number(), _field_type,               \
+                                      &_extensions_);                         \
+  }                                                                           \
+                                                                              \
+  /* Repeated accessors */                                                    \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline typename _proto_TypeTraits::Repeated::ConstType GetExtension(        \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      int index) const {                                                      \
+    return _proto_TypeTraits::Get(id.number(), _extensions_, index);          \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline typename _proto_TypeTraits::Repeated::MutableType MutableExtension(  \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      int index) {                                                            \
+    return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_);     \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline void SetExtension(                                                   \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      int index, typename _proto_TypeTraits::Repeated::ConstType value) {     \
+    _proto_TypeTraits::Set(id.number(), index, value, &_extensions_);         \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline typename _proto_TypeTraits::Repeated::MutableType AddExtension(      \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id) {         \
+    return _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_);   \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline void AddExtension(                                                   \
+      const ::google::protobuf::internal::ExtensionIdentifier<                          \
+        CLASSNAME, _proto_TypeTraits, _field_type, _is_packed>& id,           \
+      typename _proto_TypeTraits::Repeated::ConstType value) {                \
+    _proto_TypeTraits::Add(id.number(), _field_type, _is_packed,              \
+                           value, &_extensions_);                             \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline const typename _proto_TypeTraits::Repeated::RepeatedFieldType&       \
+      GetRepeatedExtension(                                                   \
+          const ::google::protobuf::internal::ExtensionIdentifier<                      \
+            CLASSNAME, _proto_TypeTraits, _field_type,                        \
+            _is_packed>& id) const {                                          \
+    return _proto_TypeTraits::GetRepeated(id.number(), _extensions_);         \
+  }                                                                           \
+                                                                              \
+  template <typename _proto_TypeTraits,                                       \
+            ::google::protobuf::internal::FieldType _field_type,                        \
+            bool _is_packed>                                                  \
+  inline typename _proto_TypeTraits::Repeated::RepeatedFieldType*             \
+      MutableRepeatedExtension(                                               \
+          const ::google::protobuf::internal::ExtensionIdentifier<                      \
+              CLASSNAME, _proto_TypeTraits, _field_type,                      \
+              _is_packed>& id) {                                              \
+    return _proto_TypeTraits::MutableRepeated(id.number(), _field_type,       \
+                                              _is_packed, &_extensions_);     \
+  }
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_EXTENSION_SET_H__
diff --git a/protobuf/src/google/protobuf/extension_set_heavy.cc b/protobuf/src/google/protobuf/extension_set_heavy.cc
new file mode 100644
index 0000000..a50efac
--- /dev/null
+++ b/protobuf/src/google/protobuf/extension_set_heavy.cc
@@ -0,0 +1,734 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Contains methods defined in extension_set.h which cannot be part of the
+// lite library because they use descriptors or reflection.
+
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+
+namespace google {
+
+namespace protobuf {
+namespace internal {
+
+// A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet.
+class MessageSetFieldSkipper
+    : public UnknownFieldSetFieldSkipper {
+ public:
+  explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
+      : UnknownFieldSetFieldSkipper(unknown_fields) {}
+  virtual ~MessageSetFieldSkipper() {}
+
+  virtual bool SkipMessageSetField(io::CodedInputStream* input,
+                                   int field_number);
+};
+bool MessageSetFieldSkipper::SkipMessageSetField(
+    io::CodedInputStream* input, int field_number) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  if (unknown_fields_ == NULL) {
+    return input->Skip(length);
+  } else {
+    return input->ReadString(
+        unknown_fields_->AddLengthDelimited(field_number), length);
+  }
+}
+
+
+// Implementation of ExtensionFinder which finds extensions in a given
+// DescriptorPool, using the given MessageFactory to construct sub-objects.
+// This class is implemented in extension_set_heavy.cc.
+class DescriptorPoolExtensionFinder : public ExtensionFinder {
+ public:
+  DescriptorPoolExtensionFinder(const DescriptorPool* pool,
+                                MessageFactory* factory,
+                                const Descriptor* containing_type)
+      : pool_(pool), factory_(factory), containing_type_(containing_type) {}
+  virtual ~DescriptorPoolExtensionFinder() {}
+
+  virtual bool Find(int number, ExtensionInfo* output);
+
+ private:
+  const DescriptorPool* pool_;
+  MessageFactory* factory_;
+  const Descriptor* containing_type_;
+};
+
+void ExtensionSet::AppendToList(const Descriptor* containing_type,
+                                const DescriptorPool* pool,
+                                std::vector<const FieldDescriptor*>* output) const {
+  for (map<int, Extension>::const_iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    bool has = false;
+    if (iter->second.is_repeated) {
+      has = iter->second.GetSize() > 0;
+    } else {
+      has = !iter->second.is_cleared;
+    }
+
+    if (has) {
+      // TODO(kenton): Looking up each field by number is somewhat unfortunate.
+      //   Is there a better way?  The problem is that descriptors are lazily-
+      //   initialized, so they might not even be constructed until
+      //   AppendToList() is called.
+
+      if (iter->second.descriptor == NULL) {
+        output->push_back(pool->FindExtensionByNumber(
+            containing_type, iter->first));
+      } else {
+        output->push_back(iter->second.descriptor);
+      }
+    }
+  }
+}
+
+inline FieldDescriptor::Type real_type(FieldType type) {
+  GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
+  return static_cast<FieldDescriptor::Type>(type);
+}
+
+inline FieldDescriptor::CppType cpp_type(FieldType type) {
+  return FieldDescriptor::TypeToCppType(
+      static_cast<FieldDescriptor::Type>(type));
+}
+
+inline WireFormatLite::FieldType field_type(FieldType type) {
+  GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
+  return static_cast<WireFormatLite::FieldType>(type);
+}
+
+#define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                            \
+  GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED     \
+                                  : FieldDescriptor::LABEL_OPTIONAL,      \
+            FieldDescriptor::LABEL_##LABEL);                              \
+  GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
+
+const MessageLite& ExtensionSet::GetMessage(int number,
+                                            const Descriptor* message_type,
+                                            MessageFactory* factory) const {
+  map<int, Extension>::const_iterator iter = extensions_.find(number);
+  if (iter == extensions_.end() || iter->second.is_cleared) {
+    // Not present.  Return the default value.
+    return *factory->GetPrototype(message_type);
+  } else {
+    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
+    if (iter->second.is_lazy) {
+      return iter->second.lazymessage_value->GetMessage(
+          *factory->GetPrototype(message_type));
+    } else {
+      return *iter->second.message_value;
+    }
+  }
+}
+
+MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
+                                          MessageFactory* factory) {
+  Extension* extension;
+  if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
+    extension->type = descriptor->type();
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
+    extension->is_repeated = false;
+    extension->is_packed = false;
+    const MessageLite* prototype =
+        factory->GetPrototype(descriptor->message_type());
+    extension->is_lazy = false;
+    extension->message_value = prototype->New();
+    extension->is_cleared = false;
+    return extension->message_value;
+  } else {
+    GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
+    extension->is_cleared = false;
+    if (extension->is_lazy) {
+      return extension->lazymessage_value->MutableMessage(
+          *factory->GetPrototype(descriptor->message_type()));
+    } else {
+      return extension->message_value;
+    }
+  }
+}
+
+MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
+                                          MessageFactory* factory) {
+  map<int, Extension>::iterator iter = extensions_.find(descriptor->number());
+  if (iter == extensions_.end()) {
+    // Not present.  Return NULL.
+    return NULL;
+  } else {
+    GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
+    MessageLite* ret = NULL;
+    if (iter->second.is_lazy) {
+      ret = iter->second.lazymessage_value->ReleaseMessage(
+          *factory->GetPrototype(descriptor->message_type()));
+      delete iter->second.lazymessage_value;
+    } else {
+      ret = iter->second.message_value;
+    }
+    extensions_.erase(descriptor->number());
+    return ret;
+  }
+}
+
+MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
+                                      MessageFactory* factory) {
+  Extension* extension;
+  if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
+    extension->type = descriptor->type();
+    GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
+    extension->is_repeated = true;
+    extension->repeated_message_value =
+      new RepeatedPtrField<MessageLite>();
+  } else {
+    GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
+  }
+
+  // RepeatedPtrField<Message> does not know how to Add() since it cannot
+  // allocate an abstract object, so we have to be tricky.
+  MessageLite* result = extension->repeated_message_value
+      ->AddFromCleared<GenericTypeHandler<MessageLite> >();
+  if (result == NULL) {
+    const MessageLite* prototype;
+    if (extension->repeated_message_value->size() == 0) {
+      prototype = factory->GetPrototype(descriptor->message_type());
+      GOOGLE_CHECK(prototype != NULL);
+    } else {
+      prototype = &extension->repeated_message_value->Get(0);
+    }
+    result = prototype->New();
+    extension->repeated_message_value->AddAllocated(result);
+  }
+  return result;
+}
+
+static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
+  return reinterpret_cast<const EnumDescriptor*>(arg)
+      ->FindValueByNumber(number) != NULL;
+}
+
+bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
+  const FieldDescriptor* extension =
+      pool_->FindExtensionByNumber(containing_type_, number);
+  if (extension == NULL) {
+    return false;
+  } else {
+    output->type = extension->type();
+    output->is_repeated = extension->is_repeated();
+    output->is_packed = extension->options().packed();
+    output->descriptor = extension;
+    if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      output->message_prototype =
+          factory_->GetPrototype(extension->message_type());
+      GOOGLE_CHECK(output->message_prototype != NULL)
+          << "Extension factory's GetPrototype() returned NULL for extension: "
+          << extension->full_name();
+    } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+      output->enum_validity_check.func = ValidateEnumUsingDescriptor;
+      output->enum_validity_check.arg = extension->enum_type();
+    }
+
+    return true;
+  }
+}
+
+bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
+                              const Message* containing_type,
+                              UnknownFieldSet* unknown_fields) {
+  UnknownFieldSetFieldSkipper skipper(unknown_fields);
+  if (input->GetExtensionPool() == NULL) {
+    GeneratedExtensionFinder finder(containing_type);
+    return ParseField(tag, input, &finder, &skipper);
+  } else {
+    DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
+                                         input->GetExtensionFactory(),
+                                         containing_type->GetDescriptor());
+    return ParseField(tag, input, &finder, &skipper);
+  }
+}
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+                                   const Message* containing_type,
+                                   UnknownFieldSet* unknown_fields) {
+  MessageSetFieldSkipper skipper(unknown_fields);
+  if (input->GetExtensionPool() == NULL) {
+    GeneratedExtensionFinder finder(containing_type);
+    return ParseMessageSet(input, &finder, &skipper);
+  } else {
+    DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
+                                         input->GetExtensionFactory(),
+                                         containing_type->GetDescriptor());
+    return ParseMessageSet(input, &finder, &skipper);
+  }
+}
+
+int ExtensionSet::SpaceUsedExcludingSelf() const {
+  int total_size =
+      extensions_.size() * sizeof(map<int, Extension>::value_type);
+  for (map<int, Extension>::const_iterator iter = extensions_.begin(),
+       end = extensions_.end();
+       iter != end;
+       ++iter) {
+    total_size += iter->second.SpaceUsedExcludingSelf();
+  }
+  return total_size;
+}
+
+inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf(
+    RepeatedPtrFieldBase* field) {
+  return field->SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
+}
+
+int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
+  int total_size = 0;
+  if (is_repeated) {
+    switch (cpp_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
+      case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
+        total_size += sizeof(*repeated_##LOWERCASE##_value) +      \
+            repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\
+        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);
+#undef HANDLE_TYPE
+
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        // repeated_message_value is actually a RepeatedPtrField<MessageLite>,
+        // but MessageLite has no SpaceUsed(), so we must directly call
+        // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type
+        // handler.
+        total_size += sizeof(*repeated_message_value) +
+            RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value);
+        break;
+    }
+  } else {
+    switch (cpp_type(type)) {
+      case FieldDescriptor::CPPTYPE_STRING:
+        total_size += sizeof(*string_value) +
+                      StringSpaceUsedExcludingSelf(*string_value);
+        break;
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        if (is_lazy) {
+          total_size += lazymessage_value->SpaceUsed();
+        } else {
+          total_size += down_cast<Message*>(message_value)->SpaceUsed();
+        }
+        break;
+      default:
+        // No extra storage costs for primitive types.
+        break;
+    }
+  }
+  return total_size;
+}
+
+// The Serialize*ToArray methods are only needed in the heavy library, as
+// the lite library only generates SerializeWithCachedSizes.
+uint8* ExtensionSet::SerializeWithCachedSizesToArray(
+    int start_field_number, int end_field_number,
+    uint8* target) const {
+  map<int, Extension>::const_iterator iter;
+  for (iter = extensions_.lower_bound(start_field_number);
+       iter != extensions_.end() && iter->first < end_field_number;
+       ++iter) {
+    target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first,
+                                                               target);
+  }
+  return target;
+}
+
+uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
+    uint8* target) const {
+  map<int, Extension>::const_iterator iter;
+  for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
+    target = iter->second.SerializeMessageSetItemWithCachedSizesToArray(
+        iter->first, target);
+  }
+  return target;
+}
+
+uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
+    int number, uint8* target) const {
+  if (is_repeated) {
+    if (is_packed) {
+      if (cached_size == 0) return target;
+
+      target = WireFormatLite::WriteTagToArray(number,
+          WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
+      target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
+
+      switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
+        case FieldDescriptor::TYPE_##UPPERCASE:                             \
+          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
+            target = WireFormatLite::Write##CAMELCASE##NoTagToArray(        \
+              repeated_##LOWERCASE##_value->Get(i), target);                \
+          }                                                                 \
+          break
+
+        HANDLE_TYPE(   INT32,    Int32,   int32);
+        HANDLE_TYPE(   INT64,    Int64,   int64);
+        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
+        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
+        HANDLE_TYPE(  SINT32,   SInt32,   int32);
+        HANDLE_TYPE(  SINT64,   SInt64,   int64);
+        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(    ENUM,     Enum,    enum);
+#undef HANDLE_TYPE
+
+        case WireFormatLite::TYPE_STRING:
+        case WireFormatLite::TYPE_BYTES:
+        case WireFormatLite::TYPE_GROUP:
+        case WireFormatLite::TYPE_MESSAGE:
+          GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
+          break;
+      }
+    } else {
+      switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
+        case FieldDescriptor::TYPE_##UPPERCASE:                             \
+          for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
+            target = WireFormatLite::Write##CAMELCASE##ToArray(number,      \
+              repeated_##LOWERCASE##_value->Get(i), target);                \
+          }                                                                 \
+          break
+
+        HANDLE_TYPE(   INT32,    Int32,   int32);
+        HANDLE_TYPE(   INT64,    Int64,   int64);
+        HANDLE_TYPE(  UINT32,   UInt32,  uint32);
+        HANDLE_TYPE(  UINT64,   UInt64,  uint64);
+        HANDLE_TYPE(  SINT32,   SInt32,   int32);
+        HANDLE_TYPE(  SINT64,   SInt64,   int64);
+        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(  STRING,   String,  string);
+        HANDLE_TYPE(   BYTES,    Bytes,  string);
+        HANDLE_TYPE(    ENUM,     Enum,    enum);
+        HANDLE_TYPE(   GROUP,    Group, message);
+        HANDLE_TYPE( MESSAGE,  Message, message);
+#undef HANDLE_TYPE
+      }
+    }
+  } else if (!is_cleared) {
+    switch (real_type(type)) {
+#define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
+      case FieldDescriptor::TYPE_##UPPERCASE:                    \
+        target = WireFormatLite::Write##CAMELCASE##ToArray(      \
+            number, VALUE, target); \
+        break
+
+      HANDLE_TYPE(   INT32,    Int32,    int32_value);
+      HANDLE_TYPE(   INT64,    Int64,    int64_value);
+      HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
+      HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
+      HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
+      HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
+      HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
+      HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
+      HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
+      HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
+      HANDLE_TYPE(   FLOAT,    Float,    float_value);
+      HANDLE_TYPE(  DOUBLE,   Double,   double_value);
+      HANDLE_TYPE(    BOOL,     Bool,     bool_value);
+      HANDLE_TYPE(  STRING,   String,  *string_value);
+      HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
+      HANDLE_TYPE(    ENUM,     Enum,     enum_value);
+      HANDLE_TYPE(   GROUP,    Group, *message_value);
+#undef HANDLE_TYPE
+      case FieldDescriptor::TYPE_MESSAGE:
+        if (is_lazy) {
+          target = lazymessage_value->WriteMessageToArray(number, target);
+        } else {
+          target = WireFormatLite::WriteMessageToArray(
+              number, *message_value, target);
+        }
+        break;
+    }
+  }
+  return target;
+}
+
+uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray(
+    int number,
+    uint8* target) const {
+  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
+    // Not a valid MessageSet extension, but serialize it the normal way.
+    GOOGLE_LOG(WARNING) << "Invalid message set extension.";
+    return SerializeFieldWithCachedSizesToArray(number, target);
+  }
+
+  if (is_cleared) return target;
+
+  // Start group.
+  target = io::CodedOutputStream::WriteTagToArray(
+      WireFormatLite::kMessageSetItemStartTag, target);
+  // Write type ID.
+  target = WireFormatLite::WriteUInt32ToArray(
+      WireFormatLite::kMessageSetTypeIdNumber, number, target);
+  // Write message.
+  if (is_lazy) {
+    target = lazymessage_value->WriteMessageToArray(
+        WireFormatLite::kMessageSetMessageNumber, target);
+  } else {
+    target = WireFormatLite::WriteMessageToArray(
+        WireFormatLite::kMessageSetMessageNumber, *message_value, target);
+  }
+  // End group.
+  target = io::CodedOutputStream::WriteTagToArray(
+      WireFormatLite::kMessageSetItemEndTag, target);
+  return target;
+}
+
+
+bool ExtensionSet::ParseFieldMaybeLazily(
+    int wire_type, int field_number, io::CodedInputStream* input,
+    ExtensionFinder* extension_finder,
+    MessageSetFieldSkipper* field_skipper) {
+  return ParseField(WireFormatLite::MakeTag(
+      field_number, static_cast<WireFormatLite::WireType>(wire_type)),
+                    input, extension_finder, field_skipper);
+}
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+                                   ExtensionFinder* extension_finder,
+                                   MessageSetFieldSkipper* field_skipper) {
+  while (true) {
+    const uint32 tag = input->ReadTag();
+    switch (tag) {
+      case 0:
+        return true;
+      case WireFormatLite::kMessageSetItemStartTag:
+        if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
+          return false;
+        }
+        break;
+      default:
+        if (!ParseField(tag, input, extension_finder, field_skipper)) {
+          return false;
+        }
+        break;
+    }
+  }
+}
+
+bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
+                                   const MessageLite* containing_type) {
+  MessageSetFieldSkipper skipper(NULL);
+  GeneratedExtensionFinder finder(containing_type);
+  return ParseMessageSet(input, &finder, &skipper);
+}
+
+bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
+                                       ExtensionFinder* extension_finder,
+                                       MessageSetFieldSkipper* field_skipper) {
+  // TODO(kenton):  It would be nice to share code between this and
+  // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
+  // differences would be hard to factor out.
+
+  // This method parses a group which should contain two fields:
+  //   required int32 type_id = 2;
+  //   required data message = 3;
+
+  uint32 last_type_id = 0;
+
+  // If we see message data before the type_id, we'll append it to this so
+  // we can parse it later.
+  string message_data;
+
+  while (true) {
+    const uint32 tag = input->ReadTag();
+    if (tag == 0) return false;
+
+    switch (tag) {
+      case WireFormatLite::kMessageSetTypeIdTag: {
+        uint32 type_id;
+        if (!input->ReadVarint32(&type_id)) return false;
+        last_type_id = type_id;
+
+        if (!message_data.empty()) {
+          // We saw some message data before the type_id.  Have to parse it
+          // now.
+          io::CodedInputStream sub_input(
+              reinterpret_cast<const uint8*>(message_data.data()),
+              message_data.size());
+          if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+                                     last_type_id, &sub_input,
+                                     extension_finder, field_skipper)) {
+            return false;
+          }
+          message_data.clear();
+        }
+
+        break;
+      }
+
+      case WireFormatLite::kMessageSetMessageTag: {
+        if (last_type_id == 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;
+          io::StringOutputStream output_stream(&message_data);
+          io::CodedOutputStream coded_output(&output_stream);
+          coded_output.WriteVarint32(length);
+          coded_output.WriteString(temp);
+        } else {
+          // Already saw type_id, so we can parse this directly.
+          if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+                                     last_type_id, input,
+                                     extension_finder, field_skipper)) {
+            return false;
+          }
+        }
+
+        break;
+      }
+
+      case WireFormatLite::kMessageSetItemEndTag: {
+        return true;
+      }
+
+      default: {
+        if (!field_skipper->SkipField(input, tag)) return false;
+      }
+    }
+  }
+}
+
+void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
+    int number,
+    io::CodedOutputStream* output) const {
+  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
+    // Not a valid MessageSet extension, but serialize it the normal way.
+    SerializeFieldWithCachedSizes(number, output);
+    return;
+  }
+
+  if (is_cleared) return;
+
+  // Start group.
+  output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
+
+  // Write type ID.
+  WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
+                              number,
+                              output);
+  // Write message.
+  if (is_lazy) {
+    lazymessage_value->WriteMessage(
+        WireFormatLite::kMessageSetMessageNumber, output);
+  } else {
+    WireFormatLite::WriteMessageMaybeToArray(
+        WireFormatLite::kMessageSetMessageNumber,
+        *message_value,
+        output);
+  }
+
+  // End group.
+  output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
+}
+
+int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
+  if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
+    // Not a valid MessageSet extension, but compute the byte size for it the
+    // normal way.
+    return ByteSize(number);
+  }
+
+  if (is_cleared) return 0;
+
+  int our_size = WireFormatLite::kMessageSetItemTagsSize;
+
+  // type_id
+  our_size += io::CodedOutputStream::VarintSize32(number);
+
+  // message
+  int message_size = 0;
+  if (is_lazy) {
+    message_size = lazymessage_value->ByteSize();
+  } else {
+    message_size = message_value->ByteSize();
+  }
+
+  our_size += io::CodedOutputStream::VarintSize32(message_size);
+  our_size += message_size;
+
+  return our_size;
+}
+
+void ExtensionSet::SerializeMessageSetWithCachedSizes(
+    io::CodedOutputStream* output) const {
+  for (map<int, Extension>::const_iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
+  }
+}
+
+int ExtensionSet::MessageSetByteSize() const {
+  int total_size = 0;
+
+  for (map<int, Extension>::const_iterator iter = extensions_.begin();
+       iter != extensions_.end(); ++iter) {
+    total_size += iter->second.MessageSetItemByteSize(iter->first);
+  }
+
+  return total_size;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/extension_set_unittest.cc b/protobuf/src/google/protobuf/extension_set_unittest.cc
new file mode 100644
index 0000000..8a00baf
--- /dev/null
+++ b/protobuf/src/google/protobuf/extension_set_unittest.cc
@@ -0,0 +1,1095 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/unittest_mset.pb.h>
+#include <google/protobuf/test_util.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/coded_stream.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/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/stl_util.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));
+
+  // Make sure setting stuff again after clearing works.  (This takes slightly
+  // different code paths since the objects are reused.)
+  TestUtil::SetAllExtensions(&message);
+  TestUtil::ExpectAllExtensionsSet(message);
+}
+
+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, SetAllocatedExtension) {
+  unittest::TestAllExtensions message;
+  EXPECT_FALSE(message.HasExtension(
+      unittest::optional_foreign_message_extension));
+  // Add a extension using SetAllocatedExtension
+  unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
+  message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
+                                foreign_message);
+  EXPECT_TRUE(message.HasExtension(
+      unittest::optional_foreign_message_extension));
+  EXPECT_EQ(foreign_message,
+            message.MutableExtension(
+                unittest::optional_foreign_message_extension));
+  EXPECT_EQ(foreign_message,
+            &message.GetExtension(
+                unittest::optional_foreign_message_extension));
+
+  // SetAllocatedExtension should delete the previously existing extension.
+  // (We reply on unittest to check memory leaks for this case)
+  message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
+                                new unittest::ForeignMessage());
+
+  // SetAllocatedExtension with a NULL parameter is equivalent to ClearExtenion.
+  message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
+                                NULL);
+  EXPECT_FALSE(message.HasExtension(
+      unittest::optional_foreign_message_extension));
+}
+
+TEST(ExtensionSetTest, ReleaseExtension) {
+  unittest::TestMessageSet message;
+  EXPECT_FALSE(message.HasExtension(
+      unittest::TestMessageSetExtension1::message_set_extension));
+  // Add a extension using SetAllocatedExtension
+  unittest::TestMessageSetExtension1* extension =
+      new unittest::TestMessageSetExtension1();
+  message.SetAllocatedExtension(
+      unittest::TestMessageSetExtension1::message_set_extension,
+      extension);
+  EXPECT_TRUE(message.HasExtension(
+      unittest::TestMessageSetExtension1::message_set_extension));
+  // Release the extension using ReleaseExtension
+  unittest::TestMessageSetExtension1* released_extension =
+      message.ReleaseExtension(
+          unittest::TestMessageSetExtension1::message_set_extension);
+  EXPECT_EQ(extension, released_extension);
+  EXPECT_FALSE(message.HasExtension(
+      unittest::TestMessageSetExtension1::message_set_extension));
+  // ReleaseExtension will return the underlying object even after
+  // ClearExtension is called.
+  message.SetAllocatedExtension(
+      unittest::TestMessageSetExtension1::message_set_extension,
+      extension);
+  message.ClearExtension(
+      unittest::TestMessageSetExtension1::message_set_extension);
+  released_extension = message.ReleaseExtension(
+      unittest::TestMessageSetExtension1::message_set_extension);
+  EXPECT_TRUE(released_extension != NULL);
+  delete released_extension;
+}
+
+
+TEST(ExtensionSetTest, CopyFrom) {
+  unittest::TestAllExtensions message1, message2;
+
+  TestUtil::SetAllExtensions(&message1);
+  message2.CopyFrom(message1);
+  TestUtil::ExpectAllExtensionsSet(message2);
+  message2.CopyFrom(message1);  // exercise copy when fields already exist
+  TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensioSetTest, CopyFromPacked) {
+  unittest::TestPackedExtensions message1, message2;
+
+  TestUtil::SetPackedExtensions(&message1);
+  message2.CopyFrom(message1);
+  TestUtil::ExpectPackedExtensionsSet(message2);
+  message2.CopyFrom(message1);  // exercise copy when fields already exist
+  TestUtil::ExpectPackedExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, CopyFromUpcasted) {
+  unittest::TestAllExtensions message1, message2;
+  const Message& upcasted_message = message1;
+
+  TestUtil::SetAllExtensions(&message1);
+  message2.CopyFrom(upcasted_message);
+  TestUtil::ExpectAllExtensionsSet(message2);
+  // exercise copy when fields already exist
+  message2.CopyFrom(upcasted_message);
+  TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, SwapWithEmpty) {
+  unittest::TestAllExtensions message1, message2;
+  TestUtil::SetAllExtensions(&message1);
+
+  TestUtil::ExpectAllExtensionsSet(message1);
+  TestUtil::ExpectExtensionsClear(message2);
+  message1.Swap(&message2);
+  TestUtil::ExpectAllExtensionsSet(message2);
+  TestUtil::ExpectExtensionsClear(message1);
+}
+
+TEST(ExtensionSetTest, SwapWithSelf) {
+  unittest::TestAllExtensions message;
+  TestUtil::SetAllExtensions(&message);
+
+  TestUtil::ExpectAllExtensionsSet(message);
+  message.Swap(&message);
+  TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ExtensionSetTest, SwapExtension) {
+  unittest::TestAllExtensions message1;
+  unittest::TestAllExtensions message2;
+
+  TestUtil::SetAllExtensions(&message1);
+  vector<const FieldDescriptor*> fields;
+
+  // Swap empty fields.
+  const Reflection* reflection = message1.GetReflection();
+  reflection->SwapFields(&message1, &message2, fields);
+  TestUtil::ExpectAllExtensionsSet(message1);
+  TestUtil::ExpectExtensionsClear(message2);
+
+  // Swap two extensions.
+  fields.push_back(
+      reflection->FindKnownExtensionByNumber(12));
+  fields.push_back(
+      reflection->FindKnownExtensionByNumber(25));
+  reflection->SwapFields(&message1, &message2, fields);
+
+  EXPECT_TRUE(message1.HasExtension(unittest::optional_int32_extension));
+  EXPECT_FALSE(message1.HasExtension(unittest::optional_double_extension));
+  EXPECT_FALSE(message1.HasExtension(unittest::optional_cord_extension));
+
+  EXPECT_FALSE(message2.HasExtension(unittest::optional_int32_extension));
+  EXPECT_TRUE(message2.HasExtension(unittest::optional_double_extension));
+  EXPECT_TRUE(message2.HasExtension(unittest::optional_cord_extension));
+}
+
+TEST(ExtensionSetTest, SwapExtensionWithEmpty) {
+  unittest::TestAllExtensions message1;
+  unittest::TestAllExtensions message2;
+  unittest::TestAllExtensions message3;
+
+  TestUtil::SetAllExtensions(&message3);
+
+  const Reflection* reflection = message3.GetReflection();
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(message3, &fields);
+
+  reflection->SwapFields(&message1, &message2, fields);
+
+  TestUtil::ExpectExtensionsClear(message1);
+  TestUtil::ExpectExtensionsClear(message2);
+}
+
+TEST(ExtensionSetTest, SwapExtensionBothFull) {
+  unittest::TestAllExtensions message1;
+  unittest::TestAllExtensions message2;
+
+  TestUtil::SetAllExtensions(&message1);
+  TestUtil::SetAllExtensions(&message2);
+
+  const Reflection* reflection = message1.GetReflection();
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(message1, &fields);
+
+  reflection->SwapFields(&message1, &message2, fields);
+
+  TestUtil::ExpectAllExtensionsSet(message1);
+  TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ExtensionSetTest, SwapExtensionWithSelf) {
+  unittest::TestAllExtensions message1;
+
+  TestUtil::SetAllExtensions(&message1);
+
+  vector<const FieldDescriptor*> fields;
+  const Reflection* reflection = message1.GetReflection();
+  reflection->ListFields(message1, &fields);
+  reflection->SwapFields(&message1, &message1, fields);
+
+  TestUtil::ExpectAllExtensionsSet(message1);
+}
+
+TEST(ExtensionSetTest, SerializationToArray) {
+  // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
+  // compatibility of extensions.
+  //
+  // This checks serialization to a flat array by explicitly reserving space in
+  // the string and calling the generated message's
+  // SerializeWithCachedSizesToArray.
+  unittest::TestAllExtensions source;
+  unittest::TestAllTypes destination;
+  TestUtil::SetAllExtensions(&source);
+  int size = source.ByteSize();
+  string data;
+  data.resize(size);
+  uint8* target = reinterpret_cast<uint8*>(string_as_array(&data));
+  uint8* end = source.SerializeWithCachedSizesToArray(target);
+  EXPECT_EQ(size, end - target);
+  EXPECT_TRUE(destination.ParseFromString(data));
+  TestUtil::ExpectAllFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, SerializationToStream) {
+  // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
+  // compatibility of extensions.
+  //
+  // This checks serialization to an output stream by creating an array output
+  // stream that can only buffer 1 byte at a time - this prevents the message
+  // from ever jumping to the fast path, ensuring that serialization happens via
+  // the CodedOutputStream.
+  unittest::TestAllExtensions source;
+  unittest::TestAllTypes destination;
+  TestUtil::SetAllExtensions(&source);
+  int size = source.ByteSize();
+  string data;
+  data.resize(size);
+  {
+    io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+    io::CodedOutputStream output_stream(&array_stream);
+    source.SerializeWithCachedSizes(&output_stream);
+    ASSERT_FALSE(output_stream.HadError());
+  }
+  EXPECT_TRUE(destination.ParseFromString(data));
+  TestUtil::ExpectAllFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedSerializationToArray) {
+  // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
+  // wire compatibility of extensions.
+  //
+  // This checks serialization to a flat array by explicitly reserving space in
+  // the string and calling the generated message's
+  // SerializeWithCachedSizesToArray.
+  unittest::TestPackedExtensions source;
+  unittest::TestPackedTypes destination;
+  TestUtil::SetPackedExtensions(&source);
+  int size = source.ByteSize();
+  string data;
+  data.resize(size);
+  uint8* target = reinterpret_cast<uint8*>(string_as_array(&data));
+  uint8* end = source.SerializeWithCachedSizesToArray(target);
+  EXPECT_EQ(size, end - target);
+  EXPECT_TRUE(destination.ParseFromString(data));
+  TestUtil::ExpectPackedFieldsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedSerializationToStream) {
+  // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
+  // wire compatibility of extensions.
+  //
+  // This checks serialization to an output stream by creating an array output
+  // stream that can only buffer 1 byte at a time - this prevents the message
+  // from ever jumping to the fast path, ensuring that serialization happens via
+  // the CodedOutputStream.
+  unittest::TestPackedExtensions source;
+  unittest::TestPackedTypes destination;
+  TestUtil::SetPackedExtensions(&source);
+  int size = source.ByteSize();
+  string data;
+  data.resize(size);
+  {
+    io::ArrayOutputStream array_stream(string_as_array(&data), size, 1);
+    io::CodedOutputStream output_stream(&array_stream);
+    source.SerializeWithCachedSizes(&output_stream);
+    ASSERT_FALSE(output_stream.HadError());
+  }
+  EXPECT_TRUE(destination.ParseFromString(data));
+  TestUtil::ExpectPackedFieldsSet(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::SetOneofFields(&destination);
+  TestUtil::ExpectAllExtensionsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedParsing) {
+  // Serialize as TestPackedTypes and parse as TestPackedExtensions.
+  unittest::TestPackedTypes source;
+  unittest::TestPackedExtensions destination;
+  string data;
+
+  TestUtil::SetPackedFields(&source);
+  source.SerializeToString(&data);
+  EXPECT_TRUE(destination.ParseFromString(data));
+  TestUtil::ExpectPackedExtensionsSet(destination);
+}
+
+TEST(ExtensionSetTest, PackedToUnpackedParsing) {
+  unittest::TestPackedTypes source;
+  unittest::TestUnpackedExtensions destination;
+  string data;
+
+  TestUtil::SetPackedFields(&source);
+  source.SerializeToString(&data);
+  EXPECT_TRUE(destination.ParseFromString(data));
+  TestUtil::ExpectUnpackedExtensionsSet(destination);
+
+  // Reserialize
+  unittest::TestUnpackedTypes unpacked;
+  TestUtil::SetUnpackedFields(&unpacked);
+  EXPECT_TRUE(unpacked.SerializeAsString() == destination.SerializeAsString());
+
+  // Make sure we can add extensions.
+  destination.AddExtension(unittest::unpacked_int32_extension, 1);
+  destination.AddExtension(unittest::unpacked_enum_extension,
+                           protobuf_unittest::FOREIGN_BAR);
+}
+
+TEST(ExtensionSetTest, UnpackedToPackedParsing) {
+  unittest::TestUnpackedTypes source;
+  unittest::TestPackedExtensions destination;
+  string data;
+
+  TestUtil::SetUnpackedFields(&source);
+  source.SerializeToString(&data);
+  EXPECT_TRUE(destination.ParseFromString(data));
+  TestUtil::ExpectPackedExtensionsSet(destination);
+
+  // Reserialize
+  unittest::TestPackedTypes packed;
+  TestUtil::SetPackedFields(&packed);
+  EXPECT_TRUE(packed.SerializeAsString() == destination.SerializeAsString());
+
+  // Make sure we can add extensions.
+  destination.AddExtension(unittest::packed_int32_extension, 1);
+  destination.AddExtension(unittest::packed_enum_extension,
+                           protobuf_unittest::FOREIGN_BAR);
+}
+
+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));
+}
+
+TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
+  // Scalar primitive extensions should increase the extension set size by a
+  // minimum of the size of the primitive type.
+#define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value)                        \
+  do {                                                                        \
+    unittest::TestAllExtensions message;                                      \
+    const int base_size = message.SpaceUsed();                                \
+    message.SetExtension(unittest::optional_##type##_extension, value);       \
+    int min_expected_size = base_size +                                       \
+        sizeof(message.GetExtension(unittest::optional_##type##_extension));  \
+    EXPECT_LE(min_expected_size, message.SpaceUsed());                        \
+  } while (0)
+
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(int32   , 101);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(int64   , 102);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(uint32  , 103);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(uint64  , 104);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(sint32  , 105);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(sint64  , 106);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed32 , 107);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed64 , 108);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed32, 109);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed64, 110);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(float   , 111);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(double  , 112);
+  TEST_SCALAR_EXTENSIONS_SPACE_USED(bool    , true);
+#undef TEST_SCALAR_EXTENSIONS_SPACE_USED
+  {
+    unittest::TestAllExtensions message;
+    const int base_size = message.SpaceUsed();
+    message.SetExtension(unittest::optional_nested_enum_extension,
+                         unittest::TestAllTypes::FOO);
+    int min_expected_size = base_size +
+        sizeof(message.GetExtension(unittest::optional_nested_enum_extension));
+    EXPECT_LE(min_expected_size, message.SpaceUsed());
+  }
+  {
+    // Strings may cause extra allocations depending on their length; ensure
+    // that gets included as well.
+    unittest::TestAllExtensions message;
+    const int base_size = message.SpaceUsed();
+    const string s("this is a fairly large string that will cause some "
+                   "allocation in order to store it in the extension");
+    message.SetExtension(unittest::optional_string_extension, s);
+    int min_expected_size = base_size + s.length();
+    EXPECT_LE(min_expected_size, message.SpaceUsed());
+  }
+  {
+    // Messages also have additional allocation that need to be counted.
+    unittest::TestAllExtensions message;
+    const int base_size = message.SpaceUsed();
+    unittest::ForeignMessage foreign;
+    foreign.set_c(42);
+    message.MutableExtension(unittest::optional_foreign_message_extension)->
+        CopyFrom(foreign);
+    int min_expected_size = base_size + foreign.SpaceUsed();
+    EXPECT_LE(min_expected_size, message.SpaceUsed());
+  }
+
+  // Repeated primitive extensions will increase space used by at least a
+  // RepeatedField<T>, and will cause additional allocations when the array
+  // gets too big for the initial space.
+  // This macro:
+  //   - Adds a value to the repeated extension, then clears it, establishing
+  //     the base size.
+  //   - Adds a small number of values, testing that it doesn't increase the
+  //     SpaceUsed()
+  //   - Adds a large number of values (requiring allocation in the repeated
+  //     field), and ensures that that allocation is included in SpaceUsed()
+#define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value)              \
+  do {                                                                         \
+    unittest::TestAllExtensions message;                                       \
+    const int base_size = message.SpaceUsed();                                 \
+    int min_expected_size = sizeof(RepeatedField<cpptype>) + base_size;        \
+    message.AddExtension(unittest::repeated_##type##_extension, value);        \
+    message.ClearExtension(unittest::repeated_##type##_extension);             \
+    const int empty_repeated_field_size = message.SpaceUsed();                 \
+    EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type;          \
+    message.AddExtension(unittest::repeated_##type##_extension, value);        \
+    message.AddExtension(unittest::repeated_##type##_extension, value);        \
+    EXPECT_EQ(empty_repeated_field_size, message.SpaceUsed()) << #type;        \
+    message.ClearExtension(unittest::repeated_##type##_extension);             \
+    for (int i = 0; i < 16; ++i) {                                             \
+      message.AddExtension(unittest::repeated_##type##_extension, value);      \
+    }                                                                          \
+    int expected_size = sizeof(cpptype) * (16 -                                \
+        kMinRepeatedFieldAllocationSize) + empty_repeated_field_size;          \
+    EXPECT_EQ(expected_size, message.SpaceUsed()) << #type;                    \
+  } while (0)
+
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(int32   , int32 , 101);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(int64   , int64 , 102);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(uint32  , uint32, 103);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(uint64  , uint64, 104);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(sint32  , int32 , 105);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(sint64  , int64 , 106);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed32 , uint32, 107);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed64 , uint64, 108);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed32, int32 , 109);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed64, int64 , 110);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(float   , float , 111);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(double  , double, 112);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(bool    , bool  , true);
+  TEST_REPEATED_EXTENSIONS_SPACE_USED(nested_enum, int,
+                                      unittest::TestAllTypes::FOO);
+#undef TEST_REPEATED_EXTENSIONS_SPACE_USED
+  // Repeated strings
+  {
+    unittest::TestAllExtensions message;
+    const int base_size = message.SpaceUsed();
+    int min_expected_size = sizeof(RepeatedPtrField<string>) + base_size;
+    const string value(256, 'x');
+    // Once items are allocated, they may stick around even when cleared so
+    // without the hardcore memory management accessors there isn't a notion of
+    // the empty repeated field memory usage as there is with primitive types.
+    for (int i = 0; i < 16; ++i) {
+      message.AddExtension(unittest::repeated_string_extension, value);
+    }
+    min_expected_size += (sizeof(value) + value.size()) *
+        (16 - kMinRepeatedFieldAllocationSize);
+    EXPECT_LE(min_expected_size, message.SpaceUsed());
+  }
+  // Repeated messages
+  {
+    unittest::TestAllExtensions message;
+    const int base_size = message.SpaceUsed();
+    int min_expected_size = sizeof(RepeatedPtrField<unittest::ForeignMessage>) +
+        base_size;
+    unittest::ForeignMessage prototype;
+    prototype.set_c(2);
+    for (int i = 0; i < 16; ++i) {
+      message.AddExtension(unittest::repeated_foreign_message_extension)->
+          CopyFrom(prototype);
+    }
+    min_expected_size +=
+        (16 - kMinRepeatedFieldAllocationSize) * prototype.SpaceUsed();
+    EXPECT_LE(min_expected_size, message.SpaceUsed());
+  }
+}
+
+// N.B.: We do not test range-based for here because we remain C++03 compatible.
+template<typename T, typename M, typename ID>
+inline T SumAllExtensions(const M& message, ID extension, T zero) {
+  T sum = zero;
+  typename RepeatedField<T>::const_iterator iter =
+      message.GetRepeatedExtension(extension).begin();
+  typename RepeatedField<T>::const_iterator end =
+      message.GetRepeatedExtension(extension).end();
+  for (; iter != end; ++iter) {
+    sum += *iter;
+  }
+  return sum;
+}
+
+template<typename T, typename M, typename ID>
+inline void IncAllExtensions(M* message, ID extension,
+                          T val) {
+  typename RepeatedField<T>::iterator iter =
+      message->MutableRepeatedExtension(extension)->begin();
+  typename RepeatedField<T>::iterator end  =
+      message->MutableRepeatedExtension(extension)->end();
+  for (; iter != end; ++iter) {
+    *iter += val;
+  }
+}
+
+TEST(ExtensionSetTest, RepeatedFields) {
+  unittest::TestAllExtensions message;
+
+  // Test empty repeated-field case (b/12926163)
+  ASSERT_EQ(0, message.GetRepeatedExtension(
+      unittest::repeated_int32_extension).size());
+  ASSERT_EQ(0, message.GetRepeatedExtension(
+      unittest::repeated_nested_enum_extension).size());
+  ASSERT_EQ(0, message.GetRepeatedExtension(
+      unittest::repeated_string_extension).size());
+  ASSERT_EQ(0, message.GetRepeatedExtension(
+      unittest::repeated_nested_message_extension).size());
+
+  unittest::TestAllTypes::NestedMessage nested_message;
+  nested_message.set_bb(42);
+  unittest::TestAllTypes::NestedEnum nested_enum =
+      unittest::TestAllTypes::NestedEnum_MIN;
+
+  for (int i = 0; i < 10; ++i) {
+    message.AddExtension(unittest::repeated_int32_extension, 1);
+    message.AddExtension(unittest::repeated_int64_extension, 2);
+    message.AddExtension(unittest::repeated_uint32_extension, 3);
+    message.AddExtension(unittest::repeated_uint64_extension, 4);
+    message.AddExtension(unittest::repeated_sint32_extension, 5);
+    message.AddExtension(unittest::repeated_sint64_extension, 6);
+    message.AddExtension(unittest::repeated_fixed32_extension, 7);
+    message.AddExtension(unittest::repeated_fixed64_extension, 8);
+    message.AddExtension(unittest::repeated_sfixed32_extension, 7);
+    message.AddExtension(unittest::repeated_sfixed64_extension, 8);
+    message.AddExtension(unittest::repeated_float_extension, 9.0);
+    message.AddExtension(unittest::repeated_double_extension, 10.0);
+    message.AddExtension(unittest::repeated_bool_extension, true);
+    message.AddExtension(unittest::repeated_nested_enum_extension, nested_enum);
+    message.AddExtension(unittest::repeated_string_extension,
+                         ::std::string("test"));
+    message.AddExtension(unittest::repeated_bytes_extension,
+                         ::std::string("test\xFF"));
+    message.AddExtension(
+        unittest::repeated_nested_message_extension)->CopyFrom(nested_message);
+    message.AddExtension(unittest::repeated_nested_enum_extension,
+                         nested_enum);
+  }
+
+  ASSERT_EQ(10, SumAllExtensions<int32>(
+      message, unittest::repeated_int32_extension, 0));
+  IncAllExtensions<int32>(
+      &message, unittest::repeated_int32_extension, 1);
+  ASSERT_EQ(20, SumAllExtensions<int32>(
+      message, unittest::repeated_int32_extension, 0));
+
+  ASSERT_EQ(20, SumAllExtensions<int64>(
+      message, unittest::repeated_int64_extension, 0));
+  IncAllExtensions<int64>(
+      &message, unittest::repeated_int64_extension, 1);
+  ASSERT_EQ(30, SumAllExtensions<int64>(
+      message, unittest::repeated_int64_extension, 0));
+
+  ASSERT_EQ(30, SumAllExtensions<uint32>(
+      message, unittest::repeated_uint32_extension, 0));
+  IncAllExtensions<uint32>(
+      &message, unittest::repeated_uint32_extension, 1);
+  ASSERT_EQ(40, SumAllExtensions<uint32>(
+      message, unittest::repeated_uint32_extension, 0));
+
+  ASSERT_EQ(40, SumAllExtensions<uint64>(
+      message, unittest::repeated_uint64_extension, 0));
+  IncAllExtensions<uint64>(
+      &message, unittest::repeated_uint64_extension, 1);
+  ASSERT_EQ(50, SumAllExtensions<uint64>(
+      message, unittest::repeated_uint64_extension, 0));
+
+  ASSERT_EQ(50, SumAllExtensions<int32>(
+      message, unittest::repeated_sint32_extension, 0));
+  IncAllExtensions<int32>(
+      &message, unittest::repeated_sint32_extension, 1);
+  ASSERT_EQ(60, SumAllExtensions<int32>(
+      message, unittest::repeated_sint32_extension, 0));
+
+  ASSERT_EQ(60, SumAllExtensions<int64>(
+      message, unittest::repeated_sint64_extension, 0));
+  IncAllExtensions<int64>(
+      &message, unittest::repeated_sint64_extension, 1);
+  ASSERT_EQ(70, SumAllExtensions<int64>(
+      message, unittest::repeated_sint64_extension, 0));
+
+  ASSERT_EQ(70, SumAllExtensions<uint32>(
+      message, unittest::repeated_fixed32_extension, 0));
+  IncAllExtensions<uint32>(
+      &message, unittest::repeated_fixed32_extension, 1);
+  ASSERT_EQ(80, SumAllExtensions<uint32>(
+      message, unittest::repeated_fixed32_extension, 0));
+
+  ASSERT_EQ(80, SumAllExtensions<uint64>(
+      message, unittest::repeated_fixed64_extension, 0));
+  IncAllExtensions<uint64>(
+      &message, unittest::repeated_fixed64_extension, 1);
+  ASSERT_EQ(90, SumAllExtensions<uint64>(
+      message, unittest::repeated_fixed64_extension, 0));
+
+  // Usually, floating-point arithmetic cannot be trusted to be exact, so it is
+  // a Bad Idea to assert equality in a test like this. However, we're dealing
+  // with integers with a small number of significant mantissa bits, so we
+  // should actually have exact precision here.
+  ASSERT_EQ(90, SumAllExtensions<float>(
+      message, unittest::repeated_float_extension, 0));
+  IncAllExtensions<float>(
+      &message, unittest::repeated_float_extension, 1);
+  ASSERT_EQ(100, SumAllExtensions<float>(
+      message, unittest::repeated_float_extension, 0));
+
+  ASSERT_EQ(100, SumAllExtensions<double>(
+      message, unittest::repeated_double_extension, 0));
+  IncAllExtensions<double>(
+      &message, unittest::repeated_double_extension, 1);
+  ASSERT_EQ(110, SumAllExtensions<double>(
+      message, unittest::repeated_double_extension, 0));
+
+  RepeatedPtrField< ::std::string>::iterator string_iter;
+  RepeatedPtrField< ::std::string>::iterator string_end;
+  for (string_iter = message.MutableRepeatedExtension(
+          unittest::repeated_string_extension)->begin(),
+       string_end  = message.MutableRepeatedExtension(
+           unittest::repeated_string_extension)->end();
+       string_iter != string_end; ++string_iter) {
+    *string_iter += "test";
+  }
+  RepeatedPtrField< ::std::string>::const_iterator string_const_iter;
+  RepeatedPtrField< ::std::string>::const_iterator string_const_end;
+  for (string_const_iter = message.GetRepeatedExtension(
+           unittest::repeated_string_extension).begin(),
+       string_const_end  = message.GetRepeatedExtension(
+           unittest::repeated_string_extension).end();
+       string_iter != string_end; ++string_iter) {
+    ASSERT_TRUE(*string_iter == "testtest");
+  }
+
+  RepeatedField<unittest::TestAllTypes_NestedEnum>::iterator enum_iter;
+  RepeatedField<unittest::TestAllTypes_NestedEnum>::iterator enum_end;
+  for (enum_iter = message.MutableRepeatedExtension(
+           unittest::repeated_nested_enum_extension)->begin(),
+       enum_end  = message.MutableRepeatedExtension(
+           unittest::repeated_nested_enum_extension)->end();
+       enum_iter != enum_end; ++enum_iter) {
+    *enum_iter = unittest::TestAllTypes::NestedEnum_MAX;
+  }
+  RepeatedField<unittest::TestAllTypes_NestedEnum>::const_iterator
+      enum_const_iter;
+  RepeatedField<unittest::TestAllTypes_NestedEnum>::const_iterator
+      enum_const_end;
+  for (enum_const_iter = message.GetRepeatedExtension(
+           unittest::repeated_nested_enum_extension).begin(),
+       enum_const_end  = message.GetRepeatedExtension(
+           unittest::repeated_nested_enum_extension).end();
+       enum_iter != enum_end; ++enum_iter) {
+    ASSERT_EQ(*enum_const_iter, unittest::TestAllTypes::NestedEnum_MAX);
+  }
+
+  RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::iterator
+      msg_iter;
+  RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::iterator
+      msg_end;
+  for (msg_iter = message.MutableRepeatedExtension(
+           unittest::repeated_nested_message_extension)->begin(),
+       msg_end  = message.MutableRepeatedExtension(
+           unittest::repeated_nested_message_extension)->end();
+       msg_iter != msg_end; ++msg_iter) {
+    msg_iter->set_bb(1234);
+  }
+  RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::
+      const_iterator msg_const_iter;
+  RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::
+      const_iterator msg_const_end;
+  for (msg_const_iter = message.GetRepeatedExtension(
+           unittest::repeated_nested_message_extension).begin(),
+       msg_const_end  = message.GetRepeatedExtension(
+           unittest::repeated_nested_message_extension).end();
+       msg_const_iter != msg_const_end; ++msg_const_iter) {
+    ASSERT_EQ(msg_const_iter->bb(), 1234);
+  }
+
+  // Test range-based for as well, but only if compiled as C++11.
+#if __cplusplus >= 201103L
+  // Test one primitive field.
+  for (auto& x : *message.MutableRepeatedExtension(
+          unittest::repeated_int32_extension)) {
+    x = 4321;
+  }
+  for (const auto& x : message.GetRepeatedExtension(
+          unittest::repeated_int32_extension)) {
+    ASSERT_EQ(x, 4321);
+  }
+  // Test one string field.
+  for (auto& x : *message.MutableRepeatedExtension(
+          unittest::repeated_string_extension)) {
+    x = "test_range_based_for";
+  }
+  for (const auto& x : message.GetRepeatedExtension(
+          unittest::repeated_string_extension)) {
+    ASSERT_TRUE(x == "test_range_based_for");
+  }
+  // Test one message field.
+  for (auto& x : *message.MutableRepeatedExtension(
+          unittest::repeated_nested_message_extension)) {
+    x.set_bb(4321);
+  }
+  for (const auto& x : *message.MutableRepeatedExtension(
+          unittest::repeated_nested_message_extension)) {
+    ASSERT_EQ(x.bb(), 4321);
+  }
+#endif
+}
+
+// From b/12926163
+TEST(ExtensionSetTest, AbsentExtension) {
+  unittest::TestAllExtensions message;
+  message.MutableRepeatedExtension(unittest::repeated_nested_message_extension)
+      ->Add()->set_bb(123);
+  ASSERT_EQ(1, message.ExtensionSize(
+      unittest::repeated_nested_message_extension));
+  EXPECT_EQ(
+      123, message.GetExtension(
+          unittest::repeated_nested_message_extension, 0).bb());
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+
+TEST(ExtensionSetTest, InvalidEnumDeath) {
+  unittest::TestAllExtensions message;
+  EXPECT_DEBUG_DEATH(
+    message.SetExtension(unittest::optional_foreign_enum_extension,
+                         static_cast<unittest::ForeignEnum>(53)),
+    "IsValid");
+}
+
+#endif  // PROTOBUF_HAS_DEATH_TEST
+
+TEST(ExtensionSetTest, DynamicExtensions) {
+  // Test adding a dynamic extension to a compiled-in message object.
+
+  FileDescriptorProto dynamic_proto;
+  dynamic_proto.set_name("dynamic_extensions_test.proto");
+  dynamic_proto.add_dependency(
+      unittest::TestAllExtensions::descriptor()->file()->name());
+  dynamic_proto.set_package("dynamic_extensions");
+
+  // Copy the fields and nested types from TestDynamicExtensions into our new
+  // proto, converting the fields into extensions.
+  const Descriptor* template_descriptor =
+      unittest::TestDynamicExtensions::descriptor();
+  DescriptorProto template_descriptor_proto;
+  template_descriptor->CopyTo(&template_descriptor_proto);
+  dynamic_proto.mutable_message_type()->MergeFrom(
+      template_descriptor_proto.nested_type());
+  dynamic_proto.mutable_enum_type()->MergeFrom(
+      template_descriptor_proto.enum_type());
+  dynamic_proto.mutable_extension()->MergeFrom(
+      template_descriptor_proto.field());
+
+  // For each extension that we added...
+  for (int i = 0; i < dynamic_proto.extension_size(); i++) {
+    // Set its extendee to TestAllExtensions.
+    FieldDescriptorProto* extension = dynamic_proto.mutable_extension(i);
+    extension->set_extendee(
+        unittest::TestAllExtensions::descriptor()->full_name());
+
+    // If the field refers to one of the types nested in TestDynamicExtensions,
+    // make it refer to the type in our dynamic proto instead.
+    string prefix = "." + template_descriptor->full_name() + ".";
+    if (extension->has_type_name()) {
+      string* type_name = extension->mutable_type_name();
+      if (HasPrefixString(*type_name, prefix)) {
+        type_name->replace(0, prefix.size(), ".dynamic_extensions.");
+      }
+    }
+  }
+
+  // Now build the file, using the generated pool as an underlay.
+  DescriptorPool dynamic_pool(DescriptorPool::generated_pool());
+  const FileDescriptor* file = dynamic_pool.BuildFile(dynamic_proto);
+  ASSERT_TRUE(file != NULL);
+  DynamicMessageFactory dynamic_factory(&dynamic_pool);
+  dynamic_factory.SetDelegateToGeneratedFactory(true);
+
+  // Construct a message that we can parse with the extensions we defined.
+  // Since the extensions were based off of the fields of TestDynamicExtensions,
+  // we can use that message to create this test message.
+  string data;
+  {
+    unittest::TestDynamicExtensions message;
+    message.set_scalar_extension(123);
+    message.set_enum_extension(unittest::FOREIGN_BAR);
+    message.set_dynamic_enum_extension(
+        unittest::TestDynamicExtensions::DYNAMIC_BAZ);
+    message.mutable_message_extension()->set_c(456);
+    message.mutable_dynamic_message_extension()->set_dynamic_field(789);
+    message.add_repeated_extension("foo");
+    message.add_repeated_extension("bar");
+    message.add_packed_extension(12);
+    message.add_packed_extension(-34);
+    message.add_packed_extension(56);
+    message.add_packed_extension(-78);
+
+    // Also add some unknown fields.
+
+    // An unknown enum value (for a known field).
+    message.mutable_unknown_fields()->AddVarint(
+      unittest::TestDynamicExtensions::kDynamicEnumExtensionFieldNumber,
+      12345);
+    // A regular unknown field.
+    message.mutable_unknown_fields()->AddLengthDelimited(54321, "unknown");
+
+    message.SerializeToString(&data);
+  }
+
+  // Now we can parse this using our dynamic extension definitions...
+  unittest::TestAllExtensions message;
+  {
+    io::ArrayInputStream raw_input(data.data(), data.size());
+    io::CodedInputStream input(&raw_input);
+    input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
+    ASSERT_TRUE(message.ParseFromCodedStream(&input));
+    ASSERT_TRUE(input.ConsumedEntireMessage());
+  }
+
+  // Can we print it?
+  EXPECT_EQ(
+    "[dynamic_extensions.scalar_extension]: 123\n"
+    "[dynamic_extensions.enum_extension]: FOREIGN_BAR\n"
+    "[dynamic_extensions.dynamic_enum_extension]: DYNAMIC_BAZ\n"
+    "[dynamic_extensions.message_extension] {\n"
+    "  c: 456\n"
+    "}\n"
+    "[dynamic_extensions.dynamic_message_extension] {\n"
+    "  dynamic_field: 789\n"
+    "}\n"
+    "[dynamic_extensions.repeated_extension]: \"foo\"\n"
+    "[dynamic_extensions.repeated_extension]: \"bar\"\n"
+    "[dynamic_extensions.packed_extension]: 12\n"
+    "[dynamic_extensions.packed_extension]: -34\n"
+    "[dynamic_extensions.packed_extension]: 56\n"
+    "[dynamic_extensions.packed_extension]: -78\n"
+    "2002: 12345\n"
+    "54321: \"unknown\"\n",
+    message.DebugString());
+
+  // Can we serialize it?
+  // (Don't use EXPECT_EQ because we don't want to dump raw binary data to the
+  // terminal on failure.)
+  EXPECT_TRUE(message.SerializeAsString() == data);
+
+  // What if we parse using the reflection-based parser?
+  {
+    unittest::TestAllExtensions message2;
+    io::ArrayInputStream raw_input(data.data(), data.size());
+    io::CodedInputStream input(&raw_input);
+    input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
+    ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message2));
+    ASSERT_TRUE(input.ConsumedEntireMessage());
+    EXPECT_EQ(message.DebugString(), message2.DebugString());
+  }
+
+  // Are the embedded generated types actually using the generated objects?
+  {
+    const FieldDescriptor* message_extension =
+        file->FindExtensionByName("message_extension");
+    ASSERT_TRUE(message_extension != NULL);
+    const Message& sub_message =
+        message.GetReflection()->GetMessage(message, message_extension);
+    const unittest::ForeignMessage* typed_sub_message =
+#ifdef GOOGLE_PROTOBUF_NO_RTTI
+        static_cast<const unittest::ForeignMessage*>(&sub_message);
+#else
+        dynamic_cast<const unittest::ForeignMessage*>(&sub_message);
+#endif
+    ASSERT_TRUE(typed_sub_message != NULL);
+    EXPECT_EQ(456, typed_sub_message->c());
+  }
+
+  // What does GetMessage() return for the embedded dynamic type if it isn't
+  // present?
+  {
+    const FieldDescriptor* dynamic_message_extension =
+        file->FindExtensionByName("dynamic_message_extension");
+    ASSERT_TRUE(dynamic_message_extension != NULL);
+    const Message& parent = unittest::TestAllExtensions::default_instance();
+    const Message& sub_message =
+        parent.GetReflection()->GetMessage(parent, dynamic_message_extension,
+                                           &dynamic_factory);
+    const Message* prototype =
+        dynamic_factory.GetPrototype(dynamic_message_extension->message_type());
+    EXPECT_EQ(prototype, &sub_message);
+  }
+}
+
+}  // namespace
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/generated_enum_reflection.h b/protobuf/src/google/protobuf/generated_enum_reflection.h
new file mode 100644
index 0000000..3852cea
--- /dev/null
+++ b/protobuf/src/google/protobuf/generated_enum_reflection.h
@@ -0,0 +1,91 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jasonh@google.com (Jason Hsueh)
+//
+// This header is logically internal, but is made public because it is used
+// from protocol-compiler-generated code, which may reside in other components.
+// It provides reflection support for generated enums, and is included in
+// generated .pb.h files and should have minimal dependencies. The methods are
+// implemented in generated_message_reflection.cc.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
+#define GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
+
+#include <string>
+
+#include <google/protobuf/stubs/template_util.h>
+
+namespace google {
+namespace protobuf {
+  class EnumDescriptor;
+}  // namespace protobuf
+
+namespace protobuf {
+
+// This type trait can be used to cause templates to only match proto2 enum
+// types.
+template <typename T> struct is_proto_enum : ::google::protobuf::internal::false_type {};
+
+// Returns the EnumDescriptor for enum type E, which must be a
+// proto-declared enum type.  Code generated by the protocol compiler
+// will include specializations of this template for each enum type declared.
+template <typename E>
+const EnumDescriptor* GetEnumDescriptor();
+
+namespace internal {
+
+// Helper for EnumType_Parse functions: try to parse the string 'name' as an
+// enum name of the given type, returning true and filling in value on success,
+// or returning false and leaving value unchanged on failure.
+LIBPROTOBUF_EXPORT bool ParseNamedEnum(const EnumDescriptor* descriptor,
+                    const string& name,
+                    int* value);
+
+template<typename EnumType>
+bool ParseNamedEnum(const EnumDescriptor* descriptor,
+                    const string& name,
+                    EnumType* value) {
+  int tmp;
+  if (!ParseNamedEnum(descriptor, name, &tmp)) return false;
+  *value = static_cast<EnumType>(tmp);
+  return true;
+}
+
+// Just a wrapper around printing the name of a value. The main point of this
+// function is not to be inlined, so that you can do this without including
+// descriptor.h.
+LIBPROTOBUF_EXPORT const string& NameOfEnum(const EnumDescriptor* descriptor, int value);
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__
diff --git a/protobuf/src/google/protobuf/generated_message_reflection.cc b/protobuf/src/google/protobuf/generated_message_reflection.cc
new file mode 100644
index 0000000..536de7d
--- /dev/null
+++ b/protobuf/src/google/protobuf/generated_message_reflection.cc
@@ -0,0 +1,1683 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <algorithm>
+#include <set>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/stubs/common.h>
+
+#define GOOGLE_PROTOBUF_HAS_ONEOF
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+int StringSpaceUsedExcludingSelf(const string& str) {
+  const void* start = &str;
+  const void* end = &str + 1;
+
+  if (start <= str.data() && str.data() < end) {
+    // The string's data is stored inside the string object itself.
+    return 0;
+  } else {
+    return str.capacity();
+  }
+}
+
+bool ParseNamedEnum(const EnumDescriptor* descriptor,
+                    const string& name,
+                    int* value) {
+  const EnumValueDescriptor* d = descriptor->FindValueByName(name);
+  if (d == NULL) return false;
+  *value = d->number();
+  return true;
+}
+
+const string& NameOfEnum(const EnumDescriptor* descriptor, int value) {
+  const EnumValueDescriptor* d = descriptor->FindValueByNumber(value);
+  return (d == NULL ? GetEmptyString() : d->name());
+}
+
+// ===================================================================
+// 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::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::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::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,
+    const Message* default_instance,
+    const int offsets[],
+    int has_bits_offset,
+    int unknown_fields_offset,
+    int extensions_offset,
+    const DescriptorPool* descriptor_pool,
+    MessageFactory* factory,
+    int object_size)
+  : descriptor_       (descriptor),
+    default_instance_ (default_instance),
+    offsets_          (offsets),
+    has_bits_offset_  (has_bits_offset),
+    unknown_fields_offset_(unknown_fields_offset),
+    extensions_offset_(extensions_offset),
+    object_size_      (object_size),
+    descriptor_pool_  ((descriptor_pool == NULL) ?
+                         DescriptorPool::generated_pool() :
+                         descriptor_pool),
+    message_factory_  (factory) {
+}
+
+GeneratedMessageReflection::GeneratedMessageReflection(
+    const Descriptor* descriptor,
+    const Message* default_instance,
+    const int offsets[],
+    int has_bits_offset,
+    int unknown_fields_offset,
+    int extensions_offset,
+    const void* default_oneof_instance,
+    int oneof_case_offset,
+    const DescriptorPool* descriptor_pool,
+    MessageFactory* factory,
+    int object_size)
+  : descriptor_       (descriptor),
+    default_instance_ (default_instance),
+    default_oneof_instance_ (default_oneof_instance),
+    offsets_          (offsets),
+    has_bits_offset_  (has_bits_offset),
+    oneof_case_offset_(oneof_case_offset),
+    unknown_fields_offset_(unknown_fields_offset),
+    extensions_offset_(extensions_offset),
+    object_size_      (object_size),
+    descriptor_pool_  ((descriptor_pool == NULL) ?
+                         DescriptorPool::generated_pool() :
+                         descriptor_pool),
+    message_factory_  (factory) {
+}
+
+GeneratedMessageReflection::~GeneratedMessageReflection() {}
+
+const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
+    const Message& message) const {
+  const void* ptr = reinterpret_cast<const uint8*>(&message) +
+                    unknown_fields_offset_;
+  return *reinterpret_cast<const UnknownFieldSet*>(ptr);
+}
+UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
+    Message* message) const {
+  void* ptr = reinterpret_cast<uint8*>(message) + unknown_fields_offset_;
+  return reinterpret_cast<UnknownFieldSet*>(ptr);
+}
+
+int GeneratedMessageReflection::SpaceUsed(const Message& message) const {
+  // object_size_ already includes the in-memory representation of each field
+  // in the message, so we only need to account for additional memory used by
+  // the fields.
+  int total_size = object_size_;
+
+  total_size += GetUnknownFields(message).SpaceUsedExcludingSelf();
+
+  if (extensions_offset_ != -1) {
+    total_size += GetExtensionSet(message).SpaceUsedExcludingSelf();
+  }
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+
+    if (field->is_repeated()) {
+      switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
+        case FieldDescriptor::CPPTYPE_##UPPERCASE :                           \
+          total_size += GetRaw<RepeatedField<LOWERCASE> >(message, field)     \
+                          .SpaceUsedExcludingSelf();                          \
+          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);
+        HANDLE_TYPE(  ENUM,    int);
+#undef HANDLE_TYPE
+
+        case FieldDescriptor::CPPTYPE_STRING:
+          switch (field->options().ctype()) {
+            default:  // TODO(kenton):  Support other string reps.
+            case FieldOptions::STRING:
+              total_size += GetRaw<RepeatedPtrField<string> >(message, field)
+                              .SpaceUsedExcludingSelf();
+              break;
+          }
+          break;
+
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          // We don't know which subclass of RepeatedPtrFieldBase the type is,
+          // so we use RepeatedPtrFieldBase directly.
+          total_size +=
+              GetRaw<RepeatedPtrFieldBase>(message, field)
+                .SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
+          break;
+      }
+    } else {
+      if (field->containing_oneof() && !HasOneofField(message, field)) {
+        continue;
+      }
+      switch (field->cpp_type()) {
+        case FieldDescriptor::CPPTYPE_INT32 :
+        case FieldDescriptor::CPPTYPE_INT64 :
+        case FieldDescriptor::CPPTYPE_UINT32:
+        case FieldDescriptor::CPPTYPE_UINT64:
+        case FieldDescriptor::CPPTYPE_DOUBLE:
+        case FieldDescriptor::CPPTYPE_FLOAT :
+        case FieldDescriptor::CPPTYPE_BOOL  :
+        case FieldDescriptor::CPPTYPE_ENUM  :
+          // Field is inline, so we've already counted it.
+          break;
+
+        case FieldDescriptor::CPPTYPE_STRING: {
+          switch (field->options().ctype()) {
+            default:  // TODO(kenton):  Support other string reps.
+            case FieldOptions::STRING: {
+              const string* ptr = GetField<const string*>(message, field);
+
+              // Initially, the string points to the default value stored in
+              // the prototype. Only count the string if it has been changed
+              // from the default value.
+              const string* default_ptr = DefaultRaw<const string*>(field);
+
+              if (ptr != default_ptr) {
+                // string fields are represented by just a pointer, so also
+                // include sizeof(string) as well.
+                total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr);
+              }
+              break;
+            }
+          }
+          break;
+        }
+
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          if (&message == default_instance_) {
+            // For singular fields, the prototype just stores a pointer to the
+            // external type's prototype, so there is no extra memory usage.
+          } else {
+            const Message* sub_message = GetRaw<const Message*>(message, field);
+            if (sub_message != NULL) {
+              total_size += sub_message->SpaceUsed();
+            }
+          }
+          break;
+      }
+    }
+  }
+
+  return total_size;
+}
+
+void GeneratedMessageReflection::SwapField(
+    Message* message1,
+    Message* message2,
+    const FieldDescriptor* field) const {
+  if (field->is_repeated()) {
+    switch (field->cpp_type()) {
+#define SWAP_ARRAYS(CPPTYPE, TYPE)                                      \
+      case FieldDescriptor::CPPTYPE_##CPPTYPE:                          \
+        MutableRaw<RepeatedField<TYPE> >(message1, field)->Swap(        \
+            MutableRaw<RepeatedField<TYPE> >(message2, field));         \
+        break;
+
+      SWAP_ARRAYS(INT32 , int32 );
+      SWAP_ARRAYS(INT64 , int64 );
+      SWAP_ARRAYS(UINT32, uint32);
+      SWAP_ARRAYS(UINT64, uint64);
+      SWAP_ARRAYS(FLOAT , float );
+      SWAP_ARRAYS(DOUBLE, double);
+      SWAP_ARRAYS(BOOL  , bool  );
+      SWAP_ARRAYS(ENUM  , int   );
+#undef SWAP_ARRAYS
+
+      case FieldDescriptor::CPPTYPE_STRING:
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        MutableRaw<RepeatedPtrFieldBase>(message1, field)->Swap(
+            MutableRaw<RepeatedPtrFieldBase>(message2, field));
+        break;
+
+      default:
+        GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
+    }
+  } else {
+    switch (field->cpp_type()) {
+#define SWAP_VALUES(CPPTYPE, TYPE)                                      \
+      case FieldDescriptor::CPPTYPE_##CPPTYPE:                          \
+        std::swap(*MutableRaw<TYPE>(message1, field),                   \
+                  *MutableRaw<TYPE>(message2, field));                  \
+        break;
+
+      SWAP_VALUES(INT32 , int32 );
+      SWAP_VALUES(INT64 , int64 );
+      SWAP_VALUES(UINT32, uint32);
+      SWAP_VALUES(UINT64, uint64);
+      SWAP_VALUES(FLOAT , float );
+      SWAP_VALUES(DOUBLE, double);
+      SWAP_VALUES(BOOL  , bool  );
+      SWAP_VALUES(ENUM  , int   );
+#undef SWAP_VALUES
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        std::swap(*MutableRaw<Message*>(message1, field),
+                  *MutableRaw<Message*>(message2, field));
+        break;
+
+      case FieldDescriptor::CPPTYPE_STRING:
+        switch (field->options().ctype()) {
+          default:  // TODO(kenton):  Support other string reps.
+          case FieldOptions::STRING:
+            std::swap(*MutableRaw<string*>(message1, field),
+                      *MutableRaw<string*>(message2, field));
+            break;
+        }
+        break;
+
+      default:
+        GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
+    }
+  }
+}
+
+void GeneratedMessageReflection::SwapOneofField(
+    Message* message1,
+    Message* message2,
+    const OneofDescriptor* oneof_descriptor) const {
+  uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor);
+  uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor);
+
+  int32 temp_int32;
+  int64 temp_int64;
+  uint32 temp_uint32;
+  uint64 temp_uint64;
+  float temp_float;
+  double temp_double;
+  bool temp_bool;
+  int temp_int;
+  Message* temp_message;
+  string temp_string;
+
+  // Stores message1's oneof field to a temp variable.
+  const FieldDescriptor* field1;
+  if (oneof_case1 > 0) {
+    field1 = descriptor_->FindFieldByNumber(oneof_case1);
+    //oneof_descriptor->field(oneof_case1);
+    switch (field1->cpp_type()) {
+#define GET_TEMP_VALUE(CPPTYPE, TYPE)                                   \
+      case FieldDescriptor::CPPTYPE_##CPPTYPE:                          \
+        temp_##TYPE = GetField<TYPE>(*message1, field1);                \
+        break;
+
+      GET_TEMP_VALUE(INT32 , int32 );
+      GET_TEMP_VALUE(INT64 , int64 );
+      GET_TEMP_VALUE(UINT32, uint32);
+      GET_TEMP_VALUE(UINT64, uint64);
+      GET_TEMP_VALUE(FLOAT , float );
+      GET_TEMP_VALUE(DOUBLE, double);
+      GET_TEMP_VALUE(BOOL  , bool  );
+      GET_TEMP_VALUE(ENUM  , int   );
+#undef GET_TEMP_VALUE
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        temp_message = ReleaseMessage(message1, field1);
+        break;
+
+      case FieldDescriptor::CPPTYPE_STRING:
+        temp_string = GetString(*message1, field1);
+        break;
+
+      default:
+        GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
+    }
+  }
+
+  // Sets message1's oneof field from the message2's oneof field.
+  if (oneof_case2 > 0) {
+    const FieldDescriptor* field2 =
+        descriptor_->FindFieldByNumber(oneof_case2);
+    switch (field2->cpp_type()) {
+#define SET_ONEOF_VALUE1(CPPTYPE, TYPE)                                 \
+      case FieldDescriptor::CPPTYPE_##CPPTYPE:                          \
+        SetField<TYPE>(message1, field2, GetField<TYPE>(*message2, field2)); \
+        break;
+
+      SET_ONEOF_VALUE1(INT32 , int32 );
+      SET_ONEOF_VALUE1(INT64 , int64 );
+      SET_ONEOF_VALUE1(UINT32, uint32);
+      SET_ONEOF_VALUE1(UINT64, uint64);
+      SET_ONEOF_VALUE1(FLOAT , float );
+      SET_ONEOF_VALUE1(DOUBLE, double);
+      SET_ONEOF_VALUE1(BOOL  , bool  );
+      SET_ONEOF_VALUE1(ENUM  , int   );
+#undef SET_ONEOF_VALUE1
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        SetAllocatedMessage(message1,
+                            ReleaseMessage(message2, field2),
+                            field2);
+        break;
+
+      case FieldDescriptor::CPPTYPE_STRING:
+        SetString(message1, field2, GetString(*message2, field2));
+        break;
+
+      default:
+        GOOGLE_LOG(FATAL) << "Unimplemented type: " << field2->cpp_type();
+    }
+  } else {
+    ClearOneof(message1, oneof_descriptor);
+  }
+
+  // Sets message2's oneof field from the temp variable.
+  if (oneof_case1 > 0) {
+    switch (field1->cpp_type()) {
+#define SET_ONEOF_VALUE2(CPPTYPE, TYPE)                                 \
+      case FieldDescriptor::CPPTYPE_##CPPTYPE:                          \
+        SetField<TYPE>(message2, field1, temp_##TYPE);                  \
+        break;
+
+      SET_ONEOF_VALUE2(INT32 , int32 );
+      SET_ONEOF_VALUE2(INT64 , int64 );
+      SET_ONEOF_VALUE2(UINT32, uint32);
+      SET_ONEOF_VALUE2(UINT64, uint64);
+      SET_ONEOF_VALUE2(FLOAT , float );
+      SET_ONEOF_VALUE2(DOUBLE, double);
+      SET_ONEOF_VALUE2(BOOL  , bool  );
+      SET_ONEOF_VALUE2(ENUM  , int   );
+#undef SET_ONEOF_VALUE2
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        SetAllocatedMessage(message2, temp_message, field1);
+        break;
+
+      case FieldDescriptor::CPPTYPE_STRING:
+        SetString(message2, field1, temp_string);
+        break;
+
+      default:
+        GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
+    }
+  } else {
+    ClearOneof(message2, oneof_descriptor);
+  }
+}
+
+void GeneratedMessageReflection::Swap(
+    Message* message1,
+    Message* message2) const {
+  if (message1 == message2) return;
+
+  // TODO(kenton):  Other Reflection methods should probably check this too.
+  GOOGLE_CHECK_EQ(message1->GetReflection(), this)
+    << "First argument to Swap() (of type \""
+    << message1->GetDescriptor()->full_name()
+    << "\") is not compatible with this reflection object (which is for type \""
+    << descriptor_->full_name()
+    << "\").  Note that the exact same class is required; not just the same "
+       "descriptor.";
+  GOOGLE_CHECK_EQ(message2->GetReflection(), this)
+    << "Second argument to Swap() (of type \""
+    << message2->GetDescriptor()->full_name()
+    << "\") is not compatible with this reflection object (which is for type \""
+    << descriptor_->full_name()
+    << "\").  Note that the exact same class is required; not just the same "
+       "descriptor.";
+
+  uint32* has_bits1 = MutableHasBits(message1);
+  uint32* has_bits2 = MutableHasBits(message2);
+  int has_bits_size = (descriptor_->field_count() + 31) / 32;
+
+  for (int i = 0; i < has_bits_size; i++) {
+    std::swap(has_bits1[i], has_bits2[i]);
+  }
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    if (!field->containing_oneof()) {
+      SwapField(message1, message2, field);
+    }
+  }
+
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
+  }
+
+  if (extensions_offset_ != -1) {
+    MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
+  }
+
+  MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
+}
+
+void GeneratedMessageReflection::SwapFields(
+    Message* message1,
+    Message* message2,
+    const vector<const FieldDescriptor*>& fields) const {
+  if (message1 == message2) return;
+
+  // TODO(kenton):  Other Reflection methods should probably check this too.
+  GOOGLE_CHECK_EQ(message1->GetReflection(), this)
+    << "First argument to SwapFields() (of type \""
+    << message1->GetDescriptor()->full_name()
+    << "\") is not compatible with this reflection object (which is for type \""
+    << descriptor_->full_name()
+    << "\").  Note that the exact same class is required; not just the same "
+       "descriptor.";
+  GOOGLE_CHECK_EQ(message2->GetReflection(), this)
+    << "Second argument to SwapFields() (of type \""
+    << message2->GetDescriptor()->full_name()
+    << "\") is not compatible with this reflection object (which is for type \""
+    << descriptor_->full_name()
+    << "\").  Note that the exact same class is required; not just the same "
+       "descriptor.";
+
+  std::set<int> swapped_oneof;
+
+  for (int i = 0; i < fields.size(); i++) {
+    const FieldDescriptor* field = fields[i];
+    if (field->is_extension()) {
+      MutableExtensionSet(message1)->SwapExtension(
+          MutableExtensionSet(message2),
+          field->number());
+    } else {
+      if (field->containing_oneof()) {
+        int oneof_index = field->containing_oneof()->index();
+        // Only swap the oneof field once.
+        if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
+          continue;
+        }
+        swapped_oneof.insert(oneof_index);
+        SwapOneofField(message1, message2, field->containing_oneof());
+      } else {
+        // Swap has bit.
+        SwapBit(message1, message2, field);
+        // Swap field.
+        SwapField(message1, message2, field);
+      }
+    }
+  }
+}
+
+// -------------------------------------------------------------------
+
+bool GeneratedMessageReflection::HasField(const Message& message,
+                                          const FieldDescriptor* field) const {
+  USAGE_CHECK_MESSAGE_TYPE(HasField);
+  USAGE_CHECK_SINGULAR(HasField);
+
+  if (field->is_extension()) {
+    return GetExtensionSet(message).Has(field->number());
+  } else {
+    if (field->containing_oneof()) {
+      return HasOneofField(message, field);
+    } else {
+      return HasBit(message, field);
+    }
+  }
+}
+
+int GeneratedMessageReflection::FieldSize(const Message& message,
+                                          const FieldDescriptor* field) const {
+  USAGE_CHECK_MESSAGE_TYPE(FieldSize);
+  USAGE_CHECK_REPEATED(FieldSize);
+
+  if (field->is_extension()) {
+    return GetExtensionSet(message).ExtensionSize(field->number());
+  } else {
+    switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
+      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
+        return GetRaw<RepeatedField<LOWERCASE> >(message, field).size()
+
+      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);
+      HANDLE_TYPE(  ENUM,    int);
+#undef HANDLE_TYPE
+
+      case FieldDescriptor::CPPTYPE_STRING:
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        return GetRaw<RepeatedPtrFieldBase>(message, field).size();
+    }
+
+    GOOGLE_LOG(FATAL) << "Can't get here.";
+    return 0;
+  }
+}
+
+void GeneratedMessageReflection::ClearField(
+    Message* message, const FieldDescriptor* field) const {
+  USAGE_CHECK_MESSAGE_TYPE(ClearField);
+
+  if (field->is_extension()) {
+    MutableExtensionSet(message)->ClearExtension(field->number());
+  } else if (!field->is_repeated()) {
+    if (field->containing_oneof()) {
+      ClearOneofField(message, field);
+      return;
+    }
+
+    if (HasBit(*message, field)) {
+      ClearBit(message, field);
+
+      // We need to set the field back to its default value.
+      switch (field->cpp_type()) {
+#define CLEAR_TYPE(CPPTYPE, TYPE)                                            \
+        case FieldDescriptor::CPPTYPE_##CPPTYPE:                             \
+          *MutableRaw<TYPE>(message, 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>(message, field) =
+            field->default_value_enum()->number();
+          break;
+
+        case FieldDescriptor::CPPTYPE_STRING: {
+          switch (field->options().ctype()) {
+            default:  // TODO(kenton):  Support other string reps.
+            case FieldOptions::STRING:
+              const string* default_ptr = DefaultRaw<const string*>(field);
+              string** value = MutableRaw<string*>(message, field);
+              if (*value != default_ptr) {
+                if (field->has_default_value()) {
+                  (*value)->assign(field->default_value_string());
+                } else {
+                  (*value)->clear();
+                }
+              }
+              break;
+          }
+          break;
+        }
+
+        case FieldDescriptor::CPPTYPE_MESSAGE:
+          (*MutableRaw<Message*>(message, field))->Clear();
+          break;
+      }
+    }
+  } else {
+    switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
+      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
+        MutableRaw<RepeatedField<LOWERCASE> >(message, field)->Clear();       \
+        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);
+      HANDLE_TYPE(  ENUM,    int);
+#undef HANDLE_TYPE
+
+      case FieldDescriptor::CPPTYPE_STRING: {
+        switch (field->options().ctype()) {
+          default:  // TODO(kenton):  Support other string reps.
+          case FieldOptions::STRING:
+            MutableRaw<RepeatedPtrField<string> >(message, field)->Clear();
+            break;
+        }
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_MESSAGE: {
+        // We don't know which subclass of RepeatedPtrFieldBase the type is,
+        // so we use RepeatedPtrFieldBase directly.
+        MutableRaw<RepeatedPtrFieldBase>(message, field)
+            ->Clear<GenericTypeHandler<Message> >();
+        break;
+      }
+    }
+  }
+}
+
+void GeneratedMessageReflection::RemoveLast(
+    Message* message,
+    const FieldDescriptor* field) const {
+  USAGE_CHECK_MESSAGE_TYPE(RemoveLast);
+  USAGE_CHECK_REPEATED(RemoveLast);
+
+  if (field->is_extension()) {
+    MutableExtensionSet(message)->RemoveLast(field->number());
+  } else {
+    switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
+      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
+        MutableRaw<RepeatedField<LOWERCASE> >(message, field)->RemoveLast();  \
+        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);
+      HANDLE_TYPE(  ENUM,    int);
+#undef HANDLE_TYPE
+
+      case FieldDescriptor::CPPTYPE_STRING:
+        switch (field->options().ctype()) {
+          default:  // TODO(kenton):  Support other string reps.
+          case FieldOptions::STRING:
+            MutableRaw<RepeatedPtrField<string> >(message, field)->RemoveLast();
+            break;
+        }
+        break;
+
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        MutableRaw<RepeatedPtrFieldBase>(message, field)
+            ->RemoveLast<GenericTypeHandler<Message> >();
+        break;
+    }
+  }
+}
+
+Message* GeneratedMessageReflection::ReleaseLast(
+    Message* message,
+    const FieldDescriptor* field) const {
+  USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
+
+  if (field->is_extension()) {
+    return static_cast<Message*>(
+        MutableExtensionSet(message)->ReleaseLast(field->number()));
+  } else {
+    return MutableRaw<RepeatedPtrFieldBase>(message, field)
+        ->ReleaseLast<GenericTypeHandler<Message> >();
+  }
+}
+
+void GeneratedMessageReflection::SwapElements(
+    Message* message,
+    const FieldDescriptor* field,
+    int index1,
+    int index2) const {
+  USAGE_CHECK_MESSAGE_TYPE(Swap);
+  USAGE_CHECK_REPEATED(Swap);
+
+  if (field->is_extension()) {
+    MutableExtensionSet(message)->SwapElements(field->number(), index1, index2);
+  } else {
+    switch (field->cpp_type()) {
+#define HANDLE_TYPE(UPPERCASE, LOWERCASE)                                     \
+      case FieldDescriptor::CPPTYPE_##UPPERCASE :                             \
+        MutableRaw<RepeatedField<LOWERCASE> >(message, field)                 \
+            ->SwapElements(index1, index2);                                   \
+        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);
+      HANDLE_TYPE(  ENUM,    int);
+#undef HANDLE_TYPE
+
+      case FieldDescriptor::CPPTYPE_STRING:
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        MutableRaw<RepeatedPtrFieldBase>(message, field)
+            ->SwapElements(index1, index2);
+        break;
+    }
+  }
+}
+
+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(
+    const Message& message,
+    vector<const FieldDescriptor*>* output) const {
+  output->clear();
+
+  // Optimization:  The default instance never has any fields set.
+  if (&message == default_instance_) return;
+
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* field = descriptor_->field(i);
+    if (field->is_repeated()) {
+      if (FieldSize(message, field) > 0) {
+        output->push_back(field);
+      }
+    } else {
+      if (field->containing_oneof()) {
+        if (HasOneofField(message, field)) {
+          output->push_back(field);
+        }
+      } else if (HasBit(message, field)) {
+        output->push_back(field);
+      }
+    }
+  }
+
+  if (extensions_offset_ != -1) {
+    GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
+                                          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 Message& message, const FieldDescriptor* field) const {          \
+    USAGE_CHECK_ALL(Get##TYPENAME, SINGULAR, CPPTYPE);                       \
+    if (field->is_extension()) {                                             \
+      return GetExtensionSet(message).Get##TYPENAME(                         \
+        field->number(), field->default_value_##PASSTYPE());                 \
+    } else {                                                                 \
+      return GetField<TYPE>(message, field);                                 \
+    }                                                                        \
+  }                                                                          \
+                                                                             \
+  void GeneratedMessageReflection::Set##TYPENAME(                            \
+      Message* message, const FieldDescriptor* field,                        \
+      PASSTYPE value) const {                                                \
+    USAGE_CHECK_ALL(Set##TYPENAME, SINGULAR, CPPTYPE);                       \
+    if (field->is_extension()) {                                             \
+      return MutableExtensionSet(message)->Set##TYPENAME(                    \
+        field->number(), field->type(), value, field);                       \
+    } else {                                                                 \
+      SetField<TYPE>(message, field, value);                                 \
+    }                                                                        \
+  }                                                                          \
+                                                                             \
+  PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME(                \
+      const Message& message,                                                \
+      const FieldDescriptor* field, int index) const {                       \
+    USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED, CPPTYPE);               \
+    if (field->is_extension()) {                                             \
+      return GetExtensionSet(message).GetRepeated##TYPENAME(                 \
+        field->number(), index);                                             \
+    } else {                                                                 \
+      return GetRepeatedField<TYPE>(message, field, index);                  \
+    }                                                                        \
+  }                                                                          \
+                                                                             \
+  void GeneratedMessageReflection::SetRepeated##TYPENAME(                    \
+      Message* message, const FieldDescriptor* field,                        \
+      int index, PASSTYPE value) const {                                     \
+    USAGE_CHECK_ALL(SetRepeated##TYPENAME, REPEATED, CPPTYPE);               \
+    if (field->is_extension()) {                                             \
+      MutableExtensionSet(message)->SetRepeated##TYPENAME(                   \
+        field->number(), index, value);                                      \
+    } else {                                                                 \
+      SetRepeatedField<TYPE>(message, field, index, value);                  \
+    }                                                                        \
+  }                                                                          \
+                                                                             \
+  void GeneratedMessageReflection::Add##TYPENAME(                            \
+      Message* message, const FieldDescriptor* field,                        \
+      PASSTYPE value) const {                                                \
+    USAGE_CHECK_ALL(Add##TYPENAME, REPEATED, CPPTYPE);                       \
+    if (field->is_extension()) {                                             \
+      MutableExtensionSet(message)->Add##TYPENAME(                           \
+        field->number(), field->type(), field->options().packed(), value,    \
+        field);                                                              \
+    } else {                                                                 \
+      AddField<TYPE>(message, 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 Message& message, const FieldDescriptor* field) const {
+  USAGE_CHECK_ALL(GetString, SINGULAR, STRING);
+  if (field->is_extension()) {
+    return GetExtensionSet(message).GetString(field->number(),
+                                              field->default_value_string());
+  } else {
+    switch (field->options().ctype()) {
+      default:  // TODO(kenton):  Support other string reps.
+      case FieldOptions::STRING:
+        return *GetField<const string*>(message, field);
+    }
+
+    GOOGLE_LOG(FATAL) << "Can't get here.";
+    return GetEmptyString();  // Make compiler happy.
+  }
+}
+
+const string& GeneratedMessageReflection::GetStringReference(
+    const Message& message,
+    const FieldDescriptor* field, string* scratch) const {
+  USAGE_CHECK_ALL(GetStringReference, SINGULAR, STRING);
+  if (field->is_extension()) {
+    return GetExtensionSet(message).GetString(field->number(),
+                                              field->default_value_string());
+  } else {
+    switch (field->options().ctype()) {
+      default:  // TODO(kenton):  Support other string reps.
+      case FieldOptions::STRING:
+        return *GetField<const string*>(message, field);
+    }
+
+    GOOGLE_LOG(FATAL) << "Can't get here.";
+    return GetEmptyString();  // Make compiler happy.
+  }
+}
+
+
+void GeneratedMessageReflection::SetString(
+    Message* message, const FieldDescriptor* field,
+    const string& value) const {
+  USAGE_CHECK_ALL(SetString, SINGULAR, STRING);
+  if (field->is_extension()) {
+    return MutableExtensionSet(message)->SetString(field->number(),
+                                                   field->type(), value, field);
+  } else {
+    switch (field->options().ctype()) {
+      default:  // TODO(kenton):  Support other string reps.
+      case FieldOptions::STRING: {
+        if (field->containing_oneof() && !HasOneofField(*message, field)) {
+          ClearOneof(message, field->containing_oneof());
+          *MutableField<string*>(message, field) = new string;
+        }
+        string** ptr = MutableField<string*>(message, field);
+        if (*ptr == DefaultRaw<const string*>(field)) {
+          *ptr = new string(value);
+        } else {
+          (*ptr)->assign(value);
+        }
+        break;
+      }
+    }
+  }
+}
+
+
+string GeneratedMessageReflection::GetRepeatedString(
+    const Message& message, const FieldDescriptor* field, int index) const {
+  USAGE_CHECK_ALL(GetRepeatedString, REPEATED, STRING);
+  if (field->is_extension()) {
+    return GetExtensionSet(message).GetRepeatedString(field->number(), index);
+  } else {
+    switch (field->options().ctype()) {
+      default:  // TODO(kenton):  Support other string reps.
+      case FieldOptions::STRING:
+        return GetRepeatedPtrField<string>(message, field, index);
+    }
+
+    GOOGLE_LOG(FATAL) << "Can't get here.";
+    return GetEmptyString();  // Make compiler happy.
+  }
+}
+
+const string& GeneratedMessageReflection::GetRepeatedStringReference(
+    const Message& message, const FieldDescriptor* field,
+    int index, string* scratch) const {
+  USAGE_CHECK_ALL(GetRepeatedStringReference, REPEATED, STRING);
+  if (field->is_extension()) {
+    return GetExtensionSet(message).GetRepeatedString(field->number(), index);
+  } else {
+    switch (field->options().ctype()) {
+      default:  // TODO(kenton):  Support other string reps.
+      case FieldOptions::STRING:
+        return GetRepeatedPtrField<string>(message, field, index);
+    }
+
+    GOOGLE_LOG(FATAL) << "Can't get here.";
+    return GetEmptyString();  // Make compiler happy.
+  }
+}
+
+
+void GeneratedMessageReflection::SetRepeatedString(
+    Message* message, const FieldDescriptor* field,
+    int index, const string& value) const {
+  USAGE_CHECK_ALL(SetRepeatedString, REPEATED, STRING);
+  if (field->is_extension()) {
+    MutableExtensionSet(message)->SetRepeatedString(
+      field->number(), index, value);
+  } else {
+    switch (field->options().ctype()) {
+      default:  // TODO(kenton):  Support other string reps.
+      case FieldOptions::STRING:
+        *MutableRepeatedField<string>(message, field, index) = value;
+        break;
+    }
+  }
+}
+
+
+void GeneratedMessageReflection::AddString(
+    Message* message, const FieldDescriptor* field,
+    const string& value) const {
+  USAGE_CHECK_ALL(AddString, REPEATED, STRING);
+  if (field->is_extension()) {
+    MutableExtensionSet(message)->AddString(field->number(),
+                                            field->type(), value, field);
+  } else {
+    switch (field->options().ctype()) {
+      default:  // TODO(kenton):  Support other string reps.
+      case FieldOptions::STRING:
+        *AddField<string>(message, field) = value;
+        break;
+    }
+  }
+}
+
+
+// -------------------------------------------------------------------
+
+const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
+    const Message& message, const FieldDescriptor* field) const {
+  USAGE_CHECK_ALL(GetEnum, SINGULAR, ENUM);
+
+  int value;
+  if (field->is_extension()) {
+    value = GetExtensionSet(message).GetEnum(
+      field->number(), field->default_value_enum()->number());
+  } else {
+    value = GetField<int>(message, field);
+  }
+  const EnumValueDescriptor* result =
+    field->enum_type()->FindValueByNumber(value);
+  GOOGLE_CHECK(result != NULL) << "Value " << value << " is not valid for field "
+                        << field->full_name() << " of type "
+                        << field->enum_type()->full_name() << ".";
+  return result;
+}
+
+void GeneratedMessageReflection::SetEnum(
+    Message* message, const FieldDescriptor* field,
+    const EnumValueDescriptor* value) const {
+  USAGE_CHECK_ALL(SetEnum, SINGULAR, ENUM);
+  USAGE_CHECK_ENUM_VALUE(SetEnum);
+
+  if (field->is_extension()) {
+    MutableExtensionSet(message)->SetEnum(field->number(), field->type(),
+                                          value->number(), field);
+  } else {
+    SetField<int>(message, field, value->number());
+  }
+}
+
+const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
+    const Message& message, const FieldDescriptor* field, int index) const {
+  USAGE_CHECK_ALL(GetRepeatedEnum, REPEATED, ENUM);
+
+  int value;
+  if (field->is_extension()) {
+    value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
+  } else {
+    value = GetRepeatedField<int>(message, field, index);
+  }
+  const EnumValueDescriptor* result =
+    field->enum_type()->FindValueByNumber(value);
+  GOOGLE_CHECK(result != NULL) << "Value " << value << " is not valid for field "
+                        << field->full_name() << " of type "
+                        << field->enum_type()->full_name() << ".";
+  return result;
+}
+
+void GeneratedMessageReflection::SetRepeatedEnum(
+    Message* message,
+    const FieldDescriptor* field, int index,
+    const EnumValueDescriptor* value) const {
+  USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
+  USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
+
+  if (field->is_extension()) {
+    MutableExtensionSet(message)->SetRepeatedEnum(
+      field->number(), index, value->number());
+  } else {
+    SetRepeatedField<int>(message, field, index, value->number());
+  }
+}
+
+void GeneratedMessageReflection::AddEnum(
+    Message* message, const FieldDescriptor* field,
+    const EnumValueDescriptor* value) const {
+  USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
+  USAGE_CHECK_ENUM_VALUE(AddEnum);
+
+  if (field->is_extension()) {
+    MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
+                                          field->options().packed(),
+                                          value->number(), field);
+  } else {
+    AddField<int>(message, field, value->number());
+  }
+}
+
+// -------------------------------------------------------------------
+
+const Message& GeneratedMessageReflection::GetMessage(
+    const Message& message, const FieldDescriptor* field,
+    MessageFactory* factory) const {
+  USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
+
+  if (factory == NULL) factory = message_factory_;
+
+  if (field->is_extension()) {
+    return static_cast<const Message&>(
+        GetExtensionSet(message).GetMessage(
+          field->number(), field->message_type(), factory));
+  } else {
+    const Message* result;
+    result = GetRaw<const Message*>(message, field);
+    if (result == NULL) {
+      result = DefaultRaw<const Message*>(field);
+    }
+    return *result;
+  }
+}
+
+Message* GeneratedMessageReflection::MutableMessage(
+    Message* message, const FieldDescriptor* field,
+    MessageFactory* factory) const {
+  if (factory == NULL) factory = message_factory_;
+
+  if (field->is_extension()) {
+    return static_cast<Message*>(
+        MutableExtensionSet(message)->MutableMessage(field, factory));
+  } else {
+    Message* result;
+    Message** result_holder = MutableRaw<Message*>(message, field);
+
+    if (field->containing_oneof()) {
+      if (!HasOneofField(*message, field)) {
+        ClearOneof(message, field->containing_oneof());
+        result_holder = MutableField<Message*>(message, field);
+        const Message* default_message = DefaultRaw<const Message*>(field);
+        *result_holder = default_message->New();
+      }
+    } else {
+      SetBit(message, field);
+    }
+
+    if (*result_holder == NULL) {
+      const Message* default_message = DefaultRaw<const Message*>(field);
+      *result_holder = default_message->New();
+    }
+    result = *result_holder;
+    return result;
+  }
+}
+
+void GeneratedMessageReflection::SetAllocatedMessage(
+    Message* message,
+    Message* sub_message,
+    const FieldDescriptor* field) const {
+  USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
+
+  if (field->is_extension()) {
+    MutableExtensionSet(message)->SetAllocatedMessage(
+        field->number(), field->type(), field, sub_message);
+  } else {
+    if (field->containing_oneof()) {
+      if (sub_message == NULL) {
+        ClearOneof(message, field->containing_oneof());
+        return;
+      }
+        ClearOneof(message, field->containing_oneof());
+        *MutableRaw<Message*>(message, field) = sub_message;
+      SetOneofCase(message, field);
+      return;
+    }
+
+    if (sub_message == NULL) {
+      ClearBit(message, field);
+    } else {
+      SetBit(message, field);
+    }
+    Message** sub_message_holder = MutableRaw<Message*>(message, field);
+    delete *sub_message_holder;
+    *sub_message_holder = sub_message;
+  }
+}
+
+Message* GeneratedMessageReflection::ReleaseMessage(
+    Message* message,
+    const FieldDescriptor* field,
+    MessageFactory* factory) const {
+  USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
+
+  if (factory == NULL) factory = message_factory_;
+
+  if (field->is_extension()) {
+    return static_cast<Message*>(
+        MutableExtensionSet(message)->ReleaseMessage(field, factory));
+  } else {
+    ClearBit(message, field);
+    if (field->containing_oneof()) {
+      if (HasOneofField(*message, field)) {
+        *MutableOneofCase(message, field->containing_oneof()) = 0;
+      } else {
+        return NULL;
+      }
+    }
+    Message** result = MutableRaw<Message*>(message, field);
+    Message* ret = *result;
+    *result = NULL;
+    return ret;
+  }
+}
+
+const Message& GeneratedMessageReflection::GetRepeatedMessage(
+    const Message& message, const FieldDescriptor* field, int index) const {
+  USAGE_CHECK_ALL(GetRepeatedMessage, REPEATED, MESSAGE);
+
+  if (field->is_extension()) {
+    return static_cast<const Message&>(
+        GetExtensionSet(message).GetRepeatedMessage(field->number(), index));
+  } else {
+    return GetRaw<RepeatedPtrFieldBase>(message, field)
+        .Get<GenericTypeHandler<Message> >(index);
+  }
+}
+
+Message* GeneratedMessageReflection::MutableRepeatedMessage(
+    Message* message, const FieldDescriptor* field, int index) const {
+  USAGE_CHECK_ALL(MutableRepeatedMessage, REPEATED, MESSAGE);
+
+  if (field->is_extension()) {
+    return static_cast<Message*>(
+        MutableExtensionSet(message)->MutableRepeatedMessage(
+          field->number(), index));
+  } else {
+    return MutableRaw<RepeatedPtrFieldBase>(message, field)
+        ->Mutable<GenericTypeHandler<Message> >(index);
+  }
+}
+
+Message* GeneratedMessageReflection::AddMessage(
+    Message* message, const FieldDescriptor* field,
+    MessageFactory* factory) const {
+  USAGE_CHECK_ALL(AddMessage, REPEATED, MESSAGE);
+
+  if (factory == NULL) factory = message_factory_;
+
+  if (field->is_extension()) {
+    return static_cast<Message*>(
+        MutableExtensionSet(message)->AddMessage(field, factory));
+  } else {
+    // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
+    // know how to allocate one.
+    RepeatedPtrFieldBase* repeated =
+        MutableRaw<RepeatedPtrFieldBase>(message, field);
+    Message* result = repeated->AddFromCleared<GenericTypeHandler<Message> >();
+    if (result == NULL) {
+      // We must allocate a new object.
+      const Message* prototype;
+      if (repeated->size() == 0) {
+        prototype = factory->GetPrototype(field->message_type());
+      } else {
+        prototype = &repeated->Get<GenericTypeHandler<Message> >(0);
+      }
+      result = prototype->New();
+      repeated->AddAllocated<GenericTypeHandler<Message> >(result);
+    }
+    return result;
+  }
+}
+
+void* GeneratedMessageReflection::MutableRawRepeatedField(
+    Message* message, const FieldDescriptor* field,
+    FieldDescriptor::CppType cpptype,
+    int ctype, const Descriptor* desc) const {
+  USAGE_CHECK_REPEATED("MutableRawRepeatedField");
+  if (field->cpp_type() != cpptype)
+    ReportReflectionUsageTypeError(descriptor_,
+        field, "MutableRawRepeatedField", cpptype);
+  if (ctype >= 0)
+    GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
+  if (desc != NULL)
+    GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
+  if (field->is_extension())
+    return MutableExtensionSet(message)->MutableRawRepeatedField(
+        field->number(), field->type(), field->is_packed(), field);
+  else
+    return reinterpret_cast<uint8*>(message) + offsets_[field->index()];
+}
+
+const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor(
+    const Message& message,
+    const OneofDescriptor* oneof_descriptor) const {
+  uint32 field_number = GetOneofCase(message, oneof_descriptor);
+  if (field_number == 0) {
+    return NULL;
+  }
+  return descriptor_->FindFieldByNumber(field_number);
+}
+
+// -----------------------------------------------------------------------------
+
+const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
+    const string& name) const {
+  if (extensions_offset_ == -1) return NULL;
+
+  const FieldDescriptor* result = descriptor_pool_->FindExtensionByName(name);
+  if (result != NULL && result->containing_type() == descriptor_) {
+    return result;
+  }
+
+  if (descriptor_->options().message_set_wire_format()) {
+    // MessageSet extensions may be identified by type name.
+    const Descriptor* type = descriptor_pool_->FindMessageTypeByName(name);
+    if (type != NULL) {
+      // Look for a matching extension in the foreign type's scope.
+      for (int i = 0; i < type->extension_count(); i++) {
+        const FieldDescriptor* extension = type->extension(i);
+        if (extension->containing_type() == descriptor_ &&
+            extension->type() == FieldDescriptor::TYPE_MESSAGE &&
+            extension->is_optional() &&
+            extension->message_type() == type) {
+          // Found it.
+          return extension;
+        }
+      }
+    }
+  }
+
+  return NULL;
+}
+
+const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByNumber(
+    int number) const {
+  if (extensions_offset_ == -1) return NULL;
+  return descriptor_pool_->FindExtensionByNumber(descriptor_, 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 Message& message, const FieldDescriptor* field) const {
+  if (field->containing_oneof() && !HasOneofField(message, field)) {
+    return DefaultRaw<Type>(field);
+  }
+  int index = field->containing_oneof() ?
+      descriptor_->field_count() + field->containing_oneof()->index() :
+      field->index();
+  const void* ptr = reinterpret_cast<const uint8*>(&message) +
+      offsets_[index];
+  return *reinterpret_cast<const Type*>(ptr);
+}
+
+template <typename Type>
+inline Type* GeneratedMessageReflection::MutableRaw(
+    Message* message, const FieldDescriptor* field) const {
+  int index = field->containing_oneof() ?
+      descriptor_->field_count() + field->containing_oneof()->index() :
+      field->index();
+  void* ptr = reinterpret_cast<uint8*>(message) + offsets_[index];
+  return reinterpret_cast<Type*>(ptr);
+}
+
+template <typename Type>
+inline const Type& GeneratedMessageReflection::DefaultRaw(
+    const FieldDescriptor* field) const {
+  const void* ptr = field->containing_oneof() ?
+      reinterpret_cast<const uint8*>(default_oneof_instance_) +
+      offsets_[field->index()] :
+      reinterpret_cast<const uint8*>(default_instance_) +
+      offsets_[field->index()];
+  return *reinterpret_cast<const Type*>(ptr);
+}
+
+inline const uint32* GeneratedMessageReflection::GetHasBits(
+    const Message& message) const {
+  const void* ptr = reinterpret_cast<const uint8*>(&message) + has_bits_offset_;
+  return reinterpret_cast<const uint32*>(ptr);
+}
+inline uint32* GeneratedMessageReflection::MutableHasBits(
+    Message* message) const {
+  void* ptr = reinterpret_cast<uint8*>(message) + has_bits_offset_;
+  return reinterpret_cast<uint32*>(ptr);
+}
+
+inline uint32 GeneratedMessageReflection::GetOneofCase(
+    const Message& message,
+    const OneofDescriptor* oneof_descriptor) const {
+  const void* ptr = reinterpret_cast<const uint8*>(&message)
+      + oneof_case_offset_;
+  return reinterpret_cast<const uint32*>(ptr)[oneof_descriptor->index()];
+}
+
+inline uint32* GeneratedMessageReflection::MutableOneofCase(
+    Message* message,
+    const OneofDescriptor* oneof_descriptor) const {
+  void* ptr = reinterpret_cast<uint8*>(message) + oneof_case_offset_;
+  return &(reinterpret_cast<uint32*>(ptr)[oneof_descriptor->index()]);
+}
+
+inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
+    const Message& message) const {
+  GOOGLE_DCHECK_NE(extensions_offset_, -1);
+  const void* ptr = reinterpret_cast<const uint8*>(&message) +
+                    extensions_offset_;
+  return *reinterpret_cast<const ExtensionSet*>(ptr);
+}
+inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
+    Message* message) const {
+  GOOGLE_DCHECK_NE(extensions_offset_, -1);
+  void* ptr = reinterpret_cast<uint8*>(message) + extensions_offset_;
+  return reinterpret_cast<ExtensionSet*>(ptr);
+}
+
+// Simple accessors for manipulating has_bits_.
+inline bool GeneratedMessageReflection::HasBit(
+    const Message& message, const FieldDescriptor* field) const {
+  return GetHasBits(message)[field->index() / 32] &
+    (1 << (field->index() % 32));
+}
+
+inline void GeneratedMessageReflection::SetBit(
+    Message* message, const FieldDescriptor* field) const {
+  MutableHasBits(message)[field->index() / 32] |= (1 << (field->index() % 32));
+}
+
+inline void GeneratedMessageReflection::ClearBit(
+    Message* message, const FieldDescriptor* field) const {
+  MutableHasBits(message)[field->index() / 32] &= ~(1 << (field->index() % 32));
+}
+
+inline void GeneratedMessageReflection::SwapBit(
+    Message* message1, Message* message2, const FieldDescriptor* field) const {
+  bool temp_has_bit = HasBit(*message1, field);
+  if (HasBit(*message2, field)) {
+    SetBit(message1, field);
+  } else {
+    ClearBit(message1, field);
+  }
+  if (temp_has_bit) {
+    SetBit(message2, field);
+  } else {
+    ClearBit(message2, field);
+  }
+}
+
+inline bool GeneratedMessageReflection::HasOneof(
+    const Message& message, const OneofDescriptor* oneof_descriptor) const {
+  return (GetOneofCase(message, oneof_descriptor) > 0);
+}
+
+inline bool GeneratedMessageReflection::HasOneofField(
+    const Message& message, const FieldDescriptor* field) const {
+  return (GetOneofCase(message, field->containing_oneof()) == field->number());
+}
+
+inline void GeneratedMessageReflection::SetOneofCase(
+    Message* message, const FieldDescriptor* field) const {
+  *MutableOneofCase(message, field->containing_oneof()) = field->number();
+}
+
+inline void GeneratedMessageReflection::ClearOneofField(
+    Message* message, const FieldDescriptor* field) const {
+  if (HasOneofField(*message, field)) {
+    ClearOneof(message, field->containing_oneof());
+  }
+}
+
+inline void GeneratedMessageReflection::ClearOneof(
+    Message* message, const OneofDescriptor* oneof_descriptor) const {
+  // TODO(jieluo): Consider to cache the unused object instead of deleting
+  // it. It will be much faster if an aplication switches a lot from
+  // a few oneof fields.  Time/space tradeoff
+  uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
+  if (oneof_case > 0) {
+    const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
+    switch (field->cpp_type()) {
+      case FieldDescriptor::CPPTYPE_STRING: {
+        switch (field->options().ctype()) {
+          default:  // TODO(kenton):  Support other string reps.
+          case FieldOptions::STRING:
+            delete *MutableRaw<string*>(message, field);
+            break;
+        }
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_MESSAGE:
+        delete *MutableRaw<Message*>(message, field);
+        break;
+      default:
+        break;
+    }
+
+    *MutableOneofCase(message, oneof_descriptor) = 0;
+  }
+}
+
+// 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 Message& message, const FieldDescriptor* field) const {
+  return GetRaw<Type>(message, field);
+}
+
+template <typename Type>
+inline void GeneratedMessageReflection::SetField(
+    Message* message, const FieldDescriptor* field, const Type& value) const {
+  if (field->containing_oneof() && !HasOneofField(*message, field)) {
+    ClearOneof(message, field->containing_oneof());
+  }
+  *MutableRaw<Type>(message, field) = value;
+  field->containing_oneof() ?
+      SetOneofCase(message, field) : SetBit(message, field);
+}
+
+template <typename Type>
+inline Type* GeneratedMessageReflection::MutableField(
+    Message* message, const FieldDescriptor* field) const {
+  field->containing_oneof() ?
+      SetOneofCase(message, field) : SetBit(message, field);
+  return MutableRaw<Type>(message, field);
+}
+
+template <typename Type>
+inline const Type& GeneratedMessageReflection::GetRepeatedField(
+    const Message& message, const FieldDescriptor* field, int index) const {
+  return GetRaw<RepeatedField<Type> >(message, field).Get(index);
+}
+
+template <typename Type>
+inline const Type& GeneratedMessageReflection::GetRepeatedPtrField(
+    const Message& message, const FieldDescriptor* field, int index) const {
+  return GetRaw<RepeatedPtrField<Type> >(message, field).Get(index);
+}
+
+template <typename Type>
+inline void GeneratedMessageReflection::SetRepeatedField(
+    Message* message, const FieldDescriptor* field,
+    int index, Type value) const {
+  MutableRaw<RepeatedField<Type> >(message, field)->Set(index, value);
+}
+
+template <typename Type>
+inline Type* GeneratedMessageReflection::MutableRepeatedField(
+    Message* message, const FieldDescriptor* field, int index) const {
+  RepeatedPtrField<Type>* repeated =
+    MutableRaw<RepeatedPtrField<Type> >(message, field);
+  return repeated->Mutable(index);
+}
+
+template <typename Type>
+inline void GeneratedMessageReflection::AddField(
+    Message* message, const FieldDescriptor* field, const Type& value) const {
+  MutableRaw<RepeatedField<Type> >(message, field)->Add(value);
+}
+
+template <typename Type>
+inline Type* GeneratedMessageReflection::AddField(
+    Message* message, const FieldDescriptor* field) const {
+  RepeatedPtrField<Type>* repeated =
+    MutableRaw<RepeatedPtrField<Type> >(message, field);
+  return repeated->Add();
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/generated_message_reflection.h b/protobuf/src/google/protobuf/generated_message_reflection.h
new file mode 100644
index 0000000..b6671ad
--- /dev/null
+++ b/protobuf/src/google/protobuf/generated_message_reflection.h
@@ -0,0 +1,504 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/stubs/common.h>
+// TODO(jasonh): Remove this once the compiler change to directly include this
+// is released to components.
+#include <google/protobuf/generated_enum_reflection.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/unknown_field_set.h>
+
+
+namespace google {
+namespace upb {
+namespace google_opensource {
+class GMR_Handlers;
+}  // namespace google_opensource
+}  // namespace upb
+
+namespace protobuf {
+  class DescriptorPool;
+}
+
+namespace protobuf {
+namespace internal {
+class DefaultEmptyOneof;
+
+// 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 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 Reflection {
+ public:
+  // Constructs a GeneratedMessageReflection.
+  // Parameters:
+  //   descriptor:    The descriptor for the message type being implemented.
+  //   default_instance:  The default instance of the message.  This is only
+  //                  used to obtain pointers to default instances of embedded
+  //                  messages, which GetMessage() will return if the particular
+  //                  sub-message has not been initialized yet.  (Thus, all
+  //                  embedded message fields *must* have non-NULL pointers
+  //                  in the default instance.)
+  //   offsets:       An array of ints giving the byte offsets, relative to
+  //                  the start of the message object, of each field.  These can
+  //                  be computed at compile time using the
+  //                  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro, defined
+  //                  below.
+  //   has_bits_offset:  Offset in the message of an array of uint32s of size
+  //                  descriptor->field_count()/32, rounded up.  This is a
+  //                  bitfield where each bit indicates whether or not the
+  //                  corresponding field of the message has been initialized.
+  //                  The bit for field index i is obtained by the expression:
+  //                    has_bits[i / 32] & (1 << (i % 32))
+  //   unknown_fields_offset:  Offset in the message of the UnknownFieldSet for
+  //                  the message.
+  //   extensions_offset:  Offset in the message of the ExtensionSet for the
+  //                  message, or -1 if the message type has no extension
+  //                  ranges.
+  //   pool:          DescriptorPool to search for extension definitions.  Only
+  //                  used by FindKnownExtensionByName() and
+  //                  FindKnownExtensionByNumber().
+  //   factory:       MessageFactory to use to construct extension messages.
+  //   object_size:   The size of a message object of this type, as measured
+  //                  by sizeof().
+  GeneratedMessageReflection(const Descriptor* descriptor,
+                             const Message* default_instance,
+                             const int offsets[],
+                             int has_bits_offset,
+                             int unknown_fields_offset,
+                             int extensions_offset,
+                             const DescriptorPool* pool,
+                             MessageFactory* factory,
+                             int object_size);
+
+  // Similar with the construction above. Call this construction if the
+  // message has oneof definition.
+  // Parameters:
+  //   offsets:       An array of ints giving the byte offsets.
+  //                  For each oneof field, the offset is relative to the
+  //                  default_oneof_instance. These can be computed at compile
+  //                  time using the
+  //                  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() macro.
+  //                  For each none oneof field, the offset is related to
+  //                  the start of the message object.  These can be computed
+  //                  at compile time using the
+  //                  GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro.
+  //                  Besides offsets for all fields, this array also contains
+  //                  offsets for oneof unions. The offset of the i-th oneof
+  //                  union is offsets[descriptor->field_count() + i].
+  //   default_oneof_instance: The default instance of the oneofs. It is a
+  //                  struct holding the default value of all oneof fields
+  //                  for this message. It is only used to obtain pointers
+  //                  to default instances of oneof fields, which Get
+  //                  methods will return if the field is not set.
+  //   oneof_case_offset:  Offset in the message of an array of uint32s of
+  //                  size descriptor->oneof_decl_count().  Each uint32
+  //                  indicates what field is set for each oneof.
+  //   other parameters are the same with the construction above.
+  GeneratedMessageReflection(const Descriptor* descriptor,
+                             const Message* default_instance,
+                             const int offsets[],
+                             int has_bits_offset,
+                             int unknown_fields_offset,
+                             int extensions_offset,
+                             const void* default_oneof_instance,
+                             int oneof_case_offset,
+                             const DescriptorPool* pool,
+                             MessageFactory* factory,
+                             int object_size);
+  ~GeneratedMessageReflection();
+
+  // implements Reflection -------------------------------------------
+
+  const UnknownFieldSet& GetUnknownFields(const Message& message) const;
+  UnknownFieldSet* MutableUnknownFields(Message* message) const;
+
+  int SpaceUsed(const Message& message) const;
+
+  bool HasField(const Message& message, const FieldDescriptor* field) const;
+  int FieldSize(const Message& message, const FieldDescriptor* field) const;
+  void ClearField(Message* message, const FieldDescriptor* field) const;
+  bool HasOneof(const Message& message,
+                const OneofDescriptor* oneof_descriptor) const;
+  void ClearOneof(Message* message, const OneofDescriptor* field) const;
+  void RemoveLast(Message* message, const FieldDescriptor* field) const;
+  Message* ReleaseLast(Message* message, const FieldDescriptor* field) const;
+  void Swap(Message* message1, Message* message2) const;
+  void SwapFields(Message* message1, Message* message2,
+                  const vector<const FieldDescriptor*>& fields) const;
+  void SwapElements(Message* message, const FieldDescriptor* field,
+                    int index1, int index2) const;
+  void ListFields(const Message& message,
+                  vector<const FieldDescriptor*>* output) const;
+
+  int32  GetInt32 (const Message& message,
+                   const FieldDescriptor* field) const;
+  int64  GetInt64 (const Message& message,
+                   const FieldDescriptor* field) const;
+  uint32 GetUInt32(const Message& message,
+                   const FieldDescriptor* field) const;
+  uint64 GetUInt64(const Message& message,
+                   const FieldDescriptor* field) const;
+  float  GetFloat (const Message& message,
+                   const FieldDescriptor* field) const;
+  double GetDouble(const Message& message,
+                   const FieldDescriptor* field) const;
+  bool   GetBool  (const Message& message,
+                   const FieldDescriptor* field) const;
+  string GetString(const Message& message,
+                   const FieldDescriptor* field) const;
+  const string& GetStringReference(const Message& message,
+                                   const FieldDescriptor* field,
+                                   string* scratch) const;
+  const EnumValueDescriptor* GetEnum(const Message& message,
+                                     const FieldDescriptor* field) const;
+  const Message& GetMessage(const Message& message,
+                            const FieldDescriptor* field,
+                            MessageFactory* factory = NULL) const;
+
+  const FieldDescriptor* GetOneofFieldDescriptor(
+      const Message& message,
+      const OneofDescriptor* oneof_descriptor) const;
+
+ public:
+  void SetInt32 (Message* message,
+                 const FieldDescriptor* field, int32  value) const;
+  void SetInt64 (Message* message,
+                 const FieldDescriptor* field, int64  value) const;
+  void SetUInt32(Message* message,
+                 const FieldDescriptor* field, uint32 value) const;
+  void SetUInt64(Message* message,
+                 const FieldDescriptor* field, uint64 value) const;
+  void SetFloat (Message* message,
+                 const FieldDescriptor* field, float  value) const;
+  void SetDouble(Message* message,
+                 const FieldDescriptor* field, double value) const;
+  void SetBool  (Message* message,
+                 const FieldDescriptor* field, bool   value) const;
+  void SetString(Message* message,
+                 const FieldDescriptor* field,
+                 const string& value) const;
+  void SetEnum  (Message* message, const FieldDescriptor* field,
+                 const EnumValueDescriptor* value) const;
+  Message* MutableMessage(Message* message, const FieldDescriptor* field,
+                          MessageFactory* factory = NULL) const;
+  void SetAllocatedMessage(Message* message,
+                           Message* sub_message,
+                           const FieldDescriptor* field) const;
+  Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
+                          MessageFactory* factory = NULL) const;
+
+  int32  GetRepeatedInt32 (const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  int64  GetRepeatedInt64 (const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  uint32 GetRepeatedUInt32(const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  uint64 GetRepeatedUInt64(const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  float  GetRepeatedFloat (const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  double GetRepeatedDouble(const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  bool   GetRepeatedBool  (const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  string GetRepeatedString(const Message& message,
+                           const FieldDescriptor* field, int index) const;
+  const string& GetRepeatedStringReference(const Message& message,
+                                           const FieldDescriptor* field,
+                                           int index, string* scratch) const;
+  const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
+                                             const FieldDescriptor* field,
+                                             int index) const;
+  const Message& GetRepeatedMessage(const Message& message,
+                                    const FieldDescriptor* field,
+                                    int index) const;
+
+  // Set the value of a field.
+  void SetRepeatedInt32 (Message* message,
+                         const FieldDescriptor* field, int index, int32  value) const;
+  void SetRepeatedInt64 (Message* message,
+                         const FieldDescriptor* field, int index, int64  value) const;
+  void SetRepeatedUInt32(Message* message,
+                         const FieldDescriptor* field, int index, uint32 value) const;
+  void SetRepeatedUInt64(Message* message,
+                         const FieldDescriptor* field, int index, uint64 value) const;
+  void SetRepeatedFloat (Message* message,
+                         const FieldDescriptor* field, int index, float  value) const;
+  void SetRepeatedDouble(Message* message,
+                         const FieldDescriptor* field, int index, double value) const;
+  void SetRepeatedBool  (Message* message,
+                         const FieldDescriptor* field, int index, bool   value) const;
+  void SetRepeatedString(Message* message,
+                         const FieldDescriptor* field, int index,
+                         const string& value) const;
+  void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
+                       int index, const EnumValueDescriptor* value) const;
+  // Get a mutable pointer to a field with a message type.
+  Message* MutableRepeatedMessage(Message* message,
+                                  const FieldDescriptor* field,
+                                  int index) const;
+
+  void AddInt32 (Message* message,
+                 const FieldDescriptor* field, int32  value) const;
+  void AddInt64 (Message* message,
+                 const FieldDescriptor* field, int64  value) const;
+  void AddUInt32(Message* message,
+                 const FieldDescriptor* field, uint32 value) const;
+  void AddUInt64(Message* message,
+                 const FieldDescriptor* field, uint64 value) const;
+  void AddFloat (Message* message,
+                 const FieldDescriptor* field, float  value) const;
+  void AddDouble(Message* message,
+                 const FieldDescriptor* field, double value) const;
+  void AddBool  (Message* message,
+                 const FieldDescriptor* field, bool   value) const;
+  void AddString(Message* message,
+                 const FieldDescriptor* field, const string& value) const;
+  void AddEnum(Message* message,
+               const FieldDescriptor* field,
+               const EnumValueDescriptor* value) const;
+  Message* AddMessage(Message* message, const FieldDescriptor* field,
+                      MessageFactory* factory = NULL) const;
+
+  const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
+  const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
+
+ protected:
+  virtual void* MutableRawRepeatedField(
+      Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
+      int ctype, const Descriptor* desc) const;
+
+ private:
+  friend class GeneratedMessage;
+
+  // To parse directly into a proto2 generated class, the class GMR_Handlers
+  // needs access to member offsets and hasbits.
+  friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
+
+  const Descriptor* descriptor_;
+  const Message* default_instance_;
+  const void* default_oneof_instance_;
+  const int* offsets_;
+
+  int has_bits_offset_;
+  int oneof_case_offset_;
+  int unknown_fields_offset_;
+  int extensions_offset_;
+  int object_size_;
+
+  const DescriptorPool* descriptor_pool_;
+  MessageFactory* message_factory_;
+
+  template <typename Type>
+  inline const Type& GetRaw(const Message& message,
+                            const FieldDescriptor* field) const;
+  template <typename Type>
+  inline Type* MutableRaw(Message* message,
+                          const FieldDescriptor* field) const;
+  template <typename Type>
+  inline const Type& DefaultRaw(const FieldDescriptor* field) const;
+  template <typename Type>
+  inline const Type& DefaultOneofRaw(const FieldDescriptor* field) const;
+
+  inline const uint32* GetHasBits(const Message& message) const;
+  inline uint32* MutableHasBits(Message* message) const;
+  inline uint32 GetOneofCase(
+      const Message& message,
+      const OneofDescriptor* oneof_descriptor) const;
+  inline uint32* MutableOneofCase(
+      Message* message,
+      const OneofDescriptor* oneof_descriptor) const;
+  inline const ExtensionSet& GetExtensionSet(const Message& message) const;
+  inline ExtensionSet* MutableExtensionSet(Message* message) const;
+
+  inline bool HasBit(const Message& message,
+                     const FieldDescriptor* field) const;
+  inline void SetBit(Message* message,
+                     const FieldDescriptor* field) const;
+  inline void ClearBit(Message* message,
+                       const FieldDescriptor* field) const;
+  inline void SwapBit(Message* message1,
+                      Message* message2,
+                      const FieldDescriptor* field) const;
+
+  // This function only swaps the field. Should swap corresponding has_bit
+  // before or after using this function.
+  void SwapField(Message* message1,
+                 Message* message2,
+                 const FieldDescriptor* field) const;
+
+  void SwapOneofField(Message* message1,
+                      Message* message2,
+                      const OneofDescriptor* oneof_descriptor) const;
+
+  inline bool HasOneofField(const Message& message,
+                            const FieldDescriptor* field) const;
+  inline void SetOneofCase(Message* message,
+                           const FieldDescriptor* field) const;
+  inline void ClearOneofField(Message* message,
+                              const FieldDescriptor* field) const;
+
+  template <typename Type>
+  inline const Type& GetField(const Message& message,
+                              const FieldDescriptor* field) const;
+  template <typename Type>
+  inline void SetField(Message* message,
+                       const FieldDescriptor* field, const Type& value) const;
+  template <typename Type>
+  inline Type* MutableField(Message* message,
+                            const FieldDescriptor* field) const;
+  template <typename Type>
+  inline const Type& GetRepeatedField(const Message& message,
+                                      const FieldDescriptor* field,
+                                      int index) const;
+  template <typename Type>
+  inline const Type& GetRepeatedPtrField(const Message& message,
+                                         const FieldDescriptor* field,
+                                         int index) const;
+  template <typename Type>
+  inline void SetRepeatedField(Message* message,
+                               const FieldDescriptor* field, int index,
+                               Type value) const;
+  template <typename Type>
+  inline Type* MutableRepeatedField(Message* message,
+                                    const FieldDescriptor* field,
+                                    int index) const;
+  template <typename Type>
+  inline void AddField(Message* message,
+                       const FieldDescriptor* field, const Type& value) const;
+  template <typename Type>
+  inline Type* AddField(Message* message,
+                        const FieldDescriptor* field) const;
+
+  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)    \
+  static_cast<int>(                                           \
+      reinterpret_cast<const char*>(                          \
+          &reinterpret_cast<const TYPE*>(16)->FIELD) -        \
+      reinterpret_cast<const char*>(16))
+
+#define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD)     \
+  static_cast<int>(                                                   \
+      reinterpret_cast<const char*>(&(ONEOF->FIELD))                  \
+      - reinterpret_cast<const char*>(ONEOF))
+
+// 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/protobuf/src/google/protobuf/generated_message_reflection_unittest.cc b/protobuf/src/google/protobuf/generated_message_reflection_unittest.cc
new file mode 100644
index 0000000..ca1a291
--- /dev/null
+++ b/protobuf/src/google/protobuf/generated_message_reflection_unittest.cc
@@ -0,0 +1,795 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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);
+
+  const Reflection* reflection = message.GetReflection();
+
+  // Messages should return pointers to default instances until first use.
+  // (This is not checked by ExpectClear() since it is not actually true after
+  // the fields have been set and then cleared.)
+  EXPECT_EQ(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+            &reflection->GetMessage(message, F("optionalgroup")));
+  EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &reflection->GetMessage(message, F("optional_nested_message")));
+  EXPECT_EQ(&unittest::ForeignMessage::default_instance(),
+            &reflection->GetMessage(message, F("optional_foreign_message")));
+  EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
+            &reflection->GetMessage(message, 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);
+  TestUtil::ExpectAllFieldsSet(message);
+  reflection_tester.ExpectAllFieldsSetViaReflection(message);
+
+  reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
+  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 Reflection* reflection = message.GetReflection();
+  string scratch;
+
+  EXPECT_EQ(&message.optional_string(),
+      &reflection->GetStringReference(message, F("optional_string"), &scratch))
+    << "For simple string fields, GetStringReference() should return a "
+       "reference to the underlying string.";
+  EXPECT_EQ(&message.repeated_string(0),
+      &reflection->GetRepeatedStringReference(message, 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 Reflection* reflection = message.GetReflection();
+
+  EXPECT_NE(&unittest::TestAllTypes::OptionalGroup::default_instance(),
+            &reflection->GetMessage(message, F("optionalgroup")));
+  EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
+            &reflection->GetMessage(message, F("optional_nested_message")));
+  EXPECT_NE(&unittest::ForeignMessage::default_instance(),
+            &reflection->GetMessage(message, F("optional_foreign_message")));
+  EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
+            &reflection->GetMessage(message, F("optional_import_message")));
+}
+
+
+TEST(GeneratedMessageReflectionTest, Swap) {
+  unittest::TestAllTypes message1;
+  unittest::TestAllTypes message2;
+
+  TestUtil::SetAllFields(&message1);
+
+  const Reflection* reflection = message1.GetReflection();
+  reflection->Swap(&message1, &message2);
+
+  TestUtil::ExpectClear(message1);
+  TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapWithBothSet) {
+  unittest::TestAllTypes message1;
+  unittest::TestAllTypes message2;
+
+  TestUtil::SetAllFields(&message1);
+  TestUtil::SetAllFields(&message2);
+  TestUtil::ModifyRepeatedFields(&message2);
+
+  const Reflection* reflection = message1.GetReflection();
+  reflection->Swap(&message1, &message2);
+
+  TestUtil::ExpectRepeatedFieldsModified(message1);
+  TestUtil::ExpectAllFieldsSet(message2);
+
+  message1.set_optional_int32(532819);
+
+  reflection->Swap(&message1, &message2);
+
+  EXPECT_EQ(532819, message2.optional_int32());
+}
+
+TEST(GeneratedMessageReflectionTest, SwapExtensions) {
+  unittest::TestAllExtensions message1;
+  unittest::TestAllExtensions message2;
+
+  TestUtil::SetAllExtensions(&message1);
+
+  const Reflection* reflection = message1.GetReflection();
+  reflection->Swap(&message1, &message2);
+
+  TestUtil::ExpectExtensionsClear(message1);
+  TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapUnknown) {
+  unittest::TestEmptyMessage message1, message2;
+
+  message1.mutable_unknown_fields()->AddVarint(1234, 1);
+
+  EXPECT_EQ(1, message1.unknown_fields().field_count());
+  EXPECT_EQ(0, message2.unknown_fields().field_count());
+  const Reflection* reflection = message1.GetReflection();
+  reflection->Swap(&message1, &message2);
+  EXPECT_EQ(0, message1.unknown_fields().field_count());
+  EXPECT_EQ(1, message2.unknown_fields().field_count());
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFields) {
+  unittest::TestAllTypes message1, message2;
+  message1.set_optional_double(12.3);
+  message1.mutable_repeated_int32()->Add(10);
+  message1.mutable_repeated_int32()->Add(20);
+
+  message2.set_optional_string("hello");
+  message2.mutable_repeated_int64()->Add(30);
+
+  vector<const FieldDescriptor*> fields;
+  const Descriptor* descriptor = message1.GetDescriptor();
+  fields.push_back(descriptor->FindFieldByName("optional_double"));
+  fields.push_back(descriptor->FindFieldByName("repeated_int32"));
+  fields.push_back(descriptor->FindFieldByName("optional_string"));
+  fields.push_back(descriptor->FindFieldByName("optional_uint64"));
+
+  const Reflection* reflection = message1.GetReflection();
+  reflection->SwapFields(&message1, &message2, fields);
+
+  EXPECT_FALSE(message1.has_optional_double());
+  EXPECT_EQ(0, message1.repeated_int32_size());
+  EXPECT_TRUE(message1.has_optional_string());
+  EXPECT_EQ("hello", message1.optional_string());
+  EXPECT_EQ(0, message1.repeated_int64_size());
+  EXPECT_FALSE(message1.has_optional_uint64());
+
+  EXPECT_TRUE(message2.has_optional_double());
+  EXPECT_EQ(12.3, message2.optional_double());
+  EXPECT_EQ(2, message2.repeated_int32_size());
+  EXPECT_EQ(10, message2.repeated_int32(0));
+  EXPECT_EQ(20, message2.repeated_int32(1));
+  EXPECT_FALSE(message2.has_optional_string());
+  EXPECT_EQ(1, message2.repeated_int64_size());
+  EXPECT_FALSE(message2.has_optional_uint64());
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsAll) {
+  unittest::TestAllTypes message1;
+  unittest::TestAllTypes message2;
+
+  TestUtil::SetAllFields(&message2);
+
+  vector<const FieldDescriptor*> fields;
+  const Reflection* reflection = message1.GetReflection();
+  reflection->ListFields(message2, &fields);
+  reflection->SwapFields(&message1, &message2, fields);
+
+  TestUtil::ExpectAllFieldsSet(message1);
+  TestUtil::ExpectClear(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsAllExtension) {
+  unittest::TestAllExtensions message1;
+  unittest::TestAllExtensions message2;
+
+  TestUtil::SetAllExtensions(&message1);
+
+  vector<const FieldDescriptor*> fields;
+  const Reflection* reflection = message1.GetReflection();
+  reflection->ListFields(message1, &fields);
+  reflection->SwapFields(&message1, &message2, fields);
+
+  TestUtil::ExpectExtensionsClear(message1);
+  TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapOneof) {
+  unittest::TestOneof2 message1, message2;
+  TestUtil::SetOneof1(&message1);
+
+  const Reflection* reflection = message1.GetReflection();
+  reflection->Swap(&message1, &message2);
+
+  TestUtil::ExpectOneofClear(message1);
+  TestUtil::ExpectOneofSet1(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapOneofBothSet) {
+  unittest::TestOneof2 message1, message2;
+  TestUtil::SetOneof1(&message1);
+  TestUtil::SetOneof2(&message2);
+
+  const Reflection* reflection = message1.GetReflection();
+  reflection->Swap(&message1, &message2);
+
+  TestUtil::ExpectOneofSet2(message1);
+  TestUtil::ExpectOneofSet1(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapFieldsOneof) {
+  unittest::TestOneof2 message1, message2;
+  TestUtil::SetOneof1(&message1);
+
+  vector<const FieldDescriptor*> fields;
+  const Descriptor* descriptor = message1.GetDescriptor();
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    fields.push_back(descriptor->field(i));
+  }
+  const Reflection* reflection = message1.GetReflection();
+  reflection->SwapFields(&message1, &message2, fields);
+
+  TestUtil::ExpectOneofClear(message1);
+  TestUtil::ExpectOneofSet1(message2);
+}
+
+TEST(GeneratedMessageReflectionTest, RemoveLast) {
+  unittest::TestAllTypes message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllTypes::descriptor());
+
+  TestUtil::SetAllFields(&message);
+
+  reflection_tester.RemoveLastRepeatedsViaReflection(&message);
+
+  TestUtil::ExpectLastRepeatedsRemoved(message);
+}
+
+TEST(GeneratedMessageReflectionTest, RemoveLastExtensions) {
+  unittest::TestAllExtensions message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllExtensions::descriptor());
+
+  TestUtil::SetAllExtensions(&message);
+
+  reflection_tester.RemoveLastRepeatedsViaReflection(&message);
+
+  TestUtil::ExpectLastRepeatedExtensionsRemoved(message);
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseLast) {
+  unittest::TestAllTypes message;
+  const Descriptor* descriptor = message.GetDescriptor();
+  TestUtil::ReflectionTester reflection_tester(descriptor);
+
+  TestUtil::SetAllFields(&message);
+
+  reflection_tester.ReleaseLastRepeatedsViaReflection(&message, false);
+
+  TestUtil::ExpectLastRepeatedsReleased(message);
+
+  // Now test that we actually release the right message.
+  message.Clear();
+  TestUtil::SetAllFields(&message);
+  ASSERT_EQ(2, message.repeated_foreign_message_size());
+  const protobuf_unittest::ForeignMessage* expected =
+      message.mutable_repeated_foreign_message(1);
+  scoped_ptr<Message> released(message.GetReflection()->ReleaseLast(
+      &message, descriptor->FindFieldByName("repeated_foreign_message")));
+  EXPECT_EQ(expected, released.get());
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseLastExtensions) {
+  unittest::TestAllExtensions message;
+  const Descriptor* descriptor = message.GetDescriptor();
+  TestUtil::ReflectionTester reflection_tester(descriptor);
+
+  TestUtil::SetAllExtensions(&message);
+
+  reflection_tester.ReleaseLastRepeatedsViaReflection(&message, true);
+
+  TestUtil::ExpectLastRepeatedExtensionsReleased(message);
+
+  // Now test that we actually release the right message.
+  message.Clear();
+  TestUtil::SetAllExtensions(&message);
+  ASSERT_EQ(2, message.ExtensionSize(
+      unittest::repeated_foreign_message_extension));
+  const protobuf_unittest::ForeignMessage* expected = message.MutableExtension(
+      unittest::repeated_foreign_message_extension, 1);
+  scoped_ptr<Message> released(message.GetReflection()->ReleaseLast(
+      &message, descriptor->file()->FindExtensionByName(
+          "repeated_foreign_message_extension")));
+  EXPECT_EQ(expected, released.get());
+
+}
+
+TEST(GeneratedMessageReflectionTest, SwapRepeatedElements) {
+  unittest::TestAllTypes message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllTypes::descriptor());
+
+  TestUtil::SetAllFields(&message);
+
+  // Swap and test that fields are all swapped.
+  reflection_tester.SwapRepeatedsViaReflection(&message);
+  TestUtil::ExpectRepeatedsSwapped(message);
+
+  // Swap back and test that fields are all back to original values.
+  reflection_tester.SwapRepeatedsViaReflection(&message);
+  TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, SwapRepeatedElementsExtension) {
+  unittest::TestAllExtensions message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllExtensions::descriptor());
+
+  TestUtil::SetAllExtensions(&message);
+
+  // Swap and test that fields are all swapped.
+  reflection_tester.SwapRepeatedsViaReflection(&message);
+  TestUtil::ExpectRepeatedExtensionsSwapped(message);
+
+  // Swap back and test that fields are all back to original values.
+  reflection_tester.SwapRepeatedsViaReflection(&message);
+  TestUtil::ExpectAllExtensionsSet(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);
+  TestUtil::ExpectAllExtensionsSet(message);
+  reflection_tester.ExpectAllFieldsSetViaReflection(message);
+
+  reflection_tester.ModifyRepeatedFieldsViaReflection(&message);
+  TestUtil::ExpectRepeatedExtensionsModified(message);
+}
+
+TEST(GeneratedMessageReflectionTest, FindExtensionTypeByNumber) {
+  const 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 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);
+}
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedMessageTest) {
+  unittest::TestAllTypes from_message1;
+  unittest::TestAllTypes from_message2;
+  unittest::TestAllTypes to_message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllTypes::descriptor());
+  reflection_tester.SetAllFieldsViaReflection(&from_message1);
+  reflection_tester.SetAllFieldsViaReflection(&from_message2);
+
+  // Before moving fields, we expect the nested messages to be NULL.
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &to_message, TestUtil::ReflectionTester::IS_NULL);
+
+  // After fields are moved we should get non-NULL releases.
+  reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+      &from_message1, &to_message);
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+  // Another move to make sure that we can SetAllocated several times.
+  reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+      &from_message2, &to_message);
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+  // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the
+  // releases to be NULL again.
+  reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection(
+      &to_message);
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &to_message, TestUtil::ReflectionTester::IS_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedExtensionMessageTest) {
+  unittest::TestAllExtensions from_message1;
+  unittest::TestAllExtensions from_message2;
+  unittest::TestAllExtensions to_message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllExtensions::descriptor());
+  reflection_tester.SetAllFieldsViaReflection(&from_message1);
+  reflection_tester.SetAllFieldsViaReflection(&from_message2);
+
+  // Before moving fields, we expect the nested messages to be NULL.
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &to_message, TestUtil::ReflectionTester::IS_NULL);
+
+  // After fields are moved we should get non-NULL releases.
+  reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+      &from_message1, &to_message);
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+  // Another move to make sure that we can SetAllocated several times.
+  reflection_tester.SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+      &from_message2, &to_message);
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &to_message, TestUtil::ReflectionTester::NOT_NULL);
+
+  // After SetAllocatedOptionalMessageFieldsToNullViaReflection() we expect the
+  // releases to be NULL again.
+  reflection_tester.SetAllocatedOptionalMessageFieldsToNullViaReflection(
+      &to_message);
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &to_message, TestUtil::ReflectionTester::IS_NULL);
+}
+
+TEST(GeneratedMessageReflectionTest, ListFieldsOneOf) {
+  unittest::TestOneof2 message;
+  TestUtil::SetOneof1(&message);
+
+  const Reflection* reflection = message.GetReflection();
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(message, &fields);
+  EXPECT_EQ(4, fields.size());
+}
+
+TEST(GeneratedMessageReflectionTest, Oneof) {
+  unittest::TestOneof2 message;
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* reflection = message.GetReflection();
+
+  // Check default values.
+  EXPECT_EQ(0, reflection->GetInt32(
+      message, descriptor->FindFieldByName("foo_int")));
+  EXPECT_EQ("", reflection->GetString(
+      message, descriptor->FindFieldByName("foo_string")));
+  EXPECT_EQ("", reflection->GetString(
+      message, descriptor->FindFieldByName("foo_cord")));
+  EXPECT_EQ("", reflection->GetString(
+      message, descriptor->FindFieldByName("foo_string_piece")));
+  EXPECT_EQ("", reflection->GetString(
+      message, descriptor->FindFieldByName("foo_bytes")));
+  EXPECT_EQ(unittest::TestOneof2::FOO, reflection->GetEnum(
+      message, descriptor->FindFieldByName("foo_enum"))->number());
+  EXPECT_EQ(&unittest::TestOneof2::NestedMessage::default_instance(),
+            &reflection->GetMessage(
+                message, descriptor->FindFieldByName("foo_message")));
+  EXPECT_EQ(&unittest::TestOneof2::FooGroup::default_instance(),
+            &reflection->GetMessage(
+                message, descriptor->FindFieldByName("foogroup")));
+  EXPECT_NE(&unittest::TestOneof2::FooGroup::default_instance(),
+            &reflection->GetMessage(
+                message, descriptor->FindFieldByName("foo_lazy_message")));
+  EXPECT_EQ(5, reflection->GetInt32(
+      message, descriptor->FindFieldByName("bar_int")));
+  EXPECT_EQ("STRING", reflection->GetString(
+      message, descriptor->FindFieldByName("bar_string")));
+  EXPECT_EQ("CORD", reflection->GetString(
+      message, descriptor->FindFieldByName("bar_cord")));
+  EXPECT_EQ("SPIECE", reflection->GetString(
+      message, descriptor->FindFieldByName("bar_string_piece")));
+  EXPECT_EQ("BYTES", reflection->GetString(
+      message, descriptor->FindFieldByName("bar_bytes")));
+  EXPECT_EQ(unittest::TestOneof2::BAR, reflection->GetEnum(
+      message, descriptor->FindFieldByName("bar_enum"))->number());
+
+  // Check Set functions.
+  reflection->SetInt32(
+      &message, descriptor->FindFieldByName("foo_int"), 123);
+  EXPECT_EQ(123, reflection->GetInt32(
+      message, descriptor->FindFieldByName("foo_int")));
+  reflection->SetString(
+      &message, descriptor->FindFieldByName("foo_string"), "abc");
+  EXPECT_EQ("abc", reflection->GetString(
+      message, descriptor->FindFieldByName("foo_string")));
+  reflection->SetString(
+      &message, descriptor->FindFieldByName("foo_bytes"), "bytes");
+  EXPECT_EQ("bytes", reflection->GetString(
+      message, descriptor->FindFieldByName("foo_bytes")));
+  reflection->SetString(
+      &message, descriptor->FindFieldByName("bar_cord"), "change_cord");
+  EXPECT_EQ("change_cord", reflection->GetString(
+      message, descriptor->FindFieldByName("bar_cord")));
+  reflection->SetString(
+      &message, descriptor->FindFieldByName("bar_string_piece"),
+      "change_spiece");
+  EXPECT_EQ("change_spiece", reflection->GetString(
+      message, descriptor->FindFieldByName("bar_string_piece")));
+}
+
+TEST(GeneratedMessageReflectionTest, SetAllocatedOneofMessageTest) {
+  unittest::TestOneof2 from_message1;
+  unittest::TestOneof2 from_message2;
+  unittest::TestOneof2 to_message;
+  const Descriptor* descriptor = unittest::TestOneof2::descriptor();
+  const Reflection* reflection = to_message.GetReflection();
+
+  Message* released = reflection->ReleaseMessage(
+      &to_message, descriptor->FindFieldByName("foo_lazy_message"));
+  EXPECT_TRUE(released == NULL);
+  released = reflection->ReleaseMessage(
+      &to_message, descriptor->FindFieldByName("foo_message"));
+  EXPECT_TRUE(released == NULL);
+
+  TestUtil::ReflectionTester::SetOneofViaReflection(&from_message1);
+  TestUtil::ReflectionTester::ExpectOneofSetViaReflection(from_message1);
+
+  TestUtil::ReflectionTester::
+      SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+          &from_message1, &to_message);
+  const Message& sub_message = reflection->GetMessage(
+      to_message, descriptor->FindFieldByName("foo_lazy_message"));
+  released = reflection->ReleaseMessage(
+      &to_message, descriptor->FindFieldByName("foo_lazy_message"));
+  EXPECT_TRUE(released != NULL);
+  EXPECT_EQ(&sub_message, released);
+  delete released;
+
+  TestUtil::ReflectionTester::SetOneofViaReflection(&from_message2);
+
+  reflection->MutableMessage(
+      &from_message2, descriptor->FindFieldByName("foo_message"));
+
+  TestUtil::ReflectionTester::
+      SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+          &from_message2, &to_message);
+
+  const Message& sub_message2 = reflection->GetMessage(
+      to_message, descriptor->FindFieldByName("foo_message"));
+  released = reflection->ReleaseMessage(
+      &to_message, descriptor->FindFieldByName("foo_message"));
+  EXPECT_TRUE(released != NULL);
+  EXPECT_EQ(&sub_message2, released);
+  delete released;
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseMessageTest) {
+  unittest::TestAllTypes message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllTypes::descriptor());
+
+  // When nothing is set, we expect all released messages to be NULL.
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &message, TestUtil::ReflectionTester::IS_NULL);
+
+  // After fields are set we should get non-NULL releases.
+  reflection_tester.SetAllFieldsViaReflection(&message);
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &message, TestUtil::ReflectionTester::NOT_NULL);
+
+  // After Clear() we may or may not get a message from ReleaseMessage().
+  // This is implementation specific.
+  reflection_tester.SetAllFieldsViaReflection(&message);
+  message.Clear();
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &message, TestUtil::ReflectionTester::CAN_BE_NULL);
+
+  // Test a different code path for setting after releasing.
+  TestUtil::SetAllFields(&message);
+  TestUtil::ExpectAllFieldsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseExtensionMessageTest) {
+  unittest::TestAllExtensions message;
+  TestUtil::ReflectionTester reflection_tester(
+    unittest::TestAllExtensions::descriptor());
+
+  // When nothing is set, we expect all released messages to be NULL.
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &message, TestUtil::ReflectionTester::IS_NULL);
+
+  // After fields are set we should get non-NULL releases.
+  reflection_tester.SetAllFieldsViaReflection(&message);
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &message, TestUtil::ReflectionTester::NOT_NULL);
+
+  // After Clear() we may or may not get a message from ReleaseMessage().
+  // This is implementation specific.
+  reflection_tester.SetAllFieldsViaReflection(&message);
+  message.Clear();
+  reflection_tester.ExpectMessagesReleasedViaReflection(
+      &message, TestUtil::ReflectionTester::CAN_BE_NULL);
+
+  // Test a different code path for setting after releasing.
+  TestUtil::SetAllExtensions(&message);
+  TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(GeneratedMessageReflectionTest, ReleaseOneofMessageTest) {
+  unittest::TestOneof2 message;
+  TestUtil::ReflectionTester::SetOneofViaReflection(&message);
+
+  const Descriptor* descriptor = unittest::TestOneof2::descriptor();
+  const Reflection* reflection = message.GetReflection();
+  const Message& sub_message = reflection->GetMessage(
+      message, descriptor->FindFieldByName("foo_lazy_message"));
+  Message* released = reflection->ReleaseMessage(
+      &message, descriptor->FindFieldByName("foo_lazy_message"));
+
+  EXPECT_TRUE(released != NULL);
+  EXPECT_EQ(&sub_message, released);
+  delete released;
+
+  released = reflection->ReleaseMessage(
+      &message, descriptor->FindFieldByName("foo_lazy_message"));
+  EXPECT_TRUE(released == NULL);
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+
+TEST(GeneratedMessageReflectionTest, UsageErrors) {
+  unittest::TestAllTypes message;
+  const 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(
+      message, descriptor->FindFieldByName("optional_int64")),
+    "Protocol Buffer reflection usage error:\n"
+    "  Method      : google::protobuf::Reflection::GetInt32\n"
+    "  Message type: protobuf_unittest\\.TestAllTypes\n"
+    "  Field       : protobuf_unittest\\.TestAllTypes\\.optional_int64\n"
+    "  Problem     : Field is not the right type for this message:\n"
+    "    Expected  : CPPTYPE_INT32\n"
+    "    Field type: CPPTYPE_INT64");
+  EXPECT_DEATH(
+    reflection->GetInt32(
+      message, descriptor->FindFieldByName("repeated_int32")),
+    "Protocol Buffer reflection usage error:\n"
+    "  Method      : google::protobuf::Reflection::GetInt32\n"
+    "  Message type: protobuf_unittest.TestAllTypes\n"
+    "  Field       : protobuf_unittest.TestAllTypes.repeated_int32\n"
+    "  Problem     : Field is repeated; the method requires a singular field.");
+  EXPECT_DEATH(
+    reflection->GetInt32(
+      message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
+    "Protocol Buffer reflection usage error:\n"
+    "  Method      : google::protobuf::Reflection::GetInt32\n"
+    "  Message type: protobuf_unittest.TestAllTypes\n"
+    "  Field       : protobuf_unittest.ForeignMessage.c\n"
+    "  Problem     : Field does not match message type.");
+  EXPECT_DEATH(
+    reflection->HasField(
+      message, unittest::ForeignMessage::descriptor()->FindFieldByName("c")),
+    "Protocol Buffer reflection usage error:\n"
+    "  Method      : google::protobuf::Reflection::HasField\n"
+    "  Message type: protobuf_unittest.TestAllTypes\n"
+    "  Field       : protobuf_unittest.ForeignMessage.c\n"
+    "  Problem     : Field does not match message type.");
+
+#undef f
+}
+
+#endif  // PROTOBUF_HAS_DEATH_TEST
+
+
+}  // namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/generated_message_util.cc b/protobuf/src/google/protobuf/generated_message_util.cc
new file mode 100644
index 0000000..0c20d81
--- /dev/null
+++ b/protobuf/src/google/protobuf/generated_message_util.cc
@@ -0,0 +1,65 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/generated_message_util.h>
+
+#include <limits>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+double Infinity() {
+  return std::numeric_limits<double>::infinity();
+}
+double NaN() {
+  return std::numeric_limits<double>::quiet_NaN();
+}
+
+const ::std::string* empty_string_;
+GOOGLE_PROTOBUF_DECLARE_ONCE(empty_string_once_init_);
+
+void DeleteEmptyString() {
+  delete empty_string_;
+}
+
+void InitEmptyString() {
+  empty_string_ = new string;
+  OnShutdown(&DeleteEmptyString);
+}
+
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/generated_message_util.h b/protobuf/src/google/protobuf/generated_message_util.h
new file mode 100644
index 0000000..678f92a
--- /dev/null
+++ b/protobuf/src/google/protobuf/generated_message_util.h
@@ -0,0 +1,113 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains miscellaneous helper code used by generated code --
+// including lite types -- but which should not be used directly by users.
+
+#ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
+#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
+
+#include <assert.h>
+#include <string>
+
+#include <google/protobuf/stubs/once.h>
+
+#include <google/protobuf/stubs/common.h>
+namespace google {
+
+namespace protobuf {
+namespace internal {
+
+
+// Annotation for the compiler to emit a deprecation message if a field marked
+// with option 'deprecated=true' is used in the code, or for other things in
+// generated code which are deprecated.
+//
+// For internal use in the pb.cc files, deprecation warnings are suppressed
+// there.
+#undef DEPRECATED_PROTOBUF_FIELD
+#define PROTOBUF_DEPRECATED
+
+
+// Constants for special floating point values.
+LIBPROTOBUF_EXPORT double Infinity();
+LIBPROTOBUF_EXPORT double NaN();
+
+// TODO(jieluo): Change to template. We have tried to use template,
+// but it causes net/rpc/python:rpcutil_test fail (the empty string will
+// init twice). It may related to swig. Change to template after we
+// found the solution.
+
+// Default empty string object. Don't use the pointer directly. Instead, call
+// GetEmptyString() to get the reference.
+LIBPROTOBUF_EXPORT extern const ::std::string* empty_string_;
+LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_;
+LIBPROTOBUF_EXPORT void InitEmptyString();
+
+
+LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyStringAlreadyInited() {
+  assert(empty_string_ != NULL);
+  return *empty_string_;
+}
+LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() {
+  ::google::protobuf::GoogleOnceInit(&empty_string_once_init_, &InitEmptyString);
+  return GetEmptyStringAlreadyInited();
+}
+
+// Defined in generated_message_reflection.cc -- not actually part of the lite
+// library.
+//
+// TODO(jasonh): The various callers get this declaration from a variety of
+// places: probably in most cases repeated_field.h. Clean these up so they all
+// get the declaration from this file.
+LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str);
+
+
+// True if IsInitialized() is true for all elements of t.  Type is expected
+// to be a RepeatedPtrField<some message type>.  It's useful to have this
+// helper here to keep the protobuf compiler from ever having to emit loops in
+// IsInitialized() methods.  We want the C++ compiler to inline this or not
+// as it sees fit.
+template <class Type> bool AllAreInitialized(const Type& t) {
+  for (int i = t.size(); --i >= 0; ) {
+    if (!t.Get(i).IsInitialized()) return false;
+  }
+  return true;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__
diff --git a/protobuf/src/google/protobuf/io/coded_stream.cc b/protobuf/src/google/protobuf/io/coded_stream.cc
new file mode 100644
index 0000000..5344975
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/coded_stream.cc
@@ -0,0 +1,914 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <google/protobuf/io/coded_stream_inl.h>
+#include <algorithm>
+#include <limits.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+namespace {
+
+static const int kMaxVarintBytes = 10;
+static const int kMaxVarint32Bytes = 5;
+
+
+inline bool NextNonEmpty(ZeroCopyInputStream* input,
+                         const void** data, int* size) {
+  bool success;
+  do {
+    success = input->Next(data, size);
+  } while (success && *size == 0);
+  return success;
+}
+
+}  // namespace
+
+// CodedInputStream ==================================================
+
+CodedInputStream::~CodedInputStream() {
+  if (input_ != NULL) {
+    BackUpInputToCurrentPosition();
+  }
+
+  if (total_bytes_warning_threshold_ == -2) {
+    GOOGLE_LOG(WARNING) << "The total number of bytes read was " << total_bytes_read_;
+  }
+}
+
+// Static.
+int CodedInputStream::default_recursion_limit_ = 100;
+
+
+void CodedOutputStream::EnableAliasing(bool enabled) {
+  aliasing_enabled_ = enabled && output_->AllowsAliasing();
+}
+
+void CodedInputStream::BackUpInputToCurrentPosition() {
+  int backup_bytes = BufferSize() + buffer_size_after_limit_ + overflow_bytes_;
+  if (backup_bytes > 0) {
+    input_->BackUp(backup_bytes);
+
+    // total_bytes_read_ doesn't include overflow_bytes_.
+    total_bytes_read_ -= BufferSize() + buffer_size_after_limit_;
+    buffer_end_ = buffer_;
+    buffer_size_after_limit_ = 0;
+    overflow_bytes_ = 0;
+  }
+}
+
+inline void CodedInputStream::RecomputeBufferLimits() {
+  buffer_end_ += 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_end_ -= 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 = CurrentPosition();
+
+  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() const {
+  if (current_limit_ == INT_MAX) return -1;
+  int current_position = CurrentPosition();
+
+  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 = CurrentPosition();
+  total_bytes_limit_ = max(current_position, total_bytes_limit);
+  if (warning_threshold >= 0) {
+    total_bytes_warning_threshold_ = warning_threshold;
+  } else {
+    // warning_threshold is negative
+    total_bytes_warning_threshold_ = -1;
+  }
+  RecomputeBufferLimits();
+}
+
+int CodedInputStream::BytesUntilTotalBytesLimit() const {
+  if (total_bytes_limit_ == INT_MAX) return -1;
+  return total_bytes_limit_ - CurrentPosition();
+}
+
+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
+
+  const int original_buffer_size = BufferSize();
+
+  if (count <= original_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(original_buffer_size);
+    return false;
+  }
+
+  count -= original_buffer_size;
+  buffer_ = NULL;
+  buffer_end_ = buffer_;
+
+  // 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.
+    if (bytes_until_limit > 0) {
+      total_bytes_read_ = closest_limit;
+      input_->Skip(bytes_until_limit);
+    }
+    return false;
+  }
+
+  total_bytes_read_ += count;
+  return input_->Skip(count);
+}
+
+bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) {
+  if (BufferSize() == 0 && !Refresh()) return false;
+
+  *data = buffer_;
+  *size = BufferSize();
+  return true;
+}
+
+bool CodedInputStream::ReadRaw(void* buffer, int size) {
+  int current_buffer_size;
+  while ((current_buffer_size = BufferSize()) < size) {
+    // Reading past end of buffer.  Copy what we have, then refresh.
+    memcpy(buffer, buffer_, current_buffer_size);
+    buffer = reinterpret_cast<uint8*>(buffer) + current_buffer_size;
+    size -= current_buffer_size;
+    Advance(current_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
+  return InternalReadStringInline(buffer, size);
+}
+
+bool CodedInputStream::ReadStringFallback(string* buffer, int size) {
+  if (!buffer->empty()) {
+    buffer->clear();
+  }
+
+  int closest_limit = min(current_limit_, total_bytes_limit_);
+  if (closest_limit != INT_MAX) {
+    int bytes_to_limit = closest_limit - CurrentPosition();
+    if (bytes_to_limit > 0 && size > 0 && size <= bytes_to_limit) {
+      buffer->reserve(size);
+    }
+  }
+
+  int current_buffer_size;
+  while ((current_buffer_size = BufferSize()) < size) {
+    // Some STL implementations "helpfully" crash on buffer->append(NULL, 0).
+    if (current_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_),
+                     current_buffer_size);
+    }
+    size -= current_buffer_size;
+    Advance(current_buffer_size);
+    if (!Refresh()) return false;
+  }
+
+  buffer->append(reinterpret_cast<const char*>(buffer_), size);
+  Advance(size);
+
+  return true;
+}
+
+
+bool CodedInputStream::ReadLittleEndian32Fallback(uint32* value) {
+  uint8 bytes[sizeof(*value)];
+
+  const uint8* ptr;
+  if (BufferSize() >= 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;
+  }
+  ReadLittleEndian32FromArray(ptr, value);
+  return true;
+}
+
+bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) {
+  uint8 bytes[sizeof(*value)];
+
+  const uint8* ptr;
+  if (BufferSize() >= 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;
+  }
+  ReadLittleEndian64FromArray(ptr, value);
+  return true;
+}
+
+namespace {
+
+inline const uint8* ReadVarint32FromArray(
+    const uint8* buffer, uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) {
+  // 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      ; if (!(b & 0x80)) goto done;
+  result -= 0x80;
+  b = *(ptr++); result += b <<  7; if (!(b & 0x80)) goto done;
+  result -= 0x80 << 7;
+  b = *(ptr++); result += b << 14; if (!(b & 0x80)) goto done;
+  result -= 0x80 << 14;
+  b = *(ptr++); result += b << 21; if (!(b & 0x80)) goto done;
+  result -= 0x80 << 21;
+  b = *(ptr++); result += b << 28; if (!(b & 0x80)) goto done;
+  // "result -= 0x80 << 28" is irrevelant.
+
+  // 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 NULL;
+
+ done:
+  *value = result;
+  return ptr;
+}
+
+}  // namespace
+
+bool CodedInputStream::ReadVarint32Slow(uint32* value) {
+  uint64 result;
+  // Directly invoke ReadVarint64Fallback, since we already tried to optimize
+  // for one-byte varints.
+  if (!ReadVarint64Fallback(&result)) return false;
+  *value = (uint32)result;
+  return true;
+}
+
+bool CodedInputStream::ReadVarint32Fallback(uint32* value) {
+  if (BufferSize() >= kMaxVarintBytes ||
+      // Optimization:  We're also safe if the buffer is non-empty and it ends
+      // with a byte that would terminate a varint.
+      (buffer_end_ > buffer_ && !(buffer_end_[-1] & 0x80))) {
+    const uint8* end = ReadVarint32FromArray(buffer_, value);
+    if (end == NULL) return false;
+    buffer_ = end;
+    return true;
+  } else {
+    // Really slow case: we will incur the cost of an extra function call here,
+    // but moving this out of line reduces the size of this function, which
+    // improves the common case. In micro benchmarks, this is worth about 10-15%
+    return ReadVarint32Slow(value);
+  }
+}
+
+uint32 CodedInputStream::ReadTagSlow() {
+  if (buffer_ == buffer_end_) {
+    // 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 0;
+    }
+  }
+
+  // For the slow path, just do a 64-bit read. Try to optimize for one-byte tags
+  // again, since we have now refreshed the buffer.
+  uint64 result = 0;
+  if (!ReadVarint64(&result)) return 0;
+  return static_cast<uint32>(result);
+}
+
+uint32 CodedInputStream::ReadTagFallback() {
+  const int buf_size = BufferSize();
+  if (buf_size >= kMaxVarintBytes ||
+      // Optimization:  We're also safe if the buffer is non-empty and it ends
+      // with a byte that would terminate a varint.
+      (buf_size > 0 && !(buffer_end_[-1] & 0x80))) {
+    uint32 tag;
+    const uint8* end = ReadVarint32FromArray(buffer_, &tag);
+    if (end == NULL) {
+      return 0;
+    }
+    buffer_ = end;
+    return tag;
+  } else {
+    // We are commonly at a limit when attempting to read tags. Try to quickly
+    // detect this case without making another function call.
+    if ((buf_size == 0) &&
+        ((buffer_size_after_limit_ > 0) ||
+         (total_bytes_read_ == current_limit_)) &&
+        // 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 0;
+    }
+    return ReadTagSlow();
+  }
+}
+
+bool CodedInputStream::ReadVarint64Slow(uint64* value) {
+  // 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_ == buffer_end_) {
+      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::ReadVarint64Fallback(uint64* value) {
+  if (BufferSize() >= kMaxVarintBytes ||
+      // Optimization:  We're also safe if the buffer is non-empty and it ends
+      // with a byte that would terminate a varint.
+      (buffer_end_ > buffer_ && !(buffer_end_[-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      ; if (!(b & 0x80)) goto done;
+    part0 -= 0x80;
+    b = *(ptr++); part0 += b <<  7; if (!(b & 0x80)) goto done;
+    part0 -= 0x80 << 7;
+    b = *(ptr++); part0 += b << 14; if (!(b & 0x80)) goto done;
+    part0 -= 0x80 << 14;
+    b = *(ptr++); part0 += b << 21; if (!(b & 0x80)) goto done;
+    part0 -= 0x80 << 21;
+    b = *(ptr++); part1  = b      ; if (!(b & 0x80)) goto done;
+    part1 -= 0x80;
+    b = *(ptr++); part1 += b <<  7; if (!(b & 0x80)) goto done;
+    part1 -= 0x80 << 7;
+    b = *(ptr++); part1 += b << 14; if (!(b & 0x80)) goto done;
+    part1 -= 0x80 << 14;
+    b = *(ptr++); part1 += b << 21; if (!(b & 0x80)) goto done;
+    part1 -= 0x80 << 21;
+    b = *(ptr++); part2  = b      ; if (!(b & 0x80)) goto done;
+    part2 -= 0x80;
+    b = *(ptr++); part2 += b <<  7; if (!(b & 0x80)) goto done;
+    // "part2 -= 0x80 << 7" is irrelevant because (0x80 << 7) << 56 is 0.
+
+    // 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 {
+    return ReadVarint64Slow(value);
+  }
+}
+
+bool CodedInputStream::Refresh() {
+  GOOGLE_DCHECK_EQ(0, BufferSize());
+
+  if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
+      total_bytes_read_ == current_limit_) {
+    // We've hit a limit.  Stop.
+    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, and print total size at the end.
+    total_bytes_warning_threshold_ = -2;
+  }
+
+  const void* void_buffer;
+  int buffer_size;
+  if (NextNonEmpty(input_, &void_buffer, &buffer_size)) {
+    buffer_ = reinterpret_cast<const uint8*>(void_buffer);
+    buffer_end_ = buffer_ + buffer_size;
+    GOOGLE_CHECK_GE(buffer_size, 0);
+
+    if (total_bytes_read_ <= INT_MAX - buffer_size) {
+      total_bytes_read_ += buffer_size;
+    } else {
+      // Overflow.  Reset buffer_end_ 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_end_ -= overflow_bytes_;
+      total_bytes_read_ = INT_MAX;
+    }
+
+    RecomputeBufferLimits();
+    return true;
+  } else {
+    buffer_ = NULL;
+    buffer_end_ = NULL;
+    return false;
+  }
+}
+
+// CodedOutputStream =================================================
+
+CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
+  : output_(output),
+    buffer_(NULL),
+    buffer_size_(0),
+    total_bytes_(0),
+    had_error_(false),
+    aliasing_enabled_(false) {
+  // Eagerly Refresh() so buffer space is immediately available.
+  Refresh();
+  // The Refresh() may have failed. If the client doesn't write any data,
+  // though, don't consider this an error. If the client does write data, then
+  // another Refresh() will be attempted and it will set the error once again.
+  had_error_ = false;
+}
+
+CodedOutputStream::~CodedOutputStream() {
+  if (buffer_size_ > 0) {
+    output_->BackUp(buffer_size_);
+  }
+}
+
+bool CodedOutputStream::Skip(int count) {
+  if (count < 0) return false;
+
+  while (count > buffer_size_) {
+    count -= buffer_size_;
+    if (!Refresh()) return false;
+  }
+
+  Advance(count);
+  return true;
+}
+
+bool CodedOutputStream::GetDirectBufferPointer(void** data, int* size) {
+  if (buffer_size_ == 0 && !Refresh()) return false;
+
+  *data = buffer_;
+  *size = buffer_size_;
+  return true;
+}
+
+void 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;
+  }
+
+  memcpy(buffer_, data, size);
+  Advance(size);
+}
+
+uint8* CodedOutputStream::WriteRawToArray(
+    const void* data, int size, uint8* target) {
+  memcpy(target, data, size);
+  return target + size;
+}
+
+
+void CodedOutputStream::WriteAliasedRaw(const void* data, int size) {
+  if (size < buffer_size_
+      ) {
+    WriteRaw(data, size);
+  } else {
+    if (buffer_size_ > 0) {
+      output_->BackUp(buffer_size_);
+      total_bytes_ -= buffer_size_;
+      buffer_ = NULL;
+      buffer_size_ = 0;
+    }
+
+    total_bytes_ += size;
+    had_error_ |= !output_->WriteAliasedRaw(data, size);
+  }
+}
+
+void CodedOutputStream::WriteLittleEndian32(uint32 value) {
+  uint8 bytes[sizeof(value)];
+
+  bool use_fast = buffer_size_ >= sizeof(value);
+  uint8* ptr = use_fast ? buffer_ : bytes;
+
+  WriteLittleEndian32ToArray(value, ptr);
+
+  if (use_fast) {
+    Advance(sizeof(value));
+  } else {
+    WriteRaw(bytes, sizeof(value));
+  }
+}
+
+void CodedOutputStream::WriteLittleEndian64(uint64 value) {
+  uint8 bytes[sizeof(value)];
+
+  bool use_fast = buffer_size_ >= sizeof(value);
+  uint8* ptr = use_fast ? buffer_ : bytes;
+
+  WriteLittleEndian64ToArray(value, ptr);
+
+  if (use_fast) {
+    Advance(sizeof(value));
+  } else {
+    WriteRaw(bytes, sizeof(value));
+  }
+}
+
+inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
+    uint32 value, uint8* target) {
+  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);
+          return target + 5;
+        } else {
+          target[3] &= 0x7F;
+          return target + 4;
+        }
+      } else {
+        target[2] &= 0x7F;
+        return target + 3;
+      }
+    } else {
+      target[1] &= 0x7F;
+      return target + 2;
+    }
+  } else {
+    target[0] &= 0x7F;
+    return target + 1;
+  }
+}
+
+void CodedOutputStream::WriteVarint32(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_;
+    uint8* end = WriteVarint32FallbackToArrayInline(value, target);
+    int size = end - target;
+    Advance(size);
+  } 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;
+    WriteRaw(bytes, size);
+  }
+}
+
+uint8* CodedOutputStream::WriteVarint32FallbackToArray(
+    uint32 value, uint8* target) {
+  return WriteVarint32FallbackToArrayInline(value, target);
+}
+
+inline uint8* CodedOutputStream::WriteVarint64ToArrayInline(
+    uint64 value, uint8* target) {
+  // 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;
+  return target + size;
+}
+
+void 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_;
+
+    uint8* end = WriteVarint64ToArrayInline(value, target);
+    int size = end - target;
+    Advance(size);
+  } 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;
+    WriteRaw(bytes, size);
+  }
+}
+
+uint8* CodedOutputStream::WriteVarint64ToArray(
+    uint64 value, uint8* target) {
+  return WriteVarint64ToArrayInline(value, target);
+}
+
+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;
+    had_error_ = true;
+    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;
+    }
+  }
+}
+
+uint8* CodedOutputStream::WriteStringWithSizeToArray(const string& str,
+                                                     uint8* target) {
+  GOOGLE_DCHECK_LE(str.size(), kuint32max);
+  target = WriteVarint32ToArray(str.size(), target);
+  return WriteStringToArray(str, target);
+}
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/io/coded_stream.h b/protobuf/src/google/protobuf/io/coded_stream.h
new file mode 100644
index 0000000..81fabb1
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/coded_stream.h
@@ -0,0 +1,1220 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+#ifdef _MSC_VER
+  #if defined(_M_IX86) && \
+      !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+    #define PROTOBUF_LITTLE_ENDIAN 1
+  #endif
+  #if _MSC_VER >= 1300
+    // If MSVC has "/RTCc" set, it will complain about truncating casts at
+    // runtime.  This file contains some intentional truncating casts.
+    #pragma runtime_checks("c", off)
+  #endif
+#else
+  #include <sys/param.h>   // __BYTE_ORDER
+  #if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN && \
+      !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
+    #define PROTOBUF_LITTLE_ENDIAN 1
+  #endif
+#endif
+#include <google/protobuf/stubs/common.h>
+
+
+namespace google {
+namespace protobuf {
+
+class DescriptorPool;
+class MessageFactory;
+
+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);
+
+  // Create a CodedInputStream that reads from the given flat array.  This is
+  // faster than using an ArrayInputStream.  PushLimit(size) is implied by
+  // this constructor.
+  explicit CodedInputStream(const uint8* buffer, int size);
+
+  // 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();
+
+  // Return true if this CodedInputStream reads from a flat array instead of
+  // a ZeroCopyInputStream.
+  inline bool IsFlat() const;
+
+  // Skips a number of bytes.  Returns false if an underlying read error
+  // occurs.
+  bool Skip(int count);
+
+  // Sets *data to point directly at the unread part of the CodedInputStream's
+  // underlying buffer, and *size to the size of that buffer, but does not
+  // advance the stream's current position.  This will always either produce
+  // a non-empty buffer or return false.  If the caller consumes any of
+  // this data, it should then call Skip() to skip over the consumed bytes.
+  // This may be useful for implementing external fast parsing routines for
+  // types of data not covered by the CodedInputStream interface.
+  bool GetDirectBufferPointer(const void** data, int* size);
+
+  // Like GetDirectBufferPointer, but this method is inlined, and does not
+  // attempt to Refresh() if the buffer is currently empty.
+  inline void GetDirectBufferPointerInline(const void** data,
+                                           int* size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+  // 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);
+  // Like the above, with inlined optimizations. This should only be used
+  // by the protobuf implementation.
+  inline bool InternalReadStringInline(string* buffer,
+                                       int size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+
+  // Read a 32-bit little-endian integer.
+  bool ReadLittleEndian32(uint32* value);
+  // Read a 64-bit little-endian integer.
+  bool ReadLittleEndian64(uint64* value);
+
+  // These methods read from an externally provided buffer. The caller is
+  // responsible for ensuring that the buffer has sufficient space.
+  // Read a 32-bit little-endian integer.
+  static const uint8* ReadLittleEndian32FromArray(const uint8* buffer,
+                                                   uint32* value);
+  // Read a 64-bit little-endian integer.
+  static const uint8* ReadLittleEndian64FromArray(const uint8* buffer,
+                                                   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 one 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;
+
+  // This usually a faster alternative to ReadTag() when cutoff is a manifest
+  // constant.  It does particularly well for cutoff >= 127.  The first part
+  // of the return value is the tag that was read, though it can also be 0 in
+  // the cases where ReadTag() would return 0.  If the second part is true
+  // then the tag is known to be in [0, cutoff].  If not, the tag either is
+  // above cutoff or is 0.  (There's intentional wiggle room when tag is 0,
+  // because that can arise in several ways, and for best performance we want
+  // to avoid an extra "is tag == 0?" check here.)
+  inline std::pair<uint32, bool> ReadTagWithCutoff(uint32 cutoff)
+      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;
+
+  // Like above, except this reads from the specified buffer. The caller is
+  // responsible for ensuring that the buffer is large enough to read a varint
+  // of the expected size. For best performance, use a compile-time constant as
+  // the expected tag parameter.
+  //
+  // Returns a pointer beyond the expected tag if it was found, or NULL if it
+  // was not.
+  static const uint8* ExpectTagFromArray(
+      const uint8* buffer,
+      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() or ReadTagWithCutoff() 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() const;
+
+  // Returns current position relative to the beginning of the input stream.
+  int CurrentPosition() const;
+
+  // 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.  For backwards compatibility all negative values get squashed to -1,
+  // as other negative values might have special internal meanings.
+  // 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);
+
+  // The Total Bytes Limit minus the Current Position, or -1 if there
+  // is no Total Bytes Limit.
+  int BytesUntilTotalBytesLimit() const;
+
+  // 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 100.
+  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();
+
+  // Extension Registry ----------------------------------------------
+  // ADVANCED USAGE:  99.9% of people can ignore this section.
+  //
+  // By default, when parsing extensions, the parser looks for extension
+  // definitions in the pool which owns the outer message's Descriptor.
+  // However, you may call SetExtensionRegistry() to provide an alternative
+  // pool instead.  This makes it possible, for example, to parse a message
+  // using a generated class, but represent some extensions using
+  // DynamicMessage.
+
+  // Set the pool used to look up extensions.  Most users do not need to call
+  // this as the correct pool will be chosen automatically.
+  //
+  // WARNING:  It is very easy to misuse this.  Carefully read the requirements
+  //   below.  Do not use this unless you are sure you need it.  Almost no one
+  //   does.
+  //
+  // Let's say you are parsing a message into message object m, and you want
+  // to take advantage of SetExtensionRegistry().  You must follow these
+  // requirements:
+  //
+  // The given DescriptorPool must contain m->GetDescriptor().  It is not
+  // sufficient for it to simply contain a descriptor that has the same name
+  // and content -- it must be the *exact object*.  In other words:
+  //   assert(pool->FindMessageTypeByName(m->GetDescriptor()->full_name()) ==
+  //          m->GetDescriptor());
+  // There are two ways to satisfy this requirement:
+  // 1) Use m->GetDescriptor()->pool() as the pool.  This is generally useless
+  //    because this is the pool that would be used anyway if you didn't call
+  //    SetExtensionRegistry() at all.
+  // 2) Use a DescriptorPool which has m->GetDescriptor()->pool() as an
+  //    "underlay".  Read the documentation for DescriptorPool for more
+  //    information about underlays.
+  //
+  // You must also provide a MessageFactory.  This factory will be used to
+  // construct Message objects representing extensions.  The factory's
+  // GetPrototype() MUST return non-NULL for any Descriptor which can be found
+  // through the provided pool.
+  //
+  // If the provided factory might return instances of protocol-compiler-
+  // generated (i.e. compiled-in) types, or if the outer message object m is
+  // a generated type, then the given factory MUST have this property:  If
+  // GetPrototype() is given a Descriptor which resides in
+  // DescriptorPool::generated_pool(), the factory MUST return the same
+  // prototype which MessageFactory::generated_factory() would return.  That
+  // is, given a descriptor for a generated type, the factory must return an
+  // instance of the generated class (NOT DynamicMessage).  However, when
+  // given a descriptor for a type that is NOT in generated_pool, the factory
+  // is free to return any implementation.
+  //
+  // The reason for this requirement is that generated sub-objects may be
+  // accessed via the standard (non-reflection) extension accessor methods,
+  // and these methods will down-cast the object to the generated class type.
+  // If the object is not actually of that type, the results would be undefined.
+  // On the other hand, if an extension is not compiled in, then there is no
+  // way the code could end up accessing it via the standard accessors -- the
+  // only way to access the extension is via reflection.  When using reflection,
+  // DynamicMessage and generated messages are indistinguishable, so it's fine
+  // if these objects are represented using DynamicMessage.
+  //
+  // Using DynamicMessageFactory on which you have called
+  // SetDelegateToGeneratedFactory(true) should be sufficient to satisfy the
+  // above requirement.
+  //
+  // If either pool or factory is NULL, both must be NULL.
+  //
+  // Note that this feature is ignored when parsing "lite" messages as they do
+  // not have descriptors.
+  void SetExtensionRegistry(const DescriptorPool* pool,
+                            MessageFactory* factory);
+
+  // Get the DescriptorPool set via SetExtensionRegistry(), or NULL if no pool
+  // has been provided.
+  const DescriptorPool* GetExtensionPool();
+
+  // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no
+  // factory has been provided.
+  MessageFactory* GetExtensionFactory();
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream);
+
+  ZeroCopyInputStream* input_;
+  const uint8* buffer_;
+  const uint8* buffer_end_;     // pointer to the end of the 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() or ReadTagWithCutoff().
+
+  // This is set true by ReadTag{Fallback/Slow}() 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_;
+
+  // If positive/0: Limit for bytes read after which a warning due to size
+  // should be logged.
+  // If -1: Printing of warning disabled. Can be set by client.
+  // If -2: Internal: Limit has been reached, print full size when destructing.
+  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_;
+
+  // See SetExtensionRegistry().
+  const DescriptorPool* extension_pool_;
+  MessageFactory* extension_factory_;
+
+  // Private member functions.
+
+  // Advance the buffer by a given number of bytes.
+  void Advance(int amount);
+
+  // Back up input_ to the current buffer position.
+  void BackUpInputToCurrentPosition();
+
+  // 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(BufferSize()).
+  bool Refresh();
+
+  // When parsing varints, we optimize for the common case of small values, and
+  // then optimize for the case when the varint fits within the current buffer
+  // piece. The Fallback method is used when we can't use the one-byte
+  // optimization. The Slow method is yet another fallback when the buffer is
+  // not large enough. Making the slow path out-of-line speeds up the common
+  // case by 10-15%. The slow path is fairly uncommon: it only triggers when a
+  // message crosses multiple buffers.
+  bool ReadVarint32Fallback(uint32* value);
+  bool ReadVarint64Fallback(uint64* value);
+  bool ReadVarint32Slow(uint32* value);
+  bool ReadVarint64Slow(uint64* value);
+  bool ReadLittleEndian32Fallback(uint32* value);
+  bool ReadLittleEndian64Fallback(uint64* value);
+  // Fallback/slow methods for reading tags. These do not update last_tag_,
+  // but will set legitimate_message_end_ if we are at the end of the input
+  // stream.
+  uint32 ReadTagFallback();
+  uint32 ReadTagSlow();
+  bool ReadStringFallback(string* buffer, int size);
+
+  // Return the size of the buffer.
+  int BufferSize() const;
+
+  static const int kDefaultTotalBytesLimit = 64 << 20;  // 64MB
+
+  static const int kDefaultTotalBytesWarningThreshold = 32 << 20;  // 32MB
+
+  static int default_recursion_limit_;  // 100 by default.
+};
+
+// 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. The Write* methods do
+// not return the stream status, but will invalidate the stream if an error
+// occurs. The client can probe HadError() to determine the status.
+//
+// Note that every method of CodedOutputStream which writes some data has
+// a corresponding static "ToArray" version. These versions write directly
+// to the provided buffer, returning a pointer past the last written byte.
+// They require that the buffer has sufficient capacity for the encoded data.
+// This allows an optimization where we check if an output stream has enough
+// space for an entire message before we start writing and, if there is, we
+// call only the ToArray methods to avoid doing bound checks for each
+// individual value.
+// i.e., in the example above:
+//
+//   CodedOutputStream coded_output = new CodedOutputStream(raw_output);
+//   int magic_number = 1234;
+//   char text[] = "Hello world!";
+//
+//   int coded_size = sizeof(magic_number) +
+//                    CodedOutputStream::VarintSize32(strlen(text)) +
+//                    strlen(text);
+//
+//   uint8* buffer =
+//       coded_output->GetDirectBufferForNBytesAndAdvance(coded_size);
+//   if (buffer != NULL) {
+//     // The output stream has enough space in the buffer: write directly to
+//     // the array.
+//     buffer = CodedOutputStream::WriteLittleEndian32ToArray(magic_number,
+//                                                            buffer);
+//     buffer = CodedOutputStream::WriteVarint32ToArray(strlen(text), buffer);
+//     buffer = CodedOutputStream::WriteRawToArray(text, strlen(text), buffer);
+//   } else {
+//     // Make bound-checked writes, which will ask the underlying stream for
+//     // more space as needed.
+//     coded_output->WriteLittleEndian32(magic_number);
+//     coded_output->WriteVarint32(strlen(text));
+//     coded_output->WriteRaw(text, strlen(text));
+//   }
+//
+//   delete coded_output;
+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();
+
+  // Skips a number of bytes, leaving the bytes unmodified in the underlying
+  // buffer.  Returns false if an underlying write error occurs.  This is
+  // mainly useful with GetDirectBufferPointer().
+  bool Skip(int count);
+
+  // Sets *data to point directly at the unwritten part of the
+  // CodedOutputStream's underlying buffer, and *size to the size of that
+  // buffer, but does not advance the stream's current position.  This will
+  // always either produce a non-empty buffer or return false.  If the caller
+  // writes any data to this buffer, it should then call Skip() to skip over
+  // the consumed bytes.  This may be useful for implementing external fast
+  // serialization routines for types of data not covered by the
+  // CodedOutputStream interface.
+  bool GetDirectBufferPointer(void** data, int* size);
+
+  // If there are at least "size" bytes available in the current buffer,
+  // returns a pointer directly into the buffer and advances over these bytes.
+  // The caller may then write directly into this buffer (e.g. using the
+  // *ToArray static methods) rather than go through CodedOutputStream.  If
+  // there are not enough bytes available, returns NULL.  The return pointer is
+  // invalidated as soon as any other non-const method of CodedOutputStream
+  // is called.
+  inline uint8* GetDirectBufferForNBytesAndAdvance(int size);
+
+  // Write raw bytes, copying them from the given buffer.
+  void WriteRaw(const void* buffer, int size);
+  // Like WriteRaw()  but will try to write aliased data if aliasing is
+  // turned on.
+  void WriteRawMaybeAliased(const void* data, int size);
+  // Like WriteRaw()  but writing directly to the target array.
+  // This is _not_ inlined, as the compiler often optimizes memcpy into inline
+  // copy loops. Since this gets called by every field with string or bytes
+  // type, inlining may lead to a significant amount of code bloat, with only a
+  // minor performance gain.
+  static uint8* WriteRawToArray(const void* buffer, int size, uint8* target);
+
+  // Equivalent to WriteRaw(str.data(), str.size()).
+  void WriteString(const string& str);
+  // Like WriteString()  but writing directly to the target array.
+  static uint8* WriteStringToArray(const string& str, uint8* target);
+  // Write the varint-encoded size of str followed by str.
+  static uint8* WriteStringWithSizeToArray(const string& str, uint8* target);
+
+
+  // Instructs the CodedOutputStream to allow the underlying
+  // ZeroCopyOutputStream to hold pointers to the original structure instead of
+  // copying, if it supports it (i.e. output->AllowsAliasing() is true).  If the
+  // underlying stream does not support aliasing, then enabling it has no
+  // affect.  For now, this only affects the behavior of
+  // WriteRawMaybeAliased().
+  //
+  // NOTE: It is caller's responsibility to ensure that the chunk of memory
+  // remains live until all of the data has been consumed from the stream.
+  void EnableAliasing(bool enabled);
+
+  // Write a 32-bit little-endian integer.
+  void WriteLittleEndian32(uint32 value);
+  // Like WriteLittleEndian32()  but writing directly to the target array.
+  static uint8* WriteLittleEndian32ToArray(uint32 value, uint8* target);
+  // Write a 64-bit little-endian integer.
+  void WriteLittleEndian64(uint64 value);
+  // Like WriteLittleEndian64()  but writing directly to the target array.
+  static uint8* WriteLittleEndian64ToArray(uint64 value, uint8* target);
+
+  // 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.
+  void WriteVarint32(uint32 value);
+  // Like WriteVarint32()  but writing directly to the target array.
+  static uint8* WriteVarint32ToArray(uint32 value, uint8* target);
+  // Write an unsigned integer with Varint encoding.
+  void WriteVarint64(uint64 value);
+  // Like WriteVarint64()  but writing directly to the target array.
+  static uint8* WriteVarint64ToArray(uint64 value, uint8* target);
+
+  // Equivalent to WriteVarint32() except when the value is negative,
+  // in which case it must be sign-extended to a full 10 bytes.
+  void WriteVarint32SignExtended(int32 value);
+  // Like WriteVarint32SignExtended()  but writing directly to the target array.
+  static uint8* WriteVarint32SignExtendedToArray(int32 value, uint8* target);
+
+  // 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.
+  void WriteTag(uint32 value);
+  // Like WriteTag()  but writing directly to the target array.
+  static uint8* WriteTagToArray(
+      uint32 value, uint8* target) 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);
+
+  // Compile-time equivalent of VarintSize32().
+  template <uint32 Value>
+  struct StaticVarintSize32 {
+    static const int value =
+        (Value < (1 << 7))
+            ? 1
+            : (Value < (1 << 14))
+                ? 2
+                : (Value < (1 << 21))
+                    ? 3
+                    : (Value < (1 << 28))
+                        ? 4
+                        : 5;
+  };
+
+  // Returns the total number of bytes written since this object was created.
+  inline int ByteCount() const;
+
+  // Returns true if there was an underlying I/O error since this object was
+  // created.
+  bool HadError() const { return had_error_; }
+
+ 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.
+  bool had_error_;   // Whether an error occurred during output.
+  bool aliasing_enabled_;  // See EnableAliasing().
+
+  // 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();
+
+  // Like WriteRaw() but may avoid copying if the underlying
+  // ZeroCopyOutputStream supports it.
+  void WriteAliasedRaw(const void* buffer, int size);
+
+  static uint8* WriteVarint32FallbackToArray(uint32 value, uint8* target);
+
+  // Always-inlined versions of WriteVarint* functions so that code can be
+  // reused, while still controlling size. For instance, WriteVarint32ToArray()
+  // should not directly call this: since it is inlined itself, doing so
+  // would greatly increase the size of generated code. Instead, it should call
+  // WriteVarint32FallbackToArray.  Meanwhile, WriteVarint32() is already
+  // out-of-line, so it should just invoke this directly to avoid any extra
+  // function call overhead.
+  static uint8* WriteVarint32FallbackToArrayInline(
+      uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+  static uint8* WriteVarint64ToArrayInline(
+      uint64 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+  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 (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) {
+    *value = *buffer_;
+    Advance(1);
+    return true;
+  } else {
+    return ReadVarint32Fallback(value);
+  }
+}
+
+inline bool CodedInputStream::ReadVarint64(uint64* value) {
+  if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) {
+    *value = *buffer_;
+    Advance(1);
+    return true;
+  } else {
+    return ReadVarint64Fallback(value);
+  }
+}
+
+// static
+inline const uint8* CodedInputStream::ReadLittleEndian32FromArray(
+    const uint8* buffer,
+    uint32* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+  memcpy(value, buffer, sizeof(*value));
+  return buffer + sizeof(*value);
+#else
+  *value = (static_cast<uint32>(buffer[0])      ) |
+           (static_cast<uint32>(buffer[1]) <<  8) |
+           (static_cast<uint32>(buffer[2]) << 16) |
+           (static_cast<uint32>(buffer[3]) << 24);
+  return buffer + sizeof(*value);
+#endif
+}
+// static
+inline const uint8* CodedInputStream::ReadLittleEndian64FromArray(
+    const uint8* buffer,
+    uint64* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+  memcpy(value, buffer, sizeof(*value));
+  return buffer + sizeof(*value);
+#else
+  uint32 part0 = (static_cast<uint32>(buffer[0])      ) |
+                 (static_cast<uint32>(buffer[1]) <<  8) |
+                 (static_cast<uint32>(buffer[2]) << 16) |
+                 (static_cast<uint32>(buffer[3]) << 24);
+  uint32 part1 = (static_cast<uint32>(buffer[4])      ) |
+                 (static_cast<uint32>(buffer[5]) <<  8) |
+                 (static_cast<uint32>(buffer[6]) << 16) |
+                 (static_cast<uint32>(buffer[7]) << 24);
+  *value = static_cast<uint64>(part0) |
+          (static_cast<uint64>(part1) << 32);
+  return buffer + sizeof(*value);
+#endif
+}
+
+inline bool CodedInputStream::ReadLittleEndian32(uint32* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+  if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
+    memcpy(value, buffer_, sizeof(*value));
+    Advance(sizeof(*value));
+    return true;
+  } else {
+    return ReadLittleEndian32Fallback(value);
+  }
+#else
+  return ReadLittleEndian32Fallback(value);
+#endif
+}
+
+inline bool CodedInputStream::ReadLittleEndian64(uint64* value) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+  if (GOOGLE_PREDICT_TRUE(BufferSize() >= static_cast<int>(sizeof(*value)))) {
+    memcpy(value, buffer_, sizeof(*value));
+    Advance(sizeof(*value));
+    return true;
+  } else {
+    return ReadLittleEndian64Fallback(value);
+  }
+#else
+  return ReadLittleEndian64Fallback(value);
+#endif
+}
+
+inline uint32 CodedInputStream::ReadTag() {
+  if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] < 0x80) {
+    last_tag_ = buffer_[0];
+    Advance(1);
+    return last_tag_;
+  } else {
+    last_tag_ = ReadTagFallback();
+    return last_tag_;
+  }
+}
+
+inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff(
+    uint32 cutoff) {
+  // In performance-sensitive code we can expect cutoff to be a compile-time
+  // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at
+  // compile time.
+  if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) {
+    // Hot case: buffer_ non_empty, buffer_[0] in [1, 128).
+    // TODO(gpike): Is it worth rearranging this? E.g., if the number of fields
+    // is large enough then is it better to check for the two-byte case first?
+    if (static_cast<int8>(buffer_[0]) > 0) {
+      const uint32 kMax1ByteVarint = 0x7f;
+      uint32 tag = last_tag_ = buffer_[0];
+      Advance(1);
+      return make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff);
+    }
+    // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available,
+    // and tag is two bytes.  The latter is tested by bitwise-and-not of the
+    // first byte and the second byte.
+    if (cutoff >= 0x80 &&
+        GOOGLE_PREDICT_TRUE(buffer_ + 1 < buffer_end_) &&
+        GOOGLE_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) {
+      const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f;
+      uint32 tag = last_tag_ = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80);
+      Advance(2);
+      // It might make sense to test for tag == 0 now, but it is so rare that
+      // that we don't bother.  A varint-encoded 0 should be one byte unless
+      // the encoder lost its mind.  The second part of the return value of
+      // this function is allowed to be either true or false if the tag is 0,
+      // so we don't have to check for tag == 0.  We may need to check whether
+      // it exceeds cutoff.
+      bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff;
+      return make_pair(tag, at_or_below_cutoff);
+    }
+  }
+  // Slow path
+  last_tag_ = ReadTagFallback();
+  return make_pair(last_tag_, static_cast<uint32>(last_tag_ - 1) < cutoff);
+}
+
+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 (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] == expected) {
+      Advance(1);
+      return true;
+    } else {
+      return false;
+    }
+  } else if (expected < (1 << 14)) {
+    if (GOOGLE_PREDICT_TRUE(BufferSize() >= 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 const uint8* CodedInputStream::ExpectTagFromArray(
+    const uint8* buffer, uint32 expected) {
+  if (expected < (1 << 7)) {
+    if (buffer[0] == expected) {
+      return buffer + 1;
+    }
+  } else if (expected < (1 << 14)) {
+    if (buffer[0] == static_cast<uint8>(expected | 0x80) &&
+        buffer[1] == static_cast<uint8>(expected >> 7)) {
+      return buffer + 2;
+    }
+  }
+  return NULL;
+}
+
+inline void CodedInputStream::GetDirectBufferPointerInline(const void** data,
+                                                           int* size) {
+  *data = buffer_;
+  *size = buffer_end_ - buffer_;
+}
+
+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_ == buffer_end_ &&
+      ((buffer_size_after_limit_ != 0) ||
+       (total_bytes_read_ == current_limit_))) {
+    last_tag_ = 0;                   // Pretend we called ReadTag()...
+    legitimate_message_end_ = true;  // ... and it hit EOF.
+    return true;
+  } else {
+    return false;
+  }
+}
+
+inline int CodedInputStream::CurrentPosition() const {
+  return total_bytes_read_ - (BufferSize() + buffer_size_after_limit_);
+}
+
+inline uint8* CodedOutputStream::GetDirectBufferForNBytesAndAdvance(int size) {
+  if (buffer_size_ < size) {
+    return NULL;
+  } else {
+    uint8* result = buffer_;
+    Advance(size);
+    return result;
+  }
+}
+
+inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value,
+                                                        uint8* target) {
+  if (value < 0x80) {
+    *target = value;
+    return target + 1;
+  } else {
+    return WriteVarint32FallbackToArray(value, target);
+  }
+}
+
+inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) {
+  if (value < 0) {
+    WriteVarint64(static_cast<uint64>(value));
+  } else {
+    WriteVarint32(static_cast<uint32>(value));
+  }
+}
+
+inline uint8* CodedOutputStream::WriteVarint32SignExtendedToArray(
+    int32 value, uint8* target) {
+  if (value < 0) {
+    return WriteVarint64ToArray(static_cast<uint64>(value), target);
+  } else {
+    return WriteVarint32ToArray(static_cast<uint32>(value), target);
+  }
+}
+
+inline uint8* CodedOutputStream::WriteLittleEndian32ToArray(uint32 value,
+                                                            uint8* target) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+  memcpy(target, &value, sizeof(value));
+#else
+  target[0] = static_cast<uint8>(value);
+  target[1] = static_cast<uint8>(value >>  8);
+  target[2] = static_cast<uint8>(value >> 16);
+  target[3] = static_cast<uint8>(value >> 24);
+#endif
+  return target + sizeof(value);
+}
+
+inline uint8* CodedOutputStream::WriteLittleEndian64ToArray(uint64 value,
+                                                            uint8* target) {
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+  memcpy(target, &value, sizeof(value));
+#else
+  uint32 part0 = static_cast<uint32>(value);
+  uint32 part1 = static_cast<uint32>(value >> 32);
+
+  target[0] = static_cast<uint8>(part0);
+  target[1] = static_cast<uint8>(part0 >>  8);
+  target[2] = static_cast<uint8>(part0 >> 16);
+  target[3] = static_cast<uint8>(part0 >> 24);
+  target[4] = static_cast<uint8>(part1);
+  target[5] = static_cast<uint8>(part1 >>  8);
+  target[6] = static_cast<uint8>(part1 >> 16);
+  target[7] = static_cast<uint8>(part1 >> 24);
+#endif
+  return target + sizeof(value);
+}
+
+inline void CodedOutputStream::WriteTag(uint32 value) {
+  WriteVarint32(value);
+}
+
+inline uint8* CodedOutputStream::WriteTagToArray(
+    uint32 value, uint8* target) {
+  if (value < (1 << 7)) {
+    target[0] = value;
+    return target + 1;
+  } else if (value < (1 << 14)) {
+    target[0] = static_cast<uint8>(value | 0x80);
+    target[1] = static_cast<uint8>(value >> 7);
+    return target + 2;
+  } else {
+    return WriteVarint32FallbackToArray(value, target);
+  }
+}
+
+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 void CodedOutputStream::WriteString(const string& str) {
+  WriteRaw(str.data(), static_cast<int>(str.size()));
+}
+
+inline void CodedOutputStream::WriteRawMaybeAliased(
+    const void* data, int size) {
+  if (aliasing_enabled_) {
+    WriteAliasedRaw(data, size);
+  } else {
+    WriteRaw(data, size);
+  }
+}
+
+inline uint8* CodedOutputStream::WriteStringToArray(
+    const string& str, uint8* target) {
+  return WriteRawToArray(str.data(), static_cast<int>(str.size()), target);
+}
+
+inline int CodedOutputStream::ByteCount() const {
+  return total_bytes_ - buffer_size_;
+}
+
+inline void CodedInputStream::Advance(int amount) {
+  buffer_ += 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_;
+}
+
+inline void CodedInputStream::SetExtensionRegistry(const DescriptorPool* pool,
+                                                   MessageFactory* factory) {
+  extension_pool_ = pool;
+  extension_factory_ = factory;
+}
+
+inline const DescriptorPool* CodedInputStream::GetExtensionPool() {
+  return extension_pool_;
+}
+
+inline MessageFactory* CodedInputStream::GetExtensionFactory() {
+  return extension_factory_;
+}
+
+inline int CodedInputStream::BufferSize() const {
+  return buffer_end_ - buffer_;
+}
+
+inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input)
+  : input_(input),
+    buffer_(NULL),
+    buffer_end_(NULL),
+    total_bytes_read_(0),
+    overflow_bytes_(0),
+    last_tag_(0),
+    legitimate_message_end_(false),
+    aliasing_enabled_(false),
+    current_limit_(kint32max),
+    buffer_size_after_limit_(0),
+    total_bytes_limit_(kDefaultTotalBytesLimit),
+    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
+    recursion_depth_(0),
+    recursion_limit_(default_recursion_limit_),
+    extension_pool_(NULL),
+    extension_factory_(NULL) {
+  // Eagerly Refresh() so buffer space is immediately available.
+  Refresh();
+}
+
+inline CodedInputStream::CodedInputStream(const uint8* buffer, int size)
+  : input_(NULL),
+    buffer_(buffer),
+    buffer_end_(buffer + size),
+    total_bytes_read_(size),
+    overflow_bytes_(0),
+    last_tag_(0),
+    legitimate_message_end_(false),
+    aliasing_enabled_(false),
+    current_limit_(size),
+    buffer_size_after_limit_(0),
+    total_bytes_limit_(kDefaultTotalBytesLimit),
+    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
+    recursion_depth_(0),
+    recursion_limit_(default_recursion_limit_),
+    extension_pool_(NULL),
+    extension_factory_(NULL) {
+  // Note that setting current_limit_ == size is important to prevent some
+  // code paths from trying to access input_ and segfaulting.
+}
+
+inline bool CodedInputStream::IsFlat() const {
+  return input_ == NULL;
+}
+
+}  // namespace io
+}  // namespace protobuf
+
+
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+  #pragma runtime_checks("c", restore)
+#endif  // _MSC_VER
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__
diff --git a/protobuf/src/google/protobuf/io/coded_stream_inl.h b/protobuf/src/google/protobuf/io/coded_stream_inl.h
new file mode 100644
index 0000000..88c14ca
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/coded_stream_inl.h
@@ -0,0 +1,69 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jasonh@google.com (Jason Hsueh)
+//
+// Implements methods of coded_stream.h that need to be inlined for performance
+// reasons, but should not be defined in a public header.
+
+#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
+#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
+
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <string>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+inline bool CodedInputStream::InternalReadStringInline(string* buffer,
+                                                       int size) {
+  if (size < 0) return false;  // security: size is often user-supplied
+
+  if (BufferSize() >= size) {
+    STLStringResizeUninitialized(buffer, size);
+    // When buffer is empty, string_as_array(buffer) will return NULL but memcpy
+    // requires non-NULL pointers even when size is 0. Hench this check.
+    if (size > 0) {
+      memcpy(mutable_string_data(buffer), buffer_, size);
+      Advance(size);
+    }
+    return true;
+  }
+
+  return ReadStringFallback(buffer, size);
+}
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
diff --git a/protobuf/src/google/protobuf/io/coded_stream_unittest.cc b/protobuf/src/google/protobuf/io/coded_stream_unittest.cc
new file mode 100644
index 0000000..f4cb5ea
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/coded_stream_unittest.cc
@@ -0,0 +1,1378 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+
+
+// 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<<.
+
+// TODO(kenton):  gTest now supports "parameterized tests" which would be
+//   a better way to accomplish this.  Rewrite when time permits.
+
+#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:
+  // Helper method used by tests for bytes warning. See implementation comment
+  // for further information.
+  static void SetupTotalBytesLimitWarningTest(
+      int total_bytes_limit, int warning_threshold,
+      vector<string>* out_errors, vector<string>* out_warnings);
+
+  // Buffer used during most of the tests. This assumes tests run sequentially.
+  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());
+}
+
+// This is the regression test that verifies that there is no issues
+// with the empty input buffers handling.
+TEST_F(CodedStreamTest, EmptyInputBeforeEos) {
+  class In : public ZeroCopyInputStream {
+   public:
+    In() : count_(0) {}
+   private:
+    virtual bool Next(const void** data, int* size) {
+      *data = NULL;
+      *size = 0;
+      return count_++ < 2;
+    }
+    virtual void BackUp(int count)  {
+      GOOGLE_LOG(FATAL) << "Tests never call this.";
+    }
+    virtual bool Skip(int count) {
+      GOOGLE_LOG(FATAL) << "Tests never call this.";
+      return false;
+    }
+    virtual int64 ByteCount() const { return 0; }
+    int count_;
+  } in;
+  CodedInputStream input(&in);
+  input.ReadTag();
+  EXPECT_TRUE(input.ConsumedEntireMessage());
+}
+
+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_1D(CodedStreamTest, ExpectTagFromArray, kVarintCases) {
+  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
+
+  const uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
+
+  // If the expectation succeeds, it should return a pointer past the tag.
+  if (kVarintCases_case.size <= 2) {
+    EXPECT_TRUE(NULL ==
+                CodedInputStream::ExpectTagFromArray(buffer_,
+                                                     expected_value + 1));
+    EXPECT_TRUE(buffer_ + kVarintCases_case.size ==
+                CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
+  } else {
+    EXPECT_TRUE(NULL ==
+                CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
+  }
+}
+
+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);
+
+    coded_output.WriteVarint32(static_cast<uint32>(kVarintCases_case.value));
+    EXPECT_FALSE(coded_output.HadError());
+
+    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);
+
+    coded_output.WriteVarint64(kVarintCases_case.value);
+    EXPECT_FALSE(coded_output.HadError());
+
+    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);
+
+    coded_output.WriteVarint32SignExtended(kSignExtendedVarintCases_case);
+    EXPECT_FALSE(coded_output.HadError());
+
+    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);
+
+    coded_output.WriteLittleEndian32(kFixed32Cases_case.value);
+    EXPECT_FALSE(coded_output.HadError());
+
+    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);
+
+    coded_output.WriteLittleEndian64(kFixed64Cases_case.value);
+    EXPECT_FALSE(coded_output.HadError());
+
+    EXPECT_EQ(sizeof(uint64), coded_output.ByteCount());
+  }
+
+  EXPECT_EQ(sizeof(uint64), output.ByteCount());
+  EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64)));
+}
+
+// Tests using the static methods to read fixed-size values from raw arrays.
+
+TEST_1D(CodedStreamTest, ReadLittleEndian32FromArray, kFixed32Cases) {
+  memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
+
+  uint32 value;
+  const uint8* end = CodedInputStream::ReadLittleEndian32FromArray(
+      buffer_, &value);
+  EXPECT_EQ(kFixed32Cases_case.value, value);
+  EXPECT_TRUE(end == buffer_ + sizeof(value));
+}
+
+TEST_1D(CodedStreamTest, ReadLittleEndian64FromArray, kFixed64Cases) {
+  memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
+
+  uint64 value;
+  const uint8* end = CodedInputStream::ReadLittleEndian64FromArray(
+      buffer_, &value);
+  EXPECT_EQ(kFixed64Cases_case.value, value);
+  EXPECT_TRUE(end == buffer_ + sizeof(value));
+}
+
+// -------------------------------------------------------------------
+// Raw reads and writes
+
+const char kRawBytes[] = "Some bytes which will be written 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);
+
+    coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes));
+    EXPECT_FALSE(coded_output.HadError());
+
+    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));
+  }
+}
+
+TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnStack) {
+  // Same test as above, except directly use a buffer. This used to cause
+  // crashes while the above did not.
+  uint8 buffer[8];
+  CodedInputStream coded_input(buffer, 8);
+  string str;
+  EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+}
+
+TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) {
+  scoped_array<uint8> buffer(new uint8[8]);
+  CodedInputStream coded_input(buffer.get(), 8);
+  string str;
+  EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+}
+
+TEST_1D(CodedStreamTest, ReadStringReservesMemoryOnTotalLimit, kBlockSizes) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+    coded_input.SetTotalBytesLimit(sizeof(kRawBytes), sizeof(kRawBytes));
+    EXPECT_EQ(sizeof(kRawBytes), coded_input.BytesUntilTotalBytesLimit());
+
+    string str;
+    EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+    EXPECT_EQ(sizeof(kRawBytes) - strlen(kRawBytes),
+              coded_input.BytesUntilTotalBytesLimit());
+    EXPECT_EQ(kRawBytes, str);
+    // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
+    EXPECT_GE(str.capacity(), strlen(kRawBytes));
+  }
+
+  EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+TEST_1D(CodedStreamTest, ReadStringReservesMemoryOnPushedLimit, kBlockSizes) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
+
+  {
+    CodedInputStream coded_input(&input);
+    coded_input.PushLimit(sizeof(buffer_));
+
+    string str;
+    EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+    EXPECT_EQ(kRawBytes, str);
+    // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
+    EXPECT_GE(str.capacity(), strlen(kRawBytes));
+  }
+
+  EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationIfLimitsNotSet) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  // Buffer size in the input must be smaller than sizeof(kRawBytes),
+  // otherwise check against capacity will fail as ReadStringInline()
+  // will handle the reading and will reserve the memory as needed.
+  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+  {
+    CodedInputStream coded_input(&input);
+
+    string str;
+    EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
+    EXPECT_EQ(kRawBytes, str);
+    // Note: this check depends on string class implementation. It
+    // expects that string will allocate more than strlen(kRawBytes)
+    // if the content of kRawBytes is appended to string in small
+    // chunks.
+    // TODO(liujisi): Replace with a more meaningful test (see cl/60966023).
+    EXPECT_GE(str.capacity(), strlen(kRawBytes));
+  }
+
+  EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsNegative) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  // Buffer size in the input must be smaller than sizeof(kRawBytes),
+  // otherwise check against capacity will fail as ReadStringInline()
+  // will handle the reading and will reserve the memory as needed.
+  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+  {
+    CodedInputStream coded_input(&input);
+    coded_input.PushLimit(sizeof(buffer_));
+
+    string str;
+    EXPECT_FALSE(coded_input.ReadString(&str, -1));
+    // Note: this check depends on string class implementation. It
+    // expects that string will always allocate the same amount of
+    // memory for an empty string.
+    EXPECT_EQ(string().capacity(), str.capacity());
+  }
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsLarge) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  // Buffer size in the input must be smaller than sizeof(kRawBytes),
+  // otherwise check against capacity will fail as ReadStringInline()
+  // will handle the reading and will reserve the memory as needed.
+  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+  {
+    CodedInputStream coded_input(&input);
+    coded_input.PushLimit(sizeof(buffer_));
+
+    string str;
+    EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
+    EXPECT_GT(1 << 30, str.capacity());
+  }
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsOverTheLimit) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  // Buffer size in the input must be smaller than sizeof(kRawBytes),
+  // otherwise check against capacity will fail as ReadStringInline()
+  // will handle the reading and will reserve the memory as needed.
+  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+  {
+    CodedInputStream coded_input(&input);
+    coded_input.PushLimit(16);
+
+    string str;
+    EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+    // Note: this check depends on string class implementation. It
+    // expects that string will allocate less than strlen(kRawBytes)
+    // for an empty string.
+    EXPECT_GT(strlen(kRawBytes), str.capacity());
+  }
+}
+
+TEST_F(CodedStreamTest, ReadStringNoReservationSizeIsOverTheTotalBytesLimit) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  // Buffer size in the input must be smaller than sizeof(kRawBytes),
+  // otherwise check against capacity will fail as ReadStringInline()
+  // will handle the reading and will reserve the memory as needed.
+  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+  {
+    CodedInputStream coded_input(&input);
+    coded_input.SetTotalBytesLimit(16, 16);
+
+    string str;
+    EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+    // Note: this check depends on string class implementation. It
+    // expects that string will allocate less than strlen(kRawBytes)
+    // for an empty string.
+    EXPECT_GT(strlen(kRawBytes), str.capacity());
+  }
+}
+
+TEST_F(CodedStreamTest,
+       ReadStringNoReservationSizeIsOverTheClosestLimit_GlobalLimitIsCloser) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  // Buffer size in the input must be smaller than sizeof(kRawBytes),
+  // otherwise check against capacity will fail as ReadStringInline()
+  // will handle the reading and will reserve the memory as needed.
+  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+  {
+    CodedInputStream coded_input(&input);
+    coded_input.PushLimit(sizeof(buffer_));
+    coded_input.SetTotalBytesLimit(16, 16);
+
+    string str;
+    EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+    // Note: this check depends on string class implementation. It
+    // expects that string will allocate less than strlen(kRawBytes)
+    // for an empty string.
+    EXPECT_GT(strlen(kRawBytes), str.capacity());
+  }
+}
+
+TEST_F(CodedStreamTest,
+       ReadStringNoReservationSizeIsOverTheClosestLimit_LocalLimitIsCloser) {
+  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
+  // Buffer size in the input must be smaller than sizeof(kRawBytes),
+  // otherwise check against capacity will fail as ReadStringInline()
+  // will handle the reading and will reserve the memory as needed.
+  ArrayInputStream input(buffer_, sizeof(buffer_), 32);
+
+  {
+    CodedInputStream coded_input(&input);
+    coded_input.PushLimit(16);
+    coded_input.SetTotalBytesLimit(sizeof(buffer_), sizeof(buffer_));
+    EXPECT_EQ(sizeof(buffer_), coded_input.BytesUntilTotalBytesLimit());
+
+    string str;
+    EXPECT_FALSE(coded_input.ReadString(&str, strlen(kRawBytes)));
+    // Note: this check depends on string class implementation. It
+    // expects that string will allocate less than strlen(kRawBytes)
+    // for an empty string.
+    EXPECT_GT(strlen(kRawBytes), str.capacity());
+  }
+}
+
+
+// -------------------------------------------------------------------
+// Skip
+
+const char kSkipTestBytes[] =
+  "<Before skipping><To be skipped><After skipping>";
+
+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());
+}
+
+// -------------------------------------------------------------------
+// GetDirectBufferPointer
+
+TEST_F(CodedStreamTest, GetDirectBufferPointerInput) {
+  ArrayInputStream input(buffer_, sizeof(buffer_), 8);
+  CodedInputStream coded_input(&input);
+
+  const void* ptr;
+  int size;
+
+  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+  EXPECT_EQ(buffer_, ptr);
+  EXPECT_EQ(8, size);
+
+  // Peeking again should return the same pointer.
+  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+  EXPECT_EQ(buffer_, ptr);
+  EXPECT_EQ(8, size);
+
+  // Skip forward in the same buffer then peek again.
+  EXPECT_TRUE(coded_input.Skip(3));
+  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+  EXPECT_EQ(buffer_ + 3, ptr);
+  EXPECT_EQ(5, size);
+
+  // Skip to end of buffer and peek -- should get next buffer.
+  EXPECT_TRUE(coded_input.Skip(5));
+  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
+  EXPECT_EQ(buffer_ + 8, ptr);
+  EXPECT_EQ(8, size);
+}
+
+TEST_F(CodedStreamTest, GetDirectBufferPointerInlineInput) {
+  ArrayInputStream input(buffer_, sizeof(buffer_), 8);
+  CodedInputStream coded_input(&input);
+
+  const void* ptr;
+  int size;
+
+  coded_input.GetDirectBufferPointerInline(&ptr, &size);
+  EXPECT_EQ(buffer_, ptr);
+  EXPECT_EQ(8, size);
+
+  // Peeking again should return the same pointer.
+  coded_input.GetDirectBufferPointerInline(&ptr, &size);
+  EXPECT_EQ(buffer_, ptr);
+  EXPECT_EQ(8, size);
+
+  // Skip forward in the same buffer then peek again.
+  EXPECT_TRUE(coded_input.Skip(3));
+  coded_input.GetDirectBufferPointerInline(&ptr, &size);
+  EXPECT_EQ(buffer_ + 3, ptr);
+  EXPECT_EQ(5, size);
+
+  // Skip to end of buffer and peek -- should return false and provide an empty
+  // buffer. It does not try to Refresh().
+  EXPECT_TRUE(coded_input.Skip(5));
+  coded_input.GetDirectBufferPointerInline(&ptr, &size);
+  EXPECT_EQ(buffer_ + 8, ptr);
+  EXPECT_EQ(0, size);
+}
+
+TEST_F(CodedStreamTest, GetDirectBufferPointerOutput) {
+  ArrayOutputStream output(buffer_, sizeof(buffer_), 8);
+  CodedOutputStream coded_output(&output);
+
+  void* ptr;
+  int size;
+
+  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+  EXPECT_EQ(buffer_, ptr);
+  EXPECT_EQ(8, size);
+
+  // Peeking again should return the same pointer.
+  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+  EXPECT_EQ(buffer_, ptr);
+  EXPECT_EQ(8, size);
+
+  // Skip forward in the same buffer then peek again.
+  EXPECT_TRUE(coded_output.Skip(3));
+  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+  EXPECT_EQ(buffer_ + 3, ptr);
+  EXPECT_EQ(5, size);
+
+  // Skip to end of buffer and peek -- should get next buffer.
+  EXPECT_TRUE(coded_output.Skip(5));
+  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+  EXPECT_EQ(buffer_ + 8, ptr);
+  EXPECT_EQ(8, size);
+
+  // Skip over multiple buffers.
+  EXPECT_TRUE(coded_output.Skip(22));
+  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
+  EXPECT_EQ(buffer_ + 30, ptr);
+  EXPECT_EQ(2, size);
+}
+
+// -------------------------------------------------------------------
+// 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);
+  EXPECT_EQ(16, coded_input.BytesUntilTotalBytesLimit());
+
+  string str;
+  EXPECT_TRUE(coded_input.ReadString(&str, 16));
+  EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit());
+
+  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_EQ(16, coded_input.BytesUntilTotalBytesLimit());
+  EXPECT_TRUE(coded_input.ReadString(&str, 16));
+  EXPECT_EQ(0, coded_input.BytesUntilTotalBytesLimit());
+}
+
+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());
+}
+
+// This method is used by the tests below.
+// It constructs a CodedInputStream with the given limits and tries to read 2KiB
+// of data from it. Then it returns the logged errors and warnings in the given
+// vectors.
+void CodedStreamTest::SetupTotalBytesLimitWarningTest(
+    int total_bytes_limit, int warning_threshold,
+    vector<string>* out_errors, vector<string>* out_warnings) {
+  ArrayInputStream raw_input(buffer_, sizeof(buffer_), 128);
+
+  ScopedMemoryLog scoped_log;
+  {
+    CodedInputStream input(&raw_input);
+    input.SetTotalBytesLimit(total_bytes_limit, warning_threshold);
+    string str;
+    EXPECT_TRUE(input.ReadString(&str, 2048));
+  }
+
+  *out_errors = scoped_log.GetMessages(ERROR);
+  *out_warnings = scoped_log.GetMessages(WARNING);
+}
+
+TEST_F(CodedStreamTest, TotalBytesLimitWarning) {
+  vector<string> errors;
+  vector<string> warnings;
+  SetupTotalBytesLimitWarningTest(10240, 1024, &errors, &warnings);
+
+  EXPECT_EQ(0, errors.size());
+
+  ASSERT_EQ(2, warnings.size());
+  EXPECT_PRED_FORMAT2(testing::IsSubstring,
+    "Reading dangerously large protocol message.  If the message turns out to "
+    "be larger than 10240 bytes, parsing will be halted for security reasons.",
+    warnings[0]);
+  EXPECT_PRED_FORMAT2(testing::IsSubstring,
+    "The total number of bytes read was 2048",
+    warnings[1]);
+}
+
+TEST_F(CodedStreamTest, TotalBytesLimitWarningDisabled) {
+  vector<string> errors;
+  vector<string> warnings;
+
+  // Test with -1
+  SetupTotalBytesLimitWarningTest(10240, -1, &errors, &warnings);
+  EXPECT_EQ(0, errors.size());
+  EXPECT_EQ(0, warnings.size());
+
+  // Test again with -2, expecting the same result
+  SetupTotalBytesLimitWarningTest(10240, -2, &errors, &warnings);
+  EXPECT_EQ(0, errors.size());
+  EXPECT_EQ(0, warnings.size());
+}
+
+
+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/protobuf/src/google/protobuf/io/gzip_stream.cc b/protobuf/src/google/protobuf/io/gzip_stream.cc
new file mode 100644
index 0000000..ee28696
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/gzip_stream.cc
@@ -0,0 +1,326 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: brianolson@google.com (Brian Olson)
+//
+// This file contains the implementation of classes GzipInputStream and
+// GzipOutputStream.
+
+#include "config.h"
+
+#if HAVE_ZLIB
+#include <google/protobuf/io/gzip_stream.h>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+static const int kDefaultBufferSize = 65536;
+
+GzipInputStream::GzipInputStream(
+    ZeroCopyInputStream* sub_stream, Format format, int buffer_size)
+    : format_(format), sub_stream_(sub_stream), zerror_(Z_OK) {
+  zcontext_.zalloc = Z_NULL;
+  zcontext_.zfree = Z_NULL;
+  zcontext_.opaque = Z_NULL;
+  zcontext_.total_out = 0;
+  zcontext_.next_in = NULL;
+  zcontext_.avail_in = 0;
+  zcontext_.total_in = 0;
+  zcontext_.msg = NULL;
+  if (buffer_size == -1) {
+    output_buffer_length_ = kDefaultBufferSize;
+  } else {
+    output_buffer_length_ = buffer_size;
+  }
+  output_buffer_ = operator new(output_buffer_length_);
+  GOOGLE_CHECK(output_buffer_ != NULL);
+  zcontext_.next_out = static_cast<Bytef*>(output_buffer_);
+  zcontext_.avail_out = output_buffer_length_;
+  output_position_ = output_buffer_;
+}
+GzipInputStream::~GzipInputStream() {
+  operator delete(output_buffer_);
+  zerror_ = inflateEnd(&zcontext_);
+}
+
+static inline int internalInflateInit2(
+    z_stream* zcontext, GzipInputStream::Format format) {
+  int windowBitsFormat = 0;
+  switch (format) {
+    case GzipInputStream::GZIP: windowBitsFormat = 16; break;
+    case GzipInputStream::AUTO: windowBitsFormat = 32; break;
+    case GzipInputStream::ZLIB: windowBitsFormat = 0; break;
+  }
+  return inflateInit2(zcontext, /* windowBits */15 | windowBitsFormat);
+}
+
+int GzipInputStream::Inflate(int flush) {
+  if ((zerror_ == Z_OK) && (zcontext_.avail_out == 0)) {
+    // previous inflate filled output buffer. don't change input params yet.
+  } else if (zcontext_.avail_in == 0) {
+    const void* in;
+    int in_size;
+    bool first = zcontext_.next_in == NULL;
+    bool ok = sub_stream_->Next(&in, &in_size);
+    if (!ok) {
+      zcontext_.next_out = NULL;
+      zcontext_.avail_out = 0;
+      return Z_STREAM_END;
+    }
+    zcontext_.next_in = static_cast<Bytef*>(const_cast<void*>(in));
+    zcontext_.avail_in = in_size;
+    if (first) {
+      int error = internalInflateInit2(&zcontext_, format_);
+      if (error != Z_OK) {
+        return error;
+      }
+    }
+  }
+  zcontext_.next_out = static_cast<Bytef*>(output_buffer_);
+  zcontext_.avail_out = output_buffer_length_;
+  output_position_ = output_buffer_;
+  int error = inflate(&zcontext_, flush);
+  return error;
+}
+
+void GzipInputStream::DoNextOutput(const void** data, int* size) {
+  *data = output_position_;
+  *size = ((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_);
+  output_position_ = zcontext_.next_out;
+}
+
+// implements ZeroCopyInputStream ----------------------------------
+bool GzipInputStream::Next(const void** data, int* size) {
+  bool ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END)
+      || (zerror_ == Z_BUF_ERROR);
+  if ((!ok) || (zcontext_.next_out == NULL)) {
+    return false;
+  }
+  if (zcontext_.next_out != output_position_) {
+    DoNextOutput(data, size);
+    return true;
+  }
+  if (zerror_ == Z_STREAM_END) {
+    if (zcontext_.next_out != NULL) {
+      // sub_stream_ may have concatenated streams to follow
+      zerror_ = inflateEnd(&zcontext_);
+      if (zerror_ != Z_OK) {
+        return false;
+      }
+      zerror_ = internalInflateInit2(&zcontext_, format_);
+      if (zerror_ != Z_OK) {
+        return false;
+      }
+    } else {
+      *data = NULL;
+      *size = 0;
+      return false;
+    }
+  }
+  zerror_ = Inflate(Z_NO_FLUSH);
+  if ((zerror_ == Z_STREAM_END) && (zcontext_.next_out == NULL)) {
+    // The underlying stream's Next returned false inside Inflate.
+    return false;
+  }
+  ok = (zerror_ == Z_OK) || (zerror_ == Z_STREAM_END)
+      || (zerror_ == Z_BUF_ERROR);
+  if (!ok) {
+    return false;
+  }
+  DoNextOutput(data, size);
+  return true;
+}
+void GzipInputStream::BackUp(int count) {
+  output_position_ = reinterpret_cast<void*>(
+      reinterpret_cast<uintptr_t>(output_position_) - count);
+}
+bool GzipInputStream::Skip(int count) {
+  const void* data;
+  int size;
+  bool ok = Next(&data, &size);
+  while (ok && (size < count)) {
+    count -= size;
+    ok = Next(&data, &size);
+  }
+  if (size > count) {
+    BackUp(size - count);
+  }
+  return ok;
+}
+int64 GzipInputStream::ByteCount() const {
+  return zcontext_.total_out +
+    (((uintptr_t)zcontext_.next_out) - ((uintptr_t)output_position_));
+}
+
+// =========================================================================
+
+GzipOutputStream::Options::Options()
+    : format(GZIP),
+      buffer_size(kDefaultBufferSize),
+      compression_level(Z_DEFAULT_COMPRESSION),
+      compression_strategy(Z_DEFAULT_STRATEGY) {}
+
+GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream) {
+  Init(sub_stream, Options());
+}
+
+GzipOutputStream::GzipOutputStream(ZeroCopyOutputStream* sub_stream,
+                                   const Options& options) {
+  Init(sub_stream, options);
+}
+
+void GzipOutputStream::Init(ZeroCopyOutputStream* sub_stream,
+                            const Options& options) {
+  sub_stream_ = sub_stream;
+  sub_data_ = NULL;
+  sub_data_size_ = 0;
+
+  input_buffer_length_ = options.buffer_size;
+  input_buffer_ = operator new(input_buffer_length_);
+  GOOGLE_CHECK(input_buffer_ != NULL);
+
+  zcontext_.zalloc = Z_NULL;
+  zcontext_.zfree = Z_NULL;
+  zcontext_.opaque = Z_NULL;
+  zcontext_.next_out = NULL;
+  zcontext_.avail_out = 0;
+  zcontext_.total_out = 0;
+  zcontext_.next_in = NULL;
+  zcontext_.avail_in = 0;
+  zcontext_.total_in = 0;
+  zcontext_.msg = NULL;
+  // default to GZIP format
+  int windowBitsFormat = 16;
+  if (options.format == ZLIB) {
+    windowBitsFormat = 0;
+  }
+  zerror_ = deflateInit2(
+      &zcontext_,
+      options.compression_level,
+      Z_DEFLATED,
+      /* windowBits */15 | windowBitsFormat,
+      /* memLevel (default) */8,
+      options.compression_strategy);
+}
+
+GzipOutputStream::~GzipOutputStream() {
+  Close();
+  if (input_buffer_ != NULL) {
+    operator delete(input_buffer_);
+  }
+}
+
+// private
+int GzipOutputStream::Deflate(int flush) {
+  int error = Z_OK;
+  do {
+    if ((sub_data_ == NULL) || (zcontext_.avail_out == 0)) {
+      bool ok = sub_stream_->Next(&sub_data_, &sub_data_size_);
+      if (!ok) {
+        sub_data_ = NULL;
+        sub_data_size_ = 0;
+        return Z_BUF_ERROR;
+      }
+      GOOGLE_CHECK_GT(sub_data_size_, 0);
+      zcontext_.next_out = static_cast<Bytef*>(sub_data_);
+      zcontext_.avail_out = sub_data_size_;
+    }
+    error = deflate(&zcontext_, flush);
+  } while (error == Z_OK && zcontext_.avail_out == 0);
+  if ((flush == Z_FULL_FLUSH) || (flush == Z_FINISH)) {
+    // Notify lower layer of data.
+    sub_stream_->BackUp(zcontext_.avail_out);
+    // We don't own the buffer anymore.
+    sub_data_ = NULL;
+    sub_data_size_ = 0;
+  }
+  return error;
+}
+
+// implements ZeroCopyOutputStream ---------------------------------
+bool GzipOutputStream::Next(void** data, int* size) {
+  if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
+    return false;
+  }
+  if (zcontext_.avail_in != 0) {
+    zerror_ = Deflate(Z_NO_FLUSH);
+    if (zerror_ != Z_OK) {
+      return false;
+    }
+  }
+  if (zcontext_.avail_in == 0) {
+    // all input was consumed. reset the buffer.
+    zcontext_.next_in = static_cast<Bytef*>(input_buffer_);
+    zcontext_.avail_in = input_buffer_length_;
+    *data = input_buffer_;
+    *size = input_buffer_length_;
+  } else {
+    // The loop in Deflate should consume all avail_in
+    GOOGLE_LOG(DFATAL) << "Deflate left bytes unconsumed";
+  }
+  return true;
+}
+void GzipOutputStream::BackUp(int count) {
+  GOOGLE_CHECK_GE(zcontext_.avail_in, count);
+  zcontext_.avail_in -= count;
+}
+int64 GzipOutputStream::ByteCount() const {
+  return zcontext_.total_in + zcontext_.avail_in;
+}
+
+bool GzipOutputStream::Flush() {
+  zerror_ = Deflate(Z_FULL_FLUSH);
+  // Return true if the flush succeeded or if it was a no-op.
+  return  (zerror_ == Z_OK) ||
+      (zerror_ == Z_BUF_ERROR && zcontext_.avail_in == 0 &&
+       zcontext_.avail_out != 0);
+}
+
+bool GzipOutputStream::Close() {
+  if ((zerror_ != Z_OK) && (zerror_ != Z_BUF_ERROR)) {
+    return false;
+  }
+  do {
+    zerror_ = Deflate(Z_FINISH);
+  } while (zerror_ == Z_OK);
+  zerror_ = deflateEnd(&zcontext_);
+  bool ok = zerror_ == Z_OK;
+  zerror_ = Z_STREAM_END;
+  return ok;
+}
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // HAVE_ZLIB
diff --git a/protobuf/src/google/protobuf/io/gzip_stream.h b/protobuf/src/google/protobuf/io/gzip_stream.h
new file mode 100644
index 0000000..c7ccc26
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/gzip_stream.h
@@ -0,0 +1,209 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: brianolson@google.com (Brian Olson)
+//
+// This file contains the definition for classes GzipInputStream and
+// GzipOutputStream.
+//
+// GzipInputStream decompresses data from an underlying
+// ZeroCopyInputStream and provides the decompressed data as a
+// ZeroCopyInputStream.
+//
+// GzipOutputStream is an ZeroCopyOutputStream that compresses data to
+// an underlying ZeroCopyOutputStream.
+
+#ifndef GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
+#define GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
+
+#include <zlib.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// A ZeroCopyInputStream that reads compressed data through zlib
+class LIBPROTOBUF_EXPORT GzipInputStream : public ZeroCopyInputStream {
+ public:
+  // Format key for constructor
+  enum Format {
+    // zlib will autodetect gzip header or deflate stream
+    AUTO = 0,
+
+    // GZIP streams have some extra header data for file attributes.
+    GZIP = 1,
+
+    // Simpler zlib stream format.
+    ZLIB = 2,
+  };
+
+  // buffer_size and format may be -1 for default of 64kB and GZIP format
+  explicit GzipInputStream(
+      ZeroCopyInputStream* sub_stream,
+      Format format = AUTO,
+      int buffer_size = -1);
+  virtual ~GzipInputStream();
+
+  // Return last error message or NULL if no error.
+  inline const char* ZlibErrorMessage() const {
+    return zcontext_.msg;
+  }
+  inline int ZlibErrorCode() const {
+    return zerror_;
+  }
+
+  // implements ZeroCopyInputStream ----------------------------------
+  bool Next(const void** data, int* size);
+  void BackUp(int count);
+  bool Skip(int count);
+  int64 ByteCount() const;
+
+ private:
+  Format format_;
+
+  ZeroCopyInputStream* sub_stream_;
+
+  z_stream zcontext_;
+  int zerror_;
+
+  void* output_buffer_;
+  void* output_position_;
+  size_t output_buffer_length_;
+
+  int Inflate(int flush);
+  void DoNextOutput(const void** data, int* size);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipInputStream);
+};
+
+
+class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream {
+ public:
+  // Format key for constructor
+  enum Format {
+    // GZIP streams have some extra header data for file attributes.
+    GZIP = 1,
+
+    // Simpler zlib stream format.
+    ZLIB = 2,
+  };
+
+  struct Options {
+    // Defaults to GZIP.
+    Format format;
+
+    // What size buffer to use internally.  Defaults to 64kB.
+    int buffer_size;
+
+    // A number between 0 and 9, where 0 is no compression and 9 is best
+    // compression.  Defaults to Z_DEFAULT_COMPRESSION (see zlib.h).
+    int compression_level;
+
+    // Defaults to Z_DEFAULT_STRATEGY.  Can also be set to Z_FILTERED,
+    // Z_HUFFMAN_ONLY, or Z_RLE.  See the documentation for deflateInit2 in
+    // zlib.h for definitions of these constants.
+    int compression_strategy;
+
+    Options();  // Initializes with default values.
+  };
+
+  // Create a GzipOutputStream with default options.
+  explicit GzipOutputStream(ZeroCopyOutputStream* sub_stream);
+
+  // Create a GzipOutputStream with the given options.
+  GzipOutputStream(
+      ZeroCopyOutputStream* sub_stream,
+      const Options& options);
+
+  virtual ~GzipOutputStream();
+
+  // Return last error message or NULL if no error.
+  inline const char* ZlibErrorMessage() const {
+    return zcontext_.msg;
+  }
+  inline int ZlibErrorCode() const {
+    return zerror_;
+  }
+
+  // Flushes data written so far to zipped data in the underlying stream.
+  // It is the caller's responsibility to flush the underlying stream if
+  // necessary.
+  // Compression may be less efficient stopping and starting around flushes.
+  // Returns true if no error.
+  //
+  // Please ensure that block size is > 6. Here is an excerpt from the zlib
+  // doc that explains why:
+  //
+  // In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out
+  // is greater than six to avoid repeated flush markers due to
+  // avail_out == 0 on return.
+  bool Flush();
+
+  // Writes out all data and closes the gzip stream.
+  // It is the caller's responsibility to close the underlying stream if
+  // necessary.
+  // Returns true if no error.
+  bool Close();
+
+  // implements ZeroCopyOutputStream ---------------------------------
+  bool Next(void** data, int* size);
+  void BackUp(int count);
+  int64 ByteCount() const;
+
+ private:
+  ZeroCopyOutputStream* sub_stream_;
+  // Result from calling Next() on sub_stream_
+  void* sub_data_;
+  int sub_data_size_;
+
+  z_stream zcontext_;
+  int zerror_;
+  void* input_buffer_;
+  size_t input_buffer_length_;
+
+  // Shared constructor code.
+  void Init(ZeroCopyOutputStream* sub_stream, const Options& options);
+
+  // Do some compression.
+  // Takes zlib flush mode.
+  // Returns zlib error code.
+  int Deflate(int flush);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GzipOutputStream);
+};
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_GZIP_STREAM_H__
diff --git a/protobuf/src/google/protobuf/io/gzip_stream_unittest.sh b/protobuf/src/google/protobuf/io/gzip_stream_unittest.sh
new file mode 100755
index 0000000..16251a9
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/gzip_stream_unittest.sh
@@ -0,0 +1,44 @@
+#!/bin/sh -x
+#
+# Protocol Buffers - Google's data interchange format
+# Copyright 2009 Google Inc.  All rights reserved.
+# https://developers.google.com/protocol-buffers/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: brianolson@google.com (Brian Olson)
+#
+# Test compatibility between command line gzip/gunzip binaries and
+# ZeroCopyStream versions.
+
+TESTFILE=Makefile
+
+(./zcgzip < ${TESTFILE} | gunzip | cmp - ${TESTFILE}) && \
+(gzip < ${TESTFILE} | ./zcgunzip | cmp - ${TESTFILE})
+
+# Result of "(cmd) && (cmd)" implicitly becomes result of this script
+# and thus the test.
diff --git a/protobuf/src/google/protobuf/io/package_info.h b/protobuf/src/google/protobuf/io/package_info.h
new file mode 100644
index 0000000..dc1fc91
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/package_info.h
@@ -0,0 +1,54 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// 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/protobuf/src/google/protobuf/io/printer.cc b/protobuf/src/google/protobuf/io/printer.cc
new file mode 100644
index 0000000..c8df417
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/printer.cc
@@ -0,0 +1,198 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+
+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 have called Next() at least once and never failed.
+  if (buffer_size_ > 0 && !failed_) {
+    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'.
+      WriteRaw(text + pos, i - pos + 1);
+      pos = i + 1;
+
+      // Setting this true will cause the next WriteRaw() 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.
+      WriteRaw(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.
+        WriteRaw(&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 {
+          WriteRaw(iter->second.data(), iter->second.size());
+        }
+      }
+
+      // Advance past this variable.
+      i = endpos;
+      pos = endpos + 1;
+    }
+  }
+
+  // Write the rest.
+  WriteRaw(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::Print(const char* text,
+                    const char* variable1, const string& value1,
+                    const char* variable2, const string& value2,
+                    const char* variable3, const string& value3) {
+  map<string, string> vars;
+  vars[variable1] = value1;
+  vars[variable2] = value2;
+  vars[variable3] = value3;
+  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::PrintRaw(const string& data) {
+  WriteRaw(data.data(), data.size());
+}
+
+void Printer::PrintRaw(const char* data) {
+  if (failed_) return;
+  WriteRaw(data, strlen(data));
+}
+
+void Printer::WriteRaw(const char* data, int size) {
+  if (failed_) return;
+  if (size == 0) return;
+
+  if (at_start_of_line_ && (size > 0) && (data[0] != '\n')) {
+    // Insert an indent.
+    at_start_of_line_ = false;
+    WriteRaw(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/protobuf/src/google/protobuf/io/printer.h b/protobuf/src/google/protobuf/io/printer.h
new file mode 100644
index 0000000..f06cbf2
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/printer.h
@@ -0,0 +1,136 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 in debug builds. This helps greatly in
+// debugging code which uses it.
+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);
+  // 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,
+                               const char* variable3, const string& value3);
+  // TODO(kenton):  Overloaded versions with more variables?  Three 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();
+
+  // Write a string to the output buffer.
+  // This method does not look for newlines to add indentation.
+  void PrintRaw(const string& data);
+
+  // Write a zero-delimited string to output buffer.
+  // This method does not look for newlines to add indentation.
+  void PrintRaw(const char* data);
+
+  // Write some bytes to the output buffer.
+  // This method does not look for newlines to add indentation.
+  void WriteRaw(const char* data, int size);
+
+  // 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:
+  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/protobuf/src/google/protobuf/io/printer_unittest.cc b/protobuf/src/google/protobuf/io/printer_unittest.cc
new file mode 100644
index 0000000..1331a8d
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/printer_unittest.cc
@@ -0,0 +1,285 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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("Hello World!  This is the same line.\n"
+                 "But this is a new one.\n"
+                 "And this is another one.",
+                 buffer);
+  }
+}
+
+TEST(Printer, WriteRaw) {
+  char buffer[8192];
+
+  for (int block_size = 1; block_size < 512; block_size *= 2) {
+    ArrayOutputStream output(buffer, sizeof(buffer), block_size);
+
+    {
+      string string_obj = "From an object\n";
+      Printer printer(&output, '$');
+      printer.WriteRaw("Hello World!", 12);
+      printer.PrintRaw("  This is the same line.\n");
+      printer.PrintRaw("But this is a new one.\nAnd this is another one.");
+      printer.WriteRaw("\n", 1);
+      printer.PrintRaw(string_obj);
+      EXPECT_FALSE(printer.failed());
+    }
+
+    buffer[output.ByteCount()] = '\0';
+
+    EXPECT_STREQ("Hello World!  This is the same line.\n"
+                 "But this is a new one.\n"
+                 "And this is another one."
+                 "\n"
+                 "From an object\n",
+                 buffer);
+  }
+}
+
+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.PrintRaw("RawBit\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("Hello World!\n"
+                 "bar = $foo$\n"
+                 "RawBit\n"
+                 "1234\n"
+                 "A literal dollar sign:  $\n"
+                 "Now foo = blah.",
+                 buffer);
+  }
+}
+
+TEST(Printer, InlineVariableSubstitution) {
+  char buffer[8192];
+
+  ArrayOutputStream output(buffer, sizeof(buffer));
+
+  {
+    Printer printer(&output, '$');
+    printer.Print("Hello $foo$!\n", "foo", "World");
+    printer.PrintRaw("RawBit\n");
+    printer.Print("$foo$ $bar$\n", "foo", "one", "bar", "two");
+    EXPECT_FALSE(printer.failed());
+  }
+
+  buffer[output.ByteCount()] = '\0';
+
+  EXPECT_STREQ("Hello World!\n"
+               "RawBit\n"
+               "one two\n",
+               buffer);
+}
+
+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.PrintRaw("RawBit has indent at start\n");
+      printer.PrintRaw("but not after a raw newline\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(
+      "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"
+      "  RawBit has indent at start\n"
+      "but not after a raw newline\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.",
+      buffer);
+  }
+}
+
+// Death tests do not work on Windows as of yet.
+#ifdef PROTOBUF_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  // PROTOBUF_HAS_DEATH_TEST
+
+TEST(Printer, WriteFailurePartial) {
+  char buffer[17];
+
+  ArrayOutputStream output(buffer, sizeof(buffer));
+  Printer printer(&output, '$');
+
+  // Print 16 bytes to almost fill the buffer (should not fail).
+  printer.Print("0123456789abcdef");
+  EXPECT_FALSE(printer.failed());
+
+  // Try to print 2 chars. Only one fits.
+  printer.Print("<>");
+  EXPECT_TRUE(printer.failed());
+
+  // Anything else should fail too.
+  printer.Print(" ");
+  EXPECT_TRUE(printer.failed());
+  printer.Print("blah");
+  EXPECT_TRUE(printer.failed());
+
+  // Buffer should contain the first 17 bytes written.
+  EXPECT_EQ("0123456789abcdef<", string(buffer, sizeof(buffer)));
+}
+
+TEST(Printer, WriteFailureExact) {
+  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/protobuf/src/google/protobuf/io/strtod.cc b/protobuf/src/google/protobuf/io/strtod.cc
new file mode 100644
index 0000000..5697343
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/strtod.cc
@@ -0,0 +1,113 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/io/strtod.h>
+
+#include <cstdio>
+#include <cstring>
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// ----------------------------------------------------------------------
+// NoLocaleStrtod()
+//   This code will make you cry.
+// ----------------------------------------------------------------------
+
+namespace {
+
+// 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;
+}
+
+}  // namespace
+
+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 io
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/io/strtod.h b/protobuf/src/google/protobuf/io/strtod.h
new file mode 100644
index 0000000..c2efc8d
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/strtod.h
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// A locale-independent version of strtod(), used to parse floating
+// point default values in .proto files, where the decimal separator
+// is always a dot.
+
+#ifndef GOOGLE_PROTOBUF_IO_STRTOD_H__
+#define GOOGLE_PROTOBUF_IO_STRTOD_H__
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+// A locale-independent version of the standard strtod(), which always
+// uses a dot as the decimal separator.
+double NoLocaleStrtod(const char* str, char** endptr);
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_STRTOD_H__
diff --git a/protobuf/src/google/protobuf/io/tokenizer.cc b/protobuf/src/google/protobuf/io/tokenizer.cc
new file mode 100644
index 0000000..ef2de30
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/tokenizer.cc
@@ -0,0 +1,1127 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// 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/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/io/strtod.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stl_util.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' || c == '\f');
+CHARACTER_CLASS(WhitespaceNoNewline, c == ' ' || c == '\t' ||
+                                     c == '\r' || c == '\v' || c == '\f');
+
+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),
+    record_target_(NULL),
+    record_start_(-1),
+    allow_f_after_float_(false),
+    comment_style_(CPP_COMMENT_STYLE),
+    require_space_after_number_(true),
+    allow_multiline_strings_(false) {
+
+  current_.line = 0;
+  current_.column = 0;
+  current_.end_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 (record_target_ != NULL && record_start_ < buffer_size_) {
+    record_target_->append(buffer_ + record_start_, buffer_size_ - record_start_);
+    record_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::RecordTo(string* target) {
+  record_target_ = target;
+  record_start_ = buffer_pos_;
+}
+
+inline void Tokenizer::StopRecording() {
+  // 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_ != record_start_) {
+    record_target_->append(buffer_ + record_start_, buffer_pos_ - record_start_);
+  }
+  record_target_ = NULL;
+  record_start_ = -1;
+}
+
+inline void Tokenizer::StartToken() {
+  current_.type = TYPE_START;    // Just for the sake of initializing it.
+  current_.text.clear();
+  current_.line = line_;
+  current_.column = column_;
+  RecordTo(&current_.text);
+}
+
+inline void Tokenizer::EndToken() {
+  StopRecording();
+  current_.end_column = column_;
+}
+
+// -------------------------------------------------------------------
+// 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':
+        AddError("Unexpected end of string.");
+        return;
+
+      case '\n': {
+        if (!allow_multiline_strings_) {
+          AddError("String literals cannot cross line boundaries.");
+          return;
+        }
+        NextChar();
+        break;
+      }
+
+      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 if (TryConsume('u')) {
+          if (!TryConsumeOne<HexDigit>() ||
+              !TryConsumeOne<HexDigit>() ||
+              !TryConsumeOne<HexDigit>() ||
+              !TryConsumeOne<HexDigit>()) {
+            AddError("Expected four hex digits for \\u escape sequence.");
+          }
+        } else if (TryConsume('U')) {
+          // We expect 8 hex digits; but only the range up to 0x10ffff is
+          // legal.
+          if (!TryConsume('0') ||
+              !TryConsume('0') ||
+              !(TryConsume('0') || TryConsume('1')) ||
+              !TryConsumeOne<HexDigit>() ||
+              !TryConsumeOne<HexDigit>() ||
+              !TryConsumeOne<HexDigit>() ||
+              !TryConsumeOne<HexDigit>() ||
+              !TryConsumeOne<HexDigit>()) {
+            AddError("Expected eight hex digits up to 10ffff for \\U escape "
+                     "sequence");
+          }
+        } 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>() && require_space_after_number_) {
+    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(string* content) {
+  if (content != NULL) RecordTo(content);
+
+  while (current_char_ != '\0' && current_char_ != '\n') {
+    NextChar();
+  }
+  TryConsume('\n');
+
+  if (content != NULL) StopRecording();
+}
+
+void Tokenizer::ConsumeBlockComment(string* content) {
+  int start_line = line_;
+  int start_column = column_ - 2;
+
+  if (content != NULL) RecordTo(content);
+
+  while (true) {
+    while (current_char_ != '\0' &&
+           current_char_ != '*' &&
+           current_char_ != '/' &&
+           current_char_ != '\n') {
+      NextChar();
+    }
+
+    if (TryConsume('\n')) {
+      if (content != NULL) StopRecording();
+
+      // Consume leading whitespace and asterisk;
+      ConsumeZeroOrMore<WhitespaceNoNewline>();
+      if (TryConsume('*')) {
+        if (TryConsume('/')) {
+          // End of comment.
+          break;
+        }
+      }
+
+      if (content != NULL) RecordTo(content);
+    } else if (TryConsume('*') && TryConsume('/')) {
+      // End of comment.
+      if (content != NULL) {
+        StopRecording();
+        // Strip trailing "*/".
+        content->erase(content->size() - 2);
+      }
+      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.");
+      if (content != NULL) StopRecording();
+      break;
+    }
+  }
+}
+
+Tokenizer::NextCommentStatus Tokenizer::TryConsumeCommentStart() {
+  if (comment_style_ == CPP_COMMENT_STYLE && TryConsume('/')) {
+    if (TryConsume('/')) {
+      return LINE_COMMENT;
+    } else if (TryConsume('*')) {
+      return BLOCK_COMMENT;
+    } else {
+      // Oops, it was just a slash.  Return it.
+      current_.type = TYPE_SYMBOL;
+      current_.text = "/";
+      current_.line = line_;
+      current_.column = column_ - 1;
+      current_.end_column = column_;
+      return SLASH_NOT_COMMENT;
+    }
+  } else if (comment_style_ == SH_COMMENT_STYLE && TryConsume('#')) {
+    return LINE_COMMENT;
+  } else {
+    return NO_COMMENT;
+  }
+}
+
+// -------------------------------------------------------------------
+
+bool Tokenizer::Next() {
+  previous_ = current_;
+
+  while (!read_error_) {
+    ConsumeZeroOrMore<Whitespace>();
+
+    switch (TryConsumeCommentStart()) {
+      case LINE_COMMENT:
+        ConsumeLineComment(NULL);
+        continue;
+      case BLOCK_COMMENT:
+        ConsumeBlockComment(NULL);
+        continue;
+      case SLASH_NOT_COMMENT:
+        return true;
+      case NO_COMMENT:
+        break;
+    }
+
+    // Check for EOF before continuing.
+    if (read_error_) break;
+
+    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 (previous_.type == TYPE_IDENTIFIER &&
+              current_.line == previous_.line &&
+              current_.column == previous_.end_column) {
+            // 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 {
+        // Check if the high order bit is set.
+        if (current_char_ & 0x80) {
+          error_collector_->AddError(line_, column_,
+              StringPrintf("Interpreting non ascii codepoint %d.",
+                           static_cast<unsigned char>(current_char_)));
+        }
+        NextChar();
+        current_.type = TYPE_SYMBOL;
+      }
+
+      EndToken();
+      return true;
+    }
+  }
+
+  // EOF
+  current_.type = TYPE_END;
+  current_.text.clear();
+  current_.line = line_;
+  current_.column = column_;
+  current_.end_column = column_;
+  return false;
+}
+
+namespace {
+
+// Helper class for collecting comments and putting them in the right places.
+//
+// This basically just buffers the most recent comment until it can be decided
+// exactly where that comment should be placed.  When Flush() is called, the
+// current comment goes into either prev_trailing_comments or detached_comments.
+// When the CommentCollector is destroyed, the last buffered comment goes into
+// next_leading_comments.
+class CommentCollector {
+ public:
+  CommentCollector(string* prev_trailing_comments,
+                   vector<string>* detached_comments,
+                   string* next_leading_comments)
+      : prev_trailing_comments_(prev_trailing_comments),
+        detached_comments_(detached_comments),
+        next_leading_comments_(next_leading_comments),
+        has_comment_(false),
+        is_line_comment_(false),
+        can_attach_to_prev_(true) {
+    if (prev_trailing_comments != NULL) prev_trailing_comments->clear();
+    if (detached_comments != NULL) detached_comments->clear();
+    if (next_leading_comments != NULL) next_leading_comments->clear();
+  }
+
+  ~CommentCollector() {
+    // Whatever is in the buffer is a leading comment.
+    if (next_leading_comments_ != NULL && has_comment_) {
+      comment_buffer_.swap(*next_leading_comments_);
+    }
+  }
+
+  // About to read a line comment.  Get the comment buffer pointer in order to
+  // read into it.
+  string* GetBufferForLineComment() {
+    // We want to combine with previous line comments, but not block comments.
+    if (has_comment_ && !is_line_comment_) {
+      Flush();
+    }
+    has_comment_ = true;
+    is_line_comment_ = true;
+    return &comment_buffer_;
+  }
+
+  // About to read a block comment.  Get the comment buffer pointer in order to
+  // read into it.
+  string* GetBufferForBlockComment() {
+    if (has_comment_) {
+      Flush();
+    }
+    has_comment_ = true;
+    is_line_comment_ = false;
+    return &comment_buffer_;
+  }
+
+  void ClearBuffer() {
+    comment_buffer_.clear();
+    has_comment_ = false;
+  }
+
+  // Called once we know that the comment buffer is complete and is *not*
+  // connected to the next token.
+  void Flush() {
+    if (has_comment_) {
+      if (can_attach_to_prev_) {
+        if (prev_trailing_comments_ != NULL) {
+          prev_trailing_comments_->append(comment_buffer_);
+        }
+        can_attach_to_prev_ = false;
+      } else {
+        if (detached_comments_ != NULL) {
+          detached_comments_->push_back(comment_buffer_);
+        }
+      }
+      ClearBuffer();
+    }
+  }
+
+  void DetachFromPrev() {
+    can_attach_to_prev_ = false;
+  }
+
+ private:
+  string* prev_trailing_comments_;
+  vector<string>* detached_comments_;
+  string* next_leading_comments_;
+
+  string comment_buffer_;
+
+  // True if any comments were read into comment_buffer_.  This can be true even
+  // if comment_buffer_ is empty, namely if the comment was "/**/".
+  bool has_comment_;
+
+  // Is the comment in the comment buffer a line comment?
+  bool is_line_comment_;
+
+  // Is it still possible that we could be reading a comment attached to the
+  // previous token?
+  bool can_attach_to_prev_;
+};
+
+} // namespace
+
+bool Tokenizer::NextWithComments(string* prev_trailing_comments,
+                                 vector<string>* detached_comments,
+                                 string* next_leading_comments) {
+  CommentCollector collector(prev_trailing_comments, detached_comments,
+                             next_leading_comments);
+
+  if (current_.type == TYPE_START) {
+    collector.DetachFromPrev();
+  } else {
+    // A comment appearing on the same line must be attached to the previous
+    // declaration.
+    ConsumeZeroOrMore<WhitespaceNoNewline>();
+    switch (TryConsumeCommentStart()) {
+      case LINE_COMMENT:
+        ConsumeLineComment(collector.GetBufferForLineComment());
+
+        // Don't allow comments on subsequent lines to be attached to a trailing
+        // comment.
+        collector.Flush();
+        break;
+      case BLOCK_COMMENT:
+        ConsumeBlockComment(collector.GetBufferForBlockComment());
+
+        ConsumeZeroOrMore<WhitespaceNoNewline>();
+        if (!TryConsume('\n')) {
+          // Oops, the next token is on the same line.  If we recorded a comment
+          // we really have no idea which token it should be attached to.
+          collector.ClearBuffer();
+          return Next();
+        }
+
+        // Don't allow comments on subsequent lines to be attached to a trailing
+        // comment.
+        collector.Flush();
+        break;
+      case SLASH_NOT_COMMENT:
+        return true;
+      case NO_COMMENT:
+        if (!TryConsume('\n')) {
+          // The next token is on the same line.  There are no comments.
+          return Next();
+        }
+        break;
+    }
+  }
+
+  // OK, we are now on the line *after* the previous token.
+  while (true) {
+    ConsumeZeroOrMore<WhitespaceNoNewline>();
+
+    switch (TryConsumeCommentStart()) {
+      case LINE_COMMENT:
+        ConsumeLineComment(collector.GetBufferForLineComment());
+        break;
+      case BLOCK_COMMENT:
+        ConsumeBlockComment(collector.GetBufferForBlockComment());
+
+        // Consume the rest of the line so that we don't interpret it as a
+        // blank line the next time around the loop.
+        ConsumeZeroOrMore<WhitespaceNoNewline>();
+        TryConsume('\n');
+        break;
+      case SLASH_NOT_COMMENT:
+        return true;
+      case NO_COMMENT:
+        if (TryConsume('\n')) {
+          // Completely blank line.
+          collector.Flush();
+          collector.DetachFromPrev();
+        } else {
+          bool result = Next();
+          if (!result ||
+              current_.text == "}" ||
+              current_.text == "]" ||
+              current_.text == ")") {
+            // It looks like we're at the end of a scope.  In this case it
+            // makes no sense to attach a comment to the following token.
+            collector.Flush();
+          }
+          return result;
+        }
+        break;
+    }
+  }
+}
+
+// -------------------------------------------------------------------
+// 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' || 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;
+}
+
+// Helper to append a Unicode code point to a string as UTF8, without bringing
+// in any external dependencies.
+static void AppendUTF8(uint32 code_point, string* output) {
+  uint32 tmp = 0;
+  int len = 0;
+  if (code_point <= 0x7f) {
+    tmp = code_point;
+    len = 1;
+  } else if (code_point <= 0x07ff) {
+    tmp = 0x0000c080 |
+        ((code_point & 0x07c0) << 2) |
+        (code_point & 0x003f);
+    len = 2;
+  } else if (code_point <= 0xffff) {
+    tmp = 0x00e08080 |
+        ((code_point & 0xf000) << 4) |
+        ((code_point & 0x0fc0) << 2) |
+        (code_point & 0x003f);
+    len = 3;
+  } else if (code_point <= 0x1fffff) {
+    tmp = 0xf0808080 |
+        ((code_point & 0x1c0000) << 6) |
+        ((code_point & 0x03f000) << 4) |
+        ((code_point & 0x000fc0) << 2) |
+        (code_point & 0x003f);
+    len = 4;
+  } else {
+    // UTF-16 is only defined for code points up to 0x10FFFF, and UTF-8 is
+    // normally only defined up to there as well.
+    StringAppendF(output, "\\U%08x", code_point);
+    return;
+  }
+  tmp = ghtonl(tmp);
+  output->append(reinterpret_cast<const char*>(&tmp) + sizeof(tmp) - len, len);
+}
+
+// Try to read <len> hex digits from ptr, and stuff the numeric result into
+// *result. Returns true if that many digits were successfully consumed.
+static bool ReadHexDigits(const char* ptr, int len, uint32* result) {
+  *result = 0;
+  if (len == 0) return false;
+  for (const char* end = ptr + len; ptr < end; ++ptr) {
+    if (*ptr == '\0') return false;
+    *result = (*result << 4) + DigitValue(*ptr);
+  }
+  return true;
+}
+
+// Handling UTF-16 surrogate pairs. UTF-16 encodes code points in the range
+// 0x10000...0x10ffff as a pair of numbers, a head surrogate followed by a trail
+// surrogate. These numbers are in a reserved range of Unicode code points, so
+// if we encounter such a pair we know how to parse it and convert it into a
+// single code point.
+static const uint32 kMinHeadSurrogate = 0xd800;
+static const uint32 kMaxHeadSurrogate = 0xdc00;
+static const uint32 kMinTrailSurrogate = 0xdc00;
+static const uint32 kMaxTrailSurrogate = 0xe000;
+
+static inline bool IsHeadSurrogate(uint32 code_point) {
+  return (code_point >= kMinHeadSurrogate) && (code_point < kMaxHeadSurrogate);
+}
+
+static inline bool IsTrailSurrogate(uint32 code_point) {
+  return (code_point >= kMinTrailSurrogate) &&
+      (code_point < kMaxTrailSurrogate);
+}
+
+// Combine a head and trail surrogate into a single Unicode code point.
+static uint32 AssembleUTF16(uint32 head_surrogate, uint32 trail_surrogate) {
+  GOOGLE_DCHECK(IsHeadSurrogate(head_surrogate));
+  GOOGLE_DCHECK(IsTrailSurrogate(trail_surrogate));
+  return 0x10000 + (((head_surrogate - kMinHeadSurrogate) << 10) |
+      (trail_surrogate - kMinTrailSurrogate));
+}
+
+// Convert the escape sequence parameter to a number of expected hex digits.
+static inline int UnicodeLength(char key) {
+  if (key == 'u') return 4;
+  if (key == 'U') return 8;
+  return 0;
+}
+
+// Given a pointer to the 'u' or 'U' starting a Unicode escape sequence, attempt
+// to parse that sequence. On success, returns a pointer to the first char
+// beyond that sequence, and fills in *code_point. On failure, returns ptr
+// itself.
+static const char* FetchUnicodePoint(const char* ptr, uint32* code_point) {
+  const char* p = ptr;
+  // Fetch the code point.
+  const int len = UnicodeLength(*p++);
+  if (!ReadHexDigits(p, len, code_point))
+    return ptr;
+  p += len;
+
+  // Check if the code point we read is a "head surrogate." If so, then we
+  // expect it to be immediately followed by another code point which is a valid
+  // "trail surrogate," and together they form a UTF-16 pair which decodes into
+  // a single Unicode point. Trail surrogates may only use \u, not \U.
+  if (IsHeadSurrogate(*code_point) && *p == '\\' && *(p + 1) == 'u') {
+    uint32 trail_surrogate;
+    if (ReadHexDigits(p + 2, 4, &trail_surrogate) &&
+        IsTrailSurrogate(trail_surrogate)) {
+      *code_point = AssembleUTF16(*code_point, trail_surrogate);
+      p += 6;
+    }
+    // If this failed, then we just emit the head surrogate as a code point.
+    // It's bogus, but so is the string.
+  }
+
+  return p;
+}
+
+// The text string must begin and end with single or double quote
+// characters.
+void Tokenizer::ParseStringAppend(const string& text, string* output) {
+  // Reminder: text[0] is always a quote character.  (If text is
+  // empty, it's invalid, so we'll just return).
+  const size_t text_size = text.size();
+  if (text_size == 0) {
+    GOOGLE_LOG(DFATAL)
+      << " Tokenizer::ParseStringAppend() passed text that could not"
+         " have been tokenized as a string: " << CEscape(text);
+    return;
+  }
+
+  // Reserve room for new string. The branch is necessary because if
+  // there is already space available the reserve() call might
+  // downsize the output.
+  const size_t new_len = text_size + output->size();
+  if (new_len > output->capacity()) {
+    output->reserve(new_len);
+  }
+
+  // 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 if (*ptr == 'u' || *ptr == 'U') {
+        uint32 unicode;
+        const char* end = FetchUnicodePoint(ptr, &unicode);
+        if (end == ptr) {
+          // Failure: Just dump out what we saw, don't try to parse it.
+          output->push_back(*ptr);
+        } else {
+          AppendUTF8(unicode, output);
+          ptr = end - 1;  // Because we're about to ++ptr.
+        }
+      } else {
+        // Some other escape code.
+        output->push_back(TranslateEscape(*ptr));
+      }
+
+    } else if (*ptr == text[0] && ptr[1] == '\0') {
+      // Ignore final quote matching the starting quote.
+    } else {
+      output->push_back(*ptr);
+    }
+  }
+}
+
+template<typename CharacterClass>
+static bool AllInClass(const string& s) {
+  for (int i = 0; i < s.size(); ++i) {
+    if (!CharacterClass::InClass(s[i]))
+      return false;
+  }
+  return true;
+}
+
+bool Tokenizer::IsIdentifier(const string& text) {
+  // Mirrors IDENTIFIER definition in Tokenizer::Next() above.
+  if (text.size() == 0)
+    return false;
+  if (!Letter::InClass(text.at(0)))
+    return false;
+  if (!AllInClass<Alphanumeric>(text.substr(1)))
+    return false;
+  return true;
+}
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/io/tokenizer.h b/protobuf/src/google/protobuf/io/tokenizer.h
new file mode 100644
index 0000000..8c6220a
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/tokenizer.h
@@ -0,0 +1,402 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <vector>
+#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;
+
+  // Indicates that there was a warning 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 AddWarning(int /* line */, int /* column */,
+                          const string& /* message */) { }
+
+ 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;
+    int end_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();
+
+  // Return the previous token -- i.e. what current() returned before the
+  // previous call to Next().
+  const Token& previous();
+
+  // Advance to the next token.  Returns false if the end of the input is
+  // reached.
+  bool Next();
+
+  // Like Next(), but also collects comments which appear between the previous
+  // and next tokens.
+  //
+  // Comments which appear to be attached to the previous token are stored
+  // in *prev_tailing_comments.  Comments which appear to be attached to the
+  // next token are stored in *next_leading_comments.  Comments appearing in
+  // between which do not appear to be attached to either will be added to
+  // detached_comments.  Any of these parameters can be NULL to simply discard
+  // the comments.
+  //
+  // A series of line comments appearing on consecutive lines, with no other
+  // tokens appearing on those lines, will be treated as a single comment.
+  //
+  // Only the comment content is returned; comment markers (e.g. //) are
+  // stripped out.  For block comments, leading whitespace and an asterisk will
+  // be stripped from the beginning of each line other than the first.  Newlines
+  // are included in the output.
+  //
+  // Examples:
+  //
+  //   optional int32 foo = 1;  // Comment attached to foo.
+  //   // Comment attached to bar.
+  //   optional int32 bar = 2;
+  //
+  //   optional string baz = 3;
+  //   // Comment attached to baz.
+  //   // Another line attached to baz.
+  //
+  //   // Comment attached to qux.
+  //   //
+  //   // Another line attached to qux.
+  //   optional double qux = 4;
+  //
+  //   // Detached comment.  This is not attached to qux or corge
+  //   // because there are blank lines separating it from both.
+  //
+  //   optional string corge = 5;
+  //   /* Block comment attached
+  //    * to corge.  Leading asterisks
+  //    * will be removed. */
+  //   /* Block comment attached to
+  //    * grault. */
+  //   optional int32 grault = 6;
+  bool NextWithComments(string* prev_trailing_comments,
+                        vector<string>* detached_comments,
+                        string* next_leading_comments);
+
+  // 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);
+
+  // Identical to ParseString, but appends to output.
+  static void ParseStringAppend(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; }
+
+  // Whether to require whitespace between a number and a field name.
+  // Default is true. Do not use this; for Google-internal cleanup only.
+  void set_require_space_after_number(bool require) {
+    require_space_after_number_ = require;
+  }
+
+  // Whether to allow string literals to span multiple lines. Default is false.
+  // Do not use this; for Google-internal cleanup only.
+  void set_allow_multiline_strings(bool allow) {
+    allow_multiline_strings_ = allow;
+  }
+
+  // External helper: validate an identifier.
+  static bool IsIdentifier(const string& text);
+
+  // -----------------------------------------------------------------
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Tokenizer);
+
+  Token current_;           // Returned by current().
+  Token previous_;          // Returned by previous().
+
+  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_;
+
+  // String to which text should be appended as we advance through it.
+  // Call RecordTo(&str) to start recording and StopRecording() to stop.
+  // E.g. StartToken() calls RecordTo(&current_.text).  record_start_ is the
+  // position within the current buffer where recording started.
+  string* record_target_;
+  int record_start_;
+
+  // Options.
+  bool allow_f_after_float_;
+  CommentStyle comment_style_;
+  bool require_space_after_number_;
+  bool allow_multiline_strings_;
+
+  // 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();
+
+  inline void RecordTo(string* target);
+  inline void StopRecording();
+
+  // 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(string* content);
+  // Consume until "*/".
+  void ConsumeBlockComment(string* content);
+
+  enum NextCommentStatus {
+    // Started a line comment.
+    LINE_COMMENT,
+
+    // Started a block comment.
+    BLOCK_COMMENT,
+
+    // Consumed a slash, then realized it wasn't a comment.  current_ has
+    // been filled in with a slash token.  The caller should return it.
+    SLASH_NOT_COMMENT,
+
+    // We do not appear to be starting a comment here.
+    NO_COMMENT
+  };
+
+  // If we're at the start of a new comment, consume it and return what kind
+  // of comment it is.
+  NextCommentStatus TryConsumeCommentStart();
+
+  // -----------------------------------------------------------------
+  // 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_;
+}
+
+inline const Tokenizer::Token& Tokenizer::previous() {
+  return previous_;
+}
+
+inline void Tokenizer::ParseString(const string& text, string* output) {
+  output->clear();
+  ParseStringAppend(text, output);
+}
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_TOKENIZER_H__
diff --git a/protobuf/src/google/protobuf/io/tokenizer_unittest.cc b/protobuf/src/google/protobuf/io/tokenizer_unittest.cc
new file mode 100644
index 0000000..de096fb
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/tokenizer_unittest.cc
@@ -0,0 +1,999 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <limits.h>
+#include <math.h>
+
+#include <vector>
+
+#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);
+  EXPECT_EQ(0, tokenizer.current().end_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);
+  EXPECT_EQ(kSimpleTokenCases_case.input.size(),
+            tokenizer.current().end_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);
+  EXPECT_EQ(kSimpleTokenCases_case.input.size(),
+            tokenizer.current().end_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,  3 },
+    { Tokenizer::TYPE_INTEGER   , "1"    , 0,  4,  5 },
+    { Tokenizer::TYPE_FLOAT     , "1.2"  , 0,  6,  9 },
+    { Tokenizer::TYPE_SYMBOL    , "+"    , 0, 10, 11 },
+    { Tokenizer::TYPE_STRING    , "'bar'", 0, 12, 17 },
+    { Tokenizer::TYPE_END       , ""     , 0, 17, 17 },
+  }},
+
+  // Test that consecutive symbols are parsed as separate tokens.
+  { "!@+%", {
+    { Tokenizer::TYPE_SYMBOL    , "!"    , 0, 0, 1 },
+    { Tokenizer::TYPE_SYMBOL    , "@"    , 0, 1, 2 },
+    { Tokenizer::TYPE_SYMBOL    , "+"    , 0, 2, 3 },
+    { Tokenizer::TYPE_SYMBOL    , "%"    , 0, 3, 4 },
+    { Tokenizer::TYPE_END       , ""     , 0, 4, 4 },
+  }},
+
+  // Test that newlines affect line numbers correctly.
+  { "foo bar\nrab oof", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0,  0, 3 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 0,  4, 7 },
+    { Tokenizer::TYPE_IDENTIFIER, "rab", 1,  0, 3 },
+    { Tokenizer::TYPE_IDENTIFIER, "oof", 1,  4, 7 },
+    { Tokenizer::TYPE_END       , ""   , 1,  7, 7 },
+  }},
+
+  // Test that tabs affect column numbers correctly.
+  { "foo\tbar  \tbaz", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0,  0,  3 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 0,  8, 11 },
+    { Tokenizer::TYPE_IDENTIFIER, "baz", 0, 16, 19 },
+    { Tokenizer::TYPE_END       , ""   , 0, 19, 19 },
+  }},
+
+  // Test that tabs in string literals affect column numbers correctly.
+  { "\"foo\tbar\" baz", {
+    { Tokenizer::TYPE_STRING    , "\"foo\tbar\"", 0,  0, 12 },
+    { Tokenizer::TYPE_IDENTIFIER, "baz"         , 0, 13, 16 },
+    { Tokenizer::TYPE_END       , ""            , 0, 16, 16 },
+  }},
+
+  // Test that line comments are ignored.
+  { "foo // This is a comment\n"
+    "bar // This is another comment", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0,  0,  3 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 1,  0,  3 },
+    { Tokenizer::TYPE_END       , ""   , 1, 30, 30 },
+  }},
+
+  // Test that block comments are ignored.
+  { "foo /* This is a block comment */ bar", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0,  0,  3 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 34, 37 },
+    { Tokenizer::TYPE_END       , ""   , 0, 37, 37 },
+  }},
+
+  // Test that sh-style comments are not ignored by default.
+  { "foo # bar\n"
+    "baz", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0, 0, 3 },
+    { Tokenizer::TYPE_SYMBOL    , "#"  , 0, 4, 5 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 0, 6, 9 },
+    { Tokenizer::TYPE_IDENTIFIER, "baz", 1, 0, 3 },
+    { Tokenizer::TYPE_END       , ""   , 1, 3, 3 },
+  }},
+
+  // Test all whitespace chars
+  { "foo\n\t\r\v\fbar", {
+    { Tokenizer::TYPE_IDENTIFIER, "foo", 0,  0,  3 },
+    { Tokenizer::TYPE_IDENTIFIER, "bar", 1, 11, 14 },
+    { Tokenizer::TYPE_END       , ""   , 1, 14, 14 },
+  }},
+};
+
+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);
+  EXPECT_EQ(0, tokenizer.current().end_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);
+
+    Tokenizer::Token previous = tokenizer.current();
+
+    // 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 previous token is set correctly.
+    EXPECT_EQ(previous.type, tokenizer.previous().type);
+    EXPECT_EQ(previous.text, tokenizer.previous().text);
+    EXPECT_EQ(previous.line, tokenizer.previous().line);
+    EXPECT_EQ(previous.column, tokenizer.previous().column);
+    EXPECT_EQ(previous.end_column, tokenizer.previous().end_column);
+
+    // 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);
+    EXPECT_EQ(token.end_column, tokenizer.current().end_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
+
+// -------------------------------------------------------------------
+
+// In each case, the input is expected to have two tokens named "prev" and
+// "next" with comments in between.
+struct DocCommentCase {
+  string input;
+
+  const char* prev_trailing_comments;
+  const char* detached_comments[10];
+  const char* next_leading_comments;
+};
+
+inline ostream& operator<<(ostream& out,
+                           const DocCommentCase& test_case) {
+  return out << CEscape(test_case.input);
+}
+
+DocCommentCase kDocCommentCases[] = {
+  {
+    "prev next",
+
+    "",
+    {},
+    ""
+      },
+
+        {
+      "prev /* ignored */ next",
+
+      "",
+      {},
+      ""
+        },
+
+          {
+        "prev // trailing comment\n"
+            "next",
+
+            " trailing comment\n",
+            {},
+            ""
+          },
+
+            {
+          "prev\n"
+              "// leading comment\n"
+              "// line 2\n"
+              "next",
+
+              "",
+              {},
+              " leading comment\n"
+              " line 2\n"
+            },
+
+              {
+            "prev\n"
+                "// trailing comment\n"
+                "// line 2\n"
+                "\n"
+                "next",
+
+                " trailing comment\n"
+                " line 2\n",
+                {},
+                ""
+              },
+
+                {
+              "prev // trailing comment\n"
+                  "// leading comment\n"
+                  "// line 2\n"
+                  "next",
+
+                  " trailing comment\n",
+                  {},
+                  " leading comment\n"
+                  " line 2\n"
+                },
+
+                  {
+                "prev /* trailing block comment */\n"
+                    "/* leading block comment\n"
+                    " * line 2\n"
+                    " * line 3 */"
+                    "next",
+
+                    " trailing block comment ",
+                    {},
+                    " leading block comment\n"
+                    " line 2\n"
+                    " line 3 "
+                  },
+
+                    {
+                  "prev\n"
+                      "/* trailing block comment\n"
+                      " * line 2\n"
+                      " * line 3\n"
+                      " */\n"
+                      "/* leading block comment\n"
+                      " * line 2\n"
+                      " * line 3 */"
+                      "next",
+
+                      " trailing block comment\n"
+                      " line 2\n"
+                      " line 3\n",
+                      {},
+                      " leading block comment\n"
+                      " line 2\n"
+                      " line 3 "
+                    },
+
+                      {
+                    "prev\n"
+                        "// trailing comment\n"
+                        "\n"
+                        "// detached comment\n"
+                        "// line 2\n"
+                        "\n"
+                        "// second detached comment\n"
+                        "/* third detached comment\n"
+                        " * line 2 */\n"
+                        "// leading comment\n"
+                        "next",
+
+                        " trailing comment\n",
+                        {
+                      " detached comment\n"
+                          " line 2\n",
+                          " second detached comment\n",
+                          " third detached comment\n"
+                          " line 2 "
+                        },
+                          " leading comment\n"
+                        },
+
+                          {
+                        "prev /**/\n"
+                            "\n"
+                            "// detached comment\n"
+                            "\n"
+                            "// leading comment\n"
+                            "next",
+
+                            "",
+                            {
+                          " detached comment\n"
+                            },
+                              " leading comment\n"
+                            },
+
+                              {
+                            "prev /**/\n"
+                                "// leading comment\n"
+                                "next",
+
+                                "",
+                                {},
+                                " leading comment\n"
+                              },
+                              };
+
+TEST_2D(TokenizerTest, DocComments, kDocCommentCases, kBlockSizes) {
+  // Set up the tokenizer.
+  TestInputStream input(kDocCommentCases_case.input.data(),
+                        kDocCommentCases_case.input.size(),
+                        kBlockSizes_case);
+  TestErrorCollector error_collector;
+  Tokenizer tokenizer(&input, &error_collector);
+
+  // Set up a second tokenizer where we'll pass all NULLs to NextWithComments().
+  TestInputStream input2(kDocCommentCases_case.input.data(),
+                        kDocCommentCases_case.input.size(),
+                        kBlockSizes_case);
+  Tokenizer tokenizer2(&input2, &error_collector);
+
+  tokenizer.Next();
+  tokenizer2.Next();
+
+  EXPECT_EQ("prev", tokenizer.current().text);
+  EXPECT_EQ("prev", tokenizer2.current().text);
+
+  string prev_trailing_comments;
+  vector<string> detached_comments;
+  string next_leading_comments;
+  tokenizer.NextWithComments(&prev_trailing_comments, &detached_comments,
+                             &next_leading_comments);
+  tokenizer2.NextWithComments(NULL, NULL, NULL);
+  EXPECT_EQ("next", tokenizer.current().text);
+  EXPECT_EQ("next", tokenizer2.current().text);
+
+  EXPECT_EQ(kDocCommentCases_case.prev_trailing_comments,
+            prev_trailing_comments);
+
+  for (int i = 0; i < detached_comments.size(); i++) {
+    ASSERT_LT(i, GOOGLE_ARRAYSIZE(kDocCommentCases));
+    ASSERT_TRUE(kDocCommentCases_case.detached_comments[i] != NULL);
+    EXPECT_EQ(kDocCommentCases_case.detached_comments[i],
+              detached_comments[i]);
+  }
+
+  // Verify that we matched all the detached comments.
+  EXPECT_EQ(NULL,
+      kDocCommentCases_case.detached_comments[detached_comments.size()]);
+
+  EXPECT_EQ(kDocCommentCases_case.next_leading_comments,
+            next_leading_comments);
+}
+
+// -------------------------------------------------------------------
+
+// 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"));
+  EXPECT_EQ(0X123, ParseInteger("0X123"));
+
+  // Test invalid integers that may still be tokenized as integers.
+  EXPECT_EQ(0, ParseInteger("0x"));
+
+  uint64 i;
+#ifdef PROTOBUF_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::ParseInteger("zxy", kuint64max, &i),
+    "passed text that could not have been tokenized as an integer");
+  EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("1.2", kuint64max, &i),
+    "passed text that could not have been tokenized as an integer");
+  EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("08", kuint64max, &i),
+    "passed text that could not have been tokenized as an integer");
+  EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("0xg", kuint64max, &i),
+    "passed text that could not have been tokenized as an integer");
+  EXPECT_DEBUG_DEATH(Tokenizer::ParseInteger("-1", kuint64max, &i),
+    "passed text that could not have been tokenized as an integer");
+#endif  // PROTOBUF_HAS_DEATH_TEST
+
+  // Test overflows.
+  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 PROTOBUF_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  // PROTOBUF_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);
+
+  // Experiment with Unicode escapes. Here are one-, two- and three-byte Unicode
+  // characters.
+  Tokenizer::ParseString("'\\u0024\\u00a2\\u20ac\\U00024b62XX'", &output);
+  EXPECT_EQ("$¢€𤭢XX", output);
+  // Same thing encoded using UTF16.
+  Tokenizer::ParseString("'\\u0024\\u00a2\\u20ac\\ud852\\udf62XX'", &output);
+  EXPECT_EQ("$¢€𤭢XX", output);
+  // Here's some broken UTF16; there's a head surrogate with no tail surrogate.
+  // We just output this as if it were UTF8; it's not a defined code point, but
+  // it has a defined encoding.
+  Tokenizer::ParseString("'\\ud852XX'", &output);
+  EXPECT_EQ("\xed\xa1\x92XX", output);
+  // Malformed escape: Demons may fly out of the nose.
+  Tokenizer::ParseString("\\u0", &output);
+  EXPECT_EQ("u0", output);
+
+  // Test invalid strings that will never be tokenized as strings.
+#ifdef PROTOBUF_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  // PROTOBUF_HAS_DEATH_TEST
+}
+
+TEST_F(TokenizerTest, ParseStringAppend) {
+  // Check that ParseString and ParseStringAppend differ.
+  string output("stuff+");
+  Tokenizer::ParseStringAppend("'hello'", &output);
+  EXPECT_EQ("stuff+hello", output);
+  Tokenizer::ParseString("'hello'", &output);
+  EXPECT_EQ("hello", output);
+}
+
+// -------------------------------------------------------------------
+
+// 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: Unexpected end of string.\n" },
+  { "'bar\nfoo", true,
+    "0:4: String literals cannot cross line boundaries.\n" },
+  { "'\\u01' foo", true,
+    "0:5: Expected four hex digits for \\u escape sequence.\n" },
+  { "'\\u01' foo", true,
+    "0:5: Expected four hex digits for \\u escape sequence.\n" },
+  { "'\\uXYZ' foo", true,
+    "0:3: Expected four hex digits for \\u escape sequence.\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" },
+
+  // Check error from high order bits set
+  { "\300foo", true,
+    "0:0: Interpreting non ascii codepoint 192.\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(kErrorCases_case.errors, error_collector.text_);
+
+  // 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/protobuf/src/google/protobuf/io/zero_copy_stream.cc b/protobuf/src/google/protobuf/io/zero_copy_stream.cc
new file mode 100644
index 0000000..f77c768
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/zero_copy_stream.cc
@@ -0,0 +1,57 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+ZeroCopyInputStream::~ZeroCopyInputStream() {}
+ZeroCopyOutputStream::~ZeroCopyOutputStream() {}
+
+
+bool ZeroCopyOutputStream::WriteAliasedRaw(const void* /* data */,
+                                           int /* size */) {
+  GOOGLE_LOG(FATAL) << "This ZeroCopyOutputStream doesn't support aliasing. "
+                "Reaching here usually means a ZeroCopyOutputStream "
+                "implementation bug.";
+  return false;
+}
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/io/zero_copy_stream.h b/protobuf/src/google/protobuf/io/zero_copy_stream.h
new file mode 100644
index 0000000..52650fc
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/zero_copy_stream.h
@@ -0,0 +1,248 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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);
+//   ZeroCopyOutputStream* 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;
+
+  // Write a given chunk of data to the output.  Some output streams may
+  // implement this in a way that avoids copying. Check AllowsAliasing() before
+  // calling WriteAliasedRaw(). It will GOOGLE_CHECK fail if WriteAliasedRaw() is
+  // called on a stream that does not allow aliasing.
+  //
+  // NOTE: It is caller's responsibility to ensure that the chunk of memory
+  // remains live until all of the data has been consumed from the stream.
+  virtual bool WriteAliasedRaw(const void* data, int size);
+  virtual bool AllowsAliasing() const { return false; }
+
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream);
+};
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__
diff --git a/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc b/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc
new file mode 100644
index 0000000..f7901b2
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc
@@ -0,0 +1,473 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <algorithm>
+
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stl_util.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;
+}
+
+}  // namespace
+
+
+// ===================================================================
+
+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::Flush() {
+  return impl_.Flush();
+}
+
+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) {
+  prior_bytes_read_ = input_->ByteCount();
+}
+
+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_ - prior_bytes_read_;
+  } else {
+    return input_->ByteCount() - prior_bytes_read_;
+  }
+}
+
+
+// ===================================================================
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h b/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h
new file mode 100644
index 0000000..0746fa6
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h
@@ -0,0 +1,358 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 which are only included in the full (non-lite)
+// protobuf library.  These implementations include Unix file descriptors
+// and C++ iostreams.  See also:  zero_copy_stream_impl_lite.h
+
+#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/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/stubs/common.h>
+
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+
+// ===================================================================
+
+// 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.
+//
+// FileOutputStream is preferred over using an ofstream with
+// OstreamOutputStream.  The latter will introduce an extra layer of buffering,
+// harming performance.  Also, it's conceivable that FileOutputStream 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();
+
+  // Flushes FileOutputStream's buffers but does not close the
+  // underlying file. No special measures are taken to ensure that
+  // underlying operating system file object is synchronized to disk.
+  bool Flush();
+
+  // 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.
+  int64 prior_bytes_read_;  // Bytes read on underlying stream at construction
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream);
+};
+
+// ===================================================================
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__
diff --git a/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
new file mode 100644
index 0000000..58aff0e
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
@@ -0,0 +1,405 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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_impl_lite.h>
+
+#include <algorithm>
+#include <limits>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+namespace io {
+
+namespace {
+
+// 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.
+    STLStringResizeUninitialized(target_, target_->capacity());
+  } else {
+    // Size has reached capacity, try to double the size.
+    if (old_size > std::numeric_limits<int>::max() / 2) {
+      // Can not double the size otherwise it is going to cause integer
+      // overflow in the expression below: old_size * 2 ";
+      GOOGLE_LOG(ERROR) << "Cannot allocate buffer larger than kint32max for "
+                 << "StringOutputStream.";
+      return false;
+    }
+    // Double the size, also make sure that the new size is at least
+    // kMinimumSize.
+    STLStringResizeUninitialized(
+      target_,
+      max(old_size * 2,
+          kMinimumSize + 0));  // "+ 0" works around GCC4 weirdness.
+  }
+
+  *data = mutable_string_data(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 - skipped,
+                               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();
+}
+
+// ===================================================================
+
+}  // namespace io
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h
new file mode 100644
index 0000000..e18da72
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -0,0 +1,354 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 which are included in the "lite" protobuf library.
+// These implementations cover I/O on raw arrays and strings, as well as
+// adaptors which make it easy to implement streams based on traditional
+// streams.  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_LITE_H__
+#define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
+
+#include <string>
+#include <iosfwd>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stl_util.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);
+};
+
+// ===================================================================
+
+// Return a pointer to mutable characters underlying the given string.  The
+// return value is valid until the next time the string is resized.  We
+// trust the caller to treat the return value as an array of length s->size().
+inline char* mutable_string_data(string* s) {
+#ifdef LANG_CXX11
+  // This should be simpler & faster than string_as_array() because the latter
+  // is guaranteed to return NULL when *s is empty, so it has to check for that.
+  return &(*s)[0];
+#else
+  return string_as_array(s);
+#endif
+}
+
+}  // namespace io
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_LITE_H__
diff --git a/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc b/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc
new file mode 100644
index 0000000..bf978cc
--- /dev/null
+++ b/protobuf/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -0,0 +1,965 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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.
+
+#include "config.h"
+
+#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/io/coded_stream.h>
+
+#if HAVE_ZLIB
+#include <google/protobuf/io/gzip_stream.h>
+#endif
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+#include <google/protobuf/testing/file.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 string& 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 string& 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);
+
+  // Similar to WriteStuff, but performs more sophisticated testing.
+  int WriteStuffLarge(ZeroCopyOutputStream* output);
+  // Reads and tests a stream that should have been written to
+  // via WriteStuffLarge().
+  void ReadStuffLarge(ZeroCopyInputStream* input);
+
+#if HAVE_ZLIB
+  string Compress(const string& data, const GzipOutputStream::Options& options);
+  string Uncompress(const string& data);
+#endif
+
+  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;
+    }
+    EXPECT_GT(out_size, 0);
+
+    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;
+  }
+}
+
+#define MAX_REPEATED_ZEROS 100
+
+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;
+
+  int repeated_zeros = 0;
+
+  while (true) {
+    if (!input->Next(&in, &in_size)) {
+      return size - out_size;
+    }
+    EXPECT_GT(in_size, -1);
+    if (in_size == 0) {
+      repeated_zeros++;
+    } else {
+      repeated_zeros = 0;
+    }
+    EXPECT_LT(repeated_zeros, MAX_REPEATED_ZEROS);
+
+    if (out_size <= in_size) {
+      memcpy(out, in, out_size);
+      if (in_size > 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 string& str) {
+  EXPECT_TRUE(WriteToOutput(output, str.c_str(), str.size()));
+}
+
+void IoTest::ReadString(ZeroCopyInputStream* input, const string& str) {
+  scoped_array<char> buffer(new char[str.size() + 1]);
+  buffer[str.size()] = '\0';
+  EXPECT_EQ(ReadFromInput(input, buffer.get(), str.size()), str.size());
+  EXPECT_STREQ(str.c_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);
+}
+
+int IoTest::WriteStuffLarge(ZeroCopyOutputStream* output) {
+  WriteString(output, "Hello world!\n");
+  WriteString(output, "Some te");
+  WriteString(output, "xt.  Blah blah.");
+  WriteString(output, string(100000, 'x'));  // A very long string
+  WriteString(output, string(100000, 'y'));  // A very long string
+  WriteString(output, "01234567890123456789");
+
+  EXPECT_EQ(output->ByteCount(), 200055);
+
+  int result = output->ByteCount();
+  return result;
+}
+
+// Reads text from an input stream and expects it to match what WriteStuff()
+// writes.
+void IoTest::ReadStuffLarge(ZeroCopyInputStream* input) {
+  ReadString(input, "Hello world!\nSome text.  ");
+  EXPECT_TRUE(input->Skip(5));
+  ReadString(input, "blah.");
+  EXPECT_TRUE(input->Skip(100000 - 10));
+  ReadString(input, string(10, 'x') + string(100000 - 20000, 'y'));
+  EXPECT_TRUE(input->Skip(20000 - 10));
+  ReadString(input, "yyyyyyyyyy01234567890123456789");
+
+  EXPECT_EQ(input->ByteCount(), 200055);
+
+  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);
+      }
+    }
+  }
+}
+
+TEST_F(IoTest, TwoSessionWrite) {
+  // Test that two concatenated write sessions read correctly
+
+  static const char* strA = "0123456789";
+  static const char* strB = "WhirledPeas";
+  const int kBufferSize = 2*1024;
+  uint8* buffer = new uint8[kBufferSize];
+  char* temp_buffer = new char[40];
+
+  for (int i = 0; i < kBlockSizeCount; i++) {
+    for (int j = 0; j < kBlockSizeCount; j++) {
+      ArrayOutputStream* output =
+          new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]);
+      CodedOutputStream* coded_output = new CodedOutputStream(output);
+      coded_output->WriteVarint32(strlen(strA));
+      coded_output->WriteRaw(strA, strlen(strA));
+      delete coded_output;  // flush
+      int64 pos = output->ByteCount();
+      delete output;
+      output = new ArrayOutputStream(
+          buffer + pos, kBufferSize - pos, kBlockSizes[i]);
+      coded_output = new CodedOutputStream(output);
+      coded_output->WriteVarint32(strlen(strB));
+      coded_output->WriteRaw(strB, strlen(strB));
+      delete coded_output;  // flush
+      int64 size = pos + output->ByteCount();
+      delete output;
+
+      ArrayInputStream* input =
+          new ArrayInputStream(buffer, size, kBlockSizes[j]);
+      CodedInputStream* coded_input = new CodedInputStream(input);
+      uint32 insize;
+      EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+      EXPECT_EQ(strlen(strA), insize);
+      EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+      EXPECT_EQ(0, memcmp(temp_buffer, strA, insize));
+
+      EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+      EXPECT_EQ(strlen(strB), insize);
+      EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+      EXPECT_EQ(0, memcmp(temp_buffer, strB, insize));
+
+      delete coded_input;
+      delete input;
+    }
+  }
+
+  delete [] temp_buffer;
+  delete [] buffer;
+}
+
+#if HAVE_ZLIB
+TEST_F(IoTest, GzipIo) {
+  const int kBufferSize = 2*1024;
+  uint8* buffer = new uint8[kBufferSize];
+  for (int i = 0; i < kBlockSizeCount; i++) {
+    for (int j = 0; j < kBlockSizeCount; j++) {
+      for (int z = 0; z < kBlockSizeCount; z++) {
+        int gzip_buffer_size = kBlockSizes[z];
+        int size;
+        {
+          ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+          GzipOutputStream::Options options;
+          options.format = GzipOutputStream::GZIP;
+          if (gzip_buffer_size != -1) {
+            options.buffer_size = gzip_buffer_size;
+          }
+          GzipOutputStream gzout(&output, options);
+          WriteStuff(&gzout);
+          gzout.Close();
+          size = output.ByteCount();
+        }
+        {
+          ArrayInputStream input(buffer, size, kBlockSizes[j]);
+          GzipInputStream gzin(
+              &input, GzipInputStream::GZIP, gzip_buffer_size);
+          ReadStuff(&gzin);
+        }
+      }
+    }
+  }
+  delete [] buffer;
+}
+
+TEST_F(IoTest, GzipIoWithFlush) {
+  const int kBufferSize = 2*1024;
+  uint8* buffer = new uint8[kBufferSize];
+  // We start with i = 4 as we want a block size > 6. With block size <= 6
+  // Flush() fills up the entire 2K buffer with flush markers and the test
+  // fails. See documentation for Flush() for more detail.
+  for (int i = 4; i < kBlockSizeCount; i++) {
+    for (int j = 0; j < kBlockSizeCount; j++) {
+      for (int z = 0; z < kBlockSizeCount; z++) {
+        int gzip_buffer_size = kBlockSizes[z];
+        int size;
+        {
+          ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+          GzipOutputStream::Options options;
+          options.format = GzipOutputStream::GZIP;
+          if (gzip_buffer_size != -1) {
+            options.buffer_size = gzip_buffer_size;
+          }
+          GzipOutputStream gzout(&output, options);
+          WriteStuff(&gzout);
+          EXPECT_TRUE(gzout.Flush());
+          gzout.Close();
+          size = output.ByteCount();
+        }
+        {
+          ArrayInputStream input(buffer, size, kBlockSizes[j]);
+          GzipInputStream gzin(
+              &input, GzipInputStream::GZIP, gzip_buffer_size);
+          ReadStuff(&gzin);
+        }
+      }
+    }
+  }
+  delete [] buffer;
+}
+
+TEST_F(IoTest, GzipIoContiguousFlushes) {
+  const int kBufferSize = 2*1024;
+  uint8* buffer = new uint8[kBufferSize];
+
+  int block_size = kBlockSizes[4];
+  int gzip_buffer_size = block_size;
+  int size;
+
+  ArrayOutputStream output(buffer, kBufferSize, block_size);
+  GzipOutputStream::Options options;
+  options.format = GzipOutputStream::GZIP;
+  if (gzip_buffer_size != -1) {
+    options.buffer_size = gzip_buffer_size;
+  }
+  GzipOutputStream gzout(&output, options);
+  WriteStuff(&gzout);
+  EXPECT_TRUE(gzout.Flush());
+  EXPECT_TRUE(gzout.Flush());
+  gzout.Close();
+  size = output.ByteCount();
+
+  ArrayInputStream input(buffer, size, block_size);
+  GzipInputStream gzin(
+      &input, GzipInputStream::GZIP, gzip_buffer_size);
+  ReadStuff(&gzin);
+
+  delete [] buffer;
+}
+
+TEST_F(IoTest, GzipIoReadAfterFlush) {
+  const int kBufferSize = 2*1024;
+  uint8* buffer = new uint8[kBufferSize];
+
+  int block_size = kBlockSizes[4];
+  int gzip_buffer_size = block_size;
+  int size;
+  ArrayOutputStream output(buffer, kBufferSize, block_size);
+  GzipOutputStream::Options options;
+  options.format = GzipOutputStream::GZIP;
+  if (gzip_buffer_size != -1) {
+    options.buffer_size = gzip_buffer_size;
+  }
+
+  GzipOutputStream gzout(&output, options);
+  WriteStuff(&gzout);
+  EXPECT_TRUE(gzout.Flush());
+  size = output.ByteCount();
+
+  ArrayInputStream input(buffer, size, block_size);
+  GzipInputStream gzin(
+      &input, GzipInputStream::GZIP, gzip_buffer_size);
+  ReadStuff(&gzin);
+
+  gzout.Close();
+
+  delete [] buffer;
+}
+
+TEST_F(IoTest, ZlibIo) {
+  const int kBufferSize = 2*1024;
+  uint8* buffer = new uint8[kBufferSize];
+  for (int i = 0; i < kBlockSizeCount; i++) {
+    for (int j = 0; j < kBlockSizeCount; j++) {
+      for (int z = 0; z < kBlockSizeCount; z++) {
+        int gzip_buffer_size = kBlockSizes[z];
+        int size;
+        {
+          ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]);
+          GzipOutputStream::Options options;
+          options.format = GzipOutputStream::ZLIB;
+          if (gzip_buffer_size != -1) {
+            options.buffer_size = gzip_buffer_size;
+          }
+          GzipOutputStream gzout(&output, options);
+          WriteStuff(&gzout);
+          gzout.Close();
+          size = output.ByteCount();
+        }
+        {
+          ArrayInputStream input(buffer, size, kBlockSizes[j]);
+          GzipInputStream gzin(
+              &input, GzipInputStream::ZLIB, gzip_buffer_size);
+          ReadStuff(&gzin);
+        }
+      }
+    }
+  }
+  delete [] buffer;
+}
+
+TEST_F(IoTest, ZlibIoInputAutodetect) {
+  const int kBufferSize = 2*1024;
+  uint8* buffer = new uint8[kBufferSize];
+  int size;
+  {
+    ArrayOutputStream output(buffer, kBufferSize);
+    GzipOutputStream::Options options;
+    options.format = GzipOutputStream::ZLIB;
+    GzipOutputStream gzout(&output, options);
+    WriteStuff(&gzout);
+    gzout.Close();
+    size = output.ByteCount();
+  }
+  {
+    ArrayInputStream input(buffer, size);
+    GzipInputStream gzin(&input, GzipInputStream::AUTO);
+    ReadStuff(&gzin);
+  }
+  {
+    ArrayOutputStream output(buffer, kBufferSize);
+    GzipOutputStream::Options options;
+    options.format = GzipOutputStream::GZIP;
+    GzipOutputStream gzout(&output, options);
+    WriteStuff(&gzout);
+    gzout.Close();
+    size = output.ByteCount();
+  }
+  {
+    ArrayInputStream input(buffer, size);
+    GzipInputStream gzin(&input, GzipInputStream::AUTO);
+    ReadStuff(&gzin);
+  }
+  delete [] buffer;
+}
+
+string IoTest::Compress(const string& data,
+                        const GzipOutputStream::Options& options) {
+  string result;
+  {
+    StringOutputStream output(&result);
+    GzipOutputStream gzout(&output, options);
+    WriteToOutput(&gzout, data.data(), data.size());
+  }
+  return result;
+}
+
+string IoTest::Uncompress(const string& data) {
+  string result;
+  {
+    ArrayInputStream input(data.data(), data.size());
+    GzipInputStream gzin(&input);
+    const void* buffer;
+    int size;
+    while (gzin.Next(&buffer, &size)) {
+      result.append(reinterpret_cast<const char*>(buffer), size);
+    }
+  }
+  return result;
+}
+
+TEST_F(IoTest, CompressionOptions) {
+  // Some ad-hoc testing of compression options.
+
+  string golden;
+  GOOGLE_CHECK_OK(File::GetContents(
+      TestSourceDir() +
+          "/google/protobuf/testdata/golden_message",
+      &golden, true));
+
+  GzipOutputStream::Options options;
+  string gzip_compressed = Compress(golden, options);
+
+  options.compression_level = 0;
+  string not_compressed = Compress(golden, options);
+
+  // Try zlib compression for fun.
+  options = GzipOutputStream::Options();
+  options.format = GzipOutputStream::ZLIB;
+  string zlib_compressed = Compress(golden, options);
+
+  // Uncompressed should be bigger than the original since it should have some
+  // sort of header.
+  EXPECT_GT(not_compressed.size(), golden.size());
+
+  // Higher compression levels should result in smaller sizes.
+  EXPECT_LT(zlib_compressed.size(), not_compressed.size());
+
+  // ZLIB format should differ from GZIP format.
+  EXPECT_TRUE(zlib_compressed != gzip_compressed);
+
+  // Everything should decompress correctly.
+  EXPECT_TRUE(Uncompress(not_compressed) == golden);
+  EXPECT_TRUE(Uncompress(gzip_compressed) == golden);
+  EXPECT_TRUE(Uncompress(zlib_compressed) == golden);
+}
+
+TEST_F(IoTest, TwoSessionWriteGzip) {
+  // Test that two concatenated gzip streams can be read correctly
+
+  static const char* strA = "0123456789";
+  static const char* strB = "QuickBrownFox";
+  const int kBufferSize = 2*1024;
+  uint8* buffer = new uint8[kBufferSize];
+  char* temp_buffer = new char[40];
+
+  for (int i = 0; i < kBlockSizeCount; i++) {
+    for (int j = 0; j < kBlockSizeCount; j++) {
+      ArrayOutputStream* output =
+          new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]);
+      GzipOutputStream* gzout = new GzipOutputStream(output);
+      CodedOutputStream* coded_output = new CodedOutputStream(gzout);
+      int32 outlen = strlen(strA) + 1;
+      coded_output->WriteVarint32(outlen);
+      coded_output->WriteRaw(strA, outlen);
+      delete coded_output;  // flush
+      delete gzout;  // flush
+      int64 pos = output->ByteCount();
+      delete output;
+      output = new ArrayOutputStream(
+          buffer + pos, kBufferSize - pos, kBlockSizes[i]);
+      gzout = new GzipOutputStream(output);
+      coded_output = new CodedOutputStream(gzout);
+      outlen = strlen(strB) + 1;
+      coded_output->WriteVarint32(outlen);
+      coded_output->WriteRaw(strB, outlen);
+      delete coded_output;  // flush
+      delete gzout;  // flush
+      int64 size = pos + output->ByteCount();
+      delete output;
+
+      ArrayInputStream* input =
+          new ArrayInputStream(buffer, size, kBlockSizes[j]);
+      GzipInputStream* gzin = new GzipInputStream(input);
+      CodedInputStream* coded_input = new CodedInputStream(gzin);
+      uint32 insize;
+      EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+      EXPECT_EQ(strlen(strA) + 1, insize);
+      EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+      EXPECT_EQ(0, memcmp(temp_buffer, strA, insize))
+          << "strA=" << strA << " in=" << temp_buffer;
+
+      EXPECT_TRUE(coded_input->ReadVarint32(&insize));
+      EXPECT_EQ(strlen(strB) + 1, insize);
+      EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
+      EXPECT_EQ(0, memcmp(temp_buffer, strB, insize))
+          << " out_block_size=" << kBlockSizes[i]
+          << " in_block_size=" << kBlockSizes[j]
+          << " pos=" << pos
+          << " size=" << size
+          << " strB=" << strB << " in=" << temp_buffer;
+
+      delete coded_input;
+      delete gzin;
+      delete input;
+    }
+  }
+
+  delete [] temp_buffer;
+  delete [] buffer;
+}
+#endif
+
+// 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);
+    }
+  }
+}
+
+#if HAVE_ZLIB
+TEST_F(IoTest, GzipFileIo) {
+  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]);
+        GzipOutputStream gzout(&output);
+        WriteStuffLarge(&gzout);
+        gzout.Close();
+        output.Flush();
+        EXPECT_EQ(0, output.GetErrno());
+      }
+
+      // Rewind.
+      ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1);
+
+      {
+        FileInputStream input(file, kBlockSizes[j]);
+        GzipInputStream gzin(&input);
+        ReadStuffLarge(&gzin);
+        EXPECT_EQ(0, input.GetErrno());
+      }
+
+      close(file);
+    }
+  }
+}
+#endif
+
+// 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:
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+  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());
+        }
+      }
+
+      {
+        stringstream stream;
+
+        {
+          OstreamOutputStream output(&stream, kBlockSizes[i]);
+          WriteStuffLarge(&output);
+          EXPECT_FALSE(stream.fail());
+        }
+
+        {
+          IstreamInputStream input(&stream, kBlockSizes[j]);
+          ReadStuffLarge(&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);
+}
+
+// Checks that ByteCount works correctly for LimitingInputStreams where the
+// underlying stream has already been read.
+TEST_F(IoTest, LimitingInputStreamByteCount) {
+  const int kHalfBufferSize = 128;
+  const int kBufferSize = kHalfBufferSize * 2;
+  uint8 buffer[kBufferSize];
+
+  // Set up input. Only allow half to be read at once.
+  ArrayInputStream array_input(buffer, kBufferSize, kHalfBufferSize);
+  const void* data;
+  int size;
+  EXPECT_TRUE(array_input.Next(&data, &size));
+  EXPECT_EQ(kHalfBufferSize, array_input.ByteCount());
+  // kHalfBufferSize - 1 to test limiting logic as well.
+  LimitingInputStream input(&array_input, kHalfBufferSize - 1);
+  EXPECT_EQ(0, input.ByteCount());
+  EXPECT_TRUE(input.Next(&data, &size));
+  EXPECT_EQ(kHalfBufferSize - 1 , input.ByteCount());
+}
+
+// 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/protobuf/src/google/protobuf/lite_unittest.cc b/protobuf/src/google/protobuf/lite_unittest.cc
new file mode 100644
index 0000000..a370526
--- /dev/null
+++ b/protobuf/src/google/protobuf/lite_unittest.cc
@@ -0,0 +1,350 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <string>
+#include <iostream>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/test_util_lite.h>
+#include <google/protobuf/unittest_lite.pb.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+
+using namespace std;
+
+namespace {
+// Helper methods to test parsing merge behavior.
+void ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) {
+  GOOGLE_CHECK(message.optional_int32() == 3);
+  GOOGLE_CHECK(message.optional_int64() == 2);
+  GOOGLE_CHECK(message.optional_string() == "hello");
+}
+
+void AssignParsingMergeMessages(
+    google::protobuf::unittest::TestAllTypesLite* msg1,
+    google::protobuf::unittest::TestAllTypesLite* msg2,
+    google::protobuf::unittest::TestAllTypesLite* msg3) {
+  msg1->set_optional_int32(1);
+  msg2->set_optional_int64(2);
+  msg3->set_optional_int32(3);
+  msg3->set_optional_string("hello");
+}
+
+void SetAllTypesInEmptyMessageUnknownFields(
+    google::protobuf::unittest::TestEmptyMessageLite* empty_message) {
+  protobuf_unittest::TestAllTypesLite message;
+  google::protobuf::TestUtilLite::ExpectClear(message);
+  google::protobuf::TestUtilLite::SetAllFields(&message);
+  string data = message.SerializeAsString();
+  empty_message->ParseFromString(data);
+}
+
+void SetSomeTypesInEmptyMessageUnknownFields(
+    google::protobuf::unittest::TestEmptyMessageLite* empty_message) {
+  protobuf_unittest::TestAllTypesLite message;
+  google::protobuf::TestUtilLite::ExpectClear(message);
+  message.set_optional_int32(101);
+  message.set_optional_int64(102);
+  message.set_optional_uint32(103);
+  message.set_optional_uint64(104);
+  string data = message.SerializeAsString();
+  empty_message->ParseFromString(data);
+}
+
+}  // namespace
+
+int main(int argc, char* argv[]) {
+  string data, data2, packed_data;
+
+  {
+    protobuf_unittest::TestAllTypesLite message, message2, message3;
+    google::protobuf::TestUtilLite::ExpectClear(message);
+    google::protobuf::TestUtilLite::SetAllFields(&message);
+    message2.CopyFrom(message);
+    data = message.SerializeAsString();
+    message3.ParseFromString(data);
+    google::protobuf::TestUtilLite::ExpectAllFieldsSet(message);
+    google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2);
+    google::protobuf::TestUtilLite::ExpectAllFieldsSet(message3);
+    google::protobuf::TestUtilLite::ModifyRepeatedFields(&message);
+    google::protobuf::TestUtilLite::ExpectRepeatedFieldsModified(message);
+    message.Clear();
+    google::protobuf::TestUtilLite::ExpectClear(message);
+  }
+
+  {
+    protobuf_unittest::TestAllExtensionsLite message, message2, message3;
+    google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
+    google::protobuf::TestUtilLite::SetAllExtensions(&message);
+    message2.CopyFrom(message);
+    string extensions_data = message.SerializeAsString();
+    message3.ParseFromString(extensions_data);
+    google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message);
+    google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2);
+    google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message3);
+    google::protobuf::TestUtilLite::ModifyRepeatedExtensions(&message);
+    google::protobuf::TestUtilLite::ExpectRepeatedExtensionsModified(message);
+    message.Clear();
+    google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
+  }
+
+  {
+    protobuf_unittest::TestPackedTypesLite message, message2, message3;
+    google::protobuf::TestUtilLite::ExpectPackedClear(message);
+    google::protobuf::TestUtilLite::SetPackedFields(&message);
+    message2.CopyFrom(message);
+    packed_data = message.SerializeAsString();
+    message3.ParseFromString(packed_data);
+    google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message);
+    google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2);
+    google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message3);
+    google::protobuf::TestUtilLite::ModifyPackedFields(&message);
+    google::protobuf::TestUtilLite::ExpectPackedFieldsModified(message);
+    message.Clear();
+    google::protobuf::TestUtilLite::ExpectPackedClear(message);
+  }
+
+  {
+    protobuf_unittest::TestPackedExtensionsLite message, message2, message3;
+    google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
+    google::protobuf::TestUtilLite::SetPackedExtensions(&message);
+    message2.CopyFrom(message);
+    string packed_extensions_data = message.SerializeAsString();
+    GOOGLE_CHECK(packed_extensions_data == packed_data);
+    message3.ParseFromString(packed_extensions_data);
+    google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message);
+    google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2);
+    google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message3);
+    google::protobuf::TestUtilLite::ModifyPackedExtensions(&message);
+    google::protobuf::TestUtilLite::ExpectPackedExtensionsModified(message);
+    message.Clear();
+    google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
+  }
+
+  {
+    // Test that if an optional or required message/group field appears multiple
+    // times in the input, they need to be merged.
+    google::protobuf::unittest::TestParsingMergeLite::RepeatedFieldsGenerator generator;
+    google::protobuf::unittest::TestAllTypesLite* msg1;
+    google::protobuf::unittest::TestAllTypesLite* msg2;
+    google::protobuf::unittest::TestAllTypesLite* msg3;
+
+#define ASSIGN_REPEATED_FIELD(FIELD)                \
+  msg1 = generator.add_##FIELD();                   \
+  msg2 = generator.add_##FIELD();                   \
+  msg3 = generator.add_##FIELD();                   \
+  AssignParsingMergeMessages(msg1, msg2, msg3)
+
+    ASSIGN_REPEATED_FIELD(field1);
+    ASSIGN_REPEATED_FIELD(field2);
+    ASSIGN_REPEATED_FIELD(field3);
+    ASSIGN_REPEATED_FIELD(ext1);
+    ASSIGN_REPEATED_FIELD(ext2);
+
+#undef ASSIGN_REPEATED_FIELD
+#define ASSIGN_REPEATED_GROUP(FIELD)                \
+  msg1 = generator.add_##FIELD()->mutable_field1(); \
+  msg2 = generator.add_##FIELD()->mutable_field1(); \
+  msg3 = generator.add_##FIELD()->mutable_field1(); \
+  AssignParsingMergeMessages(msg1, msg2, msg3)
+
+    ASSIGN_REPEATED_GROUP(group1);
+    ASSIGN_REPEATED_GROUP(group2);
+
+#undef ASSIGN_REPEATED_GROUP
+
+    string buffer;
+    generator.SerializeToString(&buffer);
+    google::protobuf::unittest::TestParsingMergeLite parsing_merge;
+    parsing_merge.ParseFromString(buffer);
+
+    // Required and optional fields should be merged.
+    ExpectMessageMerged(parsing_merge.required_all_types());
+    ExpectMessageMerged(parsing_merge.optional_all_types());
+    ExpectMessageMerged(
+        parsing_merge.optionalgroup().optional_group_all_types());
+    ExpectMessageMerged(parsing_merge.GetExtension(
+        google::protobuf::unittest::TestParsingMergeLite::optional_ext));
+
+    // Repeated fields should not be merged.
+    GOOGLE_CHECK(parsing_merge.repeated_all_types_size() == 3);
+    GOOGLE_CHECK(parsing_merge.repeatedgroup_size() == 3);
+    GOOGLE_CHECK(parsing_merge.ExtensionSize(
+        google::protobuf::unittest::TestParsingMergeLite::repeated_ext) == 3);
+  }
+
+  // Test unknown fields support for lite messages.
+  {
+    protobuf_unittest::TestAllTypesLite message, message2;
+    protobuf_unittest::TestEmptyMessageLite empty_message;
+    google::protobuf::TestUtilLite::ExpectClear(message);
+    google::protobuf::TestUtilLite::SetAllFields(&message);
+    data = message.SerializeAsString();
+    empty_message.ParseFromString(data);
+    data.clear();
+    data = empty_message.SerializeAsString();
+    message2.ParseFromString(data);
+    data = message2.SerializeAsString();
+    google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2);
+    message.Clear();
+    google::protobuf::TestUtilLite::ExpectClear(message);
+  }
+
+  {
+    protobuf_unittest::TestAllExtensionsLite message, message2;
+    protobuf_unittest::TestEmptyMessageLite empty_message;
+    google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
+    google::protobuf::TestUtilLite::SetAllExtensions(&message);
+    data = message.SerializeAsString();
+    empty_message.ParseFromString(data);
+    data.clear();
+    data = empty_message.SerializeAsString();
+    message2.ParseFromString(data);
+    data = message2.SerializeAsString();
+    google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2);
+    message.Clear();
+    google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
+  }
+
+  {
+    protobuf_unittest::TestPackedTypesLite message, message2;
+    protobuf_unittest::TestEmptyMessageLite empty_message;
+    google::protobuf::TestUtilLite::ExpectPackedClear(message);
+    google::protobuf::TestUtilLite::SetPackedFields(&message);
+    data = message.SerializeAsString();
+    empty_message.ParseFromString(data);
+    data.clear();
+    data = empty_message.SerializeAsString();
+    message2.ParseFromString(data);
+    data = message2.SerializeAsString();
+    google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2);
+    message.Clear();
+    google::protobuf::TestUtilLite::ExpectPackedClear(message);
+  }
+
+  {
+    protobuf_unittest::TestPackedExtensionsLite message, message2;
+    protobuf_unittest::TestEmptyMessageLite empty_message;
+    google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
+    google::protobuf::TestUtilLite::SetPackedExtensions(&message);
+    data = message.SerializeAsString();
+    empty_message.ParseFromString(data);
+    data.clear();
+    data = empty_message.SerializeAsString();
+    message2.ParseFromString(data);
+    data = message2.SerializeAsString();
+    google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2);
+    message.Clear();
+    google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
+  }
+
+  {
+    // Test Unknown fields swap
+    protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2;
+    SetAllTypesInEmptyMessageUnknownFields(&empty_message);
+    SetSomeTypesInEmptyMessageUnknownFields(&empty_message2);
+    data = empty_message.SerializeAsString();
+    data2 = empty_message2.SerializeAsString();
+    empty_message.Swap(&empty_message2);
+    GOOGLE_CHECK_EQ(data, empty_message2.SerializeAsString());
+    GOOGLE_CHECK_EQ(data2, empty_message.SerializeAsString());
+  }
+
+  {
+    // Test unknown fields swap with self
+    protobuf_unittest::TestEmptyMessageLite empty_message;
+    SetAllTypesInEmptyMessageUnknownFields(&empty_message);
+    data = empty_message.SerializeAsString();
+    empty_message.Swap(&empty_message);
+    GOOGLE_CHECK_EQ(data, empty_message.SerializeAsString());
+  }
+
+  {
+    // Test MergeFrom with unknown fields
+    protobuf_unittest::TestAllTypesLite message, message2;
+    protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2;
+    message.set_optional_int32(101);
+    message.add_repeated_int32(201);
+    message.set_optional_nested_enum(google::protobuf::unittest::TestAllTypesLite::BAZ);
+    message2.set_optional_int64(102);
+    message2.add_repeated_int64(202);
+    message2.set_optional_foreign_enum(google::protobuf::unittest::FOREIGN_LITE_BAZ);
+
+    data = message.SerializeAsString();
+    empty_message.ParseFromString(data);
+    data = message2.SerializeAsString();
+    empty_message2.ParseFromString(data);
+    message.MergeFrom(message2);
+    empty_message.MergeFrom(empty_message2);
+
+    data = empty_message.SerializeAsString();
+    message2.ParseFromString(data);
+    // We do not compare the serialized output of a normal message and a lite
+    // message because the order of fields do not match. We convert lite message
+    // back into normal message, then compare.
+    GOOGLE_CHECK_EQ(message.SerializeAsString(), message2.SerializeAsString());
+  }
+
+  {
+    // Test unknown enum value
+    protobuf_unittest::TestAllTypesLite message;
+    string buffer;
+    {
+      google::protobuf::io::StringOutputStream output_stream(&buffer);
+      google::protobuf::io::CodedOutputStream coded_output(&output_stream);
+      google::protobuf::internal::WireFormatLite::WriteTag(
+          protobuf_unittest::TestAllTypesLite::kOptionalNestedEnumFieldNumber,
+          google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
+      coded_output.WriteVarint32(10);
+      google::protobuf::internal::WireFormatLite::WriteTag(
+          protobuf_unittest::TestAllTypesLite::kRepeatedNestedEnumFieldNumber,
+          google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
+      coded_output.WriteVarint32(20);
+    }
+    message.ParseFromString(buffer);
+    data = message.SerializeAsString();
+    GOOGLE_CHECK_EQ(data, buffer);
+  }
+
+  {
+    // Test Clear with unknown fields
+    protobuf_unittest::TestEmptyMessageLite empty_message;
+    SetAllTypesInEmptyMessageUnknownFields(&empty_message);
+    empty_message.Clear();
+    GOOGLE_CHECK_EQ(0, empty_message.unknown_fields().size());
+  }
+
+  cout << "PASS" << endl;
+  return 0;
+}
diff --git a/protobuf/src/google/protobuf/message.cc b/protobuf/src/google/protobuf/message.cc
new file mode 100644
index 0000000..1324ed9
--- /dev/null
+++ b/protobuf/src/google/protobuf/message.cc
@@ -0,0 +1,358 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <iostream>
+#include <stack>
+#include <google/protobuf/stubs/hash.h>
+
+#include <google/protobuf/message.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.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/generated_message_util.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+
+using internal::WireFormat;
+using internal::ReflectionOps;
+
+Message::~Message() {}
+
+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(from, this);
+}
+
+void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
+  MergeFrom(*down_cast<const Message*>(&other));
+}
+
+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(from, this);
+}
+
+string Message::GetTypeName() const {
+  return GetDescriptor()->full_name();
+}
+
+void Message::Clear() {
+  ReflectionOps::Clear(this);
+}
+
+bool Message::IsInitialized() const {
+  return ReflectionOps::IsInitialized(*this);
+}
+
+void Message::FindInitializationErrors(vector<string>* errors) const {
+  return ReflectionOps::FindInitializationErrors(*this, "", errors);
+}
+
+string Message::InitializationErrorString() const {
+  vector<string> errors;
+  FindInitializationErrors(&errors);
+  return Join(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(this);
+}
+
+bool Message::MergePartialFromCodedStream(io::CodedInputStream* input) {
+  return WireFormat::ParseAndMergePartial(input, this);
+}
+
+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();
+}
+
+
+void Message::SerializeWithCachedSizes(
+    io::CodedOutputStream* output) const {
+  WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output);
+}
+
+int Message::ByteSize() const {
+  int size = WireFormat::ByteSize(*this);
+  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.";
+}
+
+int Message::SpaceUsed() const {
+  return GetReflection()->SpaceUsed(*this);
+}
+
+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);
+    if (!SerializeToZeroCopyStream(&zero_copy_output)) return false;
+  }
+  return output->good();
+}
+
+bool Message::SerializePartialToOstream(ostream* output) const {
+  io::OstreamOutputStream zero_copy_output(output);
+  return SerializePartialToZeroCopyStream(&zero_copy_output);
+}
+
+
+// =============================================================================
+// Reflection and associated Template Specializations
+
+Reflection::~Reflection() {}
+
+#define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE)                             \
+template<>                                                            \
+const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>(        \
+    const Message& message, const FieldDescriptor* field) const {     \
+  return *static_cast<RepeatedField<TYPE>* >(                         \
+      MutableRawRepeatedField(const_cast<Message*>(&message),         \
+                          field, CPPTYPE, CTYPE, NULL));              \
+}                                                                     \
+                                                                      \
+template<>                                                            \
+RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>(          \
+    Message* message, const FieldDescriptor* field) const {           \
+  return static_cast<RepeatedField<TYPE>* >(                          \
+      MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \
+}
+
+HANDLE_TYPE(int32,  FieldDescriptor::CPPTYPE_INT32,  -1);
+HANDLE_TYPE(int64,  FieldDescriptor::CPPTYPE_INT64,  -1);
+HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1);
+HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1);
+HANDLE_TYPE(float,  FieldDescriptor::CPPTYPE_FLOAT,  -1);
+HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
+HANDLE_TYPE(bool,   FieldDescriptor::CPPTYPE_BOOL,   -1);
+
+
+#undef HANDLE_TYPE
+
+void* Reflection::MutableRawRepeatedString(
+    Message* message, const FieldDescriptor* field, bool is_string) const {
+  return MutableRawRepeatedField(message, field,
+      FieldDescriptor::CPPTYPE_STRING, FieldOptions::STRING, NULL);
+}
+
+
+// =============================================================================
+// MessageFactory
+
+MessageFactory::~MessageFactory() {}
+
+namespace {
+
+class GeneratedMessageFactory : public MessageFactory {
+ public:
+  GeneratedMessageFactory();
+  ~GeneratedMessageFactory();
+
+  static GeneratedMessageFactory* singleton();
+
+  typedef void RegistrationFunc(const string&);
+  void RegisterFile(const char* file, RegistrationFunc* registration_func);
+  void RegisterType(const Descriptor* descriptor, const Message* prototype);
+
+  // implements MessageFactory ---------------------------------------
+  const Message* GetPrototype(const Descriptor* type);
+
+ private:
+  // Only written at static init time, so does not require locking.
+  hash_map<const char*, RegistrationFunc*,
+           hash<const char*>, streq> file_map_;
+
+  // Initialized lazily, so requires locking.
+  Mutex mutex_;
+  hash_map<const Descriptor*, const Message*> type_map_;
+};
+
+GeneratedMessageFactory* generated_message_factory_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(generated_message_factory_once_init_);
+
+void ShutdownGeneratedMessageFactory() {
+  delete generated_message_factory_;
+}
+
+void InitGeneratedMessageFactory() {
+  generated_message_factory_ = new GeneratedMessageFactory;
+  internal::OnShutdown(&ShutdownGeneratedMessageFactory);
+}
+
+GeneratedMessageFactory::GeneratedMessageFactory() {}
+GeneratedMessageFactory::~GeneratedMessageFactory() {}
+
+GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
+  ::google::protobuf::GoogleOnceInit(&generated_message_factory_once_init_,
+                 &InitGeneratedMessageFactory);
+  return generated_message_factory_;
+}
+
+void GeneratedMessageFactory::RegisterFile(
+    const char* file, RegistrationFunc* registration_func) {
+  if (!InsertIfNotPresent(&file_map_, file, registration_func)) {
+    GOOGLE_LOG(FATAL) << "File is already registered: " << file;
+  }
+}
+
+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.";
+
+  // This should only be called as a result of calling a file registration
+  // function during GetPrototype(), in which case we already have locked
+  // the mutex.
+  mutex_.AssertHeld();
+  if (!InsertIfNotPresent(&type_map_, descriptor, prototype)) {
+    GOOGLE_LOG(DFATAL) << "Type is already registered: " << descriptor->full_name();
+  }
+}
+
+
+const Message* GeneratedMessageFactory::GetPrototype(const Descriptor* type) {
+  {
+    ReaderMutexLock lock(&mutex_);
+    const Message* result = FindPtrOrNull(type_map_, type);
+    if (result != NULL) return result;
+  }
+
+  // If the type is not in the generated pool, then we can't possibly handle
+  // it.
+  if (type->file()->pool() != DescriptorPool::generated_pool()) return NULL;
+
+  // Apparently the file hasn't been registered yet.  Let's do that now.
+  RegistrationFunc* registration_func =
+      FindPtrOrNull(file_map_, type->file()->name().c_str());
+  if (registration_func == NULL) {
+    GOOGLE_LOG(DFATAL) << "File appears to be in generated pool but wasn't "
+                   "registered: " << type->file()->name();
+    return NULL;
+  }
+
+  WriterMutexLock lock(&mutex_);
+
+  // Check if another thread preempted us.
+  const Message* result = FindPtrOrNull(type_map_, type);
+  if (result == NULL) {
+    // Nope.  OK, register everything.
+    registration_func(type->file()->name());
+    // Should be here now.
+    result = FindPtrOrNull(type_map_, type);
+  }
+
+  if (result == NULL) {
+    GOOGLE_LOG(DFATAL) << "Type appears to be in generated pool but wasn't "
+                << "registered: " << type->full_name();
+  }
+
+  return result;
+}
+
+}  // namespace
+
+MessageFactory* MessageFactory::generated_factory() {
+  return GeneratedMessageFactory::singleton();
+}
+
+void MessageFactory::InternalRegisterGeneratedFile(
+    const char* filename, void (*register_messages)(const string&)) {
+  GeneratedMessageFactory::singleton()->RegisterFile(filename,
+                                                     register_messages);
+}
+
+void MessageFactory::InternalRegisterGeneratedMessage(
+    const Descriptor* descriptor, const Message* prototype) {
+  GeneratedMessageFactory::singleton()->RegisterType(descriptor, prototype);
+}
+
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/message.h b/protobuf/src/google/protobuf/message.h
new file mode 100644
index 0000000..ff2fcd8
--- /dev/null
+++ b/protobuf/src/google/protobuf/message.h
@@ -0,0 +1,866 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Defines Message, the abstract interface implemented by non-lite
+// protocol message objects.  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;
+//     const Descriptor* descriptor = foo->GetDescriptor();
+//
+//     // Get the descriptors for the fields we're interested in and verify
+//     // their types.
+//     const FieldDescriptor* text_field = descriptor->FindFieldByName("text");
+//     assert(text_field != NULL);
+//     assert(text_field->type() == FieldDescriptor::TYPE_STRING);
+//     assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL);
+//     const FieldDescriptor* numbers_field = descriptor->
+//                                            FindFieldByName("numbers");
+//     assert(numbers_field != NULL);
+//     assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
+//     assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED);
+//
+//     // Parse the message.
+//     foo->ParseFromString(data);
+//
+//     // Use the reflection interface to examine the contents.
+//     const Reflection* reflection = foo->GetReflection();
+//     assert(reflection->GetString(foo, text_field) == "Hello World!");
+//     assert(reflection->FieldSize(foo, numbers_field) == 3);
+//     assert(reflection->GetRepeatedInt32(foo, numbers_field, 0) == 1);
+//     assert(reflection->GetRepeatedInt32(foo, numbers_field, 1) == 5);
+//     assert(reflection->GetRepeatedInt32(foo, numbers_field, 2) == 42);
+//
+//     delete foo;
+//   }
+
+#ifndef GOOGLE_PROTOBUF_MESSAGE_H__
+#define GOOGLE_PROTOBUF_MESSAGE_H__
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/message_lite.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+
+
+#define GOOGLE_PROTOBUF_HAS_ONEOF
+
+namespace google {
+namespace protobuf {
+
+// Defined in this file.
+class Message;
+class Reflection;
+class MessageFactory;
+
+// Defined in other files.
+class UnknownFieldSet;         // unknown_field_set.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
+}
+
+
+template<typename T>
+class RepeatedField;     // repeated_field.h
+
+template<typename T>
+class RepeatedPtrField;  // repeated_field.h
+
+// A container to hold message metadata.
+struct Metadata {
+  const Descriptor* descriptor;
+  const Reflection* reflection;
+};
+
+// Abstract interface for protocol messages.
+//
+// See also MessageLite, which contains most every-day operations.  Message
+// adds descriptors and reflection on top of that.
+//
+// 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 MessageLite {
+ public:
+  inline Message() {}
+  virtual ~Message();
+
+  // Basic Operations ------------------------------------------------
+
+  // Construct a new instance of the same type.  Ownership is passed to the
+  // caller.  (This is also defined in MessageLite, but is defined again here
+  // for return-type covariance.)
+  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, if specified in from, 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);
+
+  // 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(std::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();
+
+  // Computes (an estimate of) the total number of bytes currently used for
+  // storing the message in memory.  The default implementation calls the
+  // Reflection object's SpaceUsed() method.
+  virtual int SpaceUsed() const;
+
+  // Debugging & Testing----------------------------------------------
+
+  // 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;
+  // Like DebugString(), but do not escape UTF-8 byte sequences.
+  string Utf8DebugString() const;
+  // Convenience function useful in GDB.  Prints DebugString() to stdout.
+  void PrintDebugString() const;
+
+  // Heavy I/O -------------------------------------------------------
+  // Additional parsing and serialization methods not implemented by
+  // MessageLite because they are not supported by the lite library.
+
+  // 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);
+
+  // 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;
+
+
+  // Reflection-based methods ----------------------------------------
+  // These methods are pure-virtual in MessageLite, but Message provides
+  // reflection-based default implementations.
+
+  virtual string GetTypeName() const;
+  virtual void Clear();
+  virtual bool IsInitialized() const;
+  virtual void CheckTypeAndMergeFrom(const MessageLite& other);
+  virtual bool MergePartialFromCodedStream(io::CodedInputStream* input);
+  virtual int ByteSize() const;
+  virtual void SerializeWithCachedSizes(io::CodedOutputStream* output) const;
+
+ 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 ---------------------------------------------------
+
+  // Typedef for backwards-compatibility.
+  typedef google::protobuf::Reflection Reflection;
+
+  // Get a Descriptor for this message's type.  This describes what
+  // fields the message contains, the types of those fields, etc.
+  const Descriptor* GetDescriptor() const { return GetMetadata().descriptor; }
+
+  // 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.
+  //
+  // This method remains virtual in case a subclass does not implement
+  // reflection and wants to override the default behavior.
+  virtual const Reflection* GetReflection() const {
+    return GetMetadata().reflection;
+  }
+
+ protected:
+  // Get a struct containing the metadata for the Message. Most subclasses only
+  // need to implement this method, rather than the GetDescriptor() and
+  // GetReflection() wrappers.
+  virtual Metadata GetMetadata() const  = 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), and all Messages of a particular class
+// should share the same Reflection object (though you should not rely on
+// the latter fact).
+//
+// There are several ways that these methods can be used incorrectly.  For
+// example, any of the following conditions will lead to undefined
+// 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.
+// - The Message object passed to any method is not of the right type for
+//   this Reflection object (i.e. message.GetReflection() != reflection).
+//
+// You might wonder why there is not any abstract representation for a field
+// of arbitrary type.  E.g., why isn't there just a "GetField()" method that
+// 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 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 Message& message) const = 0;
+  // Get a mutable pointer to the UnknownFieldSet for the message.  This
+  // contains fields which were seen when the Message was parsed but were not
+  // recognized according to the Message's definition.
+  virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0;
+
+  // Estimate the amount of memory used by the message object.
+  virtual int SpaceUsed(const Message& message) const = 0;
+
+  // Check if the given non-repeated field is set.
+  virtual bool HasField(const Message& message,
+                        const FieldDescriptor* field) const = 0;
+
+  // Get the number of elements of a repeated field.
+  virtual int FieldSize(const Message& message,
+                        const FieldDescriptor* field) const = 0;
+
+  // Clear the value of a field, so that HasField() returns false or
+  // FieldSize() returns zero.
+  virtual void ClearField(Message* message,
+                          const FieldDescriptor* field) const = 0;
+
+  // Check if the oneof is set. Returns ture if any field in oneof
+  // is set, false otherwise.
+  // TODO(jieluo) - make it pure virtual after updating all
+  // the subclasses.
+  virtual bool HasOneof(const Message& /*message*/,
+                        const OneofDescriptor* /*oneof_descriptor*/) const {
+    return false;
+  }
+
+  virtual void ClearOneof(Message* /*message*/,
+                          const OneofDescriptor* /*oneof_descriptor*/) const {}
+
+  // Returns the field descriptor if the oneof is set. NULL otherwise.
+  // TODO(jieluo) - make it pure virtual.
+  virtual const FieldDescriptor* GetOneofFieldDescriptor(
+      const Message& /*message*/,
+      const OneofDescriptor* /*oneof_descriptor*/) const {
+    return NULL;
+  }
+
+  // Removes the last element of a repeated field.
+  // 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
+  // (using Swap()) so that the one you want removed is at the end, then
+  // call RemoveLast().
+  virtual void RemoveLast(Message* message,
+                          const FieldDescriptor* field) const = 0;
+  // Removes the last element of a repeated message field, and returns the
+  // pointer to the caller.  Caller takes ownership of the returned pointer.
+  virtual Message* ReleaseLast(Message* message,
+                               const FieldDescriptor* field) const = 0;
+
+  // Swap the complete contents of two messages.
+  virtual void Swap(Message* message1, Message* message2) const = 0;
+
+  // Swap fields listed in fields vector of two messages.
+  virtual void SwapFields(Message* message1,
+                          Message* message2,
+                          const std::vector<const FieldDescriptor*>& fields)
+      const = 0;
+
+  // Swap two elements of a repeated field.
+  virtual void SwapElements(Message* message,
+                            const FieldDescriptor* field,
+                            int index1,
+                            int index2) const = 0;
+
+  // List all fields of the message which are currently set.  This includes
+  // extensions.  Singular fields will only be listed if HasField(field) would
+  // return true and repeated fields will only be listed if FieldSize(field)
+  // would return non-zero.  Fields (both normal fields and extension fields)
+  // will be listed ordered by field number.
+  virtual void ListFields(const Message& message,
+                          std::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 Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual int64  GetInt64 (const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual uint32 GetUInt32(const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual uint64 GetUInt64(const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual float  GetFloat (const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual double GetDouble(const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual bool   GetBool  (const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual string GetString(const Message& message,
+                           const FieldDescriptor* field) const = 0;
+  virtual const EnumValueDescriptor* GetEnum(
+      const Message& message, const FieldDescriptor* field) const = 0;
+  // See MutableMessage() for the meaning of the "factory" parameter.
+  virtual const Message& GetMessage(const Message& message,
+                                    const FieldDescriptor* field,
+                                    MessageFactory* factory = NULL) 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 Message& message,
+                                           const FieldDescriptor* field,
+                                           string* scratch) const = 0;
+
+
+  // Singular field mutators -----------------------------------------
+  // These mutate the value of a non-repeated field.
+
+  virtual void SetInt32 (Message* message,
+                         const FieldDescriptor* field, int32  value) const = 0;
+  virtual void SetInt64 (Message* message,
+                         const FieldDescriptor* field, int64  value) const = 0;
+  virtual void SetUInt32(Message* message,
+                         const FieldDescriptor* field, uint32 value) const = 0;
+  virtual void SetUInt64(Message* message,
+                         const FieldDescriptor* field, uint64 value) const = 0;
+  virtual void SetFloat (Message* message,
+                         const FieldDescriptor* field, float  value) const = 0;
+  virtual void SetDouble(Message* message,
+                         const FieldDescriptor* field, double value) const = 0;
+  virtual void SetBool  (Message* message,
+                         const FieldDescriptor* field, bool   value) const = 0;
+  virtual void SetString(Message* message,
+                         const FieldDescriptor* field,
+                         const string& value) const = 0;
+  virtual void SetEnum  (Message* message,
+                         const FieldDescriptor* field,
+                         const EnumValueDescriptor* value) const = 0;
+  // Get a mutable pointer to a field with a message type.  If a MessageFactory
+  // is provided, it will be used to construct instances of the sub-message;
+  // otherwise, the default factory is used.  If the field is an extension that
+  // does not live in the same pool as the containing message's descriptor (e.g.
+  // it lives in an overlay pool), then a MessageFactory must be provided.
+  // If you have no idea what that meant, then you probably don't need to worry
+  // about it (don't provide a MessageFactory).  WARNING:  If the
+  // FieldDescriptor is for a compiled-in extension, then
+  // factory->GetPrototype(field->message_type() MUST return an instance of the
+  // compiled-in class for this type, NOT DynamicMessage.
+  virtual Message* MutableMessage(Message* message,
+                                  const FieldDescriptor* field,
+                                  MessageFactory* factory = NULL) const = 0;
+  // Replaces the message specified by 'field' with the already-allocated object
+  // sub_message, passing ownership to the message.  If the field contained a
+  // message, that message is deleted.  If sub_message is NULL, the field is
+  // cleared.
+  virtual void SetAllocatedMessage(Message* message,
+                                   Message* sub_message,
+                                   const FieldDescriptor* field) const = 0;
+  // Releases the message specified by 'field' and returns the pointer,
+  // ReleaseMessage() will return the message the message object if it exists.
+  // Otherwise, it may or may not return NULL.  In any case, if the return value
+  // is non-NULL, the caller takes ownership of the pointer.
+  // If the field existed (HasField() is true), then the returned pointer will
+  // be the same as the pointer returned by MutableMessage().
+  // This function has the same effect as ClearField().
+  virtual Message* ReleaseMessage(Message* message,
+                                  const FieldDescriptor* field,
+                                  MessageFactory* factory = NULL) const = 0;
+
+
+  // Repeated field getters ------------------------------------------
+  // These get the value of one element of a repeated field.
+
+  virtual int32  GetRepeatedInt32 (const Message& message,
+                                   const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual int64  GetRepeatedInt64 (const Message& message,
+                                   const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual uint32 GetRepeatedUInt32(const Message& message,
+                                   const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual uint64 GetRepeatedUInt64(const Message& message,
+                                   const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual float  GetRepeatedFloat (const Message& message,
+                                   const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual double GetRepeatedDouble(const Message& message,
+                                   const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual bool   GetRepeatedBool  (const Message& message,
+                                   const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual string GetRepeatedString(const Message& message,
+                                   const FieldDescriptor* field,
+                                   int index) const = 0;
+  virtual const EnumValueDescriptor* GetRepeatedEnum(
+      const Message& message,
+      const FieldDescriptor* field, int index) const = 0;
+  virtual const Message& GetRepeatedMessage(
+      const Message& message,
+      const FieldDescriptor* field, int index) const = 0;
+
+  // See GetStringReference(), above.
+  virtual const string& GetRepeatedStringReference(
+      const Message& message, const FieldDescriptor* field,
+      int index, string* scratch) const = 0;
+
+
+  // Repeated field mutators -----------------------------------------
+  // These mutate the value of one element of a repeated field.
+
+  virtual void SetRepeatedInt32 (Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, int32  value) const = 0;
+  virtual void SetRepeatedInt64 (Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, int64  value) const = 0;
+  virtual void SetRepeatedUInt32(Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, uint32 value) const = 0;
+  virtual void SetRepeatedUInt64(Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, uint64 value) const = 0;
+  virtual void SetRepeatedFloat (Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, float  value) const = 0;
+  virtual void SetRepeatedDouble(Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, double value) const = 0;
+  virtual void SetRepeatedBool  (Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, bool   value) const = 0;
+  virtual void SetRepeatedString(Message* message,
+                                 const FieldDescriptor* field,
+                                 int index, const string& value) const = 0;
+  virtual void SetRepeatedEnum(Message* message,
+                               const FieldDescriptor* field, int index,
+                               const EnumValueDescriptor* value) const = 0;
+  // Get a mutable pointer to an element of a repeated field with a message
+  // type.
+  virtual Message* MutableRepeatedMessage(
+      Message* message, const FieldDescriptor* field, int index) const = 0;
+
+
+  // Repeated field adders -------------------------------------------
+  // These add an element to a repeated field.
+
+  virtual void AddInt32 (Message* message,
+                         const FieldDescriptor* field, int32  value) const = 0;
+  virtual void AddInt64 (Message* message,
+                         const FieldDescriptor* field, int64  value) const = 0;
+  virtual void AddUInt32(Message* message,
+                         const FieldDescriptor* field, uint32 value) const = 0;
+  virtual void AddUInt64(Message* message,
+                         const FieldDescriptor* field, uint64 value) const = 0;
+  virtual void AddFloat (Message* message,
+                         const FieldDescriptor* field, float  value) const = 0;
+  virtual void AddDouble(Message* message,
+                         const FieldDescriptor* field, double value) const = 0;
+  virtual void AddBool  (Message* message,
+                         const FieldDescriptor* field, bool   value) const = 0;
+  virtual void AddString(Message* message,
+                         const FieldDescriptor* field,
+                         const string& value) const = 0;
+  virtual void AddEnum  (Message* message,
+                         const FieldDescriptor* field,
+                         const EnumValueDescriptor* value) const = 0;
+  // See MutableMessage() for comments on the "factory" parameter.
+  virtual Message* AddMessage(Message* message,
+                              const FieldDescriptor* field,
+                              MessageFactory* factory = NULL) const = 0;
+
+
+  // Repeated field accessors  -------------------------------------------------
+  // The methods above, e.g. GetRepeatedInt32(msg, fd, index), provide singular
+  // access to the data in a RepeatedField.  The methods below provide aggregate
+  // access by exposing the RepeatedField object itself with the Message.
+  // Applying these templates to inappropriate types will lead to an undefined
+  // reference at link time (e.g. GetRepeatedField<***double>), or possibly a
+  // template matching error at compile time (e.g. GetRepeatedPtrField<File>).
+  //
+  // Usage example: my_doubs = refl->GetRepeatedField<double>(msg, fd);
+
+  // for T = Cord and all protobuf scalar types except enums.
+  template<typename T>
+  const RepeatedField<T>& GetRepeatedField(
+      const Message&, const FieldDescriptor*) const;
+
+  // for T = Cord and all protobuf scalar types except enums.
+  template<typename T>
+  RepeatedField<T>* MutableRepeatedField(
+      Message*, const FieldDescriptor*) const;
+
+  // for T = string, google::protobuf::internal::StringPieceField
+  //         google::protobuf::Message & descendants.
+  template<typename T>
+  const RepeatedPtrField<T>& GetRepeatedPtrField(
+      const Message&, const FieldDescriptor*) const;
+
+  // for T = string, google::protobuf::internal::StringPieceField
+  //         google::protobuf::Message & descendants.
+  template<typename T>
+  RepeatedPtrField<T>* MutableRepeatedPtrField(
+      Message*, const FieldDescriptor*) const;
+
+  // 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;
+
+  // ---------------------------------------------------------------------------
+
+ protected:
+  // Obtain a pointer to a Repeated Field Structure and do some type checking:
+  //   on field->cpp_type(),
+  //   on field->field_option().ctype() (if ctype >= 0)
+  //   of field->message_type() (if message_type != NULL).
+  // We use 1 routine rather than 4 (const vs mutable) x (scalar vs pointer).
+  virtual void* MutableRawRepeatedField(
+      Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
+      int ctype, const Descriptor* message_type) const = 0;
+
+ private:
+  // Special version for specialized implementations of string.  We can't call
+  // MutableRawRepeatedField directly here because we don't have access to
+  // FieldOptions::* which are defined in descriptor.pb.h.  Including that
+  // file here is not possible because it would cause a circular include cycle.
+  void* MutableRawRepeatedString(
+      Message* message, const FieldDescriptor* field, bool is_string) const;
+
+  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 destroyed 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 .proto file at static initialization
+  // time, to be placed in generated_factory.  The first time GetPrototype()
+  // is called with a descriptor from this file, |register_messages| will be
+  // called, with the file name as the parameter.  It must call
+  // InternalRegisterGeneratedMessage() (below) to register each message type
+  // in the file.  This strange mechanism is necessary because descriptors are
+  // built lazily, so we can't register types by their descriptor until we
+  // know that the descriptor exists.  |filename| must be a permanent string.
+  static void InternalRegisterGeneratedFile(
+      const char* filename, void (*register_messages)(const string&));
+
+  // For internal use only:  Registers a message type.  Called only by the
+  // functions which are registered with InternalRegisterGeneratedFile(),
+  // above.
+  static void InternalRegisterGeneratedMessage(const Descriptor* descriptor,
+                                               const Message* prototype);
+
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFactory);
+};
+
+#define DECLARE_GET_REPEATED_FIELD(TYPE)                         \
+template<>                                                       \
+LIBPROTOBUF_EXPORT                                               \
+const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>(   \
+    const Message& message, const FieldDescriptor* field) const; \
+                                                                 \
+template<>                                                       \
+RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>(     \
+    Message* message, const FieldDescriptor* field) const;
+
+DECLARE_GET_REPEATED_FIELD(int32)
+DECLARE_GET_REPEATED_FIELD(int64)
+DECLARE_GET_REPEATED_FIELD(uint32)
+DECLARE_GET_REPEATED_FIELD(uint64)
+DECLARE_GET_REPEATED_FIELD(float)
+DECLARE_GET_REPEATED_FIELD(double)
+DECLARE_GET_REPEATED_FIELD(bool)
+
+#undef DECLARE_GET_REPEATED_FIELD
+
+// =============================================================================
+// Implementation details for {Get,Mutable}RawRepeatedPtrField.  We provide
+// specializations for <string>, <StringPieceField> and <Message> and handle
+// everything else with the default template which will match any type having
+// a method with signature "static const google::protobuf::Descriptor* descriptor()".
+// Such a type presumably is a descendant of google::protobuf::Message.
+
+template<>
+inline const RepeatedPtrField<string>& Reflection::GetRepeatedPtrField<string>(
+    const Message& message, const FieldDescriptor* field) const {
+  return *static_cast<RepeatedPtrField<string>* >(
+      MutableRawRepeatedString(const_cast<Message*>(&message), field, true));
+}
+
+template<>
+inline RepeatedPtrField<string>* Reflection::MutableRepeatedPtrField<string>(
+    Message* message, const FieldDescriptor* field) const {
+  return static_cast<RepeatedPtrField<string>* >(
+      MutableRawRepeatedString(message, field, true));
+}
+
+
+// -----
+
+template<>
+inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrField(
+    const Message& message, const FieldDescriptor* field) const {
+  return *static_cast<RepeatedPtrField<Message>* >(
+      MutableRawRepeatedField(const_cast<Message*>(&message), field,
+          FieldDescriptor::CPPTYPE_MESSAGE, -1,
+          NULL));
+}
+
+template<>
+inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrField(
+    Message* message, const FieldDescriptor* field) const {
+  return static_cast<RepeatedPtrField<Message>* >(
+      MutableRawRepeatedField(message, field,
+          FieldDescriptor::CPPTYPE_MESSAGE, -1,
+          NULL));
+}
+
+template<typename PB>
+inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrField(
+    const Message& message, const FieldDescriptor* field) const {
+  return *static_cast<RepeatedPtrField<PB>* >(
+      MutableRawRepeatedField(const_cast<Message*>(&message), field,
+          FieldDescriptor::CPPTYPE_MESSAGE, -1,
+          PB::default_instance().GetDescriptor()));
+}
+
+template<typename PB>
+inline RepeatedPtrField<PB>* Reflection::MutableRepeatedPtrField(
+    Message* message, const FieldDescriptor* field) const {
+  return static_cast<RepeatedPtrField<PB>* >(
+      MutableRawRepeatedField(message, field,
+          FieldDescriptor::CPPTYPE_MESSAGE, -1,
+          PB::default_instance().GetDescriptor()));
+}
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_MESSAGE_H__
diff --git a/protobuf/src/google/protobuf/message_lite.cc b/protobuf/src/google/protobuf/message_lite.cc
new file mode 100644
index 0000000..14cdc91
--- /dev/null
+++ b/protobuf/src/google/protobuf/message_lite.cc
@@ -0,0 +1,335 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Authors: wink@google.com (Wink Saville),
+//          kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/message_lite.h>
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+
+MessageLite::~MessageLite() {}
+
+string MessageLite::InitializationErrorString() const {
+  return "(cannot determine missing fields for lite message)";
+}
+
+namespace {
+
+// When serializing, we first compute the byte size, then serialize the message.
+// If serialization produces a different number of bytes than expected, we
+// call this function, which crashes.  The problem could be due to a bug in the
+// protobuf implementation but is more likely caused by concurrent modification
+// of the message.  This function attempts to distinguish between the two and
+// provide a useful error message.
+void ByteSizeConsistencyError(int byte_size_before_serialization,
+                              int byte_size_after_serialization,
+                              int bytes_produced_by_serialization) {
+  GOOGLE_CHECK_EQ(byte_size_before_serialization, byte_size_after_serialization)
+      << "Protocol message was modified concurrently during serialization.";
+  GOOGLE_CHECK_EQ(bytes_produced_by_serialization, byte_size_before_serialization)
+      << "Byte size calculation and serialization were inconsistent.  This "
+         "may indicate a bug in protocol buffers or it may be caused by "
+         "concurrent modification of the message.";
+  GOOGLE_LOG(FATAL) << "This shouldn't be called if all the sizes are equal.";
+}
+
+string InitializationErrorMessage(const char* action,
+                                  const MessageLite& message) {
+  // Note:  We want to avoid depending on strutil in the lite library, otherwise
+  //   we'd use:
+  //
+  // return strings::Substitute(
+  //   "Can't $0 message of type \"$1\" because it is missing required "
+  //   "fields: $2",
+  //   action, message.GetTypeName(),
+  //   message.InitializationErrorString());
+
+  string result;
+  result += "Can't ";
+  result += action;
+  result += " message of type \"";
+  result += message.GetTypeName();
+  result += "\" because it is missing required fields: ";
+  result += message.InitializationErrorString();
+  return result;
+}
+
+// Several of the Parse methods below just do one thing and then call another
+// method.  In a naive implementation, we might have ParseFromString() call
+// ParseFromArray() which would call ParseFromZeroCopyStream() which would call
+// ParseFromCodedStream() which would call MergeFromCodedStream() which would
+// call MergePartialFromCodedStream().  However, when parsing very small
+// messages, every function call introduces significant overhead.  To avoid
+// this without reproducing code, we use these forced-inline helpers.
+//
+// Note:  GCC only allows GOOGLE_ATTRIBUTE_ALWAYS_INLINE on declarations, not
+//   definitions.
+inline bool InlineMergeFromCodedStream(io::CodedInputStream* input,
+                                       MessageLite* message)
+                                       GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline bool InlineParseFromCodedStream(io::CodedInputStream* input,
+                                       MessageLite* message)
+                                       GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
+                                              MessageLite* message)
+                                              GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline bool InlineParseFromArray(const void* data, int size,
+                                 MessageLite* message)
+                                 GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+inline bool InlineParsePartialFromArray(const void* data, int size,
+                                        MessageLite* message)
+                                        GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+bool InlineMergeFromCodedStream(io::CodedInputStream* input,
+                                MessageLite* message) {
+  if (!message->MergePartialFromCodedStream(input)) return false;
+  if (!message->IsInitialized()) {
+    GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);
+    return false;
+  }
+  return true;
+}
+
+bool InlineParseFromCodedStream(io::CodedInputStream* input,
+                                MessageLite* message) {
+  message->Clear();
+  return InlineMergeFromCodedStream(input, message);
+}
+
+bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
+                                       MessageLite* message) {
+  message->Clear();
+  return message->MergePartialFromCodedStream(input);
+}
+
+bool InlineParseFromArray(const void* data, int size, MessageLite* message) {
+  io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
+  return InlineParseFromCodedStream(&input, message) &&
+         input.ConsumedEntireMessage();
+}
+
+bool InlineParsePartialFromArray(const void* data, int size,
+                                 MessageLite* message) {
+  io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
+  return InlineParsePartialFromCodedStream(&input, message) &&
+         input.ConsumedEntireMessage();
+}
+
+}  // namespace
+
+bool MessageLite::MergeFromCodedStream(io::CodedInputStream* input) {
+  return InlineMergeFromCodedStream(input, this);
+}
+
+bool MessageLite::ParseFromCodedStream(io::CodedInputStream* input) {
+  return InlineParseFromCodedStream(input, this);
+}
+
+bool MessageLite::ParsePartialFromCodedStream(io::CodedInputStream* input) {
+  return InlineParsePartialFromCodedStream(input, this);
+}
+
+bool MessageLite::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
+  io::CodedInputStream decoder(input);
+  return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage();
+}
+
+bool MessageLite::ParsePartialFromZeroCopyStream(
+    io::ZeroCopyInputStream* input) {
+  io::CodedInputStream decoder(input);
+  return ParsePartialFromCodedStream(&decoder) &&
+         decoder.ConsumedEntireMessage();
+}
+
+bool MessageLite::ParseFromBoundedZeroCopyStream(
+    io::ZeroCopyInputStream* input, int size) {
+  io::CodedInputStream decoder(input);
+  decoder.PushLimit(size);
+  return ParseFromCodedStream(&decoder) &&
+         decoder.ConsumedEntireMessage() &&
+         decoder.BytesUntilLimit() == 0;
+}
+
+bool MessageLite::ParsePartialFromBoundedZeroCopyStream(
+    io::ZeroCopyInputStream* input, int size) {
+  io::CodedInputStream decoder(input);
+  decoder.PushLimit(size);
+  return ParsePartialFromCodedStream(&decoder) &&
+         decoder.ConsumedEntireMessage() &&
+         decoder.BytesUntilLimit() == 0;
+}
+
+bool MessageLite::ParseFromString(const string& data) {
+  return InlineParseFromArray(data.data(), data.size(), this);
+}
+
+bool MessageLite::ParsePartialFromString(const string& data) {
+  return InlineParsePartialFromArray(data.data(), data.size(), this);
+}
+
+bool MessageLite::ParseFromArray(const void* data, int size) {
+  return InlineParseFromArray(data, size, this);
+}
+
+bool MessageLite::ParsePartialFromArray(const void* data, int size) {
+  return InlineParsePartialFromArray(data, size, this);
+}
+
+
+// ===================================================================
+
+uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const {
+  // We only optimize this when using optimize_for = SPEED.  In other cases
+  // we just use the CodedOutputStream path.
+  int size = GetCachedSize();
+  io::ArrayOutputStream out(target, size);
+  io::CodedOutputStream coded_out(&out);
+  SerializeWithCachedSizes(&coded_out);
+  GOOGLE_CHECK(!coded_out.HadError());
+  return target + size;
+}
+
+bool MessageLite::SerializeToCodedStream(io::CodedOutputStream* output) const {
+  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
+  return SerializePartialToCodedStream(output);
+}
+
+bool MessageLite::SerializePartialToCodedStream(
+    io::CodedOutputStream* output) const {
+  const int size = ByteSize();  // Force size to be cached.
+  uint8* buffer = output->GetDirectBufferForNBytesAndAdvance(size);
+  if (buffer != NULL) {
+    uint8* end = SerializeWithCachedSizesToArray(buffer);
+    if (end - buffer != size) {
+      ByteSizeConsistencyError(size, ByteSize(), end - buffer);
+    }
+    return true;
+  } else {
+    int original_byte_count = output->ByteCount();
+    SerializeWithCachedSizes(output);
+    if (output->HadError()) {
+      return false;
+    }
+    int final_byte_count = output->ByteCount();
+
+    if (final_byte_count - original_byte_count != size) {
+      ByteSizeConsistencyError(size, ByteSize(),
+                               final_byte_count - original_byte_count);
+    }
+
+    return true;
+  }
+}
+
+bool MessageLite::SerializeToZeroCopyStream(
+    io::ZeroCopyOutputStream* output) const {
+  io::CodedOutputStream encoder(output);
+  return SerializeToCodedStream(&encoder);
+}
+
+bool MessageLite::SerializePartialToZeroCopyStream(
+    io::ZeroCopyOutputStream* output) const {
+  io::CodedOutputStream encoder(output);
+  return SerializePartialToCodedStream(&encoder);
+}
+
+bool MessageLite::AppendToString(string* output) const {
+  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
+  return AppendPartialToString(output);
+}
+
+bool MessageLite::AppendPartialToString(string* output) const {
+  int old_size = output->size();
+  int byte_size = ByteSize();
+  STLStringResizeUninitialized(output, old_size + byte_size);
+  uint8* start =
+      reinterpret_cast<uint8*>(io::mutable_string_data(output) + old_size);
+  uint8* end = SerializeWithCachedSizesToArray(start);
+  if (end - start != byte_size) {
+    ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
+  }
+  return true;
+}
+
+bool MessageLite::SerializeToString(string* output) const {
+  output->clear();
+  return AppendToString(output);
+}
+
+bool MessageLite::SerializePartialToString(string* output) const {
+  output->clear();
+  return AppendPartialToString(output);
+}
+
+bool MessageLite::SerializeToArray(void* data, int size) const {
+  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
+  return SerializePartialToArray(data, size);
+}
+
+bool MessageLite::SerializePartialToArray(void* data, int size) const {
+  int byte_size = ByteSize();
+  if (size < byte_size) return false;
+  uint8* start = reinterpret_cast<uint8*>(data);
+  uint8* end = SerializeWithCachedSizesToArray(start);
+  if (end - start != byte_size) {
+    ByteSizeConsistencyError(byte_size, ByteSize(), end - start);
+  }
+  return true;
+}
+
+string MessageLite::SerializeAsString() const {
+  // If the compiler implements the (Named) Return Value Optimization,
+  // the local variable 'result' will not actually reside on the stack
+  // of this function, but will be overlaid with the object that the
+  // caller supplied for the return value to be constructed in.
+  string output;
+  if (!AppendToString(&output))
+    output.clear();
+  return output;
+}
+
+string MessageLite::SerializePartialAsString() const {
+  string output;
+  if (!AppendPartialToString(&output))
+    output.clear();
+  return output;
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/message_lite.h b/protobuf/src/google/protobuf/message_lite.h
new file mode 100644
index 0000000..027cabf
--- /dev/null
+++ b/protobuf/src/google/protobuf/message_lite.h
@@ -0,0 +1,247 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Authors: wink@google.com (Wink Saville),
+//          kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Defines MessageLite, the abstract interface implemented by all (lite
+// and non-lite) protocol message objects.
+
+#ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__
+#define GOOGLE_PROTOBUF_MESSAGE_LITE_H__
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+namespace io {
+  class CodedInputStream;
+  class CodedOutputStream;
+  class ZeroCopyInputStream;
+  class ZeroCopyOutputStream;
+}
+
+// Interface to light weight protocol messages.
+//
+// This interface is implemented by all protocol message objects.  Non-lite
+// messages additionally implement the Message interface, which is a
+// subclass of MessageLite.  Use MessageLite instead when you only need
+// the subset of features which it supports -- namely, nothing that uses
+// descriptors or reflection.  You can instruct the protocol compiler
+// to generate classes which implement only MessageLite, not the full
+// Message interface, by adding the following line to the .proto file:
+//
+//   option optimize_for = LITE_RUNTIME;
+//
+// This is particularly useful on resource-constrained systems where
+// the full protocol buffers runtime library is too big.
+//
+// Note that on non-constrained systems (e.g. servers) when you need
+// to link in lots of protocol definitions, a better way to reduce
+// total code footprint is to use optimize_for = CODE_SIZE.  This
+// will make the generated code smaller while still supporting all the
+// same features (at the expense of speed).  optimize_for = LITE_RUNTIME
+// is best when you only have a small number of message types linked
+// into your binary, in which case the size of the protocol buffers
+// runtime itself is the biggest problem.
+class LIBPROTOBUF_EXPORT MessageLite {
+ public:
+  inline MessageLite() {}
+  virtual ~MessageLite();
+
+  // Basic Operations ------------------------------------------------
+
+  // Get the name of this message type, e.g. "foo.bar.BazProto".
+  virtual string GetTypeName() const = 0;
+
+  // Construct a new instance of the same type.  Ownership is passed to the
+  // caller.
+  virtual MessageLite* New() const = 0;
+
+  // 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() = 0;
+
+  // Quickly check if all required fields have values set.
+  virtual bool IsInitialized() const = 0;
+
+  // This is not implemented for Lite messages -- it just returns "(cannot
+  // determine missing fields for lite message)".  However, it is implemented
+  // for full messages.  See message.h.
+  virtual string InitializationErrorString() const;
+
+  // If |other| is the exact same class as this, calls MergeFrom().  Otherwise,
+  // results are undefined (probably crash).
+  virtual void CheckTypeAndMergeFrom(const MessageLite& other) = 0;
+
+  // Parsing ---------------------------------------------------------
+  // Methods for parsing in protocol buffer format.  Most of these are
+  // just simple wrappers around MergeFromCodedStream().  Clear() will be called
+  // before merging the input.
+
+  // 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);
+  // Read a protocol buffer from the given zero-copy input stream, expecting
+  // the message to be exactly "size" bytes long.  If successful, exactly
+  // this many bytes will have been consumed from the input.
+  bool ParseFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size);
+  // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are
+  // missing required fields.
+  bool ParsePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input,
+                                             int size);
+  // 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);
+
+
+  // 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) = 0;
+
+
+  // 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;
+
+  // Make a string encoding the message. Is equivalent to calling
+  // SerializeToString() on a string and using that.  Returns the empty
+  // string if SerializeToString() would have returned an error.
+  // Note: If you intend to generate many such strings, you may
+  // reduce heap fragmentation by instead re-using the same string
+  // object with calls to SerializeToString().
+  string SerializeAsString() const;
+  // Like SerializeAsString(), but allows missing required fields.
+  string SerializePartialAsString() 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 = 0;
+
+  // 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 void SerializeWithCachedSizes(
+      io::CodedOutputStream* output) const = 0;
+
+  // Like SerializeWithCachedSizes, but writes directly to *target, returning
+  // a pointer to the byte immediately after the last byte written.  "target"
+  // must point at a byte array of at least ByteSize() bytes.
+  virtual uint8* SerializeWithCachedSizesToArray(uint8* target) 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:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageLite);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_MESSAGE_LITE_H__
diff --git a/protobuf/src/google/protobuf/message_unittest.cc b/protobuf/src/google/protobuf/message_unittest.cc
new file mode 100644
index 0000000..a5f339f
--- /dev/null
+++ b/protobuf/src/google/protobuf/message_unittest.cc
@@ -0,0 +1,427 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <fstream>
+
+#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/stubs/common.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");
+
+  EXPECT_TRUE(message.SerializeToString(&str1));
+  EXPECT_TRUE(message.AppendToString(&str2));
+  EXPECT_TRUE(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);
+
+  EXPECT_TRUE(message.SerializeAsString() == str1);
+
+}
+
+TEST(MessageTest, SerializeToBrokenOstream) {
+  ofstream out;
+  protobuf_unittest::TestAllTypes message;
+  message.set_optional_int32(123);
+
+  EXPECT_FALSE(message.SerializeToOstream(&out));
+}
+
+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, ParsePackedFromFileDescriptor) {
+  string filename =
+      TestSourceDir() +
+      "/google/protobuf/testdata/golden_packed_fields_message";
+  int file = open(filename.c_str(), O_RDONLY | O_BINARY);
+
+  unittest::TestPackedTypes message;
+  EXPECT_TRUE(message.ParseFromFileDescriptor(file));
+  TestUtil::ExpectPackedFieldsSet(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 ParseFromBoundedZeroCopyStream.
+    string data_with_junk(data);
+    data_with_junk.append("some junk on the end");
+    io::ArrayInputStream stream(data_with_junk.data(), data_with_junk.size());
+    protobuf_unittest::TestAllTypes message;
+    EXPECT_TRUE(message.ParseFromBoundedZeroCopyStream(&stream, data.size()));
+    TestUtil::ExpectAllFieldsSet(message);
+  }
+
+  {
+    // Test that ParseFromBoundedZeroCopyStream fails (but doesn't crash) if
+    // EOF is reached before the expected number of bytes.
+    io::ArrayInputStream stream(data.data(), data.size());
+    protobuf_unittest::TestAllTypes message;
+    EXPECT_FALSE(
+      message.ParseFromBoundedZeroCopyStream(&stream, data.size() + 1));
+  }
+}
+
+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 PROTOBUF_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");
+}
+
+TEST(MessageTest, CheckOverflow) {
+  unittest::TestAllTypes message;
+  // Create a message with size just over 2GB. This triggers integer overflow
+  // when computing message size.
+  const string data(1024, 'x');
+  Cord one_megabyte;
+  for (int i = 0; i < 1024; i++) {
+    one_megabyte.Append(data);
+  }
+
+  for (int i = 0; i < 2 * 1024 + 1; ++i) {
+    message.add_repeated_cord()->CopyFrom(one_megabyte);
+  }
+
+  Cord serialized;
+  EXPECT_FALSE(message.AppendToCord(&serialized));
+}
+
+#endif  // PROTOBUF_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));
+}
+
+namespace {
+
+void ExpectMessageMerged(const unittest::TestAllTypes& message) {
+  EXPECT_EQ(3, message.optional_int32());
+  EXPECT_EQ(2, message.optional_int64());
+  EXPECT_EQ("hello", message.optional_string());
+}
+
+void AssignParsingMergeMessages(
+    unittest::TestAllTypes* msg1,
+    unittest::TestAllTypes* msg2,
+    unittest::TestAllTypes* msg3) {
+  msg1->set_optional_int32(1);
+  msg2->set_optional_int64(2);
+  msg3->set_optional_int32(3);
+  msg3->set_optional_string("hello");
+}
+
+}  // namespace
+
+// Test that if an optional or required message/group field appears multiple
+// times in the input, they need to be merged.
+TEST(MessageTest, ParsingMerge) {
+  unittest::TestParsingMerge::RepeatedFieldsGenerator generator;
+  unittest::TestAllTypes* msg1;
+  unittest::TestAllTypes* msg2;
+  unittest::TestAllTypes* msg3;
+
+#define ASSIGN_REPEATED_FIELD(FIELD)                \
+  msg1 = generator.add_##FIELD();                   \
+  msg2 = generator.add_##FIELD();                   \
+  msg3 = generator.add_##FIELD();                   \
+  AssignParsingMergeMessages(msg1, msg2, msg3)
+
+  ASSIGN_REPEATED_FIELD(field1);
+  ASSIGN_REPEATED_FIELD(field2);
+  ASSIGN_REPEATED_FIELD(field3);
+  ASSIGN_REPEATED_FIELD(ext1);
+  ASSIGN_REPEATED_FIELD(ext2);
+
+#undef ASSIGN_REPEATED_FIELD
+#define ASSIGN_REPEATED_GROUP(FIELD)                \
+  msg1 = generator.add_##FIELD()->mutable_field1(); \
+  msg2 = generator.add_##FIELD()->mutable_field1(); \
+  msg3 = generator.add_##FIELD()->mutable_field1(); \
+  AssignParsingMergeMessages(msg1, msg2, msg3)
+
+  ASSIGN_REPEATED_GROUP(group1);
+  ASSIGN_REPEATED_GROUP(group2);
+
+#undef ASSIGN_REPEATED_GROUP
+
+  string buffer;
+  generator.SerializeToString(&buffer);
+  unittest::TestParsingMerge parsing_merge;
+  parsing_merge.ParseFromString(buffer);
+
+  // Required and optional fields should be merged.
+  ExpectMessageMerged(parsing_merge.required_all_types());
+  ExpectMessageMerged(parsing_merge.optional_all_types());
+  ExpectMessageMerged(
+      parsing_merge.optionalgroup().optional_group_all_types());
+  ExpectMessageMerged(
+      parsing_merge.GetExtension(unittest::TestParsingMerge::optional_ext));
+
+  // Repeated fields should not be merged.
+  EXPECT_EQ(3, parsing_merge.repeated_all_types_size());
+  EXPECT_EQ(3, parsing_merge.repeatedgroup_size());
+  EXPECT_EQ(3, parsing_merge.ExtensionSize(
+      unittest::TestParsingMerge::repeated_ext));
+}
+
+TEST(MessageTest, MergeFrom) {
+  unittest::TestAllTypes source;
+  unittest::TestAllTypes dest;
+
+  // Optional fields
+  source.set_optional_int32(1);  // only source
+  source.set_optional_int64(2);  // both source and dest
+  dest.set_optional_int64(3);
+  dest.set_optional_uint32(4);   // only dest
+
+  // Optional fields with defaults
+  source.set_default_int32(13);  // only source
+  source.set_default_int64(14);  // both source and dest
+  dest.set_default_int64(15);
+  dest.set_default_uint32(16);   // only dest
+
+  // Repeated fields
+  source.add_repeated_int32(5);  // only source
+  source.add_repeated_int32(6);
+  source.add_repeated_int64(7);  // both source and dest
+  source.add_repeated_int64(8);
+  dest.add_repeated_int64(9);
+  dest.add_repeated_int64(10);
+  dest.add_repeated_uint32(11);  // only dest
+  dest.add_repeated_uint32(12);
+
+  dest.MergeFrom(source);
+
+  // Optional fields: source overwrites dest if source is specified
+  EXPECT_EQ(1, dest.optional_int32());  // only source: use source
+  EXPECT_EQ(2, dest.optional_int64());  // source and dest: use source
+  EXPECT_EQ(4, dest.optional_uint32());  // only dest: use dest
+  EXPECT_EQ(0, dest.optional_uint64());  // neither: use default
+
+  // Optional fields with defaults
+  EXPECT_EQ(13, dest.default_int32());  // only source: use source
+  EXPECT_EQ(14, dest.default_int64());  // source and dest: use source
+  EXPECT_EQ(16, dest.default_uint32());  // only dest: use dest
+  EXPECT_EQ(44, dest.default_uint64());  // neither: use default
+
+  // Repeated fields: concatenate source onto the end of dest
+  ASSERT_EQ(2, dest.repeated_int32_size());
+  EXPECT_EQ(5, dest.repeated_int32(0));
+  EXPECT_EQ(6, dest.repeated_int32(1));
+  ASSERT_EQ(4, dest.repeated_int64_size());
+  EXPECT_EQ(9,  dest.repeated_int64(0));
+  EXPECT_EQ(10, dest.repeated_int64(1));
+  EXPECT_EQ(7,  dest.repeated_int64(2));
+  EXPECT_EQ(8,  dest.repeated_int64(3));
+  ASSERT_EQ(2, dest.repeated_uint32_size());
+  EXPECT_EQ(11, dest.repeated_uint32(0));
+  EXPECT_EQ(12, dest.repeated_uint32(1));
+  ASSERT_EQ(0, dest.repeated_uint64_size());
+}
+
+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/protobuf/src/google/protobuf/package_info.h b/protobuf/src/google/protobuf/package_info.h
new file mode 100644
index 0000000..935e963
--- /dev/null
+++ b/protobuf/src/google/protobuf/package_info.h
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/protobuf/src/google/protobuf/reflection_ops.cc b/protobuf/src/google/protobuf/reflection_ops.cc
new file mode 100644
index 0000000..4629dec
--- /dev/null
+++ b/protobuf/src/google/protobuf/reflection_ops.cc
@@ -0,0 +1,269 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <string>
+#include <vector>
+
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+void ReflectionOps::Copy(const Message& from, Message* to) {
+  if (&from == to) return;
+  Clear(to);
+  Merge(from, to);
+}
+
+void ReflectionOps::Merge(const Message& from, Message* to) {
+  GOOGLE_CHECK_NE(&from, to);
+
+  const Descriptor* descriptor = from.GetDescriptor();
+  GOOGLE_CHECK_EQ(to->GetDescriptor(), descriptor)
+    << "Tried to merge messages of different types "
+    << "(merge " << descriptor->full_name()
+    << " to " << to->GetDescriptor()->full_name() << ")";
+
+  const Reflection* from_reflection = from.GetReflection();
+  const Reflection* to_reflection = to->GetReflection();
+
+  vector<const FieldDescriptor*> fields;
+  from_reflection->ListFields(from, &fields);
+  for (int i = 0; i < fields.size(); i++) {
+    const FieldDescriptor* field = fields[i];
+
+    if (field->is_repeated()) {
+      int count = from_reflection->FieldSize(from, field);
+      for (int j = 0; j < count; j++) {
+        switch (field->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, METHOD)                                     \
+          case FieldDescriptor::CPPTYPE_##CPPTYPE:                       \
+            to_reflection->Add##METHOD(to, field,                        \
+              from_reflection->GetRepeated##METHOD(from, 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_reflection->AddMessage(to, field)->MergeFrom(
+              from_reflection->GetRepeatedMessage(from, field, j));
+            break;
+        }
+      }
+    } else {
+      switch (field->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, METHOD)                                        \
+        case FieldDescriptor::CPPTYPE_##CPPTYPE:                            \
+          to_reflection->Set##METHOD(to, field,                             \
+            from_reflection->Get##METHOD(from, 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_reflection->MutableMessage(to, field)->MergeFrom(
+            from_reflection->GetMessage(from, field));
+          break;
+      }
+    }
+  }
+
+  to_reflection->MutableUnknownFields(to)->MergeFrom(
+    from_reflection->GetUnknownFields(from));
+}
+
+void ReflectionOps::Clear(Message* message) {
+  const Reflection* reflection = message->GetReflection();
+
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(*message, &fields);
+  for (int i = 0; i < fields.size(); i++) {
+    reflection->ClearField(message, fields[i]);
+  }
+
+  reflection->MutableUnknownFields(message)->Clear();
+}
+
+bool ReflectionOps::IsInitialized(const Message& message) {
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* reflection = message.GetReflection();
+
+  // Check required fields of this message.
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    if (descriptor->field(i)->is_required()) {
+      if (!reflection->HasField(message, descriptor->field(i))) {
+        return false;
+      }
+    }
+  }
+
+  // Check that sub-messages are initialized.
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(message, &fields);
+  for (int i = 0; i < fields.size(); i++) {
+    const FieldDescriptor* field = fields[i];
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+
+      if (field->is_repeated()) {
+        int size = reflection->FieldSize(message, field);
+
+        for (int j = 0; j < size; j++) {
+          if (!reflection->GetRepeatedMessage(message, field, j)
+                          .IsInitialized()) {
+            return false;
+          }
+        }
+      } else {
+        if (!reflection->GetMessage(message, field).IsInitialized()) {
+          return false;
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
+void ReflectionOps::DiscardUnknownFields(Message* message) {
+  const Reflection* reflection = message->GetReflection();
+
+  reflection->MutableUnknownFields(message)->Clear();
+
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(*message, &fields);
+  for (int i = 0; i < fields.size(); i++) {
+    const FieldDescriptor* field = fields[i];
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (field->is_repeated()) {
+        int size = reflection->FieldSize(*message, field);
+        for (int j = 0; j < size; j++) {
+          reflection->MutableRepeatedMessage(message, field, j)
+                    ->DiscardUnknownFields();
+        }
+      } else {
+        reflection->MutableMessage(message, 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 Message& message,
+    const string& prefix,
+    vector<string>* errors) {
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* reflection = message.GetReflection();
+
+  // Check required fields of this message.
+  for (int i = 0; i < descriptor->field_count(); i++) {
+    if (descriptor->field(i)->is_required()) {
+      if (!reflection->HasField(message, descriptor->field(i))) {
+        errors->push_back(prefix + descriptor->field(i)->name());
+      }
+    }
+  }
+
+  // Check sub-messages.
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(message, &fields);
+  for (int i = 0; i < fields.size(); i++) {
+    const FieldDescriptor* field = fields[i];
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+
+      if (field->is_repeated()) {
+        int size = reflection->FieldSize(message, field);
+
+        for (int j = 0; j < size; j++) {
+          const Message& sub_message =
+            reflection->GetRepeatedMessage(message, field, j);
+          FindInitializationErrors(sub_message,
+                                   SubMessagePrefix(prefix, field, j),
+                                   errors);
+        }
+      } else {
+        const Message& sub_message = reflection->GetMessage(message, field);
+        FindInitializationErrors(sub_message,
+                                 SubMessagePrefix(prefix, field, -1),
+                                 errors);
+      }
+    }
+  }
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/reflection_ops.h b/protobuf/src/google/protobuf/reflection_ops.h
new file mode 100644
index 0000000..4775911
--- /dev/null
+++ b/protobuf/src/google/protobuf/reflection_ops.h
@@ -0,0 +1,81 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/stubs/common.h>
+#include <google/protobuf/message.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Basic operations that can be performed using reflection.
+// These can be used as a cheap way to implement the corresponding
+// methods of the Message interface, though they are likely to be
+// slower than implementations tailored for the specific message type.
+//
+// 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 Message& from, Message* to);
+  static void Merge(const Message& from, Message* to);
+  static void Clear(Message* message);
+  static bool IsInitialized(const Message& message);
+  static void DiscardUnknownFields(Message* message);
+
+  // Finds all unset required fields in the message and adds their full
+  // paths (e.g. "foo.bar[5].baz") to *names.  "prefix" will be attached to
+  // the front of each name.
+  static void FindInitializationErrors(const Message& message,
+                                       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/protobuf/src/google/protobuf/reflection_ops_unittest.cc b/protobuf/src/google/protobuf/reflection_ops_unittest.cc
new file mode 100644
index 0000000..32740ea
--- /dev/null
+++ b/protobuf/src/google/protobuf/reflection_ops_unittest.cc
@@ -0,0 +1,475 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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, &message2);
+
+  TestUtil::ExpectAllFieldsSet(message2);
+
+  // Copying from self should be a no-op.
+  ReflectionOps::Copy(message2, &message2);
+  TestUtil::ExpectAllFieldsSet(message2);
+}
+
+TEST(ReflectionOpsTest, CopyExtensions) {
+  unittest::TestAllExtensions message, message2;
+
+  TestUtil::SetAllExtensions(&message);
+
+  ReflectionOps::Copy(message, &message2);
+
+  TestUtil::ExpectAllExtensionsSet(message2);
+}
+
+TEST(ReflectionOpsTest, CopyOneof) {
+  unittest::TestOneof2 message, message2;
+  TestUtil::SetOneof1(&message);
+  ReflectionOps::Copy(message, &message2);
+  TestUtil::ExpectOneofSet1(message2);
+
+  TestUtil::SetOneof2(&message);
+  TestUtil::ExpectOneofSet2(message);
+  ReflectionOps::Copy(message, &message2);
+  TestUtil::ExpectOneofSet2(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, &message);
+
+  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, &message);
+
+  TestUtil::ExpectAllExtensionsSet(message);
+}
+
+TEST(ReflectionOpsTest, MergeUnknown) {
+  // Test that the messages' UnknownFieldSets are correctly merged.
+  unittest::TestEmptyMessage message1, message2;
+  message1.mutable_unknown_fields()->AddVarint(1234, 1);
+  message2.mutable_unknown_fields()->AddVarint(1234, 2);
+
+  ReflectionOps::Merge(message2, &message1);
+
+  ASSERT_EQ(2, message1.unknown_fields().field_count());
+  ASSERT_EQ(UnknownField::TYPE_VARINT,
+            message1.unknown_fields().field(0).type());
+  EXPECT_EQ(1, message1.unknown_fields().field(0).varint());
+  ASSERT_EQ(UnknownField::TYPE_VARINT,
+            message1.unknown_fields().field(1).type());
+  EXPECT_EQ(2, message1.unknown_fields().field(1).varint());
+}
+
+TEST(ReflectionOpsTest, MergeOneof) {
+  unittest::TestOneof2 message1, message2;
+  TestUtil::SetOneof1(&message1);
+
+  // Merge to empty message
+  ReflectionOps::Merge(message1, &message2);
+  TestUtil::ExpectOneofSet1(message2);
+
+  // Merge with the same oneof fields
+  ReflectionOps::Merge(message1, &message2);
+  TestUtil::ExpectOneofSet1(message2);
+
+  // Merge with different oneof fields
+  TestUtil::SetOneof2(&message1);
+  ReflectionOps::Merge(message1, &message2);
+  TestUtil::ExpectOneofSet2(message2);
+}
+
+#ifdef PROTOBUF_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, &message),
+    "&from");
+}
+
+#endif  // PROTOBUF_HAS_DEATH_TEST
+
+TEST(ReflectionOpsTest, Clear) {
+  unittest::TestAllTypes message;
+
+  TestUtil::SetAllFields(&message);
+
+  ReflectionOps::Clear(&message);
+
+  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);
+
+  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()->AddVarint(1234, 1);
+
+  ReflectionOps::Clear(&message);
+
+  EXPECT_EQ(0, message.unknown_fields().field_count());
+}
+
+TEST(ReflectionOpsTest, ClearOneof) {
+  unittest::TestOneof2 message;
+
+  TestUtil::ExpectOneofClear(message);
+  TestUtil::SetOneof1(&message);
+  TestUtil::ExpectOneofSet1(message);
+  ReflectionOps::Clear(&message);
+  TestUtil::ExpectOneofClear(message);
+
+  TestUtil::SetOneof1(&message);
+  TestUtil::ExpectOneofSet1(message);
+  TestUtil::SetOneof2(&message);
+  TestUtil::ExpectOneofSet2(message);
+  ReflectionOps::Clear(&message);
+  TestUtil::ExpectOneofClear(message);
+}
+
+TEST(ReflectionOpsTest, DiscardUnknownFields) {
+  unittest::TestAllTypes message;
+  TestUtil::SetAllFields(&message);
+
+  // Set some unknown fields in message.
+  message.mutable_unknown_fields()
+        ->AddVarint(123456, 654321);
+  message.mutable_optional_nested_message()
+        ->mutable_unknown_fields()
+        ->AddVarint(123456, 654321);
+  message.mutable_repeated_nested_message(0)
+        ->mutable_unknown_fields()
+        ->AddVarint(123456, 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);
+  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()
+        ->AddVarint(123456, 654321);
+  message.MutableExtension(unittest::optional_nested_message_extension)
+        ->mutable_unknown_fields()
+        ->AddVarint(123456, 654321);
+  message.MutableExtension(unittest::repeated_nested_message_extension, 0)
+        ->mutable_unknown_fields()
+        ->AddVarint(123456, 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);
+  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));
+  message.set_a(1);
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+  message.set_b(2);
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+  message.set_c(3);
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+}
+
+TEST(ReflectionOpsTest, ForeignIsInitialized) {
+  unittest::TestRequiredForeign message;
+
+  // Starts out initialized because the foreign message is itself an optional
+  // field.
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+
+  // Once we create that field, the message is no longer initialized.
+  message.mutable_optional_message();
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+
+  // 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));
+
+  // Add a repeated version of the message.  No longer initialized.
+  unittest::TestRequired* sub_message = message.add_repeated_message();
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+
+  // Initialize that repeated version.
+  sub_message->set_a(1);
+  sub_message->set_b(2);
+  sub_message->set_c(3);
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+}
+
+TEST(ReflectionOpsTest, ExtensionIsInitialized) {
+  unittest::TestAllExtensions message;
+
+  // Starts out initialized because the foreign message is itself an optional
+  // field.
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+
+  // Once we create that field, the message is no longer initialized.
+  message.MutableExtension(unittest::TestRequired::single);
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+
+  // 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));
+
+  // Add a repeated version of the message.  No longer initialized.
+  message.AddExtension(unittest::TestRequired::multi);
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+
+  // Initialize that repeated version.
+  message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
+  message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
+  message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+}
+
+TEST(ReflectionOpsTest, OneofIsInitialized) {
+  unittest::TestRequiredOneof message;
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+
+  message.mutable_foo_message();
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+
+  message.set_foo_int(1);
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+
+  message.mutable_foo_message();
+  EXPECT_FALSE(ReflectionOps::IsInitialized(message));
+  message.mutable_foo_message()->set_required_double(0.1);
+  EXPECT_TRUE(ReflectionOps::IsInitialized(message));
+}
+
+static string FindInitializationErrors(const Message& message) {
+  vector<string> errors;
+  ReflectionOps::FindInitializationErrors(message, "", &errors);
+  return Join(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));
+}
+
+TEST(ReflectionOpsTest, FindOneofInitializationErrors) {
+  unittest::TestRequiredOneof message;
+  message.mutable_foo_message();
+  EXPECT_EQ("foo_message.required_double",
+            FindInitializationErrors(message));
+}
+
+}  // namespace
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/repeated_field.cc b/protobuf/src/google/protobuf/repeated_field.cc
new file mode 100644
index 0000000..b400732
--- /dev/null
+++ b/protobuf/src/google/protobuf/repeated_field.cc
@@ -0,0 +1,87 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <algorithm>
+
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+namespace internal {
+
+void RepeatedPtrFieldBase::Reserve(int new_size) {
+  if (total_size_ >= new_size) return;
+
+  void** old_elements = elements_;
+  total_size_ = max(kMinRepeatedFieldAllocationSize,
+                    max(total_size_ * 2, new_size));
+  elements_ = new void*[total_size_];
+  if (old_elements != NULL) {
+    memcpy(elements_, old_elements, allocated_size_ * sizeof(elements_[0]));
+    delete [] old_elements;
+  }
+}
+
+void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
+  if (this == other) return;
+  void** swap_elements       = elements_;
+  int    swap_current_size   = current_size_;
+  int    swap_allocated_size = allocated_size_;
+  int    swap_total_size     = total_size_;
+
+  elements_       = other->elements_;
+  current_size_   = other->current_size_;
+  allocated_size_ = other->allocated_size_;
+  total_size_     = other->total_size_;
+
+  other->elements_       = swap_elements;
+  other->current_size_   = swap_current_size;
+  other->allocated_size_ = swap_allocated_size;
+  other->total_size_     = swap_total_size;
+}
+
+string* StringTypeHandlerBase::New() {
+  return new string;
+}
+void StringTypeHandlerBase::Delete(string* value) {
+  delete value;
+}
+
+}  // namespace internal
+
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/repeated_field.h b/protobuf/src/google/protobuf/repeated_field.h
new file mode 100644
index 0000000..816ea68
--- /dev/null
+++ b/protobuf/src/google/protobuf/repeated_field.h
@@ -0,0 +1,1604 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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__
+
+#ifdef _MSC_VER
+// This is required for min/max on VS2013 only.
+#include <algorithm>
+#endif
+
+#include <string>
+#include <iterator>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/type_traits.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/message_lite.h>
+
+namespace google {
+
+namespace upb {
+namespace google_opensource {
+class GMR_Handlers;
+}  // namespace google_opensource
+}  // namespace upb
+
+namespace protobuf {
+
+class Message;
+
+namespace internal {
+
+static const int kMinRepeatedFieldAllocationSize = 4;
+
+// A utility function for logging that doesn't need any template types.
+void LogIndexOutOfBounds(int index, int size);
+
+template <typename Iter>
+inline int CalculateReserve(Iter begin, Iter end, std::forward_iterator_tag) {
+  return std::distance(begin, end);
+}
+
+template <typename Iter>
+inline int CalculateReserve(Iter /*begin*/, Iter /*end*/,
+                            std::input_iterator_tag) {
+  return -1;
+}
+
+template <typename Iter>
+inline int CalculateReserve(Iter begin, Iter end) {
+  typedef typename std::iterator_traits<Iter>::iterator_category Category;
+  return CalculateReserve(begin, end, Category());
+}
+}  // 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:
+  RepeatedField();
+  RepeatedField(const RepeatedField& other);
+  template <typename Iter>
+  RepeatedField(Iter begin, const Iter& end);
+  ~RepeatedField();
+
+  RepeatedField& operator=(const RepeatedField& other);
+
+  bool empty() const;
+  int size() const;
+
+  const Element& Get(int index) const;
+  Element* Mutable(int index);
+  void Set(int index, const Element& value);
+  void Add(const Element& value);
+  Element* Add();
+  // Remove the last element in the array.
+  void RemoveLast();
+
+  // Extract elements with indices in "[start .. start+num-1]".
+  // Copy them into "elements[0 .. num-1]" if "elements" is not NULL.
+  // Caution: implementation also moves elements with indices [start+num ..].
+  // Calling this routine inside a loop can cause quadratic behavior.
+  void ExtractSubrange(int start, int num, Element* elements);
+
+  void Clear();
+  void MergeFrom(const RepeatedField& other);
+  void CopyFrom(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);
+
+  // Resize the RepeatedField to a new, smaller size.  This is O(1).
+  void Truncate(int new_size);
+
+  void AddAlreadyReserved(const Element& value);
+  Element* AddAlreadyReserved();
+  int Capacity() const;
+
+  // Like STL resize.  Uses value to fill appended elements.
+  // Like Truncate() if new_size <= size(), otherwise this is
+  // O(new_size - size()).
+  void Resize(int new_size, const Element& value);
+
+  // 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);
+
+  // Swap two elements.
+  void SwapElements(int index1, int index2);
+
+  // STL-like iterator support
+  typedef Element* iterator;
+  typedef const Element* const_iterator;
+  typedef Element value_type;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef value_type* pointer;
+  typedef const value_type* const_pointer;
+  typedef int size_type;
+  typedef ptrdiff_t difference_type;
+
+  iterator begin();
+  const_iterator begin() const;
+  iterator end();
+  const_iterator end() const;
+
+  // Reverse iterator support
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef std::reverse_iterator<iterator> reverse_iterator;
+  reverse_iterator rbegin() {
+    return reverse_iterator(end());
+  }
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+  reverse_iterator rend() {
+    return reverse_iterator(begin());
+  }
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator(begin());
+  }
+
+  // Returns the number of bytes used by the repeated field, excluding
+  // sizeof(*this)
+  int SpaceUsedExcludingSelf() const;
+
+ private:
+  static const int kInitialSize = 0;
+
+  Element* elements_;
+  int      current_size_;
+  int      total_size_;
+
+  // Move the contents of |from| into |to|, possibly clobbering |from| in the
+  // process.  For primitive types this is just a memcpy(), but it could be
+  // specialized for non-primitive types to, say, swap each element instead.
+  void MoveArray(Element to[], Element from[], int size);
+
+  // Copy the elements of |from| into |to|.
+  void CopyArray(Element to[], const Element from[], int size);
+};
+
+namespace internal {
+template <typename It> class RepeatedPtrIterator;
+template <typename It, typename VoidPtr> class RepeatedPtrOverPtrsIterator;
+}  // namespace internal
+
+namespace internal {
+
+// This is a helper template to copy an array of elements effeciently when they
+// have a trivial copy constructor, and correctly otherwise. This really
+// shouldn't be necessary, but our compiler doesn't optimize std::copy very
+// effectively.
+template <typename Element,
+          bool HasTrivialCopy = has_trivial_copy<Element>::value>
+struct ElementCopier {
+  void operator()(Element to[], const Element from[], int array_size);
+};
+
+}  // namespace internal
+
+namespace internal {
+
+// This is the common base class for RepeatedPtrFields.  It deals only in void*
+// pointers.  Users should not use this interface directly.
+//
+// The methods of this interface correspond to the methods of RepeatedPtrField,
+// but may have a template argument called TypeHandler.  Its signature is:
+//   class TypeHandler {
+//    public:
+//     typedef MyType Type;
+//     static Type* New();
+//     static void Delete(Type*);
+//     static void Clear(Type*);
+//     static void Merge(const Type& from, Type* to);
+//
+//     // Only needs to be implemented if SpaceUsedExcludingSelf() is called.
+//     static int SpaceUsed(const Type&);
+//   };
+class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
+ protected:
+  // The reflection implementation needs to call protected methods directly,
+  // reinterpreting pointers as being to Message instead of a specific Message
+  // subclass.
+  friend class GeneratedMessageReflection;
+
+  // ExtensionSet stores repeated message extensions as
+  // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to
+  // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf()
+  // reinterpreting MessageLite as Message.  ExtensionSet also needs to make
+  // use of AddFromCleared(), which is not part of the public interface.
+  friend class ExtensionSet;
+
+  // To parse directly into a proto2 generated class, the upb class GMR_Handlers
+  // needs to be able to modify a RepeatedPtrFieldBase directly.
+  friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
+
+  RepeatedPtrFieldBase();
+
+  // Must be called from destructor.
+  template <typename TypeHandler>
+  void Destroy();
+
+  bool empty() const;
+  int size() const;
+
+  template <typename TypeHandler>
+  const typename TypeHandler::Type& Get(int index) const;
+  template <typename TypeHandler>
+  typename TypeHandler::Type* Mutable(int index);
+  template <typename TypeHandler>
+  typename TypeHandler::Type* Add();
+  template <typename TypeHandler>
+  void RemoveLast();
+  template <typename TypeHandler>
+  void Clear();
+  template <typename TypeHandler>
+  void MergeFrom(const RepeatedPtrFieldBase& other);
+  template <typename TypeHandler>
+  void CopyFrom(const RepeatedPtrFieldBase& other);
+
+  void CloseGap(int start, int num) {
+    // Close up a gap of "num" elements starting at offset "start".
+    for (int i = start + num; i < allocated_size_; ++i)
+      elements_[i - num] = elements_[i];
+    current_size_ -= num;
+    allocated_size_ -= num;
+  }
+
+  void Reserve(int new_size);
+
+  int Capacity() const;
+
+  // Used for constructing iterators.
+  void* const* raw_data() const;
+  void** raw_mutable_data() const;
+
+  template <typename TypeHandler>
+  typename TypeHandler::Type** mutable_data();
+  template <typename TypeHandler>
+  const typename TypeHandler::Type* const* data() const;
+
+  void Swap(RepeatedPtrFieldBase* other);
+
+  void SwapElements(int index1, int index2);
+
+  template <typename TypeHandler>
+  int SpaceUsedExcludingSelf() const;
+
+
+  // Advanced memory management --------------------------------------
+
+  // Like Add(), but if there are no cleared objects to use, returns NULL.
+  template <typename TypeHandler>
+  typename TypeHandler::Type* AddFromCleared();
+
+  template <typename TypeHandler>
+  void AddAllocated(typename TypeHandler::Type* value);
+  template <typename TypeHandler>
+  typename TypeHandler::Type* ReleaseLast();
+
+  int ClearedCount() const;
+  template <typename TypeHandler>
+  void AddCleared(typename TypeHandler::Type* value);
+  template <typename TypeHandler>
+  typename TypeHandler::Type* ReleaseCleared();
+
+ private:
+  static const int kInitialSize = 0;
+
+  void** elements_;
+  int    current_size_;
+  int    allocated_size_;
+  int    total_size_;
+
+  template <typename TypeHandler>
+  static inline typename TypeHandler::Type* cast(void* element) {
+    return reinterpret_cast<typename TypeHandler::Type*>(element);
+  }
+  template <typename TypeHandler>
+  static inline const typename TypeHandler::Type* cast(const void* element) {
+    return reinterpret_cast<const typename TypeHandler::Type*>(element);
+  }
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPtrFieldBase);
+};
+
+template <typename GenericType>
+class GenericTypeHandler {
+ public:
+  typedef GenericType Type;
+  static GenericType* New() { return new GenericType; }
+  static void Delete(GenericType* value) { delete value; }
+  static void Clear(GenericType* value) { value->Clear(); }
+  static void Merge(const GenericType& from, GenericType* to) {
+    to->MergeFrom(from);
+  }
+  static int SpaceUsed(const GenericType& value) { return value.SpaceUsed(); }
+  static const Type& default_instance() { return Type::default_instance(); }
+};
+
+template <>
+inline void GenericTypeHandler<MessageLite>::Merge(
+    const MessageLite& from, MessageLite* to) {
+  to->CheckTypeAndMergeFrom(from);
+}
+
+template <>
+inline const MessageLite& GenericTypeHandler<MessageLite>::default_instance() {
+  // Yes, the behavior of the code is undefined, but this function is only
+  // called when we're already deep into the world of undefined, because the
+  // caller called Get(index) out of bounds.
+  MessageLite* null = NULL;
+  return *null;
+}
+
+template <>
+inline const Message& GenericTypeHandler<Message>::default_instance() {
+  // Yes, the behavior of the code is undefined, but this function is only
+  // called when we're already deep into the world of undefined, because the
+  // caller called Get(index) out of bounds.
+  Message* null = NULL;
+  return *null;
+}
+
+
+// HACK:  If a class is declared as DLL-exported in MSVC, it insists on
+//   generating copies of all its methods -- even inline ones -- to include
+//   in the DLL.  But SpaceUsed() calls StringSpaceUsedExcludingSelf() which
+//   isn't in the lite library, therefore the lite library cannot link if
+//   StringTypeHandler is exported.  So, we factor out StringTypeHandlerBase,
+//   export that, then make StringTypeHandler be a subclass which is NOT
+//   exported.
+// TODO(kenton):  There has to be a better way.
+class LIBPROTOBUF_EXPORT StringTypeHandlerBase {
+ public:
+  typedef string Type;
+  static string* New();
+  static void Delete(string* value);
+  static void Clear(string* value) { value->clear(); }
+  static void Merge(const string& from, string* to) { *to = from; }
+  static const Type& default_instance() {
+    return ::google::protobuf::internal::GetEmptyString();
+  }
+};
+
+class StringTypeHandler : public StringTypeHandlerBase {
+ public:
+  static int SpaceUsed(const string& value)  {
+    return sizeof(value) + StringSpaceUsedExcludingSelf(value);
+  }
+};
+
+
+}  // namespace internal
+
+// RepeatedPtrField is like RepeatedField, but used for repeated strings or
+// Messages.
+template <typename Element>
+class RepeatedPtrField : public internal::RepeatedPtrFieldBase {
+ public:
+  RepeatedPtrField();
+  RepeatedPtrField(const RepeatedPtrField& other);
+  template <typename Iter>
+  RepeatedPtrField(Iter begin, const Iter& end);
+  ~RepeatedPtrField();
+
+  RepeatedPtrField& operator=(const RepeatedPtrField& other);
+
+  bool empty() const;
+  int size() const;
+
+  const Element& Get(int index) const;
+  Element* Mutable(int index);
+  Element* Add();
+
+  // Remove the last element in the array.
+  // Ownership of the element is retained by the array.
+  void RemoveLast();
+
+  // Delete elements with indices in the range [start .. start+num-1].
+  // Caution: implementation moves all elements with indices [start+num .. ].
+  // Calling this routine inside a loop can cause quadratic behavior.
+  void DeleteSubrange(int start, int num);
+
+  void Clear();
+  void MergeFrom(const RepeatedPtrField& other);
+  void CopyFrom(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);
+
+  int Capacity() const;
+
+  // 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);
+
+  // Swap two elements.
+  void SwapElements(int index1, int index2);
+
+  // STL-like iterator support
+  typedef internal::RepeatedPtrIterator<Element> iterator;
+  typedef internal::RepeatedPtrIterator<const Element> const_iterator;
+  typedef Element value_type;
+  typedef value_type& reference;
+  typedef const value_type& const_reference;
+  typedef value_type* pointer;
+  typedef const value_type* const_pointer;
+  typedef int size_type;
+  typedef ptrdiff_t difference_type;
+
+  iterator begin();
+  const_iterator begin() const;
+  iterator end();
+  const_iterator end() const;
+
+  // Reverse iterator support
+  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+  typedef std::reverse_iterator<iterator> reverse_iterator;
+  reverse_iterator rbegin() {
+    return reverse_iterator(end());
+  }
+  const_reverse_iterator rbegin() const {
+    return const_reverse_iterator(end());
+  }
+  reverse_iterator rend() {
+    return reverse_iterator(begin());
+  }
+  const_reverse_iterator rend() const {
+    return const_reverse_iterator(begin());
+  }
+
+  // Custom STL-like iterator that iterates over and returns the underlying
+  // pointers to Element rather than Element itself.
+  typedef internal::RepeatedPtrOverPtrsIterator<Element, void*>
+  pointer_iterator;
+  typedef internal::RepeatedPtrOverPtrsIterator<const Element, const void*>
+  const_pointer_iterator;
+  pointer_iterator pointer_begin();
+  const_pointer_iterator pointer_begin() const;
+  pointer_iterator pointer_end();
+  const_pointer_iterator pointer_end() const;
+
+  // Returns (an estimate of) the number of bytes used by the repeated field,
+  // excluding sizeof(*this).
+  int SpaceUsedExcludingSelf() const;
+
+  // Advanced memory management --------------------------------------
+  // When hardcore memory management becomes necessary -- as it sometimes
+  // 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();
+
+  // Extract elements with indices in the range "[start .. start+num-1]".
+  // The caller assumes ownership of the extracted elements and is responsible
+  // for deleting them when they are no longer needed.
+  // If "elements" is non-NULL, then pointers to the extracted elements
+  // are stored in "elements[0 .. num-1]" for the convenience of the caller.
+  // If "elements" is NULL, then the caller must use some other mechanism
+  // to perform any further operations (like deletion) on these elements.
+  // Caution: implementation also moves elements with indices [start+num ..].
+  // Calling this routine inside a loop can cause quadratic behavior.
+  void ExtractSubrange(int start, int num, Element** elements);
+
+  // 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.
+  //
+  // Hardcore programs may choose to manipulate these cleared objects
+  // to better optimize memory management using the following routines.
+
+  // Get the number of cleared objects that are currently being kept
+  // around for reuse.
+  int ClearedCount() const;
+  // 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();
+
+ protected:
+  // Note:  RepeatedPtrField SHOULD NOT be subclassed by users.  We only
+  //   subclass it in one place as a hack for compatibility with proto1.  The
+  //   subclass needs to know about TypeHandler in order to call protected
+  //   methods on RepeatedPtrFieldBase.
+  class TypeHandler;
+
+};
+
+// implementation ====================================================
+
+template <typename Element>
+inline RepeatedField<Element>::RepeatedField()
+  : elements_(NULL),
+    current_size_(0),
+    total_size_(kInitialSize) {
+}
+
+template <typename Element>
+inline RepeatedField<Element>::RepeatedField(const RepeatedField& other)
+  : elements_(NULL),
+    current_size_(0),
+    total_size_(kInitialSize) {
+  CopyFrom(other);
+}
+
+template <typename Element>
+template <typename Iter>
+inline RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
+  : elements_(NULL),
+    current_size_(0),
+    total_size_(kInitialSize) {
+  int reserve = internal::CalculateReserve(begin, end);
+  if (reserve != -1) {
+    Reserve(reserve);
+    for (; begin != end; ++begin) {
+      AddAlreadyReserved(*begin);
+    }
+  } else {
+    for (; begin != end; ++begin) {
+      Add(*begin);
+    }
+  }
+}
+
+template <typename Element>
+RepeatedField<Element>::~RepeatedField() {
+  delete [] elements_;
+}
+
+template <typename Element>
+inline RepeatedField<Element>&
+RepeatedField<Element>::operator=(const RepeatedField& other) {
+  if (this != &other)
+    CopyFrom(other);
+  return *this;
+}
+
+template <typename Element>
+inline bool RepeatedField<Element>::empty() const {
+  return current_size_ == 0;
+}
+
+template <typename Element>
+inline int RepeatedField<Element>::size() const {
+  return current_size_;
+}
+
+template <typename Element>
+inline int RepeatedField<Element>::Capacity() const {
+  return total_size_;
+}
+
+template<typename Element>
+inline void RepeatedField<Element>::AddAlreadyReserved(const Element& value) {
+  GOOGLE_DCHECK_LT(size(), Capacity());
+  elements_[current_size_++] = value;
+}
+
+template<typename Element>
+inline Element* RepeatedField<Element>::AddAlreadyReserved() {
+  GOOGLE_DCHECK_LT(size(), Capacity());
+  return &elements_[current_size_++];
+}
+
+template<typename Element>
+inline void RepeatedField<Element>::Resize(int new_size, const Element& value) {
+  GOOGLE_DCHECK_GE(new_size, 0);
+  if (new_size > size()) {
+    Reserve(new_size);
+    std::fill(&elements_[current_size_], &elements_[new_size], value);
+  }
+  current_size_ = new_size;
+}
+
+template <typename Element>
+inline const Element& RepeatedField<Element>::Get(int index) const {
+  GOOGLE_DCHECK_GE(index, 0);
+  GOOGLE_DCHECK_LT(index, size());
+  return elements_[index];
+}
+
+template <typename Element>
+inline Element* RepeatedField<Element>::Mutable(int index) {
+  GOOGLE_DCHECK_GE(index, 0);
+  GOOGLE_DCHECK_LT(index, size());
+  return elements_ + index;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Set(int index, const Element& value) {
+  GOOGLE_DCHECK_GE(index, 0);
+  GOOGLE_DCHECK_LT(index, size());
+  elements_[index] = value;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Add(const Element& value) {
+  if (current_size_ == total_size_) Reserve(total_size_ + 1);
+  elements_[current_size_++] = value;
+}
+
+template <typename Element>
+inline Element* RepeatedField<Element>::Add() {
+  if (current_size_ == total_size_) Reserve(total_size_ + 1);
+  return &elements_[current_size_++];
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::RemoveLast() {
+  GOOGLE_DCHECK_GT(current_size_, 0);
+  --current_size_;
+}
+
+template <typename Element>
+void RepeatedField<Element>::ExtractSubrange(
+    int start, int num, Element* elements) {
+  GOOGLE_DCHECK_GE(start, 0);
+  GOOGLE_DCHECK_GE(num, 0);
+  GOOGLE_DCHECK_LE(start + num, this->size());
+
+  // Save the values of the removed elements if requested.
+  if (elements != NULL) {
+    for (int i = 0; i < num; ++i)
+      elements[i] = this->Get(i + start);
+  }
+
+  // Slide remaining elements down to fill the gap.
+  if (num > 0) {
+    for (int i = start + num; i < this->size(); ++i)
+      this->Set(i - num, this->Get(i));
+    this->Truncate(this->size() - num);
+  }
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Clear() {
+  current_size_ = 0;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::MergeFrom(const RepeatedField& other) {
+  GOOGLE_CHECK_NE(&other, this);
+  if (other.current_size_ != 0) {
+    Reserve(current_size_ + other.current_size_);
+    CopyArray(elements_ + current_size_, other.elements_, other.current_size_);
+    current_size_ += other.current_size_;
+  }
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::CopyFrom(const RepeatedField& other) {
+  if (&other == this) return;
+  Clear();
+  MergeFrom(other);
+}
+
+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) {
+  if (this == other) return;
+  Element* swap_elements     = elements_;
+  int      swap_current_size = current_size_;
+  int      swap_total_size   = total_size_;
+
+  elements_     = other->elements_;
+  current_size_ = other->current_size_;
+  total_size_   = other->total_size_;
+
+  other->elements_     = swap_elements;
+  other->current_size_ = swap_current_size;
+  other->total_size_   = swap_total_size;
+}
+
+template <typename Element>
+void RepeatedField<Element>::SwapElements(int index1, int index2) {
+  using std::swap;  // enable ADL with fallback
+  swap(elements_[index1], elements_[index2]);
+}
+
+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>
+inline int RepeatedField<Element>::SpaceUsedExcludingSelf() const {
+  return (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0;
+}
+
+// Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant
+// amount of code bloat.
+template <typename Element>
+void RepeatedField<Element>::Reserve(int new_size) {
+  if (total_size_ >= new_size) return;
+
+  Element* old_elements = elements_;
+  total_size_ = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
+                    max(total_size_ * 2, new_size));
+  elements_ = new Element[total_size_];
+  if (old_elements != NULL) {
+    MoveArray(elements_, old_elements, current_size_);
+    delete [] old_elements;
+  }
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::Truncate(int new_size) {
+  GOOGLE_DCHECK_LE(new_size, current_size_);
+  current_size_ = new_size;
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::MoveArray(
+    Element to[], Element from[], int array_size) {
+  CopyArray(to, from, array_size);
+}
+
+template <typename Element>
+inline void RepeatedField<Element>::CopyArray(
+    Element to[], const Element from[], int array_size) {
+  internal::ElementCopier<Element>()(to, from, array_size);
+}
+
+namespace internal {
+
+template <typename Element, bool HasTrivialCopy>
+void ElementCopier<Element, HasTrivialCopy>::operator()(
+    Element to[], const Element from[], int array_size) {
+  std::copy(from, from + array_size, to);
+}
+
+template <typename Element>
+struct ElementCopier<Element, true> {
+  void operator()(Element to[], const Element from[], int array_size) {
+    memcpy(to, from, array_size * sizeof(Element));
+  }
+};
+
+}  // namespace internal
+
+
+// -------------------------------------------------------------------
+
+namespace internal {
+
+inline RepeatedPtrFieldBase::RepeatedPtrFieldBase()
+  : elements_(NULL),
+    current_size_(0),
+    allocated_size_(0),
+    total_size_(kInitialSize) {
+}
+
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::Destroy() {
+  for (int i = 0; i < allocated_size_; i++) {
+    TypeHandler::Delete(cast<TypeHandler>(elements_[i]));
+  }
+  delete [] elements_;
+}
+
+inline bool RepeatedPtrFieldBase::empty() const {
+  return current_size_ == 0;
+}
+
+inline int RepeatedPtrFieldBase::size() const {
+  return current_size_;
+}
+
+template <typename TypeHandler>
+inline const typename TypeHandler::Type&
+RepeatedPtrFieldBase::Get(int index) const {
+  GOOGLE_DCHECK_GE(index, 0);
+  GOOGLE_DCHECK_LT(index, size());
+  return *cast<TypeHandler>(elements_[index]);
+}
+
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type*
+RepeatedPtrFieldBase::Mutable(int index) {
+  GOOGLE_DCHECK_GE(index, 0);
+  GOOGLE_DCHECK_LT(index, size());
+  return cast<TypeHandler>(elements_[index]);
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add() {
+  if (current_size_ < allocated_size_) {
+    return cast<TypeHandler>(elements_[current_size_++]);
+  }
+  if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
+  typename TypeHandler::Type* result = TypeHandler::New();
+  ++allocated_size_;
+  elements_[current_size_++] = result;
+  return result;
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::RemoveLast() {
+  GOOGLE_DCHECK_GT(current_size_, 0);
+  TypeHandler::Clear(cast<TypeHandler>(elements_[--current_size_]));
+}
+
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::Clear() {
+  for (int i = 0; i < current_size_; i++) {
+    TypeHandler::Clear(cast<TypeHandler>(elements_[i]));
+  }
+  current_size_ = 0;
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::MergeFrom(const RepeatedPtrFieldBase& other) {
+  GOOGLE_CHECK_NE(&other, this);
+  Reserve(current_size_ + other.current_size_);
+  for (int i = 0; i < other.current_size_; i++) {
+    TypeHandler::Merge(other.template Get<TypeHandler>(i), Add<TypeHandler>());
+  }
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::CopyFrom(const RepeatedPtrFieldBase& other) {
+  if (&other == this) return;
+  RepeatedPtrFieldBase::Clear<TypeHandler>();
+  RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
+}
+
+inline int RepeatedPtrFieldBase::Capacity() const {
+  return total_size_;
+}
+
+inline void* const* RepeatedPtrFieldBase::raw_data() const {
+  return elements_;
+}
+
+inline void** RepeatedPtrFieldBase::raw_mutable_data() const {
+  return elements_;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type** RepeatedPtrFieldBase::mutable_data() {
+  // TODO(kenton):  Breaks C++ aliasing rules.  We should probably remove this
+  //   method entirely.
+  return reinterpret_cast<typename TypeHandler::Type**>(elements_);
+}
+
+template <typename TypeHandler>
+inline const typename TypeHandler::Type* const*
+RepeatedPtrFieldBase::data() const {
+  // TODO(kenton):  Breaks C++ aliasing rules.  We should probably remove this
+  //   method entirely.
+  return reinterpret_cast<const typename TypeHandler::Type* const*>(elements_);
+}
+
+inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) {
+  using std::swap;  // enable ADL with fallback
+  swap(elements_[index1], elements_[index2]);
+}
+
+template <typename TypeHandler>
+inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const {
+  int allocated_bytes =
+      (elements_ != NULL) ? total_size_ * sizeof(elements_[0]) : 0;
+  for (int i = 0; i < allocated_size_; ++i) {
+    allocated_bytes += TypeHandler::SpaceUsed(*cast<TypeHandler>(elements_[i]));
+  }
+  return allocated_bytes;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::AddFromCleared() {
+  if (current_size_ < allocated_size_) {
+    return cast<TypeHandler>(elements_[current_size_++]);
+  } else {
+    return NULL;
+  }
+}
+
+template <typename TypeHandler>
+void RepeatedPtrFieldBase::AddAllocated(
+    typename TypeHandler::Type* value) {
+  // Make room for the new pointer.
+  if (current_size_ == total_size_) {
+    // The array is completely full with no cleared objects, so grow it.
+    Reserve(total_size_ + 1);
+    ++allocated_size_;
+  } else if (allocated_size_ == total_size_) {
+    // There is no more space in the pointer array because it contains some
+    // cleared objects awaiting reuse.  We don't want to grow the array in this
+    // case because otherwise a loop calling AddAllocated() followed by Clear()
+    // would leak memory.
+    TypeHandler::Delete(cast<TypeHandler>(elements_[current_size_]));
+  } else if (current_size_ < allocated_size_) {
+    // We have some cleared objects.  We don't care about their order, so we
+    // can just move the first one to the end to make space.
+    elements_[allocated_size_] = elements_[current_size_];
+    ++allocated_size_;
+  } else {
+    // There are no cleared objects.
+    ++allocated_size_;
+  }
+
+  elements_[current_size_++] = value;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseLast() {
+  GOOGLE_DCHECK_GT(current_size_, 0);
+  typename TypeHandler::Type* result =
+      cast<TypeHandler>(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;
+}
+
+inline int RepeatedPtrFieldBase::ClearedCount() const {
+  return allocated_size_ - current_size_;
+}
+
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::AddCleared(
+    typename TypeHandler::Type* value) {
+  if (allocated_size_ == total_size_) Reserve(total_size_ + 1);
+  elements_[allocated_size_++] = value;
+}
+
+template <typename TypeHandler>
+inline typename TypeHandler::Type* RepeatedPtrFieldBase::ReleaseCleared() {
+  GOOGLE_DCHECK_GT(allocated_size_, current_size_);
+  return cast<TypeHandler>(elements_[--allocated_size_]);
+}
+
+}  // namespace internal
+
+// -------------------------------------------------------------------
+
+template <typename Element>
+class RepeatedPtrField<Element>::TypeHandler
+    : public internal::GenericTypeHandler<Element> {
+};
+
+template <>
+class RepeatedPtrField<string>::TypeHandler
+    : public internal::StringTypeHandler {
+};
+
+
+template <typename Element>
+inline RepeatedPtrField<Element>::RepeatedPtrField() {}
+
+template <typename Element>
+inline RepeatedPtrField<Element>::RepeatedPtrField(
+    const RepeatedPtrField& other)
+    : RepeatedPtrFieldBase() {
+  CopyFrom(other);
+}
+
+template <typename Element>
+template <typename Iter>
+inline RepeatedPtrField<Element>::RepeatedPtrField(
+    Iter begin, const Iter& end) {
+  int reserve = internal::CalculateReserve(begin, end);
+  if (reserve != -1) {
+    Reserve(reserve);
+  }
+  for (; begin != end; ++begin) {
+    *Add() = *begin;
+  }
+}
+
+template <typename Element>
+RepeatedPtrField<Element>::~RepeatedPtrField() {
+  Destroy<TypeHandler>();
+}
+
+template <typename Element>
+inline RepeatedPtrField<Element>& RepeatedPtrField<Element>::operator=(
+    const RepeatedPtrField& other) {
+  if (this != &other)
+    CopyFrom(other);
+  return *this;
+}
+
+template <typename Element>
+inline bool RepeatedPtrField<Element>::empty() const {
+  return RepeatedPtrFieldBase::empty();
+}
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::size() const {
+  return RepeatedPtrFieldBase::size();
+}
+
+template <typename Element>
+inline const Element& RepeatedPtrField<Element>::Get(int index) const {
+  return RepeatedPtrFieldBase::Get<TypeHandler>(index);
+}
+
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::Mutable(int index) {
+  return RepeatedPtrFieldBase::Mutable<TypeHandler>(index);
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::Add() {
+  return RepeatedPtrFieldBase::Add<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::RemoveLast() {
+  RepeatedPtrFieldBase::RemoveLast<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::DeleteSubrange(int start, int num) {
+  GOOGLE_DCHECK_GE(start, 0);
+  GOOGLE_DCHECK_GE(num, 0);
+  GOOGLE_DCHECK_LE(start + num, size());
+  for (int i = 0; i < num; ++i)
+    delete RepeatedPtrFieldBase::Mutable<TypeHandler>(start + i);
+  ExtractSubrange(start, num, NULL);
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::ExtractSubrange(
+    int start, int num, Element** elements) {
+  GOOGLE_DCHECK_GE(start, 0);
+  GOOGLE_DCHECK_GE(num, 0);
+  GOOGLE_DCHECK_LE(start + num, size());
+
+  if (num > 0) {
+    // Save the values of the removed elements if requested.
+    if (elements != NULL) {
+      for (int i = 0; i < num; ++i)
+        elements[i] = RepeatedPtrFieldBase::Mutable<TypeHandler>(i + start);
+    }
+    CloseGap(start, num);
+  }
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::Clear() {
+  RepeatedPtrFieldBase::Clear<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::MergeFrom(
+    const RepeatedPtrField& other) {
+  RepeatedPtrFieldBase::MergeFrom<TypeHandler>(other);
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::CopyFrom(
+    const RepeatedPtrField& other) {
+  RepeatedPtrFieldBase::CopyFrom<TypeHandler>(other);
+}
+
+template <typename Element>
+inline Element** RepeatedPtrField<Element>::mutable_data() {
+  return RepeatedPtrFieldBase::mutable_data<TypeHandler>();
+}
+
+template <typename Element>
+inline const Element* const* RepeatedPtrField<Element>::data() const {
+  return RepeatedPtrFieldBase::data<TypeHandler>();
+}
+
+template <typename Element>
+void RepeatedPtrField<Element>::Swap(RepeatedPtrField* other) {
+  RepeatedPtrFieldBase::Swap(other);
+}
+
+template <typename Element>
+void RepeatedPtrField<Element>::SwapElements(int index1, int index2) {
+  RepeatedPtrFieldBase::SwapElements(index1, index2);
+}
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::SpaceUsedExcludingSelf() const {
+  return RepeatedPtrFieldBase::SpaceUsedExcludingSelf<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::AddAllocated(Element* value) {
+  RepeatedPtrFieldBase::AddAllocated<TypeHandler>(value);
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::ReleaseLast() {
+  return RepeatedPtrFieldBase::ReleaseLast<TypeHandler>();
+}
+
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::ClearedCount() const {
+  return RepeatedPtrFieldBase::ClearedCount();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::AddCleared(Element* value) {
+  return RepeatedPtrFieldBase::AddCleared<TypeHandler>(value);
+}
+
+template <typename Element>
+inline Element* RepeatedPtrField<Element>::ReleaseCleared() {
+  return RepeatedPtrFieldBase::ReleaseCleared<TypeHandler>();
+}
+
+template <typename Element>
+inline void RepeatedPtrField<Element>::Reserve(int new_size) {
+  return RepeatedPtrFieldBase::Reserve(new_size);
+}
+
+template <typename Element>
+inline int RepeatedPtrField<Element>::Capacity() const {
+  return RepeatedPtrFieldBase::Capacity();
+}
+
+// -------------------------------------------------------------------
+
+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<T**> in util/gtl/iterator_adaptors.h,
+// but adds random-access operators and is modified to wrap a void** base
+// iterator (since RepeatedPtrField stores its array as a void* array and
+// casting void** to T** would violate C++ aliasing rules).
+//
+// This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
+// (jyasskin@google.com).
+template<typename Element>
+class RepeatedPtrIterator
+    : public std::iterator<
+          std::random_access_iterator_tag, Element> {
+ public:
+  typedef RepeatedPtrIterator<Element> iterator;
+  typedef std::iterator<
+          std::random_access_iterator_tag, Element> superclass;
+
+  // Shadow the value_type in std::iterator<> because const_iterator::value_type
+  // needs to be T, not const T.
+  typedef typename remove_const<Element>::type value_type;
+
+  // Let the compiler know that these are type names, so we don't have to
+  // write "typename" in front of them everywhere.
+  typedef typename superclass::reference reference;
+  typedef typename superclass::pointer pointer;
+  typedef typename superclass::difference_type difference_type;
+
+  RepeatedPtrIterator() : it_(NULL) {}
+  explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
+
+  // Allow "upcasting" from RepeatedPtrIterator<T**> to
+  // RepeatedPtrIterator<const T*const*>.
+  template<typename OtherElement>
+  RepeatedPtrIterator(const RepeatedPtrIterator<OtherElement>& other)
+      : it_(other.it_) {
+    // Force a compiler error if the other type is not convertible to ours.
+    if (false) {
+      implicit_cast<Element*, OtherElement*>(0);
+    }
+  }
+
+  // dereferenceable
+  reference operator*() const { return *reinterpret_cast<Element*>(*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:
+  template<typename OtherElement>
+  friend class RepeatedPtrIterator;
+
+  // The internal iterator.
+  void* const* it_;
+};
+
+// Provide an iterator that operates on pointers to the underlying objects
+// rather than the objects themselves as RepeatedPtrIterator does.
+// Consider using this when working with stl algorithms that change
+// the array.
+// The VoidPtr template parameter holds the type-agnostic pointer value
+// referenced by the iterator.  It should either be "void *" for a mutable
+// iterator, or "const void *" for a constant iterator.
+template<typename Element, typename VoidPtr>
+class RepeatedPtrOverPtrsIterator
+    : public std::iterator<std::random_access_iterator_tag, Element*> {
+ public:
+  typedef RepeatedPtrOverPtrsIterator<Element, VoidPtr> iterator;
+  typedef std::iterator<
+          std::random_access_iterator_tag, Element*> superclass;
+
+  // Shadow the value_type in std::iterator<> because const_iterator::value_type
+  // needs to be T, not const T.
+  typedef typename remove_const<Element*>::type value_type;
+
+  // Let the compiler know that these are type names, so we don't have to
+  // write "typename" in front of them everywhere.
+  typedef typename superclass::reference reference;
+  typedef typename superclass::pointer pointer;
+  typedef typename superclass::difference_type difference_type;
+
+  RepeatedPtrOverPtrsIterator() : it_(NULL) {}
+  explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
+
+  // dereferenceable
+  reference operator*() const { return *reinterpret_cast<Element**>(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:
+  template<typename OtherElement>
+  friend class RepeatedPtrIterator;
+
+  // The internal iterator.
+  VoidPtr* it_;
+};
+
+}  // namespace internal
+
+template <typename Element>
+inline typename RepeatedPtrField<Element>::iterator
+RepeatedPtrField<Element>::begin() {
+  return iterator(raw_data());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_iterator
+RepeatedPtrField<Element>::begin() const {
+  return iterator(raw_data());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::iterator
+RepeatedPtrField<Element>::end() {
+  return iterator(raw_data() + size());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_iterator
+RepeatedPtrField<Element>::end() const {
+  return iterator(raw_data() + size());
+}
+
+template <typename Element>
+inline typename RepeatedPtrField<Element>::pointer_iterator
+RepeatedPtrField<Element>::pointer_begin() {
+  return pointer_iterator(raw_mutable_data());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_pointer_iterator
+RepeatedPtrField<Element>::pointer_begin() const {
+  return const_pointer_iterator(const_cast<const void**>(raw_mutable_data()));
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::pointer_iterator
+RepeatedPtrField<Element>::pointer_end() {
+  return pointer_iterator(raw_mutable_data() + size());
+}
+template <typename Element>
+inline typename RepeatedPtrField<Element>::const_pointer_iterator
+RepeatedPtrField<Element>::pointer_end() const {
+  return const_pointer_iterator(
+      const_cast<const void**>(raw_mutable_data() + size()));
+}
+
+
+// Iterators and helper functions that follow the spirit of the STL
+// std::back_insert_iterator and std::back_inserter but are tailor-made
+// for RepeatedField and RepatedPtrField. Typical usage would be:
+//
+//   std::copy(some_sequence.begin(), some_sequence.end(),
+//             google::protobuf::RepeatedFieldBackInserter(proto.mutable_sequence()));
+//
+// Ported by johannes from util/gtl/proto-array-iterators.h
+
+namespace internal {
+// A back inserter for RepeatedField objects.
+template<typename T> class RepeatedFieldBackInsertIterator
+    : public std::iterator<std::output_iterator_tag, T> {
+ public:
+  explicit RepeatedFieldBackInsertIterator(
+      RepeatedField<T>* const mutable_field)
+      : field_(mutable_field) {
+  }
+  RepeatedFieldBackInsertIterator<T>& operator=(const T& value) {
+    field_->Add(value);
+    return *this;
+  }
+  RepeatedFieldBackInsertIterator<T>& operator*() {
+    return *this;
+  }
+  RepeatedFieldBackInsertIterator<T>& operator++() {
+    return *this;
+  }
+  RepeatedFieldBackInsertIterator<T>& operator++(int /* unused */) {
+    return *this;
+  }
+
+ private:
+  RepeatedField<T>* field_;
+};
+
+// A back inserter for RepeatedPtrField objects.
+template<typename T> class RepeatedPtrFieldBackInsertIterator
+    : public std::iterator<std::output_iterator_tag, T> {
+ public:
+  RepeatedPtrFieldBackInsertIterator(
+      RepeatedPtrField<T>* const mutable_field)
+      : field_(mutable_field) {
+  }
+  RepeatedPtrFieldBackInsertIterator<T>& operator=(const T& value) {
+    *field_->Add() = value;
+    return *this;
+  }
+  RepeatedPtrFieldBackInsertIterator<T>& operator=(
+      const T* const ptr_to_value) {
+    *field_->Add() = *ptr_to_value;
+    return *this;
+  }
+  RepeatedPtrFieldBackInsertIterator<T>& operator*() {
+    return *this;
+  }
+  RepeatedPtrFieldBackInsertIterator<T>& operator++() {
+    return *this;
+  }
+  RepeatedPtrFieldBackInsertIterator<T>& operator++(int /* unused */) {
+    return *this;
+  }
+
+ private:
+  RepeatedPtrField<T>* field_;
+};
+
+// A back inserter for RepeatedPtrFields that inserts by transfering ownership
+// of a pointer.
+template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
+    : public std::iterator<std::output_iterator_tag, T> {
+ public:
+  explicit AllocatedRepeatedPtrFieldBackInsertIterator(
+      RepeatedPtrField<T>* const mutable_field)
+      : field_(mutable_field) {
+  }
+  AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator=(
+      T* const ptr_to_value) {
+    field_->AddAllocated(ptr_to_value);
+    return *this;
+  }
+  AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator*() {
+    return *this;
+  }
+  AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++() {
+    return *this;
+  }
+  AllocatedRepeatedPtrFieldBackInsertIterator<T>& operator++(
+      int /* unused */) {
+    return *this;
+  }
+
+ private:
+  RepeatedPtrField<T>* field_;
+};
+}  // namespace internal
+
+// Provides a back insert iterator for RepeatedField instances,
+// similar to std::back_inserter().
+template<typename T> internal::RepeatedFieldBackInsertIterator<T>
+RepeatedFieldBackInserter(RepeatedField<T>* const mutable_field) {
+  return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
+}
+
+// Provides a back insert iterator for RepeatedPtrField instances,
+// similar to std::back_inserter().
+template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
+RepeatedPtrFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
+  return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
+}
+
+// Special back insert iterator for RepeatedPtrField instances, just in
+// case someone wants to write generic template code that can access both
+// RepeatedFields and RepeatedPtrFields using a common name.
+template<typename T> internal::RepeatedPtrFieldBackInsertIterator<T>
+RepeatedFieldBackInserter(RepeatedPtrField<T>* const mutable_field) {
+  return internal::RepeatedPtrFieldBackInsertIterator<T>(mutable_field);
+}
+
+// Provides a back insert iterator for RepeatedPtrField instances
+// similar to std::back_inserter() which transfers the ownership while
+// copying elements.
+template<typename T> internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>
+AllocatedRepeatedPtrFieldBackInserter(
+    RepeatedPtrField<T>* const mutable_field) {
+  return internal::AllocatedRepeatedPtrFieldBackInsertIterator<T>(
+      mutable_field);
+}
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_REPEATED_FIELD_H__
diff --git a/protobuf/src/google/protobuf/repeated_field_reflection_unittest.cc b/protobuf/src/google/protobuf/repeated_field_reflection_unittest.cc
new file mode 100644
index 0000000..62833aa
--- /dev/null
+++ b/protobuf/src/google/protobuf/repeated_field_reflection_unittest.cc
@@ -0,0 +1,195 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: tgs@google.com (Tom Szymanski)
+//
+// Test reflection methods for aggregate access to Repeated[Ptr]Fields.
+// This test proto2 methods on a proto2 layout.
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+using unittest::ForeignMessage;
+using unittest::TestAllTypes;
+using unittest::TestAllExtensions;
+
+namespace {
+
+static int Func(int i, int j) {
+  return i * j;
+}
+
+static string StrFunc(int i, int j) {
+  string str;
+  SStringPrintf(&str, "%d", Func(i, 4));
+  return str;
+}
+
+
+TEST(RepeatedFieldReflectionTest, RegularFields) {
+  TestAllTypes message;
+  const Reflection* refl = message.GetReflection();
+  const Descriptor* desc = message.GetDescriptor();
+
+  for (int i = 0; i < 10; ++i) {
+    message.add_repeated_int32(Func(i, 1));
+    message.add_repeated_double(Func(i, 2));
+    message.add_repeated_string(StrFunc(i, 5));
+    message.add_repeated_foreign_message()->set_c(Func(i, 6));
+  }
+
+  // Get FieldDescriptors for all the fields of interest.
+  const FieldDescriptor* fd_repeated_int32 =
+      desc->FindFieldByName("repeated_int32");
+  const FieldDescriptor* fd_repeated_double =
+      desc->FindFieldByName("repeated_double");
+  const FieldDescriptor* fd_repeated_string =
+      desc->FindFieldByName("repeated_string");
+  const FieldDescriptor* fd_repeated_foreign_message =
+      desc->FindFieldByName("repeated_foreign_message");
+
+  // Get RepeatedField objects for all fields of interest.
+  const RepeatedField<int32>& rf_int32 =
+      refl->GetRepeatedField<int32>(message, fd_repeated_int32);
+  const RepeatedField<double>& rf_double =
+      refl->GetRepeatedField<double>(message, fd_repeated_double);
+
+  // Get mutable RepeatedField objects for all fields of interest.
+  RepeatedField<int32>* mrf_int32 =
+      refl->MutableRepeatedField<int32>(&message, fd_repeated_int32);
+  RepeatedField<double>* mrf_double =
+      refl->MutableRepeatedField<double>(&message, fd_repeated_double);
+
+  // Get RepeatedPtrField objects for all fields of interest.
+  const RepeatedPtrField<string>& rpf_string =
+      refl->GetRepeatedPtrField<string>(message, fd_repeated_string);
+  const RepeatedPtrField<ForeignMessage>& rpf_foreign_message =
+      refl->GetRepeatedPtrField<ForeignMessage>(
+          message, fd_repeated_foreign_message);
+  const RepeatedPtrField<Message>& rpf_message =
+      refl->GetRepeatedPtrField<Message>(
+          message, fd_repeated_foreign_message);
+
+  // Get mutable RepeatedPtrField objects for all fields of interest.
+  RepeatedPtrField<string>* mrpf_string =
+      refl->MutableRepeatedPtrField<string>(&message, fd_repeated_string);
+  RepeatedPtrField<ForeignMessage>* mrpf_foreign_message =
+      refl->MutableRepeatedPtrField<ForeignMessage>(
+          &message, fd_repeated_foreign_message);
+  RepeatedPtrField<Message>* mrpf_message =
+      refl->MutableRepeatedPtrField<Message>(
+          &message, fd_repeated_foreign_message);
+
+  // Make sure we can do get and sets through the Repeated[Ptr]Field objects.
+  for (int i = 0; i < 10; ++i) {
+    // Check gets through const objects.
+    EXPECT_EQ(rf_int32.Get(i), Func(i, 1));
+    EXPECT_EQ(rf_double.Get(i), Func(i, 2));
+    EXPECT_EQ(rpf_string.Get(i), StrFunc(i, 5));
+    EXPECT_EQ(rpf_foreign_message.Get(i).c(), Func(i, 6));
+    EXPECT_EQ(down_cast<const ForeignMessage*>(&rpf_message.Get(i))->c(),
+              Func(i, 6));
+
+    // Check gets through mutable objects.
+    EXPECT_EQ(mrf_int32->Get(i), Func(i, 1));
+    EXPECT_EQ(mrf_double->Get(i), Func(i, 2));
+    EXPECT_EQ(mrpf_string->Get(i), StrFunc(i, 5));
+    EXPECT_EQ(mrpf_foreign_message->Get(i).c(), Func(i, 6));
+    EXPECT_EQ(down_cast<const ForeignMessage*>(&mrpf_message->Get(i))->c(),
+              Func(i, 6));
+
+    // Check sets through mutable objects.
+    mrf_int32->Set(i, Func(i, -1));
+    mrf_double->Set(i, Func(i, -2));
+    mrpf_string->Mutable(i)->assign(StrFunc(i, -5));
+    mrpf_foreign_message->Mutable(i)->set_c(Func(i, -6));
+    EXPECT_EQ(message.repeated_int32(i), Func(i, -1));
+    EXPECT_EQ(message.repeated_double(i), Func(i, -2));
+    EXPECT_EQ(message.repeated_string(i), StrFunc(i, -5));
+    EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, -6));
+    down_cast<ForeignMessage*>(mrpf_message->Mutable(i))->set_c(Func(i, 7));
+    EXPECT_EQ(message.repeated_foreign_message(i).c(), Func(i, 7));
+  }
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+  // Make sure types are checked correctly at runtime.
+  const FieldDescriptor* fd_optional_int32 =
+      desc->FindFieldByName("optional_int32");
+  EXPECT_DEATH(refl->GetRepeatedField<int32>(
+      message, fd_optional_int32), "requires a repeated field");
+  EXPECT_DEATH(refl->GetRepeatedField<double>(
+      message, fd_repeated_int32), "not the right type");
+  EXPECT_DEATH(refl->GetRepeatedPtrField<TestAllTypes>(
+      message, fd_repeated_foreign_message), "wrong submessage type");
+#endif  // PROTOBUF_HAS_DEATH_TEST
+}
+
+
+
+
+TEST(RepeatedFieldReflectionTest, ExtensionFields) {
+  TestAllExtensions extended_message;
+  const Reflection* refl = extended_message.GetReflection();
+  const Descriptor* desc = extended_message.GetDescriptor();
+
+  for (int i = 0; i < 10; ++i) {
+    extended_message.AddExtension(
+        unittest::repeated_int64_extension, Func(i, 1));
+  }
+
+  const FieldDescriptor* fd_repeated_int64_extension =
+      desc->file()->FindExtensionByName("repeated_int64_extension");
+  GOOGLE_CHECK(fd_repeated_int64_extension != NULL);
+
+  const RepeatedField<int64>& rf_int64_extension =
+      refl->GetRepeatedField<int64>(extended_message,
+                                    fd_repeated_int64_extension);
+
+  RepeatedField<int64>* mrf_int64_extension =
+      refl->MutableRepeatedField<int64>(&extended_message,
+                                        fd_repeated_int64_extension);
+
+  for (int i = 0; i < 10; ++i) {
+    EXPECT_EQ(Func(i, 1), rf_int64_extension.Get(i));
+    mrf_int64_extension->Set(i, Func(i, -1));
+    EXPECT_EQ(Func(i, -1),
+        extended_message.GetExtension(unittest::repeated_int64_extension, i));
+  }
+}
+
+}  // namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/repeated_field_unittest.cc b/protobuf/src/google/protobuf/repeated_field_unittest.cc
new file mode 100644
index 0000000..f4d48f5
--- /dev/null
+++ b/protobuf/src/google/protobuf/repeated_field_unittest.cc
@@ -0,0 +1,1442 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <limits>
+#include <list>
+#include <vector>
+
+#include <google/protobuf/repeated_field.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+using protobuf_unittest::TestAllTypes;
+
+namespace protobuf {
+namespace {
+
+// Test operations on a small RepeatedField.
+TEST(RepeatedField, Small) {
+  RepeatedField<int> field;
+
+  EXPECT_TRUE(field.empty());
+  EXPECT_EQ(field.size(), 0);
+
+  field.Add(5);
+
+  EXPECT_FALSE(field.empty());
+  EXPECT_EQ(field.size(), 1);
+  EXPECT_EQ(field.Get(0), 5);
+
+  field.Add(42);
+
+  EXPECT_FALSE(field.empty());
+  EXPECT_EQ(field.size(), 2);
+  EXPECT_EQ(field.Get(0), 5);
+  EXPECT_EQ(field.Get(1), 42);
+
+  field.Set(1, 23);
+
+  EXPECT_FALSE(field.empty());
+  EXPECT_EQ(field.size(), 2);
+  EXPECT_EQ(field.Get(0), 5);
+  EXPECT_EQ(field.Get(1), 23);
+
+  field.RemoveLast();
+
+  EXPECT_FALSE(field.empty());
+  EXPECT_EQ(field.size(), 1);
+  EXPECT_EQ(field.Get(0), 5);
+
+  field.Clear();
+
+  EXPECT_TRUE(field.empty());
+  EXPECT_EQ(field.size(), 0);
+  int expected_usage = 4 * sizeof(int);
+  EXPECT_EQ(field.SpaceUsedExcludingSelf(), expected_usage);
+}
+
+
+// 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_FALSE(field.empty());
+  EXPECT_EQ(field.size(), 16);
+
+  for (int i = 0; i < 16; i++) {
+    EXPECT_EQ(field.Get(i), i * i);
+  }
+
+  int expected_usage = 16 * sizeof(int);
+  EXPECT_GE(field.SpaceUsedExcludingSelf(), expected_usage);
+}
+
+// Test swapping between various types of RepeatedFields.
+TEST(RepeatedField, SwapSmallSmall) {
+  RepeatedField<int> field1;
+  RepeatedField<int> field2;
+
+  field1.Add(5);
+  field1.Add(42);
+
+  EXPECT_FALSE(field1.empty());
+  EXPECT_EQ(field1.size(), 2);
+  EXPECT_EQ(field1.Get(0), 5);
+  EXPECT_EQ(field1.Get(1), 42);
+
+  EXPECT_TRUE(field2.empty());
+  EXPECT_EQ(field2.size(), 0);
+
+  field1.Swap(&field2);
+
+  EXPECT_TRUE(field1.empty());
+  EXPECT_EQ(field1.size(), 0);
+
+  EXPECT_FALSE(field2.empty());
+  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, Resize) {
+  RepeatedField<int> field;
+  field.Resize(2, 1);
+  EXPECT_EQ(2, field.size());
+  field.Resize(5, 2);
+  EXPECT_EQ(5, field.size());
+  field.Resize(4, 3);
+  ASSERT_EQ(4, field.size());
+  EXPECT_EQ(1, field.Get(0));
+  EXPECT_EQ(1, field.Get(1));
+  EXPECT_EQ(2, field.Get(2));
+  EXPECT_EQ(2, field.Get(3));
+  field.Resize(0, 4);
+  EXPECT_TRUE(field.empty());
+}
+
+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));
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(RepeatedField, MergeFromSelf) {
+  RepeatedField<int> me;
+  me.Add(3);
+  EXPECT_DEATH(me.MergeFrom(me), "");
+}
+#endif  // PROTOBUF_HAS_DEATH_TEST
+
+TEST(RepeatedField, CopyFrom) {
+  RepeatedField<int> source, destination;
+  source.Add(4);
+  source.Add(5);
+  destination.Add(1);
+  destination.Add(2);
+  destination.Add(3);
+
+  destination.CopyFrom(source);
+
+  ASSERT_EQ(2, destination.size());
+  EXPECT_EQ(4, destination.Get(0));
+  EXPECT_EQ(5, destination.Get(1));
+}
+
+TEST(RepeatedField, CopyFromSelf) {
+  RepeatedField<int> me;
+  me.Add(3);
+  me.CopyFrom(me);
+  ASSERT_EQ(1, me.size());
+  EXPECT_EQ(3, me.Get(0));
+}
+
+TEST(RepeatedField, CopyConstruct) {
+  RepeatedField<int> source;
+  source.Add(1);
+  source.Add(2);
+
+  RepeatedField<int> destination(source);
+
+  ASSERT_EQ(2, destination.size());
+  EXPECT_EQ(1, destination.Get(0));
+  EXPECT_EQ(2, destination.Get(1));
+}
+
+TEST(RepeatedField, IteratorConstruct) {
+  vector<int> values;
+  values.push_back(1);
+  values.push_back(2);
+
+  RepeatedField<int> field(values.begin(), values.end());
+  ASSERT_EQ(values.size(), field.size());
+  EXPECT_EQ(values[0], field.Get(0));
+  EXPECT_EQ(values[1], field.Get(1));
+
+  RepeatedField<int> other(field.begin(), field.end());
+  ASSERT_EQ(values.size(), other.size());
+  EXPECT_EQ(values[0], other.Get(0));
+  EXPECT_EQ(values[1], other.Get(1));
+}
+
+TEST(RepeatedField, CopyAssign) {
+  RepeatedField<int> source, destination;
+  source.Add(4);
+  source.Add(5);
+  destination.Add(1);
+  destination.Add(2);
+  destination.Add(3);
+
+  destination = source;
+
+  ASSERT_EQ(2, destination.size());
+  EXPECT_EQ(4, destination.Get(0));
+  EXPECT_EQ(5, destination.Get(1));
+}
+
+TEST(RepeatedField, SelfAssign) {
+  // Verify that assignment to self does not destroy data.
+  RepeatedField<int> source, *p;
+  p = &source;
+  source.Add(7);
+  source.Add(8);
+
+  *p = source;
+
+  ASSERT_EQ(2, source.size());
+  EXPECT_EQ(7, source.Get(0));
+  EXPECT_EQ(8, source.Get(1));
+}
+
+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));
+}
+
+TEST(RepeatedField, Truncate) {
+  RepeatedField<int> field;
+
+  field.Add(12);
+  field.Add(34);
+  field.Add(56);
+  field.Add(78);
+  EXPECT_EQ(4, field.size());
+
+  field.Truncate(3);
+  EXPECT_EQ(3, field.size());
+
+  field.Add(90);
+  EXPECT_EQ(4, field.size());
+  EXPECT_EQ(90, field.Get(3));
+
+  // Truncations that don't change the size are allowed, but growing is not
+  // allowed.
+  field.Truncate(field.size());
+#ifdef PROTOBUF_HAS_DEATH_TEST
+  EXPECT_DEBUG_DEATH(field.Truncate(field.size() + 1), "new_size");
+#endif
+}
+
+
+TEST(RepeatedField, ExtractSubrange) {
+  // Exhaustively test every subrange in arrays of all sizes from 0 through 9.
+  for (int sz = 0; sz < 10; ++sz) {
+    for (int num = 0; num <= sz; ++num) {
+      for (int start = 0; start < sz - num; ++start) {
+        // Create RepeatedField with sz elements having values 0 through sz-1.
+        RepeatedField<int32> field;
+        for (int i = 0; i < sz; ++i)
+          field.Add(i);
+        EXPECT_EQ(field.size(), sz);
+
+        // Create a catcher array and call ExtractSubrange.
+        int32 catcher[10];
+        for (int i = 0; i < 10; ++i)
+          catcher[i] = -1;
+        field.ExtractSubrange(start, num, catcher);
+
+        // Does the resulting array have the right size?
+        EXPECT_EQ(field.size(), sz - num);
+
+        // Were the removed elements extracted into the catcher array?
+        for (int i = 0; i < num; ++i)
+          EXPECT_EQ(catcher[i], start + i);
+        EXPECT_EQ(catcher[num], -1);
+
+        // Does the resulting array contain the right values?
+        for (int i = 0; i < start; ++i)
+          EXPECT_EQ(field.Get(i), i);
+        for (int i = start; i < field.size(); ++i)
+          EXPECT_EQ(field.Get(i), i + num);
+      }
+    }
+  }
+}
+
+// ===================================================================
+// RepeatedPtrField tests.  These pretty much just mirror the RepeatedField
+// tests above.
+
+TEST(RepeatedPtrField, Small) {
+  RepeatedPtrField<string> field;
+
+  EXPECT_TRUE(field.empty());
+  EXPECT_EQ(field.size(), 0);
+
+  field.Add()->assign("foo");
+
+  EXPECT_FALSE(field.empty());
+  EXPECT_EQ(field.size(), 1);
+  EXPECT_EQ(field.Get(0), "foo");
+
+  field.Add()->assign("bar");
+
+  EXPECT_FALSE(field.empty());
+  EXPECT_EQ(field.size(), 2);
+  EXPECT_EQ(field.Get(0), "foo");
+  EXPECT_EQ(field.Get(1), "bar");
+
+  field.Mutable(1)->assign("baz");
+
+  EXPECT_FALSE(field.empty());
+  EXPECT_EQ(field.size(), 2);
+  EXPECT_EQ(field.Get(0), "foo");
+  EXPECT_EQ(field.Get(1), "baz");
+
+  field.RemoveLast();
+
+  EXPECT_FALSE(field.empty());
+  EXPECT_EQ(field.size(), 1);
+  EXPECT_EQ(field.Get(0), "foo");
+
+  field.Clear();
+
+  EXPECT_TRUE(field.empty());
+  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);
+  }
+
+  int min_expected_usage = 16 * sizeof(string);
+  EXPECT_GE(field.SpaceUsedExcludingSelf(), min_expected_usage);
+}
+
+TEST(RepeatedPtrField, SwapSmallSmall) {
+  RepeatedPtrField<string> field1;
+  RepeatedPtrField<string> field2;
+
+  EXPECT_TRUE(field1.empty());
+  EXPECT_EQ(field1.size(), 0);
+  EXPECT_TRUE(field2.empty());
+  EXPECT_EQ(field2.size(), 0);
+
+  field1.Add()->assign("foo");
+  field1.Add()->assign("bar");
+
+  EXPECT_FALSE(field1.empty());
+  EXPECT_EQ(field1.size(), 2);
+  EXPECT_EQ(field1.Get(0), "foo");
+  EXPECT_EQ(field1.Get(1), "bar");
+
+  EXPECT_TRUE(field2.empty());
+  EXPECT_EQ(field2.size(), 0);
+
+  field1.Swap(&field2);
+
+  EXPECT_TRUE(field1.empty());
+  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 all code paths in AddAllocated().
+TEST(RepeatedPtrField, AddAlocated) {
+  RepeatedPtrField<string> field;
+  while (field.size() < field.Capacity()) {
+    field.Add()->assign("filler");
+  }
+
+  int index = field.size();
+
+  // First branch:  Field is at capacity with no cleared objects.
+  string* foo = new string("foo");
+  field.AddAllocated(foo);
+  EXPECT_EQ(index + 1, field.size());
+  EXPECT_EQ(0, field.ClearedCount());
+  EXPECT_EQ(foo, &field.Get(index));
+
+  // Last branch:  Field is not at capacity and there are no cleared objects.
+  string* bar = new string("bar");
+  field.AddAllocated(bar);
+  ++index;
+  EXPECT_EQ(index + 1, field.size());
+  EXPECT_EQ(0, field.ClearedCount());
+  EXPECT_EQ(bar, &field.Get(index));
+
+  // Third branch:  Field is not at capacity and there are no cleared objects.
+  field.RemoveLast();
+  string* baz = new string("baz");
+  field.AddAllocated(baz);
+  EXPECT_EQ(index + 1, field.size());
+  EXPECT_EQ(1, field.ClearedCount());
+  EXPECT_EQ(baz, &field.Get(index));
+
+  // Second branch:  Field is at capacity but has some cleared objects.
+  while (field.size() < field.Capacity()) {
+    field.Add()->assign("filler2");
+  }
+  field.RemoveLast();
+  index = field.size();
+  string* qux = new string("qux");
+  field.AddAllocated(qux);
+  EXPECT_EQ(index + 1, field.size());
+  // We should have discarded the cleared object.
+  EXPECT_EQ(0, field.ClearedCount());
+  EXPECT_EQ(qux, &field.Get(index));
+}
+
+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));
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(RepeatedPtrField, MergeFromSelf) {
+  RepeatedPtrField<string> me;
+  me.Add()->assign("1");
+  EXPECT_DEATH(me.MergeFrom(me), "");
+}
+#endif  // PROTOBUF_HAS_DEATH_TEST
+
+TEST(RepeatedPtrField, CopyFrom) {
+  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.CopyFrom(source);
+
+  ASSERT_EQ(2, destination.size());
+  EXPECT_EQ("4", destination.Get(0));
+  EXPECT_EQ("5", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, CopyFromSelf) {
+  RepeatedPtrField<string> me;
+  me.Add()->assign("1");
+  me.CopyFrom(me);
+  ASSERT_EQ(1, me.size());
+  EXPECT_EQ("1", me.Get(0));
+}
+
+TEST(RepeatedPtrField, CopyConstruct) {
+  RepeatedPtrField<string> source;
+  source.Add()->assign("1");
+  source.Add()->assign("2");
+
+  RepeatedPtrField<string> destination(source);
+
+  ASSERT_EQ(2, destination.size());
+  EXPECT_EQ("1", destination.Get(0));
+  EXPECT_EQ("2", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, IteratorConstruct_String) {
+  vector<string> values;
+  values.push_back("1");
+  values.push_back("2");
+
+  RepeatedPtrField<string> field(values.begin(), values.end());
+  ASSERT_EQ(values.size(), field.size());
+  EXPECT_EQ(values[0], field.Get(0));
+  EXPECT_EQ(values[1], field.Get(1));
+
+  RepeatedPtrField<string> other(field.begin(), field.end());
+  ASSERT_EQ(values.size(), other.size());
+  EXPECT_EQ(values[0], other.Get(0));
+  EXPECT_EQ(values[1], other.Get(1));
+}
+
+TEST(RepeatedPtrField, IteratorConstruct_Proto) {
+  typedef TestAllTypes::NestedMessage Nested;
+  vector<Nested> values;
+  values.push_back(Nested());
+  values.back().set_bb(1);
+  values.push_back(Nested());
+  values.back().set_bb(2);
+
+  RepeatedPtrField<Nested> field(values.begin(), values.end());
+  ASSERT_EQ(values.size(), field.size());
+  EXPECT_EQ(values[0].bb(), field.Get(0).bb());
+  EXPECT_EQ(values[1].bb(), field.Get(1).bb());
+
+  RepeatedPtrField<Nested> other(field.begin(), field.end());
+  ASSERT_EQ(values.size(), other.size());
+  EXPECT_EQ(values[0].bb(), other.Get(0).bb());
+  EXPECT_EQ(values[1].bb(), other.Get(1).bb());
+}
+
+TEST(RepeatedPtrField, CopyAssign) {
+  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 = source;
+
+  ASSERT_EQ(2, destination.size());
+  EXPECT_EQ("4", destination.Get(0));
+  EXPECT_EQ("5", destination.Get(1));
+}
+
+TEST(RepeatedPtrField, SelfAssign) {
+  // Verify that assignment to self does not destroy data.
+  RepeatedPtrField<string> source, *p;
+  p = &source;
+  source.Add()->assign("7");
+  source.Add()->assign("8");
+
+  *p = source;
+
+  ASSERT_EQ(2, source.size());
+  EXPECT_EQ("7", source.Get(0));
+  EXPECT_EQ("8", source.Get(1));
+}
+
+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));
+}
+
+TEST(RepeatedPtrField, ExtractSubrange) {
+  // Exhaustively test every subrange in arrays of all sizes from 0 through 9
+  // with 0 through 3 cleared elements at the end.
+  for (int sz = 0; sz < 10; ++sz) {
+    for (int num = 0; num <= sz; ++num) {
+      for (int start = 0; start < sz - num; ++start) {
+        for (int extra = 0; extra < 4; ++extra) {
+          vector<string*> subject;
+
+          // Create an array with "sz" elements and "extra" cleared elements.
+          RepeatedPtrField<string> field;
+          for (int i = 0; i < sz + extra; ++i) {
+            subject.push_back(new string());
+            field.AddAllocated(subject[i]);
+          }
+          EXPECT_EQ(field.size(), sz + extra);
+          for (int i = 0; i < extra; ++i)
+            field.RemoveLast();
+          EXPECT_EQ(field.size(), sz);
+          EXPECT_EQ(field.ClearedCount(), extra);
+
+          // Create a catcher array and call ExtractSubrange.
+          string* catcher[10];
+          for (int i = 0; i < 10; ++i)
+            catcher[i] = NULL;
+          field.ExtractSubrange(start, num, catcher);
+
+          // Does the resulting array have the right size?
+          EXPECT_EQ(field.size(), sz - num);
+
+          // Were the removed elements extracted into the catcher array?
+          for (int i = 0; i < num; ++i)
+            EXPECT_EQ(catcher[i], subject[start + i]);
+          EXPECT_EQ(NULL, catcher[num]);
+
+          // Does the resulting array contain the right values?
+          for (int i = 0; i < start; ++i)
+            EXPECT_EQ(field.Mutable(i), subject[i]);
+          for (int i = start; i < field.size(); ++i)
+            EXPECT_EQ(field.Mutable(i), subject[i + num]);
+
+          // Reinstate the cleared elements.
+          EXPECT_EQ(field.ClearedCount(), extra);
+          for (int i = 0; i < extra; ++i)
+            field.Add();
+          EXPECT_EQ(field.ClearedCount(), 0);
+          EXPECT_EQ(field.size(), sz - num + extra);
+
+          // Make sure the extra elements are all there (in some order).
+          for (int i = sz; i < sz + extra; ++i) {
+            int count = 0;
+            for (int j = sz; j < sz + extra; ++j) {
+              if (field.Mutable(j - num) == subject[i])
+                count += 1;
+            }
+            EXPECT_EQ(count, 1);
+          }
+
+          // Release the caught elements.
+          for (int i = 0; i < num; ++i)
+            delete catcher[i];
+        }
+      }
+    }
+  }
+}
+
+TEST(RepeatedPtrField, DeleteSubrange) {
+  // DeleteSubrange is a trivial extension of ExtendSubrange.
+}
+
+// ===================================================================
+
+// 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;
+  RepeatedField<int>::value_type value = *c_iter;
+  EXPECT_EQ(0, value);
+}
+
+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;
+  RepeatedPtrField<string>::value_type value = *c_iter;
+  EXPECT_EQ("foo", value);
+}
+
+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, MutableReverseIteration) {
+  RepeatedPtrField<string>::reverse_iterator iter = proto_array_.rbegin();
+  EXPECT_EQ("baz", *iter);
+  ++iter;
+  EXPECT_EQ("bar", *(iter++));
+  EXPECT_EQ("foo", *iter);
+  ++iter;
+  EXPECT_TRUE(proto_array_.rend() == iter);
+  EXPECT_EQ("foo", *(--proto_array_.rend()));
+}
+
+TEST_F(RepeatedPtrFieldIteratorTest, ConstReverseIteration) {
+  const RepeatedPtrField<string>& const_proto_array = proto_array_;
+  RepeatedPtrField<string>::const_reverse_iterator iter
+      = const_proto_array.rbegin();
+  EXPECT_EQ("baz", *iter);
+  ++iter;
+  EXPECT_EQ("bar", *(iter++));
+  EXPECT_EQ("foo", *iter);
+  ++iter;
+  EXPECT_TRUE(const_proto_array.rend() == iter);
+  EXPECT_EQ("foo", *(--const_proto_array.rend()));
+}
+
+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.
+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());
+}
+
+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));
+}
+
+// -------------------------------------------------------------------
+
+class RepeatedPtrFieldPtrsIteratorTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    proto_array_.Add()->assign("foo");
+    proto_array_.Add()->assign("bar");
+    proto_array_.Add()->assign("baz");
+    const_proto_array_ = &proto_array_;
+  }
+
+  RepeatedPtrField<string> proto_array_;
+  const RepeatedPtrField<string>* const_proto_array_;
+};
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertiblePtr) {
+  RepeatedPtrField<string>::pointer_iterator iter =
+      proto_array_.pointer_begin();
+  static_cast<void>(iter);
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ConvertibleConstPtr) {
+  RepeatedPtrField<string>::const_pointer_iterator iter =
+      const_proto_array_->pointer_begin();
+  static_cast<void>(iter);
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutablePtrIteration) {
+  RepeatedPtrField<string>::pointer_iterator iter =
+      proto_array_.pointer_begin();
+  EXPECT_EQ("foo", **iter);
+  ++iter;
+  EXPECT_EQ("bar", **(iter++));
+  EXPECT_EQ("baz", **iter);
+  ++iter;
+  EXPECT_TRUE(proto_array_.pointer_end() == iter);
+  EXPECT_EQ("baz", **(--proto_array_.pointer_end()));
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, MutableConstPtrIteration) {
+  RepeatedPtrField<string>::const_pointer_iterator iter =
+      const_proto_array_->pointer_begin();
+  EXPECT_EQ("foo", **iter);
+  ++iter;
+  EXPECT_EQ("bar", **(iter++));
+  EXPECT_EQ("baz", **iter);
+  ++iter;
+  EXPECT_TRUE(const_proto_array_->pointer_end() == iter);
+  EXPECT_EQ("baz", **(--const_proto_array_->pointer_end()));
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, RandomPtrAccess) {
+  RepeatedPtrField<string>::pointer_iterator iter =
+      proto_array_.pointer_begin();
+  RepeatedPtrField<string>::pointer_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(RepeatedPtrFieldPtrsIteratorTest, RandomConstPtrAccess) {
+  RepeatedPtrField<string>::const_pointer_iterator iter =
+      const_proto_array_->pointer_begin();
+  RepeatedPtrField<string>::const_pointer_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, const_proto_array_->end() - const_proto_array_->begin());
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparablePtr) {
+  RepeatedPtrField<string>::pointer_iterator iter =
+      proto_array_.pointer_begin();
+  RepeatedPtrField<string>::pointer_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);
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, ComparableConstPtr) {
+  RepeatedPtrField<string>::const_pointer_iterator iter =
+      const_proto_array_->pointer_begin();
+  RepeatedPtrField<string>::const_pointer_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 RepeatedPtrOverPtrs.
+// Dereferencing an uninitialized iterator crashes the process.
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedPtrIterator) {
+  RepeatedPtrField<string>::pointer_iterator iter;
+  EXPECT_TRUE(iter != proto_array_.pointer_begin());
+  EXPECT_TRUE(iter != proto_array_.pointer_begin() + 1);
+  EXPECT_TRUE(iter != proto_array_.pointer_begin() + 2);
+  EXPECT_TRUE(iter != proto_array_.pointer_begin() + 3);
+  EXPECT_TRUE(iter != proto_array_.pointer_end());
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, UninitializedConstPtrIterator) {
+  RepeatedPtrField<string>::const_pointer_iterator iter;
+  EXPECT_TRUE(iter != const_proto_array_->pointer_begin());
+  EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 1);
+  EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 2);
+  EXPECT_TRUE(iter != const_proto_array_->pointer_begin() + 3);
+  EXPECT_TRUE(iter != const_proto_array_->pointer_end());
+}
+
+// This comparison functor is required by the tests for RepeatedPtrOverPtrs.
+// They operate on strings and need to compare strings as strings in
+// any stl algorithm, even though the iterator returns a pointer to a string
+// - i.e. *iter has type string*.
+struct StringLessThan {
+  bool operator()(const string* z, const string& y) {
+    return *z < y;
+  }
+  bool operator()(const string* z, const string* y) const { return *z < *y; }
+};
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrSTLAlgorithms_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>::pointer_iterator it =
+        lower_bound(proto_array_.pointer_begin(), proto_array_.pointer_end(),
+                    &v, StringLessThan());
+
+    GOOGLE_CHECK(*it != NULL);
+
+    EXPECT_EQ(**it, "n");
+    EXPECT_TRUE(it == proto_array_.pointer_begin() + 3);
+  }
+  {
+    string v = "f";
+    RepeatedPtrField<string>::const_pointer_iterator it =
+        lower_bound(const_proto_array_->pointer_begin(),
+                    const_proto_array_->pointer_end(),
+                    &v, StringLessThan());
+
+    GOOGLE_CHECK(*it != NULL);
+
+    EXPECT_EQ(**it, "n");
+    EXPECT_TRUE(it == const_proto_array_->pointer_begin() + 3);
+  }
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, PtrMutation) {
+  RepeatedPtrField<string>::pointer_iterator iter =
+      proto_array_.pointer_begin();
+  **iter = "qux";
+  EXPECT_EQ("qux", proto_array_.Get(0));
+
+  EXPECT_EQ("bar", proto_array_.Get(1));
+  EXPECT_EQ("baz", proto_array_.Get(2));
+  ++iter;
+  delete *iter;
+  *iter = new string("a");
+  ++iter;
+  delete *iter;
+  *iter = new string("b");
+  EXPECT_EQ("a", proto_array_.Get(1));
+  EXPECT_EQ("b", proto_array_.Get(2));
+}
+
+TEST_F(RepeatedPtrFieldPtrsIteratorTest, Sort) {
+  proto_array_.Add()->assign("c");
+  proto_array_.Add()->assign("d");
+  proto_array_.Add()->assign("n");
+  proto_array_.Add()->assign("p");
+  proto_array_.Add()->assign("a");
+  proto_array_.Add()->assign("y");
+  proto_array_.Add()->assign("x");
+  EXPECT_EQ("foo", proto_array_.Get(0));
+  EXPECT_EQ("n", proto_array_.Get(5));
+  EXPECT_EQ("x", proto_array_.Get(9));
+  sort(proto_array_.pointer_begin(),
+       proto_array_.pointer_end(),
+       StringLessThan());
+  EXPECT_EQ("a", proto_array_.Get(0));
+  EXPECT_EQ("baz", proto_array_.Get(2));
+  EXPECT_EQ("y", proto_array_.Get(9));
+}
+
+
+// -----------------------------------------------------------------------------
+// Unit-tests for the insert iterators
+// google::protobuf::RepeatedFieldBackInserter,
+// google::protobuf::AllocatedRepeatedPtrFieldBackInserter
+// Ported from util/gtl/proto-array-iterators_unittest.
+
+class RepeatedFieldInsertionIteratorsTest : public testing::Test {
+ protected:
+  std::list<double> halves;
+  std::list<int> fibonacci;
+  std::vector<string> words;
+  typedef TestAllTypes::NestedMessage Nested;
+  Nested nesteds[2];
+  std::vector<Nested*> nested_ptrs;
+  TestAllTypes protobuffer;
+
+  virtual void SetUp() {
+    fibonacci.push_back(1);
+    fibonacci.push_back(1);
+    fibonacci.push_back(2);
+    fibonacci.push_back(3);
+    fibonacci.push_back(5);
+    fibonacci.push_back(8);
+    std::copy(fibonacci.begin(), fibonacci.end(),
+              RepeatedFieldBackInserter(protobuffer.mutable_repeated_int32()));
+
+    halves.push_back(1.0);
+    halves.push_back(0.5);
+    halves.push_back(0.25);
+    halves.push_back(0.125);
+    halves.push_back(0.0625);
+    std::copy(halves.begin(), halves.end(),
+              RepeatedFieldBackInserter(protobuffer.mutable_repeated_double()));
+
+    words.push_back("Able");
+    words.push_back("was");
+    words.push_back("I");
+    words.push_back("ere");
+    words.push_back("I");
+    words.push_back("saw");
+    words.push_back("Elba");
+    std::copy(words.begin(), words.end(),
+              RepeatedFieldBackInserter(protobuffer.mutable_repeated_string()));
+
+    nesteds[0].set_bb(17);
+    nesteds[1].set_bb(4711);
+    std::copy(&nesteds[0], &nesteds[2],
+              RepeatedFieldBackInserter(
+                  protobuffer.mutable_repeated_nested_message()));
+
+    nested_ptrs.push_back(new Nested);
+    nested_ptrs.back()->set_bb(170);
+    nested_ptrs.push_back(new Nested);
+    nested_ptrs.back()->set_bb(47110);
+    std::copy(nested_ptrs.begin(), nested_ptrs.end(),
+              RepeatedFieldBackInserter(
+                  protobuffer.mutable_repeated_nested_message()));
+
+  }
+
+  virtual void TearDown() {
+    STLDeleteContainerPointers(nested_ptrs.begin(), nested_ptrs.end());
+  }
+};
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Fibonacci) {
+  EXPECT_TRUE(std::equal(fibonacci.begin(),
+                         fibonacci.end(),
+                         protobuffer.repeated_int32().begin()));
+  EXPECT_TRUE(std::equal(protobuffer.repeated_int32().begin(),
+                         protobuffer.repeated_int32().end(),
+                         fibonacci.begin()));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) {
+  EXPECT_TRUE(std::equal(halves.begin(),
+                         halves.end(),
+                         protobuffer.repeated_double().begin()));
+  EXPECT_TRUE(std::equal(protobuffer.repeated_double().begin(),
+                         protobuffer.repeated_double().end(),
+                         halves.begin()));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Words) {
+  ASSERT_EQ(words.size(), protobuffer.repeated_string_size());
+  for (int i = 0; i < words.size(); ++i)
+    EXPECT_EQ(words.at(i), protobuffer.repeated_string(i));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Words2) {
+  words.clear();
+  words.push_back("sing");
+  words.push_back("a");
+  words.push_back("song");
+  words.push_back("of");
+  words.push_back("six");
+  words.push_back("pence");
+  protobuffer.mutable_repeated_string()->Clear();
+  std::copy(words.begin(), words.end(), RepeatedPtrFieldBackInserter(
+      protobuffer.mutable_repeated_string()));
+  ASSERT_EQ(words.size(), protobuffer.repeated_string_size());
+  for (int i = 0; i < words.size(); ++i)
+    EXPECT_EQ(words.at(i), protobuffer.repeated_string(i));
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest, Nesteds) {
+  ASSERT_EQ(protobuffer.repeated_nested_message_size(), 4);
+  EXPECT_EQ(protobuffer.repeated_nested_message(0).bb(), 17);
+  EXPECT_EQ(protobuffer.repeated_nested_message(1).bb(), 4711);
+  EXPECT_EQ(protobuffer.repeated_nested_message(2).bb(), 170);
+  EXPECT_EQ(protobuffer.repeated_nested_message(3).bb(), 47110);
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest,
+       AllocatedRepeatedPtrFieldWithStringIntData) {
+  vector<Nested*> data;
+  TestAllTypes goldenproto;
+  for (int i = 0; i < 10; ++i) {
+    Nested* new_data = new Nested;
+    new_data->set_bb(i);
+    data.push_back(new_data);
+
+    new_data = goldenproto.add_repeated_nested_message();
+    new_data->set_bb(i);
+  }
+  TestAllTypes testproto;
+  copy(data.begin(), data.end(),
+       AllocatedRepeatedPtrFieldBackInserter(
+           testproto.mutable_repeated_nested_message()));
+  EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
+}
+
+TEST_F(RepeatedFieldInsertionIteratorsTest,
+       AllocatedRepeatedPtrFieldWithString) {
+  vector<string*> data;
+  TestAllTypes goldenproto;
+  for (int i = 0; i < 10; ++i) {
+    string* new_data = new string;
+    *new_data = "name-" + SimpleItoa(i);
+    data.push_back(new_data);
+
+    new_data = goldenproto.add_repeated_string();
+    *new_data = "name-" + SimpleItoa(i);
+  }
+  TestAllTypes testproto;
+  copy(data.begin(), data.end(),
+       AllocatedRepeatedPtrFieldBackInserter(
+           testproto.mutable_repeated_string()));
+  EXPECT_EQ(testproto.DebugString(), goldenproto.DebugString());
+}
+
+}  // namespace
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/service.cc b/protobuf/src/google/protobuf/service.cc
new file mode 100644
index 0000000..ffa919d
--- /dev/null
+++ b/protobuf/src/google/protobuf/service.cc
@@ -0,0 +1,46 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/protobuf/src/google/protobuf/service.h b/protobuf/src/google/protobuf/service.h
new file mode 100644
index 0000000..cc0b45d
--- /dev/null
+++ b/protobuf/src/google/protobuf/service.h
@@ -0,0 +1,291 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// DEPRECATED:  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.  Starting with version 2.3.0, RPC implementations should
+// not try to build on these, but should instead provide code generator plugins
+// which generate code specific to the particular RPC implementation.  This way
+// the generated code can be more appropriate for the implementation in use
+// and can avoid unnecessary layers of indirection.
+//
+//
+// 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 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/protobuf/src/google/protobuf/stubs/atomicops.h b/protobuf/src/google/protobuf/stubs/atomicops.h
new file mode 100644
index 0000000..b1336e3
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops.h
@@ -0,0 +1,227 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The routines exported by this module are subtle.  If you use them, even if
+// you get the code right, it will depend on careful reasoning about atomicity
+// and memory ordering; it will be less readable, and harder to maintain.  If
+// you plan to use these routines, you should have a good reason, such as solid
+// evidence that performance would otherwise suffer, or there being no
+// alternative.  You should assume only properties explicitly guaranteed by the
+// specifications in this file.  You are almost certainly _not_ writing code
+// just for the x86; if you assume x86 semantics, x86 hardware bugs and
+// implementations on other archtectures will cause your code to break.  If you
+// do not know what you are doing, avoid these routines, and use a Mutex.
+//
+// It is incorrect to make direct assignments to/from an atomic variable.
+// You should use one of the Load or Store routines.  The NoBarrier
+// versions are provided when no barriers are needed:
+//   NoBarrier_Store()
+//   NoBarrier_Load()
+// Although there are currently no compiler enforcement, you are encouraged
+// to use these.
+
+// This header and the implementations for each platform (located in
+// atomicops_internals_*) must be kept in sync with the upstream code (V8).
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_H_
+
+// Don't include this file for people not concerned about thread safety.
+#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+#include <google/protobuf/stubs/platform_macros.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+typedef int32 Atomic32;
+#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
+// We need to be able to go between Atomic64 and AtomicWord implicitly.  This
+// means Atomic64 and AtomicWord should be the same type on 64-bit.
+#if defined(__ILP32__) || defined(GOOGLE_PROTOBUF_OS_NACL) || defined(GOOGLE_PROTOBUF_ARCH_SPARC)
+// NaCl's intptr_t is not actually 64-bits on 64-bit!
+// http://code.google.com/p/nativeclient/issues/detail?id=1162
+// sparcv9's pointer type is 32bits
+typedef int64 Atomic64;
+#else
+typedef intptr_t Atomic64;
+#endif
+#endif
+
+// Use AtomicWord for a machine-sized pointer.  It will use the Atomic32 or
+// Atomic64 routines below, depending on your architecture.
+typedef intptr_t AtomicWord;
+
+// Atomically execute:
+//      result = *ptr;
+//      if (*ptr == old_value)
+//        *ptr = new_value;
+//      return result;
+//
+// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
+// Always return the old value of "*ptr"
+//
+// This routine implies no memory barriers.
+Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                  Atomic32 old_value,
+                                  Atomic32 new_value);
+
+// Atomically store new_value into *ptr, returning the previous value held in
+// *ptr.  This routine implies no memory barriers.
+Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
+
+// Atomically increment *ptr by "increment".  Returns the new value of
+// *ptr with the increment applied.  This routine implies no memory barriers.
+Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment);
+
+Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                 Atomic32 increment);
+
+// These following lower-level operations are typically useful only to people
+// implementing higher-level synchronization operations like spinlocks,
+// mutexes, and condition-variables.  They combine CompareAndSwap(), a load, or
+// a store with appropriate memory-ordering instructions.  "Acquire" operations
+// ensure that no later memory access can be reordered ahead of the operation.
+// "Release" operations ensure that no previous memory access can be reordered
+// after the operation.  "Barrier" operations have both "Acquire" and "Release"
+// semantics.   A MemoryBarrier() has "Barrier" semantics, but does no memory
+// access.
+Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                Atomic32 old_value,
+                                Atomic32 new_value);
+Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                Atomic32 old_value,
+                                Atomic32 new_value);
+
+#if defined(__MINGW32__) && defined(MemoryBarrier)
+#undef MemoryBarrier
+#endif
+void MemoryBarrier();
+void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value);
+void Acquire_Store(volatile Atomic32* ptr, Atomic32 value);
+void Release_Store(volatile Atomic32* ptr, Atomic32 value);
+
+Atomic32 NoBarrier_Load(volatile const Atomic32* ptr);
+Atomic32 Acquire_Load(volatile const Atomic32* ptr);
+Atomic32 Release_Load(volatile const Atomic32* ptr);
+
+// 64-bit atomic operations (only available on 64-bit processors).
+#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
+Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                  Atomic64 old_value,
+                                  Atomic64 new_value);
+Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value);
+Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
+Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment);
+
+Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+                                Atomic64 old_value,
+                                Atomic64 new_value);
+Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+                                Atomic64 old_value,
+                                Atomic64 new_value);
+void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value);
+void Acquire_Store(volatile Atomic64* ptr, Atomic64 value);
+void Release_Store(volatile Atomic64* ptr, Atomic64 value);
+Atomic64 NoBarrier_Load(volatile const Atomic64* ptr);
+Atomic64 Acquire_Load(volatile const Atomic64* ptr);
+Atomic64 Release_Load(volatile const Atomic64* ptr);
+#endif  // GOOGLE_PROTOBUF_ARCH_64_BIT
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+// Include our platform specific implementation.
+#define GOOGLE_PROTOBUF_ATOMICOPS_ERROR \
+#error "Atomic operations are not supported on your platform"
+
+// ThreadSanitizer, http://clang.llvm.org/docs/ThreadSanitizer.html.
+#if defined(THREAD_SANITIZER)
+#include <google/protobuf/stubs/atomicops_internals_tsan.h>
+// MSVC.
+#elif defined(_MSC_VER)
+#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
+#include <google/protobuf/stubs/atomicops_internals_x86_msvc.h>
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+
+// Solaris
+#elif defined(GOOGLE_PROTOBUF_OS_SOLARIS)
+#include <google/protobuf/stubs/atomicops_internals_solaris.h>
+
+// Apple.
+#elif defined(GOOGLE_PROTOBUF_OS_APPLE)
+#include <google/protobuf/stubs/atomicops_internals_macosx.h>
+
+// GCC.
+#elif defined(__GNUC__)
+#if defined(GOOGLE_PROTOBUF_ARCH_IA32) || defined(GOOGLE_PROTOBUF_ARCH_X64)
+#include <google/protobuf/stubs/atomicops_internals_x86_gcc.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_ARM) && defined(__linux__)
+#include <google/protobuf/stubs/atomicops_internals_arm_gcc.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_AARCH64)
+#include <google/protobuf/stubs/atomicops_internals_arm64_gcc.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_ARM_QNX)
+#include <google/protobuf/stubs/atomicops_internals_arm_qnx.h>
+#elif defined(GOOGLE_PROTOBUF_ARCH_MIPS) || defined(GOOGLE_PROTOBUF_ARCH_MIPS64)
+#include <google/protobuf/stubs/atomicops_internals_mips_gcc.h>
+#elif defined(__native_client__)
+#include <google/protobuf/stubs/atomicops_internals_pnacl.h>
+#elif (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
+#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
+#elif defined(__clang__)
+#if __has_extension(c_atomic)
+#include <google/protobuf/stubs/atomicops_internals_generic_gcc.h>
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+
+// Unknown.
+#else
+GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+#endif
+
+// On some platforms we need additional declarations to make AtomicWord
+// compatible with our other Atomic* types.
+#if defined(GOOGLE_PROTOBUF_OS_APPLE)
+#include <google/protobuf/stubs/atomicops_internals_atomicword_compat.h>
+#endif
+
+#undef GOOGLE_PROTOBUF_ATOMICOPS_ERROR
+
+#endif  // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
new file mode 100644
index 0000000..0a2d2b8
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h
@@ -0,0 +1,325 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline void MemoryBarrier() {
+  __asm__ __volatile__ ("dmb ish" ::: "memory");  // NOLINT
+}
+
+// NoBarrier versions of the operation include "memory" in the clobber list.
+// This is not required for direct usage of the NoBarrier versions of the
+// operations. However this is required for correctness when they are used as
+// part of the Acquire or Release versions, to ensure that nothing from outside
+// the call is reordered between the operation and the memory barrier. This does
+// not change the code generated, so has no or minimal impact on the
+// NoBarrier operations.
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  Atomic32 prev;
+  int32_t temp;
+
+  __asm__ __volatile__ (  // NOLINT
+    "0:                                    \n\t"
+    "ldxr %w[prev], %[ptr]                 \n\t"  // Load the previous value.
+    "cmp %w[prev], %w[old_value]           \n\t"
+    "bne 1f                                \n\t"
+    "stxr %w[temp], %w[new_value], %[ptr]  \n\t"  // Try to store the new value.
+    "cbnz %w[temp], 0b                     \n\t"  // Retry if it did not work.
+    "1:                                    \n\t"
+    : [prev]"=&r" (prev),
+      [temp]"=&r" (temp),
+      [ptr]"+Q" (*ptr)
+    : [old_value]"IJr" (old_value),
+      [new_value]"r" (new_value)
+    : "cc", "memory"
+  );  // NOLINT
+
+  return prev;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                         Atomic32 new_value) {
+  Atomic32 result;
+  int32_t temp;
+
+  __asm__ __volatile__ (  // NOLINT
+    "0:                                    \n\t"
+    "ldxr %w[result], %[ptr]               \n\t"  // Load the previous value.
+    "stxr %w[temp], %w[new_value], %[ptr]  \n\t"  // Try to store the new value.
+    "cbnz %w[temp], 0b                     \n\t"  // Retry if it did not work.
+    : [result]"=&r" (result),
+      [temp]"=&r" (temp),
+      [ptr]"+Q" (*ptr)
+    : [new_value]"r" (new_value)
+    : "memory"
+  );  // NOLINT
+
+  return result;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  Atomic32 result;
+  int32_t temp;
+
+  __asm__ __volatile__ (  // NOLINT
+    "0:                                       \n\t"
+    "ldxr %w[result], %[ptr]                  \n\t"  // Load the previous value.
+    "add %w[result], %w[result], %w[increment]\n\t"
+    "stxr %w[temp], %w[result], %[ptr]        \n\t"  // Try to store the result.
+    "cbnz %w[temp], 0b                        \n\t"  // Retry on failure.
+    : [result]"=&r" (result),
+      [temp]"=&r" (temp),
+      [ptr]"+Q" (*ptr)
+    : [increment]"IJr" (increment)
+    : "memory"
+  );  // NOLINT
+
+  return result;
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                        Atomic32 increment) {
+  MemoryBarrier();
+  Atomic32 result = NoBarrier_AtomicIncrement(ptr, increment);
+  MemoryBarrier();
+
+  return result;
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  MemoryBarrier();
+
+  return prev;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  MemoryBarrier();
+  Atomic32 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+
+  return prev;
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  __asm__ __volatile__ (  // NOLINT
+    "stlr %w[value], %[ptr]  \n\t"
+    : [ptr]"=Q" (*ptr)
+    : [value]"r" (value)
+    : "memory"
+  );  // NOLINT
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+  return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  Atomic32 value;
+
+  __asm__ __volatile__ (  // NOLINT
+    "ldar %w[value], %[ptr]  \n\t"
+    : [value]"=r" (value)
+    : [ptr]"Q" (*ptr)
+    : "memory"
+  );  // NOLINT
+
+  return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+// 64-bit versions of the operations.
+// See the 32-bit versions for comments.
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                         Atomic64 old_value,
+                                         Atomic64 new_value) {
+  Atomic64 prev;
+  int32_t temp;
+
+  __asm__ __volatile__ (  // NOLINT
+    "0:                                    \n\t"
+    "ldxr %[prev], %[ptr]                  \n\t"
+    "cmp %[prev], %[old_value]             \n\t"
+    "bne 1f                                \n\t"
+    "stxr %w[temp], %[new_value], %[ptr]   \n\t"
+    "cbnz %w[temp], 0b                     \n\t"
+    "1:                                    \n\t"
+    : [prev]"=&r" (prev),
+      [temp]"=&r" (temp),
+      [ptr]"+Q" (*ptr)
+    : [old_value]"IJr" (old_value),
+      [new_value]"r" (new_value)
+    : "cc", "memory"
+  );  // NOLINT
+
+  return prev;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+                                         Atomic64 new_value) {
+  Atomic64 result;
+  int32_t temp;
+
+  __asm__ __volatile__ (  // NOLINT
+    "0:                                    \n\t"
+    "ldxr %[result], %[ptr]                \n\t"
+    "stxr %w[temp], %[new_value], %[ptr]   \n\t"
+    "cbnz %w[temp], 0b                     \n\t"
+    : [result]"=&r" (result),
+      [temp]"=&r" (temp),
+      [ptr]"+Q" (*ptr)
+    : [new_value]"r" (new_value)
+    : "memory"
+  );  // NOLINT
+
+  return result;
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+                                          Atomic64 increment) {
+  Atomic64 result;
+  int32_t temp;
+
+  __asm__ __volatile__ (  // NOLINT
+    "0:                                     \n\t"
+    "ldxr %[result], %[ptr]                 \n\t"
+    "add %[result], %[result], %[increment] \n\t"
+    "stxr %w[temp], %[result], %[ptr]       \n\t"
+    "cbnz %w[temp], 0b                      \n\t"
+    : [result]"=&r" (result),
+      [temp]"=&r" (temp),
+      [ptr]"+Q" (*ptr)
+    : [increment]"IJr" (increment)
+    : "memory"
+  );  // NOLINT
+
+  return result;
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+                                        Atomic64 increment) {
+  MemoryBarrier();
+  Atomic64 result = NoBarrier_AtomicIncrement(ptr, increment);
+  MemoryBarrier();
+
+  return result;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  MemoryBarrier();
+
+  return prev;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  MemoryBarrier();
+  Atomic64 prev = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+
+  return prev;
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+  __asm__ __volatile__ (  // NOLINT
+    "stlr %x[value], %[ptr]  \n\t"
+    : [ptr]"=Q" (*ptr)
+    : [value]"r" (value)
+    : "memory"
+  );  // NOLINT
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+  return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+  Atomic64 value;
+
+  __asm__ __volatile__ (  // NOLINT
+    "ldar %x[value], %[ptr]  \n\t"
+    : [value]"=r" (value)
+    : [ptr]"Q" (*ptr)
+    : "memory"
+  );  // NOLINT
+
+  return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM64_GCC_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
new file mode 100644
index 0000000..90e727b
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h
@@ -0,0 +1,151 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+//
+// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// 0xffff0fc0 is the hard coded address of a function provided by
+// the kernel which implements an atomic compare-exchange. On older
+// ARM architecture revisions (pre-v6) this may be implemented using
+// a syscall. This address is stable, and in active use (hard coded)
+// by at least glibc-2.7 and the Android C library.
+typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value,
+                                           Atomic32 new_value,
+                                           volatile Atomic32* ptr);
+LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) =
+    (LinuxKernelCmpxchgFunc) 0xffff0fc0;
+
+typedef void (*LinuxKernelMemoryBarrierFunc)(void);
+LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) =
+    (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
+
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  Atomic32 prev_value = *ptr;
+  do {
+    if (!pLinuxKernelCmpxchg(old_value, new_value,
+                             const_cast<Atomic32*>(ptr))) {
+      return old_value;
+    }
+    prev_value = *ptr;
+  } while (prev_value == old_value);
+  return prev_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                         Atomic32 new_value) {
+  Atomic32 old_value;
+  do {
+    old_value = *ptr;
+  } while (pLinuxKernelCmpxchg(old_value, new_value,
+                               const_cast<Atomic32*>(ptr)));
+  return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                        Atomic32 increment) {
+  for (;;) {
+    // Atomic exchange the old value with an incremented one.
+    Atomic32 old_value = *ptr;
+    Atomic32 new_value = old_value + increment;
+    if (pLinuxKernelCmpxchg(old_value, new_value,
+                            const_cast<Atomic32*>(ptr)) == 0) {
+      // The exchange took place as expected.
+      return new_value;
+    }
+    // Otherwise, *ptr changed mid-loop and we need to retry.
+  }
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+}
+
+inline void MemoryBarrier() {
+  pLinuxKernelMemoryBarrier();
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  MemoryBarrier();
+  *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+  return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  Atomic32 value = *ptr;
+  MemoryBarrier();
+  return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_GCC_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h
new file mode 100644
index 0000000..17dfaa5
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h
@@ -0,0 +1,146 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
+
+// For _smp_cmpxchg()
+#include <pthread.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 QNXCmpxchg(Atomic32 old_value,
+                           Atomic32 new_value,
+                           volatile Atomic32* ptr) {
+  return static_cast<Atomic32>(
+      _smp_cmpxchg((volatile unsigned *)ptr,
+                   (unsigned)old_value,
+                   (unsigned)new_value));
+}
+
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  Atomic32 prev_value = *ptr;
+  do {
+    if (!QNXCmpxchg(old_value, new_value,
+                    const_cast<Atomic32*>(ptr))) {
+      return old_value;
+    }
+    prev_value = *ptr;
+  } while (prev_value == old_value);
+  return prev_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                         Atomic32 new_value) {
+  Atomic32 old_value;
+  do {
+    old_value = *ptr;
+  } while (QNXCmpxchg(old_value, new_value,
+                      const_cast<Atomic32*>(ptr)));
+  return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                        Atomic32 increment) {
+  for (;;) {
+    // Atomic exchange the old value with an incremented one.
+    Atomic32 old_value = *ptr;
+    Atomic32 new_value = old_value + increment;
+    if (QNXCmpxchg(old_value, new_value,
+                   const_cast<Atomic32*>(ptr)) == 0) {
+      // The exchange took place as expected.
+      return new_value;
+    }
+    // Otherwise, *ptr changed mid-loop and we need to retry.
+  }
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+}
+
+inline void MemoryBarrier() {
+  __sync_synchronize();
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  MemoryBarrier();
+  *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+  return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  Atomic32 value = *ptr;
+  MemoryBarrier();
+  return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ARM_QNX_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
new file mode 100644
index 0000000..eb198ff
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h
@@ -0,0 +1,122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
+
+// AtomicWord is a synonym for intptr_t, and Atomic32 is a synonym for int32,
+// which in turn means int. On some LP32 platforms, intptr_t is an int, but
+// on others, it's a long. When AtomicWord and Atomic32 are based on different
+// fundamental types, their pointers are incompatible.
+//
+// This file defines function overloads to allow both AtomicWord and Atomic32
+// data to be used with this interface.
+//
+// On LP64 platforms, AtomicWord and Atomic64 are both always long,
+// so this problem doesn't occur.
+
+#if !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline AtomicWord NoBarrier_CompareAndSwap(volatile AtomicWord* ptr,
+                                           AtomicWord old_value,
+                                           AtomicWord new_value) {
+  return NoBarrier_CompareAndSwap(
+      reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline AtomicWord NoBarrier_AtomicExchange(volatile AtomicWord* ptr,
+                                           AtomicWord new_value) {
+  return NoBarrier_AtomicExchange(
+      reinterpret_cast<volatile Atomic32*>(ptr), new_value);
+}
+
+inline AtomicWord NoBarrier_AtomicIncrement(volatile AtomicWord* ptr,
+                                            AtomicWord increment) {
+  return NoBarrier_AtomicIncrement(
+      reinterpret_cast<volatile Atomic32*>(ptr), increment);
+}
+
+inline AtomicWord Barrier_AtomicIncrement(volatile AtomicWord* ptr,
+                                          AtomicWord increment) {
+  return Barrier_AtomicIncrement(
+      reinterpret_cast<volatile Atomic32*>(ptr), increment);
+}
+
+inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
+                                         AtomicWord old_value,
+                                         AtomicWord new_value) {
+  return Acquire_CompareAndSwap(
+      reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
+                                         AtomicWord old_value,
+                                         AtomicWord new_value) {
+  return Release_CompareAndSwap(
+      reinterpret_cast<volatile Atomic32*>(ptr), old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile AtomicWord *ptr, AtomicWord value) {
+  NoBarrier_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
+  return Acquire_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
+  return Release_Store(reinterpret_cast<volatile Atomic32*>(ptr), value);
+}
+
+inline AtomicWord NoBarrier_Load(volatile const AtomicWord *ptr) {
+  return NoBarrier_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
+  return Acquire_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
+  return Release_Load(reinterpret_cast<volatile const Atomic32*>(ptr));
+}
+
+}   // namespace internal
+}   // namespace protobuf
+}   // namespace google
+
+#endif  // !defined(GOOGLE_PROTOBUF_ARCH_64_BIT)
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_ATOMICWORD_COMPAT_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
new file mode 100644
index 0000000..dd7abf6
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
@@ -0,0 +1,137 @@
+// Copyright 2013 Red Hat 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 Red Hat 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 an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+                              __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+  return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                         Atomic32 new_value) {
+  return __atomic_exchange_n(ptr, new_value, __ATOMIC_RELAXED);
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  return __atomic_add_fetch(ptr, increment, __ATOMIC_RELAXED);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                        Atomic32 increment) {
+  return __atomic_add_fetch(ptr, increment, __ATOMIC_SEQ_CST);
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  __atomic_compare_exchange(ptr, &old_value, &new_value, true,
+                            __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+  return old_value;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+                              __ATOMIC_RELEASE, __ATOMIC_ACQUIRE);
+  return old_value;
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  __atomic_store_n(ptr, value, __ATOMIC_RELAXED);
+}
+
+inline void MemoryBarrier() {
+  __sync_synchronize();
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST);
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  __atomic_store_n(ptr, value, __ATOMIC_RELEASE);
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+  return __atomic_load_n(ptr, __ATOMIC_RELAXED);
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
+}
+
+#ifdef __LP64__
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+  __atomic_store_n(ptr, value, __ATOMIC_RELEASE);
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+  return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+                              __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
+  return old_value;
+}
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                         Atomic64 old_value,
+                                         Atomic64 new_value) {
+  __atomic_compare_exchange_n(ptr, &old_value, new_value, true,
+                              __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+  return old_value;
+}
+
+#endif // defined(__LP64__)
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_GENERIC_GCC_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h
new file mode 100644
index 0000000..7963324
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h
@@ -0,0 +1,225 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
+
+#include <libkern/OSAtomic.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  Atomic32 prev_value;
+  do {
+    if (OSAtomicCompareAndSwap32(old_value, new_value,
+                                 const_cast<Atomic32*>(ptr))) {
+      return old_value;
+    }
+    prev_value = *ptr;
+  } while (prev_value == old_value);
+  return prev_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                         Atomic32 new_value) {
+  Atomic32 old_value;
+  do {
+    old_value = *ptr;
+  } while (!OSAtomicCompareAndSwap32(old_value, new_value,
+                                     const_cast<Atomic32*>(ptr)));
+  return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr));
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));
+}
+
+inline void MemoryBarrier() {
+  OSMemoryBarrier();
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  Atomic32 prev_value;
+  do {
+    if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,
+                                        const_cast<Atomic32*>(ptr))) {
+      return old_value;
+    }
+    prev_value = *ptr;
+  } while (prev_value == old_value);
+  return prev_value;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  return Acquire_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  MemoryBarrier();
+  *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+  return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  Atomic32 value = *ptr;
+  MemoryBarrier();
+  return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+#ifdef __LP64__
+
+// 64-bit implementation on 64-bit platform
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                         Atomic64 old_value,
+                                         Atomic64 new_value) {
+  Atomic64 prev_value;
+  do {
+    if (OSAtomicCompareAndSwap64(old_value, new_value,
+                                 reinterpret_cast<volatile int64_t*>(ptr))) {
+      return old_value;
+    }
+    prev_value = *ptr;
+  } while (prev_value == old_value);
+  return prev_value;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+                                         Atomic64 new_value) {
+  Atomic64 old_value;
+  do {
+    old_value = *ptr;
+  } while (!OSAtomicCompareAndSwap64(old_value, new_value,
+                                     reinterpret_cast<volatile int64_t*>(ptr)));
+  return old_value;
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+                                          Atomic64 increment) {
+  return OSAtomicAdd64(increment, reinterpret_cast<volatile int64_t*>(ptr));
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+                                        Atomic64 increment) {
+  return OSAtomicAdd64Barrier(increment,
+                              reinterpret_cast<volatile int64_t*>(ptr));
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  Atomic64 prev_value;
+  do {
+    if (OSAtomicCompareAndSwap64Barrier(
+        old_value, new_value, reinterpret_cast<volatile int64_t*>(ptr))) {
+      return old_value;
+    }
+    prev_value = *ptr;
+  } while (prev_value == old_value);
+  return prev_value;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  // The lib kern interface does not distinguish between
+  // Acquire and Release memory barriers; they are equivalent.
+  return Acquire_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+  MemoryBarrier();
+  *ptr = value;
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+  return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+  Atomic64 value = *ptr;
+  MemoryBarrier();
+  return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+#endif  // defined(__LP64__)
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MACOSX_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
new file mode 100644
index 0000000..e3cd14c
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h
@@ -0,0 +1,313 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
+
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Atomically execute:
+//      result = *ptr;
+//      if (*ptr == old_value)
+//        *ptr = new_value;
+//      return result;
+//
+// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
+// Always return the old value of "*ptr"
+//
+// This routine implies no memory barriers.
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  Atomic32 prev, tmp;
+  __asm__ __volatile__(".set push\n"
+                       ".set noreorder\n"
+                       "1:\n"
+                       "ll %0, %5\n"  // prev = *ptr
+                       "bne %0, %3, 2f\n"  // if (prev != old_value) goto 2
+                       "move %2, %4\n"  // tmp = new_value
+                       "sc %2, %1\n"  // *ptr = tmp (with atomic check)
+                       "beqz %2, 1b\n"  // start again on atomic error
+                       "nop\n"  // delay slot nop
+                       "2:\n"
+                       ".set pop\n"
+                       : "=&r" (prev), "=m" (*ptr), "=&r" (tmp)
+                       : "Ir" (old_value), "r" (new_value), "m" (*ptr)
+                       : "memory");
+  return prev;
+}
+
+// Atomically store new_value into *ptr, returning the previous value held in
+// *ptr.  This routine implies no memory barriers.
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                         Atomic32 new_value) {
+  Atomic32 temp, old;
+  __asm__ __volatile__(".set push\n"
+                       ".set noreorder\n"
+                       "1:\n"
+                       "ll %1, %4\n"  // old = *ptr
+                       "move %0, %3\n"  // temp = new_value
+                       "sc %0, %2\n"  // *ptr = temp (with atomic check)
+                       "beqz %0, 1b\n"  // start again on atomic error
+                       "nop\n"  // delay slot nop
+                       ".set pop\n"
+                       : "=&r" (temp), "=&r" (old), "=m" (*ptr)
+                       : "r" (new_value), "m" (*ptr)
+                       : "memory");
+
+  return old;
+}
+
+// Atomically increment *ptr by "increment".  Returns the new value of
+// *ptr with the increment applied.  This routine implies no memory barriers.
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  Atomic32 temp, temp2;
+
+  __asm__ __volatile__(".set push\n"
+                       ".set noreorder\n"
+                       "1:\n"
+                       "ll %0, %4\n"  // temp = *ptr
+                       "addu %1, %0, %3\n"  // temp2 = temp + increment
+                       "sc %1, %2\n"  // *ptr = temp2 (with atomic check)
+                       "beqz %1, 1b\n"  // start again on atomic error
+                       "addu %1, %0, %3\n"  // temp2 = temp + increment
+                       ".set pop\n"
+                       : "=&r" (temp), "=&r" (temp2), "=m" (*ptr)
+                       : "Ir" (increment), "m" (*ptr)
+                       : "memory");
+  // temp2 now holds the final value.
+  return temp2;
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                        Atomic32 increment) {
+  ATOMICOPS_COMPILER_BARRIER();
+  Atomic32 res = NoBarrier_AtomicIncrement(ptr, increment);
+  ATOMICOPS_COMPILER_BARRIER();
+  return res;
+}
+
+// "Acquire" operations
+// ensure that no later memory access can be reordered ahead of the operation.
+// "Release" operations ensure that no previous memory access can be reordered
+// after the operation.  "Barrier" operations have both "Acquire" and "Release"
+// semantics.   A MemoryBarrier() has "Barrier" semantics, but does no memory
+// access.
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  ATOMICOPS_COMPILER_BARRIER();
+  Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  ATOMICOPS_COMPILER_BARRIER();
+  return res;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  ATOMICOPS_COMPILER_BARRIER();
+  Atomic32 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  ATOMICOPS_COMPILER_BARRIER();
+  return res;
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+}
+
+inline void MemoryBarrier() {
+  __asm__ __volatile__("sync" : : : "memory");
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  MemoryBarrier();
+  *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+  return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  Atomic32 value = *ptr;
+  MemoryBarrier();
+  return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+#if defined(__LP64__)
+// 64-bit versions of the atomic ops.
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                         Atomic64 old_value,
+                                         Atomic64 new_value) {
+  Atomic64 prev, tmp;
+  __asm__ __volatile__(".set push\n"
+                       ".set noreorder\n"
+                       "1:\n"
+                       "lld %0, %5\n"  // prev = *ptr
+                       "bne %0, %3, 2f\n"  // if (prev != old_value) goto 2
+                       "move %2, %4\n"  // tmp = new_value
+                       "scd %2, %1\n"  // *ptr = tmp (with atomic check)
+                       "beqz %2, 1b\n"  // start again on atomic error
+                       "nop\n"  // delay slot nop
+                       "2:\n"
+                       ".set pop\n"
+                       : "=&r" (prev), "=m" (*ptr), "=&r" (tmp)
+                       : "Ir" (old_value), "r" (new_value), "m" (*ptr)
+                       : "memory");
+  return prev;
+}
+
+// Atomically store new_value into *ptr, returning the previous value held in
+// *ptr.  This routine implies no memory barriers.
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+                                         Atomic64 new_value) {
+  Atomic64 temp, old;
+  __asm__ __volatile__(".set push\n"
+                       ".set noreorder\n"
+                       "1:\n"
+                       "lld %1, %4\n"  // old = *ptr
+                       "move %0, %3\n"  // temp = new_value
+                       "scd %0, %2\n"  // *ptr = temp (with atomic check)
+                       "beqz %0, 1b\n"  // start again on atomic error
+                       "nop\n"  // delay slot nop
+                       ".set pop\n"
+                       : "=&r" (temp), "=&r" (old), "=m" (*ptr)
+                       : "r" (new_value), "m" (*ptr)
+                       : "memory");
+
+  return old;
+}
+
+// Atomically increment *ptr by "increment".  Returns the new value of
+// *ptr with the increment applied.  This routine implies no memory barriers.
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+                                          Atomic64 increment) {
+  Atomic64 temp, temp2;
+
+  __asm__ __volatile__(".set push\n"
+                       ".set noreorder\n"
+                       "1:\n"
+                       "lld %0, %4\n"  // temp = *ptr
+                       "daddu %1, %0, %3\n"  // temp2 = temp + increment
+                       "scd %1, %2\n"  // *ptr = temp2 (with atomic check)
+                       "beqz %1, 1b\n"  // start again on atomic error
+                       "daddu %1, %0, %3\n"  // temp2 = temp + increment
+                       ".set pop\n"
+                       : "=&r" (temp), "=&r" (temp2), "=m" (*ptr)
+                       : "Ir" (increment), "m" (*ptr)
+                       : "memory");
+  // temp2 now holds the final value.
+  return temp2;
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+                                        Atomic64 increment) {
+  MemoryBarrier();
+  Atomic64 res = NoBarrier_AtomicIncrement(ptr, increment);
+  MemoryBarrier();
+  return res;
+}
+
+// "Acquire" operations
+// ensure that no later memory access can be reordered ahead of the operation.
+// "Release" operations ensure that no previous memory access can be reordered
+// after the operation.  "Barrier" operations have both "Acquire" and "Release"
+// semantics.   A MemoryBarrier() has "Barrier" semantics, but does no memory
+// access.
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  Atomic64 res = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  MemoryBarrier();
+  return res;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  MemoryBarrier();
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+  MemoryBarrier();
+  *ptr = value;
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+  return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+  Atomic64 value = *ptr;
+  MemoryBarrier();
+  return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+#endif
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#undef ATOMICOPS_COMPILER_BARRIER
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_MIPS_GCC_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_pnacl.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_pnacl.h
new file mode 100644
index 0000000..b10ac02
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_pnacl.h
@@ -0,0 +1,73 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
+
+inline void MemoryBarrier() {
+  __sync_synchronize();
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  MemoryBarrier();
+  return ret;
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  MemoryBarrier();
+  *ptr = value;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  Atomic32 value = *ptr;
+  MemoryBarrier();
+  return value;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_solaris.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_solaris.h
new file mode 100644
index 0000000..d8057ec
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_solaris.h
@@ -0,0 +1,188 @@
+// Copyright 2014 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
+
+#include <atomic.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  return (Atomic32)atomic_cas_32((volatile uint32_t*)ptr, (uint32_t)old_value, (uint32_t)new_value);
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                         Atomic32 new_value) {
+  return (Atomic32)atomic_swap_32((volatile uint32_t*)ptr, (uint32_t)new_value);
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  return (Atomic32)atomic_add_32_nv((volatile uint32_t*)ptr, (uint32_t)increment);
+}
+
+inline void MemoryBarrier(void) {
+	membar_producer();
+	membar_consumer();
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                        Atomic32 increment) {
+  MemoryBarrier();
+  Atomic32 ret = NoBarrier_AtomicIncrement(ptr, increment);
+  MemoryBarrier();
+
+  return ret;
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  MemoryBarrier();
+
+  return ret;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  MemoryBarrier();
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+  membar_producer();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  membar_consumer();
+  *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+  return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  Atomic32 val = *ptr;
+  membar_consumer();
+  return val;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  membar_producer();
+  return *ptr;
+}
+
+#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                         Atomic64 old_value,
+                                         Atomic64 new_value) {
+  return atomic_cas_64((volatile uint64_t*)ptr, (uint64_t)old_value, (uint64_t)new_value);
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value) {
+  return atomic_swap_64((volatile uint64_t*)ptr, (uint64_t)new_value);
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) {
+  return atomic_add_64_nv((volatile uint64_t*)ptr, increment);
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) {
+  MemoryBarrier();
+  Atomic64 ret = atomic_add_64_nv((volatile uint64_t*)ptr, increment);
+  MemoryBarrier();
+  return ret;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  Atomic64 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  MemoryBarrier();
+  return ret;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  MemoryBarrier();
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+  membar_producer();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+  membar_consumer();
+  *ptr = value;
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+  return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+  Atomic64 ret = *ptr;
+  membar_consumer();
+  return ret;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+  membar_producer();
+  return *ptr;
+}
+#endif
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
+
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_tsan.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_tsan.h
new file mode 100644
index 0000000..0c90354
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_tsan.h
@@ -0,0 +1,219 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation for compiler-based
+// ThreadSanitizer (http://clang.llvm.org/docs/ThreadSanitizer.html).
+// Use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
+
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+#include <sanitizer/tsan_interface_atomic.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  Atomic32 cmp = old_value;
+  __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
+      __tsan_memory_order_relaxed, __tsan_memory_order_relaxed);
+  return cmp;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
+                                         Atomic32 new_value) {
+  return __tsan_atomic32_exchange(ptr, new_value,
+      __tsan_memory_order_relaxed);
+}
+
+inline Atomic32 Acquire_AtomicExchange(volatile Atomic32 *ptr,
+                                       Atomic32 new_value) {
+  return __tsan_atomic32_exchange(ptr, new_value,
+      __tsan_memory_order_acquire);
+}
+
+inline Atomic32 Release_AtomicExchange(volatile Atomic32 *ptr,
+                                       Atomic32 new_value) {
+  return __tsan_atomic32_exchange(ptr, new_value,
+      __tsan_memory_order_release);
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
+                                          Atomic32 increment) {
+  return increment + __tsan_atomic32_fetch_add(ptr, increment,
+      __tsan_memory_order_relaxed);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
+                                        Atomic32 increment) {
+  return increment + __tsan_atomic32_fetch_add(ptr, increment,
+      __tsan_memory_order_acq_rel);
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  Atomic32 cmp = old_value;
+  __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
+      __tsan_memory_order_acquire, __tsan_memory_order_acquire);
+  return cmp;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  Atomic32 cmp = old_value;
+  __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
+      __tsan_memory_order_release, __tsan_memory_order_relaxed);
+  return cmp;
+}
+
+inline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) {
+  __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
+}
+
+inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
+  __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
+  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
+}
+
+inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
+  __tsan_atomic32_store(ptr, value, __tsan_memory_order_release);
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) {
+  return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
+  return __tsan_atomic32_load(ptr, __tsan_memory_order_acquire);
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
+  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
+  return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
+}
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
+                                         Atomic64 old_value,
+                                         Atomic64 new_value) {
+  Atomic64 cmp = old_value;
+  __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
+      __tsan_memory_order_relaxed, __tsan_memory_order_relaxed);
+  return cmp;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
+                                         Atomic64 new_value) {
+  return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_relaxed);
+}
+
+inline Atomic64 Acquire_AtomicExchange(volatile Atomic64 *ptr,
+                                       Atomic64 new_value) {
+  return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_acquire);
+}
+
+inline Atomic64 Release_AtomicExchange(volatile Atomic64 *ptr,
+                                       Atomic64 new_value) {
+  return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_release);
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,
+                                          Atomic64 increment) {
+  return increment + __tsan_atomic64_fetch_add(ptr, increment,
+      __tsan_memory_order_relaxed);
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,
+                                        Atomic64 increment) {
+  return increment + __tsan_atomic64_fetch_add(ptr, increment,
+      __tsan_memory_order_acq_rel);
+}
+
+inline void NoBarrier_Store(volatile Atomic64 *ptr, Atomic64 value) {
+  __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed);
+}
+
+inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {
+  __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed);
+  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
+}
+
+inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
+  __tsan_atomic64_store(ptr, value, __tsan_memory_order_release);
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64 *ptr) {
+  return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed);
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
+  return __tsan_atomic64_load(ptr, __tsan_memory_order_acquire);
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
+  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
+  return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed);
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  Atomic64 cmp = old_value;
+  __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
+      __tsan_memory_order_acquire, __tsan_memory_order_acquire);
+  return cmp;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  Atomic64 cmp = old_value;
+  __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
+      __tsan_memory_order_release, __tsan_memory_order_relaxed);
+  return cmp;
+}
+
+inline void MemoryBarrier() {
+  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#undef ATOMICOPS_COMPILER_BARRIER
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc b/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
new file mode 100644
index 0000000..53c9eae
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc
@@ -0,0 +1,137 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This module gets enough CPU information to optimize the
+// atomicops module on x86.
+
+#include <cstring>
+
+#include <google/protobuf/stubs/atomicops.h>
+
+// This file only makes sense with atomicops_internals_x86_gcc.h -- it
+// depends on structs that are defined in that file.  If atomicops.h
+// doesn't sub-include that file, then we aren't needed, and shouldn't
+// try to do anything.
+#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
+
+// Inline cpuid instruction.  In PIC compilations, %ebx contains the address
+// of the global offset table.  To avoid breaking such executables, this code
+// must preserve that register's value across cpuid instructions.
+#if defined(__i386__)
+#define cpuid(a, b, c, d, inp) \
+  asm("mov %%ebx, %%edi\n"     \
+      "cpuid\n"                \
+      "xchg %%edi, %%ebx\n"    \
+      : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+#elif defined(__x86_64__)
+#define cpuid(a, b, c, d, inp) \
+  asm("mov %%rbx, %%rdi\n"     \
+      "cpuid\n"                \
+      "xchg %%rdi, %%rbx\n"    \
+      : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+#endif
+
+#if defined(cpuid)        // initialize the struct only on x86
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Set the flags so that code will run correctly and conservatively, so even
+// if we haven't been initialized yet, we're probably single threaded, and our
+// default values should hopefully be pretty safe.
+struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
+  false,          // bug can't exist before process spawns multiple threads
+  false,          // no SSE2
+};
+
+namespace {
+
+// Initialize the AtomicOps_Internalx86CPUFeatures struct.
+void AtomicOps_Internalx86CPUFeaturesInit() {
+  uint32_t eax;
+  uint32_t ebx;
+  uint32_t ecx;
+  uint32_t edx;
+
+  // Get vendor string (issue CPUID with eax = 0)
+  cpuid(eax, ebx, ecx, edx, 0);
+  char vendor[13];
+  memcpy(vendor, &ebx, 4);
+  memcpy(vendor + 4, &edx, 4);
+  memcpy(vendor + 8, &ecx, 4);
+  vendor[12] = 0;
+
+  // get feature flags in ecx/edx, and family/model in eax
+  cpuid(eax, ebx, ecx, edx, 1);
+
+  int family = (eax >> 8) & 0xf;        // family and model fields
+  int model = (eax >> 4) & 0xf;
+  if (family == 0xf) {                  // use extended family and model fields
+    family += (eax >> 20) & 0xff;
+    model += ((eax >> 16) & 0xf) << 4;
+  }
+
+  // Opteron Rev E has a bug in which on very rare occasions a locked
+  // instruction doesn't act as a read-acquire barrier if followed by a
+  // non-locked read-modify-write instruction.  Rev F has this bug in
+  // pre-release versions, but not in versions released to customers,
+  // so we test only for Rev E, which is family 15, model 32..63 inclusive.
+  if (strcmp(vendor, "AuthenticAMD") == 0 &&       // AMD
+      family == 15 &&
+      32 <= model && model <= 63) {
+    AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true;
+  } else {
+    AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false;
+  }
+
+  // edx bit 26 is SSE2 which we use to tell use whether we can use mfence
+  AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);
+}
+
+class AtomicOpsx86Initializer {
+ public:
+  AtomicOpsx86Initializer() {
+    AtomicOps_Internalx86CPUFeaturesInit();
+  }
+};
+
+// A global to get use initialized on startup via static initialization :/
+AtomicOpsx86Initializer g_initer;
+
+}  // namespace
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // __i386__
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
new file mode 100644
index 0000000..edccc59
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h
@@ -0,0 +1,293 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// This struct is not part of the public API of this module; clients may not
+// use it.
+// Features of this x86.  Values may not be correct before main() is run,
+// but are set conservatively.
+struct AtomicOps_x86CPUFeatureStruct {
+  bool has_amd_lock_mb_bug;  // Processor has AMD memory-barrier bug; do lfence
+                             // after acquire compare-and-swap.
+  bool has_sse2;             // Processor has SSE2.
+};
+extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures;
+
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+// 32-bit low-level operations on any platform.
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  Atomic32 prev;
+  __asm__ __volatile__("lock; cmpxchgl %1,%2"
+                       : "=a" (prev)
+                       : "q" (new_value), "m" (*ptr), "0" (old_value)
+                       : "memory");
+  return prev;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                         Atomic32 new_value) {
+  __asm__ __volatile__("xchgl %1,%0"  // The lock prefix is implicit for xchg.
+                       : "=r" (new_value)
+                       : "m" (*ptr), "0" (new_value)
+                       : "memory");
+  return new_value;  // Now it's the previous value.
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  Atomic32 temp = increment;
+  __asm__ __volatile__("lock; xaddl %0,%1"
+                       : "+r" (temp), "+m" (*ptr)
+                       : : "memory");
+  // temp now holds the old value of *ptr
+  return temp + increment;
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                        Atomic32 increment) {
+  Atomic32 temp = increment;
+  __asm__ __volatile__("lock; xaddl %0,%1"
+                       : "+r" (temp), "+m" (*ptr)
+                       : : "memory");
+  // temp now holds the old value of *ptr
+  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+    __asm__ __volatile__("lfence" : : : "memory");
+  }
+  return temp + increment;
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  Atomic32 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+    __asm__ __volatile__("lfence" : : : "memory");
+  }
+  return x;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+}
+
+#if defined(__x86_64__)
+
+// 64-bit implementations of memory barrier can be simpler, because it
+// "mfence" is guaranteed to exist.
+inline void MemoryBarrier() {
+  __asm__ __volatile__("mfence" : : : "memory");
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+#else
+
+inline void MemoryBarrier() {
+  if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
+    __asm__ __volatile__("mfence" : : : "memory");
+  } else {  // mfence is faster but not present on PIII
+    Atomic32 x = 0;
+    NoBarrier_AtomicExchange(&x, 0);  // acts as a barrier on PIII
+  }
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
+    *ptr = value;
+    __asm__ __volatile__("mfence" : : : "memory");
+  } else {
+    NoBarrier_AtomicExchange(ptr, value);
+                          // acts as a barrier on PIII
+  }
+}
+#endif
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  ATOMICOPS_COMPILER_BARRIER();
+  *ptr = value;  // An x86 store acts as a release barrier.
+  // See comments in Atomic64 version of Release_Store(), below.
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+  return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  Atomic32 value = *ptr;  // An x86 load acts as a acquire barrier.
+  // See comments in Atomic64 version of Release_Store(), below.
+  ATOMICOPS_COMPILER_BARRIER();
+  return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+#if defined(__x86_64__)
+
+// 64-bit low-level operations on 64-bit platform.
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                         Atomic64 old_value,
+                                         Atomic64 new_value) {
+  Atomic64 prev;
+  __asm__ __volatile__("lock; cmpxchgq %1,%2"
+                       : "=a" (prev)
+                       : "q" (new_value), "m" (*ptr), "0" (old_value)
+                       : "memory");
+  return prev;
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+                                         Atomic64 new_value) {
+  __asm__ __volatile__("xchgq %1,%0"  // The lock prefix is implicit for xchg.
+                       : "=r" (new_value)
+                       : "m" (*ptr), "0" (new_value)
+                       : "memory");
+  return new_value;  // Now it's the previous value.
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+                                          Atomic64 increment) {
+  Atomic64 temp = increment;
+  __asm__ __volatile__("lock; xaddq %0,%1"
+                       : "+r" (temp), "+m" (*ptr)
+                       : : "memory");
+  // temp now contains the previous value of *ptr
+  return temp + increment;
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+                                        Atomic64 increment) {
+  Atomic64 temp = increment;
+  __asm__ __volatile__("lock; xaddq %0,%1"
+                       : "+r" (temp), "+m" (*ptr)
+                       : : "memory");
+  // temp now contains the previous value of *ptr
+  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+    __asm__ __volatile__("lfence" : : : "memory");
+  }
+  return temp + increment;
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+  MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+  ATOMICOPS_COMPILER_BARRIER();
+
+  *ptr = value;  // An x86 store acts as a release barrier
+                 // for current AMD/Intel chips as of Jan 2008.
+                 // See also Acquire_Load(), below.
+
+  // When new chips come out, check:
+  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:
+  //  System Programming Guide, Chatper 7: Multiple-processor management,
+  //  Section 7.2, Memory Ordering.
+  // Last seen at:
+  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm
+  //
+  // x86 stores/loads fail to act as barriers for a few instructions (clflush
+  // maskmovdqu maskmovq movntdq movnti movntpd movntps movntq) but these are
+  // not generated by the compiler, and are rare.  Users of these instructions
+  // need to know about cache behaviour in any case since all of these involve
+  // either flushing cache lines or non-temporal cache hints.
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+  return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+  Atomic64 value = *ptr;  // An x86 load acts as a acquire barrier,
+                          // for current AMD/Intel chips as of Jan 2008.
+                          // See also Release_Store(), above.
+  ATOMICOPS_COMPILER_BARRIER();
+  return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  Atomic64 x = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+  if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+    __asm__ __volatile__("lfence" : : : "memory");
+  }
+  return x;
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+#endif  // defined(__x86_64__)
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#undef ATOMICOPS_COMPILER_BARRIER
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_GCC_H_
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc b/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
new file mode 100644
index 0000000..741b164
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc
@@ -0,0 +1,112 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The compilation of extension_set.cc fails when windows.h is included.
+// Therefore we move the code depending on windows.h to this separate cc file.
+
+// Don't compile this file for people not concerned about thread safety.
+#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+#include <google/protobuf/stubs/atomicops.h>
+
+#ifdef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+
+#include <windows.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline void MemoryBarrier() {
+  // We use MemoryBarrier from WinNT.h
+  ::MemoryBarrier();
+}
+
+Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                  Atomic32 old_value,
+                                  Atomic32 new_value) {
+  LONG result = InterlockedCompareExchange(
+      reinterpret_cast<volatile LONG*>(ptr),
+      static_cast<LONG>(new_value),
+      static_cast<LONG>(old_value));
+  return static_cast<Atomic32>(result);
+}
+
+Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                  Atomic32 new_value) {
+  LONG result = InterlockedExchange(
+      reinterpret_cast<volatile LONG*>(ptr),
+      static_cast<LONG>(new_value));
+  return static_cast<Atomic32>(result);
+}
+
+Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                 Atomic32 increment) {
+  return InterlockedExchangeAdd(
+      reinterpret_cast<volatile LONG*>(ptr),
+      static_cast<LONG>(increment)) + increment;
+}
+
+#if defined(_WIN64)
+
+// 64-bit low-level operations on 64-bit platform.
+
+Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                  Atomic64 old_value,
+                                  Atomic64 new_value) {
+  PVOID result = InterlockedCompareExchangePointer(
+    reinterpret_cast<volatile PVOID*>(ptr),
+    reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
+  return reinterpret_cast<Atomic64>(result);
+}
+
+Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+                                  Atomic64 new_value) {
+  PVOID result = InterlockedExchangePointer(
+    reinterpret_cast<volatile PVOID*>(ptr),
+    reinterpret_cast<PVOID>(new_value));
+  return reinterpret_cast<Atomic64>(result);
+}
+
+Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+                                 Atomic64 increment) {
+  return InterlockedExchangeAdd64(
+      reinterpret_cast<volatile LONGLONG*>(ptr),
+      static_cast<LONGLONG>(increment)) + increment;
+}
+
+#endif  // defined(_WIN64)
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+#endif  // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
diff --git a/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h b/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
new file mode 100644
index 0000000..e53a641
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h
@@ -0,0 +1,150 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  return Barrier_AtomicIncrement(ptr, increment);
+}
+
+#if !(defined(_MSC_VER) && _MSC_VER >= 1400)
+#error "We require at least vs2005 for MemoryBarrier"
+#endif
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value,
+                                       Atomic32 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  NoBarrier_AtomicExchange(ptr, value);
+              // acts as a barrier in this implementation
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  *ptr = value;  // works w/o barrier for current Intel chips as of June 2005
+  // See comments in Atomic64 version of Release_Store() below.
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+  return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  Atomic32 value = *ptr;
+  return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+#if defined(_WIN64)
+
+// 64-bit low-level operations on 64-bit platform.
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+                                          Atomic64 increment) {
+  return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+  NoBarrier_AtomicExchange(ptr, value);
+              // acts as a barrier in this implementation
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+  *ptr = value;  // works w/o barrier for current Intel chips as of June 2005
+
+  // When new chips come out, check:
+  //  IA-32 Intel Architecture Software Developer's Manual, Volume 3:
+  //  System Programming Guide, Chatper 7: Multiple-processor management,
+  //  Section 7.2, Memory Ordering.
+  // Last seen at:
+  //   http://developer.intel.com/design/pentium4/manuals/index_new.htm
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+  return *ptr;
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+  Atomic64 value = *ptr;
+  return value;
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+  MemoryBarrier();
+  return *ptr;
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value,
+                                       Atomic64 new_value) {
+  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+#endif  // defined(_WIN64)
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_X86_MSVC_H_
diff --git a/protobuf/src/google/protobuf/stubs/common.cc b/protobuf/src/google/protobuf/stubs/common.cc
new file mode 100644
index 0000000..1e02b22
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/common.cc
@@ -0,0 +1,395 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
+#include <stdio.h>
+#include <errno.h>
+#include <vector>
+
+#include "config.h"
+
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN  // We only need minimal includes
+#include <windows.h>
+#define snprintf _snprintf    // see comment in strutil.cc
+#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;
+
+  // 128 bytes should always be enough, but we use snprintf() anyway to be
+  // safe.
+  char buffer[128];
+  snprintf(buffer, sizeof(buffer), "%d.%d.%d", major, minor, micro);
+
+  // Guard against broken MSVC snprintf().
+  buffer[sizeof(buffer)-1] = '\0';
+
+  return buffer;
+}
+
+}  // 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_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(log_silencer_count_init_);
+
+void DeleteLogSilencerCount() {
+  delete log_silencer_count_mutex_;
+  log_silencer_count_mutex_ = NULL;
+}
+void InitLogSilencerCount() {
+  log_silencer_count_mutex_ = new Mutex;
+  OnShutdown(&DeleteLogSilencerCount);
+}
+void InitLogSilencerCountOnce() {
+  GoogleOnceInit(&log_silencer_count_init_, &InitLogSilencerCount);
+}
+
+LogMessage& LogMessage::operator<<(const string& value) {
+  message_ += value;
+  return *this;
+}
+
+LogMessage& LogMessage::operator<<(const char* value) {
+  message_ += value;
+  return *this;
+}
+
+// Since this is just for logging, we don't care if the current locale changes
+// the results -- in fact, we probably prefer that.  So we use snprintf()
+// instead of Simple*toa().
+#undef DECLARE_STREAM_OPERATOR
+#define DECLARE_STREAM_OPERATOR(TYPE, FORMAT)                       \
+  LogMessage& LogMessage::operator<<(TYPE value) {                  \
+    /* 128 bytes should be big enough for any of the primitive */   \
+    /* values which we print with this, but well use snprintf() */  \
+    /* anyway to be extra safe. */                                  \
+    char buffer[128];                                               \
+    snprintf(buffer, sizeof(buffer), FORMAT, value);                \
+    /* Guard against broken MSVC snprintf(). */                     \
+    buffer[sizeof(buffer)-1] = '\0';                                \
+    message_ += buffer;                                             \
+    return *this;                                                   \
+  }
+
+DECLARE_STREAM_OPERATOR(char         , "%c" )
+DECLARE_STREAM_OPERATOR(int          , "%d" )
+DECLARE_STREAM_OPERATOR(uint         , "%u" )
+DECLARE_STREAM_OPERATOR(long         , "%ld")
+DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
+DECLARE_STREAM_OPERATOR(double       , "%g" )
+#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) {
+    InitLogSilencerCountOnce();
+    MutexLock lock(log_silencer_count_mutex_);
+    suppress = log_silencer_count_ > 0;
+  }
+
+  if (!suppress) {
+    log_handler_(level_, filename_, line_, message_);
+  }
+
+  if (level_ == LOGLEVEL_FATAL) {
+#if PROTOBUF_USE_EXCEPTIONS
+    throw FatalException(filename_, line_, message_);
+#else
+    abort();
+#endif
+  }
+}
+
+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() {
+  internal::InitLogSilencerCountOnce();
+  MutexLock lock(internal::log_silencer_count_mutex_);
+  ++internal::log_silencer_count_;
+};
+
+LogSilencer::~LogSilencer() {
+  internal::InitLogSilencerCountOnce();
+  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
+
+// ===================================================================
+// emulates google3/util/endian/endian.h
+//
+// TODO(xiaofeng): PROTOBUF_LITTLE_ENDIAN is unfortunately defined in
+// google/protobuf/io/coded_stream.h and therefore can not be used here.
+// Maybe move that macro definition here in the furture.
+uint32 ghtonl(uint32 x) {
+  union {
+    uint32 result;
+    uint8 result_array[4];
+  };
+  result_array[0] = static_cast<uint8>(x >> 24);
+  result_array[1] = static_cast<uint8>((x >> 16) & 0xFF);
+  result_array[2] = static_cast<uint8>((x >> 8) & 0xFF);
+  result_array[3] = static_cast<uint8>(x & 0xFF);
+  return result;
+}
+
+// ===================================================================
+// Shutdown support.
+
+namespace internal {
+
+typedef void OnShutdownFunc();
+vector<void (*)()>* shutdown_functions = NULL;
+Mutex* shutdown_functions_mutex = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(shutdown_functions_init);
+
+void InitShutdownFunctions() {
+  shutdown_functions = new vector<void (*)()>;
+  shutdown_functions_mutex = new Mutex;
+}
+
+inline void InitShutdownFunctionsOnce() {
+  GoogleOnceInit(&shutdown_functions_init, &InitShutdownFunctions);
+}
+
+void OnShutdown(void (*func)()) {
+  InitShutdownFunctionsOnce();
+  MutexLock lock(shutdown_functions_mutex);
+  shutdown_functions->push_back(func);
+}
+
+}  // namespace internal
+
+void ShutdownProtobufLibrary() {
+  internal::InitShutdownFunctionsOnce();
+
+  // We don't need to lock shutdown_functions_mutex because it's up to the
+  // caller to make sure that no one is using the library before this is
+  // called.
+
+  // Make it safe to call this multiple times.
+  if (internal::shutdown_functions == NULL) return;
+
+  for (int i = 0; i < internal::shutdown_functions->size(); i++) {
+    internal::shutdown_functions->at(i)();
+  }
+  delete internal::shutdown_functions;
+  internal::shutdown_functions = NULL;
+  delete internal::shutdown_functions_mutex;
+  internal::shutdown_functions_mutex = NULL;
+}
+
+#if PROTOBUF_USE_EXCEPTIONS
+FatalException::~FatalException() throw() {}
+
+const char* FatalException::what() const throw() {
+  return message_.c_str();
+}
+#endif
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/stubs/common.h b/protobuf/src/google/protobuf/stubs/common.h
new file mode 100644
index 0000000..f096fa9
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/common.h
@@ -0,0 +1,1226 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+#if defined(__osf__)
+// Tru64 lacks stdint.h, but has inttypes.h which defines a superset of
+// what stdint.h would define.
+#include <inttypes.h>
+#elif !defined(_MSC_VER)
+#include <stdint.h>
+#endif
+
+#ifndef PROTOBUF_USE_EXCEPTIONS
+#if defined(_MSC_VER) && defined(_CPPUNWIND)
+  #define PROTOBUF_USE_EXCEPTIONS 1
+#elif defined(__EXCEPTIONS)
+  #define PROTOBUF_USE_EXCEPTIONS 1
+#else
+  #define PROTOBUF_USE_EXCEPTIONS 0
+#endif
+#endif
+
+#if PROTOBUF_USE_EXCEPTIONS
+#include <exception>
+#endif
+
+#if defined(_WIN32) && defined(GetMessage)
+// Allow GetMessage to be used as a valid method name in protobuf classes.
+// windows.h defines GetMessage() as a macro.  Let's re-define it as an inline
+// function.  The inline function should be equivalent for C++ users.
+inline BOOL GetMessage_Win32(
+    LPMSG lpMsg, HWND hWnd,
+    UINT wMsgFilterMin, UINT wMsgFilterMax) {
+  return GetMessage(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
+}
+#undef GetMessage
+inline BOOL GetMessage(
+    LPMSG lpMsg, HWND hWnd,
+    UINT wMsgFilterMin, UINT wMsgFilterMax) {
+  return GetMessage_Win32(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
+}
+#endif
+
+
+namespace std {}
+
+namespace google {
+namespace protobuf {
+
+#undef GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
+#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)    \
+  TypeName(const TypeName&);                           \
+  void operator=(const TypeName&)
+
+#if defined(_MSC_VER) && defined(PROTOBUF_USE_DLLS)
+  #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 2006001
+
+// The minimum library version which works with the current version of the
+// headers.
+#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 2006000
+
+// 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 = 2006000;
+
+// The minimum protoc version which works with the current version of the
+// headers.
+#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 2006000
+
+// The minimum header version which works with the current version of
+// protoc.  This constant should only be used in VerifyVersion().
+static const int kMinHeaderVersionForProtoc = 2006000;
+
+// 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.
+std::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 = -kint32max - 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);
+
+// -------------------------------------------------------------------
+// Annotations:  Some parts of the code have been annotated in ways that might
+//   be useful to some compilers or tools, but are not supported universally.
+//   You can #define these annotations yourself if the default implementation
+//   is not right for you.
+
+#ifndef 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
+#endif
+
+#ifndef GOOGLE_ATTRIBUTE_DEPRECATED
+#ifdef __GNUC__
+// If the method/variable/type is used anywhere, produce a warning.
+#define GOOGLE_ATTRIBUTE_DEPRECATED __attribute__((deprecated))
+#else
+#define GOOGLE_ATTRIBUTE_DEPRECATED
+#endif
+#endif
+
+#ifndef GOOGLE_PREDICT_TRUE
+#ifdef __GNUC__
+// Provided at least since GCC 3.0.
+#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
+#else
+#define GOOGLE_PREDICT_TRUE
+#endif
+#endif
+
+// Delimits a block of code which may write to memory which is simultaneously
+// written by other threads, but which has been determined to be thread-safe
+// (e.g. because it is an idempotent write).
+#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN
+#define GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN()
+#endif
+#ifndef GOOGLE_SAFE_CONCURRENT_WRITES_END
+#define GOOGLE_SAFE_CONCURRENT_WRITES_END()
+#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);
+  }
+
+#if !defined(NDEBUG) && !defined(GOOGLE_PROTOBUF_NO_RTTI)
+  assert(f == NULL || dynamic_cast<To>(f) != NULL);  // RTTI: debug mode only!
+#endif
+  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 std::string& value);
+  LogMessage& operator<<(const char* value);
+  LogMessage& operator<<(char value);
+  LogMessage& operator<<(int value);
+  LogMessage& operator<<(uint value);
+  LogMessage& operator<<(long value);
+  LogMessage& operator<<(unsigned long value);
+  LogMessage& operator<<(double value);
+
+ private:
+  friend class LogFinisher;
+  void Finish();
+
+  LogLevel level_;
+  const char* filename_;
+  int line_;
+  std::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_OK
+#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_CHECK_NOTNULL
+
+#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_OK(A) GOOGLE_CHECK(A)
+#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))
+
+namespace internal {
+template<typename T>
+T* CheckNotNull(const char* /* file */, int /* line */,
+                const char* name, T* val) {
+  if (val == NULL) {
+    GOOGLE_LOG(FATAL) << name;
+  }
+  return val;
+}
+}  // namespace internal
+#define GOOGLE_CHECK_NOTNULL(A) \
+  internal::CheckNotNull(__FILE__, __LINE__, "'" #A "' must not be NULL", (A))
+
+#ifdef NDEBUG
+
+#define GOOGLE_DLOG GOOGLE_LOG_IF(INFO, false)
+
+#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 std::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() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
+    function_();
+    if (needs_delete) 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() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
+    (object_->*method_)();
+    if (needs_delete) 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() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
+    function_(arg1_);
+    if (needs_delete) 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() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
+    (object_->*method_)(arg1_);
+    if (needs_delete) 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() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
+    function_(arg1_, arg2_);
+    if (needs_delete) 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() {
+    bool needs_delete = self_deleting_;  // read in case callback deletes
+    (object_->*method_)(arg1_, arg2_);
+    if (needs_delete) 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);
+};
+
+// TODO(kenton):  Implement these?  Hard to implement portably.
+typedef MutexLock ReaderMutexLock;
+typedef MutexLock WriterMutexLock;
+
+// 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::ReaderMutexLock;
+using internal::WriterMutexLock;
+using internal::MutexLockMaybe;
+
+// ===================================================================
+// from google3/util/utf8/public/unilib.h
+
+namespace internal {
+
+// Checks if the buffer contains structurally-valid UTF-8.  Implemented in
+// structurally_valid.cc.
+LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len);
+
+}  // namespace internal
+
+// ===================================================================
+// from google3/util/endian/endian.h
+LIBPROTOBUF_EXPORT uint32 ghtonl(uint32 x);
+
+// ===================================================================
+// Shutdown support.
+
+// Shut down the entire protocol buffers library, deleting all static-duration
+// objects allocated by the library or by generated .pb.cc files.
+//
+// There are two reasons you might want to call this:
+// * You use a draconian definition of "memory leak" in which you expect
+//   every single malloc() to have a corresponding free(), even for objects
+//   which live until program exit.
+// * You are writing a dynamically-loaded library which needs to clean up
+//   after itself when the library is unloaded.
+//
+// It is safe to call this multiple times.  However, it is not safe to use
+// any other part of the protocol buffers library after
+// ShutdownProtobufLibrary() has been called.
+LIBPROTOBUF_EXPORT void ShutdownProtobufLibrary();
+
+namespace internal {
+
+// Register a function to be called when ShutdownProtocolBuffers() is called.
+LIBPROTOBUF_EXPORT void OnShutdown(void (*func)());
+
+}  // namespace internal
+
+#if PROTOBUF_USE_EXCEPTIONS
+class FatalException : public std::exception {
+ public:
+  FatalException(const char* filename, int line, const std::string& message)
+      : filename_(filename), line_(line), message_(message) {}
+  virtual ~FatalException() throw();
+
+  virtual const char* what() const throw();
+
+  const char* filename() const { return filename_; }
+  int line() const { return line_; }
+  const std::string& message() const { return message_; }
+
+ private:
+  const char* filename_;
+  const int line_;
+  const std::string message_;
+};
+#endif
+
+// This is at the end of the file instead of the beginning to work around a bug
+// in some versions of MSVC.
+using namespace std;  // Don't do this at home, kids.
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_COMMON_H__
diff --git a/protobuf/src/google/protobuf/stubs/common_unittest.cc b/protobuf/src/google/protobuf/stubs/common_unittest.cc
new file mode 100644
index 0000000..cb89207
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/common_unittest.cc
@@ -0,0 +1,357 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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" or "rc1", so we remove that.
+  string version = PACKAGE_VERSION;
+  int pos = 0;
+  while (pos < version.size() &&
+         (ascii_isdigit(version[pos]) || version[pos] == '.')) {
+    ++pos;
+  }
+  version.erase(pos);
+
+  EXPECT_EQ(version, internal::VersionString(GOOGLE_PROTOBUF_VERSION));
+}
+
+#endif  // PACKAGE_VERSION
+
+TEST(CommonTest, IntMinMaxConstants) {
+  // kint32min was declared incorrectly in the first release of protobufs.
+  // Ugh.
+  EXPECT_LT(kint32min, kint32max);
+  EXPECT_EQ(static_cast<uint32>(kint32min), static_cast<uint32>(kint32max) + 1);
+  EXPECT_LT(kint64min, kint64max);
+  EXPECT_EQ(static_cast<uint64>(kint64min), static_cast<uint64>(kint64max) + 1);
+  EXPECT_EQ(0, kuint32max + 1);
+  EXPECT_EQ(0, kuint64max + 1);
+}
+
+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();
+    permanent_closure_ = NULL;
+  }
+
+  void DeleteClosureInCallback() {
+    delete permanent_closure_;
+  }
+
+  int a_;
+  const char* b_;
+  string c_;
+  Closure* permanent_closure_;
+
+  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;
+}
+
+TEST_F(ClosureTest, TestPermanentClosureDeleteInCallback) {
+  permanent_closure_ = NewPermanentCallback((ClosureTest*) this,
+      &ClosureTest::DeleteClosureInCallback);
+  permanent_closure_->Run();
+}
+
+}  // anonymous namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/stubs/hash.cc b/protobuf/src/google/protobuf/stubs/hash.cc
new file mode 100644
index 0000000..9eaf4a1
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/hash.cc
@@ -0,0 +1,41 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: 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/protobuf/src/google/protobuf/stubs/hash.h b/protobuf/src/google/protobuf/stubs/hash.h
new file mode 100644
index 0000000..5b6a073
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/hash.h
@@ -0,0 +1,232 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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
+#define MISSING_HASH
+#include <map>
+#include <set>
+#endif
+
+namespace google {
+namespace protobuf {
+
+#ifdef MISSING_HASH
+
+// This system doesn't have hash_map or hash_set.  Emulate them using map and
+// set.
+
+// Make hash<T> be the same as less<T>.  Note that everywhere where custom
+// hash functions are defined in the protobuf code, they are also defined such
+// that they can be used as "less" functions, which is required by MSVC anyway.
+template <typename Key>
+struct hash {
+  // Dummy, just to make derivative hash functions compile.
+  int operator()(const Key& key) {
+    GOOGLE_LOG(FATAL) << "Should never be called.";
+    return 0;
+  }
+
+  inline bool operator()(const Key& a, const Key& b) const {
+    return a < b;
+  }
+};
+
+// Make sure char* is compared by value.
+template <>
+struct hash<const char*> {
+  // Dummy, just to make derivative hash functions compile.
+  int operator()(const char* key) {
+    GOOGLE_LOG(FATAL) << "Should never be called.";
+    return 0;
+  }
+
+  inline bool operator()(const char* a, const char* b) const {
+    return strcmp(a, b) < 0;
+  }
+};
+
+template <typename Key, typename Data,
+          typename HashFcn = hash<Key>,
+          typename EqualKey = int >
+class hash_map : public std::map<Key, Data, HashFcn> {
+ public:
+  hash_map(int = 0) {}
+};
+
+template <typename Key,
+          typename HashFcn = hash<Key>,
+          typename EqualKey = int >
+class hash_set : public std::set<Key, HashFcn> {
+ public:
+  hash_set(int = 0) {}
+};
+
+#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
+
+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> {
+ public:
+  hash_map(int = 0) {}
+};
+
+template <typename Key,
+          typename HashFcn = hash<Key>,
+          typename EqualKey = int >
+class hash_set : public HASH_NAMESPACE::hash_set<
+    Key, HashFcn> {
+ public:
+  hash_set(int = 0) {}
+};
+
+#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);
+  }
+};
+
+// Unlike the old SGI version, the TR1 "hash" does not special-case char*.  So,
+// we go ahead and provide our own implementation.
+template <>
+struct hash<const char*> {
+  inline size_t operator()(const char* str) const {
+    size_t result = 0;
+    for (; *str != '\0'; str++) {
+      result = 5 * result + *str;
+    }
+    return result;
+  }
+};
+
+template <typename Key, typename Data,
+          typename HashFcn = hash<Key>,
+          typename EqualKey = std::equal_to<Key> >
+class hash_map : public HASH_NAMESPACE::HASH_MAP_CLASS<
+    Key, Data, HashFcn, EqualKey> {
+ public:
+  hash_map(int = 0) {}
+};
+
+template <typename Key,
+          typename HashFcn = hash<Key>,
+          typename EqualKey = std::equal_to<Key> >
+class hash_set : public HASH_NAMESPACE::HASH_SET_CLASS<
+    Key, HashFcn, EqualKey> {
+ public:
+  hash_set(int = 0) {}
+};
+
+#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;
+  }
+};
+
+template <typename First, typename Second>
+struct hash<pair<First, Second> > {
+  inline size_t operator()(const pair<First, Second>& key) const {
+    size_t first_hash = hash<First>()(key.first);
+    size_t second_hash = hash<Second>()(key.second);
+
+    // FIXME(kenton):  What is the best way to compute this hash?  I have
+    // no idea!  This seems a bit better than an XOR.
+    return first_hash * ((1 << 16) - 1) + second_hash;
+  }
+
+  static const size_t bucket_size = 4;
+  static const size_t min_buckets = 8;
+  inline size_t operator()(const pair<First, Second>& a,
+                           const pair<First, Second>& b) const {
+    return a < b;
+  }
+};
+
+// Used by GCC/SGI STL only.  (Why isn't this provided by the standard
+// library?  :( )
+struct streq {
+  inline bool operator()(const char* a, const char* b) const {
+    return strcmp(a, b) == 0;
+  }
+};
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_HASH_H__
diff --git a/protobuf/src/google/protobuf/stubs/map-util.h b/protobuf/src/google/protobuf/stubs/map-util.h
new file mode 100644
index 0000000..f5c9d6b
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/map-util.h
@@ -0,0 +1,119 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// 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 in the map then the value associated with that
+// key is returned, otherwise the value passed as a default is returned.
+template <class Collection>
+const typename Collection::value_type::second_type&
+FindWithDefault(const Collection& collection,
+                const typename Collection::value_type::first_type& key,
+                const typename Collection::value_type::second_type& value) {
+  typename Collection::const_iterator it = collection.find(key);
+  if (it == collection.end()) {
+    return value;
+  }
+  return it->second;
+}
+
+// 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/protobuf/src/google/protobuf/stubs/map_util.h b/protobuf/src/google/protobuf/stubs/map_util.h
new file mode 100644
index 0000000..7495cb6
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/map_util.h
@@ -0,0 +1,771 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2014 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// 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 <stddef.h>
+#include <iterator>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+// Local implementation of RemoveConst to avoid including base/type_traits.h.
+template <class T> struct RemoveConst { typedef T type; };
+template <class T> struct RemoveConst<const T> : RemoveConst<T> {};
+}  // namespace internal
+
+//
+// Find*()
+//
+
+// Returns a const reference to the value associated with the given key if it
+// exists. Crashes otherwise.
+//
+// This is intended as a replacement for operator[] as an rvalue (for reading)
+// when the key is guaranteed to exist.
+//
+// operator[] for lookup is discouraged for several reasons:
+//  * It has a side-effect of inserting missing keys
+//  * It is not thread-safe (even when it is not inserting, it can still
+//      choose to resize the underlying storage)
+//  * It invalidates iterators (when it chooses to resize)
+//  * It default constructs a value object even if it doesn't need to
+//
+// This version assumes the key is printable, and includes it in the fatal log
+// message.
+template <class Collection>
+const typename Collection::value_type::second_type&
+FindOrDie(const Collection& collection,
+          const typename Collection::value_type::first_type& key) {
+  typename Collection::const_iterator it = collection.find(key);
+  GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key;
+  return it->second;
+}
+
+// Same as above, but returns a non-const reference.
+template <class Collection>
+typename Collection::value_type::second_type&
+FindOrDie(Collection& collection,  // NOLINT
+          const typename Collection::value_type::first_type& key) {
+  typename Collection::iterator it = collection.find(key);
+  GOOGLE_CHECK(it != collection.end()) << "Map key not found: " << key;
+  return it->second;
+}
+
+// Same as FindOrDie above, but doesn't log the key on failure.
+template <class Collection>
+const typename Collection::value_type::second_type&
+FindOrDieNoPrint(const Collection& collection,
+                 const typename Collection::value_type::first_type& key) {
+  typename Collection::const_iterator it = collection.find(key);
+  GOOGLE_CHECK(it != collection.end()) << "Map key not found";
+  return it->second;
+}
+
+// Same as above, but returns a non-const reference.
+template <class Collection>
+typename Collection::value_type::second_type&
+FindOrDieNoPrint(Collection& collection,  // NOLINT
+                 const typename Collection::value_type::first_type& key) {
+  typename Collection::iterator it = collection.find(key);
+  GOOGLE_CHECK(it != collection.end()) << "Map key not found";
+  return it->second;
+}
+
+// Returns a const reference to the value associated with the given key if it
+// exists, otherwise returns a const reference to the provided default value.
+//
+// WARNING: If a temporary object is passed as the default "value,"
+// this function will return a reference to that temporary object,
+// which will be destroyed at the end of the statement. A common
+// example: if you have a map with string values, and you pass a char*
+// as the default "value," either use the returned value immediately
+// or store it in a string (not string&).
+// Details: http://go/findwithdefault
+template <class Collection>
+const typename Collection::value_type::second_type&
+FindWithDefault(const Collection& collection,
+                const typename Collection::value_type::first_type& key,
+                const typename Collection::value_type::second_type& value) {
+  typename Collection::const_iterator it = collection.find(key);
+  if (it == collection.end()) {
+    return value;
+  }
+  return it->second;
+}
+
+// Returns a pointer to the const value associated with the given key if it
+// exists, or NULL otherwise.
+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;
+}
+
+// Same as above but returns a pointer to the non-const value.
+template <class Collection>
+typename Collection::value_type::second_type*
+FindOrNull(Collection& collection,  // NOLINT
+           const typename Collection::value_type::first_type& key) {
+  typename Collection::iterator it = collection.find(key);
+  if (it == collection.end()) {
+    return 0;
+  }
+  return &it->second;
+}
+
+// Returns the pointer value associated with the given key. If none is found,
+// NULL is returned. The function is designed to be used with a map of keys to
+// pointers.
+//
+// This function does not distinguish between a missing key and a key mapped
+// to a NULL value.
+template <class Collection>
+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 typename Collection::value_type::second_type();
+  }
+  return it->second;
+}
+
+// Same as above, except takes non-const reference to collection.
+//
+// This function is needed for containers that propagate constness to the
+// pointee, such as boost::ptr_map.
+template <class Collection>
+typename Collection::value_type::second_type
+FindPtrOrNull(Collection& collection,  // NOLINT
+              const typename Collection::value_type::first_type& key) {
+  typename Collection::iterator it = collection.find(key);
+  if (it == collection.end()) {
+    return typename Collection::value_type::second_type();
+  }
+  return it->second;
+}
+
+// Finds the pointer value associated with the given key in a map whose values
+// are linked_ptrs. Returns NULL if key is not found.
+template <class Collection>
+typename Collection::value_type::second_type::element_type*
+FindLinkedPtrOrNull(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;
+  }
+  // Since linked_ptr::get() is a const member returning a non const,
+  // we do not need a version of this function taking a non const collection.
+  return it->second.get();
+}
+
+// Same as above, but dies if the key is not found.
+template <class Collection>
+typename Collection::value_type::second_type::element_type&
+FindLinkedPtrOrDie(const Collection& collection,
+                   const typename Collection::value_type::first_type& key) {
+  typename Collection::const_iterator it = collection.find(key);
+  CHECK(it != collection.end()) <<  "key not found: " << key;
+  // Since linked_ptr::operator*() is a const member returning a non const,
+  // we do not need a version of this function taking a non const collection.
+  return *it->second;
+}
+
+// Finds the value associated with the given key and copies it to *value (if not
+// NULL). Returns false if the key was not found, true otherwise.
+template <class Collection, class Key, class Value>
+bool FindCopy(const Collection& collection,
+              const Key& key,
+              Value* const value) {
+  typename Collection::const_iterator it = collection.find(key);
+  if (it == collection.end()) {
+    return false;
+  }
+  if (value) {
+    *value = it->second;
+  }
+  return true;
+}
+
+//
+// Contains*()
+//
+
+// Returns true if and only if the given collection contains the given key.
+template <class Collection, class Key>
+bool ContainsKey(const Collection& collection, const Key& key) {
+  return collection.find(key) != collection.end();
+}
+
+// Returns true if and only if the given collection contains the given key-value
+// pair.
+template <class Collection, class Key, class Value>
+bool ContainsKeyValuePair(const Collection& collection,
+                          const Key& key,
+                          const Value& value) {
+  typedef typename Collection::const_iterator const_iterator;
+  std::pair<const_iterator, const_iterator> range = collection.equal_range(key);
+  for (const_iterator it = range.first; it != range.second; ++it) {
+    if (it->second == value) {
+      return true;
+    }
+  }
+  return false;
+}
+
+//
+// Insert*()
+//
+
+// Inserts the given key-value pair into the collection. Returns true if and
+// only if the key from the given pair didn't previously exist. Otherwise, the
+// value in the map is replaced with the value from the given pair.
+template <class Collection>
+bool InsertOrUpdate(Collection* const collection,
+                    const typename Collection::value_type& vt) {
+  std::pair<typename Collection::iterator, bool> ret = collection->insert(vt);
+  if (!ret.second) {
+    // update
+    ret.first->second = vt.second;
+    return false;
+  }
+  return true;
+}
+
+// Same as above, except that the key and value are passed separately.
+template <class Collection>
+bool InsertOrUpdate(Collection* const collection,
+                    const typename Collection::value_type::first_type& key,
+                    const typename Collection::value_type::second_type& value) {
+  return InsertOrUpdate(
+      collection, typename Collection::value_type(key, value));
+}
+
+// Inserts/updates all the key-value pairs from the range defined by the
+// iterators "first" and "last" into the given collection.
+template <class Collection, class InputIterator>
+void InsertOrUpdateMany(Collection* const collection,
+                        InputIterator first, InputIterator last) {
+  for (; first != last; ++first) {
+    InsertOrUpdate(collection, *first);
+  }
+}
+
+// Change the value associated with a particular key in a map or hash_map
+// of the form map<Key, Value*> which owns the objects pointed to by the
+// value pointers.  If there was an existing value for the key, it is deleted.
+// True indicates an insert took place, false indicates an update + delete.
+template <class Collection>
+bool InsertAndDeleteExisting(
+    Collection* const collection,
+    const typename Collection::value_type::first_type& key,
+    const typename Collection::value_type::second_type& value) {
+  std::pair<typename Collection::iterator, bool> ret =
+      collection->insert(typename Collection::value_type(key, value));
+  if (!ret.second) {
+    delete ret.first->second;
+    ret.first->second = value;
+    return false;
+  }
+  return true;
+}
+
+// Inserts the given key and value into the given collection if and only if the
+// given key did NOT already exist in the collection. If the key previously
+// existed in the collection, the value is not changed. Returns true if the
+// key-value pair was inserted; returns false if the key was already present.
+template <class Collection>
+bool InsertIfNotPresent(Collection* const collection,
+                        const typename Collection::value_type& vt) {
+  return collection->insert(vt).second;
+}
+
+// Same as above except the key and value are passed separately.
+template <class Collection>
+bool InsertIfNotPresent(
+    Collection* const collection,
+    const typename Collection::value_type::first_type& key,
+    const typename Collection::value_type::second_type& value) {
+  return InsertIfNotPresent(
+      collection, typename Collection::value_type(key, value));
+}
+
+// Same as above except dies if the key already exists in the collection.
+template <class Collection>
+void InsertOrDie(Collection* const collection,
+                 const typename Collection::value_type& value) {
+  CHECK(InsertIfNotPresent(collection, value)) << "duplicate value: " << value;
+}
+
+// Same as above except doesn't log the value on error.
+template <class Collection>
+void InsertOrDieNoPrint(Collection* const collection,
+                        const typename Collection::value_type& value) {
+  CHECK(InsertIfNotPresent(collection, value)) << "duplicate value.";
+}
+
+// Inserts the key-value pair into the collection. Dies if key was already
+// present.
+template <class Collection>
+void InsertOrDie(Collection* const collection,
+                 const typename Collection::value_type::first_type& key,
+                 const typename Collection::value_type::second_type& data) {
+  typedef typename Collection::value_type value_type;
+  GOOGLE_CHECK(InsertIfNotPresent(collection, key, data))
+      << "duplicate key: " << key;
+}
+
+// Same as above except doesn't log the key on error.
+template <class Collection>
+void InsertOrDieNoPrint(
+    Collection* const collection,
+    const typename Collection::value_type::first_type& key,
+    const typename Collection::value_type::second_type& data) {
+  typedef typename Collection::value_type value_type;
+  GOOGLE_CHECK(InsertIfNotPresent(collection, key, data)) << "duplicate key.";
+}
+
+// Inserts a new key and default-initialized value. Dies if the key was already
+// present. Returns a reference to the value. Example usage:
+//
+// map<int, SomeProto> m;
+// SomeProto& proto = InsertKeyOrDie(&m, 3);
+// proto.set_field("foo");
+template <class Collection>
+typename Collection::value_type::second_type& InsertKeyOrDie(
+    Collection* const collection,
+    const typename Collection::value_type::first_type& key) {
+  typedef typename Collection::value_type value_type;
+  std::pair<typename Collection::iterator, bool> res =
+      collection->insert(value_type(key, typename value_type::second_type()));
+  GOOGLE_CHECK(res.second) << "duplicate key: " << key;
+  return res.first->second;
+}
+
+//
+// Lookup*()
+//
+
+// Looks up a given key and value pair in a collection and inserts the key-value
+// pair if it's not already present. Returns a reference to the value associated
+// with the key.
+template <class Collection>
+typename Collection::value_type::second_type&
+LookupOrInsert(Collection* const collection,
+               const typename Collection::value_type& vt) {
+  return collection->insert(vt).first->second;
+}
+
+// Same as above except the key-value are passed separately.
+template <class Collection>
+typename Collection::value_type::second_type&
+LookupOrInsert(Collection* const collection,
+               const typename Collection::value_type::first_type& key,
+               const typename Collection::value_type::second_type& value) {
+  return LookupOrInsert(
+      collection, typename Collection::value_type(key, value));
+}
+
+// Counts the number of equivalent elements in the given "sequence", and stores
+// the results in "count_map" with element as the key and count as the value.
+//
+// Example:
+//   vector<string> v = {"a", "b", "c", "a", "b"};
+//   map<string, int> m;
+//   AddTokenCounts(v, 1, &m);
+//   assert(m["a"] == 2);
+//   assert(m["b"] == 2);
+//   assert(m["c"] == 1);
+template <typename Sequence, typename Collection>
+void AddTokenCounts(
+    const Sequence& sequence,
+    const typename Collection::value_type::second_type& increment,
+    Collection* const count_map) {
+  for (typename Sequence::const_iterator it = sequence.begin();
+       it != sequence.end(); ++it) {
+    typename Collection::value_type::second_type& value =
+        LookupOrInsert(count_map, *it,
+                       typename Collection::value_type::second_type());
+    value += increment;
+  }
+}
+
+// Returns a reference to the value associated with key. If not found, a value
+// is default constructed on the heap and added to the map.
+//
+// This function is useful for containers of the form map<Key, Value*>, where
+// inserting a new key, value pair involves constructing a new heap-allocated
+// Value, and storing a pointer to that in the collection.
+template <class Collection>
+typename Collection::value_type::second_type&
+LookupOrInsertNew(Collection* const collection,
+                  const typename Collection::value_type::first_type& key) {
+  typedef typename std::iterator_traits<
+    typename Collection::value_type::second_type>::value_type Element;
+  std::pair<typename Collection::iterator, bool> ret =
+      collection->insert(typename Collection::value_type(
+          key,
+          static_cast<typename Collection::value_type::second_type>(NULL)));
+  if (ret.second) {
+    ret.first->second = new Element();
+  }
+  return ret.first->second;
+}
+
+// Same as above but constructs the value using the single-argument constructor
+// and the given "arg".
+template <class Collection, class Arg>
+typename Collection::value_type::second_type&
+LookupOrInsertNew(Collection* const collection,
+                  const typename Collection::value_type::first_type& key,
+                  const Arg& arg) {
+  typedef typename std::iterator_traits<
+    typename Collection::value_type::second_type>::value_type Element;
+  std::pair<typename Collection::iterator, bool> ret =
+      collection->insert(typename Collection::value_type(
+          key,
+          static_cast<typename Collection::value_type::second_type>(NULL)));
+  if (ret.second) {
+    ret.first->second = new Element(arg);
+  }
+  return ret.first->second;
+}
+
+// Lookup of linked/shared pointers is used in two scenarios:
+//
+// Use LookupOrInsertNewLinkedPtr if the container owns the elements.
+// In this case it is fine working with the raw pointer as long as it is
+// guaranteed that no other thread can delete/update an accessed element.
+// A mutex will need to lock the container operation as well as the use
+// of the returned elements. Finding an element may be performed using
+// FindLinkedPtr*().
+//
+// Use LookupOrInsertNewSharedPtr if the container does not own the elements
+// for their whole lifetime. This is typically the case when a reader allows
+// parallel updates to the container. In this case a Mutex only needs to lock
+// container operations, but all element operations must be performed on the
+// shared pointer. Finding an element must be performed using FindPtr*() and
+// cannot be done with FindLinkedPtr*() even though it compiles.
+
+// Lookup a key in a map or hash_map whose values are linked_ptrs.  If it is
+// missing, set collection[key].reset(new Value::element_type) and return that.
+// Value::element_type must be default constructable.
+template <class Collection>
+typename Collection::value_type::second_type::element_type*
+LookupOrInsertNewLinkedPtr(
+    Collection* const collection,
+    const typename Collection::value_type::first_type& key) {
+  typedef typename Collection::value_type::second_type Value;
+  std::pair<typename Collection::iterator, bool> ret =
+      collection->insert(typename Collection::value_type(key, Value()));
+  if (ret.second) {
+    ret.first->second.reset(new typename Value::element_type);
+  }
+  return ret.first->second.get();
+}
+
+// A variant of LookupOrInsertNewLinkedPtr where the value is constructed using
+// a single-parameter constructor.  Note: the constructor argument is computed
+// even if it will not be used, so only values cheap to compute should be passed
+// here.  On the other hand it does not matter how expensive the construction of
+// the actual stored value is, as that only occurs if necessary.
+template <class Collection, class Arg>
+typename Collection::value_type::second_type::element_type*
+LookupOrInsertNewLinkedPtr(
+    Collection* const collection,
+    const typename Collection::value_type::first_type& key,
+    const Arg& arg) {
+  typedef typename Collection::value_type::second_type Value;
+  std::pair<typename Collection::iterator, bool> ret =
+      collection->insert(typename Collection::value_type(key, Value()));
+  if (ret.second) {
+    ret.first->second.reset(new typename Value::element_type(arg));
+  }
+  return ret.first->second.get();
+}
+
+// Lookup a key in a map or hash_map whose values are shared_ptrs.  If it is
+// missing, set collection[key].reset(new Value::element_type). Unlike
+// LookupOrInsertNewLinkedPtr, this function returns the shared_ptr instead of
+// the raw pointer. Value::element_type must be default constructable.
+template <class Collection>
+typename Collection::value_type::second_type&
+LookupOrInsertNewSharedPtr(
+    Collection* const collection,
+    const typename Collection::value_type::first_type& key) {
+  typedef typename Collection::value_type::second_type SharedPtr;
+  typedef typename Collection::value_type::second_type::element_type Element;
+  std::pair<typename Collection::iterator, bool> ret =
+      collection->insert(typename Collection::value_type(key, SharedPtr()));
+  if (ret.second) {
+    ret.first->second.reset(new Element());
+  }
+  return ret.first->second;
+}
+
+// A variant of LookupOrInsertNewSharedPtr where the value is constructed using
+// a single-parameter constructor.  Note: the constructor argument is computed
+// even if it will not be used, so only values cheap to compute should be passed
+// here.  On the other hand it does not matter how expensive the construction of
+// the actual stored value is, as that only occurs if necessary.
+template <class Collection, class Arg>
+typename Collection::value_type::second_type&
+LookupOrInsertNewSharedPtr(
+    Collection* const collection,
+    const typename Collection::value_type::first_type& key,
+    const Arg& arg) {
+  typedef typename Collection::value_type::second_type SharedPtr;
+  typedef typename Collection::value_type::second_type::element_type Element;
+  std::pair<typename Collection::iterator, bool> ret =
+      collection->insert(typename Collection::value_type(key, SharedPtr()));
+  if (ret.second) {
+    ret.first->second.reset(new Element(arg));
+  }
+  return ret.first->second;
+}
+
+//
+// Misc Utility Functions
+//
+
+// Updates the value associated with the given key. If the key was not already
+// present, then the key-value pair are inserted and "previous" is unchanged. If
+// the key was already present, the value is updated and "*previous" will
+// contain a copy of the old value.
+//
+// InsertOrReturnExisting has complementary behavior that returns the
+// address of an already existing value, rather than updating it.
+template <class Collection>
+bool UpdateReturnCopy(Collection* const collection,
+                      const typename Collection::value_type::first_type& key,
+                      const typename Collection::value_type::second_type& value,
+                      typename Collection::value_type::second_type* previous) {
+  std::pair<typename Collection::iterator, bool> ret =
+      collection->insert(typename Collection::value_type(key, value));
+  if (!ret.second) {
+    // update
+    if (previous) {
+      *previous = ret.first->second;
+    }
+    ret.first->second = value;
+    return true;
+  }
+  return false;
+}
+
+// Same as above except that the key and value are passed as a pair.
+template <class Collection>
+bool UpdateReturnCopy(Collection* const collection,
+                      const typename Collection::value_type& vt,
+                      typename Collection::value_type::second_type* previous) {
+  std::pair<typename Collection::iterator, bool> ret = collection->insert(vt);
+  if (!ret.second) {
+    // update
+    if (previous) {
+      *previous = ret.first->second;
+    }
+    ret.first->second = vt.second;
+    return true;
+  }
+  return false;
+}
+
+// Tries to insert the given key-value pair into the collection. Returns NULL if
+// the insert succeeds. Otherwise, returns a pointer to the existing value.
+//
+// This complements UpdateReturnCopy in that it allows to update only after
+// verifying the old value and still insert quickly without having to look up
+// twice. Unlike UpdateReturnCopy this also does not come with the issue of an
+// undefined previous* in case new data was inserted.
+template <class Collection>
+typename Collection::value_type::second_type* const
+InsertOrReturnExisting(Collection* const collection,
+                       const typename Collection::value_type& vt) {
+  std::pair<typename Collection::iterator, bool> ret = collection->insert(vt);
+  if (ret.second) {
+    return NULL;  // Inserted, no existing previous value.
+  } else {
+    return &ret.first->second;  // Return address of already existing value.
+  }
+}
+
+// Same as above, except for explicit key and data.
+template <class Collection>
+typename Collection::value_type::second_type* const
+InsertOrReturnExisting(
+    Collection* const collection,
+    const typename Collection::value_type::first_type& key,
+    const typename Collection::value_type::second_type& data) {
+  return InsertOrReturnExisting(collection,
+                                typename Collection::value_type(key, data));
+}
+
+// Erases the collection item identified by the given key, and returns the value
+// associated with that key. It is assumed that the value (i.e., the
+// mapped_type) is a pointer. Returns NULL if the key was not found in the
+// collection.
+//
+// Examples:
+//   map<string, MyType*> my_map;
+//
+// One line cleanup:
+//     delete EraseKeyReturnValuePtr(&my_map, "abc");
+//
+// Use returned value:
+//     scoped_ptr<MyType> value_ptr(EraseKeyReturnValuePtr(&my_map, "abc"));
+//     if (value_ptr.get())
+//       value_ptr->DoSomething();
+//
+template <class Collection>
+typename Collection::value_type::second_type EraseKeyReturnValuePtr(
+    Collection* const collection,
+    const typename Collection::value_type::first_type& key) {
+  typename Collection::iterator it = collection->find(key);
+  if (it == collection->end()) {
+    return NULL;
+  }
+  typename Collection::value_type::second_type v = it->second;
+  collection->erase(it);
+  return v;
+}
+
+// Inserts all the keys from map_container into key_container, which must
+// support insert(MapContainer::key_type).
+//
+// Note: any initial contents of the key_container are not cleared.
+template <class MapContainer, class KeyContainer>
+void InsertKeysFromMap(const MapContainer& map_container,
+                       KeyContainer* key_container) {
+  GOOGLE_CHECK(key_container != NULL);
+  for (typename MapContainer::const_iterator it = map_container.begin();
+       it != map_container.end(); ++it) {
+    key_container->insert(it->first);
+  }
+}
+
+// Appends all the keys from map_container into key_container, which must
+// support push_back(MapContainer::key_type).
+//
+// Note: any initial contents of the key_container are not cleared.
+template <class MapContainer, class KeyContainer>
+void AppendKeysFromMap(const MapContainer& map_container,
+                       KeyContainer* key_container) {
+  GOOGLE_CHECK(key_container != NULL);
+  for (typename MapContainer::const_iterator it = map_container.begin();
+       it != map_container.end(); ++it) {
+    key_container->push_back(it->first);
+  }
+}
+
+// A more specialized overload of AppendKeysFromMap to optimize reallocations
+// for the common case in which we're appending keys to a vector and hence can
+// (and sometimes should) call reserve() first.
+//
+// (It would be possible to play SFINAE games to call reserve() for any
+// container that supports it, but this seems to get us 99% of what we need
+// without the complexity of a SFINAE-based solution.)
+template <class MapContainer, class KeyType>
+void AppendKeysFromMap(const MapContainer& map_container,
+                       vector<KeyType>* key_container) {
+  GOOGLE_CHECK(key_container != NULL);
+  // We now have the opportunity to call reserve(). Calling reserve() every
+  // time is a bad idea for some use cases: libstdc++'s implementation of
+  // vector<>::reserve() resizes the vector's backing store to exactly the
+  // given size (unless it's already at least that big). Because of this,
+  // the use case that involves appending a lot of small maps (total size
+  // N) one by one to a vector would be O(N^2). But never calling reserve()
+  // loses the opportunity to improve the use case of adding from a large
+  // map to an empty vector (this improves performance by up to 33%). A
+  // number of heuristics are possible; see the discussion in
+  // cl/34081696. Here we use the simplest one.
+  if (key_container->empty()) {
+    key_container->reserve(map_container.size());
+  }
+  for (typename MapContainer::const_iterator it = map_container.begin();
+       it != map_container.end(); ++it) {
+    key_container->push_back(it->first);
+  }
+}
+
+// Inserts all the values from map_container into value_container, which must
+// support push_back(MapContainer::mapped_type).
+//
+// Note: any initial contents of the value_container are not cleared.
+template <class MapContainer, class ValueContainer>
+void AppendValuesFromMap(const MapContainer& map_container,
+                         ValueContainer* value_container) {
+  GOOGLE_CHECK(value_container != NULL);
+  for (typename MapContainer::const_iterator it = map_container.begin();
+       it != map_container.end(); ++it) {
+    value_container->push_back(it->second);
+  }
+}
+
+// A more specialized overload of AppendValuesFromMap to optimize reallocations
+// for the common case in which we're appending values to a vector and hence
+// can (and sometimes should) call reserve() first.
+//
+// (It would be possible to play SFINAE games to call reserve() for any
+// container that supports it, but this seems to get us 99% of what we need
+// without the complexity of a SFINAE-based solution.)
+template <class MapContainer, class ValueType>
+void AppendValuesFromMap(const MapContainer& map_container,
+                         vector<ValueType>* value_container) {
+  GOOGLE_CHECK(value_container != NULL);
+  // See AppendKeysFromMap for why this is done.
+  if (value_container->empty()) {
+    value_container->reserve(map_container.size());
+  }
+  for (typename MapContainer::const_iterator it = map_container.begin();
+       it != map_container.end(); ++it) {
+    value_container->push_back(it->second);
+  }
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_MAP_UTIL_H__
diff --git a/protobuf/src/google/protobuf/stubs/once.cc b/protobuf/src/google/protobuf/stubs/once.cc
new file mode 100644
index 0000000..889c647
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/once.cc
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// emulates google3/base/once.h
+//
+// This header is intended to be included only by internal .cc files and
+// generated .pb.cc files.  Users should not use this directly.
+
+#include <google/protobuf/stubs/once.h>
+
+#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sched.h>
+#endif
+
+#include <google/protobuf/stubs/atomicops.h>
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+void SchedYield() {
+#ifdef _WIN32
+  Sleep(0);
+#else  // POSIX
+  sched_yield();
+#endif
+}
+
+}  // namespace
+
+void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure) {
+  internal::AtomicWord state = internal::Acquire_Load(once);
+  // Fast path. The provided closure was already executed.
+  if (state == ONCE_STATE_DONE) {
+    return;
+  }
+  // The closure execution did not complete yet. The once object can be in one
+  // of the two following states:
+  //   - UNINITIALIZED: We are the first thread calling this function.
+  //   - EXECUTING_CLOSURE: Another thread is already executing the closure.
+  //
+  // First, try to change the state from UNINITIALIZED to EXECUTING_CLOSURE
+  // atomically.
+  state = internal::Acquire_CompareAndSwap(
+      once, ONCE_STATE_UNINITIALIZED, ONCE_STATE_EXECUTING_CLOSURE);
+  if (state == ONCE_STATE_UNINITIALIZED) {
+    // We are the first thread to call this function, so we have to call the
+    // closure.
+    closure->Run();
+    internal::Release_Store(once, ONCE_STATE_DONE);
+  } else {
+    // Another thread has already started executing the closure. We need to
+    // wait until it completes the initialization.
+    while (state == ONCE_STATE_EXECUTING_CLOSURE) {
+      // Note that futex() could be used here on Linux as an improvement.
+      SchedYield();
+      state = internal::Acquire_Load(once);
+    }
+  }
+}
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
diff --git a/protobuf/src/google/protobuf/stubs/once.h b/protobuf/src/google/protobuf/stubs/once.h
new file mode 100644
index 0000000..cc62bba
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/once.h
@@ -0,0 +1,166 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// emulates google3/base/once.h
+//
+// This header is intended to be included only by internal .cc files and
+// generated .pb.cc files.  Users should not use this directly.
+//
+// This is basically a portable version of pthread_once().
+//
+// This header declares:
+// * A type called ProtobufOnceType.
+// * A macro GOOGLE_PROTOBUF_DECLARE_ONCE() which declares a variable of type
+//   ProtobufOnceType.  This is the only legal way to declare such a variable.
+//   The macro may only be used at the global scope (you cannot create local or
+//   class member variables of this type).
+// * A function GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()).
+//   This function, when invoked multiple times given the same ProtobufOnceType
+//   object, will invoke init_func on the first call only, and will make sure
+//   none of the calls return before that first call to init_func has finished.
+// * The user can provide a parameter which GoogleOnceInit() forwards to the
+//   user-provided function when it is called. Usage example:
+//     int a = 10;
+//     GoogleOnceInit(&my_once, &MyFunctionExpectingIntArgument, &a);
+// * This implementation guarantees that ProtobufOnceType is a POD (i.e. no
+//   static initializer generated).
+//
+// This implements a way to perform lazy initialization.  It's more efficient
+// than using mutexes as no lock is needed if initialization has already
+// happened.
+//
+// Example usage:
+//   void Init();
+//   GOOGLE_PROTOBUF_DECLARE_ONCE(once_init);
+//
+//   // Calls Init() exactly once.
+//   void InitOnce() {
+//     GoogleOnceInit(&once_init, &Init);
+//   }
+//
+// Note that if GoogleOnceInit() is called before main() has begun, it must
+// only be called by the thread that will eventually call main() -- that is,
+// the thread that performs dynamic initialization.  In general this is a safe
+// assumption since people don't usually construct threads before main() starts,
+// but it is technically not guaranteed.  Unfortunately, Win32 provides no way
+// whatsoever to statically-initialize its synchronization primitives, so our
+// only choice is to assume that dynamic initialization is single-threaded.
+
+#ifndef GOOGLE_PROTOBUF_STUBS_ONCE_H__
+#define GOOGLE_PROTOBUF_STUBS_ONCE_H__
+
+#include <google/protobuf/stubs/atomicops.h>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+typedef bool ProtobufOnceType;
+
+#define GOOGLE_PROTOBUF_ONCE_INIT false
+
+inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
+  if (!*once) {
+    *once = true;
+    init_func();
+  }
+}
+
+template <typename Arg>
+inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg),
+    Arg arg) {
+  if (!*once) {
+    *once = true;
+    init_func(arg);
+  }
+}
+
+#else
+
+enum {
+  ONCE_STATE_UNINITIALIZED = 0,
+  ONCE_STATE_EXECUTING_CLOSURE = 1,
+  ONCE_STATE_DONE = 2
+};
+
+typedef internal::AtomicWord ProtobufOnceType;
+
+#define GOOGLE_PROTOBUF_ONCE_INIT ::google::protobuf::ONCE_STATE_UNINITIALIZED
+
+LIBPROTOBUF_EXPORT
+void GoogleOnceInitImpl(ProtobufOnceType* once, Closure* closure);
+
+inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)()) {
+  if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
+    internal::FunctionClosure0 func(init_func, false);
+    GoogleOnceInitImpl(once, &func);
+  }
+}
+
+template <typename Arg>
+inline void GoogleOnceInit(ProtobufOnceType* once, void (*init_func)(Arg*),
+    Arg* arg) {
+  if (internal::Acquire_Load(once) != ONCE_STATE_DONE) {
+    internal::FunctionClosure1<Arg*> func(init_func, false, arg);
+    GoogleOnceInitImpl(once, &func);
+  }
+}
+
+#endif  // GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+
+class GoogleOnceDynamic {
+ public:
+  GoogleOnceDynamic() : state_(GOOGLE_PROTOBUF_ONCE_INIT) { }
+
+  // If this->Init() has not been called before by any thread,
+  // execute (*func_with_arg)(arg) then return.
+  // Otherwise, wait until that prior invocation has finished
+  // executing its function, then return.
+  template<typename T>
+  void Init(void (*func_with_arg)(T*), T* arg) {
+    GoogleOnceInit<T>(&this->state_,
+                      func_with_arg,
+                      arg);
+  }
+ private:
+  ProtobufOnceType state_;
+};
+
+#define GOOGLE_PROTOBUF_DECLARE_ONCE(NAME) \
+  ::google::protobuf::ProtobufOnceType NAME = GOOGLE_PROTOBUF_ONCE_INIT
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_ONCE_H__
diff --git a/protobuf/src/google/protobuf/stubs/once_unittest.cc b/protobuf/src/google/protobuf/stubs/once_unittest.cc
new file mode 100644
index 0000000..cb5a20d
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/once_unittest.cc
@@ -0,0 +1,253 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <pthread.h>
+#endif
+
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+class OnceInitTest : public testing::Test {
+ protected:
+  void SetUp() {
+    state_ = INIT_NOT_STARTED;
+    current_test_ = this;
+  }
+
+  // Since ProtobufOnceType is only allowed to be allocated in static storage,
+  // each test must use a different pair of ProtobufOnceType objects which it
+  // must declare itself.
+  void SetOnces(ProtobufOnceType* once, ProtobufOnceType* recursive_once) {
+    once_ = once;
+    recursive_once_ = recursive_once;
+  }
+
+  void InitOnce() {
+    GoogleOnceInit(once_, &InitStatic);
+  }
+  void InitRecursiveOnce() {
+    GoogleOnceInit(recursive_once_, &InitRecursiveStatic);
+  }
+
+  void BlockInit() { init_blocker_.Lock(); }
+  void UnblockInit() { init_blocker_.Unlock(); }
+
+  class TestThread {
+   public:
+    TestThread(Closure* callback)
+        : done_(false), joined_(false), callback_(callback) {
+#ifdef _WIN32
+      thread_ = CreateThread(NULL, 0, &Start, this, 0, NULL);
+#else
+      pthread_create(&thread_, NULL, &Start, this);
+#endif
+    }
+    ~TestThread() {
+      if (!joined_) Join();
+    }
+
+    bool IsDone() {
+      MutexLock lock(&done_mutex_);
+      return done_;
+    }
+    void Join() {
+      joined_ = true;
+#ifdef _WIN32
+      WaitForSingleObject(thread_, INFINITE);
+      CloseHandle(thread_);
+#else
+      pthread_join(thread_, NULL);
+#endif
+    }
+
+   private:
+#ifdef _WIN32
+    HANDLE thread_;
+#else
+    pthread_t thread_;
+#endif
+
+    Mutex done_mutex_;
+    bool done_;
+    bool joined_;
+    Closure* callback_;
+
+#ifdef _WIN32
+    static DWORD WINAPI Start(LPVOID arg) {
+#else
+    static void* Start(void* arg) {
+#endif
+      reinterpret_cast<TestThread*>(arg)->Run();
+      return 0;
+    }
+
+    void Run() {
+      callback_->Run();
+      MutexLock lock(&done_mutex_);
+      done_ = true;
+    }
+  };
+
+  TestThread* RunInitOnceInNewThread() {
+    return new TestThread(NewCallback(this, &OnceInitTest::InitOnce));
+  }
+  TestThread* RunInitRecursiveOnceInNewThread() {
+    return new TestThread(NewCallback(this, &OnceInitTest::InitRecursiveOnce));
+  }
+
+  enum State {
+    INIT_NOT_STARTED,
+    INIT_STARTED,
+    INIT_DONE
+  };
+  State CurrentState() {
+    MutexLock lock(&mutex_);
+    return state_;
+  }
+
+  void WaitABit() {
+#ifdef _WIN32
+    Sleep(1000);
+#else
+    sleep(1);
+#endif
+  }
+
+ private:
+  Mutex mutex_;
+  Mutex init_blocker_;
+  State state_;
+  ProtobufOnceType* once_;
+  ProtobufOnceType* recursive_once_;
+
+  void Init() {
+    MutexLock lock(&mutex_);
+    EXPECT_EQ(INIT_NOT_STARTED, state_);
+    state_ = INIT_STARTED;
+    mutex_.Unlock();
+    init_blocker_.Lock();
+    init_blocker_.Unlock();
+    mutex_.Lock();
+    state_ = INIT_DONE;
+  }
+
+  static OnceInitTest* current_test_;
+  static void InitStatic() { current_test_->Init(); }
+  static void InitRecursiveStatic() { current_test_->InitOnce(); }
+};
+
+OnceInitTest* OnceInitTest::current_test_ = NULL;
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(simple_once);
+
+TEST_F(OnceInitTest, Simple) {
+  SetOnces(&simple_once, NULL);
+
+  EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
+  InitOnce();
+  EXPECT_EQ(INIT_DONE, CurrentState());
+
+  // Calling again has no effect.
+  InitOnce();
+  EXPECT_EQ(INIT_DONE, CurrentState());
+}
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(recursive_once1);
+GOOGLE_PROTOBUF_DECLARE_ONCE(recursive_once2);
+
+TEST_F(OnceInitTest, Recursive) {
+  SetOnces(&recursive_once1, &recursive_once2);
+
+  EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
+  InitRecursiveOnce();
+  EXPECT_EQ(INIT_DONE, CurrentState());
+}
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_once);
+
+TEST_F(OnceInitTest, MultipleThreads) {
+  SetOnces(&multiple_threads_once, NULL);
+
+  scoped_ptr<TestThread> threads[4];
+  EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
+  for (int i = 0; i < 4; i++) {
+    threads[i].reset(RunInitOnceInNewThread());
+  }
+  for (int i = 0; i < 4; i++) {
+    threads[i]->Join();
+  }
+  EXPECT_EQ(INIT_DONE, CurrentState());
+}
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_blocked_once1);
+GOOGLE_PROTOBUF_DECLARE_ONCE(multiple_threads_blocked_once2);
+
+TEST_F(OnceInitTest, MultipleThreadsBlocked) {
+  SetOnces(&multiple_threads_blocked_once1, &multiple_threads_blocked_once2);
+
+  scoped_ptr<TestThread> threads[8];
+  EXPECT_EQ(INIT_NOT_STARTED, CurrentState());
+
+  BlockInit();
+  for (int i = 0; i < 4; i++) {
+    threads[i].reset(RunInitOnceInNewThread());
+  }
+  for (int i = 4; i < 8; i++) {
+    threads[i].reset(RunInitRecursiveOnceInNewThread());
+  }
+
+  WaitABit();
+
+  // We should now have one thread blocked inside Init(), four blocked waiting
+  // for Init() to complete, and three blocked waiting for InitRecursive() to
+  // complete.
+  EXPECT_EQ(INIT_STARTED, CurrentState());
+  UnblockInit();
+
+  for (int i = 0; i < 8; i++) {
+    threads[i]->Join();
+  }
+  EXPECT_EQ(INIT_DONE, CurrentState());
+}
+
+}  // anonymous namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/stubs/platform_macros.h b/protobuf/src/google/protobuf/stubs/platform_macros.h
new file mode 100644
index 0000000..7956d07
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/platform_macros.h
@@ -0,0 +1,103 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
+#define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
+
+#include <google/protobuf/stubs/common.h>
+
+#define GOOGLE_PROTOBUF_PLATFORM_ERROR \
+#error "Host platform was not detected as supported by protobuf"
+
+// Processor architecture detection.  For more info on what's defined, see:
+//   http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+//   http://www.agner.org/optimize/calling_conventions.pdf
+//   or with gcc, run: "echo | gcc -E -dM -"
+#if defined(_M_X64) || defined(__x86_64__)
+#define GOOGLE_PROTOBUF_ARCH_X64 1
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#elif defined(_M_IX86) || defined(__i386__)
+#define GOOGLE_PROTOBUF_ARCH_IA32 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(__QNX__)
+#define GOOGLE_PROTOBUF_ARCH_ARM_QNX 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(__ARMEL__)
+#define GOOGLE_PROTOBUF_ARCH_ARM 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(__aarch64__)
+#define GOOGLE_PROTOBUF_ARCH_AARCH64 1
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#elif defined(__MIPSEL__)
+#if defined(__LP64__)
+#define GOOGLE_PROTOBUF_ARCH_MIPS64 1
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#else
+#define GOOGLE_PROTOBUF_ARCH_MIPS 1
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#endif
+#elif defined(__pnacl__)
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#elif defined(sparc)
+#define GOOGLE_PROTOBUF_ARCH_SPARC 1
+#ifdef SOLARIS_64BIT_ENABLED
+#define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+#else
+#define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+#endif
+#elif defined(__GNUC__)
+# if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4))
+// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h
+# elif defined(__clang__)
+#  if !__has_extension(c_atomic)
+GOOGLE_PROTOBUF_PLATFORM_ERROR
+#  endif
+// We fallback to the generic Clang/GCC >= 4.7 implementation in atomicops.h
+# endif
+# if __LP64__
+#  define GOOGLE_PROTOBUF_ARCH_64_BIT 1
+# else
+#  define GOOGLE_PROTOBUF_ARCH_32_BIT 1
+# endif
+#else
+GOOGLE_PROTOBUF_PLATFORM_ERROR
+#endif
+
+#if defined(__APPLE__)
+#define GOOGLE_PROTOBUF_OS_APPLE
+#elif defined(__native_client__)
+#define GOOGLE_PROTOBUF_OS_NACL
+#elif defined(sun)
+#define GOOGLE_PROTOBUF_OS_SOLARIS
+#endif
+
+#undef GOOGLE_PROTOBUF_PLATFORM_ERROR
+
+#endif  // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
diff --git a/protobuf/src/google/protobuf/stubs/shared_ptr.h b/protobuf/src/google/protobuf/stubs/shared_ptr.h
new file mode 100644
index 0000000..d250bf4
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/shared_ptr.h
@@ -0,0 +1,470 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2014 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/util/gtl/shared_ptr.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
+#define GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
+
+#include <google/protobuf/stubs/atomicops.h>
+
+#include <algorithm>  // for swap
+#include <stddef.h>
+#include <memory>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Alias to std::shared_ptr for any C++11 platform,
+// and for any supported MSVC compiler.
+#if !defined(UTIL_GTL_USE_STD_SHARED_PTR) && \
+    (defined(COMPILER_MSVC) || defined(LANG_CXX11))
+#define UTIL_GTL_USE_STD_SHARED_PTR 1
+#endif
+
+#if defined(UTIL_GTL_USE_STD_SHARED_PTR) && UTIL_GTL_USE_STD_SHARED_PTR
+
+// These are transitional.  They will be going away soon.
+// Please just #include <memory> and just type std::shared_ptr yourself, instead
+// of relying on this file.
+//
+// Migration doc: http://go/std-shared-ptr-lsc
+using std::enable_shared_from_this;
+using std::shared_ptr;
+using std::static_pointer_cast;
+using std::weak_ptr;
+
+#else  // below, UTIL_GTL_USE_STD_SHARED_PTR not set or set to 0.
+
+// For everything else there is the google3 implementation.
+inline bool RefCountDec(volatile Atomic32 *ptr) {
+  return Barrier_AtomicIncrement(ptr, -1) != 0;
+}
+
+inline void RefCountInc(volatile Atomic32 *ptr) {
+  NoBarrier_AtomicIncrement(ptr, 1);
+}
+
+template <typename T> class shared_ptr;
+template <typename T> class weak_ptr;
+
+// This class is an internal implementation detail for shared_ptr. If two
+// shared_ptrs point to the same object, they also share a control block.
+// An "empty" shared_pointer refers to NULL and also has a NULL control block.
+// It contains all of the state that's needed for reference counting or any
+// other kind of resource management. In this implementation the control block
+// happens to consist of two atomic words, the reference count (the number
+// of shared_ptrs that share ownership of the object) and the weak count
+// (the number of weak_ptrs that observe the object, plus 1 if the
+// refcount is nonzero).
+//
+// The "plus 1" is to prevent a race condition in the shared_ptr and
+// weak_ptr destructors. We need to make sure the control block is
+// only deleted once, so we need to make sure that at most one
+// object sees the weak count decremented from 1 to 0.
+class SharedPtrControlBlock {
+  template <typename T> friend class shared_ptr;
+  template <typename T> friend class weak_ptr;
+ private:
+  SharedPtrControlBlock() : refcount_(1), weak_count_(1) { }
+  Atomic32 refcount_;
+  Atomic32 weak_count_;
+};
+
+// Forward declaration. The class is defined below.
+template <typename T> class enable_shared_from_this;
+
+template <typename T>
+class shared_ptr {
+  template <typename U> friend class weak_ptr;
+ public:
+  typedef T element_type;
+
+  shared_ptr() : ptr_(NULL), control_block_(NULL) {}
+
+  explicit shared_ptr(T* ptr)
+      : ptr_(ptr),
+        control_block_(ptr != NULL ? new SharedPtrControlBlock : NULL) {
+    // If p is non-null and T inherits from enable_shared_from_this, we
+    // set up the data that shared_from_this needs.
+    MaybeSetupWeakThis(ptr);
+  }
+
+  // Copy constructor: makes this object a copy of ptr, and increments
+  // the reference count.
+  template <typename U>
+  shared_ptr(const shared_ptr<U>& ptr)
+      : ptr_(NULL),
+        control_block_(NULL) {
+    Initialize(ptr);
+  }
+  // Need non-templated version to prevent the compiler-generated default
+  shared_ptr(const shared_ptr<T>& ptr)
+      : ptr_(NULL),
+        control_block_(NULL) {
+    Initialize(ptr);
+  }
+
+  // Assignment operator. Replaces the existing shared_ptr with ptr.
+  // Increment ptr's reference count and decrement the one being replaced.
+  template <typename U>
+  shared_ptr<T>& operator=(const shared_ptr<U>& ptr) {
+    if (ptr_ != ptr.ptr_) {
+      shared_ptr<T> me(ptr);   // will hold our previous state to be destroyed.
+      swap(me);
+    }
+    return *this;
+  }
+
+  // Need non-templated version to prevent the compiler-generated default
+  shared_ptr<T>& operator=(const shared_ptr<T>& ptr) {
+    if (ptr_ != ptr.ptr_) {
+      shared_ptr<T> me(ptr);   // will hold our previous state to be destroyed.
+      swap(me);
+    }
+    return *this;
+  }
+
+  // TODO(austern): Consider providing this constructor. The draft C++ standard
+  // (20.8.10.2.1) includes it. However, it says that this constructor throws
+  // a bad_weak_ptr exception when ptr is expired. Is it better to provide this
+  // constructor and make it do something else, like fail with a CHECK, or to
+  // leave this constructor out entirely?
+  //
+  // template <typename U>
+  // shared_ptr(const weak_ptr<U>& ptr);
+
+  ~shared_ptr() {
+    if (ptr_ != NULL) {
+      if (!RefCountDec(&control_block_->refcount_)) {
+        delete ptr_;
+
+        // weak_count_ is defined as the number of weak_ptrs that observe
+        // ptr_, plus 1 if refcount_ is nonzero.
+        if (!RefCountDec(&control_block_->weak_count_)) {
+          delete control_block_;
+        }
+      }
+    }
+  }
+
+  // Replaces underlying raw pointer with the one passed in.  The reference
+  // count is set to one (or zero if the pointer is NULL) for the pointer
+  // being passed in and decremented for the one being replaced.
+  //
+  // If you have a compilation error with this code, make sure you aren't
+  // passing NULL, nullptr, or 0 to this function.  Call reset without an
+  // argument to reset to a null ptr.
+  template <typename Y>
+  void reset(Y* p) {
+    if (p != ptr_) {
+      shared_ptr<T> tmp(p);
+      tmp.swap(*this);
+    }
+  }
+
+  void reset() {
+    reset(static_cast<T*>(NULL));
+  }
+
+  // Exchanges the contents of this with the contents of r.  This function
+  // supports more efficient swapping since it eliminates the need for a
+  // temporary shared_ptr object.
+  void swap(shared_ptr<T>& r) {
+    using std::swap;  // http://go/using-std-swap
+    swap(ptr_, r.ptr_);
+    swap(control_block_, r.control_block_);
+  }
+
+  // The following function is useful for gaining access to the underlying
+  // pointer when a shared_ptr remains in scope so the reference-count is
+  // known to be > 0 (e.g. for parameter passing).
+  T* get() const {
+    return ptr_;
+  }
+
+  T& operator*() const {
+    return *ptr_;
+  }
+
+  T* operator->() const {
+    return ptr_;
+  }
+
+  long use_count() const {
+    return control_block_ ? control_block_->refcount_ : 1;
+  }
+
+  bool unique() const {
+    return use_count() == 1;
+  }
+
+ private:
+  // If r is non-empty, initialize *this to share ownership with r,
+  // increasing the underlying reference count.
+  // If r is empty, *this remains empty.
+  // Requires: this is empty, namely this->ptr_ == NULL.
+  template <typename U>
+  void Initialize(const shared_ptr<U>& r) {
+    // This performs a static_cast on r.ptr_ to U*, which is a no-op since it
+    // is already a U*. So initialization here requires that r.ptr_ is
+    // implicitly convertible to T*.
+    InitializeWithStaticCast<U>(r);
+  }
+
+  // Initializes *this as described in Initialize, but additionally performs a
+  // static_cast from r.ptr_ (V*) to U*.
+  // NOTE(gfc): We'd need a more general form to support const_pointer_cast and
+  // dynamic_pointer_cast, but those operations are sufficiently discouraged
+  // that supporting static_pointer_cast is sufficient.
+  template <typename U, typename V>
+  void InitializeWithStaticCast(const shared_ptr<V>& r) {
+    if (r.control_block_ != NULL) {
+      RefCountInc(&r.control_block_->refcount_);
+
+      ptr_ = static_cast<U*>(r.ptr_);
+      control_block_ = r.control_block_;
+    }
+  }
+
+  // Helper function for the constructor that takes a raw pointer. If T
+  // doesn't inherit from enable_shared_from_this<T> then we have nothing to
+  // do, so this function is trivial and inline. The other version is declared
+  // out of line, after the class definition of enable_shared_from_this.
+  void MaybeSetupWeakThis(enable_shared_from_this<T>* ptr);
+  void MaybeSetupWeakThis(...) { }
+
+  T* ptr_;
+  SharedPtrControlBlock* control_block_;
+
+#ifndef SWIG
+  template <typename U>
+  friend class shared_ptr;
+
+  template <typename U, typename V>
+  friend shared_ptr<U> static_pointer_cast(const shared_ptr<V>& rhs);
+#endif
+};
+
+// Matches the interface of std::swap as an aid to generic programming.
+template <typename T> void swap(shared_ptr<T>& r, shared_ptr<T>& s) {
+  r.swap(s);
+}
+
+template <typename T, typename U>
+shared_ptr<T> static_pointer_cast(const shared_ptr<U>& rhs) {
+  shared_ptr<T> lhs;
+  lhs.template InitializeWithStaticCast<T>(rhs);
+  return lhs;
+}
+
+// See comments at the top of the file for a description of why this
+// class exists, and the draft C++ standard (as of July 2009 the
+// latest draft is N2914) for the detailed specification.
+template <typename T>
+class weak_ptr {
+  template <typename U> friend class weak_ptr;
+ public:
+  typedef T element_type;
+
+  // Create an empty (i.e. already expired) weak_ptr.
+  weak_ptr() : ptr_(NULL), control_block_(NULL) { }
+
+  // Create a weak_ptr that observes the same object that ptr points
+  // to.  Note that there is no race condition here: we know that the
+  // control block can't disappear while we're looking at it because
+  // it is owned by at least one shared_ptr, ptr.
+  template <typename U> weak_ptr(const shared_ptr<U>& ptr) {
+    CopyFrom(ptr.ptr_, ptr.control_block_);
+  }
+
+  // Copy a weak_ptr. The object it points to might disappear, but we
+  // don't care: we're only working with the control block, and it can't
+  // disappear while we're looking at because it's owned by at least one
+  // weak_ptr, ptr.
+  template <typename U> weak_ptr(const weak_ptr<U>& ptr) {
+    CopyFrom(ptr.ptr_, ptr.control_block_);
+  }
+
+  // Need non-templated version to prevent default copy constructor
+  weak_ptr(const weak_ptr& ptr) {
+    CopyFrom(ptr.ptr_, ptr.control_block_);
+  }
+
+  // Destroy the weak_ptr. If no shared_ptr owns the control block, and if
+  // we are the last weak_ptr to own it, then it can be deleted. Note that
+  // weak_count_ is defined as the number of weak_ptrs sharing this control
+  // block, plus 1 if there are any shared_ptrs. We therefore know that it's
+  // safe to delete the control block when weak_count_ reaches 0, without
+  // having to perform any additional tests.
+  ~weak_ptr() {
+    if (control_block_ != NULL &&
+        !RefCountDec(&control_block_->weak_count_)) {
+      delete control_block_;
+    }
+  }
+
+  weak_ptr& operator=(const weak_ptr& ptr) {
+    if (&ptr != this) {
+      weak_ptr tmp(ptr);
+      tmp.swap(*this);
+    }
+    return *this;
+  }
+  template <typename U> weak_ptr& operator=(const weak_ptr<U>& ptr) {
+    weak_ptr tmp(ptr);
+    tmp.swap(*this);
+    return *this;
+  }
+  template <typename U> weak_ptr& operator=(const shared_ptr<U>& ptr) {
+    weak_ptr tmp(ptr);
+    tmp.swap(*this);
+    return *this;
+  }
+
+  void swap(weak_ptr& ptr) {
+    using std::swap;  // http://go/using-std-swap
+    swap(ptr_, ptr.ptr_);
+    swap(control_block_, ptr.control_block_);
+  }
+
+  void reset() {
+    weak_ptr tmp;
+    tmp.swap(*this);
+  }
+
+  // Return the number of shared_ptrs that own the object we are observing.
+  // Note that this number can be 0 (if this pointer has expired).
+  long use_count() const {
+    return control_block_ != NULL ? control_block_->refcount_ : 0;
+  }
+
+  bool expired() const { return use_count() == 0; }
+
+  // Return a shared_ptr that owns the object we are observing. If we
+  // have expired, the shared_ptr will be empty. We have to be careful
+  // about concurrency, though, since some other thread might be
+  // destroying the last owning shared_ptr while we're in this
+  // function.  We want to increment the refcount only if it's nonzero
+  // and get the new value, and we want that whole operation to be
+  // atomic.
+  shared_ptr<T> lock() const {
+    shared_ptr<T> result;
+    if (control_block_ != NULL) {
+      Atomic32 old_refcount;
+      do {
+        old_refcount = control_block_->refcount_;
+        if (old_refcount == 0)
+          break;
+      } while (old_refcount !=
+               NoBarrier_CompareAndSwap(
+                   &control_block_->refcount_, old_refcount,
+                   old_refcount + 1));
+      if (old_refcount > 0) {
+        result.ptr_ = ptr_;
+        result.control_block_ = control_block_;
+      }
+    }
+
+    return result;
+  }
+
+ private:
+  void CopyFrom(T* ptr, SharedPtrControlBlock* control_block) {
+    ptr_ = ptr;
+    control_block_ = control_block;
+    if (control_block_ != NULL)
+      RefCountInc(&control_block_->weak_count_);
+  }
+
+ private:
+  element_type* ptr_;
+  SharedPtrControlBlock* control_block_;
+};
+
+template <typename T> void swap(weak_ptr<T>& r, weak_ptr<T>& s) {
+  r.swap(s);
+}
+
+// See comments at the top of the file for a description of why this class
+// exists, and section 20.8.10.5 of the draft C++ standard (as of July 2009
+// the latest draft is N2914) for the detailed specification.
+template <typename T>
+class enable_shared_from_this {
+  friend class shared_ptr<T>;
+ public:
+  // Precondition: there must be a shared_ptr that owns *this and that was
+  // created, directly or indirectly, from a raw pointer of type T*. (The
+  // latter part of the condition is technical but not quite redundant; it
+  // rules out some complicated uses involving inheritance hierarchies.)
+  shared_ptr<T> shared_from_this() {
+    // Behavior is undefined if the precondition isn't satisfied; we choose
+    // to die with a CHECK failure.
+    CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
+    return weak_this_.lock();
+  }
+  shared_ptr<const T> shared_from_this() const {
+    CHECK(!weak_this_.expired()) << "No shared_ptr owns this object";
+    return weak_this_.lock();
+  }
+
+ protected:
+  enable_shared_from_this() { }
+  enable_shared_from_this(const enable_shared_from_this& other) { }
+  enable_shared_from_this& operator=(const enable_shared_from_this& other) {
+    return *this;
+  }
+  ~enable_shared_from_this() { }
+
+ private:
+  weak_ptr<T> weak_this_;
+};
+
+// This is a helper function called by shared_ptr's constructor from a raw
+// pointer. If T inherits from enable_shared_from_this<T>, it sets up
+// weak_this_ so that shared_from_this works correctly. If T does not inherit
+// from weak_this we get a different overload, defined inline, which does
+// nothing.
+template<typename T>
+void shared_ptr<T>::MaybeSetupWeakThis(enable_shared_from_this<T>* ptr) {
+  if (ptr) {
+    CHECK(ptr->weak_this_.expired()) << "Object already owned by a shared_ptr";
+    ptr->weak_this_ = *this;
+  }
+}
+
+#endif  // UTIL_GTL_USE_STD_SHARED_PTR
+
+}  // internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_SHARED_PTR_H__
diff --git a/protobuf/src/google/protobuf/stubs/stl_util-inl.h b/protobuf/src/google/protobuf/stubs/stl_util-inl.h
new file mode 100644
index 0000000..a2e671b
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/stl_util-inl.h
@@ -0,0 +1,121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+// 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/protobuf/src/google/protobuf/stubs/stl_util.h b/protobuf/src/google/protobuf/stubs/stl_util.h
new file mode 100644
index 0000000..9e4c82a
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/stl_util.h
@@ -0,0 +1,121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/util/gtl/stl_util.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STL_UTIL_H__
+#define GOOGLE_PROTOBUF_STUBS_STL_UTIL_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_H__
diff --git a/protobuf/src/google/protobuf/stubs/stringprintf.cc b/protobuf/src/google/protobuf/stubs/stringprintf.cc
new file mode 100644
index 0000000..3272d8e
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/stringprintf.cc
@@ -0,0 +1,175 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/base/stringprintf.cc
+
+#include <google/protobuf/stubs/stringprintf.h>
+
+#include <errno.h>
+#include <stdarg.h> // For va_list and related operations
+#include <stdio.h> // MSVC requires this for _vsnprintf
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/testing/googletest.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _MSC_VER
+enum { IS_COMPILER_MSVC = 1 };
+#ifndef va_copy
+// Define va_copy for MSVC. This is a hack, assuming va_list is simply a
+// pointer into the stack and is safe to copy.
+#define va_copy(dest, src) ((dest) = (src))
+#endif
+#else
+enum { IS_COMPILER_MSVC = 0 };
+#endif
+
+void StringAppendV(string* dst, const char* format, va_list ap) {
+  // First try with a small fixed size buffer
+  static const int kSpaceLength = 1024;
+  char space[kSpaceLength];
+
+  // It's possible for methods that use a va_list to invalidate
+  // the data in it upon use.  The fix is to make a copy
+  // of the structure before using it and use that copy instead.
+  va_list backup_ap;
+  va_copy(backup_ap, ap);
+  int result = vsnprintf(space, kSpaceLength, format, backup_ap);
+  va_end(backup_ap);
+
+  if (result < kSpaceLength) {
+    if (result >= 0) {
+      // Normal case -- everything fit.
+      dst->append(space, result);
+      return;
+    }
+
+    if (IS_COMPILER_MSVC) {
+      // Error or MSVC running out of space.  MSVC 8.0 and higher
+      // can be asked about space needed with the special idiom below:
+      va_copy(backup_ap, ap);
+      result = vsnprintf(NULL, 0, format, backup_ap);
+      va_end(backup_ap);
+    }
+
+    if (result < 0) {
+      // Just an error.
+      return;
+    }
+  }
+
+  // Increase the buffer size to the size requested by vsnprintf,
+  // plus one for the closing \0.
+  int length = result+1;
+  char* buf = new char[length];
+
+  // Restore the va_list before we use it again
+  va_copy(backup_ap, ap);
+  result = vsnprintf(buf, length, format, backup_ap);
+  va_end(backup_ap);
+
+  if (result >= 0 && result < length) {
+    // It fit
+    dst->append(buf, result);
+  }
+  delete[] buf;
+}
+
+
+string StringPrintf(const char* format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  string result;
+  StringAppendV(&result, format, ap);
+  va_end(ap);
+  return result;
+}
+
+const string& SStringPrintf(string* dst, const char* format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  dst->clear();
+  StringAppendV(dst, format, ap);
+  va_end(ap);
+  return *dst;
+}
+
+void StringAppendF(string* dst, const char* format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  StringAppendV(dst, format, ap);
+  va_end(ap);
+}
+
+// Max arguments supported by StringPrintVector
+const int kStringPrintfVectorMaxArgs = 32;
+
+// An empty block of zero for filler arguments.  This is const so that if
+// printf tries to write to it (via %n) then the program gets a SIGSEGV
+// and we can fix the problem or protect against an attack.
+static const char string_printf_empty_block[256] = { '\0' };
+
+string StringPrintfVector(const char* format, const vector<string>& v) {
+  GOOGLE_CHECK_LE(v.size(), kStringPrintfVectorMaxArgs)
+      << "StringPrintfVector currently only supports up to "
+      << kStringPrintfVectorMaxArgs << " arguments. "
+      << "Feel free to add support for more if you need it.";
+
+  // Add filler arguments so that bogus format+args have a harder time
+  // crashing the program, corrupting the program (%n),
+  // or displaying random chunks of memory to users.
+
+  const char* cstr[kStringPrintfVectorMaxArgs];
+  for (int i = 0; i < v.size(); ++i) {
+    cstr[i] = v[i].c_str();
+  }
+  for (int i = v.size(); i < GOOGLE_ARRAYSIZE(cstr); ++i) {
+    cstr[i] = &string_printf_empty_block[0];
+  }
+
+  // I do not know any way to pass kStringPrintfVectorMaxArgs arguments,
+  // or any way to build a va_list by hand, or any API for printf
+  // that accepts an array of arguments.  The best I can do is stick
+  // this COMPILE_ASSERT right next to the actual statement.
+
+  GOOGLE_COMPILE_ASSERT(kStringPrintfVectorMaxArgs == 32, arg_count_mismatch);
+  return StringPrintf(format,
+                      cstr[0], cstr[1], cstr[2], cstr[3], cstr[4],
+                      cstr[5], cstr[6], cstr[7], cstr[8], cstr[9],
+                      cstr[10], cstr[11], cstr[12], cstr[13], cstr[14],
+                      cstr[15], cstr[16], cstr[17], cstr[18], cstr[19],
+                      cstr[20], cstr[21], cstr[22], cstr[23], cstr[24],
+                      cstr[25], cstr[26], cstr[27], cstr[28], cstr[29],
+                      cstr[30], cstr[31]);
+}
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/stubs/stringprintf.h b/protobuf/src/google/protobuf/stubs/stringprintf.h
new file mode 100644
index 0000000..ab1ab55
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/stringprintf.h
@@ -0,0 +1,76 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/base/stringprintf.h
+//
+// Printf variants that place their output in a C++ string.
+//
+// Usage:
+//      string result = StringPrintf("%d %s\n", 10, "hello");
+//      SStringPrintf(&result, "%d %s\n", 10, "hello");
+//      StringAppendF(&result, "%d %s\n", 20, "there");
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
+#define GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
+
+#include <stdarg.h>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+// Return a C++ string
+LIBPROTOBUF_EXPORT extern string StringPrintf(const char* format, ...);
+
+// Store result into a supplied string and return it
+LIBPROTOBUF_EXPORT extern const string& SStringPrintf(string* dst, const char* format, ...);
+
+// Append result to a supplied string
+LIBPROTOBUF_EXPORT extern void StringAppendF(string* dst, const char* format, ...);
+
+// Lower-level routine that takes a va_list and appends to a specified
+// string.  All other routines are just convenience wrappers around it.
+LIBPROTOBUF_EXPORT extern void StringAppendV(string* dst, const char* format, va_list ap);
+
+// The max arguments supported by StringPrintfVector
+LIBPROTOBUF_EXPORT extern const int kStringPrintfVectorMaxArgs;
+
+// You can use this version when all your arguments are strings, but
+// you don't know how many arguments you'll have at compile time.
+// StringPrintfVector will LOG(FATAL) if v.size() > kStringPrintfVectorMaxArgs
+LIBPROTOBUF_EXPORT extern string StringPrintfVector(const char* format, const vector<string>& v);
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_STRINGPRINTF_H
diff --git a/protobuf/src/google/protobuf/stubs/stringprintf_unittest.cc b/protobuf/src/google/protobuf/stubs/stringprintf_unittest.cc
new file mode 100644
index 0000000..15895e5
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/stringprintf_unittest.cc
@@ -0,0 +1,152 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2012 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/base/stringprintf_unittest.cc
+
+#include <google/protobuf/stubs/stringprintf.h>
+
+#include <cerrno>
+#include <string>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+TEST(StringPrintfTest, Empty) {
+#if 0
+  // gcc 2.95.3, gcc 4.1.0, and gcc 4.2.2 all warn about this:
+  // warning: zero-length printf format string.
+  // so we do not allow them in google3.
+  EXPECT_EQ("", StringPrintf(""));
+#endif
+  EXPECT_EQ("", StringPrintf("%s", string().c_str()));
+  EXPECT_EQ("", StringPrintf("%s", ""));
+}
+
+TEST(StringPrintfTest, Misc) {
+// MSVC and mingw does not support $ format specifier.
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+  EXPECT_EQ("123hello w", StringPrintf("%3$d%2$s %1$c", 'w', "hello", 123));
+#endif  // !_MSC_VER
+}
+
+TEST(StringAppendFTest, Empty) {
+  string value("Hello");
+  const char* empty = "";
+  StringAppendF(&value, "%s", empty);
+  EXPECT_EQ("Hello", value);
+}
+
+TEST(StringAppendFTest, EmptyString) {
+  string value("Hello");
+  StringAppendF(&value, "%s", "");
+  EXPECT_EQ("Hello", value);
+}
+
+TEST(StringAppendFTest, String) {
+  string value("Hello");
+  StringAppendF(&value, " %s", "World");
+  EXPECT_EQ("Hello World", value);
+}
+
+TEST(StringAppendFTest, Int) {
+  string value("Hello");
+  StringAppendF(&value, " %d", 123);
+  EXPECT_EQ("Hello 123", value);
+}
+
+TEST(StringPrintfTest, Multibyte) {
+  // If we are in multibyte mode and feed invalid multibyte sequence,
+  // StringPrintf should return an empty string instead of running
+  // out of memory while trying to determine destination buffer size.
+  // see b/4194543.
+
+  char* old_locale = setlocale(LC_CTYPE, NULL);
+  // Push locale with multibyte mode
+  setlocale(LC_CTYPE, "en_US.utf8");
+
+  const char kInvalidCodePoint[] = "\375\067s";
+  string value = StringPrintf("%.*s", 3, kInvalidCodePoint);
+
+  // In some versions of glibc (e.g. eglibc-2.11.1, aka GRTEv2), snprintf
+  // returns error given an invalid codepoint. Other versions
+  // (e.g. eglibc-2.15, aka pre-GRTEv3) emit the codepoint verbatim.
+  // We test that the output is one of the above.
+  EXPECT_TRUE(value.empty() || value == kInvalidCodePoint);
+
+  // Repeat with longer string, to make sure that the dynamically
+  // allocated path in StringAppendV is handled correctly.
+  int n = 2048;
+  char* buf = new char[n+1];
+  memset(buf, ' ', n-3);
+  memcpy(buf + n - 3, kInvalidCodePoint, 4);
+  value =  StringPrintf("%.*s", n, buf);
+  // See GRTEv2 vs. GRTEv3 comment above.
+  EXPECT_TRUE(value.empty() || value == buf);
+  delete[] buf;
+
+  setlocale(LC_CTYPE, old_locale);
+}
+
+TEST(StringPrintfTest, NoMultibyte) {
+  // No multibyte handling, but the string contains funny chars.
+  char* old_locale = setlocale(LC_CTYPE, NULL);
+  setlocale(LC_CTYPE, "POSIX");
+  string value = StringPrintf("%.*s", 3, "\375\067s");
+  setlocale(LC_CTYPE, old_locale);
+  EXPECT_EQ("\375\067s", value);
+}
+
+TEST(StringPrintfTest, DontOverwriteErrno) {
+  // Check that errno isn't overwritten unless we're printing
+  // something significantly larger than what people are normally
+  // printing in their badly written PLOG() statements.
+  errno = ECHILD;
+  string value = StringPrintf("Hello, %s!", "World");
+  EXPECT_EQ(ECHILD, errno);
+}
+
+TEST(StringPrintfTest, LargeBuf) {
+  // Check that the large buffer is handled correctly.
+  int n = 2048;
+  char* buf = new char[n+1];
+  memset(buf, ' ', n);
+  buf[n] = 0;
+  string value = StringPrintf("%s", buf);
+  EXPECT_EQ(buf, value);
+  delete[] buf;
+}
+
+}  // anonymous namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/stubs/structurally_valid.cc b/protobuf/src/google/protobuf/stubs/structurally_valid.cc
new file mode 100644
index 0000000..0f6afe6
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/structurally_valid.cc
@@ -0,0 +1,536 @@
+// Copyright 2005-2008 Google Inc. All Rights Reserved.
+// Author: jrm@google.com (Jim Meehan)
+
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// These four-byte entries compactly encode how many bytes 0..255 to delete
+// in making a string replacement, how many bytes to add 0..255, and the offset
+// 0..64k-1 of the replacement string in remap_string.
+struct RemapEntry {
+  uint8 delete_bytes;
+  uint8 add_bytes;
+  uint16 bytes_offset;
+};
+
+// Exit type codes for state tables. All but the first get stuffed into
+// signed one-byte entries. The first is only generated by executable code.
+// To distinguish from next-state entries, these must be contiguous and
+// all <= kExitNone
+typedef enum {
+  kExitDstSpaceFull = 239,
+  kExitIllegalStructure,  // 240
+  kExitOK,                // 241
+  kExitReject,            // ...
+  kExitReplace1,
+  kExitReplace2,
+  kExitReplace3,
+  kExitReplace21,
+  kExitReplace31,
+  kExitReplace32,
+  kExitReplaceOffset1,
+  kExitReplaceOffset2,
+  kExitReplace1S0,
+  kExitSpecial,
+  kExitDoAgain,
+  kExitRejectAlt,
+  kExitNone               // 255
+} ExitReason;
+
+
+// This struct represents one entire state table. The three initialized byte
+// areas are state_table, remap_base, and remap_string. state0 and state0_size
+// give the byte offset and length within state_table of the initial state --
+// table lookups are expected to start and end in this state, but for
+// truncated UTF-8 strings, may end in a different state. These allow a quick
+// test for that condition. entry_shift is 8 for tables subscripted by a full
+// byte value and 6 for space-optimized tables subscripted by only six
+// significant bits in UTF-8 continuation bytes.
+typedef struct {
+  const uint32 state0;
+  const uint32 state0_size;
+  const uint32 total_size;
+  const int max_expand;
+  const int entry_shift;
+  const int bytes_per_entry;
+  const uint32 losub;
+  const uint32 hiadd;
+  const uint8* state_table;
+  const RemapEntry* remap_base;
+  const uint8* remap_string;
+  const uint8* fast_state;
+} UTF8StateMachineObj;
+
+typedef UTF8StateMachineObj UTF8ScanObj;
+
+#define X__ (kExitIllegalStructure)
+#define RJ_ (kExitReject)
+#define S1_ (kExitReplace1)
+#define S2_ (kExitReplace2)
+#define S3_ (kExitReplace3)
+#define S21 (kExitReplace21)
+#define S31 (kExitReplace31)
+#define S32 (kExitReplace32)
+#define T1_ (kExitReplaceOffset1)
+#define T2_ (kExitReplaceOffset2)
+#define S11 (kExitReplace1S0)
+#define SP_ (kExitSpecial)
+#define D__ (kExitDoAgain)
+#define RJA (kExitRejectAlt)
+
+//  Entire table has 9 state blocks of 256 entries each
+static const unsigned int utf8acceptnonsurrogates_STATE0 = 0;     // state[0]
+static const unsigned int utf8acceptnonsurrogates_STATE0_SIZE = 256;  // =[1]
+static const unsigned int utf8acceptnonsurrogates_TOTAL_SIZE = 2304;
+static const unsigned int utf8acceptnonsurrogates_MAX_EXPAND_X4 = 0;
+static const unsigned int utf8acceptnonsurrogates_SHIFT = 8;
+static const unsigned int utf8acceptnonsurrogates_BYTES = 1;
+static const unsigned int utf8acceptnonsurrogates_LOSUB = 0x20202020;
+static const unsigned int utf8acceptnonsurrogates_HIADD = 0x00000000;
+
+static const uint8 utf8acceptnonsurrogates[] = {
+// state[0] 0x000000 Byte 1
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
+  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
+  2,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   7,   3,   3,
+  4,   5,   5,   5,   6, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[1] 0x000080 Byte 2 of 2
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+  0,   0,   0,   0,   0,   0,   0,   0,    0,   0,   0,   0,   0,   0,   0,   0,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[2] 0x000000 Byte 2 of 3
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
+  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[3] 0x001000 Byte 2 of 3
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
+  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
+  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
+  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[4] 0x000000 Byte 2 of 4
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
+  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
+  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[5] 0x040000 Byte 2 of 4
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
+  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
+  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
+  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[6] 0x100000 Byte 2 of 4
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+  3,   3,   3,   3,   3,   3,   3,   3,    3,   3,   3,   3,   3,   3,   3,   3,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[7] 0x00d000 Byte 2 of 3
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
+  1,   1,   1,   1,   1,   1,   1,   1,    1,   1,   1,   1,   1,   1,   1,   1,
+  8,   8,   8,   8,   8,   8,   8,   8,    8,   8,   8,   8,   8,   8,   8,   8,
+  8,   8,   8,   8,   8,   8,   8,   8,    8,   8,   8,   8,   8,   8,   8,   8,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+// state[8] 0x00d800 Byte 3 of 3
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,  RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,  RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,  RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,  RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_, RJ_,
+
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+X__, X__, X__, X__, X__, X__, X__, X__,  X__, X__, X__, X__, X__, X__, X__, X__,
+};
+
+// Remap base[0] = (del, add, string_offset)
+static const RemapEntry utf8acceptnonsurrogates_remap_base[] = {
+{0, 0, 0} };
+
+// Remap string[0]
+static const unsigned char utf8acceptnonsurrogates_remap_string[] = {
+0 };
+
+static const unsigned char utf8acceptnonsurrogates_fast[256] = {
+0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+
+0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0,
+
+1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+
+1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1,
+};
+
+static const UTF8ScanObj utf8acceptnonsurrogates_obj = {
+  utf8acceptnonsurrogates_STATE0,
+  utf8acceptnonsurrogates_STATE0_SIZE,
+  utf8acceptnonsurrogates_TOTAL_SIZE,
+  utf8acceptnonsurrogates_MAX_EXPAND_X4,
+  utf8acceptnonsurrogates_SHIFT,
+  utf8acceptnonsurrogates_BYTES,
+  utf8acceptnonsurrogates_LOSUB,
+  utf8acceptnonsurrogates_HIADD,
+  utf8acceptnonsurrogates,
+  utf8acceptnonsurrogates_remap_base,
+  utf8acceptnonsurrogates_remap_string,
+  utf8acceptnonsurrogates_fast
+};
+
+
+#undef X__
+#undef RJ_
+#undef S1_
+#undef S2_
+#undef S3_
+#undef S21
+#undef S31
+#undef S32
+#undef T1_
+#undef T2_
+#undef S11
+#undef SP_
+#undef D__
+#undef RJA
+
+// Return true if current Tbl pointer is within state0 range
+// Note that unsigned compare checks both ends of range simultaneously
+static inline bool InStateZero(const UTF8ScanObj* st, const uint8* Tbl) {
+  const uint8* Tbl0 = &st->state_table[st->state0];
+  return (static_cast<uint32>(Tbl - Tbl0) < st->state0_size);
+}
+
+// Scan a UTF-8 string based on state table.
+// Always scan complete UTF-8 characters
+// Set number of bytes scanned. Return reason for exiting
+int UTF8GenericScan(const UTF8ScanObj* st,
+                    const char * str,
+                    int str_length,
+                    int* bytes_consumed) {
+  *bytes_consumed = 0;
+  if (str_length == 0) return kExitOK;
+
+  int eshift = st->entry_shift;
+  const uint8* isrc = reinterpret_cast<const uint8*>(str);
+  const uint8* src = isrc;
+  const uint8* srclimit = isrc + str_length;
+  const uint8* srclimit8 = srclimit - 7;
+  const uint8* Tbl_0 = &st->state_table[st->state0];
+
+ DoAgain:
+  // Do state-table scan
+  int e = 0;
+  uint8 c;
+  const uint8* Tbl2 = &st->fast_state[0];
+  const uint32 losub = st->losub;
+  const uint32 hiadd = st->hiadd;
+  // Check initial few bytes one at a time until 8-byte aligned
+  //----------------------------
+  while ((((uintptr_t)src & 0x07) != 0) &&
+         (src < srclimit) &&
+         Tbl2[src[0]] == 0) {
+    src++;
+  }
+  if (((uintptr_t)src & 0x07) == 0) {
+    // Do fast for groups of 8 identity bytes.
+    // This covers a lot of 7-bit ASCII ~8x faster then the 1-byte loop,
+    // including slowing slightly on cr/lf/ht
+    //----------------------------
+    while (src < srclimit8) {
+      uint32 s0123 = (reinterpret_cast<const uint32 *>(src))[0];
+      uint32 s4567 = (reinterpret_cast<const uint32 *>(src))[1];
+      src += 8;
+      // This is a fast range check for all bytes in [lowsub..0x80-hiadd)
+      uint32 temp = (s0123 - losub) | (s0123 + hiadd) |
+                    (s4567 - losub) | (s4567 + hiadd);
+      if ((temp & 0x80808080) != 0) {
+        // We typically end up here on cr/lf/ht; src was incremented
+        int e0123 = (Tbl2[src[-8]] | Tbl2[src[-7]]) |
+                    (Tbl2[src[-6]] | Tbl2[src[-5]]);
+        if (e0123 != 0) {
+          src -= 8;
+          break;
+        }    // Exit on Non-interchange
+        e0123 = (Tbl2[src[-4]] | Tbl2[src[-3]]) |
+                (Tbl2[src[-2]] | Tbl2[src[-1]]);
+        if (e0123 != 0) {
+          src -= 4;
+          break;
+        }    // Exit on Non-interchange
+        // Else OK, go around again
+      }
+    }
+  }
+  //----------------------------
+
+  // Byte-at-a-time scan
+  //----------------------------
+  const uint8* Tbl = Tbl_0;
+  while (src < srclimit) {
+    c = *src;
+    e = Tbl[c];
+    src++;
+    if (e >= kExitIllegalStructure) {break;}
+    Tbl = &Tbl_0[e << eshift];
+  }
+  //----------------------------
+
+
+  // Exit posibilities:
+  //  Some exit code, !state0, back up over last char
+  //  Some exit code, state0, back up one byte exactly
+  //  source consumed, !state0, back up over partial char
+  //  source consumed, state0, exit OK
+  // For illegal byte in state0, avoid backup up over PREVIOUS char
+  // For truncated last char, back up to beginning of it
+
+  if (e >= kExitIllegalStructure) {
+    // Back up over exactly one byte of rejected/illegal UTF-8 character
+    src--;
+    // Back up more if needed
+    if (!InStateZero(st, Tbl)) {
+      do {
+        src--;
+      } while ((src > isrc) && ((src[0] & 0xc0) == 0x80));
+    }
+  } else if (!InStateZero(st, Tbl)) {
+    // Back up over truncated UTF-8 character
+    e = kExitIllegalStructure;
+    do {
+      src--;
+    } while ((src > isrc) && ((src[0] & 0xc0) == 0x80));
+  } else {
+    // Normal termination, source fully consumed
+    e = kExitOK;
+  }
+
+  if (e == kExitDoAgain) {
+    // Loop back up to the fast scan
+    goto DoAgain;
+  }
+
+  *bytes_consumed = src - isrc;
+  return e;
+}
+
+int UTF8GenericScanFastAscii(const UTF8ScanObj* st,
+                    const char * str,
+                    int str_length,
+                    int* bytes_consumed) {
+  *bytes_consumed = 0;
+  if (str_length == 0) return kExitOK;
+
+  const uint8* isrc =  reinterpret_cast<const uint8*>(str);
+  const uint8* src = isrc;
+  const uint8* srclimit = isrc + str_length;
+  const uint8* srclimit8 = srclimit - 7;
+  int n;
+  int rest_consumed;
+  int exit_reason;
+  do {
+    // Check initial few bytes one at a time until 8-byte aligned
+    while ((((uintptr_t)src & 0x07) != 0) &&
+           (src < srclimit) && (src[0] < 0x80)) {
+      src++;
+    }
+    if (((uintptr_t)src & 0x07) == 0) {
+      while ((src < srclimit8) &&
+             (((reinterpret_cast<const uint32*>(src)[0] |
+                reinterpret_cast<const uint32*>(src)[1]) & 0x80808080) == 0)) {
+        src += 8;
+      }
+    }
+    while ((src < srclimit) && (src[0] < 0x80)) {
+      src++;
+    }
+    // Run state table on the rest
+    n = src - isrc;
+    exit_reason = UTF8GenericScan(st, str + n, str_length - n, &rest_consumed);
+    src += rest_consumed;
+  } while ( exit_reason == kExitDoAgain );
+
+  *bytes_consumed = src - isrc;
+  return exit_reason;
+}
+
+// Hack:  On some compilers the static tables are initialized at startup.
+//   We can't use them until they are initialized.  However, some Protocol
+//   Buffer parsing happens at static init time and may try to validate
+//   UTF-8 strings.  Since UTF-8 validation is only used for debugging
+//   anyway, we simply always return success if initialization hasn't
+//   occurred yet.
+namespace {
+
+bool module_initialized_ = false;
+
+struct InitDetector {
+  InitDetector() {
+    module_initialized_ = true;
+  }
+};
+InitDetector init_detector;
+
+}  // namespace
+
+bool IsStructurallyValidUTF8(const char* buf, int len) {
+  if (!module_initialized_) return true;
+  
+  int bytes_consumed = 0;
+  UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj,
+                           buf, len, &bytes_consumed);
+  return (bytes_consumed == len);
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/stubs/structurally_valid_unittest.cc b/protobuf/src/google/protobuf/stubs/structurally_valid_unittest.cc
new file mode 100644
index 0000000..9088888
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/structurally_valid_unittest.cc
@@ -0,0 +1,40 @@
+// Copyright 2008 Google Inc. All Rights Reserved.
+// Author: xpeng@google.com (Peter Peng)
+
+#include <google/protobuf/stubs/common.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(StructurallyValidTest, ValidUTF8String) {
+  // On GCC, this string can be written as:
+  //   "abcd 1234 - \u2014\u2013\u2212"
+  // MSVC seems to interpret \u differently.
+  string valid_str("abcd 1234 - \342\200\224\342\200\223\342\210\222 - xyz789");
+  EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data(),
+                                      valid_str.size()));
+  // Additional check for pointer alignment
+  for (int i = 1; i < 8; ++i) {
+    EXPECT_TRUE(IsStructurallyValidUTF8(valid_str.data() + i,
+                                        valid_str.size() - i));
+  }
+}
+
+TEST(StructurallyValidTest, InvalidUTF8String) {
+  const string invalid_str("abcd\xA0\xB0\xA0\xB0\xA0\xB0 - xyz789");
+  EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data(),
+                                       invalid_str.size()));
+  // Additional check for pointer alignment
+  for (int i = 1; i < 8; ++i) {
+    EXPECT_FALSE(IsStructurallyValidUTF8(invalid_str.data() + i,
+                                         invalid_str.size() - i));
+  }
+}
+
+}  // namespace
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/stubs/strutil.cc b/protobuf/src/google/protobuf/stubs/strutil.cc
new file mode 100644
index 0000000..a898259
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/strutil.cc
@@ -0,0 +1,1279 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// 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>
+#include <stdio.h>
+#include <iterator>
+
+#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;
+}
+
+// These are defined as macros on some platforms.  #undef them so that we can
+// redefine them.
+#undef isxdigit
+#undef isprint
+
+// 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.
+inline bool isxdigit(char c) {
+  return ('0' <= c && c <= '9') ||
+         ('a' <= c && c <= 'f') ||
+         ('A' <= c && c <= 'F');
+}
+
+inline 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);
+}
+
+// Split a string using a character delimiter. Append the components
+// to 'result'.  If there are consecutive delimiters, this function
+// will return corresponding empty strings. The string is split into
+// at most the specified number of pieces greedily. This means that the
+// last piece may possibly be split further. To split into as many pieces
+// as possible, specify 0 as the number of pieces.
+//
+// If "full" is the empty string, yields an empty string as the only value.
+//
+// If "pieces" is negative for some reason, it returns the whole string
+// ----------------------------------------------------------------------
+template <typename StringType, typename ITR>
+static inline
+void SplitStringToIteratorAllowEmpty(const StringType& full,
+                                     const char* delim,
+                                     int pieces,
+                                     ITR& result) {
+  string::size_type begin_index, end_index;
+  begin_index = 0;
+
+  for (int i = 0; (i < pieces-1) || (pieces == 0); i++) {
+    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 = end_index + 1;
+  }
+  *result++ = full.substr(begin_index);
+}
+
+void SplitStringAllowEmpty(const string& full, const char* delim,
+                           vector<string>* result) {
+  back_insert_iterator<vector<string> > it(*result);
+  SplitStringToIteratorAllowEmpty(full, delim, 0, 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.
+// ----------------------------------------------------------------------
+int CEscapeInternal(const char* src, int src_len, char* dest,
+                    int dest_len, bool use_hex, bool utf8_safe) {
+  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 ((!utf8_safe || static_cast<uint8>(*src) < 0x80) &&
+            (!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, 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, false);
+  GOOGLE_DCHECK_GE(len, 0);
+  return string(dest.get(), len);
+}
+
+namespace strings {
+
+string Utf8SafeCEscape(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, true);
+  GOOGLE_DCHECK_GE(len, 0);
+  return string(dest.get(), len);
+}
+
+string CHexEscape(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, true, false);
+  GOOGLE_DCHECK_GE(len, 0);
+  return string(dest.get(), len);
+}
+
+}  // namespace strings
+
+// ----------------------------------------------------------------------
+// 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);
+}
+
+inline bool safe_parse_sign(string* text  /*inout*/,
+                            bool* negative_ptr  /*output*/) {
+  const char* start = text->data();
+  const char* end = start + text->size();
+
+  // Consume whitespace.
+  while (start < end && (start[0] == ' ')) {
+    ++start;
+  }
+  while (start < end && (end[-1] == ' ')) {
+    --end;
+  }
+  if (start >= end) {
+    return false;
+  }
+
+  // Consume sign.
+  *negative_ptr = (start[0] == '-');
+  if (*negative_ptr || start[0] == '+') {
+    ++start;
+    if (start >= end) {
+      return false;
+    }
+  }
+  *text = text->substr(start - text->data(), end - start);
+  return true;
+}
+
+inline bool safe_parse_positive_int(
+    string text, int32* value_p) {
+  int base = 10;
+  int32 value = 0;
+  const int32 vmax = std::numeric_limits<int32>::max();
+  assert(vmax > 0);
+  assert(vmax >= base);
+  const int32 vmax_over_base = vmax / base;
+  const char* start = text.data();
+  const char* end = start + text.size();
+  // loop over digits
+  for (; start < end; ++start) {
+    unsigned char c = static_cast<unsigned char>(start[0]);
+    int digit = c - '0';
+    if (digit >= base || digit < 0) {
+      *value_p = value;
+      return false;
+    }
+    if (value > vmax_over_base) {
+      *value_p = vmax;
+      return false;
+    }
+    value *= base;
+    if (value > vmax - digit) {
+      *value_p = vmax;
+      return false;
+    }
+    value += digit;
+  }
+  *value_p = value;
+  return true;
+}
+
+inline bool safe_parse_negative_int(
+    string text, int32* value_p) {
+  int base = 10;
+  int32 value = 0;
+  const int32 vmin = std::numeric_limits<int32>::min();
+  assert(vmin < 0);
+  assert(vmin <= 0 - base);
+  int32 vmin_over_base = vmin / base;
+  // 2003 c++ standard [expr.mul]
+  // "... the sign of the remainder is implementation-defined."
+  // Although (vmin/base)*base + vmin%base is always vmin.
+  // 2011 c++ standard tightens the spec but we cannot rely on it.
+  if (vmin % base > 0) {
+    vmin_over_base += 1;
+  }
+  const char* start = text.data();
+  const char* end = start + text.size();
+  // loop over digits
+  for (; start < end; ++start) {
+    unsigned char c = static_cast<unsigned char>(start[0]);
+    int digit = c - '0';
+    if (digit >= base || digit < 0) {
+      *value_p = value;
+      return false;
+    }
+    if (value < vmin_over_base) {
+      *value_p = vmin;
+      return false;
+    }
+    value *= base;
+    if (value < vmin + digit) {
+      *value_p = vmin;
+      return false;
+    }
+    value -= digit;
+  }
+  *value_p = value;
+  return true;
+}
+
+bool safe_int(string text, int32* value_p) {
+  *value_p = 0;
+  bool negative;
+  if (!safe_parse_sign(&text, &negative)) {
+    return false;
+  }
+  if (!negative) {
+    return safe_parse_positive_int(text, value_p);
+  } else {
+    return safe_parse_negative_int(text, value_p);
+  }
+}
+
+// ----------------------------------------------------------------------
+// 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--) {
+#ifdef _M_X64
+    // MSVC x64 platform has a bug optimizing the uint32(value) in the #else
+    // block. Given that the uint32 cast was to improve performance on 32-bit
+    // platforms, we use 64-bit '&' directly.
+    buffer[i] = hexdigits[value & 0xf];
+#else
+    buffer[i] = hexdigits[uint32(value) & 0xf];
+#endif
+    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
+#if defined(_WIN32) || defined (__hpux)  // 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;
+}
+
+string ToHex(uint64 num) {
+  if (num == 0) {
+    return string("0");
+  }
+
+  // Compute hex bytes in reverse order, writing to the back of the
+  // buffer.
+  char buf[16];  // No more than 16 hex digits needed.
+  char* bufptr = buf + 16;
+  static const char kHexChars[] = "0123456789abcdef";
+  while (num != 0) {
+    *--bufptr = kHexChars[num & 0xf];
+    num >>= 4;
+  }
+
+  return string(bufptr, buf + 16 - bufptr);
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/stubs/strutil.h b/protobuf/src/google/protobuf/stubs/strutil.h
new file mode 100644
index 0000000..4178ac9
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/strutil.h
@@ -0,0 +1,562 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/strings/strutil.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
+#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
+
+#include <stdlib.h>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _MSC_VER
+#define strtoll  _strtoi64
+#define strtoull _strtoui64
+#elif defined(__DECCXX) && defined(__osf__)
+// HP C++ on Tru64 does not have strtoll, but strtol is already 64-bit.
+#define strtoll strtol
+#define strtoull strtoul
+#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()
+// ToUpper()
+//    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';
+  }
+}
+
+inline string ToUpper(const string& s) {
+  string out = s;
+  UpperString(&out);
+  return out;
+}
+
+// ----------------------------------------------------------------------
+// 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);
+
+// Split a string using one or more byte delimiters, presented
+// as a nul-terminated c string. Append the components to 'result'.
+// If there are consecutive delimiters, this function will return
+// corresponding empty strings.  If you want to drop the empty
+// strings, try SplitStringUsing().
+//
+// If "full" is the empty string, yields an empty string as the only value.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void SplitStringAllowEmpty(const string& full,
+                                              const char* delim,
+                                              vector<string>* result);
+
+// ----------------------------------------------------------------------
+// Split()
+//    Split a string using a character delimiter.
+// ----------------------------------------------------------------------
+inline vector<string> Split(
+    const string& full, const char* delim, bool skip_empty = true) {
+  vector<string> result;
+  if (skip_empty) {
+    SplitStringUsing(full, delim, &result);
+  } else {
+    SplitStringAllowEmpty(full, delim, &result);
+  }
+  return result;
+}
+
+// ----------------------------------------------------------------------
+// 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).
+//
+//    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);
+
+namespace strings {
+// Like CEscape() but does not escape bytes with the upper bit set.
+LIBPROTOBUF_EXPORT string Utf8SafeCEscape(const string& src);
+
+// Like CEscape() but uses hex (\x) escapes instead of octals.
+LIBPROTOBUF_EXPORT string CHexEscape(const string& src);
+}  // namespace strings
+
+// ----------------------------------------------------------------------
+// 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);
+}
+
+// ----------------------------------------------------------------------
+// safe_strto32()
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT bool safe_int(string text, int32* value_p);
+
+inline bool safe_strto32(string text, int32* value) {
+  return safe_int(text, value);
+}
+
+// ----------------------------------------------------------------------
+// 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;
+
+// ----------------------------------------------------------------------
+// ToString() are internal help methods used in StrCat() and Join()
+// ----------------------------------------------------------------------
+namespace internal {
+inline string ToString(int i) {
+  return SimpleItoa(i);
+}
+
+inline string ToString(string a) {
+  return a;
+}
+}  // namespace internal
+
+// ----------------------------------------------------------------------
+// StrCat()
+//    These methods join some strings together.
+// ----------------------------------------------------------------------
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+string StrCat(
+    const T1& a, const T2& b, const T3& c, const T4& d, const T5& e) {
+  return internal::ToString(a) + internal::ToString(b) +
+      internal::ToString(c) + internal::ToString(d) + internal::ToString(e);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+string StrCat(
+    const T1& a, const T2& b, const T3& c, const T4& d) {
+  return internal::ToString(a) + internal::ToString(b) +
+      internal::ToString(c) + internal::ToString(d);
+}
+
+template <typename T1, typename T2, typename T3>
+string StrCat(const T1& a, const T2& b, const T3& c) {
+  return internal::ToString(a) + internal::ToString(b) +
+      internal::ToString(c);
+}
+
+template <typename T1, typename T2>
+string StrCat(const T1& a, const T2& b) {
+  return internal::ToString(a) + internal::ToString(b);
+}
+
+// ----------------------------------------------------------------------
+// Join()
+//    These methods concatenate a range of components into a C++ string, using
+//    the C-string "delim" as a separator between components.
+// ----------------------------------------------------------------------
+template <typename Iterator>
+void Join(Iterator start, Iterator end,
+          const char* delim, string* result) {
+  for (Iterator it = start; it != end; ++it) {
+    if (it != start) {
+      result->append(delim);
+    }
+    result->append(internal::ToString(*it));
+  }
+}
+
+template <typename Range>
+string Join(const Range& components,
+            const char* delim) {
+  string result;
+  Join(components.begin(), components.end(), delim, &result);
+  return result;
+}
+
+// ----------------------------------------------------------------------
+// ToHex()
+//    Return a lower-case hex string representation of the given integer.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string ToHex(uint64 num);
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
diff --git a/protobuf/src/google/protobuf/stubs/strutil_unittest.cc b/protobuf/src/google/protobuf/stubs/strutil_unittest.cc
new file mode 100644
index 0000000..7f27dca
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/strutil_unittest.cc
@@ -0,0 +1,73 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/strutil.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+#include <locale.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", SimpleDtoa(1.5));
+  EXPECT_EQ("1.5", SimpleFtoa(1.5));
+
+  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", SimpleDtoa(1.5));
+    EXPECT_EQ("1.5", SimpleFtoa(1.5));
+  }
+
+  // Return to original locale.
+  setlocale(LC_NUMERIC, old_locale.c_str());
+}
+
+}  // anonymous namespace
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/stubs/substitute.cc b/protobuf/src/google/protobuf/stubs/substitute.cc
new file mode 100644
index 0000000..c9d9589
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/substitute.cc
@@ -0,0 +1,134 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stl_util.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/protobuf/src/google/protobuf/stubs/substitute.h b/protobuf/src/google/protobuf/stubs/substitute.h
new file mode 100644
index 0000000..7ee442a
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/substitute.h
@@ -0,0 +1,170 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/protobuf/src/google/protobuf/stubs/template_util.h b/protobuf/src/google/protobuf/stubs/template_util.h
new file mode 100644
index 0000000..4f30ffa
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/template_util.h
@@ -0,0 +1,138 @@
+// 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: lar@google.com (Laramie Leavitt)
+//
+// Template metaprogramming utility functions.
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems.  Before making
+// any changes here, make sure that you're not breaking any platforms.
+//
+//
+// The names choosen here reflect those used in tr1 and the boost::mpl
+// library, there are similar operations used in the Loki library as
+// well.  I prefer the boost names for 2 reasons:
+// 1.  I think that portions of the Boost libraries are more likely to
+// be included in the c++ standard.
+// 2.  It is not impossible that some of the boost libraries will be
+// included in our own build in the future.
+// Both of these outcomes means that we may be able to directly replace
+// some of these with boost equivalents.
+//
+#ifndef GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
+#define GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Types small_ and big_ are guaranteed such that sizeof(small_) <
+// sizeof(big_)
+typedef char small_;
+
+struct big_ {
+  char dummy[2];
+};
+
+// Identity metafunction.
+template <class T>
+struct identity_ {
+  typedef T type;
+};
+
+// integral_constant, defined in tr1, is a wrapper for an integer
+// value. We don't really need this generality; we could get away
+// with hardcoding the integer type to bool. We use the fully
+// general integer_constant for compatibility with tr1.
+
+template<class T, T v>
+struct integral_constant {
+  static const T value = v;
+  typedef T value_type;
+  typedef integral_constant<T, v> type;
+};
+
+template <class T, T v> const T integral_constant<T, v>::value;
+
+
+// Abbreviations: true_type and false_type are structs that represent boolean
+// true and false values. Also define the boost::mpl versions of those names,
+// true_ and false_.
+typedef integral_constant<bool, true>  true_type;
+typedef integral_constant<bool, false> false_type;
+typedef true_type  true_;
+typedef false_type false_;
+
+// if_ is a templatized conditional statement.
+// if_<cond, A, B> is a compile time evaluation of cond.
+// if_<>::type contains A if cond is true, B otherwise.
+template<bool cond, typename A, typename B>
+struct if_{
+  typedef A type;
+};
+
+template<typename A, typename B>
+struct if_<false, A, B> {
+  typedef B type;
+};
+
+
+// type_equals_ is a template type comparator, similar to Loki IsSameType.
+// type_equals_<A, B>::value is true iff "A" is the same type as "B".
+//
+// New code should prefer base::is_same, defined in base/type_traits.h.
+// It is functionally identical, but is_same is the standard spelling.
+template<typename A, typename B>
+struct type_equals_ : public false_ {
+};
+
+template<typename A>
+struct type_equals_<A, A> : public true_ {
+};
+
+// and_ is a template && operator.
+// and_<A, B>::value evaluates "A::value && B::value".
+template<typename A, typename B>
+struct and_ : public integral_constant<bool, (A::value && B::value)> {
+};
+
+// or_ is a template || operator.
+// or_<A, B>::value evaluates "A::value || B::value".
+template<typename A, typename B>
+struct or_ : public integral_constant<bool, (A::value || B::value)> {
+};
+
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_TEMPLATE_UTIL_H_
diff --git a/protobuf/src/google/protobuf/stubs/template_util_unittest.cc b/protobuf/src/google/protobuf/stubs/template_util_unittest.cc
new file mode 100644
index 0000000..b1745e2
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/template_util_unittest.cc
@@ -0,0 +1,130 @@
+// 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: lar@google.com (Laramie Leavitt)
+//
+// These tests are really compile time tests.
+// If you try to step through this in a debugger
+// you will not see any evaluations, merely that
+// value is assigned true or false sequentially.
+
+#include <google/protobuf/stubs/template_util.h>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace GOOGLE_NAMESPACE = google::protobuf::internal;
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(TemplateUtilTest, TestSize) {
+  EXPECT_GT(sizeof(GOOGLE_NAMESPACE::big_), sizeof(GOOGLE_NAMESPACE::small_));
+}
+
+TEST(TemplateUtilTest, TestIntegralConstants) {
+  // test the built-in types.
+  EXPECT_TRUE(true_type::value);
+  EXPECT_FALSE(false_type::value);
+
+  typedef integral_constant<int, 1> one_type;
+  EXPECT_EQ(1, one_type::value);
+}
+
+TEST(TemplateUtilTest, TestTemplateIf) {
+  typedef if_<true, true_type, false_type>::type if_true;
+  EXPECT_TRUE(if_true::value);
+
+  typedef if_<false, true_type, false_type>::type if_false;
+  EXPECT_FALSE(if_false::value);
+}
+
+TEST(TemplateUtilTest, TestTemplateTypeEquals) {
+  // Check that the TemplateTypeEquals works correctly.
+  bool value = false;
+
+  // Test the same type is true.
+  value = type_equals_<int, int>::value;
+  EXPECT_TRUE(value);
+
+  // Test different types are false.
+  value = type_equals_<float, int>::value;
+  EXPECT_FALSE(value);
+
+  // Test type aliasing.
+  typedef const int foo;
+  value = type_equals_<const foo, const int>::value;
+  EXPECT_TRUE(value);
+}
+
+TEST(TemplateUtilTest, TestTemplateAndOr) {
+  // Check that the TemplateTypeEquals works correctly.
+  bool value = false;
+
+  // Yes && Yes == true.
+  value = and_<true_, true_>::value;
+  EXPECT_TRUE(value);
+  // Yes && No == false.
+  value = and_<true_, false_>::value;
+  EXPECT_FALSE(value);
+  // No && Yes == false.
+  value = and_<false_, true_>::value;
+  EXPECT_FALSE(value);
+  // No && No == false.
+  value = and_<false_, false_>::value;
+  EXPECT_FALSE(value);
+
+  // Yes || Yes == true.
+  value = or_<true_, true_>::value;
+  EXPECT_TRUE(value);
+  // Yes || No == true.
+  value = or_<true_, false_>::value;
+  EXPECT_TRUE(value);
+  // No || Yes == true.
+  value = or_<false_, true_>::value;
+  EXPECT_TRUE(value);
+  // No || No == false.
+  value = or_<false_, false_>::value;
+  EXPECT_FALSE(value);
+}
+
+TEST(TemplateUtilTest, TestIdentity) {
+  EXPECT_TRUE(
+      (type_equals_<GOOGLE_NAMESPACE::identity_<int>::type, int>::value));
+  EXPECT_TRUE(
+      (type_equals_<GOOGLE_NAMESPACE::identity_<void>::type, void>::value));
+}
+
+}  // anonymous namespace
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/stubs/type_traits.h b/protobuf/src/google/protobuf/stubs/type_traits.h
new file mode 100644
index 0000000..e41f5e6
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/type_traits.h
@@ -0,0 +1,336 @@
+// Copyright (c) 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: Matt Austern
+//
+// This code is compiled directly on many platforms, including client
+// platforms like Windows, Mac, and embedded systems.  Before making
+// any changes here, make sure that you're not breaking any platforms.
+//
+// Define a small subset of tr1 type traits. The traits we define are:
+//   is_integral
+//   is_floating_point
+//   is_pointer
+//   is_enum
+//   is_reference
+//   is_pod
+//   has_trivial_constructor
+//   has_trivial_copy
+//   has_trivial_assign
+//   has_trivial_destructor
+//   remove_const
+//   remove_volatile
+//   remove_cv
+//   remove_reference
+//   add_reference
+//   remove_pointer
+//   is_same
+//   is_convertible
+// We can add more type traits as required.
+
+#ifndef GOOGLE_PROTOBUF_TYPE_TRAITS_H_
+#define GOOGLE_PROTOBUF_TYPE_TRAITS_H_
+
+#include <utility>                  // For pair
+
+#include <google/protobuf/stubs/template_util.h>  // For true_type and false_type
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+template <class T> struct is_integral;
+template <class T> struct is_floating_point;
+template <class T> struct is_pointer;
+// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least)
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+// is_enum uses is_convertible, which is not available on MSVC.
+template <class T> struct is_enum;
+#endif
+template <class T> struct is_reference;
+template <class T> struct is_pod;
+template <class T> struct has_trivial_constructor;
+template <class T> struct has_trivial_copy;
+template <class T> struct has_trivial_assign;
+template <class T> struct has_trivial_destructor;
+template <class T> struct remove_const;
+template <class T> struct remove_volatile;
+template <class T> struct remove_cv;
+template <class T> struct remove_reference;
+template <class T> struct add_reference;
+template <class T> struct remove_pointer;
+template <class T, class U> struct is_same;
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+template <class From, class To> struct is_convertible;
+#endif
+
+// is_integral is false except for the built-in integer types. A
+// cv-qualified type is integral if and only if the underlying type is.
+template <class T> struct is_integral : false_type { };
+template<> struct is_integral<bool> : true_type { };
+template<> struct is_integral<char> : true_type { };
+template<> struct is_integral<unsigned char> : true_type { };
+template<> struct is_integral<signed char> : true_type { };
+#if defined(_MSC_VER)
+// wchar_t is not by default a distinct type from unsigned short in
+// Microsoft C.
+// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
+template<> struct is_integral<__wchar_t> : true_type { };
+#else
+template<> struct is_integral<wchar_t> : true_type { };
+#endif
+template<> struct is_integral<short> : true_type { };
+template<> struct is_integral<unsigned short> : true_type { };
+template<> struct is_integral<int> : true_type { };
+template<> struct is_integral<unsigned int> : true_type { };
+template<> struct is_integral<long> : true_type { };
+template<> struct is_integral<unsigned long> : true_type { };
+#ifdef HAVE_LONG_LONG
+template<> struct is_integral<long long> : true_type { };
+template<> struct is_integral<unsigned long long> : true_type { };
+#endif
+template <class T> struct is_integral<const T> : is_integral<T> { };
+template <class T> struct is_integral<volatile T> : is_integral<T> { };
+template <class T> struct is_integral<const volatile T> : is_integral<T> { };
+
+// is_floating_point is false except for the built-in floating-point types.
+// A cv-qualified type is integral if and only if the underlying type is.
+template <class T> struct is_floating_point : false_type { };
+template<> struct is_floating_point<float> : true_type { };
+template<> struct is_floating_point<double> : true_type { };
+template<> struct is_floating_point<long double> : true_type { };
+template <class T> struct is_floating_point<const T>
+    : is_floating_point<T> { };
+template <class T> struct is_floating_point<volatile T>
+    : is_floating_point<T> { };
+template <class T> struct is_floating_point<const volatile T>
+    : is_floating_point<T> { };
+
+// is_pointer is false except for pointer types. A cv-qualified type (e.g.
+// "int* const", as opposed to "int const*") is cv-qualified if and only if
+// the underlying type is.
+template <class T> struct is_pointer : false_type { };
+template <class T> struct is_pointer<T*> : true_type { };
+template <class T> struct is_pointer<const T> : is_pointer<T> { };
+template <class T> struct is_pointer<volatile T> : is_pointer<T> { };
+template <class T> struct is_pointer<const volatile T> : is_pointer<T> { };
+
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+
+namespace internal {
+
+template <class T> struct is_class_or_union {
+  template <class U> static small_ tester(void (U::*)());
+  template <class U> static big_ tester(...);
+  static const bool value = sizeof(tester<T>(0)) == sizeof(small_);
+};
+
+// is_convertible chokes if the first argument is an array. That's why
+// we use add_reference here.
+template <bool NotUnum, class T> struct is_enum_impl
+    : is_convertible<typename add_reference<T>::type, int> { };
+
+template <class T> struct is_enum_impl<true, T> : false_type { };
+
+}  // namespace internal
+
+// Specified by TR1 [4.5.1] primary type categories.
+
+// Implementation note:
+//
+// Each type is either void, integral, floating point, array, pointer,
+// reference, member object pointer, member function pointer, enum,
+// union or class. Out of these, only integral, floating point, reference,
+// class and enum types are potentially convertible to int. Therefore,
+// if a type is not a reference, integral, floating point or class and
+// is convertible to int, it's a enum. Adding cv-qualification to a type
+// does not change whether it's an enum.
+//
+// Is-convertible-to-int check is done only if all other checks pass,
+// because it can't be used with some types (e.g. void or classes with
+// inaccessible conversion operators).
+template <class T> struct is_enum
+    : internal::is_enum_impl<
+          is_same<T, void>::value ||
+              is_integral<T>::value ||
+              is_floating_point<T>::value ||
+              is_reference<T>::value ||
+              internal::is_class_or_union<T>::value,
+          T> { };
+
+template <class T> struct is_enum<const T> : is_enum<T> { };
+template <class T> struct is_enum<volatile T> : is_enum<T> { };
+template <class T> struct is_enum<const volatile T> : is_enum<T> { };
+
+#endif
+
+// is_reference is false except for reference types.
+template<typename T> struct is_reference : false_type {};
+template<typename T> struct is_reference<T&> : true_type {};
+
+
+// We can't get is_pod right without compiler help, so fail conservatively.
+// We will assume it's false except for arithmetic types, enumerations,
+// pointers and cv-qualified versions thereof. Note that std::pair<T,U>
+// is not a POD even if T and U are PODs.
+template <class T> struct is_pod
+ : integral_constant<bool, (is_integral<T>::value ||
+                            is_floating_point<T>::value ||
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+                            // is_enum is not available on MSVC.
+                            is_enum<T>::value ||
+#endif
+                            is_pointer<T>::value)> { };
+template <class T> struct is_pod<const T> : is_pod<T> { };
+template <class T> struct is_pod<volatile T> : is_pod<T> { };
+template <class T> struct is_pod<const volatile T> : is_pod<T> { };
+
+
+// We can't get has_trivial_constructor right without compiler help, so
+// fail conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial
+// constructors. (3) array of a type with a trivial constructor.
+// (4) const versions thereof.
+template <class T> struct has_trivial_constructor : is_pod<T> { };
+template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
+  : integral_constant<bool,
+                      (has_trivial_constructor<T>::value &&
+                       has_trivial_constructor<U>::value)> { };
+template <class A, int N> struct has_trivial_constructor<A[N]>
+  : has_trivial_constructor<A> { };
+template <class T> struct has_trivial_constructor<const T>
+  : has_trivial_constructor<T> { };
+
+// We can't get has_trivial_copy right without compiler help, so fail
+// conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial copy
+// constructors. (3) array of a type with a trivial copy constructor.
+// (4) const versions thereof.
+template <class T> struct has_trivial_copy : is_pod<T> { };
+template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
+  : integral_constant<bool,
+                      (has_trivial_copy<T>::value &&
+                       has_trivial_copy<U>::value)> { };
+template <class A, int N> struct has_trivial_copy<A[N]>
+  : has_trivial_copy<A> { };
+template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
+
+// We can't get has_trivial_assign right without compiler help, so fail
+// conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial copy
+// constructors. (3) array of a type with a trivial assign constructor.
+template <class T> struct has_trivial_assign : is_pod<T> { };
+template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
+  : integral_constant<bool,
+                      (has_trivial_assign<T>::value &&
+                       has_trivial_assign<U>::value)> { };
+template <class A, int N> struct has_trivial_assign<A[N]>
+  : has_trivial_assign<A> { };
+
+// We can't get has_trivial_destructor right without compiler help, so
+// fail conservatively. We will assume it's false except for: (1) types
+// for which is_pod is true. (2) std::pair of types with trivial
+// destructors. (3) array of a type with a trivial destructor.
+// (4) const versions thereof.
+template <class T> struct has_trivial_destructor : is_pod<T> { };
+template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
+  : integral_constant<bool,
+                      (has_trivial_destructor<T>::value &&
+                       has_trivial_destructor<U>::value)> { };
+template <class A, int N> struct has_trivial_destructor<A[N]>
+  : has_trivial_destructor<A> { };
+template <class T> struct has_trivial_destructor<const T>
+  : has_trivial_destructor<T> { };
+
+// Specified by TR1 [4.7.1]
+template<typename T> struct remove_const { typedef T type; };
+template<typename T> struct remove_const<T const> { typedef T type; };
+template<typename T> struct remove_volatile { typedef T type; };
+template<typename T> struct remove_volatile<T volatile> { typedef T type; };
+template<typename T> struct remove_cv {
+  typedef typename remove_const<typename remove_volatile<T>::type>::type type;
+};
+
+
+// Specified by TR1 [4.7.2] Reference modifications.
+template<typename T> struct remove_reference { typedef T type; };
+template<typename T> struct remove_reference<T&> { typedef T type; };
+
+template <typename T> struct add_reference { typedef T& type; };
+template <typename T> struct add_reference<T&> { typedef T& type; };
+
+// 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; };
+
+// Specified by TR1 [4.6] Relationships between types
+template<typename T, typename U> struct is_same : public false_type { };
+template<typename T> struct is_same<T, T> : public true_type { };
+
+// Specified by TR1 [4.6] Relationships between types
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+namespace internal {
+
+// This class is an implementation detail for is_convertible, and you
+// don't need to know how it works to use is_convertible. For those
+// who care: we declare two different functions, one whose argument is
+// of type To and one with a variadic argument list. We give them
+// return types of different size, so we can use sizeof to trick the
+// compiler into telling us which function it would have chosen if we
+// had called it with an argument of type From.  See Alexandrescu's
+// _Modern C++ Design_ for more details on this sort of trick.
+
+template <typename From, typename To>
+struct ConvertHelper {
+  static small_ Test(To);
+  static big_ Test(...);
+  static From Create();
+};
+}  // namespace internal
+
+// Inherits from true_type if From is convertible to To, false_type otherwise.
+template <typename From, typename To>
+struct is_convertible
+    : integral_constant<bool,
+                        sizeof(internal::ConvertHelper<From, To>::Test(
+                                  internal::ConvertHelper<From, To>::Create()))
+                        == sizeof(small_)> {
+};
+#endif
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_TYPE_TRAITS_H_
diff --git a/protobuf/src/google/protobuf/stubs/type_traits_unittest.cc b/protobuf/src/google/protobuf/stubs/type_traits_unittest.cc
new file mode 100644
index 0000000..7a8cbfb
--- /dev/null
+++ b/protobuf/src/google/protobuf/stubs/type_traits_unittest.cc
@@ -0,0 +1,628 @@
+// Copyright (c) 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: Matt Austern
+
+#include <google/protobuf/stubs/type_traits.h>
+
+#include <stdlib.h>   // for exit()
+#include <stdio.h>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+typedef int int32;
+typedef long int64;
+
+using std::string;
+using std::vector;
+using std::pair;
+
+
+// This assertion produces errors like "error: invalid use of
+// incomplete type 'struct <unnamed>::AssertTypesEq<const int, int>'"
+// when it fails.
+template<typename T, typename U> struct AssertTypesEq;
+template<typename T> struct AssertTypesEq<T, T> {};
+#define COMPILE_ASSERT_TYPES_EQ(T, U) static_cast<void>(AssertTypesEq<T, U>())
+
+// A user-defined POD type.
+struct A {
+  int n_;
+};
+
+// A user-defined non-POD type with a trivial copy constructor.
+class B {
+ public:
+  explicit B(int n) : n_(n) { }
+ private:
+  int n_;
+};
+
+// Another user-defined non-POD type with a trivial copy constructor.
+// We will explicitly declare C to have a trivial copy constructor
+// by specializing has_trivial_copy.
+class C {
+ public:
+  explicit C(int n) : n_(n) { }
+ private:
+  int n_;
+};
+
+namespace google {
+namespace protobuf {
+namespace internal {
+template<> struct has_trivial_copy<C> : true_type { };
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+// Another user-defined non-POD type with a trivial assignment operator.
+// We will explicitly declare C to have a trivial assignment operator
+// by specializing has_trivial_assign.
+class D {
+ public:
+  explicit D(int n) : n_(n) { }
+ private:
+  int n_;
+};
+
+namespace google {
+namespace protobuf {
+namespace internal {
+template<> struct has_trivial_assign<D> : true_type { };
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+// Another user-defined non-POD type with a trivial constructor.
+// We will explicitly declare E to have a trivial constructor
+// by specializing has_trivial_constructor.
+class E {
+ public:
+  int n_;
+};
+
+namespace google {
+namespace protobuf {
+namespace internal {
+template<> struct has_trivial_constructor<E> : true_type { };
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+// Another user-defined non-POD type with a trivial destructor.
+// We will explicitly declare E to have a trivial destructor
+// by specializing has_trivial_destructor.
+class F {
+ public:
+  explicit F(int n) : n_(n) { }
+ private:
+  int n_;
+};
+
+namespace google {
+namespace protobuf {
+namespace internal {
+template<> struct has_trivial_destructor<F> : true_type { };
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
+
+enum G {};
+
+union H {};
+
+class I {
+ public:
+  operator int() const;
+};
+
+class J {
+ private:
+  operator int() const;
+};
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+// A base class and a derived class that inherits from it, used for
+// testing conversion type traits.
+class Base {
+ public:
+  virtual ~Base() { }
+};
+
+class Derived : public Base {
+};
+
+TEST(TypeTraitsTest, TestIsInteger) {
+  // Verify that is_integral is true for all integer types.
+  EXPECT_TRUE(is_integral<bool>::value);
+  EXPECT_TRUE(is_integral<char>::value);
+  EXPECT_TRUE(is_integral<unsigned char>::value);
+  EXPECT_TRUE(is_integral<signed char>::value);
+  EXPECT_TRUE(is_integral<wchar_t>::value);
+  EXPECT_TRUE(is_integral<int>::value);
+  EXPECT_TRUE(is_integral<unsigned int>::value);
+  EXPECT_TRUE(is_integral<short>::value);
+  EXPECT_TRUE(is_integral<unsigned short>::value);
+  EXPECT_TRUE(is_integral<long>::value);
+  EXPECT_TRUE(is_integral<unsigned long>::value);
+
+  // Verify that is_integral is false for a few non-integer types.
+  EXPECT_FALSE(is_integral<void>::value);
+  EXPECT_FALSE(is_integral<float>::value);
+  EXPECT_FALSE(is_integral<string>::value);
+  EXPECT_FALSE(is_integral<int*>::value);
+  EXPECT_FALSE(is_integral<A>::value);
+  EXPECT_FALSE((is_integral<pair<int, int> >::value));
+
+  // Verify that cv-qualified integral types are still integral, and
+  // cv-qualified non-integral types are still non-integral.
+  EXPECT_TRUE(is_integral<const char>::value);
+  EXPECT_TRUE(is_integral<volatile bool>::value);
+  EXPECT_TRUE(is_integral<const volatile unsigned int>::value);
+  EXPECT_FALSE(is_integral<const float>::value);
+  EXPECT_FALSE(is_integral<int* volatile>::value);
+  EXPECT_FALSE(is_integral<const volatile string>::value);
+}
+
+TEST(TypeTraitsTest, TestIsFloating) {
+  // Verify that is_floating_point is true for all floating-point types.
+  EXPECT_TRUE(is_floating_point<float>::value);
+  EXPECT_TRUE(is_floating_point<double>::value);
+  EXPECT_TRUE(is_floating_point<long double>::value);
+
+  // Verify that is_floating_point is false for a few non-float types.
+  EXPECT_FALSE(is_floating_point<void>::value);
+  EXPECT_FALSE(is_floating_point<long>::value);
+  EXPECT_FALSE(is_floating_point<string>::value);
+  EXPECT_FALSE(is_floating_point<float*>::value);
+  EXPECT_FALSE(is_floating_point<A>::value);
+  EXPECT_FALSE((is_floating_point<pair<int, int> >::value));
+
+  // Verify that cv-qualified floating point types are still floating, and
+  // cv-qualified non-floating types are still non-floating.
+  EXPECT_TRUE(is_floating_point<const float>::value);
+  EXPECT_TRUE(is_floating_point<volatile double>::value);
+  EXPECT_TRUE(is_floating_point<const volatile long double>::value);
+  EXPECT_FALSE(is_floating_point<const int>::value);
+  EXPECT_FALSE(is_floating_point<volatile string>::value);
+  EXPECT_FALSE(is_floating_point<const volatile char>::value);
+}
+
+TEST(TypeTraitsTest, TestIsPointer) {
+  // Verify that is_pointer is true for some pointer types.
+  EXPECT_TRUE(is_pointer<int*>::value);
+  EXPECT_TRUE(is_pointer<void*>::value);
+  EXPECT_TRUE(is_pointer<string*>::value);
+  EXPECT_TRUE(is_pointer<const void*>::value);
+  EXPECT_TRUE(is_pointer<volatile float* const*>::value);
+
+  // Verify that is_pointer is false for some non-pointer types.
+  EXPECT_FALSE(is_pointer<void>::value);
+  EXPECT_FALSE(is_pointer<float&>::value);
+  EXPECT_FALSE(is_pointer<long>::value);
+  EXPECT_FALSE(is_pointer<vector<int*> >::value);
+  EXPECT_FALSE(is_pointer<int[5]>::value);
+
+  // A function pointer is a pointer, but a function type, or a function
+  // reference type, is not.
+  EXPECT_TRUE(is_pointer<int (*)(int x)>::value);
+  EXPECT_FALSE(is_pointer<void(char x)>::value);
+  EXPECT_FALSE(is_pointer<double (&)(string x)>::value);
+
+  // Verify that is_pointer<T> is true for some cv-qualified pointer types,
+  // and false for some cv-qualified non-pointer types.
+  EXPECT_TRUE(is_pointer<int* const>::value);
+  EXPECT_TRUE(is_pointer<const void* volatile>::value);
+  EXPECT_TRUE(is_pointer<char** const volatile>::value);
+  EXPECT_FALSE(is_pointer<const int>::value);
+  EXPECT_FALSE(is_pointer<volatile vector<int*> >::value);
+  EXPECT_FALSE(is_pointer<const volatile double>::value);
+}
+
+TEST(TypeTraitsTest, TestIsEnum) {
+// is_enum isn't supported on MSVC or gcc 3.x
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+  // Verify that is_enum is true for enum types.
+  EXPECT_TRUE(is_enum<G>::value);
+  EXPECT_TRUE(is_enum<const G>::value);
+  EXPECT_TRUE(is_enum<volatile G>::value);
+  EXPECT_TRUE(is_enum<const volatile G>::value);
+
+  // Verify that is_enum is false for a few non-enum types.
+  EXPECT_FALSE(is_enum<void>::value);
+  EXPECT_FALSE(is_enum<G&>::value);
+  EXPECT_FALSE(is_enum<G[1]>::value);
+  EXPECT_FALSE(is_enum<const G[1]>::value);
+  EXPECT_FALSE(is_enum<G[]>::value);
+  EXPECT_FALSE(is_enum<int>::value);
+  EXPECT_FALSE(is_enum<float>::value);
+  EXPECT_FALSE(is_enum<A>::value);
+  EXPECT_FALSE(is_enum<A*>::value);
+  EXPECT_FALSE(is_enum<const A>::value);
+  EXPECT_FALSE(is_enum<H>::value);
+  EXPECT_FALSE(is_enum<I>::value);
+  EXPECT_FALSE(is_enum<J>::value);
+  EXPECT_FALSE(is_enum<void()>::value);
+  EXPECT_FALSE(is_enum<void(*)()>::value);
+  EXPECT_FALSE(is_enum<int A::*>::value);
+  EXPECT_FALSE(is_enum<void (A::*)()>::value);
+#endif
+}
+
+TEST(TypeTraitsTest, TestIsReference) {
+  // Verifies that is_reference is true for all reference types.
+  typedef float& RefFloat;
+  EXPECT_TRUE(is_reference<float&>::value);
+  EXPECT_TRUE(is_reference<const int&>::value);
+  EXPECT_TRUE(is_reference<const int*&>::value);
+  EXPECT_TRUE(is_reference<int (&)(bool)>::value);
+  EXPECT_TRUE(is_reference<RefFloat>::value);
+  EXPECT_TRUE(is_reference<const RefFloat>::value);
+  EXPECT_TRUE(is_reference<volatile RefFloat>::value);
+  EXPECT_TRUE(is_reference<const volatile RefFloat>::value);
+
+
+  // Verifies that is_reference is false for all non-reference types.
+  EXPECT_FALSE(is_reference<float>::value);
+  EXPECT_FALSE(is_reference<const float>::value);
+  EXPECT_FALSE(is_reference<volatile float>::value);
+  EXPECT_FALSE(is_reference<const volatile float>::value);
+  EXPECT_FALSE(is_reference<const int*>::value);
+  EXPECT_FALSE(is_reference<int()>::value);
+  EXPECT_FALSE(is_reference<void(*)(const char&)>::value);
+}
+
+TEST(TypeTraitsTest, TestAddReference) {
+  COMPILE_ASSERT_TYPES_EQ(int&, add_reference<int>::type);
+  COMPILE_ASSERT_TYPES_EQ(const int&, add_reference<const int>::type);
+  COMPILE_ASSERT_TYPES_EQ(volatile int&,
+                          add_reference<volatile int>::type);
+  COMPILE_ASSERT_TYPES_EQ(const volatile int&,
+                          add_reference<const volatile int>::type);
+  COMPILE_ASSERT_TYPES_EQ(int&, add_reference<int&>::type);
+  COMPILE_ASSERT_TYPES_EQ(const int&, add_reference<const int&>::type);
+  COMPILE_ASSERT_TYPES_EQ(volatile int&,
+                          add_reference<volatile int&>::type);
+  COMPILE_ASSERT_TYPES_EQ(const volatile int&,
+                          add_reference<const volatile int&>::type);
+}
+
+TEST(TypeTraitsTest, TestIsPod) {
+  // Verify that arithmetic types and pointers are marked as PODs.
+  EXPECT_TRUE(is_pod<bool>::value);
+  EXPECT_TRUE(is_pod<char>::value);
+  EXPECT_TRUE(is_pod<unsigned char>::value);
+  EXPECT_TRUE(is_pod<signed char>::value);
+  EXPECT_TRUE(is_pod<wchar_t>::value);
+  EXPECT_TRUE(is_pod<int>::value);
+  EXPECT_TRUE(is_pod<unsigned int>::value);
+  EXPECT_TRUE(is_pod<short>::value);
+  EXPECT_TRUE(is_pod<unsigned short>::value);
+  EXPECT_TRUE(is_pod<long>::value);
+  EXPECT_TRUE(is_pod<unsigned long>::value);
+  EXPECT_TRUE(is_pod<float>::value);
+  EXPECT_TRUE(is_pod<double>::value);
+  EXPECT_TRUE(is_pod<long double>::value);
+  EXPECT_TRUE(is_pod<string*>::value);
+  EXPECT_TRUE(is_pod<A*>::value);
+  EXPECT_TRUE(is_pod<const B*>::value);
+  EXPECT_TRUE(is_pod<C**>::value);
+  EXPECT_TRUE(is_pod<const int>::value);
+  EXPECT_TRUE(is_pod<char* volatile>::value);
+  EXPECT_TRUE(is_pod<const volatile double>::value);
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+  EXPECT_TRUE(is_pod<G>::value);
+  EXPECT_TRUE(is_pod<const G>::value);
+  EXPECT_TRUE(is_pod<volatile G>::value);
+  EXPECT_TRUE(is_pod<const volatile G>::value);
+#endif
+
+  // Verify that some non-POD types are not marked as PODs.
+  EXPECT_FALSE(is_pod<void>::value);
+  EXPECT_FALSE(is_pod<string>::value);
+  EXPECT_FALSE((is_pod<pair<int, int> >::value));
+  EXPECT_FALSE(is_pod<A>::value);
+  EXPECT_FALSE(is_pod<B>::value);
+  EXPECT_FALSE(is_pod<C>::value);
+  EXPECT_FALSE(is_pod<const string>::value);
+  EXPECT_FALSE(is_pod<volatile A>::value);
+  EXPECT_FALSE(is_pod<const volatile B>::value);
+}
+
+TEST(TypeTraitsTest, TestHasTrivialConstructor) {
+  // Verify that arithmetic types and pointers have trivial constructors.
+  EXPECT_TRUE(has_trivial_constructor<bool>::value);
+  EXPECT_TRUE(has_trivial_constructor<char>::value);
+  EXPECT_TRUE(has_trivial_constructor<unsigned char>::value);
+  EXPECT_TRUE(has_trivial_constructor<signed char>::value);
+  EXPECT_TRUE(has_trivial_constructor<wchar_t>::value);
+  EXPECT_TRUE(has_trivial_constructor<int>::value);
+  EXPECT_TRUE(has_trivial_constructor<unsigned int>::value);
+  EXPECT_TRUE(has_trivial_constructor<short>::value);
+  EXPECT_TRUE(has_trivial_constructor<unsigned short>::value);
+  EXPECT_TRUE(has_trivial_constructor<long>::value);
+  EXPECT_TRUE(has_trivial_constructor<unsigned long>::value);
+  EXPECT_TRUE(has_trivial_constructor<float>::value);
+  EXPECT_TRUE(has_trivial_constructor<double>::value);
+  EXPECT_TRUE(has_trivial_constructor<long double>::value);
+  EXPECT_TRUE(has_trivial_constructor<string*>::value);
+  EXPECT_TRUE(has_trivial_constructor<A*>::value);
+  EXPECT_TRUE(has_trivial_constructor<const B*>::value);
+  EXPECT_TRUE(has_trivial_constructor<C**>::value);
+
+  // Verify that pairs and arrays of such types have trivial
+  // constructors.
+  typedef int int10[10];
+  EXPECT_TRUE((has_trivial_constructor<pair<int, char*> >::value));
+  EXPECT_TRUE(has_trivial_constructor<int10>::value);
+
+  // Verify that pairs of types without trivial constructors
+  // are not marked as trivial.
+  EXPECT_FALSE((has_trivial_constructor<pair<int, string> >::value));
+  EXPECT_FALSE((has_trivial_constructor<pair<string, int> >::value));
+
+  // Verify that types without trivial constructors are
+  // correctly marked as such.
+  EXPECT_FALSE(has_trivial_constructor<string>::value);
+  EXPECT_FALSE(has_trivial_constructor<vector<int> >::value);
+
+  // Verify that E, which we have declared to have a trivial
+  // constructor, is correctly marked as such.
+  EXPECT_TRUE(has_trivial_constructor<E>::value);
+}
+
+TEST(TypeTraitsTest, TestHasTrivialCopy) {
+  // Verify that arithmetic types and pointers have trivial copy
+  // constructors.
+  EXPECT_TRUE(has_trivial_copy<bool>::value);
+  EXPECT_TRUE(has_trivial_copy<char>::value);
+  EXPECT_TRUE(has_trivial_copy<unsigned char>::value);
+  EXPECT_TRUE(has_trivial_copy<signed char>::value);
+  EXPECT_TRUE(has_trivial_copy<wchar_t>::value);
+  EXPECT_TRUE(has_trivial_copy<int>::value);
+  EXPECT_TRUE(has_trivial_copy<unsigned int>::value);
+  EXPECT_TRUE(has_trivial_copy<short>::value);
+  EXPECT_TRUE(has_trivial_copy<unsigned short>::value);
+  EXPECT_TRUE(has_trivial_copy<long>::value);
+  EXPECT_TRUE(has_trivial_copy<unsigned long>::value);
+  EXPECT_TRUE(has_trivial_copy<float>::value);
+  EXPECT_TRUE(has_trivial_copy<double>::value);
+  EXPECT_TRUE(has_trivial_copy<long double>::value);
+  EXPECT_TRUE(has_trivial_copy<string*>::value);
+  EXPECT_TRUE(has_trivial_copy<A*>::value);
+  EXPECT_TRUE(has_trivial_copy<const B*>::value);
+  EXPECT_TRUE(has_trivial_copy<C**>::value);
+
+  // Verify that pairs and arrays of such types have trivial
+  // copy constructors.
+  typedef int int10[10];
+  EXPECT_TRUE((has_trivial_copy<pair<int, char*> >::value));
+  EXPECT_TRUE(has_trivial_copy<int10>::value);
+
+  // Verify that pairs of types without trivial copy constructors
+  // are not marked as trivial.
+  EXPECT_FALSE((has_trivial_copy<pair<int, string> >::value));
+  EXPECT_FALSE((has_trivial_copy<pair<string, int> >::value));
+
+  // Verify that types without trivial copy constructors are
+  // correctly marked as such.
+  EXPECT_FALSE(has_trivial_copy<string>::value);
+  EXPECT_FALSE(has_trivial_copy<vector<int> >::value);
+
+  // Verify that C, which we have declared to have a trivial
+  // copy constructor, is correctly marked as such.
+  EXPECT_TRUE(has_trivial_copy<C>::value);
+}
+
+TEST(TypeTraitsTest, TestHasTrivialAssign) {
+  // Verify that arithmetic types and pointers have trivial assignment
+  // operators.
+  EXPECT_TRUE(has_trivial_assign<bool>::value);
+  EXPECT_TRUE(has_trivial_assign<char>::value);
+  EXPECT_TRUE(has_trivial_assign<unsigned char>::value);
+  EXPECT_TRUE(has_trivial_assign<signed char>::value);
+  EXPECT_TRUE(has_trivial_assign<wchar_t>::value);
+  EXPECT_TRUE(has_trivial_assign<int>::value);
+  EXPECT_TRUE(has_trivial_assign<unsigned int>::value);
+  EXPECT_TRUE(has_trivial_assign<short>::value);
+  EXPECT_TRUE(has_trivial_assign<unsigned short>::value);
+  EXPECT_TRUE(has_trivial_assign<long>::value);
+  EXPECT_TRUE(has_trivial_assign<unsigned long>::value);
+  EXPECT_TRUE(has_trivial_assign<float>::value);
+  EXPECT_TRUE(has_trivial_assign<double>::value);
+  EXPECT_TRUE(has_trivial_assign<long double>::value);
+  EXPECT_TRUE(has_trivial_assign<string*>::value);
+  EXPECT_TRUE(has_trivial_assign<A*>::value);
+  EXPECT_TRUE(has_trivial_assign<const B*>::value);
+  EXPECT_TRUE(has_trivial_assign<C**>::value);
+
+  // Verify that pairs and arrays of such types have trivial
+  // assignment operators.
+  typedef int int10[10];
+  EXPECT_TRUE((has_trivial_assign<pair<int, char*> >::value));
+  EXPECT_TRUE(has_trivial_assign<int10>::value);
+
+  // Verify that pairs of types without trivial assignment operators
+  // are not marked as trivial.
+  EXPECT_FALSE((has_trivial_assign<pair<int, string> >::value));
+  EXPECT_FALSE((has_trivial_assign<pair<string, int> >::value));
+
+  // Verify that types without trivial assignment operators are
+  // correctly marked as such.
+  EXPECT_FALSE(has_trivial_assign<string>::value);
+  EXPECT_FALSE(has_trivial_assign<vector<int> >::value);
+
+  // Verify that D, which we have declared to have a trivial
+  // assignment operator, is correctly marked as such.
+  EXPECT_TRUE(has_trivial_assign<D>::value);
+}
+
+TEST(TypeTraitsTest, TestHasTrivialDestructor) {
+  // Verify that arithmetic types and pointers have trivial destructors.
+  EXPECT_TRUE(has_trivial_destructor<bool>::value);
+  EXPECT_TRUE(has_trivial_destructor<char>::value);
+  EXPECT_TRUE(has_trivial_destructor<unsigned char>::value);
+  EXPECT_TRUE(has_trivial_destructor<signed char>::value);
+  EXPECT_TRUE(has_trivial_destructor<wchar_t>::value);
+  EXPECT_TRUE(has_trivial_destructor<int>::value);
+  EXPECT_TRUE(has_trivial_destructor<unsigned int>::value);
+  EXPECT_TRUE(has_trivial_destructor<short>::value);
+  EXPECT_TRUE(has_trivial_destructor<unsigned short>::value);
+  EXPECT_TRUE(has_trivial_destructor<long>::value);
+  EXPECT_TRUE(has_trivial_destructor<unsigned long>::value);
+  EXPECT_TRUE(has_trivial_destructor<float>::value);
+  EXPECT_TRUE(has_trivial_destructor<double>::value);
+  EXPECT_TRUE(has_trivial_destructor<long double>::value);
+  EXPECT_TRUE(has_trivial_destructor<string*>::value);
+  EXPECT_TRUE(has_trivial_destructor<A*>::value);
+  EXPECT_TRUE(has_trivial_destructor<const B*>::value);
+  EXPECT_TRUE(has_trivial_destructor<C**>::value);
+
+  // Verify that pairs and arrays of such types have trivial
+  // destructors.
+  typedef int int10[10];
+  EXPECT_TRUE((has_trivial_destructor<pair<int, char*> >::value));
+  EXPECT_TRUE(has_trivial_destructor<int10>::value);
+
+  // Verify that pairs of types without trivial destructors
+  // are not marked as trivial.
+  EXPECT_FALSE((has_trivial_destructor<pair<int, string> >::value));
+  EXPECT_FALSE((has_trivial_destructor<pair<string, int> >::value));
+
+  // Verify that types without trivial destructors are
+  // correctly marked as such.
+  EXPECT_FALSE(has_trivial_destructor<string>::value);
+  EXPECT_FALSE(has_trivial_destructor<vector<int> >::value);
+
+  // Verify that F, which we have declared to have a trivial
+  // destructor, is correctly marked as such.
+  EXPECT_TRUE(has_trivial_destructor<F>::value);
+}
+
+// Tests remove_pointer.
+TEST(TypeTraitsTest, TestRemovePointer) {
+  COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int>::type);
+  COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int*>::type);
+  COMPILE_ASSERT_TYPES_EQ(const int, remove_pointer<const int*>::type);
+  COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int* const>::type);
+  COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int* volatile>::type);
+}
+
+TEST(TypeTraitsTest, TestRemoveConst) {
+  COMPILE_ASSERT_TYPES_EQ(int, remove_const<int>::type);
+  COMPILE_ASSERT_TYPES_EQ(int, remove_const<const int>::type);
+  COMPILE_ASSERT_TYPES_EQ(int *, remove_const<int * const>::type);
+  // TR1 examples.
+  COMPILE_ASSERT_TYPES_EQ(const int *, remove_const<const int *>::type);
+  COMPILE_ASSERT_TYPES_EQ(volatile int,
+                          remove_const<const volatile int>::type);
+}
+
+TEST(TypeTraitsTest, TestRemoveVolatile) {
+  COMPILE_ASSERT_TYPES_EQ(int, remove_volatile<int>::type);
+  COMPILE_ASSERT_TYPES_EQ(int, remove_volatile<volatile int>::type);
+  COMPILE_ASSERT_TYPES_EQ(int *, remove_volatile<int * volatile>::type);
+  // TR1 examples.
+  COMPILE_ASSERT_TYPES_EQ(volatile int *,
+                          remove_volatile<volatile int *>::type);
+  COMPILE_ASSERT_TYPES_EQ(const int,
+                          remove_volatile<const volatile int>::type);
+}
+
+TEST(TypeTraitsTest, TestRemoveCV) {
+  COMPILE_ASSERT_TYPES_EQ(int, remove_cv<int>::type);
+  COMPILE_ASSERT_TYPES_EQ(int, remove_cv<volatile int>::type);
+  COMPILE_ASSERT_TYPES_EQ(int, remove_cv<const int>::type);
+  COMPILE_ASSERT_TYPES_EQ(int *, remove_cv<int * const volatile>::type);
+  // TR1 examples.
+  COMPILE_ASSERT_TYPES_EQ(const volatile int *,
+                          remove_cv<const volatile int *>::type);
+  COMPILE_ASSERT_TYPES_EQ(int,
+                          remove_cv<const volatile int>::type);
+}
+
+TEST(TypeTraitsTest, TestRemoveReference) {
+  COMPILE_ASSERT_TYPES_EQ(int, remove_reference<int>::type);
+  COMPILE_ASSERT_TYPES_EQ(int, remove_reference<int&>::type);
+  COMPILE_ASSERT_TYPES_EQ(const int, remove_reference<const int&>::type);
+  COMPILE_ASSERT_TYPES_EQ(int*, remove_reference<int * &>::type);
+}
+
+TEST(TypeTraitsTest, TestIsSame) {
+  EXPECT_TRUE((is_same<int32, int32>::value));
+  EXPECT_FALSE((is_same<int32, int64>::value));
+  EXPECT_FALSE((is_same<int64, int32>::value));
+  EXPECT_FALSE((is_same<int, const int>::value));
+
+  EXPECT_TRUE((is_same<void, void>::value));
+  EXPECT_FALSE((is_same<void, int>::value));
+  EXPECT_FALSE((is_same<int, void>::value));
+
+  EXPECT_TRUE((is_same<int*, int*>::value));
+  EXPECT_TRUE((is_same<void*, void*>::value));
+  EXPECT_FALSE((is_same<int*, void*>::value));
+  EXPECT_FALSE((is_same<void*, int*>::value));
+  EXPECT_FALSE((is_same<void*, const void*>::value));
+  EXPECT_FALSE((is_same<void*, void* const>::value));
+
+  EXPECT_TRUE((is_same<Base*, Base*>::value));
+  EXPECT_TRUE((is_same<Derived*, Derived*>::value));
+  EXPECT_FALSE((is_same<Base*, Derived*>::value));
+  EXPECT_FALSE((is_same<Derived*, Base*>::value));
+}
+
+TEST(TypeTraitsTest, TestConvertible) {
+#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
+  EXPECT_TRUE((is_convertible<int, int>::value));
+  EXPECT_TRUE((is_convertible<int, long>::value));
+  EXPECT_TRUE((is_convertible<long, int>::value));
+
+  EXPECT_TRUE((is_convertible<int*, void*>::value));
+  EXPECT_FALSE((is_convertible<void*, int*>::value));
+
+  EXPECT_TRUE((is_convertible<Derived*, Base*>::value));
+  EXPECT_FALSE((is_convertible<Base*, Derived*>::value));
+  EXPECT_TRUE((is_convertible<Derived*, const Base*>::value));
+  EXPECT_FALSE((is_convertible<const Derived*, Base*>::value));
+#endif
+}
+
+}  // anonymous namespace
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/test_util.cc b/protobuf/src/google/protobuf/test_util.cc
new file mode 100644
index 0000000..be1c90e
--- /dev/null
+++ b/protobuf/src/google/protobuf/test_util.cc
@@ -0,0 +1,3345 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifdef _WIN32
+// Verify that #including windows.h does not break anything (e.g. because
+// windows.h #defines GetMessage() as a macro).
+#include <windows.h>
+#endif
+
+#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) {
+  SetOptionalFields(message);
+  AddRepeatedFields1(message);
+  AddRepeatedFields2(message);
+  SetDefaultFields(message);
+  SetOneofFields(message);
+}
+
+void TestUtil::SetOptionalFields(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->mutable_optional_public_import_message()->set_e(126);
+  message->mutable_optional_lazy_message         ()->set_bb(127);
+
+  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.
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+  message->GetReflection()->SetString(
+    message,
+    message->GetDescriptor()->FindFieldByName("optional_string_piece"),
+    "124");
+  message->GetReflection()->SetString(
+    message,
+    message->GetDescriptor()->FindFieldByName("optional_cord"),
+    "125");
+#endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::AddRepeatedFields1(unittest::TestAllTypes* message) {
+  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_lazy_message   ()->set_bb(227);
+
+  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);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+  message->GetReflection()->AddString(
+    message,
+    message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+    "224");
+  message->GetReflection()->AddString(
+    message,
+    message->GetDescriptor()->FindFieldByName("repeated_cord"),
+    "225");
+#endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+void TestUtil::AddRepeatedFields2(unittest::TestAllTypes* message) {
+  // 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_lazy_message   ()->set_bb(327);
+
+  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);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+  message->GetReflection()->AddString(
+    message,
+    message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+    "324");
+  message->GetReflection()->AddString(
+    message,
+    message->GetDescriptor()->FindFieldByName("repeated_cord"),
+    "325");
+#endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::SetDefaultFields(unittest::TestAllTypes* message) {
+  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);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+  message->GetReflection()->SetString(
+    message,
+    message->GetDescriptor()->FindFieldByName("default_string_piece"),
+    "424");
+  message->GetReflection()->SetString(
+    message,
+    message->GetDescriptor()->FindFieldByName("default_cord"),
+    "425");
+#endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+// -------------------------------------------------------------------
+
+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->mutable_repeated_lazy_message   (1)->set_bb(527);
+
+  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);
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+  message->GetReflection()->SetRepeatedString(
+    message,
+    message->GetDescriptor()->FindFieldByName("repeated_string_piece"),
+    1, "524");
+  message->GetReflection()->SetRepeatedString(
+    message,
+    message->GetDescriptor()->FindFieldByName("repeated_cord"),
+    1, "525");
+#endif  // !PROTOBUF_TEST_NO_DESCRIPTORS
+}
+
+// ------------------------------------------------------------------
+void TestUtil::SetOneofFields(unittest::TestAllTypes* message) {
+  message->set_oneof_uint32(601);
+  message->mutable_oneof_nested_message()->set_bb(602);
+  message->set_oneof_string("603");
+  message->set_oneof_bytes("604");
+}
+
+// -------------------------------------------------------------------
+
+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.has_optional_public_import_message());
+  EXPECT_TRUE(message.has_optional_lazy_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.optional_public_import_message().has_e());
+  EXPECT_TRUE(message.optional_lazy_message         ().has_bb());
+
+  EXPECT_TRUE(message.has_optional_nested_enum ());
+  EXPECT_TRUE(message.has_optional_foreign_enum());
+  EXPECT_TRUE(message.has_optional_import_enum ());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+  EXPECT_TRUE(message.has_optional_string_piece());
+  EXPECT_TRUE(message.has_optional_cord());
+#endif
+
+  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_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(126, message.optional_public_import_message ().e());
+  EXPECT_EQ(127, message.optional_lazy_message          ().bb());
+
+  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_lazy_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    ());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+  ASSERT_EQ(2, message.repeated_string_piece_size());
+  ASSERT_EQ(2, message.repeated_cord_size());
+#endif
+
+  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_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(227, message.repeated_lazy_message   (0).bb());
+
+
+  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_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(327, message.repeated_lazy_message   (1).bb());
+
+  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_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 ());
+
+
+  EXPECT_FALSE(message.has_oneof_uint32        ());
+  EXPECT_FALSE(message.has_oneof_nested_message());
+  EXPECT_FALSE(message.has_oneof_string        ());
+  EXPECT_TRUE(message.has_oneof_bytes          ());
+
+  EXPECT_EQ("604", message.oneof_bytes());
+}
+
+// -------------------------------------------------------------------
+
+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_public_import_message());
+  EXPECT_FALSE(message.has_optional_lazy_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_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_FALSE(message.optional_public_import_message().has_e());
+  EXPECT_FALSE(message.optional_lazy_message         ().has_bb());
+
+  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());
+  EXPECT_EQ(0, message.optional_public_import_message().e());
+  EXPECT_EQ(0, message.optional_lazy_message         ().bb());
+
+  // 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_lazy_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_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 ());
+
+
+  EXPECT_FALSE(message.has_oneof_uint32        ());
+  EXPECT_FALSE(message.has_oneof_nested_message());
+  EXPECT_FALSE(message.has_oneof_string        ());
+  EXPECT_FALSE(message.has_oneof_bytes         ());
+}
+
+// -------------------------------------------------------------------
+
+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_lazy_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    ());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+  ASSERT_EQ(2, message.repeated_string_piece_size());
+  ASSERT_EQ(2, message.repeated_cord_size());
+#endif
+
+  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_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(227, message.repeated_lazy_message   (0).bb());
+
+  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_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(527, message.repeated_lazy_message   (1).bb());
+
+  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));
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::SetPackedFields(unittest::TestPackedTypes* message) {
+  message->add_packed_int32   (601);
+  message->add_packed_int64   (602);
+  message->add_packed_uint32  (603);
+  message->add_packed_uint64  (604);
+  message->add_packed_sint32  (605);
+  message->add_packed_sint64  (606);
+  message->add_packed_fixed32 (607);
+  message->add_packed_fixed64 (608);
+  message->add_packed_sfixed32(609);
+  message->add_packed_sfixed64(610);
+  message->add_packed_float   (611);
+  message->add_packed_double  (612);
+  message->add_packed_bool    (true);
+  message->add_packed_enum    (unittest::FOREIGN_BAR);
+  // add a second one of each field
+  message->add_packed_int32   (701);
+  message->add_packed_int64   (702);
+  message->add_packed_uint32  (703);
+  message->add_packed_uint64  (704);
+  message->add_packed_sint32  (705);
+  message->add_packed_sint64  (706);
+  message->add_packed_fixed32 (707);
+  message->add_packed_fixed64 (708);
+  message->add_packed_sfixed32(709);
+  message->add_packed_sfixed64(710);
+  message->add_packed_float   (711);
+  message->add_packed_double  (712);
+  message->add_packed_bool    (false);
+  message->add_packed_enum    (unittest::FOREIGN_BAZ);
+}
+
+void TestUtil::SetUnpackedFields(unittest::TestUnpackedTypes* message) {
+  // The values applied here must match those of SetPackedFields.
+
+  message->add_unpacked_int32   (601);
+  message->add_unpacked_int64   (602);
+  message->add_unpacked_uint32  (603);
+  message->add_unpacked_uint64  (604);
+  message->add_unpacked_sint32  (605);
+  message->add_unpacked_sint64  (606);
+  message->add_unpacked_fixed32 (607);
+  message->add_unpacked_fixed64 (608);
+  message->add_unpacked_sfixed32(609);
+  message->add_unpacked_sfixed64(610);
+  message->add_unpacked_float   (611);
+  message->add_unpacked_double  (612);
+  message->add_unpacked_bool    (true);
+  message->add_unpacked_enum    (unittest::FOREIGN_BAR);
+  // add a second one of each field
+  message->add_unpacked_int32   (701);
+  message->add_unpacked_int64   (702);
+  message->add_unpacked_uint32  (703);
+  message->add_unpacked_uint64  (704);
+  message->add_unpacked_sint32  (705);
+  message->add_unpacked_sint64  (706);
+  message->add_unpacked_fixed32 (707);
+  message->add_unpacked_fixed64 (708);
+  message->add_unpacked_sfixed32(709);
+  message->add_unpacked_sfixed64(710);
+  message->add_unpacked_float   (711);
+  message->add_unpacked_double  (712);
+  message->add_unpacked_bool    (false);
+  message->add_unpacked_enum    (unittest::FOREIGN_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ModifyPackedFields(unittest::TestPackedTypes* message) {
+  message->set_packed_int32   (1, 801);
+  message->set_packed_int64   (1, 802);
+  message->set_packed_uint32  (1, 803);
+  message->set_packed_uint64  (1, 804);
+  message->set_packed_sint32  (1, 805);
+  message->set_packed_sint64  (1, 806);
+  message->set_packed_fixed32 (1, 807);
+  message->set_packed_fixed64 (1, 808);
+  message->set_packed_sfixed32(1, 809);
+  message->set_packed_sfixed64(1, 810);
+  message->set_packed_float   (1, 811);
+  message->set_packed_double  (1, 812);
+  message->set_packed_bool    (1, true);
+  message->set_packed_enum    (1, unittest::FOREIGN_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedFieldsSet(const unittest::TestPackedTypes& message) {
+  ASSERT_EQ(2, message.packed_int32_size   ());
+  ASSERT_EQ(2, message.packed_int64_size   ());
+  ASSERT_EQ(2, message.packed_uint32_size  ());
+  ASSERT_EQ(2, message.packed_uint64_size  ());
+  ASSERT_EQ(2, message.packed_sint32_size  ());
+  ASSERT_EQ(2, message.packed_sint64_size  ());
+  ASSERT_EQ(2, message.packed_fixed32_size ());
+  ASSERT_EQ(2, message.packed_fixed64_size ());
+  ASSERT_EQ(2, message.packed_sfixed32_size());
+  ASSERT_EQ(2, message.packed_sfixed64_size());
+  ASSERT_EQ(2, message.packed_float_size   ());
+  ASSERT_EQ(2, message.packed_double_size  ());
+  ASSERT_EQ(2, message.packed_bool_size    ());
+  ASSERT_EQ(2, message.packed_enum_size    ());
+
+  EXPECT_EQ(601  , message.packed_int32   (0));
+  EXPECT_EQ(602  , message.packed_int64   (0));
+  EXPECT_EQ(603  , message.packed_uint32  (0));
+  EXPECT_EQ(604  , message.packed_uint64  (0));
+  EXPECT_EQ(605  , message.packed_sint32  (0));
+  EXPECT_EQ(606  , message.packed_sint64  (0));
+  EXPECT_EQ(607  , message.packed_fixed32 (0));
+  EXPECT_EQ(608  , message.packed_fixed64 (0));
+  EXPECT_EQ(609  , message.packed_sfixed32(0));
+  EXPECT_EQ(610  , message.packed_sfixed64(0));
+  EXPECT_EQ(611  , message.packed_float   (0));
+  EXPECT_EQ(612  , message.packed_double  (0));
+  EXPECT_TRUE(     message.packed_bool    (0));
+  EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0));
+
+  EXPECT_EQ(701  , message.packed_int32   (1));
+  EXPECT_EQ(702  , message.packed_int64   (1));
+  EXPECT_EQ(703  , message.packed_uint32  (1));
+  EXPECT_EQ(704  , message.packed_uint64  (1));
+  EXPECT_EQ(705  , message.packed_sint32  (1));
+  EXPECT_EQ(706  , message.packed_sint64  (1));
+  EXPECT_EQ(707  , message.packed_fixed32 (1));
+  EXPECT_EQ(708  , message.packed_fixed64 (1));
+  EXPECT_EQ(709  , message.packed_sfixed32(1));
+  EXPECT_EQ(710  , message.packed_sfixed64(1));
+  EXPECT_EQ(711  , message.packed_float   (1));
+  EXPECT_EQ(712  , message.packed_double  (1));
+  EXPECT_FALSE(    message.packed_bool    (1));
+  EXPECT_EQ(unittest::FOREIGN_BAZ, message.packed_enum(1));
+}
+
+void TestUtil::ExpectUnpackedFieldsSet(
+    const unittest::TestUnpackedTypes& message) {
+  // The values expected here must match those of ExpectPackedFieldsSet.
+
+  ASSERT_EQ(2, message.unpacked_int32_size   ());
+  ASSERT_EQ(2, message.unpacked_int64_size   ());
+  ASSERT_EQ(2, message.unpacked_uint32_size  ());
+  ASSERT_EQ(2, message.unpacked_uint64_size  ());
+  ASSERT_EQ(2, message.unpacked_sint32_size  ());
+  ASSERT_EQ(2, message.unpacked_sint64_size  ());
+  ASSERT_EQ(2, message.unpacked_fixed32_size ());
+  ASSERT_EQ(2, message.unpacked_fixed64_size ());
+  ASSERT_EQ(2, message.unpacked_sfixed32_size());
+  ASSERT_EQ(2, message.unpacked_sfixed64_size());
+  ASSERT_EQ(2, message.unpacked_float_size   ());
+  ASSERT_EQ(2, message.unpacked_double_size  ());
+  ASSERT_EQ(2, message.unpacked_bool_size    ());
+  ASSERT_EQ(2, message.unpacked_enum_size    ());
+
+  EXPECT_EQ(601  , message.unpacked_int32   (0));
+  EXPECT_EQ(602  , message.unpacked_int64   (0));
+  EXPECT_EQ(603  , message.unpacked_uint32  (0));
+  EXPECT_EQ(604  , message.unpacked_uint64  (0));
+  EXPECT_EQ(605  , message.unpacked_sint32  (0));
+  EXPECT_EQ(606  , message.unpacked_sint64  (0));
+  EXPECT_EQ(607  , message.unpacked_fixed32 (0));
+  EXPECT_EQ(608  , message.unpacked_fixed64 (0));
+  EXPECT_EQ(609  , message.unpacked_sfixed32(0));
+  EXPECT_EQ(610  , message.unpacked_sfixed64(0));
+  EXPECT_EQ(611  , message.unpacked_float   (0));
+  EXPECT_EQ(612  , message.unpacked_double  (0));
+  EXPECT_TRUE(     message.unpacked_bool    (0));
+  EXPECT_EQ(unittest::FOREIGN_BAR, message.unpacked_enum(0));
+
+  EXPECT_EQ(701  , message.unpacked_int32   (1));
+  EXPECT_EQ(702  , message.unpacked_int64   (1));
+  EXPECT_EQ(703  , message.unpacked_uint32  (1));
+  EXPECT_EQ(704  , message.unpacked_uint64  (1));
+  EXPECT_EQ(705  , message.unpacked_sint32  (1));
+  EXPECT_EQ(706  , message.unpacked_sint64  (1));
+  EXPECT_EQ(707  , message.unpacked_fixed32 (1));
+  EXPECT_EQ(708  , message.unpacked_fixed64 (1));
+  EXPECT_EQ(709  , message.unpacked_sfixed32(1));
+  EXPECT_EQ(710  , message.unpacked_sfixed64(1));
+  EXPECT_EQ(711  , message.unpacked_float   (1));
+  EXPECT_EQ(712  , message.unpacked_double  (1));
+  EXPECT_FALSE(    message.unpacked_bool    (1));
+  EXPECT_EQ(unittest::FOREIGN_BAZ, message.unpacked_enum(1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedClear(
+    const unittest::TestPackedTypes& message) {
+  // Packed repeated fields are empty.
+  EXPECT_EQ(0, message.packed_int32_size   ());
+  EXPECT_EQ(0, message.packed_int64_size   ());
+  EXPECT_EQ(0, message.packed_uint32_size  ());
+  EXPECT_EQ(0, message.packed_uint64_size  ());
+  EXPECT_EQ(0, message.packed_sint32_size  ());
+  EXPECT_EQ(0, message.packed_sint64_size  ());
+  EXPECT_EQ(0, message.packed_fixed32_size ());
+  EXPECT_EQ(0, message.packed_fixed64_size ());
+  EXPECT_EQ(0, message.packed_sfixed32_size());
+  EXPECT_EQ(0, message.packed_sfixed64_size());
+  EXPECT_EQ(0, message.packed_float_size   ());
+  EXPECT_EQ(0, message.packed_double_size  ());
+  EXPECT_EQ(0, message.packed_bool_size    ());
+  EXPECT_EQ(0, message.packed_enum_size    ());
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedFieldsModified(
+    const unittest::TestPackedTypes& message) {
+  // Do the same for packed repeated fields.
+  ASSERT_EQ(2, message.packed_int32_size   ());
+  ASSERT_EQ(2, message.packed_int64_size   ());
+  ASSERT_EQ(2, message.packed_uint32_size  ());
+  ASSERT_EQ(2, message.packed_uint64_size  ());
+  ASSERT_EQ(2, message.packed_sint32_size  ());
+  ASSERT_EQ(2, message.packed_sint64_size  ());
+  ASSERT_EQ(2, message.packed_fixed32_size ());
+  ASSERT_EQ(2, message.packed_fixed64_size ());
+  ASSERT_EQ(2, message.packed_sfixed32_size());
+  ASSERT_EQ(2, message.packed_sfixed64_size());
+  ASSERT_EQ(2, message.packed_float_size   ());
+  ASSERT_EQ(2, message.packed_double_size  ());
+  ASSERT_EQ(2, message.packed_bool_size    ());
+  ASSERT_EQ(2, message.packed_enum_size    ());
+
+  EXPECT_EQ(601  , message.packed_int32   (0));
+  EXPECT_EQ(602  , message.packed_int64   (0));
+  EXPECT_EQ(603  , message.packed_uint32  (0));
+  EXPECT_EQ(604  , message.packed_uint64  (0));
+  EXPECT_EQ(605  , message.packed_sint32  (0));
+  EXPECT_EQ(606  , message.packed_sint64  (0));
+  EXPECT_EQ(607  , message.packed_fixed32 (0));
+  EXPECT_EQ(608  , message.packed_fixed64 (0));
+  EXPECT_EQ(609  , message.packed_sfixed32(0));
+  EXPECT_EQ(610  , message.packed_sfixed64(0));
+  EXPECT_EQ(611  , message.packed_float   (0));
+  EXPECT_EQ(612  , message.packed_double  (0));
+  EXPECT_TRUE(     message.packed_bool    (0));
+  EXPECT_EQ(unittest::FOREIGN_BAR, message.packed_enum(0));
+  // Actually verify the second (modified) elements now.
+  EXPECT_EQ(801  , message.packed_int32   (1));
+  EXPECT_EQ(802  , message.packed_int64   (1));
+  EXPECT_EQ(803  , message.packed_uint32  (1));
+  EXPECT_EQ(804  , message.packed_uint64  (1));
+  EXPECT_EQ(805  , message.packed_sint32  (1));
+  EXPECT_EQ(806  , message.packed_sint64  (1));
+  EXPECT_EQ(807  , message.packed_fixed32 (1));
+  EXPECT_EQ(808  , message.packed_fixed64 (1));
+  EXPECT_EQ(809  , message.packed_sfixed32(1));
+  EXPECT_EQ(810  , message.packed_sfixed64(1));
+  EXPECT_EQ(811  , message.packed_float   (1));
+  EXPECT_EQ(812  , message.packed_double  (1));
+  EXPECT_TRUE(     message.packed_bool    (1));
+  EXPECT_EQ(unittest::FOREIGN_FOO, message.packed_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->MutableExtension(unittest::optional_public_import_message_extension)->set_e(126);
+  message->MutableExtension(unittest::optional_lazy_message_extension)->set_bb(127);
+
+  // -----------------------------------------------------------------
+
+  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_lazy_message_extension   )->set_bb(227);
+
+  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_lazy_message_extension   )->set_bb(327);
+
+  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");
+
+  SetOneofFields(message);
+}
+
+void TestUtil::SetOneofFields(unittest::TestAllExtensions* message) {
+  message->SetExtension(unittest::oneof_uint32_extension, 601);
+  message->MutableExtension(unittest::oneof_nested_message_extension)->set_bb(602);
+  message->SetExtension(unittest::oneof_string_extension, "603");
+  message->SetExtension(unittest::oneof_bytes_extension, "604");
+}
+
+// -------------------------------------------------------------------
+
+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->MutableExtension(unittest::repeated_lazy_message_extension   , 1)->set_bb(527);
+
+  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.HasExtension(unittest::optional_public_import_message_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_lazy_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.GetExtension(unittest::optional_public_import_message_extension).has_e());
+  EXPECT_TRUE(message.GetExtension(unittest::optional_lazy_message_extension         ).has_bb());
+
+  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_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));
+  EXPECT_EQ(126, message.GetExtension(unittest::optional_public_import_message_extension ).e());
+  EXPECT_EQ(127, message.GetExtension(unittest::optional_lazy_message_extension).bb());
+
+  // -----------------------------------------------------------------
+
+  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_lazy_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_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(227, message.GetExtension(unittest::repeated_lazy_message_extension   , 0).bb());
+
+  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_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(327, message.GetExtension(unittest::repeated_lazy_message_extension   , 1).bb());
+
+  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_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));
+
+  EXPECT_TRUE(message.HasExtension(unittest::oneof_uint32_extension));
+  EXPECT_TRUE(message.GetExtension(unittest::oneof_nested_message_extension).has_bb());
+  EXPECT_TRUE(message.HasExtension(unittest::oneof_string_extension));
+  EXPECT_TRUE(message.HasExtension(unittest::oneof_bytes_extension));
+
+  EXPECT_EQ(601, message.GetExtension(unittest::oneof_uint32_extension));
+  EXPECT_EQ(602, message.GetExtension(unittest::oneof_nested_message_extension).bb());
+  EXPECT_EQ("603", message.GetExtension(unittest::oneof_string_extension));
+  EXPECT_EQ("604", message.GetExtension(unittest::oneof_bytes_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_public_import_message_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_lazy_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_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_FALSE(message.GetExtension(unittest::optional_public_import_message_extension).has_e());
+  EXPECT_FALSE(message.GetExtension(unittest::optional_lazy_message_extension         ).has_bb());
+
+  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());
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_public_import_message_extension).e());
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_lazy_message_extension         ).bb());
+
+  // 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_lazy_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_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));
+
+  EXPECT_FALSE(message.HasExtension(unittest::oneof_uint32_extension));
+  EXPECT_FALSE(message.GetExtension(unittest::oneof_nested_message_extension).has_bb());
+  EXPECT_FALSE(message.HasExtension(unittest::oneof_string_extension));
+  EXPECT_FALSE(message.HasExtension(unittest::oneof_bytes_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_lazy_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_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(227, message.GetExtension(unittest::repeated_lazy_message_extension   , 0).bb());
+
+  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_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(527, message.GetExtension(unittest::repeated_lazy_message_extension   , 1).bb());
+
+  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::SetPackedExtensions(unittest::TestPackedExtensions* message) {
+  message->AddExtension(unittest::packed_int32_extension   , 601);
+  message->AddExtension(unittest::packed_int64_extension   , 602);
+  message->AddExtension(unittest::packed_uint32_extension  , 603);
+  message->AddExtension(unittest::packed_uint64_extension  , 604);
+  message->AddExtension(unittest::packed_sint32_extension  , 605);
+  message->AddExtension(unittest::packed_sint64_extension  , 606);
+  message->AddExtension(unittest::packed_fixed32_extension , 607);
+  message->AddExtension(unittest::packed_fixed64_extension , 608);
+  message->AddExtension(unittest::packed_sfixed32_extension, 609);
+  message->AddExtension(unittest::packed_sfixed64_extension, 610);
+  message->AddExtension(unittest::packed_float_extension   , 611);
+  message->AddExtension(unittest::packed_double_extension  , 612);
+  message->AddExtension(unittest::packed_bool_extension    , true);
+  message->AddExtension(unittest::packed_enum_extension, unittest::FOREIGN_BAR);
+  // add a second one of each field
+  message->AddExtension(unittest::packed_int32_extension   , 701);
+  message->AddExtension(unittest::packed_int64_extension   , 702);
+  message->AddExtension(unittest::packed_uint32_extension  , 703);
+  message->AddExtension(unittest::packed_uint64_extension  , 704);
+  message->AddExtension(unittest::packed_sint32_extension  , 705);
+  message->AddExtension(unittest::packed_sint64_extension  , 706);
+  message->AddExtension(unittest::packed_fixed32_extension , 707);
+  message->AddExtension(unittest::packed_fixed64_extension , 708);
+  message->AddExtension(unittest::packed_sfixed32_extension, 709);
+  message->AddExtension(unittest::packed_sfixed64_extension, 710);
+  message->AddExtension(unittest::packed_float_extension   , 711);
+  message->AddExtension(unittest::packed_double_extension  , 712);
+  message->AddExtension(unittest::packed_bool_extension    , false);
+  message->AddExtension(unittest::packed_enum_extension, unittest::FOREIGN_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ModifyPackedExtensions(unittest::TestPackedExtensions* message) {
+  message->SetExtension(unittest::packed_int32_extension   , 1, 801);
+  message->SetExtension(unittest::packed_int64_extension   , 1, 802);
+  message->SetExtension(unittest::packed_uint32_extension  , 1, 803);
+  message->SetExtension(unittest::packed_uint64_extension  , 1, 804);
+  message->SetExtension(unittest::packed_sint32_extension  , 1, 805);
+  message->SetExtension(unittest::packed_sint64_extension  , 1, 806);
+  message->SetExtension(unittest::packed_fixed32_extension , 1, 807);
+  message->SetExtension(unittest::packed_fixed64_extension , 1, 808);
+  message->SetExtension(unittest::packed_sfixed32_extension, 1, 809);
+  message->SetExtension(unittest::packed_sfixed64_extension, 1, 810);
+  message->SetExtension(unittest::packed_float_extension   , 1, 811);
+  message->SetExtension(unittest::packed_double_extension  , 1, 812);
+  message->SetExtension(unittest::packed_bool_extension    , 1, true);
+  message->SetExtension(unittest::packed_enum_extension    , 1,
+                        unittest::FOREIGN_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedExtensionsSet(
+    const unittest::TestPackedExtensions& message) {
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension    ));
+
+  EXPECT_EQ(601  , message.GetExtension(unittest::packed_int32_extension   , 0));
+  EXPECT_EQ(602  , message.GetExtension(unittest::packed_int64_extension   , 0));
+  EXPECT_EQ(603  , message.GetExtension(unittest::packed_uint32_extension  , 0));
+  EXPECT_EQ(604  , message.GetExtension(unittest::packed_uint64_extension  , 0));
+  EXPECT_EQ(605  , message.GetExtension(unittest::packed_sint32_extension  , 0));
+  EXPECT_EQ(606  , message.GetExtension(unittest::packed_sint64_extension  , 0));
+  EXPECT_EQ(607  , message.GetExtension(unittest::packed_fixed32_extension , 0));
+  EXPECT_EQ(608  , message.GetExtension(unittest::packed_fixed64_extension , 0));
+  EXPECT_EQ(609  , message.GetExtension(unittest::packed_sfixed32_extension, 0));
+  EXPECT_EQ(610  , message.GetExtension(unittest::packed_sfixed64_extension, 0));
+  EXPECT_EQ(611  , message.GetExtension(unittest::packed_float_extension   , 0));
+  EXPECT_EQ(612  , message.GetExtension(unittest::packed_double_extension  , 0));
+  EXPECT_TRUE(     message.GetExtension(unittest::packed_bool_extension    , 0));
+  EXPECT_EQ(unittest::FOREIGN_BAR,
+            message.GetExtension(unittest::packed_enum_extension, 0));
+  EXPECT_EQ(701  , message.GetExtension(unittest::packed_int32_extension   , 1));
+  EXPECT_EQ(702  , message.GetExtension(unittest::packed_int64_extension   , 1));
+  EXPECT_EQ(703  , message.GetExtension(unittest::packed_uint32_extension  , 1));
+  EXPECT_EQ(704  , message.GetExtension(unittest::packed_uint64_extension  , 1));
+  EXPECT_EQ(705  , message.GetExtension(unittest::packed_sint32_extension  , 1));
+  EXPECT_EQ(706  , message.GetExtension(unittest::packed_sint64_extension  , 1));
+  EXPECT_EQ(707  , message.GetExtension(unittest::packed_fixed32_extension , 1));
+  EXPECT_EQ(708  , message.GetExtension(unittest::packed_fixed64_extension , 1));
+  EXPECT_EQ(709  , message.GetExtension(unittest::packed_sfixed32_extension, 1));
+  EXPECT_EQ(710  , message.GetExtension(unittest::packed_sfixed64_extension, 1));
+  EXPECT_EQ(711  , message.GetExtension(unittest::packed_float_extension   , 1));
+  EXPECT_EQ(712  , message.GetExtension(unittest::packed_double_extension  , 1));
+  EXPECT_FALSE(    message.GetExtension(unittest::packed_bool_extension    , 1));
+  EXPECT_EQ(unittest::FOREIGN_BAZ,
+            message.GetExtension(unittest::packed_enum_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedExtensionsClear(
+    const unittest::TestPackedExtensions& message) {
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension    ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension    ));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectPackedExtensionsModified(
+    const unittest::TestPackedExtensions& message) {
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension    ));
+  EXPECT_EQ(601  , message.GetExtension(unittest::packed_int32_extension   , 0));
+  EXPECT_EQ(602  , message.GetExtension(unittest::packed_int64_extension   , 0));
+  EXPECT_EQ(603  , message.GetExtension(unittest::packed_uint32_extension  , 0));
+  EXPECT_EQ(604  , message.GetExtension(unittest::packed_uint64_extension  , 0));
+  EXPECT_EQ(605  , message.GetExtension(unittest::packed_sint32_extension  , 0));
+  EXPECT_EQ(606  , message.GetExtension(unittest::packed_sint64_extension  , 0));
+  EXPECT_EQ(607  , message.GetExtension(unittest::packed_fixed32_extension , 0));
+  EXPECT_EQ(608  , message.GetExtension(unittest::packed_fixed64_extension , 0));
+  EXPECT_EQ(609  , message.GetExtension(unittest::packed_sfixed32_extension, 0));
+  EXPECT_EQ(610  , message.GetExtension(unittest::packed_sfixed64_extension, 0));
+  EXPECT_EQ(611  , message.GetExtension(unittest::packed_float_extension   , 0));
+  EXPECT_EQ(612  , message.GetExtension(unittest::packed_double_extension  , 0));
+  EXPECT_TRUE(     message.GetExtension(unittest::packed_bool_extension    , 0));
+  EXPECT_EQ(unittest::FOREIGN_BAR,
+            message.GetExtension(unittest::packed_enum_extension, 0));
+
+  // Actually verify the second (modified) elements now.
+  EXPECT_EQ(801  , message.GetExtension(unittest::packed_int32_extension   , 1));
+  EXPECT_EQ(802  , message.GetExtension(unittest::packed_int64_extension   , 1));
+  EXPECT_EQ(803  , message.GetExtension(unittest::packed_uint32_extension  , 1));
+  EXPECT_EQ(804  , message.GetExtension(unittest::packed_uint64_extension  , 1));
+  EXPECT_EQ(805  , message.GetExtension(unittest::packed_sint32_extension  , 1));
+  EXPECT_EQ(806  , message.GetExtension(unittest::packed_sint64_extension  , 1));
+  EXPECT_EQ(807  , message.GetExtension(unittest::packed_fixed32_extension , 1));
+  EXPECT_EQ(808  , message.GetExtension(unittest::packed_fixed64_extension , 1));
+  EXPECT_EQ(809  , message.GetExtension(unittest::packed_sfixed32_extension, 1));
+  EXPECT_EQ(810  , message.GetExtension(unittest::packed_sfixed64_extension, 1));
+  EXPECT_EQ(811  , message.GetExtension(unittest::packed_float_extension   , 1));
+  EXPECT_EQ(812  , message.GetExtension(unittest::packed_double_extension  , 1));
+  EXPECT_TRUE(     message.GetExtension(unittest::packed_bool_extension    , 1));
+  EXPECT_EQ(unittest::FOREIGN_FOO,
+            message.GetExtension(unittest::packed_enum_extension, 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ExpectUnpackedExtensionsSet(
+    const unittest::TestUnpackedExtensions& message) {
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_int32_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_int64_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_uint32_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_uint64_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_sint32_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_sint64_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_fixed32_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_fixed64_extension ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_sfixed32_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_sfixed64_extension));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_float_extension   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_double_extension  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_bool_extension    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::unpacked_enum_extension    ));
+
+  EXPECT_EQ(601  , message.GetExtension(unittest::unpacked_int32_extension   , 0));
+  EXPECT_EQ(602  , message.GetExtension(unittest::unpacked_int64_extension   , 0));
+  EXPECT_EQ(603  , message.GetExtension(unittest::unpacked_uint32_extension  , 0));
+  EXPECT_EQ(604  , message.GetExtension(unittest::unpacked_uint64_extension  , 0));
+  EXPECT_EQ(605  , message.GetExtension(unittest::unpacked_sint32_extension  , 0));
+  EXPECT_EQ(606  , message.GetExtension(unittest::unpacked_sint64_extension  , 0));
+  EXPECT_EQ(607  , message.GetExtension(unittest::unpacked_fixed32_extension , 0));
+  EXPECT_EQ(608  , message.GetExtension(unittest::unpacked_fixed64_extension , 0));
+  EXPECT_EQ(609  , message.GetExtension(unittest::unpacked_sfixed32_extension, 0));
+  EXPECT_EQ(610  , message.GetExtension(unittest::unpacked_sfixed64_extension, 0));
+  EXPECT_EQ(611  , message.GetExtension(unittest::unpacked_float_extension   , 0));
+  EXPECT_EQ(612  , message.GetExtension(unittest::unpacked_double_extension  , 0));
+  EXPECT_EQ(true , message.GetExtension(unittest::unpacked_bool_extension    , 0));
+  EXPECT_EQ(unittest::FOREIGN_BAR,
+            message.GetExtension(unittest::unpacked_enum_extension, 0));
+  EXPECT_EQ(701  , message.GetExtension(unittest::unpacked_int32_extension   , 1));
+  EXPECT_EQ(702  , message.GetExtension(unittest::unpacked_int64_extension   , 1));
+  EXPECT_EQ(703  , message.GetExtension(unittest::unpacked_uint32_extension  , 1));
+  EXPECT_EQ(704  , message.GetExtension(unittest::unpacked_uint64_extension  , 1));
+  EXPECT_EQ(705  , message.GetExtension(unittest::unpacked_sint32_extension  , 1));
+  EXPECT_EQ(706  , message.GetExtension(unittest::unpacked_sint64_extension  , 1));
+  EXPECT_EQ(707  , message.GetExtension(unittest::unpacked_fixed32_extension , 1));
+  EXPECT_EQ(708  , message.GetExtension(unittest::unpacked_fixed64_extension , 1));
+  EXPECT_EQ(709  , message.GetExtension(unittest::unpacked_sfixed32_extension, 1));
+  EXPECT_EQ(710  , message.GetExtension(unittest::unpacked_sfixed64_extension, 1));
+  EXPECT_EQ(711  , message.GetExtension(unittest::unpacked_float_extension   , 1));
+  EXPECT_EQ(712  , message.GetExtension(unittest::unpacked_double_extension  , 1));
+  EXPECT_EQ(false, message.GetExtension(unittest::unpacked_bool_extension    , 1));
+  EXPECT_EQ(unittest::FOREIGN_BAZ,
+            message.GetExtension(unittest::unpacked_enum_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);
+}
+
+void TestUtil::ExpectLastRepeatedsRemoved(
+    const unittest::TestAllTypes& message) {
+  ASSERT_EQ(1, message.repeated_int32_size   ());
+  ASSERT_EQ(1, message.repeated_int64_size   ());
+  ASSERT_EQ(1, message.repeated_uint32_size  ());
+  ASSERT_EQ(1, message.repeated_uint64_size  ());
+  ASSERT_EQ(1, message.repeated_sint32_size  ());
+  ASSERT_EQ(1, message.repeated_sint64_size  ());
+  ASSERT_EQ(1, message.repeated_fixed32_size ());
+  ASSERT_EQ(1, message.repeated_fixed64_size ());
+  ASSERT_EQ(1, message.repeated_sfixed32_size());
+  ASSERT_EQ(1, message.repeated_sfixed64_size());
+  ASSERT_EQ(1, message.repeated_float_size   ());
+  ASSERT_EQ(1, message.repeated_double_size  ());
+  ASSERT_EQ(1, message.repeated_bool_size    ());
+  ASSERT_EQ(1, message.repeated_string_size  ());
+  ASSERT_EQ(1, message.repeated_bytes_size   ());
+
+  ASSERT_EQ(1, message.repeatedgroup_size           ());
+  ASSERT_EQ(1, message.repeated_nested_message_size ());
+  ASSERT_EQ(1, message.repeated_foreign_message_size());
+  ASSERT_EQ(1, message.repeated_import_message_size ());
+  ASSERT_EQ(1, message.repeated_import_message_size ());
+  ASSERT_EQ(1, message.repeated_nested_enum_size    ());
+  ASSERT_EQ(1, message.repeated_foreign_enum_size   ());
+  ASSERT_EQ(1, message.repeated_import_enum_size    ());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+  ASSERT_EQ(1, message.repeated_string_piece_size());
+  ASSERT_EQ(1, message.repeated_cord_size());
+#endif
+
+  // Test that the remaining element is the correct one.
+  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_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(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));
+}
+
+void TestUtil::ExpectLastRepeatedExtensionsRemoved(
+    const unittest::TestAllExtensions& message) {
+
+  // Test that one element was removed.
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_int32_extension   ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_int64_extension   ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_uint32_extension  ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_uint64_extension  ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sint32_extension  ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sint64_extension  ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_fixed32_extension ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_fixed64_extension ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sfixed32_extension));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_sfixed64_extension));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_float_extension   ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_double_extension  ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_bool_extension    ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension  ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_bytes_extension   ));
+
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeatedgroup_extension           ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_message_extension ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_lazy_message_extension   ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_enum_extension    ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_enum_extension   ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_enum_extension    ));
+
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_piece_extension));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_cord_extension));
+
+  // Test that the remaining element is the correct one.
+  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_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(227, message.GetExtension(unittest::repeated_lazy_message_extension   , 0).bb());
+
+  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));
+}
+
+void TestUtil::ExpectLastRepeatedsReleased(
+    const unittest::TestAllTypes& message) {
+  ASSERT_EQ(1, message.repeatedgroup_size           ());
+  ASSERT_EQ(1, message.repeated_nested_message_size ());
+  ASSERT_EQ(1, message.repeated_foreign_message_size());
+  ASSERT_EQ(1, message.repeated_import_message_size ());
+  ASSERT_EQ(1, message.repeated_import_message_size ());
+
+  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(220, message.repeated_import_message (0).d());
+}
+
+void TestUtil::ExpectLastRepeatedExtensionsReleased(
+    const unittest::TestAllExtensions& message) {
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeatedgroup_extension           ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_nested_message_extension ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_foreign_message_extension));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_import_message_extension ));
+  ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_lazy_message_extension   ));
+
+  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(227, message.GetExtension(unittest::repeated_lazy_message_extension   , 0).bb());
+}
+
+void TestUtil::ExpectRepeatedsSwapped(
+    const unittest::TestAllTypes& message) {
+  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_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    ());
+
+#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
+  ASSERT_EQ(2, message.repeated_string_piece_size());
+  ASSERT_EQ(2, message.repeated_cord_size());
+#endif
+
+  // Test that the first element and second element are flipped.
+  EXPECT_EQ(201  , message.repeated_int32   (1));
+  EXPECT_EQ(202  , message.repeated_int64   (1));
+  EXPECT_EQ(203  , message.repeated_uint32  (1));
+  EXPECT_EQ(204  , message.repeated_uint64  (1));
+  EXPECT_EQ(205  , message.repeated_sint32  (1));
+  EXPECT_EQ(206  , message.repeated_sint64  (1));
+  EXPECT_EQ(207  , message.repeated_fixed32 (1));
+  EXPECT_EQ(208  , message.repeated_fixed64 (1));
+  EXPECT_EQ(209  , message.repeated_sfixed32(1));
+  EXPECT_EQ(210  , message.repeated_sfixed64(1));
+  EXPECT_EQ(211  , message.repeated_float   (1));
+  EXPECT_EQ(212  , message.repeated_double  (1));
+  EXPECT_TRUE(     message.repeated_bool    (1));
+  EXPECT_EQ("215", message.repeated_string  (1));
+  EXPECT_EQ("216", message.repeated_bytes   (1));
+
+  EXPECT_EQ(217, message.repeatedgroup           (1).a());
+  EXPECT_EQ(218, message.repeated_nested_message (1).bb());
+  EXPECT_EQ(219, message.repeated_foreign_message(1).c());
+  EXPECT_EQ(220, message.repeated_import_message (1).d());
+  EXPECT_EQ(220, message.repeated_import_message (1).d());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAR, message.repeated_nested_enum (1));
+  EXPECT_EQ(unittest::FOREIGN_BAR      , message.repeated_foreign_enum(1));
+  EXPECT_EQ(unittest_import::IMPORT_BAR, message.repeated_import_enum (1));
+
+  EXPECT_EQ(301  , message.repeated_int32   (0));
+  EXPECT_EQ(302  , message.repeated_int64   (0));
+  EXPECT_EQ(303  , message.repeated_uint32  (0));
+  EXPECT_EQ(304  , message.repeated_uint64  (0));
+  EXPECT_EQ(305  , message.repeated_sint32  (0));
+  EXPECT_EQ(306  , message.repeated_sint64  (0));
+  EXPECT_EQ(307  , message.repeated_fixed32 (0));
+  EXPECT_EQ(308  , message.repeated_fixed64 (0));
+  EXPECT_EQ(309  , message.repeated_sfixed32(0));
+  EXPECT_EQ(310  , message.repeated_sfixed64(0));
+  EXPECT_EQ(311  , message.repeated_float   (0));
+  EXPECT_EQ(312  , message.repeated_double  (0));
+  EXPECT_FALSE(    message.repeated_bool    (0));
+  EXPECT_EQ("315", message.repeated_string  (0));
+  EXPECT_EQ("316", message.repeated_bytes   (0));
+
+  EXPECT_EQ(317, message.repeatedgroup           (0).a());
+  EXPECT_EQ(318, message.repeated_nested_message (0).bb());
+  EXPECT_EQ(319, message.repeated_foreign_message(0).c());
+  EXPECT_EQ(320, message.repeated_import_message (0).d());
+  EXPECT_EQ(320, message.repeated_import_message (0).d());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAZ, message.repeated_nested_enum (0));
+  EXPECT_EQ(unittest::FOREIGN_BAZ      , message.repeated_foreign_enum(0));
+  EXPECT_EQ(unittest_import::IMPORT_BAZ, message.repeated_import_enum (0));
+}
+
+void TestUtil::ExpectRepeatedExtensionsSwapped(
+    const unittest::TestAllExtensions& message) {
+
+  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_lazy_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   , 1));
+  EXPECT_EQ(202  , message.GetExtension(unittest::repeated_int64_extension   , 1));
+  EXPECT_EQ(203  , message.GetExtension(unittest::repeated_uint32_extension  , 1));
+  EXPECT_EQ(204  , message.GetExtension(unittest::repeated_uint64_extension  , 1));
+  EXPECT_EQ(205  , message.GetExtension(unittest::repeated_sint32_extension  , 1));
+  EXPECT_EQ(206  , message.GetExtension(unittest::repeated_sint64_extension  , 1));
+  EXPECT_EQ(207  , message.GetExtension(unittest::repeated_fixed32_extension , 1));
+  EXPECT_EQ(208  , message.GetExtension(unittest::repeated_fixed64_extension , 1));
+  EXPECT_EQ(209  , message.GetExtension(unittest::repeated_sfixed32_extension, 1));
+  EXPECT_EQ(210  , message.GetExtension(unittest::repeated_sfixed64_extension, 1));
+  EXPECT_EQ(211  , message.GetExtension(unittest::repeated_float_extension   , 1));
+  EXPECT_EQ(212  , message.GetExtension(unittest::repeated_double_extension  , 1));
+  EXPECT_TRUE(     message.GetExtension(unittest::repeated_bool_extension    , 1));
+  EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension  , 1));
+  EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension   , 1));
+
+  EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension           , 1).a());
+  EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension , 1).bb());
+  EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension, 1).c());
+  EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension , 1).d());
+  EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension   , 1).bb());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAR, message.GetExtension(unittest::repeated_nested_enum_extension , 1));
+  EXPECT_EQ(unittest::FOREIGN_BAR      , message.GetExtension(unittest::repeated_foreign_enum_extension, 1));
+  EXPECT_EQ(unittest_import::IMPORT_BAR, message.GetExtension(unittest::repeated_import_enum_extension , 1));
+
+  EXPECT_EQ("224", message.GetExtension(unittest::repeated_string_piece_extension, 1));
+  EXPECT_EQ("225", message.GetExtension(unittest::repeated_cord_extension, 1));
+
+  EXPECT_EQ(301  , message.GetExtension(unittest::repeated_int32_extension   , 0));
+  EXPECT_EQ(302  , message.GetExtension(unittest::repeated_int64_extension   , 0));
+  EXPECT_EQ(303  , message.GetExtension(unittest::repeated_uint32_extension  , 0));
+  EXPECT_EQ(304  , message.GetExtension(unittest::repeated_uint64_extension  , 0));
+  EXPECT_EQ(305  , message.GetExtension(unittest::repeated_sint32_extension  , 0));
+  EXPECT_EQ(306  , message.GetExtension(unittest::repeated_sint64_extension  , 0));
+  EXPECT_EQ(307  , message.GetExtension(unittest::repeated_fixed32_extension , 0));
+  EXPECT_EQ(308  , message.GetExtension(unittest::repeated_fixed64_extension , 0));
+  EXPECT_EQ(309  , message.GetExtension(unittest::repeated_sfixed32_extension, 0));
+  EXPECT_EQ(310  , message.GetExtension(unittest::repeated_sfixed64_extension, 0));
+  EXPECT_EQ(311  , message.GetExtension(unittest::repeated_float_extension   , 0));
+  EXPECT_EQ(312  , message.GetExtension(unittest::repeated_double_extension  , 0));
+  EXPECT_FALSE(    message.GetExtension(unittest::repeated_bool_extension    , 0));
+  EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension  , 0));
+  EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension   , 0));
+
+  EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension           , 0).a());
+  EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension , 0).bb());
+  EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension, 0).c());
+  EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension , 0).d());
+  EXPECT_EQ(327, message.GetExtension(unittest::repeated_lazy_message_extension   , 0).bb());
+
+  EXPECT_EQ(unittest::TestAllTypes::BAZ, message.GetExtension(unittest::repeated_nested_enum_extension , 0));
+  EXPECT_EQ(unittest::FOREIGN_BAZ      , message.GetExtension(unittest::repeated_foreign_enum_extension, 0));
+  EXPECT_EQ(unittest_import::IMPORT_BAZ, message.GetExtension(unittest::repeated_import_enum_extension , 0));
+
+  EXPECT_EQ("324", message.GetExtension(unittest::repeated_string_piece_extension, 0));
+  EXPECT_EQ("325", message.GetExtension(unittest::repeated_cord_extension, 0));
+}
+
+void TestUtil::SetOneof1(unittest::TestOneof2* message) {
+  message->mutable_foo_lazy_message()->set_qux_int(100);
+  message->set_bar_string("101");
+  message->set_baz_int(102);
+  message->set_baz_string("103");
+}
+
+void TestUtil::SetOneof2(unittest::TestOneof2* message) {
+  message->set_foo_int(200);
+  message->set_bar_enum(unittest::TestOneof2::BAZ);
+  message->set_baz_int(202);
+  message->set_baz_string("203");
+}
+
+void TestUtil::ExpectOneofSet1(const unittest::TestOneof2& message) {
+  ExpectAtMostOneFieldSetInOneof(message);
+
+  EXPECT_TRUE(message.has_foo_lazy_message          ());
+  EXPECT_TRUE(message.foo_lazy_message().has_qux_int());
+
+  EXPECT_TRUE(message.has_bar_string());
+  EXPECT_TRUE(message.has_baz_int   ());
+  EXPECT_TRUE(message.has_baz_string());
+
+  ASSERT_EQ(0, message.foo_lazy_message().corge_int_size());
+
+  EXPECT_EQ(100  , message.foo_lazy_message().qux_int());
+  EXPECT_EQ("101", message.bar_string                ());
+  EXPECT_EQ(102  , message.baz_int                   ());
+  EXPECT_EQ("103", message.baz_string                ());
+}
+
+void TestUtil::ExpectOneofSet2(const unittest::TestOneof2& message) {
+  ExpectAtMostOneFieldSetInOneof(message);
+
+  EXPECT_TRUE(message.has_foo_int   ());
+  EXPECT_TRUE(message.has_bar_enum  ());
+  EXPECT_TRUE(message.has_baz_int   ());
+  EXPECT_TRUE(message.has_baz_string());
+
+  EXPECT_EQ(200                      , message.foo_int   ());
+  EXPECT_EQ(unittest::TestOneof2::BAZ, message.bar_enum  ());
+  EXPECT_EQ(202                      , message.baz_int   ());
+  EXPECT_EQ("203"                    , message.baz_string());
+}
+
+void TestUtil::ExpectOneofClear(const unittest::TestOneof2& message) {
+  EXPECT_FALSE(message.has_foo_int());
+  EXPECT_FALSE(message.has_foo_string());
+  EXPECT_FALSE(message.has_foo_bytes());
+  EXPECT_FALSE(message.has_foo_enum());
+  EXPECT_FALSE(message.has_foo_message());
+  EXPECT_FALSE(message.has_foogroup());
+  EXPECT_FALSE(message.has_foo_lazy_message());
+
+  EXPECT_FALSE(message.has_bar_int());
+  EXPECT_FALSE(message.has_bar_string());
+  EXPECT_FALSE(message.has_bar_bytes());
+  EXPECT_FALSE(message.has_bar_enum());
+
+  EXPECT_FALSE(message.has_baz_int());
+  EXPECT_FALSE(message.has_baz_string());
+
+  EXPECT_EQ(unittest::TestOneof2::FOO_NOT_SET, message.foo_case());
+  EXPECT_EQ(unittest::TestOneof2::BAR_NOT_SET, message.bar_case());
+}
+
+void TestUtil::ExpectAtMostOneFieldSetInOneof(
+    const unittest::TestOneof2& message) {
+  int count = 0;
+  if (message.has_foo_int()) count++;
+  if (message.has_foo_string()) count++;
+  if (message.has_foo_bytes()) count++;
+  if (message.has_foo_enum()) count++;
+  if (message.has_foo_message()) count++;
+  if (message.has_foogroup()) count++;
+  if (message.has_foo_lazy_message()) count++;
+  EXPECT_LE(count, 1);
+  count = 0;
+  if (message.has_bar_int()) count++;
+  if (message.has_bar_string()) count++;
+  if (message.has_bar_bytes()) count++;
+  if (message.has_bar_enum()) count++;
+  EXPECT_TRUE(count == 0 || count == 1);
+}
+
+// ===================================================================
+
+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");
+  import_e_ =
+    pool->FindFieldByName("protobuf_unittest_import.PublicImportMessage.e");
+  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(import_e_         != 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" ||
+      base_descriptor_->name() == "TestPackedExtensions") {
+    result = base_descriptor_->file()->FindExtensionByName(name + "_extension");
+  } else {
+    result = base_descriptor_->FindFieldByName(name);
+  }
+  GOOGLE_CHECK(result != NULL);
+  return result;
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ReflectionTester::SetAllFieldsViaReflection(Message* message) {
+  const Reflection* reflection = message->GetReflection();
+  Message* sub_message;
+
+  reflection->SetInt32 (message, F("optional_int32"   ), 101);
+  reflection->SetInt64 (message, F("optional_int64"   ), 102);
+  reflection->SetUInt32(message, F("optional_uint32"  ), 103);
+  reflection->SetUInt64(message, F("optional_uint64"  ), 104);
+  reflection->SetInt32 (message, F("optional_sint32"  ), 105);
+  reflection->SetInt64 (message, F("optional_sint64"  ), 106);
+  reflection->SetUInt32(message, F("optional_fixed32" ), 107);
+  reflection->SetUInt64(message, F("optional_fixed64" ), 108);
+  reflection->SetInt32 (message, F("optional_sfixed32"), 109);
+  reflection->SetInt64 (message, F("optional_sfixed64"), 110);
+  reflection->SetFloat (message, F("optional_float"   ), 111);
+  reflection->SetDouble(message, F("optional_double"  ), 112);
+  reflection->SetBool  (message, F("optional_bool"    ), true);
+  reflection->SetString(message, F("optional_string"  ), "115");
+  reflection->SetString(message, F("optional_bytes"   ), "116");
+
+  sub_message = reflection->MutableMessage(message, F("optionalgroup"));
+  sub_message->GetReflection()->SetInt32(sub_message, group_a_, 117);
+  sub_message = reflection->MutableMessage(message, F("optional_nested_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 118);
+  sub_message = reflection->MutableMessage(message, F("optional_foreign_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 119);
+  sub_message = reflection->MutableMessage(message, F("optional_import_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, import_d_, 120);
+
+  reflection->SetEnum(message, F("optional_nested_enum" ),  nested_baz_);
+  reflection->SetEnum(message, F("optional_foreign_enum"), foreign_baz_);
+  reflection->SetEnum(message, F("optional_import_enum" ),  import_baz_);
+
+  reflection->SetString(message, F("optional_string_piece"), "124");
+  reflection->SetString(message, F("optional_cord"), "125");
+
+  sub_message = reflection->MutableMessage(message, F("optional_public_import_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, import_e_, 126);
+
+  sub_message = reflection->MutableMessage(message, F("optional_lazy_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 127);
+
+  // -----------------------------------------------------------------
+
+  reflection->AddInt32 (message, F("repeated_int32"   ), 201);
+  reflection->AddInt64 (message, F("repeated_int64"   ), 202);
+  reflection->AddUInt32(message, F("repeated_uint32"  ), 203);
+  reflection->AddUInt64(message, F("repeated_uint64"  ), 204);
+  reflection->AddInt32 (message, F("repeated_sint32"  ), 205);
+  reflection->AddInt64 (message, F("repeated_sint64"  ), 206);
+  reflection->AddUInt32(message, F("repeated_fixed32" ), 207);
+  reflection->AddUInt64(message, F("repeated_fixed64" ), 208);
+  reflection->AddInt32 (message, F("repeated_sfixed32"), 209);
+  reflection->AddInt64 (message, F("repeated_sfixed64"), 210);
+  reflection->AddFloat (message, F("repeated_float"   ), 211);
+  reflection->AddDouble(message, F("repeated_double"  ), 212);
+  reflection->AddBool  (message, F("repeated_bool"    ), true);
+  reflection->AddString(message, F("repeated_string"  ), "215");
+  reflection->AddString(message, F("repeated_bytes"   ), "216");
+
+  sub_message = reflection->AddMessage(message, F("repeatedgroup"));
+  sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 217);
+  sub_message = reflection->AddMessage(message, F("repeated_nested_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 218);
+  sub_message = reflection->AddMessage(message, F("repeated_foreign_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 219);
+  sub_message = reflection->AddMessage(message, F("repeated_import_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, import_d_, 220);
+  sub_message = reflection->AddMessage(message, F("repeated_lazy_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 227);
+
+  reflection->AddEnum(message, F("repeated_nested_enum" ),  nested_bar_);
+  reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_bar_);
+  reflection->AddEnum(message, F("repeated_import_enum" ),  import_bar_);
+
+  reflection->AddString(message, F("repeated_string_piece"), "224");
+  reflection->AddString(message, F("repeated_cord"), "225");
+
+  // Add a second one of each field.
+  reflection->AddInt32 (message, F("repeated_int32"   ), 301);
+  reflection->AddInt64 (message, F("repeated_int64"   ), 302);
+  reflection->AddUInt32(message, F("repeated_uint32"  ), 303);
+  reflection->AddUInt64(message, F("repeated_uint64"  ), 304);
+  reflection->AddInt32 (message, F("repeated_sint32"  ), 305);
+  reflection->AddInt64 (message, F("repeated_sint64"  ), 306);
+  reflection->AddUInt32(message, F("repeated_fixed32" ), 307);
+  reflection->AddUInt64(message, F("repeated_fixed64" ), 308);
+  reflection->AddInt32 (message, F("repeated_sfixed32"), 309);
+  reflection->AddInt64 (message, F("repeated_sfixed64"), 310);
+  reflection->AddFloat (message, F("repeated_float"   ), 311);
+  reflection->AddDouble(message, F("repeated_double"  ), 312);
+  reflection->AddBool  (message, F("repeated_bool"    ), false);
+  reflection->AddString(message, F("repeated_string"  ), "315");
+  reflection->AddString(message, F("repeated_bytes"   ), "316");
+
+  sub_message = reflection->AddMessage(message, F("repeatedgroup"));
+  sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 317);
+  sub_message = reflection->AddMessage(message, F("repeated_nested_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 318);
+  sub_message = reflection->AddMessage(message, F("repeated_foreign_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 319);
+  sub_message = reflection->AddMessage(message, F("repeated_import_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, import_d_, 320);
+  sub_message = reflection->AddMessage(message, F("repeated_lazy_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 327);
+
+  reflection->AddEnum(message, F("repeated_nested_enum" ),  nested_baz_);
+  reflection->AddEnum(message, F("repeated_foreign_enum"), foreign_baz_);
+  reflection->AddEnum(message, F("repeated_import_enum" ),  import_baz_);
+
+  reflection->AddString(message, F("repeated_string_piece"), "324");
+  reflection->AddString(message, F("repeated_cord"), "325");
+
+  // -----------------------------------------------------------------
+
+  reflection->SetInt32 (message, F("default_int32"   ), 401);
+  reflection->SetInt64 (message, F("default_int64"   ), 402);
+  reflection->SetUInt32(message, F("default_uint32"  ), 403);
+  reflection->SetUInt64(message, F("default_uint64"  ), 404);
+  reflection->SetInt32 (message, F("default_sint32"  ), 405);
+  reflection->SetInt64 (message, F("default_sint64"  ), 406);
+  reflection->SetUInt32(message, F("default_fixed32" ), 407);
+  reflection->SetUInt64(message, F("default_fixed64" ), 408);
+  reflection->SetInt32 (message, F("default_sfixed32"), 409);
+  reflection->SetInt64 (message, F("default_sfixed64"), 410);
+  reflection->SetFloat (message, F("default_float"   ), 411);
+  reflection->SetDouble(message, F("default_double"  ), 412);
+  reflection->SetBool  (message, F("default_bool"    ), false);
+  reflection->SetString(message, F("default_string"  ), "415");
+  reflection->SetString(message, F("default_bytes"   ), "416");
+
+  reflection->SetEnum(message, F("default_nested_enum" ),  nested_foo_);
+  reflection->SetEnum(message, F("default_foreign_enum"), foreign_foo_);
+  reflection->SetEnum(message, F("default_import_enum" ),  import_foo_);
+
+  reflection->SetString(message, F("default_string_piece"), "424");
+  reflection->SetString(message, F("default_cord"), "425");
+
+  reflection->SetUInt32(message, F("oneof_uint32"   ), 601);
+  sub_message = reflection->MutableMessage(message, F("oneof_nested_message"));
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 602);
+  reflection->SetString(message, F("oneof_string"), "603");
+  reflection->SetString(message, F("oneof_bytes" ), "604");
+}
+
+void TestUtil::ReflectionTester::SetOneofViaReflection(Message* message) {
+  const Descriptor* descriptor = message->GetDescriptor();
+  const Reflection* reflection = message->GetReflection();
+  Message* sub_message = reflection->MutableMessage(
+      message, descriptor->FindFieldByName("foo_lazy_message"));
+  sub_message->GetReflection()->SetInt64(
+      sub_message,
+      descriptor->file()->pool()->FindFieldByName(
+          "protobuf_unittest.TestOneof2.NestedMessage.qux_int"),
+      100);
+
+  reflection->SetString(message,
+                        descriptor->FindFieldByName("bar_cord"),
+                        "101");
+  reflection->SetInt32(message,
+                        descriptor->FindFieldByName("baz_int"),
+                       102);
+  reflection->SetString(message,
+                        descriptor->FindFieldByName("baz_string"),
+                        "103");
+}
+
+void TestUtil::ReflectionTester::ExpectOneofSetViaReflection(
+    const Message& message) {
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* reflection = message.GetReflection();
+  string scratch;
+  EXPECT_TRUE(reflection->HasField(
+      message, descriptor->FindFieldByName("foo_lazy_message")));
+  EXPECT_TRUE(reflection->HasField(
+      message, descriptor->FindFieldByName("bar_cord")));
+  EXPECT_TRUE(reflection->HasField(
+      message, descriptor->FindFieldByName("baz_int")));
+  EXPECT_TRUE(reflection->HasField(
+      message, descriptor->FindFieldByName("baz_string")));
+
+  const Message* sub_message = &reflection->GetMessage(
+      message, descriptor->FindFieldByName("foo_lazy_message"));
+  EXPECT_EQ(100, sub_message->GetReflection()->GetInt64(
+      *sub_message,
+      descriptor->file()->pool()->FindFieldByName(
+          "protobuf_unittest.TestOneof2.NestedMessage.qux_int")));
+
+  EXPECT_EQ("101", reflection->GetString(
+      message, descriptor->FindFieldByName("bar_cord")));
+  EXPECT_EQ("101", reflection->GetStringReference(
+      message, descriptor->FindFieldByName("bar_cord"), &scratch));
+
+  EXPECT_EQ(102, reflection->GetInt32(
+      message, descriptor->FindFieldByName("baz_int")));
+
+  EXPECT_EQ("103", reflection->GetString(
+      message, descriptor->FindFieldByName("baz_string")));
+  EXPECT_EQ("103", reflection->GetStringReference(
+      message, descriptor->FindFieldByName("baz_string"), &scratch));
+}
+
+void TestUtil::ReflectionTester::SetPackedFieldsViaReflection(
+    Message* message) {
+  const Reflection* reflection = message->GetReflection();
+  reflection->AddInt32 (message, F("packed_int32"   ), 601);
+  reflection->AddInt64 (message, F("packed_int64"   ), 602);
+  reflection->AddUInt32(message, F("packed_uint32"  ), 603);
+  reflection->AddUInt64(message, F("packed_uint64"  ), 604);
+  reflection->AddInt32 (message, F("packed_sint32"  ), 605);
+  reflection->AddInt64 (message, F("packed_sint64"  ), 606);
+  reflection->AddUInt32(message, F("packed_fixed32" ), 607);
+  reflection->AddUInt64(message, F("packed_fixed64" ), 608);
+  reflection->AddInt32 (message, F("packed_sfixed32"), 609);
+  reflection->AddInt64 (message, F("packed_sfixed64"), 610);
+  reflection->AddFloat (message, F("packed_float"   ), 611);
+  reflection->AddDouble(message, F("packed_double"  ), 612);
+  reflection->AddBool  (message, F("packed_bool"    ), true);
+  reflection->AddEnum  (message, F("packed_enum"    ), foreign_bar_);
+
+  reflection->AddInt32 (message, F("packed_int32"   ), 701);
+  reflection->AddInt64 (message, F("packed_int64"   ), 702);
+  reflection->AddUInt32(message, F("packed_uint32"  ), 703);
+  reflection->AddUInt64(message, F("packed_uint64"  ), 704);
+  reflection->AddInt32 (message, F("packed_sint32"  ), 705);
+  reflection->AddInt64 (message, F("packed_sint64"  ), 706);
+  reflection->AddUInt32(message, F("packed_fixed32" ), 707);
+  reflection->AddUInt64(message, F("packed_fixed64" ), 708);
+  reflection->AddInt32 (message, F("packed_sfixed32"), 709);
+  reflection->AddInt64 (message, F("packed_sfixed64"), 710);
+  reflection->AddFloat (message, F("packed_float"   ), 711);
+  reflection->AddDouble(message, F("packed_double"  ), 712);
+  reflection->AddBool  (message, F("packed_bool"    ), false);
+  reflection->AddEnum  (message, F("packed_enum"    ), foreign_baz_);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection(
+    const Message& message) {
+  // We have to split this into three function otherwise it creates a stack
+  // frame so large that it triggers a warning.
+  ExpectAllFieldsSetViaReflection1(message);
+  ExpectAllFieldsSetViaReflection2(message);
+  ExpectAllFieldsSetViaReflection3(message);
+}
+
+void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection1(
+    const Message& message) {
+  const Reflection* reflection = message.GetReflection();
+  string scratch;
+  const Message* sub_message;
+
+  EXPECT_TRUE(reflection->HasField(message, F("optional_int32"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_int64"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_uint32"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_uint64"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_sint32"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_sint64"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_fixed32" )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_fixed64" )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed32")));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_sfixed64")));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_float"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_double"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_bool"    )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_string"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_bytes"   )));
+
+  EXPECT_TRUE(reflection->HasField(message, F("optionalgroup"                 )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_nested_message"       )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_message"      )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_import_message"       )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_public_import_message")));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_lazy_message"         )));
+
+  sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+  EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, group_a_));
+  sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+  EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+  sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+  EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_));
+  sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+  EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_d_));
+  sub_message = &reflection->GetMessage(message, F("optional_public_import_message"));
+  EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, import_e_));
+  sub_message = &reflection->GetMessage(message, F("optional_lazy_message"));
+  EXPECT_TRUE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+
+  EXPECT_TRUE(reflection->HasField(message, F("optional_nested_enum" )));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_foreign_enum")));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_import_enum" )));
+
+  EXPECT_TRUE(reflection->HasField(message, F("optional_string_piece")));
+  EXPECT_TRUE(reflection->HasField(message, F("optional_cord")));
+
+  EXPECT_EQ(101  , reflection->GetInt32 (message, F("optional_int32"   )));
+  EXPECT_EQ(102  , reflection->GetInt64 (message, F("optional_int64"   )));
+  EXPECT_EQ(103  , reflection->GetUInt32(message, F("optional_uint32"  )));
+  EXPECT_EQ(104  , reflection->GetUInt64(message, F("optional_uint64"  )));
+  EXPECT_EQ(105  , reflection->GetInt32 (message, F("optional_sint32"  )));
+  EXPECT_EQ(106  , reflection->GetInt64 (message, F("optional_sint64"  )));
+  EXPECT_EQ(107  , reflection->GetUInt32(message, F("optional_fixed32" )));
+  EXPECT_EQ(108  , reflection->GetUInt64(message, F("optional_fixed64" )));
+  EXPECT_EQ(109  , reflection->GetInt32 (message, F("optional_sfixed32")));
+  EXPECT_EQ(110  , reflection->GetInt64 (message, F("optional_sfixed64")));
+  EXPECT_EQ(111  , reflection->GetFloat (message, F("optional_float"   )));
+  EXPECT_EQ(112  , reflection->GetDouble(message, F("optional_double"  )));
+  EXPECT_TRUE(     reflection->GetBool  (message, F("optional_bool"    )));
+  EXPECT_EQ("115", reflection->GetString(message, F("optional_string"  )));
+  EXPECT_EQ("116", reflection->GetString(message, F("optional_bytes"   )));
+
+  EXPECT_EQ("115", reflection->GetStringReference(message, F("optional_string"), &scratch));
+  EXPECT_EQ("116", reflection->GetStringReference(message, F("optional_bytes" ), &scratch));
+
+  sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+  EXPECT_EQ(117, sub_message->GetReflection()->GetInt32(*sub_message, group_a_));
+  sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+  EXPECT_EQ(118, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+  sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+  EXPECT_EQ(119, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+  sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+  EXPECT_EQ(120, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+  sub_message = &reflection->GetMessage(message, F("optional_public_import_message"));
+  EXPECT_EQ(126, sub_message->GetReflection()->GetInt32(*sub_message, import_e_));
+  sub_message = &reflection->GetMessage(message, F("optional_lazy_message"));
+  EXPECT_EQ(127, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+
+  EXPECT_EQ( nested_baz_, reflection->GetEnum(message, F("optional_nested_enum" )));
+  EXPECT_EQ(foreign_baz_, reflection->GetEnum(message, F("optional_foreign_enum")));
+  EXPECT_EQ( import_baz_, reflection->GetEnum(message, F("optional_import_enum" )));
+
+  EXPECT_EQ("124", reflection->GetString(message, F("optional_string_piece")));
+  EXPECT_EQ("124", reflection->GetStringReference(message, F("optional_string_piece"), &scratch));
+
+  EXPECT_EQ("125", reflection->GetString(message, F("optional_cord")));
+  EXPECT_EQ("125", reflection->GetStringReference(message, F("optional_cord"), &scratch));
+
+  EXPECT_TRUE(reflection->HasField(message, F("oneof_bytes" )));
+  EXPECT_EQ("604", reflection->GetString(message, F("oneof_bytes"   )));
+
+  if (base_descriptor_->name() == "TestAllTypes") {
+    EXPECT_FALSE(reflection->HasField(message, F("oneof_uint32")));
+    EXPECT_FALSE(reflection->HasField(message, F("oneof_string")));
+  } else {
+    EXPECT_TRUE(reflection->HasField(message, F("oneof_uint32")));
+    EXPECT_TRUE(reflection->HasField(message, F("oneof_string")));
+    EXPECT_EQ(601  , reflection->GetUInt32(message, F("oneof_uint32")));
+    EXPECT_EQ("603", reflection->GetString(message, F("oneof_string")));
+    sub_message = &reflection->GetMessage(message, F("oneof_nested_message"));
+    EXPECT_EQ(602, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+  }
+}
+
+void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection2(
+    const Message& message) {
+  const Reflection* reflection = message.GetReflection();
+  string scratch;
+  const Message* sub_message;
+
+  // -----------------------------------------------------------------
+
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int32"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_int64"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint32"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_uint64"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint32"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sint64"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed32" )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_fixed64" )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed32")));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_sfixed64")));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_float"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_double"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bool"    )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_bytes"   )));
+
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeatedgroup"           )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_message" )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_message")));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_message" )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_lazy_message"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_nested_enum"    )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_foreign_enum"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_import_enum"    )));
+
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_string_piece")));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("repeated_cord")));
+
+  EXPECT_EQ(201  , reflection->GetRepeatedInt32 (message, F("repeated_int32"   ), 0));
+  EXPECT_EQ(202  , reflection->GetRepeatedInt64 (message, F("repeated_int64"   ), 0));
+  EXPECT_EQ(203  , reflection->GetRepeatedUInt32(message, F("repeated_uint32"  ), 0));
+  EXPECT_EQ(204  , reflection->GetRepeatedUInt64(message, F("repeated_uint64"  ), 0));
+  EXPECT_EQ(205  , reflection->GetRepeatedInt32 (message, F("repeated_sint32"  ), 0));
+  EXPECT_EQ(206  , reflection->GetRepeatedInt64 (message, F("repeated_sint64"  ), 0));
+  EXPECT_EQ(207  , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 0));
+  EXPECT_EQ(208  , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 0));
+  EXPECT_EQ(209  , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 0));
+  EXPECT_EQ(210  , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 0));
+  EXPECT_EQ(211  , reflection->GetRepeatedFloat (message, F("repeated_float"   ), 0));
+  EXPECT_EQ(212  , reflection->GetRepeatedDouble(message, F("repeated_double"  ), 0));
+  EXPECT_TRUE(     reflection->GetRepeatedBool  (message, F("repeated_bool"    ), 0));
+  EXPECT_EQ("215", reflection->GetRepeatedString(message, F("repeated_string"  ), 0));
+  EXPECT_EQ("216", reflection->GetRepeatedString(message, F("repeated_bytes"   ), 0));
+
+  EXPECT_EQ("215", reflection->GetRepeatedStringReference(message, F("repeated_string"), 0, &scratch));
+  EXPECT_EQ("216", reflection->GetRepeatedStringReference(message, F("repeated_bytes"), 0, &scratch));
+
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 0);
+  EXPECT_EQ(217, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 0);
+  EXPECT_EQ(218, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 0);
+  EXPECT_EQ(219, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 0);
+  EXPECT_EQ(220, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_lazy_message"), 0);
+  EXPECT_EQ(227, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+
+  EXPECT_EQ( nested_bar_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),0));
+  EXPECT_EQ(foreign_bar_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),0));
+  EXPECT_EQ( import_bar_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),0));
+
+  EXPECT_EQ("224", reflection->GetRepeatedString(message, F("repeated_string_piece"), 0));
+  EXPECT_EQ("224", reflection->GetRepeatedStringReference(
+                        message, F("repeated_string_piece"), 0, &scratch));
+
+  EXPECT_EQ("225", reflection->GetRepeatedString(message, F("repeated_cord"), 0));
+  EXPECT_EQ("225", reflection->GetRepeatedStringReference(
+                        message, F("repeated_cord"), 0, &scratch));
+
+  EXPECT_EQ(301  , reflection->GetRepeatedInt32 (message, F("repeated_int32"   ), 1));
+  EXPECT_EQ(302  , reflection->GetRepeatedInt64 (message, F("repeated_int64"   ), 1));
+  EXPECT_EQ(303  , reflection->GetRepeatedUInt32(message, F("repeated_uint32"  ), 1));
+  EXPECT_EQ(304  , reflection->GetRepeatedUInt64(message, F("repeated_uint64"  ), 1));
+  EXPECT_EQ(305  , reflection->GetRepeatedInt32 (message, F("repeated_sint32"  ), 1));
+  EXPECT_EQ(306  , reflection->GetRepeatedInt64 (message, F("repeated_sint64"  ), 1));
+  EXPECT_EQ(307  , reflection->GetRepeatedUInt32(message, F("repeated_fixed32" ), 1));
+  EXPECT_EQ(308  , reflection->GetRepeatedUInt64(message, F("repeated_fixed64" ), 1));
+  EXPECT_EQ(309  , reflection->GetRepeatedInt32 (message, F("repeated_sfixed32"), 1));
+  EXPECT_EQ(310  , reflection->GetRepeatedInt64 (message, F("repeated_sfixed64"), 1));
+  EXPECT_EQ(311  , reflection->GetRepeatedFloat (message, F("repeated_float"   ), 1));
+  EXPECT_EQ(312  , reflection->GetRepeatedDouble(message, F("repeated_double"  ), 1));
+  EXPECT_FALSE(    reflection->GetRepeatedBool  (message, F("repeated_bool"    ), 1));
+  EXPECT_EQ("315", reflection->GetRepeatedString(message, F("repeated_string"  ), 1));
+  EXPECT_EQ("316", reflection->GetRepeatedString(message, F("repeated_bytes"   ), 1));
+
+  EXPECT_EQ("315", reflection->GetRepeatedStringReference(message, F("repeated_string"),
+                                                          1, &scratch));
+  EXPECT_EQ("316", reflection->GetRepeatedStringReference(message, F("repeated_bytes"),
+                                                          1, &scratch));
+
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeatedgroup"), 1);
+  EXPECT_EQ(317, sub_message->GetReflection()->GetInt32(*sub_message, repeated_group_a_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_nested_message"), 1);
+  EXPECT_EQ(318, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_foreign_message"), 1);
+  EXPECT_EQ(319, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_import_message"), 1);
+  EXPECT_EQ(320, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+  sub_message = &reflection->GetRepeatedMessage(message, F("repeated_lazy_message"), 1);
+  EXPECT_EQ(327, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+
+  EXPECT_EQ( nested_baz_, reflection->GetRepeatedEnum(message, F("repeated_nested_enum" ),1));
+  EXPECT_EQ(foreign_baz_, reflection->GetRepeatedEnum(message, F("repeated_foreign_enum"),1));
+  EXPECT_EQ( import_baz_, reflection->GetRepeatedEnum(message, F("repeated_import_enum" ),1));
+
+  EXPECT_EQ("324", reflection->GetRepeatedString(message, F("repeated_string_piece"), 1));
+  EXPECT_EQ("324", reflection->GetRepeatedStringReference(
+                        message, F("repeated_string_piece"), 1, &scratch));
+
+  EXPECT_EQ("325", reflection->GetRepeatedString(message, F("repeated_cord"), 1));
+  EXPECT_EQ("325", reflection->GetRepeatedStringReference(
+                        message, F("repeated_cord"), 1, &scratch));
+}
+
+void TestUtil::ReflectionTester::ExpectAllFieldsSetViaReflection3(
+    const Message& message) {
+  const Reflection* reflection = message.GetReflection();
+  string scratch;
+
+  // -----------------------------------------------------------------
+
+  EXPECT_TRUE(reflection->HasField(message, F("default_int32"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_int64"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_uint32"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_uint64"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_sint32"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_sint64"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_fixed32" )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_fixed64" )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_sfixed32")));
+  EXPECT_TRUE(reflection->HasField(message, F("default_sfixed64")));
+  EXPECT_TRUE(reflection->HasField(message, F("default_float"   )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_double"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_bool"    )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_string"  )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_bytes"   )));
+
+  EXPECT_TRUE(reflection->HasField(message, F("default_nested_enum" )));
+  EXPECT_TRUE(reflection->HasField(message, F("default_foreign_enum")));
+  EXPECT_TRUE(reflection->HasField(message, F("default_import_enum" )));
+
+  EXPECT_TRUE(reflection->HasField(message, F("default_string_piece")));
+  EXPECT_TRUE(reflection->HasField(message, F("default_cord")));
+
+  EXPECT_EQ(401  , reflection->GetInt32 (message, F("default_int32"   )));
+  EXPECT_EQ(402  , reflection->GetInt64 (message, F("default_int64"   )));
+  EXPECT_EQ(403  , reflection->GetUInt32(message, F("default_uint32"  )));
+  EXPECT_EQ(404  , reflection->GetUInt64(message, F("default_uint64"  )));
+  EXPECT_EQ(405  , reflection->GetInt32 (message, F("default_sint32"  )));
+  EXPECT_EQ(406  , reflection->GetInt64 (message, F("default_sint64"  )));
+  EXPECT_EQ(407  , reflection->GetUInt32(message, F("default_fixed32" )));
+  EXPECT_EQ(408  , reflection->GetUInt64(message, F("default_fixed64" )));
+  EXPECT_EQ(409  , reflection->GetInt32 (message, F("default_sfixed32")));
+  EXPECT_EQ(410  , reflection->GetInt64 (message, F("default_sfixed64")));
+  EXPECT_EQ(411  , reflection->GetFloat (message, F("default_float"   )));
+  EXPECT_EQ(412  , reflection->GetDouble(message, F("default_double"  )));
+  EXPECT_FALSE(    reflection->GetBool  (message, F("default_bool"    )));
+  EXPECT_EQ("415", reflection->GetString(message, F("default_string"  )));
+  EXPECT_EQ("416", reflection->GetString(message, F("default_bytes"   )));
+
+  EXPECT_EQ("415", reflection->GetStringReference(message, F("default_string"), &scratch));
+  EXPECT_EQ("416", reflection->GetStringReference(message, F("default_bytes" ), &scratch));
+
+  EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("default_nested_enum" )));
+  EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("default_foreign_enum")));
+  EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("default_import_enum" )));
+
+  EXPECT_EQ("424", reflection->GetString(message, F("default_string_piece")));
+  EXPECT_EQ("424", reflection->GetStringReference(message, F("default_string_piece"),
+                                                  &scratch));
+
+  EXPECT_EQ("425", reflection->GetString(message, F("default_cord")));
+  EXPECT_EQ("425", reflection->GetStringReference(message, F("default_cord"), &scratch));
+}
+
+void TestUtil::ReflectionTester::ExpectPackedFieldsSetViaReflection(
+    const Message& message) {
+  const Reflection* reflection = message.GetReflection();
+
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int32"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_int64"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint32"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_uint64"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint32"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sint64"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed32" )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_fixed64" )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed32")));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_sfixed64")));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_float"   )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_double"  )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_bool"    )));
+  ASSERT_EQ(2, reflection->FieldSize(message, F("packed_enum"    )));
+
+  EXPECT_EQ(601  , reflection->GetRepeatedInt32 (message, F("packed_int32"   ), 0));
+  EXPECT_EQ(602  , reflection->GetRepeatedInt64 (message, F("packed_int64"   ), 0));
+  EXPECT_EQ(603  , reflection->GetRepeatedUInt32(message, F("packed_uint32"  ), 0));
+  EXPECT_EQ(604  , reflection->GetRepeatedUInt64(message, F("packed_uint64"  ), 0));
+  EXPECT_EQ(605  , reflection->GetRepeatedInt32 (message, F("packed_sint32"  ), 0));
+  EXPECT_EQ(606  , reflection->GetRepeatedInt64 (message, F("packed_sint64"  ), 0));
+  EXPECT_EQ(607  , reflection->GetRepeatedUInt32(message, F("packed_fixed32" ), 0));
+  EXPECT_EQ(608  , reflection->GetRepeatedUInt64(message, F("packed_fixed64" ), 0));
+  EXPECT_EQ(609  , reflection->GetRepeatedInt32 (message, F("packed_sfixed32"), 0));
+  EXPECT_EQ(610  , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 0));
+  EXPECT_EQ(611  , reflection->GetRepeatedFloat (message, F("packed_float"   ), 0));
+  EXPECT_EQ(612  , reflection->GetRepeatedDouble(message, F("packed_double"  ), 0));
+  EXPECT_TRUE(     reflection->GetRepeatedBool  (message, F("packed_bool"    ), 0));
+  EXPECT_EQ(foreign_bar_,
+            reflection->GetRepeatedEnum(message, F("packed_enum"), 0));
+
+  EXPECT_EQ(701  , reflection->GetRepeatedInt32 (message, F("packed_int32"   ), 1));
+  EXPECT_EQ(702  , reflection->GetRepeatedInt64 (message, F("packed_int64"   ), 1));
+  EXPECT_EQ(703  , reflection->GetRepeatedUInt32(message, F("packed_uint32"  ), 1));
+  EXPECT_EQ(704  , reflection->GetRepeatedUInt64(message, F("packed_uint64"  ), 1));
+  EXPECT_EQ(705  , reflection->GetRepeatedInt32 (message, F("packed_sint32"  ), 1));
+  EXPECT_EQ(706  , reflection->GetRepeatedInt64 (message, F("packed_sint64"  ), 1));
+  EXPECT_EQ(707  , reflection->GetRepeatedUInt32(message, F("packed_fixed32" ), 1));
+  EXPECT_EQ(708  , reflection->GetRepeatedUInt64(message, F("packed_fixed64" ), 1));
+  EXPECT_EQ(709  , reflection->GetRepeatedInt32 (message, F("packed_sfixed32"), 1));
+  EXPECT_EQ(710  , reflection->GetRepeatedInt64 (message, F("packed_sfixed64"), 1));
+  EXPECT_EQ(711  , reflection->GetRepeatedFloat (message, F("packed_float"   ), 1));
+  EXPECT_EQ(712  , reflection->GetRepeatedDouble(message, F("packed_double"  ), 1));
+  EXPECT_FALSE(    reflection->GetRepeatedBool  (message, F("packed_bool"    ), 1));
+  EXPECT_EQ(foreign_baz_,
+            reflection->GetRepeatedEnum(message, F("packed_enum"), 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ReflectionTester::ExpectClearViaReflection(
+    const Message& message) {
+  const Reflection* reflection = message.GetReflection();
+  string scratch;
+  const Message* sub_message;
+
+  // has_blah() should initially be false for all optional fields.
+  EXPECT_FALSE(reflection->HasField(message, F("optional_int32"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_int64"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_uint32"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_uint64"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_sint32"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_sint64"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_fixed32" )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_fixed64" )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed32")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_sfixed64")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_float"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_double"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_bool"    )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_string"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_bytes"   )));
+
+  EXPECT_FALSE(reflection->HasField(message, F("optionalgroup"           )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_nested_message" )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_message")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_import_message" )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_public_import_message")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_lazy_message")));
+
+  EXPECT_FALSE(reflection->HasField(message, F("optional_nested_enum" )));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_foreign_enum")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_import_enum" )));
+
+  EXPECT_FALSE(reflection->HasField(message, F("optional_string_piece")));
+  EXPECT_FALSE(reflection->HasField(message, F("optional_cord")));
+
+  // Optional fields without defaults are set to zero or something like it.
+  EXPECT_EQ(0    , reflection->GetInt32 (message, F("optional_int32"   )));
+  EXPECT_EQ(0    , reflection->GetInt64 (message, F("optional_int64"   )));
+  EXPECT_EQ(0    , reflection->GetUInt32(message, F("optional_uint32"  )));
+  EXPECT_EQ(0    , reflection->GetUInt64(message, F("optional_uint64"  )));
+  EXPECT_EQ(0    , reflection->GetInt32 (message, F("optional_sint32"  )));
+  EXPECT_EQ(0    , reflection->GetInt64 (message, F("optional_sint64"  )));
+  EXPECT_EQ(0    , reflection->GetUInt32(message, F("optional_fixed32" )));
+  EXPECT_EQ(0    , reflection->GetUInt64(message, F("optional_fixed64" )));
+  EXPECT_EQ(0    , reflection->GetInt32 (message, F("optional_sfixed32")));
+  EXPECT_EQ(0    , reflection->GetInt64 (message, F("optional_sfixed64")));
+  EXPECT_EQ(0    , reflection->GetFloat (message, F("optional_float"   )));
+  EXPECT_EQ(0    , reflection->GetDouble(message, F("optional_double"  )));
+  EXPECT_FALSE(    reflection->GetBool  (message, F("optional_bool"    )));
+  EXPECT_EQ(""   , reflection->GetString(message, F("optional_string"  )));
+  EXPECT_EQ(""   , reflection->GetString(message, F("optional_bytes"   )));
+
+  EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string"), &scratch));
+  EXPECT_EQ("", reflection->GetStringReference(message, F("optional_bytes" ), &scratch));
+
+  // Embedded messages should also be clear.
+  sub_message = &reflection->GetMessage(message, F("optionalgroup"));
+  EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, group_a_));
+  EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, group_a_));
+  sub_message = &reflection->GetMessage(message, F("optional_nested_message"));
+  EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+  EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+  sub_message = &reflection->GetMessage(message, F("optional_foreign_message"));
+  EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, foreign_c_));
+  EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, foreign_c_));
+  sub_message = &reflection->GetMessage(message, F("optional_import_message"));
+  EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_d_));
+  EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_d_));
+  sub_message = &reflection->GetMessage(message, F("optional_public_import_message"));
+  EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, import_e_));
+  EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, import_e_));
+  sub_message = &reflection->GetMessage(message, F("optional_lazy_message"));
+  EXPECT_FALSE(sub_message->GetReflection()->HasField(*sub_message, nested_b_));
+  EXPECT_EQ(0, sub_message->GetReflection()->GetInt32(*sub_message, nested_b_));
+
+  // Enums without defaults are set to the first value in the enum.
+  EXPECT_EQ( nested_foo_, reflection->GetEnum(message, F("optional_nested_enum" )));
+  EXPECT_EQ(foreign_foo_, reflection->GetEnum(message, F("optional_foreign_enum")));
+  EXPECT_EQ( import_foo_, reflection->GetEnum(message, F("optional_import_enum" )));
+
+  EXPECT_EQ("", reflection->GetString(message, F("optional_string_piece")));
+  EXPECT_EQ("", reflection->GetStringReference(message, F("optional_string_piece"), &scratch));
+
+  EXPECT_EQ("", reflection->GetString(message, F("optional_cord")));
+  EXPECT_EQ("", reflection->GetStringReference(message, F("optional_cord"), &scratch));
+
+  // Repeated fields are empty.
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int32"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_int64"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint32"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_uint64"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint32"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sint64"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed32" )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_fixed64" )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed32")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_sfixed64")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_float"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_double"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bool"    )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_bytes"   )));
+
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeatedgroup"           )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_message" )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_message")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_message" )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_lazy_message"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_nested_enum"    )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_foreign_enum"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_import_enum"    )));
+
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_string_piece")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("repeated_cord")));
+
+  // has_blah() should also be false for all default fields.
+  EXPECT_FALSE(reflection->HasField(message, F("default_int32"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_int64"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_uint32"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_uint64"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_sint32"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_sint64"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_fixed32" )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_fixed64" )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_sfixed32")));
+  EXPECT_FALSE(reflection->HasField(message, F("default_sfixed64")));
+  EXPECT_FALSE(reflection->HasField(message, F("default_float"   )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_double"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_bool"    )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_string"  )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_bytes"   )));
+
+  EXPECT_FALSE(reflection->HasField(message, F("default_nested_enum" )));
+  EXPECT_FALSE(reflection->HasField(message, F("default_foreign_enum")));
+  EXPECT_FALSE(reflection->HasField(message, F("default_import_enum" )));
+
+  EXPECT_FALSE(reflection->HasField(message, F("default_string_piece")));
+  EXPECT_FALSE(reflection->HasField(message, F("default_cord")));
+
+  // Fields with defaults have their default values (duh).
+  EXPECT_EQ( 41    , reflection->GetInt32 (message, F("default_int32"   )));
+  EXPECT_EQ( 42    , reflection->GetInt64 (message, F("default_int64"   )));
+  EXPECT_EQ( 43    , reflection->GetUInt32(message, F("default_uint32"  )));
+  EXPECT_EQ( 44    , reflection->GetUInt64(message, F("default_uint64"  )));
+  EXPECT_EQ(-45    , reflection->GetInt32 (message, F("default_sint32"  )));
+  EXPECT_EQ( 46    , reflection->GetInt64 (message, F("default_sint64"  )));
+  EXPECT_EQ( 47    , reflection->GetUInt32(message, F("default_fixed32" )));
+  EXPECT_EQ( 48    , reflection->GetUInt64(message, F("default_fixed64" )));
+  EXPECT_EQ( 49    , reflection->GetInt32 (message, F("default_sfixed32")));
+  EXPECT_EQ(-50    , reflection->GetInt64 (message, F("default_sfixed64")));
+  EXPECT_EQ( 51.5  , reflection->GetFloat (message, F("default_float"   )));
+  EXPECT_EQ( 52e3  , reflection->GetDouble(message, F("default_double"  )));
+  EXPECT_TRUE(       reflection->GetBool  (message, F("default_bool"    )));
+  EXPECT_EQ("hello", reflection->GetString(message, F("default_string"  )));
+  EXPECT_EQ("world", reflection->GetString(message, F("default_bytes"   )));
+
+  EXPECT_EQ("hello", reflection->GetStringReference(message, F("default_string"), &scratch));
+  EXPECT_EQ("world", reflection->GetStringReference(message, F("default_bytes" ), &scratch));
+
+  EXPECT_EQ( nested_bar_, reflection->GetEnum(message, F("default_nested_enum" )));
+  EXPECT_EQ(foreign_bar_, reflection->GetEnum(message, F("default_foreign_enum")));
+  EXPECT_EQ( import_bar_, reflection->GetEnum(message, F("default_import_enum" )));
+
+  EXPECT_EQ("abc", reflection->GetString(message, F("default_string_piece")));
+  EXPECT_EQ("abc", reflection->GetStringReference(message, F("default_string_piece"), &scratch));
+
+  EXPECT_EQ("123", reflection->GetString(message, F("default_cord")));
+  EXPECT_EQ("123", reflection->GetStringReference(message, F("default_cord"), &scratch));
+}
+
+void TestUtil::ReflectionTester::ExpectPackedClearViaReflection(
+    const Message& message) {
+  const Reflection* reflection = message.GetReflection();
+
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int32"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_int64"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint32"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_uint64"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint32"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sint64"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed32" )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_fixed64" )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed32")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_sfixed64")));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_float"   )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_double"  )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_bool"    )));
+  EXPECT_EQ(0, reflection->FieldSize(message, F("packed_enum"    )));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtil::ReflectionTester::ModifyRepeatedFieldsViaReflection(
+    Message* message) {
+  const Reflection* reflection = message->GetReflection();
+  Message* sub_message;
+
+  reflection->SetRepeatedInt32 (message, F("repeated_int32"   ), 1, 501);
+  reflection->SetRepeatedInt64 (message, F("repeated_int64"   ), 1, 502);
+  reflection->SetRepeatedUInt32(message, F("repeated_uint32"  ), 1, 503);
+  reflection->SetRepeatedUInt64(message, F("repeated_uint64"  ), 1, 504);
+  reflection->SetRepeatedInt32 (message, F("repeated_sint32"  ), 1, 505);
+  reflection->SetRepeatedInt64 (message, F("repeated_sint64"  ), 1, 506);
+  reflection->SetRepeatedUInt32(message, F("repeated_fixed32" ), 1, 507);
+  reflection->SetRepeatedUInt64(message, F("repeated_fixed64" ), 1, 508);
+  reflection->SetRepeatedInt32 (message, F("repeated_sfixed32"), 1, 509);
+  reflection->SetRepeatedInt64 (message, F("repeated_sfixed64"), 1, 510);
+  reflection->SetRepeatedFloat (message, F("repeated_float"   ), 1, 511);
+  reflection->SetRepeatedDouble(message, F("repeated_double"  ), 1, 512);
+  reflection->SetRepeatedBool  (message, F("repeated_bool"    ), 1, true);
+  reflection->SetRepeatedString(message, F("repeated_string"  ), 1, "515");
+  reflection->SetRepeatedString(message, F("repeated_bytes"   ), 1, "516");
+
+  sub_message = reflection->MutableRepeatedMessage(message, F("repeatedgroup"), 1);
+  sub_message->GetReflection()->SetInt32(sub_message, repeated_group_a_, 517);
+  sub_message = reflection->MutableRepeatedMessage(message, F("repeated_nested_message"), 1);
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 518);
+  sub_message = reflection->MutableRepeatedMessage(message, F("repeated_foreign_message"), 1);
+  sub_message->GetReflection()->SetInt32(sub_message, foreign_c_, 519);
+  sub_message = reflection->MutableRepeatedMessage(message, F("repeated_import_message"), 1);
+  sub_message->GetReflection()->SetInt32(sub_message, import_d_, 520);
+  sub_message = reflection->MutableRepeatedMessage(message, F("repeated_lazy_message"), 1);
+  sub_message->GetReflection()->SetInt32(sub_message, nested_b_, 527);
+
+  reflection->SetRepeatedEnum(message, F("repeated_nested_enum" ), 1,  nested_foo_);
+  reflection->SetRepeatedEnum(message, F("repeated_foreign_enum"), 1, foreign_foo_);
+  reflection->SetRepeatedEnum(message, F("repeated_import_enum" ), 1,  import_foo_);
+
+  reflection->SetRepeatedString(message, F("repeated_string_piece"), 1, "524");
+  reflection->SetRepeatedString(message, F("repeated_cord"), 1, "525");
+}
+
+void TestUtil::ReflectionTester::ModifyPackedFieldsViaReflection(
+    Message* message) {
+  const Reflection* reflection = message->GetReflection();
+  reflection->SetRepeatedInt32 (message, F("packed_int32"   ), 1, 801);
+  reflection->SetRepeatedInt64 (message, F("packed_int64"   ), 1, 802);
+  reflection->SetRepeatedUInt32(message, F("packed_uint32"  ), 1, 803);
+  reflection->SetRepeatedUInt64(message, F("packed_uint64"  ), 1, 804);
+  reflection->SetRepeatedInt32 (message, F("packed_sint32"  ), 1, 805);
+  reflection->SetRepeatedInt64 (message, F("packed_sint64"  ), 1, 806);
+  reflection->SetRepeatedUInt32(message, F("packed_fixed32" ), 1, 807);
+  reflection->SetRepeatedUInt64(message, F("packed_fixed64" ), 1, 808);
+  reflection->SetRepeatedInt32 (message, F("packed_sfixed32"), 1, 809);
+  reflection->SetRepeatedInt64 (message, F("packed_sfixed64"), 1, 810);
+  reflection->SetRepeatedFloat (message, F("packed_float"   ), 1, 811);
+  reflection->SetRepeatedDouble(message, F("packed_double"  ), 1, 812);
+  reflection->SetRepeatedBool  (message, F("packed_bool"    ), 1, true);
+  reflection->SetRepeatedEnum  (message, F("packed_enum"    ), 1, foreign_foo_);
+}
+
+void TestUtil::ReflectionTester::RemoveLastRepeatedsViaReflection(
+    Message* message) {
+  const Reflection* reflection = message->GetReflection();
+
+  vector<const FieldDescriptor*> output;
+  reflection->ListFields(*message, &output);
+  for (int i=0; i<output.size(); ++i) {
+    const FieldDescriptor* field = output[i];
+    if (!field->is_repeated()) continue;
+
+    reflection->RemoveLast(message, field);
+  }
+}
+
+void TestUtil::ReflectionTester::ReleaseLastRepeatedsViaReflection(
+    Message* message, bool expect_extensions_notnull) {
+  const Reflection* reflection = message->GetReflection();
+
+  vector<const FieldDescriptor*> output;
+  reflection->ListFields(*message, &output);
+  for (int i=0; i<output.size(); ++i) {
+    const FieldDescriptor* field = output[i];
+    if (!field->is_repeated()) continue;
+    if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+    Message* released = reflection->ReleaseLast(message, field);
+    if (!field->is_extension() || expect_extensions_notnull) {
+      ASSERT_TRUE(released != NULL) << "ReleaseLast returned NULL for: "
+                                    << field->name();
+    }
+    delete released;
+  }
+}
+
+void TestUtil::ReflectionTester::SwapRepeatedsViaReflection(Message* message) {
+  const Reflection* reflection = message->GetReflection();
+
+  vector<const FieldDescriptor*> output;
+  reflection->ListFields(*message, &output);
+  for (int i=0; i<output.size(); ++i) {
+    const FieldDescriptor* field = output[i];
+    if (!field->is_repeated()) continue;
+
+    reflection->SwapElements(message, field, 0, 1);
+  }
+}
+
+void TestUtil::ReflectionTester::
+SetAllocatedOptionalMessageFieldsToNullViaReflection(
+    Message* message) {
+  const Reflection* reflection = message->GetReflection();
+
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(*message, &fields);
+
+  for (int i = 0; i < fields.size(); ++i) {
+    const FieldDescriptor* field = fields[i];
+    if (!field->is_optional() ||
+        field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+    reflection->SetAllocatedMessage(message, NULL, field);
+  }
+}
+
+void TestUtil::ReflectionTester::
+SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+    Message* from_message,
+    Message* to_message) {
+  EXPECT_EQ(from_message->GetDescriptor(), to_message->GetDescriptor());
+  const Reflection* from_reflection = from_message->GetReflection();
+  const Reflection* to_reflection = to_message->GetReflection();
+
+  vector<const FieldDescriptor*> fields;
+  from_reflection->ListFields(*from_message, &fields);
+
+  for (int i = 0; i < fields.size(); ++i) {
+    const FieldDescriptor* field = fields[i];
+    if (!field->is_optional() ||
+        field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+    Message* sub_message =
+        from_reflection->ReleaseMessage(from_message, field);
+    to_reflection->SetAllocatedMessage(to_message, sub_message, field);
+  }
+}
+
+void TestUtil::ReflectionTester::ExpectMessagesReleasedViaReflection(
+    Message* message,
+    TestUtil::ReflectionTester::MessageReleaseState expected_release_state) {
+  const Reflection* reflection = message->GetReflection();
+
+  static const char* fields[] = {
+    "optionalgroup",
+    "optional_nested_message",
+    "optional_foreign_message",
+    "optional_import_message",
+  };
+  for (int i = 0; i < GOOGLE_ARRAYSIZE(fields); i++) {
+    const Message& sub_message = reflection->GetMessage(*message, F(fields[i]));
+    Message* released = reflection->ReleaseMessage(message, F(fields[i]));
+    switch (expected_release_state) {
+      case IS_NULL:
+        EXPECT_TRUE(released == NULL);
+        break;
+      case NOT_NULL:
+        EXPECT_TRUE(released != NULL);
+        EXPECT_EQ(&sub_message, released);
+        break;
+      case CAN_BE_NULL:
+        break;
+    }
+    delete released;
+    EXPECT_FALSE(reflection->HasField(*message, F(fields[i])));
+  }
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/test_util.h b/protobuf/src/google/protobuf/test_util.h
new file mode 100644
index 0000000..d449c00
--- /dev/null
+++ b/protobuf/src/google/protobuf/test_util.h
@@ -0,0 +1,215 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 SetOptionalFields(unittest::TestAllTypes* message);
+  static void AddRepeatedFields1(unittest::TestAllTypes* message);
+  static void AddRepeatedFields2(unittest::TestAllTypes* message);
+  static void SetDefaultFields(unittest::TestAllTypes* message);
+  static void SetOneofFields(unittest::TestAllTypes* message);
+  static void SetAllExtensions(unittest::TestAllExtensions* message);
+  static void SetOneofFields(unittest::TestAllExtensions* message);
+  static void SetAllFieldsAndExtensions(unittest::TestFieldOrderings* message);
+  static void SetPackedFields(unittest::TestPackedTypes* message);
+  static void SetPackedExtensions(unittest::TestPackedExtensions* message);
+  static void SetUnpackedFields(unittest::TestUnpackedTypes* message);
+  static void SetOneof1(unittest::TestOneof2* message);
+  static void SetOneof2(unittest::TestOneof2* 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 Set*Fields()).  Set*Fields() itself only tests
+  // the add_*() accessors.
+  static void ModifyRepeatedFields(unittest::TestAllTypes* message);
+  static void ModifyRepeatedExtensions(unittest::TestAllExtensions* message);
+  static void ModifyPackedFields(unittest::TestPackedTypes* message);
+  static void ModifyPackedExtensions(unittest::TestPackedExtensions* message);
+
+  // Check that all fields have the values that they should have after
+  // Set*Fields() is called.
+  static void ExpectAllFieldsSet(const unittest::TestAllTypes& message);
+  static void ExpectAllExtensionsSet(
+      const unittest::TestAllExtensions& message);
+  static void ExpectPackedFieldsSet(const unittest::TestPackedTypes& message);
+  static void ExpectPackedExtensionsSet(
+      const unittest::TestPackedExtensions& message);
+  static void ExpectUnpackedFieldsSet(
+      const unittest::TestUnpackedTypes& message);
+  static void ExpectUnpackedExtensionsSet(
+      const unittest::TestUnpackedExtensions& message);
+  static void ExpectOneofSet1(const unittest::TestOneof2& message);
+  static void ExpectOneofSet2(const unittest::TestOneof2& message);
+
+  // Expect that the message is modified as would be expected from
+  // Modify*Fields().
+  static void ExpectRepeatedFieldsModified(
+      const unittest::TestAllTypes& message);
+  static void ExpectRepeatedExtensionsModified(
+      const unittest::TestAllExtensions& message);
+  static void ExpectPackedFieldsModified(
+      const unittest::TestPackedTypes& message);
+  static void ExpectPackedExtensionsModified(
+      const unittest::TestPackedExtensions& message);
+
+  // Check that all fields have their default values.
+  static void ExpectClear(const unittest::TestAllTypes& message);
+  static void ExpectExtensionsClear(const unittest::TestAllExtensions& message);
+  static void ExpectPackedClear(const unittest::TestPackedTypes& message);
+  static void ExpectPackedExtensionsClear(
+      const unittest::TestPackedExtensions& message);
+  static void ExpectOneofClear(const unittest::TestOneof2& 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);
+
+  // Check that all repeated fields have had their last elements removed.
+  static void ExpectLastRepeatedsRemoved(
+      const unittest::TestAllTypes& message);
+  static void ExpectLastRepeatedExtensionsRemoved(
+      const unittest::TestAllExtensions& message);
+  static void ExpectLastRepeatedsReleased(
+      const unittest::TestAllTypes& message);
+  static void ExpectLastRepeatedExtensionsReleased(
+      const unittest::TestAllExtensions& message);
+
+  // Check that all repeated fields have had their first and last elements
+  // swapped.
+  static void ExpectRepeatedsSwapped(const unittest::TestAllTypes& message);
+  static void ExpectRepeatedExtensionsSwapped(
+      const unittest::TestAllExtensions& message);
+
+  static void ExpectAtMostOneFieldSetInOneof(
+      const unittest::TestOneof2 &message);
+
+  // 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* message);
+    void ModifyRepeatedFieldsViaReflection(Message* message);
+    void ExpectAllFieldsSetViaReflection(const Message& message);
+    void ExpectClearViaReflection(const Message& message);
+
+    void SetPackedFieldsViaReflection(Message* message);
+    void ModifyPackedFieldsViaReflection(Message* message);
+    void ExpectPackedFieldsSetViaReflection(const Message& message);
+    void ExpectPackedClearViaReflection(const Message& message);
+
+    void RemoveLastRepeatedsViaReflection(Message* message);
+    void ReleaseLastRepeatedsViaReflection(
+        Message* message, bool expect_extensions_notnull);
+    void SwapRepeatedsViaReflection(Message* message);
+    void SetAllocatedOptionalMessageFieldsToNullViaReflection(
+        Message* message);
+    static void SetAllocatedOptionalMessageFieldsToMessageViaReflection(
+        Message* from_message,
+        Message* to_message);
+
+    enum MessageReleaseState {
+      IS_NULL,
+      CAN_BE_NULL,
+      NOT_NULL,
+    };
+    void ExpectMessagesReleasedViaReflection(
+        Message* message, MessageReleaseState expected_release_state);
+
+    // Set and check functions for TestOneof2 messages. No need to construct
+    // the ReflectionTester by TestAllTypes nor TestAllExtensions.
+    static void SetOneofViaReflection(Message* message);
+    static void ExpectOneofSetViaReflection(const Message& 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 FieldDescriptor* import_e_;
+
+    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_;
+
+    // We have to split this into three function otherwise it creates a stack
+    // frame so large that it triggers a warning.
+    void ExpectAllFieldsSetViaReflection1(const Message& message);
+    void ExpectAllFieldsSetViaReflection2(const Message& message);
+    void ExpectAllFieldsSetViaReflection3(const Message& message);
+
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ReflectionTester);
+  };
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtil);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_TEST_UTIL_H__
diff --git a/protobuf/src/google/protobuf/test_util_lite.cc b/protobuf/src/google/protobuf/test_util_lite.cc
new file mode 100644
index 0000000..88eca0a
--- /dev/null
+++ b/protobuf/src/google/protobuf/test_util_lite.cc
@@ -0,0 +1,1585 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/test_util_lite.h>
+#include <google/protobuf/stubs/common.h>
+
+
+#define EXPECT_TRUE GOOGLE_CHECK
+#define ASSERT_TRUE GOOGLE_CHECK
+#define EXPECT_FALSE(COND) GOOGLE_CHECK(!(COND))
+#define EXPECT_EQ GOOGLE_CHECK_EQ
+#define ASSERT_EQ GOOGLE_CHECK_EQ
+
+namespace google {
+namespace protobuf {
+
+void TestUtilLite::SetAllFields(unittest::TestAllTypesLite* 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->mutable_optional_public_import_message()->set_e(126);
+  message->mutable_optional_lazy_message         ()->set_bb(127);
+
+  message->set_optional_nested_enum (unittest::TestAllTypesLite::BAZ );
+  message->set_optional_foreign_enum(unittest::FOREIGN_LITE_BAZ      );
+  message->set_optional_import_enum (unittest_import::IMPORT_LITE_BAZ);
+
+
+  // -----------------------------------------------------------------
+
+  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_lazy_message   ()->set_bb(227);
+
+  message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAR );
+  message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAR      );
+  message->add_repeated_import_enum (unittest_import::IMPORT_LITE_BAR);
+
+
+  // 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_lazy_message   ()->set_bb(327);
+
+  message->add_repeated_nested_enum (unittest::TestAllTypesLite::BAZ );
+  message->add_repeated_foreign_enum(unittest::FOREIGN_LITE_BAZ      );
+  message->add_repeated_import_enum (unittest_import::IMPORT_LITE_BAZ);
+
+
+  // -----------------------------------------------------------------
+
+  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::TestAllTypesLite::FOO );
+  message->set_default_foreign_enum(unittest::FOREIGN_LITE_FOO      );
+  message->set_default_import_enum (unittest_import::IMPORT_LITE_FOO);
+
+
+  message->set_oneof_uint32(601);
+  message->mutable_oneof_nested_message()->set_bb(602);
+  message->set_oneof_string("603");
+  message->set_oneof_bytes("604");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyRepeatedFields(unittest::TestAllTypesLite* 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->mutable_repeated_lazy_message   (1)->set_bb(527);
+
+  message->set_repeated_nested_enum (1, unittest::TestAllTypesLite::FOO );
+  message->set_repeated_foreign_enum(1, unittest::FOREIGN_LITE_FOO      );
+  message->set_repeated_import_enum (1, unittest_import::IMPORT_LITE_FOO);
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectAllFieldsSet(
+    const unittest::TestAllTypesLite& 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.has_optional_public_import_message());
+  EXPECT_TRUE(message.has_optional_lazy_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.optional_public_import_message().has_e());
+  EXPECT_TRUE(message.optional_lazy_message         ().has_bb());
+
+  EXPECT_TRUE(message.has_optional_nested_enum ());
+  EXPECT_TRUE(message.has_optional_foreign_enum());
+  EXPECT_TRUE(message.has_optional_import_enum ());
+
+
+  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(126, message.optional_public_import_message().e());
+  EXPECT_EQ(127, message.optional_lazy_message         ().bb());
+
+  EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.optional_nested_enum ());
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAZ      , message.optional_foreign_enum());
+  EXPECT_EQ(unittest_import::IMPORT_LITE_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_lazy_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    ());
+
+
+  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(227, message.repeated_lazy_message   (0).bb());
+
+
+  EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAR      , message.repeated_foreign_enum(0));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_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(327, message.repeated_lazy_message   (1).bb());
+
+  EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.repeated_nested_enum (1));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAZ      , message.repeated_foreign_enum(1));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_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::TestAllTypesLite::FOO , message.default_nested_enum ());
+  EXPECT_EQ(unittest::FOREIGN_LITE_FOO      , message.default_foreign_enum());
+  EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.default_import_enum ());
+
+
+  EXPECT_FALSE(message.has_oneof_uint32        ());
+  EXPECT_FALSE(message.has_oneof_nested_message());
+  EXPECT_FALSE(message.has_oneof_string        ());
+  EXPECT_TRUE(message.has_oneof_bytes          ());
+
+  EXPECT_EQ("604", message.oneof_bytes());
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectClear(const unittest::TestAllTypesLite& 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_public_import_message());
+  EXPECT_FALSE(message.has_optional_lazy_message         ());
+
+  EXPECT_FALSE(message.has_optional_nested_enum ());
+  EXPECT_FALSE(message.has_optional_foreign_enum());
+  EXPECT_FALSE(message.has_optional_import_enum ());
+
+
+  // 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_FALSE(message.optional_public_import_message().has_e());
+  EXPECT_FALSE(message.optional_lazy_message         ().has_bb());
+
+  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::TestAllTypesLite::FOO , message.optional_nested_enum ());
+  EXPECT_EQ(unittest::FOREIGN_LITE_FOO      , message.optional_foreign_enum());
+  EXPECT_EQ(unittest_import::IMPORT_LITE_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_lazy_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    ());
+
+
+  // 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::TestAllTypesLite::BAR , message.default_nested_enum ());
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAR      , message.default_foreign_enum());
+  EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.default_import_enum ());
+
+
+  EXPECT_FALSE(message.has_oneof_uint32        ());
+  EXPECT_FALSE(message.has_oneof_nested_message());
+  EXPECT_FALSE(message.has_oneof_string        ());
+  EXPECT_FALSE(message.has_oneof_bytes         ());
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectRepeatedFieldsModified(
+    const unittest::TestAllTypesLite& 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_lazy_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    ());
+
+
+  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(227, message.repeated_lazy_message   (0).bb());
+
+  EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.repeated_nested_enum (0));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAR      , message.repeated_foreign_enum(0));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_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(527, message.repeated_lazy_message   (1).bb());
+
+  EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.repeated_nested_enum (1));
+  EXPECT_EQ(unittest::FOREIGN_LITE_FOO      , message.repeated_foreign_enum(1));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.repeated_import_enum (1));
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::SetPackedFields(unittest::TestPackedTypesLite* message) {
+  message->add_packed_int32   (601);
+  message->add_packed_int64   (602);
+  message->add_packed_uint32  (603);
+  message->add_packed_uint64  (604);
+  message->add_packed_sint32  (605);
+  message->add_packed_sint64  (606);
+  message->add_packed_fixed32 (607);
+  message->add_packed_fixed64 (608);
+  message->add_packed_sfixed32(609);
+  message->add_packed_sfixed64(610);
+  message->add_packed_float   (611);
+  message->add_packed_double  (612);
+  message->add_packed_bool    (true);
+  message->add_packed_enum    (unittest::FOREIGN_LITE_BAR);
+  // add a second one of each field
+  message->add_packed_int32   (701);
+  message->add_packed_int64   (702);
+  message->add_packed_uint32  (703);
+  message->add_packed_uint64  (704);
+  message->add_packed_sint32  (705);
+  message->add_packed_sint64  (706);
+  message->add_packed_fixed32 (707);
+  message->add_packed_fixed64 (708);
+  message->add_packed_sfixed32(709);
+  message->add_packed_sfixed64(710);
+  message->add_packed_float   (711);
+  message->add_packed_double  (712);
+  message->add_packed_bool    (false);
+  message->add_packed_enum    (unittest::FOREIGN_LITE_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyPackedFields(unittest::TestPackedTypesLite* message) {
+  message->set_packed_int32   (1, 801);
+  message->set_packed_int64   (1, 802);
+  message->set_packed_uint32  (1, 803);
+  message->set_packed_uint64  (1, 804);
+  message->set_packed_sint32  (1, 805);
+  message->set_packed_sint64  (1, 806);
+  message->set_packed_fixed32 (1, 807);
+  message->set_packed_fixed64 (1, 808);
+  message->set_packed_sfixed32(1, 809);
+  message->set_packed_sfixed64(1, 810);
+  message->set_packed_float   (1, 811);
+  message->set_packed_double  (1, 812);
+  message->set_packed_bool    (1, true);
+  message->set_packed_enum    (1, unittest::FOREIGN_LITE_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedFieldsSet(
+    const unittest::TestPackedTypesLite& message) {
+  ASSERT_EQ(2, message.packed_int32_size   ());
+  ASSERT_EQ(2, message.packed_int64_size   ());
+  ASSERT_EQ(2, message.packed_uint32_size  ());
+  ASSERT_EQ(2, message.packed_uint64_size  ());
+  ASSERT_EQ(2, message.packed_sint32_size  ());
+  ASSERT_EQ(2, message.packed_sint64_size  ());
+  ASSERT_EQ(2, message.packed_fixed32_size ());
+  ASSERT_EQ(2, message.packed_fixed64_size ());
+  ASSERT_EQ(2, message.packed_sfixed32_size());
+  ASSERT_EQ(2, message.packed_sfixed64_size());
+  ASSERT_EQ(2, message.packed_float_size   ());
+  ASSERT_EQ(2, message.packed_double_size  ());
+  ASSERT_EQ(2, message.packed_bool_size    ());
+  ASSERT_EQ(2, message.packed_enum_size    ());
+
+  EXPECT_EQ(601  , message.packed_int32   (0));
+  EXPECT_EQ(602  , message.packed_int64   (0));
+  EXPECT_EQ(603  , message.packed_uint32  (0));
+  EXPECT_EQ(604  , message.packed_uint64  (0));
+  EXPECT_EQ(605  , message.packed_sint32  (0));
+  EXPECT_EQ(606  , message.packed_sint64  (0));
+  EXPECT_EQ(607  , message.packed_fixed32 (0));
+  EXPECT_EQ(608  , message.packed_fixed64 (0));
+  EXPECT_EQ(609  , message.packed_sfixed32(0));
+  EXPECT_EQ(610  , message.packed_sfixed64(0));
+  EXPECT_EQ(611  , message.packed_float   (0));
+  EXPECT_EQ(612  , message.packed_double  (0));
+  EXPECT_EQ(true , message.packed_bool    (0));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0));
+
+  EXPECT_EQ(701  , message.packed_int32   (1));
+  EXPECT_EQ(702  , message.packed_int64   (1));
+  EXPECT_EQ(703  , message.packed_uint32  (1));
+  EXPECT_EQ(704  , message.packed_uint64  (1));
+  EXPECT_EQ(705  , message.packed_sint32  (1));
+  EXPECT_EQ(706  , message.packed_sint64  (1));
+  EXPECT_EQ(707  , message.packed_fixed32 (1));
+  EXPECT_EQ(708  , message.packed_fixed64 (1));
+  EXPECT_EQ(709  , message.packed_sfixed32(1));
+  EXPECT_EQ(710  , message.packed_sfixed64(1));
+  EXPECT_EQ(711  , message.packed_float   (1));
+  EXPECT_EQ(712  , message.packed_double  (1));
+  EXPECT_EQ(false, message.packed_bool    (1));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAZ, message.packed_enum(1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedClear(
+    const unittest::TestPackedTypesLite& message) {
+  // Packed repeated fields are empty.
+  EXPECT_EQ(0, message.packed_int32_size   ());
+  EXPECT_EQ(0, message.packed_int64_size   ());
+  EXPECT_EQ(0, message.packed_uint32_size  ());
+  EXPECT_EQ(0, message.packed_uint64_size  ());
+  EXPECT_EQ(0, message.packed_sint32_size  ());
+  EXPECT_EQ(0, message.packed_sint64_size  ());
+  EXPECT_EQ(0, message.packed_fixed32_size ());
+  EXPECT_EQ(0, message.packed_fixed64_size ());
+  EXPECT_EQ(0, message.packed_sfixed32_size());
+  EXPECT_EQ(0, message.packed_sfixed64_size());
+  EXPECT_EQ(0, message.packed_float_size   ());
+  EXPECT_EQ(0, message.packed_double_size  ());
+  EXPECT_EQ(0, message.packed_bool_size    ());
+  EXPECT_EQ(0, message.packed_enum_size    ());
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedFieldsModified(
+    const unittest::TestPackedTypesLite& message) {
+  // Do the same for packed repeated fields.
+  ASSERT_EQ(2, message.packed_int32_size   ());
+  ASSERT_EQ(2, message.packed_int64_size   ());
+  ASSERT_EQ(2, message.packed_uint32_size  ());
+  ASSERT_EQ(2, message.packed_uint64_size  ());
+  ASSERT_EQ(2, message.packed_sint32_size  ());
+  ASSERT_EQ(2, message.packed_sint64_size  ());
+  ASSERT_EQ(2, message.packed_fixed32_size ());
+  ASSERT_EQ(2, message.packed_fixed64_size ());
+  ASSERT_EQ(2, message.packed_sfixed32_size());
+  ASSERT_EQ(2, message.packed_sfixed64_size());
+  ASSERT_EQ(2, message.packed_float_size   ());
+  ASSERT_EQ(2, message.packed_double_size  ());
+  ASSERT_EQ(2, message.packed_bool_size    ());
+  ASSERT_EQ(2, message.packed_enum_size    ());
+
+  EXPECT_EQ(601  , message.packed_int32   (0));
+  EXPECT_EQ(602  , message.packed_int64   (0));
+  EXPECT_EQ(603  , message.packed_uint32  (0));
+  EXPECT_EQ(604  , message.packed_uint64  (0));
+  EXPECT_EQ(605  , message.packed_sint32  (0));
+  EXPECT_EQ(606  , message.packed_sint64  (0));
+  EXPECT_EQ(607  , message.packed_fixed32 (0));
+  EXPECT_EQ(608  , message.packed_fixed64 (0));
+  EXPECT_EQ(609  , message.packed_sfixed32(0));
+  EXPECT_EQ(610  , message.packed_sfixed64(0));
+  EXPECT_EQ(611  , message.packed_float   (0));
+  EXPECT_EQ(612  , message.packed_double  (0));
+  EXPECT_EQ(true , message.packed_bool    (0));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAR, message.packed_enum(0));
+  // Actually verify the second (modified) elements now.
+  EXPECT_EQ(801  , message.packed_int32   (1));
+  EXPECT_EQ(802  , message.packed_int64   (1));
+  EXPECT_EQ(803  , message.packed_uint32  (1));
+  EXPECT_EQ(804  , message.packed_uint64  (1));
+  EXPECT_EQ(805  , message.packed_sint32  (1));
+  EXPECT_EQ(806  , message.packed_sint64  (1));
+  EXPECT_EQ(807  , message.packed_fixed32 (1));
+  EXPECT_EQ(808  , message.packed_fixed64 (1));
+  EXPECT_EQ(809  , message.packed_sfixed32(1));
+  EXPECT_EQ(810  , message.packed_sfixed64(1));
+  EXPECT_EQ(811  , message.packed_float   (1));
+  EXPECT_EQ(812  , message.packed_double  (1));
+  EXPECT_EQ(true , message.packed_bool    (1));
+  EXPECT_EQ(unittest::FOREIGN_LITE_FOO, message.packed_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 TestUtilLite::SetAllExtensions(unittest::TestAllExtensionsLite* message) {
+  message->SetExtension(unittest::optional_int32_extension_lite   , 101);
+  message->SetExtension(unittest::optional_int64_extension_lite   , 102);
+  message->SetExtension(unittest::optional_uint32_extension_lite  , 103);
+  message->SetExtension(unittest::optional_uint64_extension_lite  , 104);
+  message->SetExtension(unittest::optional_sint32_extension_lite  , 105);
+  message->SetExtension(unittest::optional_sint64_extension_lite  , 106);
+  message->SetExtension(unittest::optional_fixed32_extension_lite , 107);
+  message->SetExtension(unittest::optional_fixed64_extension_lite , 108);
+  message->SetExtension(unittest::optional_sfixed32_extension_lite, 109);
+  message->SetExtension(unittest::optional_sfixed64_extension_lite, 110);
+  message->SetExtension(unittest::optional_float_extension_lite   , 111);
+  message->SetExtension(unittest::optional_double_extension_lite  , 112);
+  message->SetExtension(unittest::optional_bool_extension_lite    , true);
+  message->SetExtension(unittest::optional_string_extension_lite  , "115");
+  message->SetExtension(unittest::optional_bytes_extension_lite   , "116");
+
+  message->MutableExtension(unittest::optionalgroup_extension_lite                 )->set_a(117);
+  message->MutableExtension(unittest::optional_nested_message_extension_lite       )->set_bb(118);
+  message->MutableExtension(unittest::optional_foreign_message_extension_lite      )->set_c(119);
+  message->MutableExtension(unittest::optional_import_message_extension_lite       )->set_d(120);
+  message->MutableExtension(unittest::optional_public_import_message_extension_lite)->set_e(126);
+  message->MutableExtension(unittest::optional_lazy_message_extension_lite         )->set_bb(127);
+
+  message->SetExtension(unittest::optional_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ );
+  message->SetExtension(unittest::optional_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ      );
+  message->SetExtension(unittest::optional_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAZ);
+
+
+  // -----------------------------------------------------------------
+
+  message->AddExtension(unittest::repeated_int32_extension_lite   , 201);
+  message->AddExtension(unittest::repeated_int64_extension_lite   , 202);
+  message->AddExtension(unittest::repeated_uint32_extension_lite  , 203);
+  message->AddExtension(unittest::repeated_uint64_extension_lite  , 204);
+  message->AddExtension(unittest::repeated_sint32_extension_lite  , 205);
+  message->AddExtension(unittest::repeated_sint64_extension_lite  , 206);
+  message->AddExtension(unittest::repeated_fixed32_extension_lite , 207);
+  message->AddExtension(unittest::repeated_fixed64_extension_lite , 208);
+  message->AddExtension(unittest::repeated_sfixed32_extension_lite, 209);
+  message->AddExtension(unittest::repeated_sfixed64_extension_lite, 210);
+  message->AddExtension(unittest::repeated_float_extension_lite   , 211);
+  message->AddExtension(unittest::repeated_double_extension_lite  , 212);
+  message->AddExtension(unittest::repeated_bool_extension_lite    , true);
+  message->AddExtension(unittest::repeated_string_extension_lite  , "215");
+  message->AddExtension(unittest::repeated_bytes_extension_lite   , "216");
+
+  message->AddExtension(unittest::repeatedgroup_extension_lite           )->set_a(217);
+  message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(218);
+  message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(219);
+  message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(220);
+  message->AddExtension(unittest::repeated_lazy_message_extension_lite   )->set_bb(227);
+
+  message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAR );
+  message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAR      );
+  message->AddExtension(unittest::repeated_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAR);
+
+
+  // Add a second one of each field.
+  message->AddExtension(unittest::repeated_int32_extension_lite   , 301);
+  message->AddExtension(unittest::repeated_int64_extension_lite   , 302);
+  message->AddExtension(unittest::repeated_uint32_extension_lite  , 303);
+  message->AddExtension(unittest::repeated_uint64_extension_lite  , 304);
+  message->AddExtension(unittest::repeated_sint32_extension_lite  , 305);
+  message->AddExtension(unittest::repeated_sint64_extension_lite  , 306);
+  message->AddExtension(unittest::repeated_fixed32_extension_lite , 307);
+  message->AddExtension(unittest::repeated_fixed64_extension_lite , 308);
+  message->AddExtension(unittest::repeated_sfixed32_extension_lite, 309);
+  message->AddExtension(unittest::repeated_sfixed64_extension_lite, 310);
+  message->AddExtension(unittest::repeated_float_extension_lite   , 311);
+  message->AddExtension(unittest::repeated_double_extension_lite  , 312);
+  message->AddExtension(unittest::repeated_bool_extension_lite    , false);
+  message->AddExtension(unittest::repeated_string_extension_lite  , "315");
+  message->AddExtension(unittest::repeated_bytes_extension_lite   , "316");
+
+  message->AddExtension(unittest::repeatedgroup_extension_lite           )->set_a(317);
+  message->AddExtension(unittest::repeated_nested_message_extension_lite )->set_bb(318);
+  message->AddExtension(unittest::repeated_foreign_message_extension_lite)->set_c(319);
+  message->AddExtension(unittest::repeated_import_message_extension_lite )->set_d(320);
+  message->AddExtension(unittest::repeated_lazy_message_extension_lite   )->set_bb(327);
+
+  message->AddExtension(unittest::repeated_nested_enum_extension_lite , unittest::TestAllTypesLite::BAZ );
+  message->AddExtension(unittest::repeated_foreign_enum_extension_lite, unittest::FOREIGN_LITE_BAZ      );
+  message->AddExtension(unittest::repeated_import_enum_extension_lite , unittest_import::IMPORT_LITE_BAZ);
+
+
+  // -----------------------------------------------------------------
+
+  message->SetExtension(unittest::default_int32_extension_lite   , 401);
+  message->SetExtension(unittest::default_int64_extension_lite   , 402);
+  message->SetExtension(unittest::default_uint32_extension_lite  , 403);
+  message->SetExtension(unittest::default_uint64_extension_lite  , 404);
+  message->SetExtension(unittest::default_sint32_extension_lite  , 405);
+  message->SetExtension(unittest::default_sint64_extension_lite  , 406);
+  message->SetExtension(unittest::default_fixed32_extension_lite , 407);
+  message->SetExtension(unittest::default_fixed64_extension_lite , 408);
+  message->SetExtension(unittest::default_sfixed32_extension_lite, 409);
+  message->SetExtension(unittest::default_sfixed64_extension_lite, 410);
+  message->SetExtension(unittest::default_float_extension_lite   , 411);
+  message->SetExtension(unittest::default_double_extension_lite  , 412);
+  message->SetExtension(unittest::default_bool_extension_lite    , false);
+  message->SetExtension(unittest::default_string_extension_lite  , "415");
+  message->SetExtension(unittest::default_bytes_extension_lite   , "416");
+
+  message->SetExtension(unittest::default_nested_enum_extension_lite , unittest::TestAllTypesLite::FOO );
+  message->SetExtension(unittest::default_foreign_enum_extension_lite, unittest::FOREIGN_LITE_FOO      );
+  message->SetExtension(unittest::default_import_enum_extension_lite , unittest_import::IMPORT_LITE_FOO);
+
+
+  message->SetExtension(unittest::oneof_uint32_extension_lite, 601);
+  message->MutableExtension(unittest::oneof_nested_message_extension_lite)->set_bb(602);;
+  message->SetExtension(unittest::oneof_string_extension_lite, "603");
+  message->SetExtension(unittest::oneof_bytes_extension_lite, "604");
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyRepeatedExtensions(
+    unittest::TestAllExtensionsLite* message) {
+  message->SetExtension(unittest::repeated_int32_extension_lite   , 1, 501);
+  message->SetExtension(unittest::repeated_int64_extension_lite   , 1, 502);
+  message->SetExtension(unittest::repeated_uint32_extension_lite  , 1, 503);
+  message->SetExtension(unittest::repeated_uint64_extension_lite  , 1, 504);
+  message->SetExtension(unittest::repeated_sint32_extension_lite  , 1, 505);
+  message->SetExtension(unittest::repeated_sint64_extension_lite  , 1, 506);
+  message->SetExtension(unittest::repeated_fixed32_extension_lite , 1, 507);
+  message->SetExtension(unittest::repeated_fixed64_extension_lite , 1, 508);
+  message->SetExtension(unittest::repeated_sfixed32_extension_lite, 1, 509);
+  message->SetExtension(unittest::repeated_sfixed64_extension_lite, 1, 510);
+  message->SetExtension(unittest::repeated_float_extension_lite   , 1, 511);
+  message->SetExtension(unittest::repeated_double_extension_lite  , 1, 512);
+  message->SetExtension(unittest::repeated_bool_extension_lite    , 1, true);
+  message->SetExtension(unittest::repeated_string_extension_lite  , 1, "515");
+  message->SetExtension(unittest::repeated_bytes_extension_lite   , 1, "516");
+
+  message->MutableExtension(unittest::repeatedgroup_extension_lite           , 1)->set_a(517);
+  message->MutableExtension(unittest::repeated_nested_message_extension_lite , 1)->set_bb(518);
+  message->MutableExtension(unittest::repeated_foreign_message_extension_lite, 1)->set_c(519);
+  message->MutableExtension(unittest::repeated_import_message_extension_lite , 1)->set_d(520);
+  message->MutableExtension(unittest::repeated_lazy_message_extension_lite   , 1)->set_bb(527);
+
+  message->SetExtension(unittest::repeated_nested_enum_extension_lite , 1, unittest::TestAllTypesLite::FOO );
+  message->SetExtension(unittest::repeated_foreign_enum_extension_lite, 1, unittest::FOREIGN_LITE_FOO      );
+  message->SetExtension(unittest::repeated_import_enum_extension_lite , 1, unittest_import::IMPORT_LITE_FOO);
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectAllExtensionsSet(
+    const unittest::TestAllExtensionsLite& message) {
+  EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension_lite   ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_int64_extension_lite   ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_uint64_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_sint32_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_sint64_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_fixed32_extension_lite ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_fixed64_extension_lite ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed32_extension_lite));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_sfixed64_extension_lite));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_float_extension_lite   ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_double_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_bool_extension_lite    ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_bytes_extension_lite   ));
+
+  EXPECT_TRUE(message.HasExtension(unittest::optionalgroup_extension_lite                 ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_nested_message_extension_lite       ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_message_extension_lite      ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_import_message_extension_lite       ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_public_import_message_extension_lite));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_lazy_message_extension_lite         ));
+
+  EXPECT_TRUE(message.GetExtension(unittest::optionalgroup_extension_lite                 ).has_a());
+  EXPECT_TRUE(message.GetExtension(unittest::optional_nested_message_extension_lite       ).has_bb());
+  EXPECT_TRUE(message.GetExtension(unittest::optional_foreign_message_extension_lite      ).has_c());
+  EXPECT_TRUE(message.GetExtension(unittest::optional_import_message_extension_lite       ).has_d());
+  EXPECT_TRUE(message.GetExtension(unittest::optional_public_import_message_extension_lite).has_e());
+  EXPECT_TRUE(message.GetExtension(unittest::optional_lazy_message_extension_lite         ).has_bb());
+
+  EXPECT_TRUE(message.HasExtension(unittest::optional_nested_enum_extension_lite ));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_foreign_enum_extension_lite));
+  EXPECT_TRUE(message.HasExtension(unittest::optional_import_enum_extension_lite ));
+
+
+  EXPECT_EQ(101  , message.GetExtension(unittest::optional_int32_extension_lite   ));
+  EXPECT_EQ(102  , message.GetExtension(unittest::optional_int64_extension_lite   ));
+  EXPECT_EQ(103  , message.GetExtension(unittest::optional_uint32_extension_lite  ));
+  EXPECT_EQ(104  , message.GetExtension(unittest::optional_uint64_extension_lite  ));
+  EXPECT_EQ(105  , message.GetExtension(unittest::optional_sint32_extension_lite  ));
+  EXPECT_EQ(106  , message.GetExtension(unittest::optional_sint64_extension_lite  ));
+  EXPECT_EQ(107  , message.GetExtension(unittest::optional_fixed32_extension_lite ));
+  EXPECT_EQ(108  , message.GetExtension(unittest::optional_fixed64_extension_lite ));
+  EXPECT_EQ(109  , message.GetExtension(unittest::optional_sfixed32_extension_lite));
+  EXPECT_EQ(110  , message.GetExtension(unittest::optional_sfixed64_extension_lite));
+  EXPECT_EQ(111  , message.GetExtension(unittest::optional_float_extension_lite   ));
+  EXPECT_EQ(112  , message.GetExtension(unittest::optional_double_extension_lite  ));
+  EXPECT_EQ(true , message.GetExtension(unittest::optional_bool_extension_lite    ));
+  EXPECT_EQ("115", message.GetExtension(unittest::optional_string_extension_lite  ));
+  EXPECT_EQ("116", message.GetExtension(unittest::optional_bytes_extension_lite   ));
+
+  EXPECT_EQ(117, message.GetExtension(unittest::optionalgroup_extension_lite                 ).a());
+  EXPECT_EQ(118, message.GetExtension(unittest::optional_nested_message_extension_lite       ).bb());
+  EXPECT_EQ(119, message.GetExtension(unittest::optional_foreign_message_extension_lite      ).c());
+  EXPECT_EQ(120, message.GetExtension(unittest::optional_import_message_extension_lite       ).d());
+  EXPECT_EQ(126, message.GetExtension(unittest::optional_public_import_message_extension_lite).e());
+  EXPECT_EQ(127, message.GetExtension(unittest::optional_lazy_message_extension_lite         ).bb());
+
+  EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::optional_nested_enum_extension_lite ));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAZ      , message.GetExtension(unittest::optional_foreign_enum_extension_lite));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.GetExtension(unittest::optional_import_enum_extension_lite ));
+
+
+  // -----------------------------------------------------------------
+
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int32_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite   ));
+
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite           ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite    ));
+
+
+  EXPECT_EQ(201  , message.GetExtension(unittest::repeated_int32_extension_lite   , 0));
+  EXPECT_EQ(202  , message.GetExtension(unittest::repeated_int64_extension_lite   , 0));
+  EXPECT_EQ(203  , message.GetExtension(unittest::repeated_uint32_extension_lite  , 0));
+  EXPECT_EQ(204  , message.GetExtension(unittest::repeated_uint64_extension_lite  , 0));
+  EXPECT_EQ(205  , message.GetExtension(unittest::repeated_sint32_extension_lite  , 0));
+  EXPECT_EQ(206  , message.GetExtension(unittest::repeated_sint64_extension_lite  , 0));
+  EXPECT_EQ(207  , message.GetExtension(unittest::repeated_fixed32_extension_lite , 0));
+  EXPECT_EQ(208  , message.GetExtension(unittest::repeated_fixed64_extension_lite , 0));
+  EXPECT_EQ(209  , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0));
+  EXPECT_EQ(210  , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0));
+  EXPECT_EQ(211  , message.GetExtension(unittest::repeated_float_extension_lite   , 0));
+  EXPECT_EQ(212  , message.GetExtension(unittest::repeated_double_extension_lite  , 0));
+  EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite    , 0));
+  EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension_lite  , 0));
+  EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension_lite   , 0));
+
+  EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension_lite           , 0).a());
+  EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb());
+  EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c());
+  EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d());
+  EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension_lite   , 0).bb());
+
+  EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAR      , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::repeated_import_enum_extension_lite , 0));
+
+
+  EXPECT_EQ(301  , message.GetExtension(unittest::repeated_int32_extension_lite   , 1));
+  EXPECT_EQ(302  , message.GetExtension(unittest::repeated_int64_extension_lite   , 1));
+  EXPECT_EQ(303  , message.GetExtension(unittest::repeated_uint32_extension_lite  , 1));
+  EXPECT_EQ(304  , message.GetExtension(unittest::repeated_uint64_extension_lite  , 1));
+  EXPECT_EQ(305  , message.GetExtension(unittest::repeated_sint32_extension_lite  , 1));
+  EXPECT_EQ(306  , message.GetExtension(unittest::repeated_sint64_extension_lite  , 1));
+  EXPECT_EQ(307  , message.GetExtension(unittest::repeated_fixed32_extension_lite , 1));
+  EXPECT_EQ(308  , message.GetExtension(unittest::repeated_fixed64_extension_lite , 1));
+  EXPECT_EQ(309  , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1));
+  EXPECT_EQ(310  , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1));
+  EXPECT_EQ(311  , message.GetExtension(unittest::repeated_float_extension_lite   , 1));
+  EXPECT_EQ(312  , message.GetExtension(unittest::repeated_double_extension_lite  , 1));
+  EXPECT_EQ(false, message.GetExtension(unittest::repeated_bool_extension_lite    , 1));
+  EXPECT_EQ("315", message.GetExtension(unittest::repeated_string_extension_lite  , 1));
+  EXPECT_EQ("316", message.GetExtension(unittest::repeated_bytes_extension_lite   , 1));
+
+  EXPECT_EQ(317, message.GetExtension(unittest::repeatedgroup_extension_lite           , 1).a());
+  EXPECT_EQ(318, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb());
+  EXPECT_EQ(319, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c());
+  EXPECT_EQ(320, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d());
+  EXPECT_EQ(327, message.GetExtension(unittest::repeated_lazy_message_extension_lite   , 1).bb());
+
+  EXPECT_EQ(unittest::TestAllTypesLite::BAZ , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAZ      , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_BAZ, message.GetExtension(unittest::repeated_import_enum_extension_lite , 1));
+
+
+  // -----------------------------------------------------------------
+
+  EXPECT_TRUE(message.HasExtension(unittest::default_int32_extension_lite   ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_int64_extension_lite   ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_uint32_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_uint64_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_sint32_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_sint64_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_fixed32_extension_lite ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_fixed64_extension_lite ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_sfixed32_extension_lite));
+  EXPECT_TRUE(message.HasExtension(unittest::default_sfixed64_extension_lite));
+  EXPECT_TRUE(message.HasExtension(unittest::default_float_extension_lite   ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_double_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_bool_extension_lite    ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_string_extension_lite  ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_bytes_extension_lite   ));
+
+  EXPECT_TRUE(message.HasExtension(unittest::default_nested_enum_extension_lite ));
+  EXPECT_TRUE(message.HasExtension(unittest::default_foreign_enum_extension_lite));
+  EXPECT_TRUE(message.HasExtension(unittest::default_import_enum_extension_lite ));
+
+
+  EXPECT_EQ(401  , message.GetExtension(unittest::default_int32_extension_lite   ));
+  EXPECT_EQ(402  , message.GetExtension(unittest::default_int64_extension_lite   ));
+  EXPECT_EQ(403  , message.GetExtension(unittest::default_uint32_extension_lite  ));
+  EXPECT_EQ(404  , message.GetExtension(unittest::default_uint64_extension_lite  ));
+  EXPECT_EQ(405  , message.GetExtension(unittest::default_sint32_extension_lite  ));
+  EXPECT_EQ(406  , message.GetExtension(unittest::default_sint64_extension_lite  ));
+  EXPECT_EQ(407  , message.GetExtension(unittest::default_fixed32_extension_lite ));
+  EXPECT_EQ(408  , message.GetExtension(unittest::default_fixed64_extension_lite ));
+  EXPECT_EQ(409  , message.GetExtension(unittest::default_sfixed32_extension_lite));
+  EXPECT_EQ(410  , message.GetExtension(unittest::default_sfixed64_extension_lite));
+  EXPECT_EQ(411  , message.GetExtension(unittest::default_float_extension_lite   ));
+  EXPECT_EQ(412  , message.GetExtension(unittest::default_double_extension_lite  ));
+  EXPECT_EQ(false, message.GetExtension(unittest::default_bool_extension_lite    ));
+  EXPECT_EQ("415", message.GetExtension(unittest::default_string_extension_lite  ));
+  EXPECT_EQ("416", message.GetExtension(unittest::default_bytes_extension_lite   ));
+
+  EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::default_nested_enum_extension_lite ));
+  EXPECT_EQ(unittest::FOREIGN_LITE_FOO      , message.GetExtension(unittest::default_foreign_enum_extension_lite));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::default_import_enum_extension_lite ));
+
+
+  EXPECT_TRUE(message.HasExtension(unittest::oneof_uint32_extension_lite));
+  EXPECT_TRUE(message.GetExtension(unittest::oneof_nested_message_extension_lite).has_bb());
+  EXPECT_TRUE(message.HasExtension(unittest::oneof_string_extension_lite));
+  EXPECT_TRUE(message.HasExtension(unittest::oneof_bytes_extension_lite));
+
+  EXPECT_EQ(601, message.GetExtension(unittest::oneof_uint32_extension_lite));
+  EXPECT_EQ(602, message.GetExtension(unittest::oneof_nested_message_extension_lite).bb());
+  EXPECT_EQ("603", message.GetExtension(unittest::oneof_string_extension_lite));
+  EXPECT_EQ("604", message.GetExtension(unittest::oneof_bytes_extension_lite));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectExtensionsClear(
+    const unittest::TestAllExtensionsLite& 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_lite   ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension_lite   ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_uint32_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_uint64_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_sint32_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_sint64_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_fixed32_extension_lite ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_fixed64_extension_lite ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed32_extension_lite));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_sfixed64_extension_lite));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_float_extension_lite   ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_double_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_bool_extension_lite    ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_string_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_bytes_extension_lite   ));
+
+  EXPECT_FALSE(message.HasExtension(unittest::optionalgroup_extension_lite                 ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_nested_message_extension_lite       ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_message_extension_lite      ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_import_message_extension_lite       ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_public_import_message_extension_lite));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_lazy_message_extension_lite         ));
+
+  EXPECT_FALSE(message.HasExtension(unittest::optional_nested_enum_extension_lite ));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_foreign_enum_extension_lite));
+  EXPECT_FALSE(message.HasExtension(unittest::optional_import_enum_extension_lite ));
+
+
+  // Optional fields without defaults are set to zero or something like it.
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_int32_extension_lite   ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_int64_extension_lite   ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_uint32_extension_lite  ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_uint64_extension_lite  ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_sint32_extension_lite  ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_sint64_extension_lite  ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_fixed32_extension_lite ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_fixed64_extension_lite ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_sfixed32_extension_lite));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_sfixed64_extension_lite));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_float_extension_lite   ));
+  EXPECT_EQ(0    , message.GetExtension(unittest::optional_double_extension_lite  ));
+  EXPECT_EQ(false, message.GetExtension(unittest::optional_bool_extension_lite    ));
+  EXPECT_EQ(""   , message.GetExtension(unittest::optional_string_extension_lite  ));
+  EXPECT_EQ(""   , message.GetExtension(unittest::optional_bytes_extension_lite   ));
+
+  // Embedded messages should also be clear.
+  EXPECT_FALSE(message.GetExtension(unittest::optionalgroup_extension_lite                 ).has_a());
+  EXPECT_FALSE(message.GetExtension(unittest::optional_nested_message_extension_lite       ).has_bb());
+  EXPECT_FALSE(message.GetExtension(unittest::optional_foreign_message_extension_lite      ).has_c());
+  EXPECT_FALSE(message.GetExtension(unittest::optional_import_message_extension_lite       ).has_d());
+  EXPECT_FALSE(message.GetExtension(unittest::optional_public_import_message_extension_lite).has_e());
+  EXPECT_FALSE(message.GetExtension(unittest::optional_lazy_message_extension_lite         ).has_bb());
+
+  EXPECT_EQ(0, message.GetExtension(unittest::optionalgroup_extension_lite                 ).a());
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_nested_message_extension_lite       ).bb());
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_foreign_message_extension_lite      ).c());
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_import_message_extension_lite       ).d());
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_public_import_message_extension_lite).e());
+  EXPECT_EQ(0, message.GetExtension(unittest::optional_lazy_message_extension_lite         ).bb());
+
+  // Enums without defaults are set to the first value in the enum.
+  EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::optional_nested_enum_extension_lite ));
+  EXPECT_EQ(unittest::FOREIGN_LITE_FOO      , message.GetExtension(unittest::optional_foreign_enum_extension_lite));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::optional_import_enum_extension_lite ));
+
+
+  // Repeated fields are empty.
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int32_extension_lite   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_int64_extension_lite   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint32_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_uint64_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint32_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sint64_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed32_extension_lite ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_fixed64_extension_lite ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_float_extension_lite   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_double_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bool_extension_lite    ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_string_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_bytes_extension_lite   ));
+
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeatedgroup_extension_lite           ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_message_extension_lite ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_message_extension_lite ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite    ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::repeated_import_enum_extension_lite    ));
+
+
+  // has_blah() should also be false for all default fields.
+  EXPECT_FALSE(message.HasExtension(unittest::default_int32_extension_lite   ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_int64_extension_lite   ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_uint32_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_uint64_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_sint32_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_sint64_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_fixed32_extension_lite ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_fixed64_extension_lite ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_sfixed32_extension_lite));
+  EXPECT_FALSE(message.HasExtension(unittest::default_sfixed64_extension_lite));
+  EXPECT_FALSE(message.HasExtension(unittest::default_float_extension_lite   ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_double_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_bool_extension_lite    ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_string_extension_lite  ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_bytes_extension_lite   ));
+
+  EXPECT_FALSE(message.HasExtension(unittest::default_nested_enum_extension_lite ));
+  EXPECT_FALSE(message.HasExtension(unittest::default_foreign_enum_extension_lite));
+  EXPECT_FALSE(message.HasExtension(unittest::default_import_enum_extension_lite ));
+
+
+  // Fields with defaults have their default values (duh).
+  EXPECT_EQ( 41    , message.GetExtension(unittest::default_int32_extension_lite   ));
+  EXPECT_EQ( 42    , message.GetExtension(unittest::default_int64_extension_lite   ));
+  EXPECT_EQ( 43    , message.GetExtension(unittest::default_uint32_extension_lite  ));
+  EXPECT_EQ( 44    , message.GetExtension(unittest::default_uint64_extension_lite  ));
+  EXPECT_EQ(-45    , message.GetExtension(unittest::default_sint32_extension_lite  ));
+  EXPECT_EQ( 46    , message.GetExtension(unittest::default_sint64_extension_lite  ));
+  EXPECT_EQ( 47    , message.GetExtension(unittest::default_fixed32_extension_lite ));
+  EXPECT_EQ( 48    , message.GetExtension(unittest::default_fixed64_extension_lite ));
+  EXPECT_EQ( 49    , message.GetExtension(unittest::default_sfixed32_extension_lite));
+  EXPECT_EQ(-50    , message.GetExtension(unittest::default_sfixed64_extension_lite));
+  EXPECT_EQ( 51.5  , message.GetExtension(unittest::default_float_extension_lite   ));
+  EXPECT_EQ( 52e3  , message.GetExtension(unittest::default_double_extension_lite  ));
+  EXPECT_EQ(true   , message.GetExtension(unittest::default_bool_extension_lite    ));
+  EXPECT_EQ("hello", message.GetExtension(unittest::default_string_extension_lite  ));
+  EXPECT_EQ("world", message.GetExtension(unittest::default_bytes_extension_lite   ));
+
+  EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::default_nested_enum_extension_lite ));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAR      , message.GetExtension(unittest::default_foreign_enum_extension_lite));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::default_import_enum_extension_lite ));
+
+
+  EXPECT_FALSE(message.HasExtension(unittest::oneof_uint32_extension_lite));
+  EXPECT_FALSE(message.GetExtension(unittest::oneof_nested_message_extension_lite).has_bb());
+  EXPECT_FALSE(message.HasExtension(unittest::oneof_string_extension_lite));
+  EXPECT_FALSE(message.HasExtension(unittest::oneof_bytes_extension_lite));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectRepeatedExtensionsModified(
+    const unittest::TestAllExtensionsLite& 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_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_int64_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint32_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_uint64_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint32_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sint64_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed32_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_fixed64_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed32_extension_lite));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_sfixed64_extension_lite));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_float_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_double_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bool_extension_lite    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_string_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_bytes_extension_lite   ));
+
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeatedgroup_extension_lite           ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_message_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_message_extension_lite));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_message_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_lazy_message_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_nested_enum_extension_lite    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_foreign_enum_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::repeated_import_enum_extension_lite    ));
+
+
+  EXPECT_EQ(201  , message.GetExtension(unittest::repeated_int32_extension_lite   , 0));
+  EXPECT_EQ(202  , message.GetExtension(unittest::repeated_int64_extension_lite   , 0));
+  EXPECT_EQ(203  , message.GetExtension(unittest::repeated_uint32_extension_lite  , 0));
+  EXPECT_EQ(204  , message.GetExtension(unittest::repeated_uint64_extension_lite  , 0));
+  EXPECT_EQ(205  , message.GetExtension(unittest::repeated_sint32_extension_lite  , 0));
+  EXPECT_EQ(206  , message.GetExtension(unittest::repeated_sint64_extension_lite  , 0));
+  EXPECT_EQ(207  , message.GetExtension(unittest::repeated_fixed32_extension_lite , 0));
+  EXPECT_EQ(208  , message.GetExtension(unittest::repeated_fixed64_extension_lite , 0));
+  EXPECT_EQ(209  , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 0));
+  EXPECT_EQ(210  , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 0));
+  EXPECT_EQ(211  , message.GetExtension(unittest::repeated_float_extension_lite   , 0));
+  EXPECT_EQ(212  , message.GetExtension(unittest::repeated_double_extension_lite  , 0));
+  EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite    , 0));
+  EXPECT_EQ("215", message.GetExtension(unittest::repeated_string_extension_lite  , 0));
+  EXPECT_EQ("216", message.GetExtension(unittest::repeated_bytes_extension_lite   , 0));
+
+  EXPECT_EQ(217, message.GetExtension(unittest::repeatedgroup_extension_lite           , 0).a());
+  EXPECT_EQ(218, message.GetExtension(unittest::repeated_nested_message_extension_lite , 0).bb());
+  EXPECT_EQ(219, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 0).c());
+  EXPECT_EQ(220, message.GetExtension(unittest::repeated_import_message_extension_lite , 0).d());
+  EXPECT_EQ(227, message.GetExtension(unittest::repeated_lazy_message_extension_lite   , 0).bb());
+
+  EXPECT_EQ(unittest::TestAllTypesLite::BAR , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 0));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAR      , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 0));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_BAR, message.GetExtension(unittest::repeated_import_enum_extension_lite , 0));
+
+
+  // Actually verify the second (modified) elements now.
+  EXPECT_EQ(501  , message.GetExtension(unittest::repeated_int32_extension_lite   , 1));
+  EXPECT_EQ(502  , message.GetExtension(unittest::repeated_int64_extension_lite   , 1));
+  EXPECT_EQ(503  , message.GetExtension(unittest::repeated_uint32_extension_lite  , 1));
+  EXPECT_EQ(504  , message.GetExtension(unittest::repeated_uint64_extension_lite  , 1));
+  EXPECT_EQ(505  , message.GetExtension(unittest::repeated_sint32_extension_lite  , 1));
+  EXPECT_EQ(506  , message.GetExtension(unittest::repeated_sint64_extension_lite  , 1));
+  EXPECT_EQ(507  , message.GetExtension(unittest::repeated_fixed32_extension_lite , 1));
+  EXPECT_EQ(508  , message.GetExtension(unittest::repeated_fixed64_extension_lite , 1));
+  EXPECT_EQ(509  , message.GetExtension(unittest::repeated_sfixed32_extension_lite, 1));
+  EXPECT_EQ(510  , message.GetExtension(unittest::repeated_sfixed64_extension_lite, 1));
+  EXPECT_EQ(511  , message.GetExtension(unittest::repeated_float_extension_lite   , 1));
+  EXPECT_EQ(512  , message.GetExtension(unittest::repeated_double_extension_lite  , 1));
+  EXPECT_EQ(true , message.GetExtension(unittest::repeated_bool_extension_lite    , 1));
+  EXPECT_EQ("515", message.GetExtension(unittest::repeated_string_extension_lite  , 1));
+  EXPECT_EQ("516", message.GetExtension(unittest::repeated_bytes_extension_lite   , 1));
+
+  EXPECT_EQ(517, message.GetExtension(unittest::repeatedgroup_extension_lite           , 1).a());
+  EXPECT_EQ(518, message.GetExtension(unittest::repeated_nested_message_extension_lite , 1).bb());
+  EXPECT_EQ(519, message.GetExtension(unittest::repeated_foreign_message_extension_lite, 1).c());
+  EXPECT_EQ(520, message.GetExtension(unittest::repeated_import_message_extension_lite , 1).d());
+  EXPECT_EQ(527, message.GetExtension(unittest::repeated_lazy_message_extension_lite   , 1).bb());
+
+  EXPECT_EQ(unittest::TestAllTypesLite::FOO , message.GetExtension(unittest::repeated_nested_enum_extension_lite , 1));
+  EXPECT_EQ(unittest::FOREIGN_LITE_FOO      , message.GetExtension(unittest::repeated_foreign_enum_extension_lite, 1));
+  EXPECT_EQ(unittest_import::IMPORT_LITE_FOO, message.GetExtension(unittest::repeated_import_enum_extension_lite , 1));
+
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::SetPackedExtensions(
+    unittest::TestPackedExtensionsLite* message) {
+  message->AddExtension(unittest::packed_int32_extension_lite   , 601);
+  message->AddExtension(unittest::packed_int64_extension_lite   , 602);
+  message->AddExtension(unittest::packed_uint32_extension_lite  , 603);
+  message->AddExtension(unittest::packed_uint64_extension_lite  , 604);
+  message->AddExtension(unittest::packed_sint32_extension_lite  , 605);
+  message->AddExtension(unittest::packed_sint64_extension_lite  , 606);
+  message->AddExtension(unittest::packed_fixed32_extension_lite , 607);
+  message->AddExtension(unittest::packed_fixed64_extension_lite , 608);
+  message->AddExtension(unittest::packed_sfixed32_extension_lite, 609);
+  message->AddExtension(unittest::packed_sfixed64_extension_lite, 610);
+  message->AddExtension(unittest::packed_float_extension_lite   , 611);
+  message->AddExtension(unittest::packed_double_extension_lite  , 612);
+  message->AddExtension(unittest::packed_bool_extension_lite    , true);
+  message->AddExtension(unittest::packed_enum_extension_lite, unittest::FOREIGN_LITE_BAR);
+  // add a second one of each field
+  message->AddExtension(unittest::packed_int32_extension_lite   , 701);
+  message->AddExtension(unittest::packed_int64_extension_lite   , 702);
+  message->AddExtension(unittest::packed_uint32_extension_lite  , 703);
+  message->AddExtension(unittest::packed_uint64_extension_lite  , 704);
+  message->AddExtension(unittest::packed_sint32_extension_lite  , 705);
+  message->AddExtension(unittest::packed_sint64_extension_lite  , 706);
+  message->AddExtension(unittest::packed_fixed32_extension_lite , 707);
+  message->AddExtension(unittest::packed_fixed64_extension_lite , 708);
+  message->AddExtension(unittest::packed_sfixed32_extension_lite, 709);
+  message->AddExtension(unittest::packed_sfixed64_extension_lite, 710);
+  message->AddExtension(unittest::packed_float_extension_lite   , 711);
+  message->AddExtension(unittest::packed_double_extension_lite  , 712);
+  message->AddExtension(unittest::packed_bool_extension_lite    , false);
+  message->AddExtension(unittest::packed_enum_extension_lite, unittest::FOREIGN_LITE_BAZ);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ModifyPackedExtensions(
+    unittest::TestPackedExtensionsLite* message) {
+  message->SetExtension(unittest::packed_int32_extension_lite   , 1, 801);
+  message->SetExtension(unittest::packed_int64_extension_lite   , 1, 802);
+  message->SetExtension(unittest::packed_uint32_extension_lite  , 1, 803);
+  message->SetExtension(unittest::packed_uint64_extension_lite  , 1, 804);
+  message->SetExtension(unittest::packed_sint32_extension_lite  , 1, 805);
+  message->SetExtension(unittest::packed_sint64_extension_lite  , 1, 806);
+  message->SetExtension(unittest::packed_fixed32_extension_lite , 1, 807);
+  message->SetExtension(unittest::packed_fixed64_extension_lite , 1, 808);
+  message->SetExtension(unittest::packed_sfixed32_extension_lite, 1, 809);
+  message->SetExtension(unittest::packed_sfixed64_extension_lite, 1, 810);
+  message->SetExtension(unittest::packed_float_extension_lite   , 1, 811);
+  message->SetExtension(unittest::packed_double_extension_lite  , 1, 812);
+  message->SetExtension(unittest::packed_bool_extension_lite    , 1, true);
+  message->SetExtension(unittest::packed_enum_extension_lite    , 1,
+                        unittest::FOREIGN_LITE_FOO);
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedExtensionsSet(
+    const unittest::TestPackedExtensionsLite& message) {
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite    ));
+
+  EXPECT_EQ(601  , message.GetExtension(unittest::packed_int32_extension_lite   , 0));
+  EXPECT_EQ(602  , message.GetExtension(unittest::packed_int64_extension_lite   , 0));
+  EXPECT_EQ(603  , message.GetExtension(unittest::packed_uint32_extension_lite  , 0));
+  EXPECT_EQ(604  , message.GetExtension(unittest::packed_uint64_extension_lite  , 0));
+  EXPECT_EQ(605  , message.GetExtension(unittest::packed_sint32_extension_lite  , 0));
+  EXPECT_EQ(606  , message.GetExtension(unittest::packed_sint64_extension_lite  , 0));
+  EXPECT_EQ(607  , message.GetExtension(unittest::packed_fixed32_extension_lite , 0));
+  EXPECT_EQ(608  , message.GetExtension(unittest::packed_fixed64_extension_lite , 0));
+  EXPECT_EQ(609  , message.GetExtension(unittest::packed_sfixed32_extension_lite, 0));
+  EXPECT_EQ(610  , message.GetExtension(unittest::packed_sfixed64_extension_lite, 0));
+  EXPECT_EQ(611  , message.GetExtension(unittest::packed_float_extension_lite   , 0));
+  EXPECT_EQ(612  , message.GetExtension(unittest::packed_double_extension_lite  , 0));
+  EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite    , 0));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAR,
+            message.GetExtension(unittest::packed_enum_extension_lite, 0));
+  EXPECT_EQ(701  , message.GetExtension(unittest::packed_int32_extension_lite   , 1));
+  EXPECT_EQ(702  , message.GetExtension(unittest::packed_int64_extension_lite   , 1));
+  EXPECT_EQ(703  , message.GetExtension(unittest::packed_uint32_extension_lite  , 1));
+  EXPECT_EQ(704  , message.GetExtension(unittest::packed_uint64_extension_lite  , 1));
+  EXPECT_EQ(705  , message.GetExtension(unittest::packed_sint32_extension_lite  , 1));
+  EXPECT_EQ(706  , message.GetExtension(unittest::packed_sint64_extension_lite  , 1));
+  EXPECT_EQ(707  , message.GetExtension(unittest::packed_fixed32_extension_lite , 1));
+  EXPECT_EQ(708  , message.GetExtension(unittest::packed_fixed64_extension_lite , 1));
+  EXPECT_EQ(709  , message.GetExtension(unittest::packed_sfixed32_extension_lite, 1));
+  EXPECT_EQ(710  , message.GetExtension(unittest::packed_sfixed64_extension_lite, 1));
+  EXPECT_EQ(711  , message.GetExtension(unittest::packed_float_extension_lite   , 1));
+  EXPECT_EQ(712  , message.GetExtension(unittest::packed_double_extension_lite  , 1));
+  EXPECT_EQ(false, message.GetExtension(unittest::packed_bool_extension_lite    , 1));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAZ,
+            message.GetExtension(unittest::packed_enum_extension_lite, 1));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedExtensionsClear(
+    const unittest::TestPackedExtensionsLite& message) {
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int32_extension_lite   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_int64_extension_lite   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint32_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_uint64_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint32_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sint64_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed32_extension_lite ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_fixed64_extension_lite ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed32_extension_lite));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_sfixed64_extension_lite));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_float_extension_lite   ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_double_extension_lite  ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_bool_extension_lite    ));
+  EXPECT_EQ(0, message.ExtensionSize(unittest::packed_enum_extension_lite    ));
+}
+
+// -------------------------------------------------------------------
+
+void TestUtilLite::ExpectPackedExtensionsModified(
+    const unittest::TestPackedExtensionsLite& message) {
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int32_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_int64_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint32_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_uint64_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint32_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sint64_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed32_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_fixed64_extension_lite ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed32_extension_lite));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_sfixed64_extension_lite));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_float_extension_lite   ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_double_extension_lite  ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_bool_extension_lite    ));
+  ASSERT_EQ(2, message.ExtensionSize(unittest::packed_enum_extension_lite    ));
+  EXPECT_EQ(601  , message.GetExtension(unittest::packed_int32_extension_lite   , 0));
+  EXPECT_EQ(602  , message.GetExtension(unittest::packed_int64_extension_lite   , 0));
+  EXPECT_EQ(603  , message.GetExtension(unittest::packed_uint32_extension_lite  , 0));
+  EXPECT_EQ(604  , message.GetExtension(unittest::packed_uint64_extension_lite  , 0));
+  EXPECT_EQ(605  , message.GetExtension(unittest::packed_sint32_extension_lite  , 0));
+  EXPECT_EQ(606  , message.GetExtension(unittest::packed_sint64_extension_lite  , 0));
+  EXPECT_EQ(607  , message.GetExtension(unittest::packed_fixed32_extension_lite , 0));
+  EXPECT_EQ(608  , message.GetExtension(unittest::packed_fixed64_extension_lite , 0));
+  EXPECT_EQ(609  , message.GetExtension(unittest::packed_sfixed32_extension_lite, 0));
+  EXPECT_EQ(610  , message.GetExtension(unittest::packed_sfixed64_extension_lite, 0));
+  EXPECT_EQ(611  , message.GetExtension(unittest::packed_float_extension_lite   , 0));
+  EXPECT_EQ(612  , message.GetExtension(unittest::packed_double_extension_lite  , 0));
+  EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite    , 0));
+  EXPECT_EQ(unittest::FOREIGN_LITE_BAR,
+            message.GetExtension(unittest::packed_enum_extension_lite, 0));
+
+  // Actually verify the second (modified) elements now.
+  EXPECT_EQ(801  , message.GetExtension(unittest::packed_int32_extension_lite   , 1));
+  EXPECT_EQ(802  , message.GetExtension(unittest::packed_int64_extension_lite   , 1));
+  EXPECT_EQ(803  , message.GetExtension(unittest::packed_uint32_extension_lite  , 1));
+  EXPECT_EQ(804  , message.GetExtension(unittest::packed_uint64_extension_lite  , 1));
+  EXPECT_EQ(805  , message.GetExtension(unittest::packed_sint32_extension_lite  , 1));
+  EXPECT_EQ(806  , message.GetExtension(unittest::packed_sint64_extension_lite  , 1));
+  EXPECT_EQ(807  , message.GetExtension(unittest::packed_fixed32_extension_lite , 1));
+  EXPECT_EQ(808  , message.GetExtension(unittest::packed_fixed64_extension_lite , 1));
+  EXPECT_EQ(809  , message.GetExtension(unittest::packed_sfixed32_extension_lite, 1));
+  EXPECT_EQ(810  , message.GetExtension(unittest::packed_sfixed64_extension_lite, 1));
+  EXPECT_EQ(811  , message.GetExtension(unittest::packed_float_extension_lite   , 1));
+  EXPECT_EQ(812  , message.GetExtension(unittest::packed_double_extension_lite  , 1));
+  EXPECT_EQ(true , message.GetExtension(unittest::packed_bool_extension_lite    , 1));
+  EXPECT_EQ(unittest::FOREIGN_LITE_FOO,
+            message.GetExtension(unittest::packed_enum_extension_lite, 1));
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/test_util_lite.h b/protobuf/src/google/protobuf/test_util_lite.h
new file mode 100644
index 0000000..f250c93
--- /dev/null
+++ b/protobuf/src/google/protobuf/test_util_lite.h
@@ -0,0 +1,101 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__
+#define GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__
+
+#include <google/protobuf/unittest_lite.pb.h>
+
+namespace google {
+namespace protobuf {
+
+namespace unittest = protobuf_unittest;
+namespace unittest_import = protobuf_unittest_import;
+
+class TestUtilLite {
+ public:
+  // Set every field in the message to a unique value.
+  static void SetAllFields(unittest::TestAllTypesLite* message);
+  static void SetAllExtensions(unittest::TestAllExtensionsLite* message);
+  static void SetPackedFields(unittest::TestPackedTypesLite* message);
+  static void SetPackedExtensions(unittest::TestPackedExtensionsLite* 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 Set*Fields()).  Set*Fields() itself only tests
+  // the add_*() accessors.
+  static void ModifyRepeatedFields(unittest::TestAllTypesLite* message);
+  static void ModifyRepeatedExtensions(
+      unittest::TestAllExtensionsLite* message);
+  static void ModifyPackedFields(unittest::TestPackedTypesLite* message);
+  static void ModifyPackedExtensions(
+      unittest::TestPackedExtensionsLite* message);
+
+  // Check that all fields have the values that they should have after
+  // Set*Fields() is called.
+  static void ExpectAllFieldsSet(const unittest::TestAllTypesLite& message);
+  static void ExpectAllExtensionsSet(
+      const unittest::TestAllExtensionsLite& message);
+  static void ExpectPackedFieldsSet(
+      const unittest::TestPackedTypesLite& message);
+  static void ExpectPackedExtensionsSet(
+      const unittest::TestPackedExtensionsLite& message);
+
+  // Expect that the message is modified as would be expected from
+  // Modify*Fields().
+  static void ExpectRepeatedFieldsModified(
+      const unittest::TestAllTypesLite& message);
+  static void ExpectRepeatedExtensionsModified(
+      const unittest::TestAllExtensionsLite& message);
+  static void ExpectPackedFieldsModified(
+      const unittest::TestPackedTypesLite& message);
+  static void ExpectPackedExtensionsModified(
+      const unittest::TestPackedExtensionsLite& message);
+
+  // Check that all fields have their default values.
+  static void ExpectClear(const unittest::TestAllTypesLite& message);
+  static void ExpectExtensionsClear(
+      const unittest::TestAllExtensionsLite& message);
+  static void ExpectPackedClear(const unittest::TestPackedTypesLite& message);
+  static void ExpectPackedExtensionsClear(
+      const unittest::TestPackedExtensionsLite& message);
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TestUtilLite);
+};
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_TEST_UTIL_LITE_H__
diff --git a/protobuf/src/google/protobuf/testdata/bad_utf8_string b/protobuf/src/google/protobuf/testdata/bad_utf8_string
new file mode 100644
index 0000000..a1337ec
--- /dev/null
+++ b/protobuf/src/google/protobuf/testdata/bad_utf8_string
@@ -0,0 +1 @@
+rÿ
\ No newline at end of file
diff --git a/protobuf/src/google/protobuf/testdata/golden_message b/protobuf/src/google/protobuf/testdata/golden_message
new file mode 100644
index 0000000..0b7e655
--- /dev/null
+++ b/protobuf/src/google/protobuf/testdata/golden_message
Binary files differ
diff --git a/protobuf/src/google/protobuf/testdata/golden_message_oneof_implemented b/protobuf/src/google/protobuf/testdata/golden_message_oneof_implemented
new file mode 100644
index 0000000..b48c898
--- /dev/null
+++ b/protobuf/src/google/protobuf/testdata/golden_message_oneof_implemented
Binary files differ
diff --git a/protobuf/src/google/protobuf/testdata/golden_packed_fields_message b/protobuf/src/google/protobuf/testdata/golden_packed_fields_message
new file mode 100644
index 0000000..ee28d38
--- /dev/null
+++ b/protobuf/src/google/protobuf/testdata/golden_packed_fields_message
Binary files differ
diff --git a/protobuf/src/google/protobuf/testdata/text_format_unittest_data.txt b/protobuf/src/google/protobuf/testdata/text_format_unittest_data.txt
new file mode 100644
index 0000000..7a874b5
--- /dev/null
+++ b/protobuf/src/google/protobuf/testdata/text_format_unittest_data.txt
@@ -0,0 +1,134 @@
+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"
+optional_public_import_message {
+  e: 126
+}
+optional_lazy_message {
+  bb: 127
+}
+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"
+repeated_lazy_message {
+  bb: 227
+}
+repeated_lazy_message {
+  bb: 327
+}
+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"
+oneof_uint32: 601
+oneof_nested_message {
+  bb: 602
+}
+oneof_string: "603"
+oneof_bytes: "604"
diff --git a/protobuf/src/google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt b/protobuf/src/google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt
new file mode 100644
index 0000000..ec95e1e
--- /dev/null
+++ b/protobuf/src/google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt
@@ -0,0 +1,129 @@
+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"
+optional_public_import_message {
+  e: 126
+}
+optional_lazy_message {
+  bb: 127
+}
+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"
+repeated_lazy_message {
+  bb: 227
+}
+repeated_lazy_message {
+  bb: 327
+}
+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"
+oneof_bytes: "604"
diff --git a/protobuf/src/google/protobuf/testdata/text_format_unittest_data_pointy.txt b/protobuf/src/google/protobuf/testdata/text_format_unittest_data_pointy.txt
new file mode 100644
index 0000000..e1011eb
--- /dev/null
+++ b/protobuf/src/google/protobuf/testdata/text_format_unittest_data_pointy.txt
@@ -0,0 +1,134 @@
+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"
+optional_public_import_message <
+  e: 126
+>
+optional_lazy_message <
+  bb: 127
+>
+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"
+repeated_lazy_message <
+  bb: 227
+>
+repeated_lazy_message <
+  bb: 327
+>
+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"
+oneof_uint32: 601
+oneof_nested_message <
+  bb: 602
+>
+oneof_string: "603"
+oneof_bytes: "604"
diff --git a/protobuf/src/google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt b/protobuf/src/google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt
new file mode 100644
index 0000000..95109f6
--- /dev/null
+++ b/protobuf/src/google/protobuf/testdata/text_format_unittest_data_pointy_oneof.txt
@@ -0,0 +1,129 @@
+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"
+optional_public_import_message <
+  e: 126
+>
+optional_lazy_message <
+  bb: 127
+>
+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"
+repeated_lazy_message <
+  bb: 227
+>
+repeated_lazy_message <
+  bb: 327
+>
+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"
+oneof_bytes: "604"
diff --git a/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt b/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt
new file mode 100644
index 0000000..8c8b1eb
--- /dev/null
+++ b/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data.txt
@@ -0,0 +1,134 @@
+[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.optional_public_import_message_extension] {
+  e: 126
+}
+[protobuf_unittest.optional_lazy_message_extension] {
+  bb: 127
+}
+[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.repeated_lazy_message_extension] {
+  bb: 227
+}
+[protobuf_unittest.repeated_lazy_message_extension] {
+  bb: 327
+}
+[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"
+[protobuf_unittest.oneof_uint32_extension]: 601
+[protobuf_unittest.oneof_nested_message_extension] {
+  bb: 602
+}
+[protobuf_unittest.oneof_string_extension]: "603"
+[protobuf_unittest.oneof_bytes_extension]: "604"
diff --git a/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt b/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt
new file mode 100644
index 0000000..132f744
--- /dev/null
+++ b/protobuf/src/google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt
@@ -0,0 +1,134 @@
+[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.optional_public_import_message_extension] <
+  e: 126
+>
+[protobuf_unittest.optional_lazy_message_extension] <
+  bb: 127
+>
+[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.repeated_lazy_message_extension] <
+  bb: 227
+>
+[protobuf_unittest.repeated_lazy_message_extension] <
+  bb: 327
+>
+[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"
+[protobuf_unittest.oneof_uint32_extension]: 601
+[protobuf_unittest.oneof_nested_message_extension] <
+  bb: 602
+>
+[protobuf_unittest.oneof_string_extension]: "603"
+[protobuf_unittest.oneof_bytes_extension]: "604"
diff --git a/protobuf/src/google/protobuf/testing/file.cc b/protobuf/src/google/protobuf/testing/file.cc
new file mode 100644
index 0000000..20e01a1
--- /dev/null
+++ b/protobuf/src/google/protobuf/testing/file.cc
@@ -0,0 +1,194 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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;
+}
+
+bool File::WriteStringToFile(const string& contents, const string& name) {
+  FILE* file = fopen(name.c_str(), "wb");
+  if (file == NULL) {
+    GOOGLE_LOG(ERROR) << "fopen(" << name << ", \"wb\"): " << strerror(errno);
+    return false;
+  }
+
+  if (fwrite(contents.data(), 1, contents.size(), file) != contents.size()) {
+    GOOGLE_LOG(ERROR) << "fwrite(" << name << "): " << strerror(errno);
+    return false;
+  }
+
+  if (fclose(file) != 0) {
+    return false;
+  }
+  return true;
+}
+
+void File::WriteStringToFileOrDie(const string& contents, const string& name) {
+  FILE* file = fopen(name.c_str(), "wb");
+  GOOGLE_CHECK(file != NULL)
+      << "fopen(" << name << ", \"wb\"): " << strerror(errno);
+  GOOGLE_CHECK_EQ(fwrite(contents.data(), 1, contents.size(), file),
+                  contents.size())
+      << "fwrite(" << name << "): " << strerror(errno);
+  GOOGLE_CHECK(fclose(file) == 0)
+      << "fclose(" << name << "): " << strerror(errno);
+}
+
+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;
+
+  if (Exists(path)) return false;
+
+  // Try creating the parent.
+  string::size_type slashpos = path.find_last_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/protobuf/src/google/protobuf/testing/file.h b/protobuf/src/google/protobuf/testing/file.h
new file mode 100644
index 0000000..d2aeabf
--- /dev/null
+++ b/protobuf/src/google/protobuf/testing/file.h
@@ -0,0 +1,97 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 bool WriteStringToFile(const string& contents,
+                                const string& name);
+
+  // Same as above, but crash on failure.
+  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);
+
+  static bool GetContents(
+      const string& name, string* output, bool /*is_default*/) {
+    return ReadFileToString(name, output);
+  }
+
+  static bool SetContents(
+      const string& name, const string& contents, bool /*is_default*/) {
+    return WriteStringToFile(contents, name);
+  }
+
+ private:
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(File);
+};
+
+}  // namespace protobuf
+}  // namespace google
+
+#endif  // GOOGLE_PROTOBUF_TESTING_FILE_H__
diff --git a/protobuf/src/google/protobuf/testing/googletest.cc b/protobuf/src/google/protobuf/testing/googletest.cc
new file mode 100644
index 0000000..d72fa5c
--- /dev/null
+++ b/protobuf/src/google/protobuf/testing/googletest.cc
@@ -0,0 +1,255 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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>
+#include <iostream>
+#include <fstream>
+
+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.
+  char b[L_tmpnam + 1];     // HPUX multithread return 0 if s is 0
+  string result = tmpnam(b);
+#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();
+}
+
+// TODO(kenton):  Share duplicated code below.  Too busy/lazy for now.
+
+static string stdout_capture_filename_;
+static string stderr_capture_filename_;
+static int original_stdout_ = -1;
+static int original_stderr_ = -1;
+
+void CaptureTestStdout() {
+  GOOGLE_CHECK_EQ(original_stdout_, -1) << "Already capturing.";
+
+  stdout_capture_filename_ = TestTempDir() + "/captured_stdout";
+
+  int fd = open(stdout_capture_filename_.c_str(),
+                O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777);
+  GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno);
+
+  original_stdout_ = dup(1);
+  close(1);
+  dup2(fd, 1);
+  close(fd);
+}
+
+void CaptureTestStderr() {
+  GOOGLE_CHECK_EQ(original_stderr_, -1) << "Already capturing.";
+
+  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 GetCapturedTestStdout() {
+  GOOGLE_CHECK_NE(original_stdout_, -1) << "Not capturing.";
+
+  close(1);
+  dup2(original_stdout_, 1);
+  original_stdout_ = -1;
+
+  string result;
+  File::ReadFileToStringOrDie(stdout_capture_filename_, &result);
+
+  remove(stdout_capture_filename_.c_str());
+
+  return result;
+}
+
+string GetCapturedTestStderr() {
+  GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing.";
+
+  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 level) {
+  GOOGLE_CHECK(level == ERROR ||
+               level == WARNING);
+  return messages_[level];
+}
+
+void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename,
+                                int line, const string& message) {
+  GOOGLE_CHECK(active_log_ != NULL);
+  if (level == ERROR || level == WARNING) {
+    active_log_->messages_[level].push_back(message);
+  }
+}
+
+namespace {
+
+// Force shutdown at process exit so that we can test for memory leaks.  To
+// actually check for leaks, I suggest using the heap checker included with
+// google-perftools.  Set it to "draconian" mode to ensure that every last
+// call to malloc() has a corresponding free().
+struct ForceShutdown {
+  ~ForceShutdown() {
+    ShutdownProtobufLibrary();
+  }
+} force_shutdown;
+
+}  // namespace
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/testing/googletest.h b/protobuf/src/google/protobuf/testing/googletest.h
new file mode 100644
index 0000000..c0d99e6
--- /dev/null
+++ b/protobuf/src/google/protobuf/testing/googletest.h
@@ -0,0 +1,102 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// emulates google3/testing/base/public/googletest.h
+
+#ifndef GOOGLE_PROTOBUF_GOOGLETEST_H__
+#define GOOGLE_PROTOBUF_GOOGLETEST_H__
+
+#include <map>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+// Disable death tests if we use exceptions in CHECK().
+#if !PROTOBUF_USE_EXCEPTIONS && defined(GTEST_HAS_DEATH_TEST)
+#define PROTOBUF_HAS_DEATH_TEST
+#endif
+
+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 stdout or stderr.
+void CaptureTestStdout();
+void CaptureTestStderr();
+
+// Stop capturing stdout or stderr and return the text captured.
+string GetCapturedTestStdout();
+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.
+#undef ERROR  // defend against promiscuous windows.h
+static const LogLevel ERROR = LOGLEVEL_ERROR;
+static const LogLevel WARNING = LOGLEVEL_WARNING;
+
+// 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 with the given severity level.
+  const vector<string>& GetMessages(LogLevel error);
+
+ private:
+  map<LogLevel, 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/protobuf/src/google/protobuf/testing/zcgunzip.cc b/protobuf/src/google/protobuf/testing/zcgunzip.cc
new file mode 100644
index 0000000..daf74ff
--- /dev/null
+++ b/protobuf/src/google/protobuf/testing/zcgunzip.cc
@@ -0,0 +1,73 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2009 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: brianolson@google.com (Brian Olson)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Test program to verify that GzipInputStream is compatible with command line
+// gunzip or java.util.zip.GzipInputStream
+//
+// Reads gzip stream on standard input and writes decompressed data to standard
+// output.
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include <google/protobuf/io/gzip_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+using google::protobuf::io::FileInputStream;
+using google::protobuf::io::GzipInputStream;
+
+int main(int argc, const char** argv) {
+  FileInputStream fin(STDIN_FILENO);
+  GzipInputStream in(&fin);
+
+  while (true) {
+    const void* inptr;
+    int inlen;
+    bool ok;
+    ok = in.Next(&inptr, &inlen);
+    if (!ok) {
+      break;
+    }
+    if (inlen > 0) {
+      int err = write(STDOUT_FILENO, inptr, inlen);
+      assert(err == inlen);
+    }
+  }
+
+  return 0;
+}
diff --git a/protobuf/src/google/protobuf/testing/zcgzip.cc b/protobuf/src/google/protobuf/testing/zcgzip.cc
new file mode 100644
index 0000000..a410199
--- /dev/null
+++ b/protobuf/src/google/protobuf/testing/zcgzip.cc
@@ -0,0 +1,79 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2009 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: brianolson@google.com (Brian Olson)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// Test program to verify that GzipOutputStream is compatible with command line
+// gzip or java.util.zip.GzipOutputStream
+//
+// Reads data on standard input and writes compressed gzip stream to standard
+// output.
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include <google/protobuf/io/gzip_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+
+using google::protobuf::io::FileOutputStream;
+using google::protobuf::io::GzipOutputStream;
+
+int main(int argc, const char** argv) {
+  FileOutputStream fout(STDOUT_FILENO);
+  GzipOutputStream out(&fout);
+  int readlen;
+
+  while (true) {
+    void* outptr;
+    int outlen;
+    bool ok;
+    do {
+      ok = out.Next(&outptr, &outlen);
+      if (!ok) {
+        break;
+      }
+    } while (outlen <= 0);
+    readlen = read(STDIN_FILENO, outptr, outlen);
+    if (readlen <= 0) {
+      out.BackUp(outlen);
+      break;
+    }
+    if (readlen < outlen) {
+      out.BackUp(outlen - readlen);
+    }
+  }
+
+  return 0;
+}
diff --git a/protobuf/src/google/protobuf/text_format.cc b/protobuf/src/google/protobuf/text_format.cc
new file mode 100644
index 0000000..84cdbb5
--- /dev/null
+++ b/protobuf/src/google/protobuf/text_format.cc
@@ -0,0 +1,1746 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: jschorr@google.com (Joseph Schorr)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <algorithm>
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+#include <stack>
+#include <limits>
+#include <vector>
+
+#include <google/protobuf/text_format.h>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/wire_format_lite.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>
+#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+
+namespace {
+
+inline bool IsHexNumber(const string& str) {
+  return (str.length() >= 2 && str[0] == '0' &&
+          (str[1] == 'x' || str[1] == 'X'));
+}
+
+inline bool IsOctNumber(const string& str) {
+  return (str.length() >= 2 && str[0] == '0' &&
+          (str[1] >= '0' && str[1] < '8'));
+}
+
+}  // namespace
+
+string Message::DebugString() const {
+  string debug_string;
+
+  TextFormat::PrintToString(*this, &debug_string);
+
+  return debug_string;
+}
+
+string Message::ShortDebugString() const {
+  string debug_string;
+
+  TextFormat::Printer printer;
+  printer.SetSingleLineMode(true);
+
+  printer.PrintToString(*this, &debug_string);
+  // Single line mode currently might have an extra space at the end.
+  if (debug_string.size() > 0 &&
+      debug_string[debug_string.size() - 1] == ' ') {
+    debug_string.resize(debug_string.size() - 1);
+  }
+
+  return debug_string;
+}
+
+string Message::Utf8DebugString() const {
+  string debug_string;
+
+  TextFormat::Printer printer;
+  printer.SetUseUtf8StringEscaping(true);
+
+  printer.PrintToString(*this, &debug_string);
+
+  return debug_string;
+}
+
+void Message::PrintDebugString() const {
+  printf("%s", DebugString().c_str());
+}
+
+
+// ===========================================================================
+// Implementation of the parse information tree class.
+TextFormat::ParseInfoTree::ParseInfoTree() { }
+
+TextFormat::ParseInfoTree::~ParseInfoTree() {
+  // Remove any nested information trees, as they are owned by this tree.
+  for (NestedMap::iterator it = nested_.begin(); it != nested_.end(); ++it) {
+    STLDeleteElements(&(it->second));
+  }
+}
+
+void TextFormat::ParseInfoTree::RecordLocation(
+    const FieldDescriptor* field,
+    TextFormat::ParseLocation location) {
+  locations_[field].push_back(location);
+}
+
+TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested(
+    const FieldDescriptor* field) {
+  // Owned by us in the map.
+  TextFormat::ParseInfoTree* instance = new TextFormat::ParseInfoTree();
+  vector<TextFormat::ParseInfoTree*>* trees = &nested_[field];
+  GOOGLE_CHECK(trees);
+  trees->push_back(instance);
+  return instance;
+}
+
+void CheckFieldIndex(const FieldDescriptor* field, int index) {
+  if (field == NULL) { return; }
+
+  if (field->is_repeated() && index == -1) {
+    GOOGLE_LOG(DFATAL) << "Index must be in range of repeated field values. "
+                << "Field: " << field->name();
+  } else if (!field->is_repeated() && index != -1) {
+    GOOGLE_LOG(DFATAL) << "Index must be -1 for singular fields."
+                << "Field: " << field->name();
+  }
+}
+
+TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation(
+    const FieldDescriptor* field, int index) const {
+  CheckFieldIndex(field, index);
+  if (index == -1) { index = 0; }
+
+  const vector<TextFormat::ParseLocation>* locations =
+      FindOrNull(locations_, field);
+  if (locations == NULL || index >= locations->size()) {
+    return TextFormat::ParseLocation();
+  }
+
+  return (*locations)[index];
+}
+
+TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
+    const FieldDescriptor* field, int index) const {
+  CheckFieldIndex(field, index);
+  if (index == -1) { index = 0; }
+
+  const vector<TextFormat::ParseInfoTree*>* trees = FindOrNull(nested_, field);
+  if (trees == NULL || index >= trees->size()) {
+    return NULL;
+  }
+
+  return (*trees)[index];
+}
+
+
+// ===========================================================================
+// 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::Parser::ParserImpl {
+ public:
+
+  // Determines if repeated values for non-repeated fields and
+  // oneofs are permitted, e.g., the string "foo: 1 foo: 2" for a
+  // required/optional field named "foo", or "baz: 1 qux: 2"
+  // where "baz" and "qux" are members of the same oneof.
+  enum SingularOverwritePolicy {
+    ALLOW_SINGULAR_OVERWRITES = 0,   // the last value is retained
+    FORBID_SINGULAR_OVERWRITES = 1,  // an error is issued
+  };
+
+  ParserImpl(const Descriptor* root_message_type,
+             io::ZeroCopyInputStream* input_stream,
+             io::ErrorCollector* error_collector,
+             TextFormat::Finder* finder,
+             ParseInfoTree* parse_info_tree,
+             SingularOverwritePolicy singular_overwrite_policy,
+             bool allow_case_insensitive_field,
+             bool allow_unknown_field,
+             bool allow_unknown_enum,
+             bool allow_field_number,
+             bool allow_relaxed_whitespace)
+    : error_collector_(error_collector),
+      finder_(finder),
+      parse_info_tree_(parse_info_tree),
+      tokenizer_error_collector_(this),
+      tokenizer_(input_stream, &tokenizer_error_collector_),
+      root_message_type_(root_message_type),
+      singular_overwrite_policy_(singular_overwrite_policy),
+      allow_case_insensitive_field_(allow_case_insensitive_field),
+      allow_unknown_field_(allow_unknown_field),
+      allow_unknown_enum_(allow_unknown_enum),
+      allow_field_number_(allow_field_number),
+      had_errors_(false) {
+    // 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);
+
+    if (allow_relaxed_whitespace) {
+      tokenizer_.set_require_space_after_number(false);
+      tokenizer_.set_allow_multiline_strings(true);
+    }
+
+    // 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) {
+    // Consume fields until we cannot do so anymore.
+    while (true) {
+      if (LookingAtType(io::Tokenizer::TYPE_END)) {
+        return !had_errors_;
+      }
+
+      DO(ConsumeField(output));
+    }
+  }
+
+  bool ParseField(const FieldDescriptor* field, Message* output) {
+    bool suc;
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      suc = ConsumeFieldMessage(output, output->GetReflection(), field);
+    } else {
+      suc = ConsumeFieldValue(output, output->GetReflection(), field);
+    }
+    return suc && LookingAtType(io::Tokenizer::TYPE_END);
+  }
+
+  void ReportError(int line, int col, const string& message) {
+    had_errors_ = true;
+    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);
+    }
+  }
+
+  void ReportWarning(int line, int col, const string& message) {
+    if (error_collector_ == NULL) {
+      if (line >= 0) {
+        GOOGLE_LOG(WARNING) << "Warning parsing text-format "
+                     << root_message_type_->full_name()
+                     << ": " << (line + 1) << ":"
+                     << (col + 1) << ": " << message;
+      } else {
+        GOOGLE_LOG(WARNING) << "Warning parsing text-format "
+                     << root_message_type_->full_name()
+                     << ": " << message;
+      }
+    } else {
+      error_collector_->AddWarning(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);
+  }
+
+  // Reports a warning with the given message with information indicating
+  // the position (as derived from the current token).
+  void ReportWarning(const string& message) {
+    ReportWarning(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) {
+    while (!LookingAt(">") &&  !LookingAt("}")) {
+      DO(ConsumeField(message));
+    }
+
+    // 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* message) {
+    const Reflection* reflection = message->GetReflection();
+    const Descriptor* descriptor = message->GetDescriptor();
+
+    string field_name;
+
+    const FieldDescriptor* field = NULL;
+    int start_line = tokenizer_.current().line;
+    int start_column = tokenizer_.current().column;
+
+    if (TryConsume("[")) {
+      // Extension.
+      DO(ConsumeIdentifier(&field_name));
+      while (TryConsume(".")) {
+        string part;
+        DO(ConsumeIdentifier(&part));
+        field_name += ".";
+        field_name += part;
+      }
+      DO(Consume("]"));
+
+      field = (finder_ != NULL
+               ? finder_->FindExtension(message, field_name)
+               : reflection->FindKnownExtensionByName(field_name));
+
+      if (field == NULL) {
+        if (!allow_unknown_field_) {
+          ReportError("Extension \"" + field_name + "\" is not defined or "
+                      "is not an extension of \"" +
+                      descriptor->full_name() + "\".");
+          return false;
+        } else {
+          ReportWarning("Extension \"" + field_name + "\" is not defined or "
+                        "is not an extension of \"" +
+                        descriptor->full_name() + "\".");
+        }
+      }
+    } else {
+      DO(ConsumeIdentifier(&field_name));
+
+      int32 field_number;
+      if (allow_field_number_ && safe_strto32(field_name, &field_number)) {
+        if (descriptor->IsExtensionNumber(field_number)) {
+          field = reflection->FindKnownExtensionByNumber(field_number);
+        } else {
+          field = descriptor->FindFieldByNumber(field_number);
+        }
+      } else {
+        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 && allow_case_insensitive_field_) {
+          string lower_field_name = field_name;
+          LowerString(&lower_field_name);
+          field = descriptor->FindFieldByLowercaseName(lower_field_name);
+        }
+      }
+
+      if (field == NULL) {
+        if (!allow_unknown_field_) {
+          ReportError("Message type \"" + descriptor->full_name() +
+                      "\" has no field named \"" + field_name + "\".");
+          return false;
+        } else {
+          ReportWarning("Message type \"" + descriptor->full_name() +
+                        "\" has no field named \"" + field_name + "\".");
+        }
+      }
+    }
+
+    // Skips unknown field.
+    if (field == NULL) {
+      GOOGLE_CHECK(allow_unknown_field_);
+      // Try to guess the type of this field.
+      // If this field is not a message, there should be a ":" between the
+      // field name and the field value and also the field value should not
+      // start with "{" or "<" which indicates the begining of a message body.
+      // If there is no ":" or there is a "{" or "<" after ":", this field has
+      // to be a message or the input is ill-formed.
+      if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
+        return SkipFieldValue();
+      } else {
+        return SkipFieldMessage();
+      }
+    }
+
+    if (singular_overwrite_policy_ == FORBID_SINGULAR_OVERWRITES) {
+      // Fail if the field is not repeated and it has already been specified.
+      if (!field->is_repeated() && reflection->HasField(*message, field)) {
+        ReportError("Non-repeated field \"" + field_name +
+                    "\" is specified multiple times.");
+        return false;
+      }
+      // Fail if the field is a member of a oneof and another member has already
+      // been specified.
+      const OneofDescriptor* oneof = field->containing_oneof();
+      if (oneof != NULL && reflection->HasOneof(*message, oneof)) {
+        const FieldDescriptor* other_field =
+            reflection->GetOneofFieldDescriptor(*message, oneof);
+        ReportError("Field \"" + field_name + "\" is specified along with "
+                    "field \"" + other_field->name() + "\", another member "
+                    "of oneof \"" + oneof->name() + "\".");
+        return false;
+      }
+    }
+
+    // Perform special handling for embedded message types.
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      // ':' is optional here.
+      TryConsume(":");
+    } else {
+      // ':' is required here.
+      DO(Consume(":"));
+    }
+
+    if (field->is_repeated() && TryConsume("[")) {
+      // Short repeated format, e.g.  "foo: [1, 2, 3]"
+      while (true) {
+        if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+          // Perform special handling for embedded message types.
+          DO(ConsumeFieldMessage(message, reflection, field));
+        } else {
+          DO(ConsumeFieldValue(message, reflection, field));
+        }
+        if (TryConsume("]")) {
+          break;
+        }
+        DO(Consume(","));
+      }
+    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      DO(ConsumeFieldMessage(message, reflection, field));
+    } else {
+      DO(ConsumeFieldValue(message, reflection, field));
+    }
+
+    // For historical reasons, fields may optionally be separated by commas or
+    // semicolons.
+    TryConsume(";") || TryConsume(",");
+
+    if (field->options().deprecated()) {
+      ReportWarning("text format contains deprecated field \""
+                    + field_name + "\"");
+    }
+
+    // If a parse info tree exists, add the location for the parsed
+    // field.
+    if (parse_info_tree_ != NULL) {
+      RecordLocation(parse_info_tree_, field,
+                     ParseLocation(start_line, start_column));
+    }
+
+    return true;
+  }
+
+  // Skips the next field including the field's name and value.
+  bool SkipField() {
+    string field_name;
+    if (TryConsume("[")) {
+      // Extension name.
+      DO(ConsumeIdentifier(&field_name));
+      while (TryConsume(".")) {
+        string part;
+        DO(ConsumeIdentifier(&part));
+        field_name += ".";
+        field_name += part;
+      }
+      DO(Consume("]"));
+    } else {
+      DO(ConsumeIdentifier(&field_name));
+    }
+
+    // Try to guess the type of this field.
+    // If this field is not a message, there should be a ":" between the
+    // field name and the field value and also the field value should not
+    // start with "{" or "<" which indicates the begining of a message body.
+    // If there is no ":" or there is a "{" or "<" after ":", this field has
+    // to be a message or the input is ill-formed.
+    if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
+      DO(SkipFieldValue());
+    } else {
+      DO(SkipFieldMessage());
+    }
+    // For historical reasons, fields may optionally be separated by commas or
+    // semicolons.
+    TryConsume(";") || TryConsume(",");
+    return true;
+  }
+
+  bool ConsumeFieldMessage(Message* message,
+                           const Reflection* reflection,
+                           const FieldDescriptor* field) {
+
+    // If the parse information tree is not NULL, create a nested one
+    // for the nested message.
+    ParseInfoTree* parent = parse_info_tree_;
+    if (parent != NULL) {
+      parse_info_tree_ = CreateNested(parent, field);
+    }
+
+    string delimeter;
+    if (TryConsume("<")) {
+      delimeter = ">";
+    } else {
+      DO(Consume("{"));
+      delimeter = "}";
+    }
+
+    if (field->is_repeated()) {
+      DO(ConsumeMessage(reflection->AddMessage(message, field), delimeter));
+    } else {
+      DO(ConsumeMessage(reflection->MutableMessage(message, field),
+                        delimeter));
+    }
+
+    // Reset the parse information tree.
+    parse_info_tree_ = parent;
+    return true;
+  }
+
+  // Skips the whole body of a message including the begining delimeter and
+  // the ending delimeter.
+  bool SkipFieldMessage() {
+    string delimeter;
+    if (TryConsume("<")) {
+      delimeter = ">";
+    } else {
+      DO(Consume("{"));
+      delimeter = "}";
+    }
+    while (!LookingAt(">") &&  !LookingAt("}")) {
+      DO(SkipField());
+    }
+    DO(Consume(delimeter));
+    return true;
+  }
+
+  bool ConsumeFieldValue(Message* message,
+                         const 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(message, field, VALUE);         \
+        } else {                                                   \
+          reflection->Set##CPPTYPE(message, 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: {
+        if (LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+          uint64 value;
+          DO(ConsumeUnsignedInteger(&value, 1));
+          SET_FIELD(Bool, value);
+        } else {
+          string value;
+          DO(ConsumeIdentifier(&value));
+          if (value == "true" || value == "True" || value == "t") {
+            SET_FIELD(Bool, true);
+          } else if (value == "false" || value == "False" || value == "f") {
+            SET_FIELD(Bool, false);
+          } else {
+            ReportError("Invalid value for boolean field \"" + field->name()
+                        + "\". Value: \"" + value  + "\".");
+            return false;
+          }
+        }
+        break;
+      }
+
+      case FieldDescriptor::CPPTYPE_ENUM: {
+        string value;
+        const EnumDescriptor* enum_type = field->enum_type();
+        const EnumValueDescriptor* enum_value = NULL;
+
+        if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+          DO(ConsumeIdentifier(&value));
+          // Find the enumeration value.
+          enum_value = enum_type->FindValueByName(value);
+
+        } else if (LookingAt("-") ||
+                   LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+          int64 int_value;
+          DO(ConsumeSignedInteger(&int_value, kint32max));
+          value = SimpleItoa(int_value);        // for error reporting
+          enum_value = enum_type->FindValueByNumber(int_value);
+        } else {
+          ReportError("Expected integer or identifier.");
+          return false;
+        }
+
+        if (enum_value == NULL) {
+          if (!allow_unknown_enum_) {
+            ReportError("Unknown enumeration value of \"" + value  + "\" for "
+                        "field \"" + field->name() + "\".");
+            return false;
+          } else {
+            ReportWarning("Unknown enumeration value of \"" + value  + "\" for "
+                          "field \"" + field->name() + "\".");
+            return true;
+          }
+        }
+
+        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;
+  }
+
+  bool SkipFieldValue() {
+    if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+      while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+        tokenizer_.Next();
+      }
+      return true;
+    }
+    // Possible field values other than string:
+    //   12345        => TYPE_INTEGER
+    //   -12345       => TYPE_SYMBOL + TYPE_INTEGER
+    //   1.2345       => TYPE_FLOAT
+    //   -1.2345      => TYPE_SYMBOL + TYPE_FLOAT
+    //   inf          => TYPE_IDENTIFIER
+    //   -inf         => TYPE_SYMBOL + TYPE_IDENTIFIER
+    //   TYPE_INTEGER => TYPE_IDENTIFIER
+    // Divides them into two group, one with TYPE_SYMBOL
+    // and the other without:
+    //   Group one:
+    //     12345        => TYPE_INTEGER
+    //     1.2345       => TYPE_FLOAT
+    //     inf          => TYPE_IDENTIFIER
+    //     TYPE_INTEGER => TYPE_IDENTIFIER
+    //   Group two:
+    //     -12345       => TYPE_SYMBOL + TYPE_INTEGER
+    //     -1.2345      => TYPE_SYMBOL + TYPE_FLOAT
+    //     -inf         => TYPE_SYMBOL + TYPE_IDENTIFIER
+    // As we can see, the field value consists of an optional '-' and one of
+    // TYPE_INTEGER, TYPE_FLOAT and TYPE_IDENTIFIER.
+    bool has_minus = TryConsume("-");
+    if (!LookingAtType(io::Tokenizer::TYPE_INTEGER) &&
+        !LookingAtType(io::Tokenizer::TYPE_FLOAT) &&
+        !LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+      return false;
+    }
+    // Combination of '-' and TYPE_IDENTIFIER may result in an invalid field
+    // value while other combinations all generate valid values.
+    // We check if the value of this combination is valid here.
+    // TYPE_IDENTIFIER after a '-' should be one of the float values listed
+    // below:
+    //   inf, inff, infinity, nan
+    if (has_minus && LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
+      string text = tokenizer_.current().text;
+      LowerString(&text);
+      if (text != "inf" &&
+          text != "infinity" &&
+          text != "nan") {
+        ReportError("Invalid float number: " + text);
+        return false;
+      }
+    }
+    tokenizer_.Next();
+    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)) {
+      *identifier = tokenizer_.current().text;
+      tokenizer_.Next();
+      return true;
+    }
+
+    // If allow_field_numer_ or allow_unknown_field_ is true, we should able
+    // to parse integer identifiers.
+    if ((allow_field_number_ || allow_unknown_field_)
+        && LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+      *identifier = tokenizer_.current().text;
+      tokenizer_.Next();
+      return true;
+    }
+
+    ReportError("Expected identifier.");
+    return false;
+  }
+
+  // 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;
+    }
+
+    text->clear();
+    while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
+      io::Tokenizer::ParseStringAppend(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 uint64 and saves its value in the value parameter.
+  // Accepts decimal numbers only, rejects hex or oct numbers.
+  bool ConsumeUnsignedDecimalInteger(uint64* value, uint64 max_value) {
+    if (!LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
+      ReportError("Expected integer.");
+      return false;
+    }
+
+    const string& text = tokenizer_.current().text;
+    if (IsHexNumber(text) || IsOctNumber(text)) {
+      ReportError("Expect a decimal number.");
+      return false;
+    }
+
+    if (!io::Tokenizer::ParseInteger(text, max_value, value)) {
+      ReportError("Integer out of range.");
+      return false;
+    }
+
+    tokenizer_.Next();
+    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(ConsumeUnsignedDecimalInteger(&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::Parser::ParserImpl* parser) :
+        parser_(parser) { }
+
+    virtual ~ParserErrorCollector() { }
+
+    virtual void AddError(int line, int column, const string& message) {
+      parser_->ReportError(line, column, message);
+    }
+
+    virtual void AddWarning(int line, int column, const string& message) {
+      parser_->ReportWarning(line, column, message);
+    }
+
+   private:
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParserErrorCollector);
+    TextFormat::Parser::ParserImpl* parser_;
+  };
+
+  io::ErrorCollector* error_collector_;
+  TextFormat::Finder* finder_;
+  ParseInfoTree* parse_info_tree_;
+  ParserErrorCollector tokenizer_error_collector_;
+  io::Tokenizer tokenizer_;
+  const Descriptor* root_message_type_;
+  SingularOverwritePolicy singular_overwrite_policy_;
+  const bool allow_case_insensitive_field_;
+  const bool allow_unknown_field_;
+  const bool allow_unknown_enum_;
+  const bool allow_field_number_;
+  bool had_errors_;
+};
+
+#undef DO
+
+// ===========================================================================
+// Internal class for writing text to the io::ZeroCopyOutputStream. Adapted
+// from the Printer found in //google/protobuf/io/printer.h
+class TextFormat::Printer::TextGenerator {
+ public:
+  explicit TextGenerator(io::ZeroCopyOutputStream* output,
+                         int initial_indent_level)
+    : output_(output),
+      buffer_(NULL),
+      buffer_size_(0),
+      at_start_of_line_(true),
+      failed_(false),
+      indent_(""),
+      initial_indent_level_(initial_indent_level) {
+    indent_.resize(initial_indent_level_ * 2, ' ');
+  }
+
+  ~TextGenerator() {
+    // Only BackUp() if we're sure we've successfully called Next() at least
+    // once.
+    if (!failed_ && 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() ||
+        indent_.size() < initial_indent_level_ * 2) {
+      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.data(), str.size());
+  }
+
+  // Print text to the output stream.
+  void Print(const char* text) {
+    Print(text, strlen(text));
+  }
+
+  // Print text to the output stream.
+  void Print(const char* text, int size) {
+    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_;
+  int initial_indent_level_;
+};
+
+// ===========================================================================
+
+TextFormat::Finder::~Finder() {
+}
+
+TextFormat::Parser::Parser()
+  : error_collector_(NULL),
+    finder_(NULL),
+    parse_info_tree_(NULL),
+    allow_partial_(false),
+    allow_case_insensitive_field_(false),
+    allow_unknown_field_(false),
+    allow_unknown_enum_(false),
+    allow_field_number_(false),
+    allow_relaxed_whitespace_(false),
+    allow_singular_overwrites_(false) {
+}
+
+TextFormat::Parser::~Parser() {}
+
+bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
+                               Message* output) {
+  output->Clear();
+
+  ParserImpl::SingularOverwritePolicy overwrites_policy =
+      allow_singular_overwrites_
+      ? ParserImpl::ALLOW_SINGULAR_OVERWRITES
+      : ParserImpl::FORBID_SINGULAR_OVERWRITES;
+
+  ParserImpl parser(output->GetDescriptor(), input, error_collector_,
+                    finder_, parse_info_tree_,
+                    overwrites_policy,
+                    allow_case_insensitive_field_, allow_unknown_field_,
+                    allow_unknown_enum_, allow_field_number_,
+                    allow_relaxed_whitespace_);
+  return MergeUsingImpl(input, output, &parser);
+}
+
+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(output->GetDescriptor(), input, error_collector_,
+                    finder_, parse_info_tree_,
+                    ParserImpl::ALLOW_SINGULAR_OVERWRITES,
+                    allow_case_insensitive_field_, allow_unknown_field_,
+                    allow_unknown_enum_, allow_field_number_,
+                    allow_relaxed_whitespace_);
+  return MergeUsingImpl(input, output, &parser);
+}
+
+bool TextFormat::Parser::MergeFromString(const string& input,
+                                         Message* output) {
+  io::ArrayInputStream input_stream(input.data(), input.size());
+  return Merge(&input_stream, output);
+}
+
+bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */,
+                                        Message* output,
+                                        ParserImpl* parser_impl) {
+  if (!parser_impl->Parse(output)) return false;
+  if (!allow_partial_ && !output->IsInitialized()) {
+    vector<string> missing_fields;
+    output->FindInitializationErrors(&missing_fields);
+    parser_impl->ReportError(-1, 0, "Message missing required fields: " +
+                                        Join(missing_fields, ", "));
+    return false;
+  }
+  return true;
+}
+
+bool TextFormat::Parser::ParseFieldValueFromString(
+    const string& input,
+    const FieldDescriptor* field,
+    Message* output) {
+  io::ArrayInputStream input_stream(input.data(), input.size());
+  ParserImpl parser(output->GetDescriptor(), &input_stream, error_collector_,
+                    finder_, parse_info_tree_,
+                    ParserImpl::ALLOW_SINGULAR_OVERWRITES,
+                    allow_case_insensitive_field_, allow_unknown_field_,
+                    allow_unknown_enum_, allow_field_number_,
+                    allow_relaxed_whitespace_);
+  return parser.ParseField(field, 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);
+}
+
+// ===========================================================================
+
+// The default implementation for FieldValuePrinter. The base class just
+// does simple formatting. That way, deriving classes could decide to fallback
+// to that behavior.
+TextFormat::FieldValuePrinter::FieldValuePrinter() {}
+TextFormat::FieldValuePrinter::~FieldValuePrinter() {}
+string TextFormat::FieldValuePrinter::PrintBool(bool val) const {
+  return val ? "true" : "false";
+}
+string TextFormat::FieldValuePrinter::PrintInt32(int32 val) const {
+  return SimpleItoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintUInt32(uint32 val) const {
+  return SimpleItoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintInt64(int64 val) const {
+  return SimpleItoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintUInt64(uint64 val) const {
+  return SimpleItoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintFloat(float val) const {
+  return SimpleFtoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintDouble(double val) const {
+  return SimpleDtoa(val);
+}
+string TextFormat::FieldValuePrinter::PrintString(const string& val) const {
+  return StrCat("\"", CEscape(val), "\"");
+}
+string TextFormat::FieldValuePrinter::PrintBytes(const string& val) const {
+  return PrintString(val);
+}
+string TextFormat::FieldValuePrinter::PrintEnum(int32 val,
+                                                const string& name) const {
+  return name;
+}
+string TextFormat::FieldValuePrinter::PrintFieldName(
+    const Message& message,
+    const Reflection* reflection,
+    const FieldDescriptor* field) const {
+  if (field->is_extension()) {
+    // 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()) {
+      return StrCat("[", field->message_type()->full_name(), "]");
+    } else {
+      return StrCat("[", field->full_name(), "]");
+    }
+  } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
+    // Groups must be serialized with their original capitalization.
+    return field->message_type()->name();
+  } else {
+    return field->name();
+  }
+}
+string TextFormat::FieldValuePrinter::PrintMessageStart(
+    const Message& message,
+    int field_index,
+    int field_count,
+    bool single_line_mode) const {
+  return single_line_mode ? " { " : " {\n";
+}
+string TextFormat::FieldValuePrinter::PrintMessageEnd(
+    const Message& message,
+    int field_index,
+    int field_count,
+    bool single_line_mode) const {
+  return single_line_mode ? "} " : "}\n";
+}
+
+namespace {
+// Our own specialization: for UTF8 escaped strings.
+class FieldValuePrinterUtf8Escaping : public TextFormat::FieldValuePrinter {
+ public:
+  virtual string PrintString(const string& val) const {
+    return StrCat("\"", strings::Utf8SafeCEscape(val), "\"");
+  }
+  virtual string PrintBytes(const string& val) const {
+    return TextFormat::FieldValuePrinter::PrintString(val);
+  }
+};
+
+}  // namespace
+
+TextFormat::Printer::Printer()
+  : initial_indent_level_(0),
+    single_line_mode_(false),
+    use_field_number_(false),
+    use_short_repeated_primitives_(false),
+    hide_unknown_fields_(false),
+    print_message_fields_in_index_order_(false) {
+  SetUseUtf8StringEscaping(false);
+}
+
+TextFormat::Printer::~Printer() {
+  STLDeleteValues(&custom_printers_);
+}
+
+void TextFormat::Printer::SetUseUtf8StringEscaping(bool as_utf8) {
+  SetDefaultFieldValuePrinter(as_utf8
+                              ? new FieldValuePrinterUtf8Escaping()
+                              : new FieldValuePrinter());
+}
+
+void TextFormat::Printer::SetDefaultFieldValuePrinter(
+    const FieldValuePrinter* printer) {
+  default_field_value_printer_.reset(printer);
+}
+
+bool TextFormat::Printer::RegisterFieldValuePrinter(
+    const FieldDescriptor* field,
+    const FieldValuePrinter* printer) {
+  return field != NULL
+      && printer != NULL
+      && custom_printers_.insert(make_pair(field, printer)).second;
+}
+
+bool TextFormat::Printer::PrintToString(const Message& message,
+                                        string* output) const {
+  GOOGLE_DCHECK(output) << "output specified is NULL";
+
+  output->clear();
+  io::StringOutputStream output_stream(output);
+
+  return Print(message, &output_stream);
+}
+
+bool TextFormat::Printer::PrintUnknownFieldsToString(
+    const UnknownFieldSet& unknown_fields,
+    string* output) const {
+  GOOGLE_DCHECK(output) << "output specified is NULL";
+
+  output->clear();
+  io::StringOutputStream output_stream(output);
+  return PrintUnknownFields(unknown_fields, &output_stream);
+}
+
+bool TextFormat::Printer::Print(const Message& message,
+                                io::ZeroCopyOutputStream* output) const {
+  TextGenerator generator(output, initial_indent_level_);
+
+  Print(message, generator);
+
+  // Output false if the generator failed internally.
+  return !generator.failed();
+}
+
+bool TextFormat::Printer::PrintUnknownFields(
+    const UnknownFieldSet& unknown_fields,
+    io::ZeroCopyOutputStream* output) const {
+  TextGenerator generator(output, initial_indent_level_);
+
+  PrintUnknownFields(unknown_fields, generator);
+
+  // Output false if the generator failed internally.
+  return !generator.failed();
+}
+
+namespace {
+// Comparison functor for sorting FieldDescriptors by field index.
+struct FieldIndexSorter {
+  bool operator()(const FieldDescriptor* left,
+                  const FieldDescriptor* right) const {
+    return left->index() < right->index();
+  }
+};
+}  // namespace
+
+void TextFormat::Printer::Print(const Message& message,
+                                TextGenerator& generator) const {
+  const Reflection* reflection = message.GetReflection();
+  vector<const FieldDescriptor*> fields;
+  reflection->ListFields(message, &fields);
+  if (print_message_fields_in_index_order_) {
+    sort(fields.begin(), fields.end(), FieldIndexSorter());
+  }
+  for (int i = 0; i < fields.size(); i++) {
+    PrintField(message, reflection, fields[i], generator);
+  }
+  if (!hide_unknown_fields_) {
+    PrintUnknownFields(reflection->GetUnknownFields(message), generator);
+  }
+}
+
+void TextFormat::Printer::PrintFieldValueToString(
+    const Message& message,
+    const FieldDescriptor* field,
+    int index,
+    string* output) const {
+
+  GOOGLE_DCHECK(output) << "output specified is NULL";
+
+  output->clear();
+  io::StringOutputStream output_stream(output);
+  TextGenerator generator(&output_stream, initial_indent_level_);
+
+  PrintFieldValue(message, message.GetReflection(), field, index, generator);
+}
+
+void TextFormat::Printer::PrintField(const Message& message,
+                                     const Reflection* reflection,
+                                     const FieldDescriptor* field,
+                                     TextGenerator& generator) const {
+  if (use_short_repeated_primitives_ &&
+      field->is_repeated() &&
+      field->cpp_type() != FieldDescriptor::CPPTYPE_STRING &&
+      field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+    PrintShortRepeatedField(message, reflection, field, generator);
+    return;
+  }
+
+  int count = 0;
+
+  if (field->is_repeated()) {
+    count = reflection->FieldSize(message, field);
+  } else if (reflection->HasField(message, field)) {
+    count = 1;
+  }
+
+  for (int j = 0; j < count; ++j) {
+    const int field_index = field->is_repeated() ? j : -1;
+
+    PrintFieldName(message, reflection, field, generator);
+
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      const FieldValuePrinter* printer = FindWithDefault(
+          custom_printers_, field, default_field_value_printer_.get());
+      const Message& sub_message =
+              field->is_repeated()
+              ? reflection->GetRepeatedMessage(message, field, j)
+              : reflection->GetMessage(message, field);
+      generator.Print(
+          printer->PrintMessageStart(
+              sub_message, field_index, count, single_line_mode_));
+      generator.Indent();
+      Print(sub_message, generator);
+      generator.Outdent();
+      generator.Print(
+          printer->PrintMessageEnd(
+              sub_message, field_index, count, single_line_mode_));
+    } else {
+      generator.Print(": ");
+      // Write the field value.
+      PrintFieldValue(message, reflection, field, field_index, generator);
+      if (single_line_mode_) {
+        generator.Print(" ");
+      } else {
+        generator.Print("\n");
+      }
+    }
+  }
+}
+
+void TextFormat::Printer::PrintShortRepeatedField(
+    const Message& message,
+    const Reflection* reflection,
+    const FieldDescriptor* field,
+    TextGenerator& generator) const {
+  // Print primitive repeated field in short form.
+  PrintFieldName(message, reflection, field, generator);
+
+  int size = reflection->FieldSize(message, field);
+  generator.Print(": [");
+  for (int i = 0; i < size; i++) {
+    if (i > 0) generator.Print(", ");
+    PrintFieldValue(message, reflection, field, i, generator);
+  }
+  if (single_line_mode_) {
+    generator.Print("] ");
+  } else {
+    generator.Print("]\n");
+  }
+}
+
+void TextFormat::Printer::PrintFieldName(const Message& message,
+                                         const Reflection* reflection,
+                                         const FieldDescriptor* field,
+                                         TextGenerator& generator) const {
+  // if use_field_number_ is true, prints field number instead
+  // of field name.
+  if (use_field_number_) {
+    generator.Print(SimpleItoa(field->number()));
+    return;
+  }
+
+  const FieldValuePrinter* printer = FindWithDefault(
+      custom_printers_, field, default_field_value_printer_.get());
+  generator.Print(printer->PrintFieldName(message, reflection, field));
+}
+
+void TextFormat::Printer::PrintFieldValue(
+    const Message& message,
+    const Reflection* reflection,
+    const FieldDescriptor* field,
+    int index,
+    TextGenerator& generator) const {
+  GOOGLE_DCHECK(field->is_repeated() || (index == -1))
+      << "Index must be -1 for non-repeated fields";
+
+  const FieldValuePrinter* printer
+      = FindWithDefault(custom_printers_, field,
+                        default_field_value_printer_.get());
+
+  switch (field->cpp_type()) {
+#define OUTPUT_FIELD(CPPTYPE, METHOD)                                   \
+    case FieldDescriptor::CPPTYPE_##CPPTYPE:                            \
+      generator.Print(printer->Print##METHOD(field->is_repeated()       \
+               ? reflection->GetRepeated##METHOD(message, field, index) \
+               : reflection->Get##METHOD(message, field)));             \
+        break
+
+    OUTPUT_FIELD( INT32,  Int32);
+    OUTPUT_FIELD( INT64,  Int64);
+    OUTPUT_FIELD(UINT32, UInt32);
+    OUTPUT_FIELD(UINT64, UInt64);
+    OUTPUT_FIELD( FLOAT,  Float);
+    OUTPUT_FIELD(DOUBLE, Double);
+    OUTPUT_FIELD(  BOOL,   Bool);
+#undef OUTPUT_FIELD
+
+    case FieldDescriptor::CPPTYPE_STRING: {
+      string scratch;
+      const string& value = field->is_repeated()
+          ? reflection->GetRepeatedStringReference(
+              message, field, index, &scratch)
+          : reflection->GetStringReference(message, field, &scratch);
+      if (field->type() == FieldDescriptor::TYPE_STRING) {
+        generator.Print(printer->PrintString(value));
+      } else {
+        GOOGLE_DCHECK_EQ(field->type(), FieldDescriptor::TYPE_BYTES);
+        generator.Print(printer->PrintBytes(value));
+      }
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_ENUM: {
+      const EnumValueDescriptor *enum_val = field->is_repeated()
+          ? reflection->GetRepeatedEnum(message, field, index)
+          : reflection->GetEnum(message, field);
+      generator.Print(printer->PrintEnum(enum_val->number(), enum_val->name()));
+      break;
+    }
+
+    case FieldDescriptor::CPPTYPE_MESSAGE:
+      Print(field->is_repeated()
+            ? reflection->GetRepeatedMessage(message, field, index)
+            : reflection->GetMessage(message, field),
+            generator);
+      break;
+  }
+}
+
+/* static */ bool TextFormat::Print(const Message& message,
+                                    io::ZeroCopyOutputStream* output) {
+  return Printer().Print(message, output);
+}
+
+/* static */ bool TextFormat::PrintUnknownFields(
+    const UnknownFieldSet& unknown_fields,
+    io::ZeroCopyOutputStream* output) {
+  return Printer().PrintUnknownFields(unknown_fields, output);
+}
+
+/* static */ bool TextFormat::PrintToString(
+    const Message& message, string* output) {
+  return Printer().PrintToString(message, output);
+}
+
+/* static */ bool TextFormat::PrintUnknownFieldsToString(
+    const UnknownFieldSet& unknown_fields, string* output) {
+  return Printer().PrintUnknownFieldsToString(unknown_fields, output);
+}
+
+/* static */ void TextFormat::PrintFieldValueToString(
+    const Message& message,
+    const FieldDescriptor* field,
+    int index,
+    string* output) {
+  return Printer().PrintFieldValueToString(message, field, index, output);
+}
+
+/* static */ bool TextFormat::ParseFieldValueFromString(
+    const string& input,
+    const FieldDescriptor* field,
+    Message* message) {
+  return Parser().ParseFieldValueFromString(input, field, message);
+}
+
+// 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;
+}
+
+void TextFormat::Printer::PrintUnknownFields(
+    const UnknownFieldSet& unknown_fields, TextGenerator& generator) const {
+  for (int i = 0; i < unknown_fields.field_count(); i++) {
+    const UnknownField& field = unknown_fields.field(i);
+    string field_number = SimpleItoa(field.number());
+
+    switch (field.type()) {
+      case UnknownField::TYPE_VARINT:
+        generator.Print(field_number);
+        generator.Print(": ");
+        generator.Print(SimpleItoa(field.varint()));
+        if (single_line_mode_) {
+          generator.Print(" ");
+        } else {
+          generator.Print("\n");
+        }
+        break;
+      case UnknownField::TYPE_FIXED32: {
+        generator.Print(field_number);
+        generator.Print(": 0x");
+        char buffer[kFastToBufferSize];
+        generator.Print(FastHex32ToBuffer(field.fixed32(), buffer));
+        if (single_line_mode_) {
+          generator.Print(" ");
+        } else {
+          generator.Print("\n");
+        }
+        break;
+      }
+      case UnknownField::TYPE_FIXED64: {
+        generator.Print(field_number);
+        generator.Print(": 0x");
+        char buffer[kFastToBufferSize];
+        generator.Print(FastHex64ToBuffer(field.fixed64(), buffer));
+        if (single_line_mode_) {
+          generator.Print(" ");
+        } else {
+          generator.Print("\n");
+        }
+        break;
+      }
+      case UnknownField::TYPE_LENGTH_DELIMITED: {
+        generator.Print(field_number);
+        const string& value = field.length_delimited();
+        UnknownFieldSet embedded_unknown_fields;
+        if (!value.empty() && embedded_unknown_fields.ParseFromString(value)) {
+          // This field is parseable as a Message.
+          // So it is probably an embedded message.
+          if (single_line_mode_) {
+            generator.Print(" { ");
+          } else {
+            generator.Print(" {\n");
+            generator.Indent();
+          }
+          PrintUnknownFields(embedded_unknown_fields, generator);
+          if (single_line_mode_) {
+            generator.Print("} ");
+          } else {
+            generator.Outdent();
+            generator.Print("}\n");
+          }
+        } else {
+          // This field is not parseable as a Message.
+          // So it is probably just a plain string.
+          generator.Print(": \"");
+          generator.Print(CEscape(value));
+          generator.Print("\"");
+          if (single_line_mode_) {
+            generator.Print(" ");
+          } else {
+            generator.Print("\n");
+          }
+        }
+        break;
+      }
+      case UnknownField::TYPE_GROUP:
+        generator.Print(field_number);
+        if (single_line_mode_) {
+          generator.Print(" { ");
+        } else {
+          generator.Print(" {\n");
+          generator.Indent();
+        }
+        PrintUnknownFields(field.group(), generator);
+        if (single_line_mode_) {
+          generator.Print("} ");
+        } else {
+          generator.Outdent();
+          generator.Print("}\n");
+        }
+        break;
+    }
+  }
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/text_format.h b/protobuf/src/google/protobuf/text_format.h
new file mode 100644
index 0000000..2954941
--- /dev/null
+++ b/protobuf/src/google/protobuf/text_format.h
@@ -0,0 +1,473 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/message.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);
+
+  // Print the fields in an UnknownFieldSet.  They are printed by tag number
+  // only.  Embedded messages are heuristically identified by attempting to
+  // parse them.
+  static bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
+                                 io::ZeroCopyOutputStream* output);
+
+  // Like Print(), but outputs directly to a string.
+  static bool PrintToString(const Message& message, string* output);
+
+  // Like PrintUnknownFields(), but outputs directly to a string.
+  static bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
+                                         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);
+
+  // The default printer that converts scalar values from fields into
+  // their string representation.
+  // You can derive from this FieldValuePrinter if you want to have
+  // fields to be printed in a different way and register it at the
+  // Printer.
+  class LIBPROTOBUF_EXPORT FieldValuePrinter {
+   public:
+    FieldValuePrinter();
+    virtual ~FieldValuePrinter();
+    virtual string PrintBool(bool val) const;
+    virtual string PrintInt32(int32 val) const;
+    virtual string PrintUInt32(uint32 val) const;
+    virtual string PrintInt64(int64 val) const;
+    virtual string PrintUInt64(uint64 val) const;
+    virtual string PrintFloat(float val) const;
+    virtual string PrintDouble(double val) const;
+    virtual string PrintString(const string& val) const;
+    virtual string PrintBytes(const string& val) const;
+    virtual string PrintEnum(int32 val, const string& name) const;
+    virtual string PrintFieldName(const Message& message,
+                                  const Reflection* reflection,
+                                  const FieldDescriptor* field) const;
+    virtual string PrintMessageStart(const Message& message,
+                                     int field_index,
+                                     int field_count,
+                                     bool single_line_mode) const;
+    virtual string PrintMessageEnd(const Message& message,
+                                   int field_index,
+                                   int field_count,
+                                   bool single_line_mode) const;
+
+   private:
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldValuePrinter);
+  };
+
+  // Class for those users which require more fine-grained control over how
+  // a protobuffer message is printed out.
+  class LIBPROTOBUF_EXPORT Printer {
+   public:
+    Printer();
+    ~Printer();
+
+    // Like TextFormat::Print
+    bool Print(const Message& message, io::ZeroCopyOutputStream* output) const;
+    // Like TextFormat::PrintUnknownFields
+    bool PrintUnknownFields(const UnknownFieldSet& unknown_fields,
+                            io::ZeroCopyOutputStream* output) const;
+    // Like TextFormat::PrintToString
+    bool PrintToString(const Message& message, string* output) const;
+    // Like TextFormat::PrintUnknownFieldsToString
+    bool PrintUnknownFieldsToString(const UnknownFieldSet& unknown_fields,
+                                    string* output) const;
+    // Like TextFormat::PrintFieldValueToString
+    void PrintFieldValueToString(const Message& message,
+                                 const FieldDescriptor* field,
+                                 int index,
+                                 string* output) const;
+
+    // Adjust the initial indent level of all output.  Each indent level is
+    // equal to two spaces.
+    void SetInitialIndentLevel(int indent_level) {
+      initial_indent_level_ = indent_level;
+    }
+
+    // If printing in single line mode, then the entire message will be output
+    // on a single line with no line breaks.
+    void SetSingleLineMode(bool single_line_mode) {
+      single_line_mode_ = single_line_mode;
+    }
+
+    bool IsInSingleLineMode() {
+      return single_line_mode_;
+    }
+
+    // If use_field_number is true, uses field number instead of field name.
+    void SetUseFieldNumber(bool use_field_number) {
+      use_field_number_ = use_field_number;
+    }
+
+    // Set true to print repeated primitives in a format like:
+    //   field_name: [1, 2, 3, 4]
+    // instead of printing each value on its own line.  Short format applies
+    // only to primitive values -- i.e. everything except strings and
+    // sub-messages/groups.
+    void SetUseShortRepeatedPrimitives(bool use_short_repeated_primitives) {
+      use_short_repeated_primitives_ = use_short_repeated_primitives;
+    }
+
+    // Set true to output UTF-8 instead of ASCII.  The only difference
+    // is that bytes >= 0x80 in string fields will not be escaped,
+    // because they are assumed to be part of UTF-8 multi-byte
+    // sequences. This will change the default FieldValuePrinter.
+    void SetUseUtf8StringEscaping(bool as_utf8);
+
+    // Set the default FieldValuePrinter that is used for all fields that
+    // don't have a field-specific printer registered.
+    // Takes ownership of the printer.
+    void SetDefaultFieldValuePrinter(const FieldValuePrinter* printer);
+
+    // Sets whether we want to hide unknown fields or not.
+    // Usually unknown fields are printed in a generic way that includes the
+    // tag number of the field instead of field name. However, sometimes it
+    // is useful to be able to print the message without unknown fields (e.g.
+    // for the python protobuf version to maintain consistency between its pure
+    // python and c++ implementations).
+    void SetHideUnknownFields(bool hide) {
+      hide_unknown_fields_ = hide;
+    }
+
+    // If print_message_fields_in_index_order is true, print fields of a proto
+    // message using the order defined in source code instead of the field
+    // number. By default, use the field number order.
+    void SetPrintMessageFieldsInIndexOrder(
+        bool print_message_fields_in_index_order) {
+      print_message_fields_in_index_order_ =
+          print_message_fields_in_index_order;
+    }
+
+    // Register a custom field-specific FieldValuePrinter for fields
+    // with a particular FieldDescriptor.
+    // Returns "true" if the registration succeeded, or "false", if there is
+    // already a printer for that FieldDescriptor.
+    // Takes ownership of the printer on successful registration.
+    bool RegisterFieldValuePrinter(const FieldDescriptor* field,
+                                   const FieldValuePrinter* printer);
+
+   private:
+    // Forward declaration of an internal class used to print the text
+    // output to the OutputStream (see text_format.cc for implementation).
+    class TextGenerator;
+
+    // Internal Print method, used for writing to the OutputStream via
+    // the TextGenerator class.
+    void Print(const Message& message,
+               TextGenerator& generator) const;
+
+    // Print a single field.
+    void PrintField(const Message& message,
+                    const Reflection* reflection,
+                    const FieldDescriptor* field,
+                    TextGenerator& generator) const;
+
+    // Print a repeated primitive field in short form.
+    void PrintShortRepeatedField(const Message& message,
+                                 const Reflection* reflection,
+                                 const FieldDescriptor* field,
+                                 TextGenerator& generator) const;
+
+    // Print the name of a field -- i.e. everything that comes before the
+    // ':' for a single name/value pair.
+    void PrintFieldName(const Message& message,
+                        const Reflection* reflection,
+                        const FieldDescriptor* field,
+                        TextGenerator& generator) const;
+
+    // Outputs a textual representation of the value of the field supplied on
+    // the message supplied or the default value if not set.
+    void PrintFieldValue(const Message& message,
+                         const Reflection* reflection,
+                         const FieldDescriptor* field,
+                         int index,
+                         TextGenerator& generator) const;
+
+    // Print the fields in an UnknownFieldSet.  They are printed by tag number
+    // only.  Embedded messages are heuristically identified by attempting to
+    // parse them.
+    void PrintUnknownFields(const UnknownFieldSet& unknown_fields,
+                            TextGenerator& generator) const;
+
+    int initial_indent_level_;
+
+    bool single_line_mode_;
+
+    bool use_field_number_;
+
+    bool use_short_repeated_primitives_;
+
+    bool hide_unknown_fields_;
+
+    bool print_message_fields_in_index_order_;
+
+    scoped_ptr<const FieldValuePrinter> default_field_value_printer_;
+    typedef map<const FieldDescriptor*,
+                const FieldValuePrinter*> CustomPrinterMap;
+    CustomPrinterMap custom_printers_;
+  };
+
+  // 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);
+
+  // Parse the given text as a single field value and store it into the
+  // given field of the given message. If the field is a repeated field,
+  // the new value will be added to the end
+  static bool ParseFieldValueFromString(const string& input,
+                                        const FieldDescriptor* field,
+                                        Message* message);
+
+  // Interface that TextFormat::Parser can use to find extensions.
+  // This class may be extended in the future to find more information
+  // like fields, etc.
+  class LIBPROTOBUF_EXPORT Finder {
+   public:
+    virtual ~Finder();
+
+    // Try to find an extension of *message by fully-qualified field
+    // name.  Returns NULL if no extension is known for this name or number.
+    virtual const FieldDescriptor* FindExtension(
+        Message* message,
+        const string& name) const = 0;
+  };
+
+  // A location in the parsed text.
+  struct ParseLocation {
+    int line;
+    int column;
+
+    ParseLocation() : line(-1), column(-1) {}
+    ParseLocation(int line_param, int column_param)
+        : line(line_param), column(column_param) {}
+  };
+
+  // Data structure which is populated with the locations of each field
+  // value parsed from the text.
+  class LIBPROTOBUF_EXPORT ParseInfoTree {
+   public:
+    ParseInfoTree();
+    ~ParseInfoTree();
+
+    // Returns the parse location for index-th value of the field in the parsed
+    // text. If none exists, returns a location with line = -1. Index should be
+    // -1 for not-repeated fields.
+    ParseLocation GetLocation(const FieldDescriptor* field, int index) const;
+
+    // Returns the parse info tree for the given field, which must be a message
+    // type. The nested information tree is owned by the root tree and will be
+    // deleted when it is deleted.
+    ParseInfoTree* GetTreeForNested(const FieldDescriptor* field,
+                                    int index) const;
+
+   private:
+    // Allow the text format parser to record information into the tree.
+    friend class TextFormat;
+
+    // Records the starting location of a single value for a field.
+    void RecordLocation(const FieldDescriptor* field, ParseLocation location);
+
+    // Create and records a nested tree for a nested message field.
+    ParseInfoTree* CreateNested(const FieldDescriptor* field);
+
+    // Defines the map from the index-th field descriptor to its parse location.
+    typedef map<const FieldDescriptor*, vector<ParseLocation> > LocationMap;
+
+    // Defines the map from the index-th field descriptor to the nested parse
+    // info tree.
+    typedef map<const FieldDescriptor*, vector<ParseInfoTree*> > NestedMap;
+
+    LocationMap locations_;
+    NestedMap nested_;
+
+    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ParseInfoTree);
+  };
+
+  // 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;
+    }
+
+    // Set how parser finds extensions.  If NULL (the default), the
+    // parser will use the standard Reflection object associated with
+    // the message being parsed.
+    void SetFinder(Finder* finder) {
+      finder_ = finder;
+    }
+
+    // Sets where location information about the parse will be written. If NULL
+    // (the default), then no location will be written.
+    void WriteLocationsTo(ParseInfoTree* tree) {
+      parse_info_tree_ = tree;
+    }
+
+    // Normally parsing fails if, after parsing, output->IsInitialized()
+    // returns false.  Call AllowPartialMessage(true) to skip this check.
+    void AllowPartialMessage(bool allow) {
+      allow_partial_ = allow;
+    }
+
+    // Allow field names to be matched case-insensitively.
+    // This is not advisable if there are fields that only differ in case, or
+    // if you want to enforce writing in the canonical form.
+    // This is 'false' by default.
+    void AllowCaseInsensitiveField(bool allow) {
+      allow_case_insensitive_field_ = allow;
+    }
+
+    // Like TextFormat::ParseFieldValueFromString
+    bool ParseFieldValueFromString(const string& input,
+                                   const FieldDescriptor* field,
+                                   Message* output);
+
+
+    void AllowFieldNumber(bool allow) {
+      allow_field_number_ = allow;
+    }
+
+   private:
+    // Forward declaration of an internal class used to parse text
+    // representations (see text_format.cc for implementation).
+    class ParserImpl;
+
+    // Like TextFormat::Merge().  The provided implementation is used
+    // to do the parsing.
+    bool MergeUsingImpl(io::ZeroCopyInputStream* input,
+                        Message* output,
+                        ParserImpl* parser_impl);
+
+    io::ErrorCollector* error_collector_;
+    Finder* finder_;
+    ParseInfoTree* parse_info_tree_;
+    bool allow_partial_;
+    bool allow_case_insensitive_field_;
+    bool allow_unknown_field_;
+    bool allow_unknown_enum_;
+    bool allow_field_number_;
+    bool allow_relaxed_whitespace_;
+    bool allow_singular_overwrites_;
+  };
+
+
+ private:
+  // Hack: ParseInfoTree declares TextFormat as a friend which should extend
+  // the friendship to TextFormat::Parser::ParserImpl, but unfortunately some
+  // old compilers (e.g. GCC 3.4.6) don't implement this correctly. We provide
+  // helpers for ParserImpl to call methods of ParseInfoTree.
+  static inline void RecordLocation(ParseInfoTree* info_tree,
+                                    const FieldDescriptor* field,
+                                    ParseLocation location);
+  static inline ParseInfoTree* CreateNested(ParseInfoTree* info_tree,
+                                            const FieldDescriptor* field);
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormat);
+};
+
+inline void TextFormat::RecordLocation(ParseInfoTree* info_tree,
+                                       const FieldDescriptor* field,
+                                       ParseLocation location) {
+  info_tree->RecordLocation(field, location);
+}
+
+
+inline TextFormat::ParseInfoTree* TextFormat::CreateNested(
+    ParseInfoTree* info_tree, const FieldDescriptor* field) {
+  return info_tree->CreateNested(field);
+}
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_TEXT_FORMAT_H__
diff --git a/protobuf/src/google/protobuf/text_format_unittest.cc b/protobuf/src/google/protobuf/text_format_unittest.cc
new file mode 100644
index 0000000..5573268
--- /dev/null
+++ b/protobuf/src/google/protobuf/text_format_unittest.cc
@@ -0,0 +1,1479 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 {
+
+// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
+namespace text_format_unittest {
+
+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 \\ and  multiple   spaces";
+
+// 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 \\\\ and  multiple   spaces\"";
+
+class TextFormatTest : public testing::Test {
+ public:
+  static void SetUpTestCase() {
+    GOOGLE_CHECK_OK(File::GetContents(
+        TestSourceDir() +
+            "/google/protobuf/"
+            "testdata/text_format_unittest_data_oneof_implemented.txt",
+        &static_proto_debug_string_, true));
+  }
+
+  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() {
+    GOOGLE_CHECK_OK(File::GetContents(TestSourceDir() +
+                                   "/google/protobuf/testdata/"
+                                   "text_format_unittest_extensions_data.txt",
+                               &static_proto_debug_string_, true));
+  }
+
+  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, ShortDebugString) {
+  proto_.set_optional_int32(1);
+  proto_.set_optional_string("hello");
+  proto_.mutable_optional_nested_message()->set_bb(2);
+  proto_.mutable_optional_foreign_message();
+
+  EXPECT_EQ("optional_int32: 1 optional_string: \"hello\" "
+            "optional_nested_message { bb: 2 } "
+            "optional_foreign_message { }",
+            proto_.ShortDebugString());
+}
+
+TEST_F(TextFormatTest, ShortPrimitiveRepeateds) {
+  proto_.set_optional_int32(123);
+  proto_.add_repeated_int32(456);
+  proto_.add_repeated_int32(789);
+  proto_.add_repeated_string("foo");
+  proto_.add_repeated_string("bar");
+  proto_.add_repeated_nested_message()->set_bb(2);
+  proto_.add_repeated_nested_message()->set_bb(3);
+  proto_.add_repeated_nested_enum(unittest::TestAllTypes::FOO);
+  proto_.add_repeated_nested_enum(unittest::TestAllTypes::BAR);
+
+  TextFormat::Printer printer;
+  printer.SetUseShortRepeatedPrimitives(true);
+  string text;
+  printer.PrintToString(proto_, &text);
+
+  EXPECT_EQ("optional_int32: 123\n"
+            "repeated_int32: [456, 789]\n"
+            "repeated_string: \"foo\"\n"
+            "repeated_string: \"bar\"\n"
+            "repeated_nested_message {\n  bb: 2\n}\n"
+            "repeated_nested_message {\n  bb: 3\n}\n"
+            "repeated_nested_enum: [FOO, BAR]\n",
+            text);
+
+  // Try in single-line mode.
+  printer.SetSingleLineMode(true);
+  printer.PrintToString(proto_, &text);
+
+  EXPECT_EQ("optional_int32: 123 "
+            "repeated_int32: [456, 789] "
+            "repeated_string: \"foo\" "
+            "repeated_string: \"bar\" "
+            "repeated_nested_message { bb: 2 } "
+            "repeated_nested_message { bb: 3 } "
+            "repeated_nested_enum: [FOO, BAR] ",
+            text);
+}
+
+
+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();
+  string utf8_debug_string = proto_.Utf8DebugString();
+
+  // Hardcode a correct value to test against.
+  string correct_string = "optional_string: "
+      + kEscapeTestStringEscaped
+       + "\n";
+
+  // Compare.
+  EXPECT_EQ(correct_string, debug_string);
+  // UTF-8 string is the same as non-UTF-8 because
+  // the protocol buffer contains no UTF-8 text.
+  EXPECT_EQ(correct_string, utf8_debug_string);
+
+  string expected_short_debug_string = "optional_string: "
+      + kEscapeTestStringEscaped;
+  EXPECT_EQ(expected_short_debug_string, proto_.ShortDebugString());
+}
+
+TEST_F(TextFormatTest, Utf8DebugString) {
+  // Set the string value to test.
+  proto_.set_optional_string("\350\260\267\346\255\214");
+  proto_.set_optional_bytes("\350\260\267\346\255\214");
+
+  // Get the DebugString from the proto.
+  string debug_string = proto_.DebugString();
+  string utf8_debug_string = proto_.Utf8DebugString();
+
+  // Hardcode a correct value to test against.
+  string correct_utf8_string =
+      "optional_string: "
+      "\"\350\260\267\346\255\214\""
+      "\n"
+      "optional_bytes: "
+      "\"\\350\\260\\267\\346\\255\\214\""
+      "\n";
+  string correct_string =
+      "optional_string: "
+      "\"\\350\\260\\267\\346\\255\\214\""
+      "\n"
+      "optional_bytes: "
+      "\"\\350\\260\\267\\346\\255\\214\""
+      "\n";
+
+  // Compare.
+  EXPECT_EQ(correct_utf8_string, utf8_debug_string);
+  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();
+
+  unknown_fields->AddVarint(5, 1);
+  unknown_fields->AddFixed32(5, 2);
+  unknown_fields->AddFixed64(5, 3);
+  unknown_fields->AddLengthDelimited(5, "4");
+  unknown_fields->AddGroup(5)->AddVarint(10, 5);
+
+  unknown_fields->AddVarint(8, 1);
+  unknown_fields->AddVarint(8, 2);
+  unknown_fields->AddVarint(8, 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, PrintUnknownFieldsHidden) {
+  // Test printing of unknown fields in a message when supressed.
+
+  unittest::OneString message;
+  message.set_data("data");
+  UnknownFieldSet* unknown_fields = message.mutable_unknown_fields();
+
+  unknown_fields->AddVarint(5, 1);
+  unknown_fields->AddFixed32(5, 2);
+  unknown_fields->AddFixed64(5, 3);
+  unknown_fields->AddLengthDelimited(5, "4");
+  unknown_fields->AddGroup(5)->AddVarint(10, 5);
+
+  unknown_fields->AddVarint(8, 1);
+  unknown_fields->AddVarint(8, 2);
+  unknown_fields->AddVarint(8, 3);
+
+  TextFormat::Printer printer;
+  printer.SetHideUnknownFields(true);
+  string output;
+  printer.PrintToString(message, &output);
+
+  EXPECT_EQ("data: \"data\"\n", output);
+}
+
+TEST_F(TextFormatTest, PrintUnknownMessage) {
+  // Test heuristic printing of messages in an UnknownFieldSet.
+
+  protobuf_unittest::TestAllTypes message;
+
+  // Cases which should not be interpreted as sub-messages.
+
+  // 'a' is a valid FIXED64 tag, so for the string to be parseable as a message
+  // it should be followed by 8 bytes.  Since this string only has two
+  // subsequent bytes, it should be treated as a string.
+  message.add_repeated_string("abc");
+
+  // 'd' happens to be a valid ENDGROUP tag.  So,
+  // UnknownFieldSet::MergeFromCodedStream() will successfully parse "def", but
+  // the ConsumedEntireMessage() check should fail.
+  message.add_repeated_string("def");
+
+  // A zero-length string should never be interpreted as a message even though
+  // it is technically valid as one.
+  message.add_repeated_string("");
+
+  // Case which should be interpreted as a sub-message.
+
+  // An actual nested message with content should always be interpreted as a
+  // nested message.
+  message.add_repeated_nested_message()->set_bb(123);
+
+  string data;
+  message.SerializeToString(&data);
+
+  string text;
+  UnknownFieldSet unknown_fields;
+  EXPECT_TRUE(unknown_fields.ParseFromString(data));
+  EXPECT_TRUE(TextFormat::PrintUnknownFieldsToString(unknown_fields, &text));
+  EXPECT_EQ(
+    "44: \"abc\"\n"
+    "44: \"def\"\n"
+    "44: \"\"\n"
+    "48 {\n"
+    "  1: 123\n"
+    "}\n",
+    text);
+}
+
+TEST_F(TextFormatTest, PrintMessageWithIndent) {
+  // Test adding an initial indent to printing.
+
+  protobuf_unittest::TestAllTypes message;
+
+  message.add_repeated_string("abc");
+  message.add_repeated_string("def");
+  message.add_repeated_nested_message()->set_bb(123);
+
+  string text;
+  TextFormat::Printer printer;
+  printer.SetInitialIndentLevel(1);
+  EXPECT_TRUE(printer.PrintToString(message, &text));
+  EXPECT_EQ(
+    "  repeated_string: \"abc\"\n"
+    "  repeated_string: \"def\"\n"
+    "  repeated_nested_message {\n"
+    "    bb: 123\n"
+    "  }\n",
+    text);
+}
+
+TEST_F(TextFormatTest, PrintMessageSingleLine) {
+  // Test printing a message on a single line.
+
+  protobuf_unittest::TestAllTypes message;
+
+  message.add_repeated_string("abc");
+  message.add_repeated_string("def");
+  message.add_repeated_nested_message()->set_bb(123);
+
+  string text;
+  TextFormat::Printer printer;
+  printer.SetInitialIndentLevel(1);
+  printer.SetSingleLineMode(true);
+  EXPECT_TRUE(printer.PrintToString(message, &text));
+  EXPECT_EQ(
+    "  repeated_string: \"abc\" repeated_string: \"def\" "
+    "repeated_nested_message { bb: 123 } ",
+    text);
+}
+
+TEST_F(TextFormatTest, PrintBufferTooSmall) {
+  // Test printing a message to a buffer that is too small.
+
+  protobuf_unittest::TestAllTypes message;
+
+  message.add_repeated_string("abc");
+  message.add_repeated_string("def");
+
+  char buffer[1] = "";
+  io::ArrayOutputStream output_stream(buffer, 1);
+  EXPECT_FALSE(TextFormat::Print(message, &output_stream));
+  EXPECT_EQ(buffer[0], 'r');
+  EXPECT_EQ(output_stream.ByteCount(), 1);
+}
+
+// A printer that appends 'u' to all unsigned int32.
+class CustomUInt32FieldValuePrinter : public TextFormat::FieldValuePrinter {
+ public:
+  virtual string PrintUInt32(uint32 val) const {
+    return StrCat(FieldValuePrinter::PrintUInt32(val), "u");
+  }
+};
+
+TEST_F(TextFormatTest, DefaultCustomFieldPrinter) {
+  protobuf_unittest::TestAllTypes message;
+
+  message.set_optional_uint32(42);
+  message.add_repeated_uint32(1);
+  message.add_repeated_uint32(2);
+  message.add_repeated_uint32(3);
+
+  TextFormat::Printer printer;
+  printer.SetDefaultFieldValuePrinter(new CustomUInt32FieldValuePrinter());
+  // Let's see if that works well together with the repeated primitives:
+  printer.SetUseShortRepeatedPrimitives(true);
+  string text;
+  printer.PrintToString(message, &text);
+  EXPECT_EQ("optional_uint32: 42u\nrepeated_uint32: [1u, 2u, 3u]\n", text);
+}
+
+class CustomInt32FieldValuePrinter : public TextFormat::FieldValuePrinter {
+ public:
+  virtual string PrintInt32(int32 val) const {
+    return StrCat("value-is(", FieldValuePrinter::PrintInt32(val), ")");
+  }
+};
+
+TEST_F(TextFormatTest, FieldSpecificCustomPrinter) {
+  protobuf_unittest::TestAllTypes message;
+
+  message.set_optional_int32(42);  // This will be handled by our Printer.
+  message.add_repeated_int32(42);  // This will be printed as number.
+
+  TextFormat::Printer printer;
+  EXPECT_TRUE(printer.RegisterFieldValuePrinter(
+      message.GetDescriptor()->FindFieldByName("optional_int32"),
+      new CustomInt32FieldValuePrinter()));
+  string text;
+  printer.PrintToString(message, &text);
+  EXPECT_EQ("optional_int32: value-is(42)\nrepeated_int32: 42\n", text);
+}
+
+TEST_F(TextFormatTest, ErrorCasesRegisteringFieldValuePrinterShouldFail) {
+  protobuf_unittest::TestAllTypes message;
+  TextFormat::Printer printer;
+  // NULL printer.
+  EXPECT_FALSE(printer.RegisterFieldValuePrinter(
+      message.GetDescriptor()->FindFieldByName("optional_int32"),
+      NULL));
+  // Because registration fails, the ownership of this printer is never taken.
+  TextFormat::FieldValuePrinter my_field_printer;
+  // NULL field
+  EXPECT_FALSE(printer.RegisterFieldValuePrinter(NULL, &my_field_printer));
+}
+
+class CustomMessageFieldValuePrinter : public TextFormat::FieldValuePrinter {
+ public:
+  virtual string PrintInt32(int32 v) const {
+    return StrCat(FieldValuePrinter::PrintInt32(v), "  # x", ToHex(v));
+  }
+
+  virtual string PrintMessageStart(const Message& message,
+                                   int field_index,
+                                   int field_count,
+                                   bool single_line_mode) const {
+    if (single_line_mode) {
+      return " { ";
+    }
+    return StrCat(
+        " {  # ", message.GetDescriptor()->name(), ": ", field_index, "\n");
+  }
+};
+
+TEST_F(TextFormatTest, CustomPrinterForComments) {
+  protobuf_unittest::TestAllTypes message;
+  message.mutable_optional_nested_message();
+  message.mutable_optional_import_message()->set_d(42);
+  message.add_repeated_nested_message();
+  message.add_repeated_nested_message();
+  message.add_repeated_import_message()->set_d(43);
+  message.add_repeated_import_message()->set_d(44);
+  TextFormat::Printer printer;
+  CustomMessageFieldValuePrinter my_field_printer;
+  printer.SetDefaultFieldValuePrinter(new CustomMessageFieldValuePrinter());
+  string text;
+  printer.PrintToString(message, &text);
+  EXPECT_EQ(
+      "optional_nested_message {  # NestedMessage: -1\n"
+      "}\n"
+      "optional_import_message {  # ImportMessage: -1\n"
+      "  d: 42  # x2a\n"
+      "}\n"
+      "repeated_nested_message {  # NestedMessage: 0\n"
+      "}\n"
+      "repeated_nested_message {  # NestedMessage: 1\n"
+      "}\n"
+      "repeated_import_message {  # ImportMessage: 0\n"
+      "  d: 43  # x2b\n"
+      "}\n"
+      "repeated_import_message {  # ImportMessage: 1\n"
+      "  d: 44  # x2c\n"
+      "}\n",
+      text);
+}
+
+class CustomMultilineCommentPrinter : public TextFormat::FieldValuePrinter {
+ public:
+  virtual string PrintMessageStart(const Message& message,
+                                   int field_index,
+                                   int field_count,
+                                   bool single_line_comment) const {
+    return StrCat(" {  # 1\n", "  # 2\n");
+  }
+};
+
+TEST_F(TextFormatTest, CustomPrinterForMultilineComments) {
+  protobuf_unittest::TestAllTypes message;
+  message.mutable_optional_nested_message();
+  message.mutable_optional_import_message()->set_d(42);
+  TextFormat::Printer printer;
+  CustomMessageFieldValuePrinter my_field_printer;
+  printer.SetDefaultFieldValuePrinter(new CustomMultilineCommentPrinter());
+  string text;
+  printer.PrintToString(message, &text);
+  EXPECT_EQ(
+      "optional_nested_message {  # 1\n"
+      "  # 2\n"
+      "}\n"
+      "optional_import_message {  # 1\n"
+      "  # 2\n"
+      "  d: 42\n"
+      "}\n",
+      text);
+}
+
+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, ParseEnumFieldFromNumber) {
+  // Create a parse string with a numerical value for an enum field.
+  string parse_string = strings::Substitute("optional_nested_enum: $0",
+                                            unittest::TestAllTypes::BAZ);
+  EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+  EXPECT_TRUE(proto_.has_optional_nested_enum());
+  EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.optional_nested_enum());
+}
+
+TEST_F(TextFormatTest, ParseEnumFieldFromNegativeNumber) {
+  ASSERT_LT(unittest::SPARSE_E, 0);
+  string parse_string = strings::Substitute("sparse_enum: $0",
+                                            unittest::SPARSE_E);
+  unittest::SparseEnumMessage proto;
+  EXPECT_TRUE(TextFormat::ParseFromString(parse_string, &proto));
+  EXPECT_TRUE(proto.has_sparse_enum());
+  EXPECT_EQ(unittest::SPARSE_E, proto.sparse_enum());
+}
+
+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, ParseConcatenatedString) {
+  // Create a parse string with multiple parts on one line.
+  string parse_string = "optional_string: \"foo\" \"bar\"\n";
+
+  io::ArrayInputStream input_stream1(parse_string.data(),
+                                    parse_string.size());
+  TextFormat::Parse(&input_stream1, &proto_);
+
+  // Compare.
+  EXPECT_EQ("foobar", proto_.optional_string());
+
+  // Create a parse string with multiple parts on seperate lines.
+  parse_string = "optional_string: \"foo\"\n"
+                 "\"bar\"\n";
+
+  io::ArrayInputStream input_stream2(parse_string.data(),
+                                    parse_string.size());
+  TextFormat::Parse(&input_stream2, &proto_);
+
+  // Compare.
+  EXPECT_EQ("foobar", 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, ParseShortRepeatedForm) {
+  string parse_string =
+      // Mixed short-form and long-form are simply concatenated.
+      "repeated_int32: 1\n"
+      "repeated_int32: [456, 789]\n"
+      "repeated_nested_enum: [  FOO ,BAR, # comment\n"
+      "                         3]\n"
+      // Note that while the printer won't print repeated strings in short-form,
+      // the parser will accept them.
+      "repeated_string: [ \"foo\", 'bar' ]\n"
+      // Repeated message
+      "repeated_nested_message: [ { bb: 1 }, { bb : 2 }]\n"
+      // Repeated group
+      "RepeatedGroup [{ a: 3 },{ a: 4 }]\n";
+
+  ASSERT_TRUE(TextFormat::ParseFromString(parse_string, &proto_));
+
+  ASSERT_EQ(3, proto_.repeated_int32_size());
+  EXPECT_EQ(1, proto_.repeated_int32(0));
+  EXPECT_EQ(456, proto_.repeated_int32(1));
+  EXPECT_EQ(789, proto_.repeated_int32(2));
+
+  ASSERT_EQ(3, proto_.repeated_nested_enum_size());
+  EXPECT_EQ(unittest::TestAllTypes::FOO, proto_.repeated_nested_enum(0));
+  EXPECT_EQ(unittest::TestAllTypes::BAR, proto_.repeated_nested_enum(1));
+  EXPECT_EQ(unittest::TestAllTypes::BAZ, proto_.repeated_nested_enum(2));
+
+  ASSERT_EQ(2, proto_.repeated_string_size());
+  EXPECT_EQ("foo", proto_.repeated_string(0));
+  EXPECT_EQ("bar", proto_.repeated_string(1));
+
+  ASSERT_EQ(2, proto_.repeated_nested_message_size());
+  EXPECT_EQ(1, proto_.repeated_nested_message(0).bb());
+  EXPECT_EQ(2, proto_.repeated_nested_message(1).bb());
+
+  ASSERT_EQ(2, proto_.repeatedgroup_size());
+  EXPECT_EQ(3, proto_.repeatedgroup(0).a());
+  EXPECT_EQ(4, proto_.repeatedgroup(1).a());
+}
+
+
+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));
+}
+
+TEST_F(TextFormatTest, PrintFieldsInIndexOrder) {
+  protobuf_unittest::TestFieldOrderings message;
+  // Fields are listed in index order instead of field number.
+  message.set_my_string("Test String");   // Field number 11
+  message.set_my_int(12345);              // Field number 1
+  message.set_my_float(0.999);            // Field number 101
+  TextFormat::Printer printer;
+  string text;
+
+  // By default, print in field number order.
+  printer.PrintToString(message, &text);
+  EXPECT_EQ("my_int: 12345\nmy_string: \"Test String\"\nmy_float: 0.999\n",
+            text);
+
+  // Print in index order.
+  printer.SetPrintMessageFieldsInIndexOrder(true);
+  printer.PrintToString(message, &text);
+  EXPECT_EQ("my_string: \"Test String\"\nmy_int: 12345\nmy_float: 0.999\n",
+            text);
+}
+
+class TextFormatParserTest : public testing::Test {
+ protected:
+  void ExpectFailure(const string& input, const string& message, int line,
+                     int col) {
+    scoped_ptr<unittest::TestAllTypes> proto(new unittest::TestAllTypes);
+    ExpectFailure(input, message, line, col, proto.get());
+  }
+
+  void ExpectFailure(const string& input, const string& message, int line,
+                     int col, Message* proto) {
+    ExpectMessage(input, message, line, col, proto, false);
+  }
+
+  void ExpectMessage(const string& input, const string& message, int line,
+                     int col, Message* proto, bool expected_result) {
+    TextFormat::Parser parser;
+    MockErrorCollector error_collector;
+    parser.RecordErrorsTo(&error_collector);
+    EXPECT_EQ(expected_result, parser.ParseFromString(input, proto))
+        << input << " -> " << proto->DebugString();
+    EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) + ": " + message + "\n",
+              error_collector.text_);
+  }
+
+  void ExpectSuccessAndTree(const string& input, Message* proto,
+                            TextFormat::ParseInfoTree* info_tree) {
+    TextFormat::Parser parser;
+    MockErrorCollector error_collector;
+    parser.RecordErrorsTo(&error_collector);
+    parser.WriteLocationsTo(info_tree);
+
+    EXPECT_TRUE(parser.ParseFromString(input, proto));
+  }
+
+  void ExpectLocation(TextFormat::ParseInfoTree* tree,
+                      const Descriptor* d, const string& field_name,
+                      int index, int line, int column) {
+    TextFormat::ParseLocation location = tree->GetLocation(
+        d->FindFieldByName(field_name), index);
+    EXPECT_EQ(line, location.line);
+    EXPECT_EQ(column, location.column);
+  }
+
+  // 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);
+    }
+
+    void AddWarning(int line, int column, const string& message) {
+      AddError(line, column, "WARNING:" + message);
+    }
+  };
+};
+
+TEST_F(TextFormatParserTest, ParseInfoTreeBuilding) {
+  scoped_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
+  const Descriptor* d = message->GetDescriptor();
+
+  string stringData =
+      "optional_int32: 1\n"
+      "optional_int64: 2\n"
+      "  optional_double: 2.4\n"
+      "repeated_int32: 5\n"
+      "repeated_int32: 10\n"
+      "optional_nested_message <\n"
+      "  bb: 78\n"
+      ">\n"
+      "repeated_nested_message <\n"
+      "  bb: 79\n"
+      ">\n"
+      "repeated_nested_message <\n"
+      "  bb: 80\n"
+      ">";
+
+
+  TextFormat::ParseInfoTree tree;
+  ExpectSuccessAndTree(stringData, message.get(), &tree);
+
+  // Verify that the tree has the correct positions.
+  ExpectLocation(&tree, d, "optional_int32", -1, 0, 0);
+  ExpectLocation(&tree, d, "optional_int64", -1, 1, 0);
+  ExpectLocation(&tree, d, "optional_double", -1, 2, 2);
+
+  ExpectLocation(&tree, d, "repeated_int32", 0, 3, 0);
+  ExpectLocation(&tree, d, "repeated_int32", 1, 4, 0);
+
+  ExpectLocation(&tree, d, "optional_nested_message", -1, 5, 0);
+  ExpectLocation(&tree, d, "repeated_nested_message", 0, 8, 0);
+  ExpectLocation(&tree, d, "repeated_nested_message", 1, 11, 0);
+
+  // Check for fields not set. For an invalid field, the location returned
+  // should be -1, -1.
+  ExpectLocation(&tree, d, "repeated_int64", 0, -1, -1);
+  ExpectLocation(&tree, d, "repeated_int32", 6, -1, -1);
+  ExpectLocation(&tree, d, "some_unknown_field", -1, -1, -1);
+
+  // Verify inside the nested message.
+  const FieldDescriptor* nested_field =
+      d->FindFieldByName("optional_nested_message");
+
+  TextFormat::ParseInfoTree* nested_tree =
+      tree.GetTreeForNested(nested_field, -1);
+  ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 6, 2);
+
+  // Verify inside another nested message.
+  nested_field = d->FindFieldByName("repeated_nested_message");
+  nested_tree = tree.GetTreeForNested(nested_field, 0);
+  ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 9, 2);
+
+  nested_tree = tree.GetTreeForNested(nested_field, 1);
+  ExpectLocation(nested_tree, nested_field->message_type(), "bb", -1, 12, 2);
+
+  // Verify a NULL tree for an unknown nested field.
+  TextFormat::ParseInfoTree* unknown_nested_tree =
+      tree.GetTreeForNested(nested_field, 2);
+
+  EXPECT_EQ(NULL, unknown_nested_tree);
+}
+
+TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
+  scoped_ptr<unittest::TestAllTypes> message(new unittest::TestAllTypes);
+  const Descriptor* d = message->GetDescriptor();
+
+#define EXPECT_FIELD(name, value, valuestring) \
+  EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+    valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+  EXPECT_EQ(value, message->optional_##name()); \
+  EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_BOOL_FIELD(name, value, valuestring) \
+  EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+    valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+  EXPECT_TRUE(message->optional_##name() == value); \
+  EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_FLOAT_FIELD(name, value, valuestring) \
+  EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+    valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+  EXPECT_FLOAT_EQ(value, message->optional_##name()); \
+  EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_DOUBLE_FIELD(name, value, valuestring) \
+  EXPECT_TRUE(TextFormat::ParseFieldValueFromString( \
+    valuestring, d->FindFieldByName("optional_" #name), message.get())); \
+  EXPECT_DOUBLE_EQ(value, message->optional_##name()); \
+  EXPECT_TRUE(message->has_optional_##name());
+
+#define EXPECT_INVALID(name, valuestring) \
+  EXPECT_FALSE(TextFormat::ParseFieldValueFromString( \
+    valuestring, d->FindFieldByName("optional_" #name), message.get()));
+
+  // int32
+  EXPECT_FIELD(int32, 1, "1");
+  EXPECT_FIELD(int32, -1, "-1");
+  EXPECT_FIELD(int32, 0x1234, "0x1234");
+  EXPECT_INVALID(int32, "a");
+  EXPECT_INVALID(int32, "999999999999999999999999999999999999");
+  EXPECT_INVALID(int32, "1,2");
+
+  // int64
+  EXPECT_FIELD(int64, 1, "1");
+  EXPECT_FIELD(int64, -1, "-1");
+  EXPECT_FIELD(int64, 0x1234567812345678LL, "0x1234567812345678");
+  EXPECT_INVALID(int64, "a");
+  EXPECT_INVALID(int64, "999999999999999999999999999999999999");
+  EXPECT_INVALID(int64, "1,2");
+
+  // uint64
+  EXPECT_FIELD(uint64, 1, "1");
+  EXPECT_FIELD(uint64, 0xf234567812345678ULL, "0xf234567812345678");
+  EXPECT_INVALID(uint64, "-1");
+  EXPECT_INVALID(uint64, "a");
+  EXPECT_INVALID(uint64, "999999999999999999999999999999999999");
+  EXPECT_INVALID(uint64, "1,2");
+
+  // fixed32
+  EXPECT_FIELD(fixed32, 1, "1");
+  EXPECT_FIELD(fixed32, 0x12345678, "0x12345678");
+  EXPECT_INVALID(fixed32, "-1");
+  EXPECT_INVALID(fixed32, "a");
+  EXPECT_INVALID(fixed32, "999999999999999999999999999999999999");
+  EXPECT_INVALID(fixed32, "1,2");
+
+  // fixed64
+  EXPECT_FIELD(fixed64, 1, "1");
+  EXPECT_FIELD(fixed64, 0x1234567812345678ULL, "0x1234567812345678");
+  EXPECT_INVALID(fixed64, "-1");
+  EXPECT_INVALID(fixed64, "a");
+  EXPECT_INVALID(fixed64, "999999999999999999999999999999999999");
+  EXPECT_INVALID(fixed64, "1,2");
+
+  // bool
+  EXPECT_BOOL_FIELD(bool, true, "true");
+  EXPECT_BOOL_FIELD(bool, false, "false");
+  EXPECT_BOOL_FIELD(bool, true, "1");
+  EXPECT_BOOL_FIELD(bool, true, "t");
+  EXPECT_BOOL_FIELD(bool, false, "0");
+  EXPECT_BOOL_FIELD(bool, false, "f");
+  EXPECT_FIELD(bool, true, "True");
+  EXPECT_FIELD(bool, false, "False");
+  EXPECT_INVALID(bool, "tRue");
+  EXPECT_INVALID(bool, "faLse");
+  EXPECT_INVALID(bool, "2");
+  EXPECT_INVALID(bool, "-0");
+  EXPECT_INVALID(bool, "on");
+  EXPECT_INVALID(bool, "a");
+
+  // float
+  EXPECT_FIELD(float, 1, "1");
+  EXPECT_FLOAT_FIELD(float, 1.5, "1.5");
+  EXPECT_FLOAT_FIELD(float, 1.5e3, "1.5e3");
+  EXPECT_FLOAT_FIELD(float, -4.55, "-4.55");
+  EXPECT_INVALID(float, "a");
+  EXPECT_INVALID(float, "1,2");
+
+  // double
+  EXPECT_FIELD(double, 1, "1");
+  EXPECT_FIELD(double, -1, "-1");
+  EXPECT_DOUBLE_FIELD(double, 2.3, "2.3");
+  EXPECT_DOUBLE_FIELD(double, 3e5, "3e5");
+  EXPECT_INVALID(double, "a");
+  EXPECT_INVALID(double, "1,2");
+  // Rejects hex and oct numbers for a double field.
+  EXPECT_INVALID(double, "0xf");
+  EXPECT_INVALID(double, "012");
+
+  // string
+  EXPECT_FIELD(string, "hello", "\"hello\"");
+  EXPECT_FIELD(string, "-1.87", "'-1.87'");
+  EXPECT_INVALID(string, "hello");  // without quote for value
+
+  // enum
+  EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR");
+  EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ,
+               SimpleItoa(unittest::TestAllTypes::BAZ));
+  EXPECT_INVALID(nested_enum, "FOOBAR");
+
+  // message
+  EXPECT_TRUE(TextFormat::ParseFieldValueFromString(
+    "<bb:12>", d->FindFieldByName("optional_nested_message"), message.get()));
+  EXPECT_EQ(12, message->optional_nested_message().bb()); \
+  EXPECT_TRUE(message->has_optional_nested_message());
+  EXPECT_INVALID(nested_message, "any");
+
+#undef EXPECT_FIELD
+#undef EXPECT_BOOL_FIELD
+#undef EXPECT_FLOAT_FIELD
+#undef EXPECT_DOUBLE_FIELD
+#undef EXPECT_INVALID
+}
+
+
+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, AllowIgnoreCapitalizationError) {
+  TextFormat::Parser parser;
+  protobuf_unittest::TestAllTypes proto;
+
+  // These fields have a mismatching case.
+  EXPECT_FALSE(parser.ParseFromString("Optional_Double: 10.0", &proto));
+  EXPECT_FALSE(parser.ParseFromString("oPtIoNaLgRoUp { a: 15 }", &proto));
+
+  // ... but are parsed correctly if we match case insensitive.
+  parser.AllowCaseInsensitiveField(true);
+  EXPECT_TRUE(parser.ParseFromString("Optional_Double: 10.0", &proto));
+  EXPECT_EQ(10.0, proto.optional_double());
+  EXPECT_TRUE(parser.ParseFromString("oPtIoNaLgRoUp { a: 15 }", &proto));
+  EXPECT_EQ(15, proto.optionalgroup().a());
+}
+
+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_int64: 0x8000000000000000\n",
+                "Integer out of range.", 1, 17);
+  ExpectFailure("optional_int32: -0x80000001\n",
+                "Integer out of range.", 1, 18);
+  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", "Integer out of range.", 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 integer or identifier.", 1, 23);
+
+  // Valid token, but enum value is not defined.
+  ExpectFailure("optional_nested_enum: 5\n",
+                "Unknown enumeration value of \"5\" for field "
+                "\"optional_nested_enum\".", 2, 1);
+  // We consume the negative sign, so the error position starts one character
+  // later.
+  ExpectFailure("optional_nested_enum: -7.5\n", "Expected integer.", 1, 24);
+  ExpectFailure("optional_nested_enum: !\n",
+                "Expected integer or 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, ParseDuplicateRequired) {
+  unittest::TestRequired message;
+  ExpectFailure("a: 1 b: 2 c: 3 a: 1",
+                "Non-repeated field \"a\" is specified multiple times.",
+                1, 17, &message);
+}
+
+TEST_F(TextFormatParserTest, ParseDuplicateOptional) {
+  unittest::ForeignMessage message;
+  ExpectFailure("c: 1 c: 2",
+                "Non-repeated field \"c\" is specified multiple times.",
+                1, 7, &message);
+}
+
+TEST_F(TextFormatParserTest, MergeDuplicateRequired) {
+  unittest::TestRequired message;
+  TextFormat::Parser parser;
+  EXPECT_TRUE(parser.MergeFromString("a: 1 b: 2 c: 3 a: 4", &message));
+  EXPECT_EQ(4, message.a());
+}
+
+TEST_F(TextFormatParserTest, MergeDuplicateOptional) {
+  unittest::ForeignMessage message;
+  TextFormat::Parser parser;
+  EXPECT_TRUE(parser.MergeFromString("c: 1 c: 2", &message));
+  EXPECT_EQ(2, message.c());
+}
+
+TEST_F(TextFormatParserTest, ExplicitDelimiters) {
+  unittest::TestRequired message;
+  EXPECT_TRUE(TextFormat::ParseFromString("a:1,b:2;c:3", &message));
+  EXPECT_EQ(1, message.a());
+  EXPECT_EQ(2, message.b());
+  EXPECT_EQ(3, message.c());
+}
+
+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]);
+}
+
+TEST_F(TextFormatParserTest, FailsOnTokenizationError) {
+  vector<string> errors;
+
+  {
+    ScopedMemoryLog log;
+    unittest::TestAllTypes proto;
+    EXPECT_FALSE(TextFormat::ParseFromString("\020", &proto));
+    errors = log.GetMessages(ERROR);
+  }
+
+  ASSERT_EQ(1, errors.size());
+  EXPECT_EQ("Error parsing text-format protobuf_unittest.TestAllTypes: "
+            "1:1: Invalid control characters encountered in text.",
+            errors[0]);
+}
+
+TEST_F(TextFormatParserTest, ParseDeprecatedField) {
+  unittest::TestDeprecatedFields message;
+  ExpectMessage("deprecated_int32: 42",
+                "WARNING:text format contains deprecated field "
+                "\"deprecated_int32\"", 1, 21, &message, true);
+}
+
+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(
+    proto.message_set(), &descriptors);
+  EXPECT_EQ(2, descriptors.size());
+}
+
+
+}  // namespace text_format_unittest
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/unittest.proto b/protobuf/src/google/protobuf/unittest.proto
new file mode 100644
index 0000000..c48cc92
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest.proto
@@ -0,0 +1,861 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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.
+
+
+// Some generic_services option(s) added automatically.
+// See:  http://go/proto2-generic-services-default
+option cc_generic_services = true;     // auto-added
+option java_generic_services = true;   // auto-added
+option py_generic_services = true;     // auto-added
+
+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;
+    NEG = -1;  // Intentionally negative.
+  }
+
+  // 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];
+
+  // Defined in unittest_import_public.proto
+  optional protobuf_unittest_import.PublicImportMessage
+      optional_public_import_message = 26;
+
+  optional NestedMessage optional_lazy_message = 27 [lazy=true];
+
+  // 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];
+
+  repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+  // 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"];
+
+  // For oneof test
+  oneof oneof_field {
+    uint32 oneof_uint32 = 111;
+    NestedMessage oneof_nested_message = 112;
+    string oneof_string = 113;
+    bytes oneof_bytes = 114;
+  }
+}
+
+// This proto includes a recusively nested message.
+message NestedTestAllTypes {
+  optional NestedTestAllTypes child = 1;
+  optional TestAllTypes payload = 2;
+}
+
+message TestDeprecatedFields {
+  optional int32 deprecated_int32 = 1 [deprecated=true];
+}
+
+// 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];
+
+  optional protobuf_unittest_import.PublicImportMessage
+    optional_public_import_message_extension = 26;
+
+  optional TestAllTypes.NestedMessage
+    optional_lazy_message_extension = 27 [lazy=true];
+
+  // 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];
+
+  repeated TestAllTypes.NestedMessage
+    repeated_lazy_message_extension = 57 [lazy=true];
+
+  // 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"];
+
+  // For oneof test
+  optional uint32 oneof_uint32_extension = 111;
+  optional TestAllTypes.NestedMessage oneof_nested_message_extension = 112;
+  optional string oneof_string_extension = 113;
+  optional bytes oneof_bytes_extension = 114;
+}
+
+message TestNestedExtension {
+  extend TestAllExtensions {
+    // Check for bug where string extensions declared in tested scope did not
+    // compile.
+    optional string test = 1002 [default="test"];
+    // Used to test if generated extension name is correct when there are
+    // underscores.
+    optional string nested_string_extension = 1003;
+  }
+}
+
+// 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;
+}
+
+message TestMultipleExtensionRanges {
+  extensions 42;
+  extensions 4143 to 4243;
+  extensions 65536 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 attempting
+// to compile with proto1, this will emit an error; so we only include it
+// in protobuf_unittest_proto.
+message TestDupFieldNumber {                        // NO_PROTO1
+  optional int32 a = 1;                             // NO_PROTO1
+  optional group Foo = 2 { optional int32 a = 1; }  // NO_PROTO1
+  optional group Bar = 3 { optional int32 a = 1; }  // NO_PROTO1
+}                                                   // NO_PROTO1
+
+// Additional messages for testing lazy fields.
+message TestEagerMessage {
+  optional TestAllTypes sub_message = 1 [lazy=false];
+}
+message TestLazyMessage {
+  optional TestAllTypes sub_message = 1 [lazy=true];
+}
+
+// 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 {
+  option allow_alias = true;
+
+  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];
+  optional  int32 really_small_int32 = 21 [default = -0x80000000];
+  optional  int64 really_small_int64 = 22 [default = -0x8000000000000000];
+
+  // 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"];
+
+  // Tests for single-precision floating-point values.
+  optional float zero_float = 7 [default = 0];
+  optional float one_float = 8 [default = 1];
+  optional float small_float = 9 [default = 1.5];
+  optional float negative_one_float = 10 [default = -1];
+  optional float negative_float = 11 [default = -1.5];
+  // Using exponents
+  optional float large_float = 12 [default = 2E8];
+  optional float small_negative_float = 13 [default = -8e-28];
+
+  // Text for nonfinite floating-point values.
+  optional double inf_double = 14 [default = inf];
+  optional double neg_inf_double = 15 [default = -inf];
+  optional double nan_double = 16 [default = nan];
+  optional float inf_float = 17 [default = inf];
+  optional float neg_inf_float = 18 [default = -inf];
+  optional float nan_float = 19 [default = nan];
+
+  // Tests for C++ trigraphs.
+  // Trigraphs should be escaped in C++ generated files, but they should not be
+  // escaped for other languages.
+  // Note that in .proto file, "\?" is a valid way to escape ? in string
+  // literals.
+  optional string cpp_trigraph = 20 [default = "? \? ?? \?? \??? ??/ ?\?-"];
+
+  // String defaults containing the character '\000'
+  optional string string_with_zero       = 23 [default = "hel\000lo"];
+  optional  bytes bytes_with_zero        = 24 [default = "wor\000ld"];
+  optional string string_piece_with_zero = 25 [ctype=STRING_PIECE,
+                                               default="ab\000c"];
+  optional string cord_with_zero         = 26 [ctype=CORD,
+                                               default="12\0003"];
+  optional string replacement_string     = 27 [default="${unknown}"];
+}
+
+message SparseEnumMessage {
+  optional TestSparseEnum sparse_enum = 1;
+}
+
+// Test String and Bytes: string is for valid UTF-8 strings
+message OneString {
+  optional string data = 1;
+}
+
+message MoreString {
+  repeated string data = 1;
+}
+
+message OneBytes {
+  optional bytes data = 1;
+}
+
+message MoreBytes {
+  repeated bytes data = 1;
+}
+
+// Test int32, uint32, int64, uint64, and bool are all compatible
+message Int32Message {
+  optional int32 data = 1;
+}
+
+message Uint32Message {
+  optional uint32 data = 1;
+}
+
+message Int64Message {
+  optional int64 data = 1;
+}
+
+message Uint64Message {
+  optional uint64 data = 1;
+}
+
+message BoolMessage {
+  optional bool data = 1;
+}
+
+// Test oneofs.
+message TestOneof {
+  oneof foo {
+    int32 foo_int = 1;
+    string foo_string = 2;
+    TestAllTypes foo_message = 3;
+    group FooGroup = 4 {
+      optional int32 a = 5;
+      optional string b = 6;
+    }
+  }
+}
+
+message TestOneofBackwardsCompatible {
+  optional int32 foo_int = 1;
+  optional string foo_string = 2;
+  optional TestAllTypes foo_message = 3;
+  optional group FooGroup = 4 {
+    optional int32 a = 5;
+    optional string b = 6;
+  }
+}
+
+message TestOneof2 {
+  oneof foo {
+    int32 foo_int = 1;
+    string foo_string = 2;
+    string foo_cord = 3 [ctype=CORD];
+    string foo_string_piece = 4 [ctype=STRING_PIECE];
+    bytes foo_bytes = 5;
+    NestedEnum foo_enum = 6;
+    NestedMessage foo_message = 7;
+    group FooGroup = 8 {
+      optional int32 a = 9;
+      optional string b = 10;
+    }
+    NestedMessage foo_lazy_message = 11 [lazy=true];
+  }
+
+  oneof bar {
+    int32 bar_int = 12 [default = 5];
+    string bar_string = 13 [default = "STRING"];
+    string bar_cord = 14 [ctype=CORD, default = "CORD"];
+    string bar_string_piece = 15 [ctype=STRING_PIECE, default = "SPIECE"];
+    bytes bar_bytes = 16 [default = "BYTES"];
+    NestedEnum bar_enum = 17 [default = BAR];
+  }
+
+  optional int32 baz_int = 18;
+  optional string baz_string = 19 [default = "BAZ"];
+
+  message NestedMessage {
+    optional int64 qux_int = 1;
+    repeated int32 corge_int = 2;
+  }
+
+  enum NestedEnum {
+    FOO = 1;
+    BAR = 2;
+    BAZ = 3;
+  }
+}
+
+message TestRequiredOneof {
+  oneof foo {
+    int32 foo_int = 1;
+    string foo_string = 2;
+    NestedMessage foo_message = 3;
+  }
+  message NestedMessage {
+    required double required_double = 1;
+  }
+}
+
+// Test messages for packed fields
+
+message TestPackedTypes {
+  repeated    int32 packed_int32    =  90 [packed = true];
+  repeated    int64 packed_int64    =  91 [packed = true];
+  repeated   uint32 packed_uint32   =  92 [packed = true];
+  repeated   uint64 packed_uint64   =  93 [packed = true];
+  repeated   sint32 packed_sint32   =  94 [packed = true];
+  repeated   sint64 packed_sint64   =  95 [packed = true];
+  repeated  fixed32 packed_fixed32  =  96 [packed = true];
+  repeated  fixed64 packed_fixed64  =  97 [packed = true];
+  repeated sfixed32 packed_sfixed32 =  98 [packed = true];
+  repeated sfixed64 packed_sfixed64 =  99 [packed = true];
+  repeated    float packed_float    = 100 [packed = true];
+  repeated   double packed_double   = 101 [packed = true];
+  repeated     bool packed_bool     = 102 [packed = true];
+  repeated ForeignEnum packed_enum  = 103 [packed = true];
+}
+
+// A message with the same fields as TestPackedTypes, but without packing. Used
+// to test packed <-> unpacked wire compatibility.
+message TestUnpackedTypes {
+  repeated    int32 unpacked_int32    =  90 [packed = false];
+  repeated    int64 unpacked_int64    =  91 [packed = false];
+  repeated   uint32 unpacked_uint32   =  92 [packed = false];
+  repeated   uint64 unpacked_uint64   =  93 [packed = false];
+  repeated   sint32 unpacked_sint32   =  94 [packed = false];
+  repeated   sint64 unpacked_sint64   =  95 [packed = false];
+  repeated  fixed32 unpacked_fixed32  =  96 [packed = false];
+  repeated  fixed64 unpacked_fixed64  =  97 [packed = false];
+  repeated sfixed32 unpacked_sfixed32 =  98 [packed = false];
+  repeated sfixed64 unpacked_sfixed64 =  99 [packed = false];
+  repeated    float unpacked_float    = 100 [packed = false];
+  repeated   double unpacked_double   = 101 [packed = false];
+  repeated     bool unpacked_bool     = 102 [packed = false];
+  repeated ForeignEnum unpacked_enum  = 103 [packed = false];
+}
+
+message TestPackedExtensions {
+  extensions 1 to max;
+}
+
+extend TestPackedExtensions {
+  repeated    int32 packed_int32_extension    =  90 [packed = true];
+  repeated    int64 packed_int64_extension    =  91 [packed = true];
+  repeated   uint32 packed_uint32_extension   =  92 [packed = true];
+  repeated   uint64 packed_uint64_extension   =  93 [packed = true];
+  repeated   sint32 packed_sint32_extension   =  94 [packed = true];
+  repeated   sint64 packed_sint64_extension   =  95 [packed = true];
+  repeated  fixed32 packed_fixed32_extension  =  96 [packed = true];
+  repeated  fixed64 packed_fixed64_extension  =  97 [packed = true];
+  repeated sfixed32 packed_sfixed32_extension =  98 [packed = true];
+  repeated sfixed64 packed_sfixed64_extension =  99 [packed = true];
+  repeated    float packed_float_extension    = 100 [packed = true];
+  repeated   double packed_double_extension   = 101 [packed = true];
+  repeated     bool packed_bool_extension     = 102 [packed = true];
+  repeated ForeignEnum packed_enum_extension  = 103 [packed = true];
+}
+
+message TestUnpackedExtensions {
+  extensions 1 to max;
+}
+
+extend TestUnpackedExtensions {
+  repeated    int32 unpacked_int32_extension    =  90 [packed = false];
+  repeated    int64 unpacked_int64_extension    =  91 [packed = false];
+  repeated   uint32 unpacked_uint32_extension   =  92 [packed = false];
+  repeated   uint64 unpacked_uint64_extension   =  93 [packed = false];
+  repeated   sint32 unpacked_sint32_extension   =  94 [packed = false];
+  repeated   sint64 unpacked_sint64_extension   =  95 [packed = false];
+  repeated  fixed32 unpacked_fixed32_extension  =  96 [packed = false];
+  repeated  fixed64 unpacked_fixed64_extension  =  97 [packed = false];
+  repeated sfixed32 unpacked_sfixed32_extension =  98 [packed = false];
+  repeated sfixed64 unpacked_sfixed64_extension =  99 [packed = false];
+  repeated    float unpacked_float_extension    = 100 [packed = false];
+  repeated   double unpacked_double_extension   = 101 [packed = false];
+  repeated     bool unpacked_bool_extension     = 102 [packed = false];
+  repeated ForeignEnum unpacked_enum_extension  = 103 [packed = false];
+}
+
+// Used by ExtensionSetTest/DynamicExtensions.  The test actually builds
+// a set of extensions to TestAllExtensions dynamically, based on the fields
+// of this message type.
+message TestDynamicExtensions {
+  enum DynamicEnumType {
+    DYNAMIC_FOO = 2200;
+    DYNAMIC_BAR = 2201;
+    DYNAMIC_BAZ = 2202;
+  }
+  message DynamicMessageType {
+    optional int32 dynamic_field = 2100;
+  }
+
+  optional fixed32 scalar_extension = 2000;
+  optional ForeignEnum enum_extension = 2001;
+  optional DynamicEnumType dynamic_enum_extension = 2002;
+
+  optional ForeignMessage message_extension = 2003;
+  optional DynamicMessageType dynamic_message_extension = 2004;
+
+  repeated string repeated_extension = 2005;
+  repeated sint32 packed_extension = 2006 [packed = true];
+}
+
+message TestRepeatedScalarDifferentTagSizes {
+  // Parsing repeated fixed size values used to fail. This message needs to be
+  // used in order to get a tag of the right size; all of the repeated fields
+  // in TestAllTypes didn't trigger the check.
+  repeated fixed32 repeated_fixed32 = 12;
+  // Check for a varint type, just for good measure.
+  repeated int32   repeated_int32   = 13;
+
+  // These have two-byte tags.
+  repeated fixed64 repeated_fixed64 = 2046;
+  repeated int64   repeated_int64   = 2047;
+
+  // Three byte tags.
+  repeated float   repeated_float   = 262142;
+  repeated uint64  repeated_uint64  = 262143;
+}
+
+// Test that if an optional or required message/group field appears multiple
+// times in the input, they need to be merged.
+message TestParsingMerge {
+  // RepeatedFieldsGenerator defines matching field types as TestParsingMerge,
+  // except that all fields are repeated. In the tests, we will serialize the
+  // RepeatedFieldsGenerator to bytes, and parse the bytes to TestParsingMerge.
+  // Repeated fields in RepeatedFieldsGenerator are expected to be merged into
+  // the corresponding required/optional fields in TestParsingMerge.
+  message RepeatedFieldsGenerator {
+    repeated TestAllTypes field1 = 1;
+    repeated TestAllTypes field2 = 2;
+    repeated TestAllTypes field3 = 3;
+    repeated group Group1 = 10 {
+      optional TestAllTypes field1 = 11;
+    }
+    repeated group Group2 = 20 {
+      optional TestAllTypes field1 = 21;
+    }
+    repeated TestAllTypes ext1 = 1000;
+    repeated TestAllTypes ext2 = 1001;
+  }
+  required TestAllTypes required_all_types = 1;
+  optional TestAllTypes optional_all_types = 2;
+  repeated TestAllTypes repeated_all_types = 3;
+  optional group OptionalGroup = 10 {
+    optional TestAllTypes optional_group_all_types = 11;
+  }
+  repeated group RepeatedGroup = 20 {
+    optional TestAllTypes repeated_group_all_types = 21;
+  }
+  extensions 1000 to max;
+  extend TestParsingMerge {
+    optional TestAllTypes optional_ext = 1000;
+    repeated TestAllTypes repeated_ext = 1001;
+  }
+}
+
+message TestCommentInjectionMessage {
+  // */ <- This should not close the generated doc comment
+  optional string a = 1 [default="*/ <- Neither should this."];
+}
+
+
+// Test that RPC services work.
+message FooRequest  {}
+message FooResponse {}
+
+message FooClientMessage {}
+message FooServerMessage{}
+
+service TestService {
+  rpc Foo(FooRequest) returns (FooResponse);
+  rpc Bar(BarRequest) returns (BarResponse);
+}
+
+
+message BarRequest  {}
+message BarResponse {}
+
diff --git a/protobuf/src/google/protobuf/unittest_accessors_nano.proto b/protobuf/src/google/protobuf/unittest_accessors_nano.proto
new file mode 100644
index 0000000..f1d4d34
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_accessors_nano.proto
@@ -0,0 +1,118 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "NanoAccessorsOuterClass";
+
+message TestNanoAccessors {
+
+  message NestedMessage {
+    optional int32 bb = 1;
+  }
+
+  enum NestedEnum {
+    FOO = 1;
+    BAR = 2;
+    BAZ = 3;
+  }
+
+  // Singular
+  optional int32  optional_int32    =  1;
+  optional float  optional_float    = 11;
+  optional double optional_double   = 12;
+  optional string optional_string   = 14;
+  optional bytes  optional_bytes    = 15;
+
+  optional NestedMessage optional_nested_message = 18;
+
+  optional NestedEnum optional_nested_enum = 21;
+
+  // Repeated
+  repeated int32  repeated_int32    = 31;
+  repeated string repeated_string   = 44;
+  repeated bytes  repeated_bytes    = 45;
+
+  repeated NestedMessage repeated_nested_message  = 48;
+
+  repeated NestedEnum repeated_nested_enum  = 51;
+
+  // Singular with defaults
+  optional int32  default_int32    = 61 [default =  41    ];
+  optional string default_string   = 74 [default = "hello"];
+  optional bytes  default_bytes    = 75 [default = "world"];
+
+  optional float default_float_nan = 99  [default =  nan];
+
+  optional NestedEnum default_nested_enum = 81 [default = BAR];
+
+  // Required
+  required int32 id = 86;
+
+  // Add enough optional fields to make 2 bit fields in total
+  optional int32 filler100 = 100;
+  optional int32 filler101 = 101;
+  optional int32 filler102 = 102;
+  optional int32 filler103 = 103;
+  optional int32 filler104 = 104;
+  optional int32 filler105 = 105;
+  optional int32 filler106 = 106;
+  optional int32 filler107 = 107;
+  optional int32 filler108 = 108;
+  optional int32 filler109 = 109;
+  optional int32 filler110 = 110;
+  optional int32 filler111 = 111;
+  optional int32 filler112 = 112;
+  optional int32 filler113 = 113;
+  optional int32 filler114 = 114;
+  optional int32 filler115 = 115;
+  optional int32 filler116 = 116;
+  optional int32 filler117 = 117;
+  optional int32 filler118 = 118;
+  optional int32 filler119 = 119;
+  optional int32 filler120 = 120;
+  optional int32 filler121 = 121;
+  optional int32 filler122 = 122;
+  optional int32 filler123 = 123;
+  optional int32 filler124 = 124;
+  optional int32 filler125 = 125;
+  optional int32 filler126 = 126;
+  optional int32 filler127 = 127;
+  optional int32 filler128 = 128;
+  optional int32 filler129 = 129;
+  optional int32 filler130 = 130;
+
+  optional int32 before_bit_field_check = 139;
+  optional int32 bit_field_check = 140;
+  optional int32 after_bit_field_check = 141;
+}
diff --git a/protobuf/src/google/protobuf/unittest_bytes_offset_length_nano.proto b/protobuf/src/google/protobuf/unittest_bytes_offset_length_nano.proto
new file mode 100644
index 0000000..629ead1
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_bytes_offset_length_nano.proto
@@ -0,0 +1,39 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "BytesOffsetLengthTestNanoOuterClass";
+
+message BytesOffsetLengthTestNano {
+  optional bytes foo = 1;
+  optional bytes bar = 2;
+}
diff --git a/protobuf/src/google/protobuf/unittest_custom_options.proto b/protobuf/src/google/protobuf/unittest_custom_options.proto
new file mode 100644
index 0000000..0bb12e1
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_custom_options.proto
@@ -0,0 +1,393 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: benjy@google.com (Benjy Weinberger)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file used to test the "custom options" feature of proto2.
+
+
+// Some generic_services option(s) added automatically.
+// See:  http://go/proto2-generic-services-default
+option cc_generic_services = true;     // auto-added
+option java_generic_services = true;   // auto-added
+option py_generic_services = true;
+
+// A custom file option (defined below).
+option (file_opt1) = 9876543210;
+
+import "google/protobuf/descriptor.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.
+package protobuf_unittest;
+
+
+// Some simple test custom options of various types.
+
+extend google.protobuf.FileOptions {
+  optional uint64 file_opt1 = 7736974;
+}
+
+extend google.protobuf.MessageOptions {
+  optional int32 message_opt1 = 7739036;
+}
+
+extend google.protobuf.FieldOptions {
+  optional fixed64 field_opt1 = 7740936;
+  // This is useful for testing that we correctly register default values for
+  // extension options.
+  optional int32 field_opt2 = 7753913 [default=42];
+}
+
+extend google.protobuf.EnumOptions {
+  optional sfixed32 enum_opt1 = 7753576;
+}
+
+extend google.protobuf.EnumValueOptions {
+  optional int32 enum_value_opt1 = 1560678;
+}
+
+extend google.protobuf.ServiceOptions {
+  optional sint64 service_opt1 = 7887650;
+}
+
+enum MethodOpt1 {
+  METHODOPT1_VAL1 = 1;
+  METHODOPT1_VAL2 = 2;
+}
+
+extend google.protobuf.MethodOptions {
+  optional MethodOpt1 method_opt1 = 7890860;
+}
+
+// A test message with custom options at all possible locations (and also some
+// regular options, to make sure they interact nicely).
+message TestMessageWithCustomOptions {
+  option message_set_wire_format = false;
+
+  option (message_opt1) = -56;
+
+  optional string field1 = 1 [ctype=CORD,
+                              (field_opt1)=8765432109];
+
+  enum AnEnum {
+    option (enum_opt1) = -789;
+
+    ANENUM_VAL1 = 1;
+    ANENUM_VAL2 = 2 [(enum_value_opt1) = 123];
+  }
+}
+
+
+// A test RPC service with custom options at all possible locations (and also
+// some regular options, to make sure they interact nicely).
+message CustomOptionFooRequest {
+}
+
+message CustomOptionFooResponse {
+}
+
+message CustomOptionFooClientMessage {
+}
+
+message CustomOptionFooServerMessage {
+}
+
+service TestServiceWithCustomOptions {
+  option (service_opt1) = -9876543210;
+
+  rpc Foo(CustomOptionFooRequest) returns (CustomOptionFooResponse) {
+    option (method_opt1) = METHODOPT1_VAL2;
+  }
+}
+
+
+
+// Options of every possible field type, so we can test them all exhaustively.
+
+message DummyMessageContainingEnum {
+  enum TestEnumType {
+    TEST_OPTION_ENUM_TYPE1 = 22;
+    TEST_OPTION_ENUM_TYPE2 = -23;
+  }
+}
+
+message DummyMessageInvalidAsOptionType {
+}
+
+extend google.protobuf.MessageOptions {
+  optional         bool     bool_opt = 7706090;
+  optional        int32    int32_opt = 7705709;
+  optional        int64    int64_opt = 7705542;
+  optional       uint32   uint32_opt = 7704880;
+  optional       uint64   uint64_opt = 7702367;
+  optional       sint32   sint32_opt = 7701568;
+  optional       sint64   sint64_opt = 7700863;
+  optional      fixed32  fixed32_opt = 7700307;
+  optional      fixed64  fixed64_opt = 7700194;
+  optional     sfixed32 sfixed32_opt = 7698645;
+  optional     sfixed64 sfixed64_opt = 7685475;
+  optional        float    float_opt = 7675390;
+  optional       double   double_opt = 7673293;
+  optional       string   string_opt = 7673285;
+  optional        bytes    bytes_opt = 7673238;
+  optional DummyMessageContainingEnum.TestEnumType enum_opt = 7673233;
+  optional DummyMessageInvalidAsOptionType message_type_opt = 7665967;
+}
+
+message CustomOptionMinIntegerValues {
+  option     (bool_opt) = false;
+  option    (int32_opt) = -0x80000000;
+  option    (int64_opt) = -0x8000000000000000;
+  option   (uint32_opt) = 0;
+  option   (uint64_opt) = 0;
+  option   (sint32_opt) = -0x80000000;
+  option   (sint64_opt) = -0x8000000000000000;
+  option  (fixed32_opt) = 0;
+  option  (fixed64_opt) = 0;
+  option (sfixed32_opt) = -0x80000000;
+  option (sfixed64_opt) = -0x8000000000000000;
+}
+
+message CustomOptionMaxIntegerValues {
+  option     (bool_opt) = true;
+  option    (int32_opt) = 0x7FFFFFFF;
+  option    (int64_opt) = 0x7FFFFFFFFFFFFFFF;
+  option   (uint32_opt) = 0xFFFFFFFF;
+  option   (uint64_opt) = 0xFFFFFFFFFFFFFFFF;
+  option   (sint32_opt) = 0x7FFFFFFF;
+  option   (sint64_opt) = 0x7FFFFFFFFFFFFFFF;
+  option  (fixed32_opt) = 0xFFFFFFFF;
+  option  (fixed64_opt) = 0xFFFFFFFFFFFFFFFF;
+  option (sfixed32_opt) = 0x7FFFFFFF;
+  option (sfixed64_opt) = 0x7FFFFFFFFFFFFFFF;
+}
+
+message CustomOptionOtherValues {
+  option  (int32_opt) = -100;  // To test sign-extension.
+  option  (float_opt) = 12.3456789;
+  option (double_opt) = 1.234567890123456789;
+  option (string_opt) = "Hello, \"World\"";
+  option  (bytes_opt) = "Hello\0World";
+  option   (enum_opt) = TEST_OPTION_ENUM_TYPE2;
+}
+
+message SettingRealsFromPositiveInts {
+  option  (float_opt) = 12;
+  option (double_opt) = 154;
+}
+
+message SettingRealsFromNegativeInts {
+  option  (float_opt) = -12;
+  option  (double_opt) = -154;
+}
+
+// Options of complex message types, themselves combined and extended in
+// various ways.
+
+message ComplexOptionType1 {
+  optional int32 foo = 1;
+  optional int32 foo2 = 2;
+  optional int32 foo3 = 3;
+  repeated int32 foo4 = 4;
+
+  extensions 100 to max;
+}
+
+message ComplexOptionType2 {
+  optional ComplexOptionType1 bar = 1;
+  optional int32 baz = 2;
+
+  message ComplexOptionType4 {
+    optional int32 waldo = 1;
+
+    extend google.protobuf.MessageOptions {
+      optional ComplexOptionType4 complex_opt4 = 7633546;
+    }
+  }
+
+  optional ComplexOptionType4 fred = 3;
+  repeated ComplexOptionType4 barney = 4;
+
+  extensions 100 to max;
+}
+
+message ComplexOptionType3 {
+  optional int32 qux = 1;
+
+  optional group ComplexOptionType5 = 2 {
+    optional int32 plugh = 3;
+  }
+}
+
+extend ComplexOptionType1 {
+  optional int32 quux = 7663707;
+  optional ComplexOptionType3 corge = 7663442;
+}
+
+extend ComplexOptionType2 {
+  optional int32 grault = 7650927;
+  optional ComplexOptionType1 garply = 7649992;
+}
+
+extend google.protobuf.MessageOptions {
+  optional protobuf_unittest.ComplexOptionType1 complex_opt1 = 7646756;
+  optional ComplexOptionType2 complex_opt2 = 7636949;
+  optional ComplexOptionType3 complex_opt3 = 7636463;
+  optional group ComplexOpt6 = 7595468 {
+    optional int32 xyzzy = 7593951;
+  }
+}
+
+// Note that we try various different ways of naming the same extension.
+message VariousComplexOptions {
+  option (.protobuf_unittest.complex_opt1).foo = 42;
+  option (protobuf_unittest.complex_opt1).(.protobuf_unittest.quux) = 324;
+  option (.protobuf_unittest.complex_opt1).(protobuf_unittest.corge).qux = 876;
+  option (protobuf_unittest.complex_opt1).foo4 = 99;
+  option (protobuf_unittest.complex_opt1).foo4 = 88;
+  option (complex_opt2).baz = 987;
+  option (complex_opt2).(grault) = 654;
+  option (complex_opt2).bar.foo = 743;
+  option (complex_opt2).bar.(quux) = 1999;
+  option (complex_opt2).bar.(protobuf_unittest.corge).qux = 2008;
+  option (complex_opt2).(garply).foo = 741;
+  option (complex_opt2).(garply).(.protobuf_unittest.quux) = 1998;
+  option (complex_opt2).(protobuf_unittest.garply).(corge).qux = 2121;
+  option (ComplexOptionType2.ComplexOptionType4.complex_opt4).waldo = 1971;
+  option (complex_opt2).fred.waldo = 321;
+  option (complex_opt2).barney = { waldo: 101 };
+  option (complex_opt2).barney = { waldo: 212 };
+  option (protobuf_unittest.complex_opt3).qux = 9;
+  option (complex_opt3).complexoptiontype5.plugh = 22;
+  option (complexopt6).xyzzy = 24;
+}
+
+// ------------------------------------------------------
+// Definitions for testing aggregate option parsing.
+// See descriptor_unittest.cc.
+
+message AggregateMessageSet {
+  option message_set_wire_format = true;
+  extensions 4 to max;
+}
+
+message AggregateMessageSetElement {
+  extend AggregateMessageSet {
+    optional AggregateMessageSetElement message_set_extension = 15447542;
+  }
+  optional string s = 1;
+}
+
+// A helper type used to test aggregate option parsing
+message Aggregate {
+  optional int32 i = 1;
+  optional string s = 2;
+
+  // A nested object
+  optional Aggregate sub = 3;
+
+  // To test the parsing of extensions inside aggregate values
+  optional google.protobuf.FileOptions file = 4;
+  extend google.protobuf.FileOptions {
+    optional Aggregate nested = 15476903;
+  }
+
+  // An embedded message set
+  optional AggregateMessageSet mset = 5;
+}
+
+// Allow Aggregate to be used as an option at all possible locations
+// in the .proto grammer.
+extend google.protobuf.FileOptions      { optional Aggregate fileopt    = 15478479; }
+extend google.protobuf.MessageOptions   { optional Aggregate msgopt     = 15480088; }
+extend google.protobuf.FieldOptions     { optional Aggregate fieldopt   = 15481374; }
+extend google.protobuf.EnumOptions      { optional Aggregate enumopt    = 15483218; }
+extend google.protobuf.EnumValueOptions { optional Aggregate enumvalopt = 15486921; }
+extend google.protobuf.ServiceOptions   { optional Aggregate serviceopt = 15497145; }
+extend google.protobuf.MethodOptions    { optional Aggregate methodopt  = 15512713; }
+
+// Try using AggregateOption at different points in the proto grammar
+option (fileopt) = {
+  s: 'FileAnnotation'
+  // Also test the handling of comments
+  /* of both types */ i: 100
+
+  sub { s: 'NestedFileAnnotation' }
+
+  // Include a google.protobuf.FileOptions and recursively extend it with
+  // another fileopt.
+  file {
+    [protobuf_unittest.fileopt] {
+      s:'FileExtensionAnnotation'
+    }
+  }
+
+  // A message set inside an option value
+  mset {
+    [protobuf_unittest.AggregateMessageSetElement.message_set_extension] {
+      s: 'EmbeddedMessageSetElement'
+    }
+  }
+};
+
+message AggregateMessage {
+  option (msgopt) = { i:101 s:'MessageAnnotation' };
+  optional int32 fieldname = 1 [(fieldopt) = { s:'FieldAnnotation' }];
+}
+
+service AggregateService {
+  option (serviceopt) = { s:'ServiceAnnotation' };
+  rpc Method (AggregateMessage) returns (AggregateMessage) {
+    option (methodopt) = { s:'MethodAnnotation' };
+  }
+}
+
+enum AggregateEnum {
+  option (enumopt) = { s:'EnumAnnotation' };
+  VALUE = 1 [(enumvalopt) = { s:'EnumValueAnnotation' }];
+}
+
+// Test custom options for nested type.
+message NestedOptionType {
+  message NestedMessage {
+    option (message_opt1) = 1001;
+    optional int32 nested_field = 1 [(field_opt1) = 1002];
+  }
+  enum NestedEnum {
+    option (enum_opt1) = 1003;
+    NESTED_ENUM_VALUE = 1 [(enum_value_opt1) = 1004];
+  }
+  extend google.protobuf.FileOptions {
+    optional int32 nested_extension = 7912573 [(field_opt2) = 1005];
+  }
+}
diff --git a/protobuf/src/google/protobuf/unittest_embed_optimize_for.proto b/protobuf/src/google/protobuf/unittest_embed_optimize_for.proto
new file mode 100644
index 0000000..ad51513
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_embed_optimize_for.proto
@@ -0,0 +1,50 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/protobuf/src/google/protobuf/unittest_empty.proto b/protobuf/src/google/protobuf/unittest_empty.proto
new file mode 100644
index 0000000..b7337ef
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_empty.proto
@@ -0,0 +1,37 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file intentionally left blank.  (At one point this wouldn't compile
+// correctly.)
+
diff --git a/protobuf/src/google/protobuf/unittest_enormous_descriptor.proto b/protobuf/src/google/protobuf/unittest_enormous_descriptor.proto
new file mode 100644
index 0000000..3ba8b41
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_enormous_descriptor.proto
@@ -0,0 +1,1046 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+//
+// A proto file that has an extremely large descriptor.  Used to test that
+// descriptors over 64k don't break the string literal length limit in Java.
+
+
+package google.protobuf;
+option java_package = "com.google.protobuf";
+
+// Avoid generating insanely long methods.
+option optimize_for = CODE_SIZE;
+
+message TestEnormousDescriptor {
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1 = 1 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_2 = 2 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_3 = 3 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_4 = 4 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_5 = 5 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_6 = 6 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_7 = 7 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_8 = 8 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_9 = 9 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_10 = 10 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_11 = 11 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_12 = 12 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_13 = 13 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_14 = 14 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_15 = 15 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_16 = 16 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_17 = 17 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_18 = 18 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_19 = 19 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_20 = 20 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_21 = 21 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_22 = 22 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_23 = 23 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_24 = 24 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_25 = 25 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_26 = 26 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_27 = 27 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_28 = 28 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_29 = 29 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_30 = 30 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_31 = 31 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_32 = 32 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_33 = 33 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_34 = 34 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_35 = 35 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_36 = 36 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_37 = 37 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_38 = 38 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_39 = 39 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_40 = 40 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_41 = 41 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_42 = 42 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_43 = 43 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_44 = 44 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_45 = 45 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_46 = 46 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_47 = 47 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_48 = 48 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_49 = 49 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_50 = 50 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_51 = 51 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_52 = 52 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_53 = 53 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_54 = 54 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_55 = 55 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_56 = 56 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_57 = 57 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_58 = 58 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_59 = 59 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_60 = 60 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_61 = 61 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_62 = 62 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_63 = 63 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_64 = 64 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_65 = 65 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_66 = 66 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_67 = 67 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_68 = 68 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_69 = 69 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_70 = 70 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_71 = 71 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_72 = 72 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_73 = 73 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_74 = 74 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_75 = 75 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_76 = 76 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_77 = 77 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_78 = 78 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_79 = 79 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_80 = 80 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_81 = 81 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_82 = 82 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_83 = 83 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_84 = 84 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_85 = 85 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_86 = 86 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_87 = 87 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_88 = 88 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_89 = 89 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_90 = 90 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_91 = 91 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_92 = 92 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_93 = 93 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_94 = 94 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_95 = 95 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_96 = 96 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_97 = 97 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_98 = 98 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_99 = 99 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_100 = 100 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_101 = 101 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_102 = 102 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_103 = 103 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_104 = 104 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_105 = 105 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_106 = 106 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_107 = 107 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_108 = 108 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_109 = 109 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_110 = 110 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_111 = 111 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_112 = 112 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_113 = 113 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_114 = 114 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_115 = 115 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_116 = 116 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_117 = 117 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_118 = 118 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_119 = 119 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_120 = 120 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_121 = 121 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_122 = 122 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_123 = 123 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_124 = 124 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_125 = 125 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_126 = 126 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_127 = 127 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_128 = 128 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_129 = 129 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_130 = 130 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_131 = 131 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_132 = 132 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_133 = 133 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_134 = 134 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_135 = 135 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_136 = 136 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_137 = 137 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_138 = 138 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_139 = 139 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_140 = 140 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_141 = 141 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_142 = 142 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_143 = 143 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_144 = 144 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_145 = 145 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_146 = 146 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_147 = 147 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_148 = 148 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_149 = 149 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_150 = 150 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_151 = 151 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_152 = 152 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_153 = 153 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_154 = 154 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_155 = 155 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_156 = 156 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_157 = 157 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_158 = 158 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_159 = 159 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_160 = 160 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_161 = 161 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_162 = 162 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_163 = 163 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_164 = 164 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_165 = 165 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_166 = 166 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_167 = 167 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_168 = 168 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_169 = 169 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_170 = 170 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_171 = 171 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_172 = 172 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_173 = 173 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_174 = 174 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_175 = 175 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_176 = 176 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_177 = 177 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_178 = 178 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_179 = 179 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_180 = 180 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_181 = 181 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_182 = 182 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_183 = 183 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_184 = 184 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_185 = 185 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_186 = 186 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_187 = 187 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_188 = 188 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_189 = 189 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_190 = 190 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_191 = 191 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_192 = 192 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_193 = 193 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_194 = 194 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_195 = 195 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_196 = 196 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_197 = 197 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_198 = 198 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_199 = 199 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_200 = 200 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_201 = 201 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_202 = 202 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_203 = 203 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_204 = 204 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_205 = 205 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_206 = 206 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_207 = 207 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_208 = 208 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_209 = 209 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_210 = 210 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_211 = 211 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_212 = 212 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_213 = 213 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_214 = 214 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_215 = 215 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_216 = 216 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_217 = 217 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_218 = 218 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_219 = 219 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_220 = 220 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_221 = 221 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_222 = 222 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_223 = 223 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_224 = 224 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_225 = 225 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_226 = 226 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_227 = 227 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_228 = 228 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_229 = 229 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_230 = 230 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_231 = 231 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_232 = 232 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_233 = 233 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_234 = 234 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_235 = 235 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_236 = 236 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_237 = 237 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_238 = 238 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_239 = 239 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_240 = 240 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_241 = 241 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_242 = 242 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_243 = 243 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_244 = 244 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_245 = 245 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_246 = 246 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_247 = 247 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_248 = 248 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_249 = 249 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_250 = 250 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_251 = 251 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_252 = 252 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_253 = 253 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_254 = 254 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_255 = 255 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_256 = 256 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_257 = 257 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_258 = 258 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_259 = 259 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_260 = 260 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_261 = 261 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_262 = 262 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_263 = 263 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_264 = 264 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_265 = 265 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_266 = 266 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_267 = 267 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_268 = 268 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_269 = 269 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_270 = 270 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_271 = 271 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_272 = 272 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_273 = 273 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_274 = 274 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_275 = 275 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_276 = 276 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_277 = 277 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_278 = 278 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_279 = 279 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_280 = 280 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_281 = 281 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_282 = 282 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_283 = 283 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_284 = 284 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_285 = 285 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_286 = 286 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_287 = 287 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_288 = 288 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_289 = 289 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_290 = 290 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_291 = 291 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_292 = 292 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_293 = 293 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_294 = 294 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_295 = 295 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_296 = 296 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_297 = 297 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_298 = 298 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_299 = 299 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_300 = 300 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_301 = 301 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_302 = 302 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_303 = 303 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_304 = 304 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_305 = 305 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_306 = 306 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_307 = 307 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_308 = 308 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_309 = 309 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_310 = 310 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_311 = 311 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_312 = 312 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_313 = 313 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_314 = 314 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_315 = 315 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_316 = 316 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_317 = 317 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_318 = 318 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_319 = 319 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_320 = 320 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_321 = 321 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_322 = 322 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_323 = 323 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_324 = 324 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_325 = 325 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_326 = 326 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_327 = 327 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_328 = 328 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_329 = 329 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_330 = 330 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_331 = 331 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_332 = 332 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_333 = 333 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_334 = 334 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_335 = 335 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_336 = 336 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_337 = 337 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_338 = 338 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_339 = 339 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_340 = 340 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_341 = 341 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_342 = 342 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_343 = 343 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_344 = 344 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_345 = 345 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_346 = 346 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_347 = 347 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_348 = 348 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_349 = 349 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_350 = 350 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_351 = 351 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_352 = 352 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_353 = 353 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_354 = 354 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_355 = 355 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_356 = 356 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_357 = 357 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_358 = 358 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_359 = 359 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_360 = 360 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_361 = 361 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_362 = 362 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_363 = 363 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_364 = 364 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_365 = 365 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_366 = 366 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_367 = 367 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_368 = 368 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_369 = 369 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_370 = 370 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_371 = 371 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_372 = 372 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_373 = 373 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_374 = 374 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_375 = 375 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_376 = 376 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_377 = 377 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_378 = 378 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_379 = 379 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_380 = 380 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_381 = 381 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_382 = 382 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_383 = 383 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_384 = 384 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_385 = 385 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_386 = 386 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_387 = 387 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_388 = 388 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_389 = 389 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_390 = 390 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_391 = 391 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_392 = 392 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_393 = 393 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_394 = 394 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_395 = 395 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_396 = 396 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_397 = 397 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_398 = 398 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_399 = 399 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_400 = 400 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_401 = 401 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_402 = 402 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_403 = 403 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_404 = 404 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_405 = 405 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_406 = 406 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_407 = 407 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_408 = 408 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_409 = 409 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_410 = 410 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_411 = 411 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_412 = 412 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_413 = 413 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_414 = 414 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_415 = 415 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_416 = 416 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_417 = 417 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_418 = 418 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_419 = 419 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_420 = 420 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_421 = 421 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_422 = 422 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_423 = 423 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_424 = 424 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_425 = 425 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_426 = 426 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_427 = 427 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_428 = 428 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_429 = 429 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_430 = 430 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_431 = 431 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_432 = 432 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_433 = 433 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_434 = 434 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_435 = 435 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_436 = 436 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_437 = 437 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_438 = 438 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_439 = 439 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_440 = 440 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_441 = 441 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_442 = 442 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_443 = 443 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_444 = 444 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_445 = 445 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_446 = 446 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_447 = 447 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_448 = 448 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_449 = 449 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_450 = 450 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_451 = 451 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_452 = 452 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_453 = 453 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_454 = 454 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_455 = 455 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_456 = 456 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_457 = 457 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_458 = 458 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_459 = 459 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_460 = 460 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_461 = 461 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_462 = 462 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_463 = 463 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_464 = 464 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_465 = 465 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_466 = 466 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_467 = 467 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_468 = 468 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_469 = 469 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_470 = 470 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_471 = 471 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_472 = 472 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_473 = 473 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_474 = 474 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_475 = 475 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_476 = 476 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_477 = 477 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_478 = 478 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_479 = 479 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_480 = 480 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_481 = 481 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_482 = 482 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_483 = 483 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_484 = 484 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_485 = 485 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_486 = 486 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_487 = 487 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_488 = 488 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_489 = 489 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_490 = 490 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_491 = 491 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_492 = 492 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_493 = 493 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_494 = 494 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_495 = 495 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_496 = 496 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_497 = 497 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_498 = 498 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_499 = 499 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_500 = 500 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_501 = 501 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_502 = 502 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_503 = 503 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_504 = 504 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_505 = 505 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_506 = 506 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_507 = 507 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_508 = 508 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_509 = 509 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_510 = 510 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_511 = 511 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_512 = 512 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_513 = 513 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_514 = 514 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_515 = 515 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_516 = 516 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_517 = 517 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_518 = 518 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_519 = 519 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_520 = 520 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_521 = 521 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_522 = 522 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_523 = 523 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_524 = 524 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_525 = 525 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_526 = 526 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_527 = 527 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_528 = 528 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_529 = 529 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_530 = 530 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_531 = 531 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_532 = 532 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_533 = 533 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_534 = 534 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_535 = 535 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_536 = 536 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_537 = 537 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_538 = 538 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_539 = 539 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_540 = 540 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_541 = 541 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_542 = 542 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_543 = 543 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_544 = 544 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_545 = 545 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_546 = 546 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_547 = 547 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_548 = 548 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_549 = 549 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_550 = 550 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_551 = 551 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_552 = 552 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_553 = 553 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_554 = 554 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_555 = 555 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_556 = 556 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_557 = 557 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_558 = 558 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_559 = 559 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_560 = 560 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_561 = 561 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_562 = 562 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_563 = 563 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_564 = 564 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_565 = 565 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_566 = 566 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_567 = 567 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_568 = 568 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_569 = 569 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_570 = 570 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_571 = 571 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_572 = 572 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_573 = 573 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_574 = 574 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_575 = 575 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_576 = 576 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_577 = 577 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_578 = 578 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_579 = 579 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_580 = 580 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_581 = 581 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_582 = 582 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_583 = 583 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_584 = 584 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_585 = 585 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_586 = 586 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_587 = 587 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_588 = 588 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_589 = 589 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_590 = 590 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_591 = 591 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_592 = 592 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_593 = 593 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_594 = 594 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_595 = 595 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_596 = 596 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_597 = 597 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_598 = 598 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_599 = 599 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_600 = 600 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_601 = 601 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_602 = 602 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_603 = 603 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_604 = 604 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_605 = 605 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_606 = 606 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_607 = 607 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_608 = 608 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_609 = 609 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_610 = 610 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_611 = 611 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_612 = 612 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_613 = 613 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_614 = 614 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_615 = 615 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_616 = 616 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_617 = 617 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_618 = 618 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_619 = 619 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_620 = 620 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_621 = 621 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_622 = 622 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_623 = 623 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_624 = 624 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_625 = 625 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_626 = 626 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_627 = 627 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_628 = 628 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_629 = 629 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_630 = 630 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_631 = 631 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_632 = 632 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_633 = 633 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_634 = 634 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_635 = 635 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_636 = 636 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_637 = 637 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_638 = 638 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_639 = 639 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_640 = 640 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_641 = 641 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_642 = 642 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_643 = 643 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_644 = 644 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_645 = 645 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_646 = 646 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_647 = 647 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_648 = 648 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_649 = 649 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_650 = 650 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_651 = 651 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_652 = 652 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_653 = 653 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_654 = 654 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_655 = 655 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_656 = 656 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_657 = 657 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_658 = 658 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_659 = 659 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_660 = 660 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_661 = 661 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_662 = 662 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_663 = 663 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_664 = 664 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_665 = 665 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_666 = 666 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_667 = 667 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_668 = 668 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_669 = 669 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_670 = 670 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_671 = 671 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_672 = 672 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_673 = 673 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_674 = 674 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_675 = 675 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_676 = 676 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_677 = 677 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_678 = 678 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_679 = 679 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_680 = 680 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_681 = 681 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_682 = 682 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_683 = 683 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_684 = 684 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_685 = 685 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_686 = 686 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_687 = 687 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_688 = 688 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_689 = 689 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_690 = 690 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_691 = 691 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_692 = 692 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_693 = 693 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_694 = 694 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_695 = 695 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_696 = 696 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_697 = 697 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_698 = 698 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_699 = 699 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_700 = 700 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_701 = 701 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_702 = 702 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_703 = 703 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_704 = 704 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_705 = 705 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_706 = 706 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_707 = 707 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_708 = 708 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_709 = 709 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_710 = 710 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_711 = 711 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_712 = 712 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_713 = 713 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_714 = 714 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_715 = 715 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_716 = 716 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_717 = 717 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_718 = 718 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_719 = 719 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_720 = 720 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_721 = 721 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_722 = 722 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_723 = 723 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_724 = 724 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_725 = 725 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_726 = 726 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_727 = 727 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_728 = 728 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_729 = 729 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_730 = 730 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_731 = 731 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_732 = 732 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_733 = 733 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_734 = 734 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_735 = 735 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_736 = 736 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_737 = 737 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_738 = 738 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_739 = 739 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_740 = 740 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_741 = 741 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_742 = 742 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_743 = 743 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_744 = 744 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_745 = 745 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_746 = 746 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_747 = 747 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_748 = 748 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_749 = 749 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_750 = 750 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_751 = 751 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_752 = 752 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_753 = 753 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_754 = 754 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_755 = 755 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_756 = 756 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_757 = 757 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_758 = 758 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_759 = 759 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_760 = 760 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_761 = 761 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_762 = 762 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_763 = 763 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_764 = 764 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_765 = 765 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_766 = 766 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_767 = 767 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_768 = 768 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_769 = 769 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_770 = 770 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_771 = 771 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_772 = 772 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_773 = 773 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_774 = 774 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_775 = 775 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_776 = 776 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_777 = 777 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_778 = 778 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_779 = 779 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_780 = 780 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_781 = 781 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_782 = 782 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_783 = 783 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_784 = 784 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_785 = 785 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_786 = 786 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_787 = 787 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_788 = 788 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_789 = 789 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_790 = 790 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_791 = 791 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_792 = 792 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_793 = 793 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_794 = 794 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_795 = 795 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_796 = 796 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_797 = 797 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_798 = 798 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_799 = 799 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_800 = 800 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_801 = 801 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_802 = 802 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_803 = 803 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_804 = 804 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_805 = 805 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_806 = 806 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_807 = 807 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_808 = 808 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_809 = 809 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_810 = 810 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_811 = 811 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_812 = 812 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_813 = 813 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_814 = 814 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_815 = 815 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_816 = 816 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_817 = 817 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_818 = 818 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_819 = 819 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_820 = 820 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_821 = 821 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_822 = 822 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_823 = 823 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_824 = 824 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_825 = 825 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_826 = 826 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_827 = 827 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_828 = 828 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_829 = 829 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_830 = 830 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_831 = 831 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_832 = 832 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_833 = 833 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_834 = 834 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_835 = 835 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_836 = 836 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_837 = 837 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_838 = 838 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_839 = 839 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_840 = 840 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_841 = 841 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_842 = 842 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_843 = 843 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_844 = 844 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_845 = 845 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_846 = 846 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_847 = 847 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_848 = 848 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_849 = 849 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_850 = 850 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_851 = 851 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_852 = 852 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_853 = 853 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_854 = 854 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_855 = 855 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_856 = 856 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_857 = 857 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_858 = 858 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_859 = 859 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_860 = 860 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_861 = 861 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_862 = 862 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_863 = 863 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_864 = 864 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_865 = 865 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_866 = 866 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_867 = 867 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_868 = 868 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_869 = 869 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_870 = 870 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_871 = 871 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_872 = 872 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_873 = 873 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_874 = 874 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_875 = 875 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_876 = 876 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_877 = 877 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_878 = 878 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_879 = 879 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_880 = 880 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_881 = 881 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_882 = 882 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_883 = 883 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_884 = 884 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_885 = 885 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_886 = 886 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_887 = 887 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_888 = 888 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_889 = 889 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_890 = 890 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_891 = 891 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_892 = 892 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_893 = 893 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_894 = 894 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_895 = 895 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_896 = 896 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_897 = 897 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_898 = 898 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_899 = 899 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_900 = 900 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_901 = 901 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_902 = 902 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_903 = 903 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_904 = 904 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_905 = 905 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_906 = 906 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_907 = 907 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_908 = 908 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_909 = 909 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_910 = 910 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_911 = 911 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_912 = 912 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_913 = 913 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_914 = 914 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_915 = 915 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_916 = 916 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_917 = 917 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_918 = 918 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_919 = 919 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_920 = 920 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_921 = 921 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_922 = 922 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_923 = 923 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_924 = 924 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_925 = 925 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_926 = 926 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_927 = 927 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_928 = 928 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_929 = 929 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_930 = 930 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_931 = 931 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_932 = 932 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_933 = 933 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_934 = 934 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_935 = 935 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_936 = 936 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_937 = 937 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_938 = 938 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_939 = 939 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_940 = 940 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_941 = 941 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_942 = 942 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_943 = 943 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_944 = 944 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_945 = 945 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_946 = 946 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_947 = 947 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_948 = 948 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_949 = 949 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_950 = 950 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_951 = 951 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_952 = 952 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_953 = 953 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_954 = 954 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_955 = 955 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_956 = 956 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_957 = 957 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_958 = 958 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_959 = 959 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_960 = 960 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_961 = 961 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_962 = 962 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_963 = 963 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_964 = 964 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_965 = 965 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_966 = 966 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_967 = 967 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_968 = 968 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_969 = 969 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_970 = 970 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_971 = 971 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_972 = 972 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_973 = 973 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_974 = 974 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_975 = 975 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_976 = 976 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_977 = 977 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_978 = 978 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_979 = 979 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_980 = 980 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_981 = 981 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_982 = 982 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_983 = 983 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_984 = 984 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_985 = 985 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_986 = 986 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_987 = 987 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_988 = 988 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_989 = 989 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_990 = 990 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_991 = 991 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_992 = 992 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_993 = 993 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_994 = 994 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_995 = 995 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_996 = 996 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_997 = 997 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_998 = 998 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_999 = 999 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+  optional string long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000 = 1000 [default="long default value is also loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong"];
+}
diff --git a/protobuf/src/google/protobuf/unittest_enum_class_multiple_nano.proto b/protobuf/src/google/protobuf/unittest_enum_class_multiple_nano.proto
new file mode 100644
index 0000000..8adb756
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_enum_class_multiple_nano.proto
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_multiple_files = true;
+
+enum FileScopeEnumMultiple {
+  THREE = 3;
+}
+
+message EnumClassNanoMultiple {
+  enum MessageScopeEnumMultiple {
+    FOUR = 4;
+  }
+  optional FileScopeEnumMultiple three = 3 [ default = THREE ];
+  optional MessageScopeEnumMultiple four = 4 [ default = FOUR ];
+}
diff --git a/protobuf/src/google/protobuf/unittest_enum_class_nano.proto b/protobuf/src/google/protobuf/unittest_enum_class_nano.proto
new file mode 100644
index 0000000..3727d68
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_enum_class_nano.proto
@@ -0,0 +1,48 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "EnumClassNanos";
+
+enum FileScopeEnum {
+  ONE = 1;
+}
+
+message EnumClassNano {
+  enum MessageScopeEnum {
+    TWO = 2;
+  }
+  optional FileScopeEnum one = 1 [ default = ONE ];
+  optional MessageScopeEnum two = 2 [ default = TWO ];
+}
diff --git a/protobuf/src/google/protobuf/unittest_enum_validity_nano.proto b/protobuf/src/google/protobuf/unittest_enum_validity_nano.proto
new file mode 100644
index 0000000..f7f5742
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_enum_validity_nano.proto
@@ -0,0 +1,28 @@
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "EnumValidity";
+
+enum E {
+  default = 1; // test java keyword renaming
+  FOO = 2;
+  BAR = 3;
+  BAZ = 4;
+}
+
+message M {
+  optional E optional_e = 1;
+  optional E default_e = 2 [ default = BAZ ];
+  repeated E repeated_e = 3;
+  repeated E packed_e = 4 [ packed = true ];
+  repeated E repeated_e2 = 5;
+  repeated E packed_e2 = 6 [ packed = true ];
+  repeated E repeated_e3 = 7;
+  repeated E packed_e3 = 8 [ packed = true ];
+}
+
+message Alt {
+  optional E repeated_e2_as_optional = 5;
+  repeated E packed_e2_as_non_packed = 6;
+  repeated E non_packed_e3_as_packed = 7 [ packed = true ];
+}
diff --git a/protobuf/src/google/protobuf/unittest_extension_nano.proto b/protobuf/src/google/protobuf/unittest_extension_nano.proto
new file mode 100644
index 0000000..ca56b3d
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_extension_nano.proto
@@ -0,0 +1,37 @@
+syntax = "proto2";
+
+option java_outer_classname = "Extensions";
+option java_package = "com.google.protobuf.nano.testext";
+
+message ExtendableMessage {
+  optional int32 field = 1;
+  extensions 10 to max;
+}
+
+enum AnEnum {
+  FIRST_VALUE = 1;
+  SECOND_VALUE = 2;
+}
+
+message AnotherMessage {
+  optional string string = 1;
+  optional bool value = 2;
+  repeated int32 integers = 3;
+}
+
+message ContainerMessage {
+  extend ExtendableMessage {
+    optional bool another_thing = 100;
+    // The largest permitted field number, per
+    // https://developers.google.com/protocol-buffers/docs/proto#simple
+    optional bool large_field_number = 536870911;
+  }
+}
+
+// For testNanoOptionalGroupWithUnknownFieldsEnabled;
+// not part of the extensions tests.
+message MessageWithGroup {
+  optional group Group = 1 {
+    optional int32 a = 2;
+  }
+}
diff --git a/protobuf/src/google/protobuf/unittest_extension_packed_nano.proto b/protobuf/src/google/protobuf/unittest_extension_packed_nano.proto
new file mode 100644
index 0000000..3586de7
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_extension_packed_nano.proto
@@ -0,0 +1,29 @@
+syntax = "proto2";
+
+option java_multiple_files = true;
+option java_package = "com.google.protobuf.nano";
+
+import "google/protobuf/unittest_extension_nano.proto";
+
+// Must be compiled separately due to extension number reuse.
+// The reuse is deliberate, for testing wire compatibility.
+
+message PackedExtensions {
+  extend ExtendableMessage {
+    repeated int32    packed_int32    = 10 [ packed = true ];
+    repeated uint32   packed_uint32   = 11 [ packed = true ];
+    repeated sint32   packed_sint32   = 12 [ packed = true ];
+    repeated int64    packed_int64    = 13 [ packed = true ];
+    repeated uint64   packed_uint64   = 14 [ packed = true ];
+    repeated sint64   packed_sint64   = 15 [ packed = true ];
+    repeated fixed32  packed_fixed32  = 16 [ packed = true ];
+    repeated sfixed32 packed_sfixed32 = 17 [ packed = true ];
+    repeated fixed64  packed_fixed64  = 18 [ packed = true ];
+    repeated sfixed64 packed_sfixed64 = 19 [ packed = true ];
+    repeated bool     packed_bool     = 20 [ packed = true ];
+    repeated float    packed_float    = 21 [ packed = true ];
+    repeated double   packed_double   = 22 [ packed = true ];
+    repeated AnEnum   packed_enum     = 23 [ packed = true ];
+    // Non-packable types omitted.
+  }
+}
diff --git a/protobuf/src/google/protobuf/unittest_extension_repeated_nano.proto b/protobuf/src/google/protobuf/unittest_extension_repeated_nano.proto
new file mode 100644
index 0000000..546c2df
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_extension_repeated_nano.proto
@@ -0,0 +1,34 @@
+syntax = "proto2";
+
+option java_multiple_files = true;
+option java_package = "com.google.protobuf.nano";
+
+import "google/protobuf/unittest_extension_nano.proto";
+
+// Must be compiled separately due to extension number reuse.
+// The reuse is deliberate, for testing wire compatibility.
+
+message RepeatedExtensions {
+  extend ExtendableMessage {
+    repeated int32          repeated_int32    = 10;
+    repeated uint32         repeated_uint32   = 11;
+    repeated sint32         repeated_sint32   = 12;
+    repeated int64          repeated_int64    = 13;
+    repeated uint64         repeated_uint64   = 14;
+    repeated sint64         repeated_sint64   = 15;
+    repeated fixed32        repeated_fixed32  = 16;
+    repeated sfixed32       repeated_sfixed32 = 17;
+    repeated fixed64        repeated_fixed64  = 18;
+    repeated sfixed64       repeated_sfixed64 = 19;
+    repeated bool           repeated_bool     = 20;
+    repeated float          repeated_float    = 21;
+    repeated double         repeated_double   = 22;
+    repeated AnEnum         repeated_enum     = 23;
+    repeated string         repeated_string   = 24;
+    repeated bytes          repeated_bytes    = 25;
+    repeated AnotherMessage repeated_message  = 26;
+    repeated group          RepeatedGroup     = 27 {
+      optional int32 a = 1;
+    }
+  }
+}
diff --git a/protobuf/src/google/protobuf/unittest_extension_singular_nano.proto b/protobuf/src/google/protobuf/unittest_extension_singular_nano.proto
new file mode 100644
index 0000000..35d9e6e
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_extension_singular_nano.proto
@@ -0,0 +1,34 @@
+syntax = "proto2";
+
+option java_multiple_files = true;
+option java_package = "com.google.protobuf.nano";
+
+import "google/protobuf/unittest_extension_nano.proto";
+
+// Must be compiled separately due to extension number reuse.
+// The reuse is deliberate, for testing wire compatibility.
+
+message SingularExtensions {
+  extend ExtendableMessage {
+    optional int32          some_int32    = 10;
+    optional uint32         some_uint32   = 11;
+    optional sint32         some_sint32   = 12;
+    optional int64          some_int64    = 13;
+    optional uint64         some_uint64   = 14;
+    optional sint64         some_sint64   = 15;
+    optional fixed32        some_fixed32  = 16;
+    optional sfixed32       some_sfixed32 = 17;
+    optional fixed64        some_fixed64  = 18;
+    optional sfixed64       some_sfixed64 = 19;
+    optional bool           some_bool     = 20;
+    optional float          some_float    = 21;
+    optional double         some_double   = 22;
+    optional AnEnum         some_enum     = 23;
+    optional string         some_string   = 24;
+    optional bytes          some_bytes    = 25;
+    optional AnotherMessage some_message  = 26;
+    optional group          SomeGroup     = 27 {
+      optional int32 a = 1;
+    }
+  }
+}
diff --git a/protobuf/src/google/protobuf/unittest_has_nano.proto b/protobuf/src/google/protobuf/unittest_has_nano.proto
new file mode 100644
index 0000000..289d08a
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_has_nano.proto
@@ -0,0 +1,82 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: ulas@google.com (Ulas Kirazci)
+
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "NanoHasOuterClass";
+
+message TestAllTypesNanoHas {
+
+  message NestedMessage {
+    optional int32 bb = 1;
+  }
+
+  enum NestedEnum {
+    FOO = 1;
+    BAR = 2;
+    BAZ = 3;
+  }
+
+  // Singular
+  optional int32  optional_int32    =  1;
+  optional float  optional_float    = 11;
+  optional double optional_double   = 12;
+  optional string optional_string   = 14;
+  optional bytes  optional_bytes    = 15;
+
+  optional NestedMessage optional_nested_message = 18;
+
+  optional NestedEnum optional_nested_enum = 21;
+
+  // Repeated
+  repeated int32  repeated_int32    = 31;
+  repeated string repeated_string   = 44;
+  repeated bytes  repeated_bytes    = 45;
+
+  repeated NestedMessage repeated_nested_message  = 48;
+
+  repeated NestedEnum repeated_nested_enum  = 51;
+
+  // Singular with defaults
+  optional int32  default_int32    = 61 [default =  41    ];
+  optional string default_string   = 74 [default = "hello"];
+  optional bytes  default_bytes    = 75 [default = "world"];
+
+  optional float default_float_nan = 99  [default =  nan];
+
+  optional NestedEnum default_nested_enum = 81 [default = BAR];
+
+  required int32 id = 86;
+  required NestedEnum required_enum = 87;
+
+}
diff --git a/protobuf/src/google/protobuf/unittest_import.proto b/protobuf/src/google/protobuf/unittest_import.proto
new file mode 100644
index 0000000..38275dc
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_import.proto
@@ -0,0 +1,64 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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.
+
+// Test public import
+import public "google/protobuf/unittest_import_public.proto";
+
+message ImportMessage {
+  optional int32 d = 1;
+}
+
+enum ImportEnum {
+  IMPORT_FOO = 7;
+  IMPORT_BAR = 8;
+  IMPORT_BAZ = 9;
+}
+
diff --git a/protobuf/src/google/protobuf/unittest_import_lite.proto b/protobuf/src/google/protobuf/unittest_import_lite.proto
new file mode 100644
index 0000000..7cee113
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_import_lite.proto
@@ -0,0 +1,51 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is like unittest_import.proto but with optimize_for = LITE_RUNTIME.
+
+package protobuf_unittest_import;
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+import public "google/protobuf/unittest_import_public_lite.proto";
+
+message ImportMessageLite {
+  optional int32 d = 1;
+}
+
+enum ImportEnumLite {
+  IMPORT_LITE_FOO = 7;
+  IMPORT_LITE_BAR = 8;
+  IMPORT_LITE_BAZ = 9;
+}
diff --git a/protobuf/src/google/protobuf/unittest_import_micro.proto b/protobuf/src/google/protobuf/unittest_import_micro.proto
new file mode 100644
index 0000000..adac807
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_import_micro.proto
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//
+// This is like unittest_import.proto but with optimize_for = MICRO_RUNTIME.
+
+package protobuf_unittest_import;
+
+// java_package and java_outer_classname are specified on the command line.
+//option java_package = "com.google.protobuf.micro";
+//option java_outer_classname = "UnittestImportMicro";
+
+message ImportMessageMicro {
+  optional int32 d = 1;
+}
+
+enum ImportEnumMicro {
+  IMPORT_MICRO_FOO = 7;
+  IMPORT_MICRO_BAR = 8;
+  IMPORT_MICRO_BAZ = 9;
+}
diff --git a/protobuf/src/google/protobuf/unittest_import_nano.proto b/protobuf/src/google/protobuf/unittest_import_nano.proto
new file mode 100644
index 0000000..0a2fde7
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_import_nano.proto
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: kenton@google.com (Kenton Varda)
+//
+// This is like unittest_import.proto but with optimize_for = NANO_RUNTIME.
+
+package protobuf_unittest_import;
+
+// java_package and java_outer_classname are specified on the command line.
+//option java_package = "com.google.protobuf.nano.testimport";
+//option java_outer_classname = "UnittestImportNano";
+
+message ImportMessageNano {
+  optional int32 d = 1;
+}
+
+enum ImportEnumNano {
+  IMPORT_NANO_FOO = 7;
+  IMPORT_NANO_BAR = 8;
+  IMPORT_NANO_BAZ = 9;
+}
diff --git a/protobuf/src/google/protobuf/unittest_import_public.proto b/protobuf/src/google/protobuf/unittest_import_public.proto
new file mode 100644
index 0000000..e5929cb
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_import_public.proto
@@ -0,0 +1,40 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.test";
+
+message PublicImportMessage {
+  optional int32 e = 1;
+}
diff --git a/protobuf/src/google/protobuf/unittest_import_public_lite.proto b/protobuf/src/google/protobuf/unittest_import_public_lite.proto
new file mode 100644
index 0000000..e39bdb4
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_import_public_lite.proto
@@ -0,0 +1,42 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: liujisi@google.com (Pherl Liu)
+
+
+package protobuf_unittest_import;
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+message PublicImportMessageLite {
+  optional int32 e = 1;
+}
diff --git a/protobuf/src/google/protobuf/unittest_lite.proto b/protobuf/src/google/protobuf/unittest_lite.proto
new file mode 100644
index 0000000..30dd67f
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_lite.proto
@@ -0,0 +1,384 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// This is like unittest.proto but with optimize_for = LITE_RUNTIME.
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest_import_lite.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+option java_package = "com.google.protobuf";
+
+// Same as TestAllTypes but with the lite runtime.
+message TestAllTypesLite {
+  message NestedMessage {
+    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 ForeignMessageLite optional_foreign_message = 19;
+  optional protobuf_unittest_import.ImportMessageLite
+    optional_import_message = 20;
+
+  optional NestedEnum      optional_nested_enum     = 21;
+  optional ForeignEnumLite optional_foreign_enum    = 22;
+  optional protobuf_unittest_import.ImportEnumLite optional_import_enum = 23;
+
+  optional string optional_string_piece = 24 [ctype=STRING_PIECE];
+  optional string optional_cord = 25 [ctype=CORD];
+
+  // Defined in unittest_import_public.proto
+  optional protobuf_unittest_import.PublicImportMessageLite
+      optional_public_import_message = 26;
+
+  optional NestedMessage optional_lazy_message = 27 [lazy=true];
+
+  // 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 ForeignMessageLite repeated_foreign_message = 49;
+  repeated protobuf_unittest_import.ImportMessageLite
+    repeated_import_message = 50;
+
+  repeated NestedEnum      repeated_nested_enum  = 51;
+  repeated ForeignEnumLite repeated_foreign_enum = 52;
+  repeated protobuf_unittest_import.ImportEnumLite repeated_import_enum = 53;
+
+  repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+  repeated string repeated_cord = 55 [ctype=CORD];
+
+  repeated NestedMessage repeated_lazy_message = 57 [lazy=true];
+
+  // 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 ForeignEnumLite default_foreign_enum = 82
+      [default = FOREIGN_LITE_BAR];
+  optional protobuf_unittest_import.ImportEnumLite
+      default_import_enum = 83 [default = IMPORT_LITE_BAR];
+
+  optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+  optional string default_cord = 85 [ctype=CORD,default="123"];
+
+  // For oneof test
+  oneof oneof_field {
+    uint32 oneof_uint32 = 111;
+    NestedMessage oneof_nested_message = 112;
+    string oneof_string = 113;
+    bytes oneof_bytes = 114;
+  }
+}
+
+message ForeignMessageLite {
+  optional int32 c = 1;
+}
+
+enum ForeignEnumLite {
+  FOREIGN_LITE_FOO = 4;
+  FOREIGN_LITE_BAR = 5;
+  FOREIGN_LITE_BAZ = 6;
+}
+
+message TestPackedTypesLite {
+  repeated    int32 packed_int32    =  90 [packed = true];
+  repeated    int64 packed_int64    =  91 [packed = true];
+  repeated   uint32 packed_uint32   =  92 [packed = true];
+  repeated   uint64 packed_uint64   =  93 [packed = true];
+  repeated   sint32 packed_sint32   =  94 [packed = true];
+  repeated   sint64 packed_sint64   =  95 [packed = true];
+  repeated  fixed32 packed_fixed32  =  96 [packed = true];
+  repeated  fixed64 packed_fixed64  =  97 [packed = true];
+  repeated sfixed32 packed_sfixed32 =  98 [packed = true];
+  repeated sfixed64 packed_sfixed64 =  99 [packed = true];
+  repeated    float packed_float    = 100 [packed = true];
+  repeated   double packed_double   = 101 [packed = true];
+  repeated     bool packed_bool     = 102 [packed = true];
+  repeated ForeignEnumLite packed_enum  = 103 [packed = true];
+}
+
+message TestAllExtensionsLite {
+  extensions 1 to max;
+}
+
+extend TestAllExtensionsLite {
+  // Singular
+  optional    int32 optional_int32_extension_lite    =  1;
+  optional    int64 optional_int64_extension_lite    =  2;
+  optional   uint32 optional_uint32_extension_lite   =  3;
+  optional   uint64 optional_uint64_extension_lite   =  4;
+  optional   sint32 optional_sint32_extension_lite   =  5;
+  optional   sint64 optional_sint64_extension_lite   =  6;
+  optional  fixed32 optional_fixed32_extension_lite  =  7;
+  optional  fixed64 optional_fixed64_extension_lite  =  8;
+  optional sfixed32 optional_sfixed32_extension_lite =  9;
+  optional sfixed64 optional_sfixed64_extension_lite = 10;
+  optional    float optional_float_extension_lite    = 11;
+  optional   double optional_double_extension_lite   = 12;
+  optional     bool optional_bool_extension_lite     = 13;
+  optional   string optional_string_extension_lite   = 14;
+  optional    bytes optional_bytes_extension_lite    = 15;
+
+  optional group OptionalGroup_extension_lite = 16 {
+    optional int32 a = 17;
+  }
+
+  optional TestAllTypesLite.NestedMessage optional_nested_message_extension_lite
+      = 18;
+  optional ForeignMessageLite optional_foreign_message_extension_lite = 19;
+  optional protobuf_unittest_import.ImportMessageLite
+    optional_import_message_extension_lite = 20;
+
+  optional TestAllTypesLite.NestedEnum optional_nested_enum_extension_lite = 21;
+  optional ForeignEnumLite optional_foreign_enum_extension_lite = 22;
+  optional protobuf_unittest_import.ImportEnumLite
+    optional_import_enum_extension_lite = 23;
+
+  optional string optional_string_piece_extension_lite = 24
+      [ctype=STRING_PIECE];
+  optional string optional_cord_extension_lite = 25 [ctype=CORD];
+
+  optional protobuf_unittest_import.PublicImportMessageLite
+    optional_public_import_message_extension_lite = 26;
+
+  optional TestAllTypesLite.NestedMessage
+    optional_lazy_message_extension_lite = 27 [lazy=true];
+
+  // Repeated
+  repeated    int32 repeated_int32_extension_lite    = 31;
+  repeated    int64 repeated_int64_extension_lite    = 32;
+  repeated   uint32 repeated_uint32_extension_lite   = 33;
+  repeated   uint64 repeated_uint64_extension_lite   = 34;
+  repeated   sint32 repeated_sint32_extension_lite   = 35;
+  repeated   sint64 repeated_sint64_extension_lite   = 36;
+  repeated  fixed32 repeated_fixed32_extension_lite  = 37;
+  repeated  fixed64 repeated_fixed64_extension_lite  = 38;
+  repeated sfixed32 repeated_sfixed32_extension_lite = 39;
+  repeated sfixed64 repeated_sfixed64_extension_lite = 40;
+  repeated    float repeated_float_extension_lite    = 41;
+  repeated   double repeated_double_extension_lite   = 42;
+  repeated     bool repeated_bool_extension_lite     = 43;
+  repeated   string repeated_string_extension_lite   = 44;
+  repeated    bytes repeated_bytes_extension_lite    = 45;
+
+  repeated group RepeatedGroup_extension_lite = 46 {
+    optional int32 a = 47;
+  }
+
+  repeated TestAllTypesLite.NestedMessage repeated_nested_message_extension_lite
+      = 48;
+  repeated ForeignMessageLite repeated_foreign_message_extension_lite = 49;
+  repeated protobuf_unittest_import.ImportMessageLite
+    repeated_import_message_extension_lite = 50;
+
+  repeated TestAllTypesLite.NestedEnum repeated_nested_enum_extension_lite = 51;
+  repeated ForeignEnumLite repeated_foreign_enum_extension_lite = 52;
+  repeated protobuf_unittest_import.ImportEnumLite
+    repeated_import_enum_extension_lite = 53;
+
+  repeated string repeated_string_piece_extension_lite = 54
+      [ctype=STRING_PIECE];
+  repeated string repeated_cord_extension_lite = 55 [ctype=CORD];
+
+  repeated TestAllTypesLite.NestedMessage
+    repeated_lazy_message_extension_lite = 57 [lazy=true];
+
+  // Singular with defaults
+  optional    int32 default_int32_extension_lite    = 61 [default =  41    ];
+  optional    int64 default_int64_extension_lite    = 62 [default =  42    ];
+  optional   uint32 default_uint32_extension_lite   = 63 [default =  43    ];
+  optional   uint64 default_uint64_extension_lite   = 64 [default =  44    ];
+  optional   sint32 default_sint32_extension_lite   = 65 [default = -45    ];
+  optional   sint64 default_sint64_extension_lite   = 66 [default =  46    ];
+  optional  fixed32 default_fixed32_extension_lite  = 67 [default =  47    ];
+  optional  fixed64 default_fixed64_extension_lite  = 68 [default =  48    ];
+  optional sfixed32 default_sfixed32_extension_lite = 69 [default =  49    ];
+  optional sfixed64 default_sfixed64_extension_lite = 70 [default = -50    ];
+  optional    float default_float_extension_lite    = 71 [default =  51.5  ];
+  optional   double default_double_extension_lite   = 72 [default =  52e3  ];
+  optional     bool default_bool_extension_lite     = 73 [default = true   ];
+  optional   string default_string_extension_lite   = 74 [default = "hello"];
+  optional    bytes default_bytes_extension_lite    = 75 [default = "world"];
+
+  optional TestAllTypesLite.NestedEnum
+    default_nested_enum_extension_lite = 81 [default = BAR];
+  optional ForeignEnumLite
+    default_foreign_enum_extension_lite = 82 [default = FOREIGN_LITE_BAR];
+  optional protobuf_unittest_import.ImportEnumLite
+    default_import_enum_extension_lite = 83 [default = IMPORT_LITE_BAR];
+
+  optional string default_string_piece_extension_lite = 84 [ctype=STRING_PIECE,
+                                                            default="abc"];
+  optional string default_cord_extension_lite = 85 [ctype=CORD, default="123"];
+
+  // For oneof test
+  optional uint32 oneof_uint32_extension_lite = 111;
+  optional TestAllTypesLite.NestedMessage oneof_nested_message_extension_lite = 112;
+  optional string oneof_string_extension_lite = 113;
+  optional bytes oneof_bytes_extension_lite = 114;
+}
+
+message TestPackedExtensionsLite {
+  extensions 1 to max;
+}
+
+extend TestPackedExtensionsLite {
+  repeated    int32 packed_int32_extension_lite    =  90 [packed = true];
+  repeated    int64 packed_int64_extension_lite    =  91 [packed = true];
+  repeated   uint32 packed_uint32_extension_lite   =  92 [packed = true];
+  repeated   uint64 packed_uint64_extension_lite   =  93 [packed = true];
+  repeated   sint32 packed_sint32_extension_lite   =  94 [packed = true];
+  repeated   sint64 packed_sint64_extension_lite   =  95 [packed = true];
+  repeated  fixed32 packed_fixed32_extension_lite  =  96 [packed = true];
+  repeated  fixed64 packed_fixed64_extension_lite  =  97 [packed = true];
+  repeated sfixed32 packed_sfixed32_extension_lite =  98 [packed = true];
+  repeated sfixed64 packed_sfixed64_extension_lite =  99 [packed = true];
+  repeated    float packed_float_extension_lite    = 100 [packed = true];
+  repeated   double packed_double_extension_lite   = 101 [packed = true];
+  repeated     bool packed_bool_extension_lite     = 102 [packed = true];
+  repeated ForeignEnumLite packed_enum_extension_lite = 103 [packed = true];
+}
+
+message TestNestedExtensionLite {
+  extend TestAllExtensionsLite {
+    optional int32 nested_extension = 12345;
+  }
+}
+
+// Test that deprecated fields work.  We only verify that they compile (at one
+// point this failed).
+message TestDeprecatedLite {
+  optional int32 deprecated_field = 1 [deprecated = true];
+}
+
+// See the comments of the same type in unittest.proto.
+message TestParsingMergeLite {
+  message RepeatedFieldsGenerator {
+    repeated TestAllTypesLite field1 = 1;
+    repeated TestAllTypesLite field2 = 2;
+    repeated TestAllTypesLite field3 = 3;
+    repeated group Group1 = 10 {
+      optional TestAllTypesLite field1 = 11;
+    }
+    repeated group Group2 = 20 {
+      optional TestAllTypesLite field1 = 21;
+    }
+    repeated TestAllTypesLite ext1 = 1000;
+    repeated TestAllTypesLite ext2 = 1001;
+  }
+  required TestAllTypesLite required_all_types = 1;
+  optional TestAllTypesLite optional_all_types = 2;
+  repeated TestAllTypesLite repeated_all_types = 3;
+  optional group OptionalGroup = 10 {
+    optional TestAllTypesLite optional_group_all_types = 11;
+  }
+  repeated group RepeatedGroup = 20 {
+    optional TestAllTypesLite repeated_group_all_types = 21;
+  }
+  extensions 1000 to max;
+  extend TestParsingMergeLite {
+    optional TestAllTypesLite optional_ext = 1000;
+    repeated TestAllTypesLite repeated_ext = 1001;
+  }
+}
+
+// TestEmptyMessageLite is used to test unknown fields support in lite mode.
+message TestEmptyMessageLite{
+}
+
+// Like above, but declare all field numbers as potential extensions.  No
+// actual extensions should ever be defined for this type.
+message TestEmptyMessageWithExtensionsLite {
+  extensions 1 to max;
+}
diff --git a/protobuf/src/google/protobuf/unittest_lite_imports_nonlite.proto b/protobuf/src/google/protobuf/unittest_lite_imports_nonlite.proto
new file mode 100644
index 0000000..5ef8a06
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_lite_imports_nonlite.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// Tests that a "lite" message can import a regular message.
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest.proto";
+
+option optimize_for = LITE_RUNTIME;
+
+message TestLiteImportsNonlite {
+  optional TestAllTypes message = 1;
+}
diff --git a/protobuf/src/google/protobuf/unittest_micro.proto b/protobuf/src/google/protobuf/unittest_micro.proto
new file mode 100644
index 0000000..e6b4618
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_micro.proto
@@ -0,0 +1,169 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: wink@google.com (Wink Saville)
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest_import_micro.proto";
+
+option java_package = "com.google.protobuf.micro";
+option java_outer_classname = "MicroOuterClass";
+
+// Same as TestAllTypes but with the micro runtime.
+message TestAllTypesMicro {
+
+  message NestedMessage {
+    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 ForeignMessageMicro optional_foreign_message = 19;
+  optional protobuf_unittest_import.ImportMessageMicro
+    optional_import_message = 20;
+
+  optional NestedEnum      optional_nested_enum     = 21;
+  optional ForeignEnumMicro optional_foreign_enum    = 22;
+  optional protobuf_unittest_import.ImportEnumMicro 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 ForeignMessageMicro repeated_foreign_message = 49;
+  repeated protobuf_unittest_import.ImportMessageMicro
+    repeated_import_message = 50;
+
+  repeated NestedEnum      repeated_nested_enum  = 51;
+  repeated ForeignEnumMicro repeated_foreign_enum = 52;
+  repeated protobuf_unittest_import.ImportEnumMicro 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  float default_float_inf      = 96  [default =  inf];
+  optional  float default_float_neg_inf  = 97  [default = -inf];
+  optional  float default_float_nan      = 98  [default =  nan];
+  optional double default_double_inf     = 99  [default =  inf];
+  optional double default_double_neg_inf = 100 [default = -inf];
+  optional double default_double_nan     = 101 [default =  nan];
+
+  optional NestedEnum default_nested_enum = 81 [default = BAR];
+  optional ForeignEnumMicro default_foreign_enum = 82
+      [default = FOREIGN_MICRO_BAR];
+  optional protobuf_unittest_import.ImportEnumMicro
+      default_import_enum = 83 [default = IMPORT_MICRO_BAR];
+
+  optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+  optional string default_cord = 85 [ctype=CORD,default="123"];
+
+  required int32 id = 86;
+}
+
+message ForeignMessageMicro {
+  optional int32 c = 1;
+}
+
+enum ForeignEnumMicro {
+  FOREIGN_MICRO_FOO = 4;
+  FOREIGN_MICRO_BAR = 5;
+  FOREIGN_MICRO_BAZ = 6;
+}
+
+// Test that deprecated fields work.  We only verify that they compile (at one
+// point this failed).
+message TestDeprecatedMicro {
+  optional int32 deprecated_field = 1 [deprecated = true];
+}
diff --git a/protobuf/src/google/protobuf/unittest_mset.proto b/protobuf/src/google/protobuf/unittest_mset.proto
new file mode 100644
index 0000000..8fbe7ab
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_mset.proto
@@ -0,0 +1,83 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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;
+}
+
+// This message was used to generate
+// //net/proto2/python/internal/testdata/message_set_message, but is commented
+// out since it must not actually exist in code, to simulate an "unknown"
+// extension.
+// message TestMessageSetUnknownExtension {
+//   extend TestMessageSet {
+//     optional TestMessageSetUnknownExtension message_set_extension = 56141421;
+//   }
+//   optional int64 a = 1;
+// }
+
+// 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/protobuf/src/google/protobuf/unittest_multiple_micro.proto b/protobuf/src/google/protobuf/unittest_multiple_micro.proto
new file mode 100644
index 0000000..fee8edc
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_multiple_micro.proto
@@ -0,0 +1,63 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest_import;
+
+import "google/protobuf/unittest_import_micro.proto";
+
+option java_package = "com.google.protobuf.micro";
+option java_multiple_files = true;
+
+enum FileScopeEnum {
+  ONE = 1;
+  TWO = 2;
+}
+
+message FileScopeEnumRefMicro {
+  optional FileScopeEnum enum_field = 1;
+}
+
+message MessageScopeEnumRefMicro {
+  enum MessageScopeEnum {
+    ONE = 1;
+    TWO = 2;
+  }
+  optional MessageScopeEnum enum_field = 1;
+}
+
+message MultipleImportingNonMultipleMicro1 {
+  optional ImportMessageMicro field = 1;
+}
+
+message MultipleImportingNonMultipleMicro2 {
+  optional MultipleImportingNonMultipleMicro1 micro1 = 1;
+}
diff --git a/protobuf/src/google/protobuf/unittest_multiple_nameclash_micro.proto b/protobuf/src/google/protobuf/unittest_multiple_nameclash_micro.proto
new file mode 100644
index 0000000..089fd85
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_multiple_nameclash_micro.proto
@@ -0,0 +1,41 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.micro";
+option java_outer_classname = "MultipleNameClashMicro";
+option java_multiple_files = true;
+
+message MultipleNameClashMicro {
+  optional int32 field = 1;
+}
diff --git a/protobuf/src/google/protobuf/unittest_multiple_nameclash_nano.proto b/protobuf/src/google/protobuf/unittest_multiple_nameclash_nano.proto
new file mode 100644
index 0000000..f2f62c4
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_multiple_nameclash_nano.proto
@@ -0,0 +1,41 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "MultipleNameClashNano";
+option java_multiple_files = true;
+
+message MultipleNameClashNano {
+  optional int32 field = 1;
+}
diff --git a/protobuf/src/google/protobuf/unittest_multiple_nano.proto b/protobuf/src/google/protobuf/unittest_multiple_nano.proto
new file mode 100644
index 0000000..5ae790b
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_multiple_nano.proto
@@ -0,0 +1,63 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest_import;
+
+import "google/protobuf/unittest_import_nano.proto";
+
+option java_package = "com.google.protobuf.nano";
+option java_multiple_files = true;
+
+enum FileScopeEnum {
+  ONE = 1;
+  TWO = 2;
+}
+
+message FileScopeEnumRefNano {
+  optional FileScopeEnum enum_field = 1;
+}
+
+message MessageScopeEnumRefNano {
+  enum MessageScopeEnum {
+    ONE = 1;
+    TWO = 2;
+  }
+  optional MessageScopeEnum enum_field = 1;
+}
+
+message MultipleImportingNonMultipleNano1 {
+  optional ImportMessageNano field = 1;
+}
+
+message MultipleImportingNonMultipleNano2 {
+  optional MultipleImportingNonMultipleNano1 nano1 = 1;
+}
diff --git a/protobuf/src/google/protobuf/unittest_nano.proto b/protobuf/src/google/protobuf/unittest_nano.proto
new file mode 100644
index 0000000..1a6ba26
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_nano.proto
@@ -0,0 +1,186 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: wink@google.com (Wink Saville)
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest_import_nano.proto";
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "NanoOuterClass";
+
+// Same as TestAllTypes but with the nano runtime.
+message TestAllTypesNano {
+
+  message NestedMessage {
+    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 ForeignMessageNano optional_foreign_message = 19;
+  optional protobuf_unittest_import.ImportMessageNano
+    optional_import_message = 20;
+
+  optional NestedEnum      optional_nested_enum     = 21;
+  optional ForeignEnumNano optional_foreign_enum    = 22;
+  optional protobuf_unittest_import.ImportEnumNano 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 ForeignMessageNano repeated_foreign_message = 49;
+  repeated protobuf_unittest_import.ImportMessageNano
+    repeated_import_message = 50;
+
+  repeated NestedEnum      repeated_nested_enum  = 51;
+  repeated ForeignEnumNano repeated_foreign_enum = 52;
+  repeated protobuf_unittest_import.ImportEnumNano repeated_import_enum = 53;
+
+  repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+  repeated string repeated_cord = 55 [ctype=CORD];
+
+  // Repeated packed
+  repeated    int32 repeated_packed_int32    = 87 [packed=true];
+  repeated sfixed64 repeated_packed_sfixed64 = 88 [packed=true];
+
+  repeated NestedEnum repeated_packed_nested_enum  = 89 [packed=true];
+
+  // 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 string default_string_nonascii = 76 [default = "dünya"];
+  optional  bytes default_bytes_nonascii  = 77 [default = "dünyab"];
+
+  optional  float default_float_inf      = 97  [default =  inf];
+  optional  float default_float_neg_inf  = 98  [default = -inf];
+  optional  float default_float_nan      = 99  [default =  nan];
+  optional double default_double_inf     = 100 [default =  inf];
+  optional double default_double_neg_inf = 101 [default = -inf];
+  optional double default_double_nan     = 102 [default =  nan];
+
+  optional NestedEnum default_nested_enum = 81 [default = BAR];
+  optional ForeignEnumNano default_foreign_enum = 82
+      [default = FOREIGN_NANO_BAR];
+  optional protobuf_unittest_import.ImportEnumNano
+      default_import_enum = 83 [default = IMPORT_NANO_BAR];
+
+  optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
+  optional string default_cord = 85 [ctype=CORD,default="123"];
+
+  required int32 id = 86;
+
+  // Try to cause conflicts.
+  optional int32 tag = 93;
+  optional int32 get_serialized_size = 94;
+  optional int32 write_to = 95;
+
+  // Try to fail with java reserved keywords
+  optional int32 synchronized = 96;
+}
+
+message ForeignMessageNano {
+  optional int32 c = 1;
+}
+
+enum ForeignEnumNano {
+  FOREIGN_NANO_FOO = 4;
+  FOREIGN_NANO_BAR = 5;
+  FOREIGN_NANO_BAZ = 6;
+}
+
+// Test that deprecated fields work.  We only verify that they compile (at one
+// point this failed).
+message TestDeprecatedNano {
+  optional int32 deprecated_field = 1 [deprecated = true];
+}
diff --git a/protobuf/src/google/protobuf/unittest_no_generic_services.proto b/protobuf/src/google/protobuf/unittest_no_generic_services.proto
new file mode 100644
index 0000000..cf6d16c
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_no_generic_services.proto
@@ -0,0 +1,53 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+package google.protobuf.no_generic_services_test;
+
+
+// *_generic_services are false by default.
+
+message TestMessage {
+  optional int32 a = 1;
+  extensions 1000 to max;
+}
+
+enum TestEnum {
+  FOO = 1;
+}
+
+extend TestMessage {
+  optional int32 test_extension = 1000;
+}
+
+service TestService {
+  rpc Foo(TestMessage) returns(TestMessage);
+}
diff --git a/protobuf/src/google/protobuf/unittest_optimize_for.proto b/protobuf/src/google/protobuf/unittest_optimize_for.proto
new file mode 100644
index 0000000..9f7b4ee
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_optimize_for.proto
@@ -0,0 +1,66 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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;
+    optional TestRequiredOptimizedForSize test_extension2 = 1235;
+  }
+
+  oneof foo {
+    int32 integer_field = 2;
+    string string_field = 3;
+  }
+}
+
+message TestRequiredOptimizedForSize {
+  required int32 x = 1;
+}
+
+message TestOptionalOptimizedForSize {
+  optional TestRequiredOptimizedForSize o = 1;
+}
diff --git a/protobuf/src/google/protobuf/unittest_recursive_micro.proto b/protobuf/src/google/protobuf/unittest_recursive_micro.proto
new file mode 100644
index 0000000..078ca9c
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_recursive_micro.proto
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: wink@google.com (Wink Saville)
+//
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.micro";
+// Explicit outer classname to suppress legacy info.
+option java_outer_classname = "UnittestRecursiveMicro";
+
+message RecursiveMessageMicro {
+  message NestedMessage {
+    optional RecursiveMessageMicro a = 1;
+  }
+
+  required int32 id = 1;
+  optional NestedMessage nested_message = 2;
+  optional RecursiveMessageMicro optional_recursive_message_micro = 3;
+  repeated RecursiveMessageMicro repeated_recursive_message_micro = 4;
+}
diff --git a/protobuf/src/google/protobuf/unittest_recursive_nano.proto b/protobuf/src/google/protobuf/unittest_recursive_nano.proto
new file mode 100644
index 0000000..3d3a6aa
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_recursive_nano.proto
@@ -0,0 +1,49 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: wink@google.com (Wink Saville)
+//
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.nano";
+// Explicit outer classname to suppress legacy info.
+option java_outer_classname = "UnittestRecursiveNano";
+
+message RecursiveMessageNano {
+  message NestedMessage {
+    optional RecursiveMessageNano a = 1;
+  }
+
+  required int32 id = 1;
+  optional NestedMessage nested_message = 2;
+  optional RecursiveMessageNano optional_recursive_message_nano = 3;
+  repeated RecursiveMessageNano repeated_recursive_message_nano = 4;
+}
diff --git a/protobuf/src/google/protobuf/unittest_reference_types_nano.proto b/protobuf/src/google/protobuf/unittest_reference_types_nano.proto
new file mode 100644
index 0000000..2b24615
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_reference_types_nano.proto
@@ -0,0 +1,116 @@
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "NanoReferenceTypes";
+
+message TestAllTypesNano {
+
+  enum NestedEnum {
+    FOO = 1;
+    BAR = 2;
+    BAZ = 3;
+  }
+
+  message NestedMessage {
+    optional int32 foo = 1;
+  }
+
+  // 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 NestedEnum      optional_nested_enum     = 21;
+
+  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 NestedEnum      repeated_nested_enum  = 51;
+
+  repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
+  repeated string repeated_cord = 55 [ctype=CORD];
+
+  // Repeated packed
+  repeated    int32 repeated_packed_int32    = 87 [packed=true];
+  repeated sfixed64 repeated_packed_sfixed64 = 88 [packed=true];
+
+  repeated NestedEnum repeated_packed_nested_enum  = 89 [packed=true];
+
+  // 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  float default_float_inf      = 97  [default =  inf];
+  optional  float default_float_neg_inf  = 98  [default = -inf];
+  optional  float default_float_nan      = 99  [default =  nan];
+  optional double default_double_inf     = 100 [default =  inf];
+  optional double default_double_neg_inf = 101 [default = -inf];
+  optional double default_double_nan     = 102 [default =  nan];
+
+}
+
+message ForeignMessageNano {
+  optional int32 c = 1;
+}
+
+enum ForeignEnumNano {
+  FOREIGN_NANO_FOO = 4;
+  FOREIGN_NANO_BAR = 5;
+  FOREIGN_NANO_BAZ = 6;
+}
+
diff --git a/protobuf/src/google/protobuf/unittest_repeated_merge_nano.proto b/protobuf/src/google/protobuf/unittest_repeated_merge_nano.proto
new file mode 100644
index 0000000..4f03224
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_repeated_merge_nano.proto
@@ -0,0 +1,47 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest;
+
+import "google/protobuf/unittest_nano.proto";
+
+option java_package = "com.google.protobuf.nano";
+option java_multiple_files = true;
+
+// A container message for testing the merging of repeated fields at a
+// nested level. Other tests will be done using the repeated fields in
+// TestAllTypesNano.
+message TestRepeatedMergeNano {
+
+  optional TestAllTypesNano contained = 1;
+
+}
diff --git a/protobuf/src/google/protobuf/unittest_repeated_packables_nano.proto b/protobuf/src/google/protobuf/unittest_repeated_packables_nano.proto
new file mode 100644
index 0000000..1c78918
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_repeated_packables_nano.proto
@@ -0,0 +1,95 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "NanoRepeatedPackables";
+
+enum Enum {
+  OPTION_ONE = 1;
+  OPTION_TWO = 2;
+}
+
+// Two almost identical messages with all packable repeated field types.
+// One with none marked as packed and the other all packed. For
+// compatibility, they should be able to parse each other's serialized
+// forms.
+
+message NonPacked {
+
+  // All packable types, none marked as packed.
+
+  repeated    int32 int32s    = 1;
+  repeated    int64 int64s    = 2;
+  repeated   uint32 uint32s   = 3;
+  repeated   uint64 uint64s   = 4;
+  repeated   sint32 sint32s   = 5;
+  repeated   sint64 sint64s   = 6;
+  repeated  fixed32 fixed32s  = 7;
+  repeated  fixed64 fixed64s  = 8;
+  repeated sfixed32 sfixed32s = 9;
+  repeated sfixed64 sfixed64s = 10;
+  repeated    float floats    = 11;
+  repeated   double doubles   = 12;
+  repeated     bool bools     = 13;
+  repeated     Enum enums     = 14;
+
+  // Noise for testing merged deserialization.
+  optional int32 noise = 15;
+
+}
+
+message Packed {
+
+  // All packable types, all matching the field numbers in NonPacked,
+  // all marked as packed.
+
+  repeated    int32 int32s    = 1  [ packed = true ];
+  repeated    int64 int64s    = 2  [ packed = true ];
+  repeated   uint32 uint32s   = 3  [ packed = true ];
+  repeated   uint64 uint64s   = 4  [ packed = true ];
+  repeated   sint32 sint32s   = 5  [ packed = true ];
+  repeated   sint64 sint64s   = 6  [ packed = true ];
+  repeated  fixed32 fixed32s  = 7  [ packed = true ];
+  repeated  fixed64 fixed64s  = 8  [ packed = true ];
+  repeated sfixed32 sfixed32s = 9  [ packed = true ];
+  repeated sfixed64 sfixed64s = 10 [ packed = true ];
+  repeated    float floats    = 11 [ packed = true ];
+  repeated   double doubles   = 12 [ packed = true ];
+  repeated     bool bools     = 13 [ packed = true ];
+  repeated     Enum enums     = 14 [ packed = true ];
+
+  // Noise for testing merged deserialization.
+  optional int32 noise = 15;
+
+}
diff --git a/protobuf/src/google/protobuf/unittest_simple_micro.proto b/protobuf/src/google/protobuf/unittest_simple_micro.proto
new file mode 100644
index 0000000..09d4aab
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_simple_micro.proto
@@ -0,0 +1,54 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: wink@google.com (Wink Saville)
+//
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.micro";
+// Explicit outer classname to suppress legacy info
+option java_outer_classname = "UnittestSimpleMicro";
+
+message SimpleMessageMicro {
+  message NestedMessage {
+    optional int32 bb = 1;
+  }
+
+  enum NestedEnum {
+    FOO = 1;
+    BAR = 2;
+    BAZ = 3;
+  }
+
+  optional int32 d = 1 [default = 123];
+  optional NestedMessage nested_msg = 2;
+  optional NestedEnum default_nested_enum = 3 [default = BAZ];
+}
diff --git a/protobuf/src/google/protobuf/unittest_simple_nano.proto b/protobuf/src/google/protobuf/unittest_simple_nano.proto
new file mode 100644
index 0000000..0c780c7
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_simple_nano.proto
@@ -0,0 +1,54 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: wink@google.com (Wink Saville)
+//
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.nano";
+// Explicit outer classname to suppress legacy info.
+option java_outer_classname = "UnittestSimpleNano";
+
+message SimpleMessageNano {
+  message NestedMessage {
+    optional int32 bb = 1;
+  }
+
+  enum NestedEnum {
+    FOO = 1;
+    BAR = 2;
+    BAZ = 3;
+  }
+
+  optional int32 d = 1 [default = 123];
+  optional NestedMessage nested_msg = 2;
+  optional NestedEnum default_nested_enum = 3 [default = BAZ];
+}
diff --git a/protobuf/src/google/protobuf/unittest_single_micro.proto b/protobuf/src/google/protobuf/unittest_single_micro.proto
new file mode 100644
index 0000000..17e0645
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_single_micro.proto
@@ -0,0 +1,38 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.micro";
+
+message SingleMessageMicro {
+}
diff --git a/protobuf/src/google/protobuf/unittest_single_nano.proto b/protobuf/src/google/protobuf/unittest_single_nano.proto
new file mode 100644
index 0000000..fcb1539
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_single_nano.proto
@@ -0,0 +1,38 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: maxtroy@google.com (Max Cai)
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.nano";
+
+message SingleMessageNano {
+}
diff --git a/protobuf/src/google/protobuf/unittest_stringutf8_micro.proto b/protobuf/src/google/protobuf/unittest_stringutf8_micro.proto
new file mode 100644
index 0000000..68bd5ef
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_stringutf8_micro.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: wink@google.com (Wink Saville)
+//
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.micro";
+// Explicit outer classname to suppress legacy info.
+option java_outer_classname = "UnittestStringutf8Micro";
+
+message StringUtf8 {
+  optional string id = 1;
+  repeated string rs = 2;
+}
diff --git a/protobuf/src/google/protobuf/unittest_stringutf8_nano.proto b/protobuf/src/google/protobuf/unittest_stringutf8_nano.proto
new file mode 100644
index 0000000..2bbf2b7
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_stringutf8_nano.proto
@@ -0,0 +1,43 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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: wink@google.com (Wink Saville)
+//
+
+package protobuf_unittest_import;
+
+option java_package = "com.google.protobuf.nano";
+// Explicit outer classname to suppress legacy info.
+option java_outer_classname = "UnittestStringutf8Nano";
+
+message StringUtf8 {
+  optional string id = 1;
+  repeated string rs = 2;
+}
diff --git a/protobuf/src/google/protobuf/unittest_unknown_enum_values_nano.proto b/protobuf/src/google/protobuf/unittest_unknown_enum_values_nano.proto
new file mode 100644
index 0000000..59d91c4
--- /dev/null
+++ b/protobuf/src/google/protobuf/unittest_unknown_enum_values_nano.proto
@@ -0,0 +1,58 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2016 Google Inc.  All rights reserved.
+// http://code.google.com/p/protobuf/
+//
+// 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.
+
+package protobuf_unittest;
+
+option java_package = "com.google.protobuf.nano";
+option java_outer_classname = "UnknownEnumValuesNanoOuterClass";
+
+message StandardVersion {
+  enum Enum {
+    UNKNOWN = 0;
+    VAL_1 = 1;
+    VAL_2 = 2;
+    VAL_3 = 3;
+  }
+  optional Enum optional_field = 1;
+  repeated Enum repeated_field = 2;
+  repeated Enum packed_field = 3 [packed = true];
+}
+
+message VersionWithoutVal3 {
+  enum Enum {
+    UNKNOWN = 0;
+    VAL_1 = 1;
+    VAL_2 = 2;
+    // VAL_3 is unknown in this version.
+  }
+  optional Enum optional_field = 1;
+  repeated Enum repeated_field = 2;
+  repeated Enum packed_field = 3 [packed = true];
+}
diff --git a/protobuf/src/google/protobuf/unknown_field_set.cc b/protobuf/src/google/protobuf/unknown_field_set.cc
new file mode 100644
index 0000000..020a323
--- /dev/null
+++ b/protobuf/src/google/protobuf/unknown_field_set.cc
@@ -0,0 +1,265 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/common.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/wire_format.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+
+UnknownFieldSet::UnknownFieldSet()
+    : fields_(NULL) {}
+
+UnknownFieldSet::~UnknownFieldSet() {
+  Clear();
+  delete fields_;
+}
+
+void UnknownFieldSet::ClearFallback() {
+  GOOGLE_DCHECK(fields_ != NULL);
+  for (int i = 0; i < fields_->size(); i++) {
+    (*fields_)[i].Delete();
+  }
+  fields_->clear();
+}
+
+void UnknownFieldSet::ClearAndFreeMemory() {
+  if (fields_ != NULL) {
+    Clear();
+    delete fields_;
+    fields_ = NULL;
+  }
+}
+
+void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) {
+  for (int i = 0; i < other.field_count(); i++) {
+    AddField(other.field(i));
+  }
+}
+
+int UnknownFieldSet::SpaceUsedExcludingSelf() const {
+  if (fields_ == NULL) return 0;
+
+  int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size();
+  for (int i = 0; i < fields_->size(); i++) {
+    const UnknownField& field = (*fields_)[i];
+    switch (field.type()) {
+      case UnknownField::TYPE_LENGTH_DELIMITED:
+        total_size += sizeof(*field.length_delimited_.string_value_) +
+                      internal::StringSpaceUsedExcludingSelf(
+                          *field.length_delimited_.string_value_);
+        break;
+      case UnknownField::TYPE_GROUP:
+        total_size += field.group_->SpaceUsed();
+        break;
+      default:
+        break;
+    }
+  }
+  return total_size;
+}
+
+int UnknownFieldSet::SpaceUsed() const {
+  return sizeof(*this) + SpaceUsedExcludingSelf();
+}
+
+void UnknownFieldSet::AddVarint(int number, uint64 value) {
+  if (fields_ == NULL) fields_ = new vector<UnknownField>;
+  UnknownField field;
+  field.number_ = number;
+  field.SetType(UnknownField::TYPE_VARINT);
+  field.varint_ = value;
+  fields_->push_back(field);
+}
+
+void UnknownFieldSet::AddFixed32(int number, uint32 value) {
+  if (fields_ == NULL) fields_ = new vector<UnknownField>;
+  UnknownField field;
+  field.number_ = number;
+  field.SetType(UnknownField::TYPE_FIXED32);
+  field.fixed32_ = value;
+  fields_->push_back(field);
+}
+
+void UnknownFieldSet::AddFixed64(int number, uint64 value) {
+  if (fields_ == NULL) fields_ = new vector<UnknownField>;
+  UnknownField field;
+  field.number_ = number;
+  field.SetType(UnknownField::TYPE_FIXED64);
+  field.fixed64_ = value;
+  fields_->push_back(field);
+}
+
+string* UnknownFieldSet::AddLengthDelimited(int number) {
+  if (fields_ == NULL) fields_ = new vector<UnknownField>;
+  UnknownField field;
+  field.number_ = number;
+  field.SetType(UnknownField::TYPE_LENGTH_DELIMITED);
+  field.length_delimited_.string_value_ = new string;
+  fields_->push_back(field);
+  return field.length_delimited_.string_value_;
+}
+
+
+UnknownFieldSet* UnknownFieldSet::AddGroup(int number) {
+  if (fields_ == NULL) fields_ = new vector<UnknownField>;
+  UnknownField field;
+  field.number_ = number;
+  field.SetType(UnknownField::TYPE_GROUP);
+  field.group_ = new UnknownFieldSet;
+  fields_->push_back(field);
+  return field.group_;
+}
+
+void UnknownFieldSet::AddField(const UnknownField& field) {
+  if (fields_ == NULL) fields_ = new vector<UnknownField>;
+  fields_->push_back(field);
+  fields_->back().DeepCopy();
+}
+
+void UnknownFieldSet::DeleteSubrange(int start, int num) {
+  GOOGLE_DCHECK(fields_ != NULL);
+  // Delete the specified fields.
+  for (int i = 0; i < num; ++i) {
+    (*fields_)[i + start].Delete();
+  }
+  // Slide down the remaining fields.
+  for (int i = start + num; i < fields_->size(); ++i) {
+    (*fields_)[i - num] = (*fields_)[i];
+  }
+  // Pop off the # of deleted fields.
+  for (int i = 0; i < num; ++i) {
+    fields_->pop_back();
+  }
+}
+
+void UnknownFieldSet::DeleteByNumber(int number) {
+  if (fields_ == NULL) return;
+  int left = 0;  // The number of fields left after deletion.
+  for (int i = 0; i < fields_->size(); ++i) {
+    UnknownField* field = &(*fields_)[i];
+    if (field->number() == number) {
+      field->Delete();
+    } else {
+      if (i != left) {
+        (*fields_)[left] = (*fields_)[i];
+      }
+      ++left;
+    }
+  }
+  fields_->resize(left);
+}
+
+bool UnknownFieldSet::MergeFromCodedStream(io::CodedInputStream* input) {
+  UnknownFieldSet other;
+  if (internal::WireFormat::SkipMessage(input, &other) &&
+      input->ConsumedEntireMessage()) {
+    MergeFrom(other);
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool UnknownFieldSet::ParseFromCodedStream(io::CodedInputStream* input) {
+  Clear();
+  return MergeFromCodedStream(input);
+}
+
+bool UnknownFieldSet::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
+  io::CodedInputStream coded_input(input);
+  return (ParseFromCodedStream(&coded_input) &&
+          coded_input.ConsumedEntireMessage());
+}
+
+bool UnknownFieldSet::ParseFromArray(const void* data, int size) {
+  io::ArrayInputStream input(data, size);
+  return ParseFromZeroCopyStream(&input);
+}
+
+void UnknownField::Delete() {
+  switch (type()) {
+    case UnknownField::TYPE_LENGTH_DELIMITED:
+      delete length_delimited_.string_value_;
+      break;
+    case UnknownField::TYPE_GROUP:
+      delete group_;
+      break;
+    default:
+      break;
+  }
+}
+
+void UnknownField::DeepCopy() {
+  switch (type()) {
+    case UnknownField::TYPE_LENGTH_DELIMITED:
+      length_delimited_.string_value_ = new string(
+          *length_delimited_.string_value_);
+      break;
+    case UnknownField::TYPE_GROUP: {
+      UnknownFieldSet* group = new UnknownFieldSet;
+      group->MergeFrom(*group_);
+      group_ = group;
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+
+void UnknownField::SerializeLengthDelimitedNoTag(
+    io::CodedOutputStream* output) const {
+  GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
+  const string& data = *length_delimited_.string_value_;
+  output->WriteVarint32(data.size());
+  output->WriteRawMaybeAliased(data.data(), data.size());
+}
+
+uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const {
+  GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
+  const string& data = *length_delimited_.string_value_;
+  target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target);
+  target = io::CodedOutputStream::WriteStringToArray(data, target);
+  return target;
+}
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/unknown_field_set.h b/protobuf/src/google/protobuf/unknown_field_set.h
new file mode 100644
index 0000000..31f17e2
--- /dev/null
+++ b/protobuf/src/google/protobuf/unknown_field_set.h
@@ -0,0 +1,318 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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 <assert.h>
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+  namespace io {
+    class CodedInputStream;         // coded_stream.h
+    class CodedOutputStream;        // coded_stream.h
+    class ZeroCopyInputStream;      // zero_copy_stream.h
+  }
+  namespace internal {
+    class WireFormat;               // wire_format.h
+    class MessageSetFieldSkipperUsingCord;
+                                    // extension_set_heavy.cc
+  }
+
+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
+// 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.
+  inline void Clear();
+
+  // Remove all fields and deallocate internal data objects
+  void ClearAndFreeMemory();
+
+  // Is this set empty?
+  inline bool empty() const;
+
+  // Merge the contents of some other UnknownFieldSet with this one.
+  void MergeFrom(const UnknownFieldSet& other);
+
+  // Swaps the contents of some other UnknownFieldSet with this one.
+  inline void Swap(UnknownFieldSet* x);
+
+  // Computes (an estimate of) the total number of bytes currently used for
+  // storing the unknown fields in memory. Does NOT include
+  // sizeof(*this) in the calculation.
+  int SpaceUsedExcludingSelf() const;
+
+  // Version of SpaceUsed() including sizeof(*this).
+  int SpaceUsed() const;
+
+  // 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 the order in which they were added.
+  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 the order in which
+  // they were added.
+  inline UnknownField* mutable_field(int index);
+
+  // Adding fields ---------------------------------------------------
+
+  void AddVarint(int number, uint64 value);
+  void AddFixed32(int number, uint32 value);
+  void AddFixed64(int number, uint64 value);
+  void AddLengthDelimited(int number, const string& value);
+  string* AddLengthDelimited(int number);
+  UnknownFieldSet* AddGroup(int number);
+
+  // Adds an unknown field from another set.
+  void AddField(const UnknownField& field);
+
+  // Delete fields with indices in the range [start .. start+num-1].
+  // Caution: implementation moves all fields with indices [start+num .. ].
+  void DeleteSubrange(int start, int num);
+
+  // Delete all fields with a specific field number. The order of left fields
+  // is preserved.
+  // Caution: implementation moves all fields after the first deleted field.
+  void DeleteByNumber(int number);
+
+  // Parsing helpers -------------------------------------------------
+  // These work exactly like the similarly-named methods of Message.
+
+  bool MergeFromCodedStream(io::CodedInputStream* input);
+  bool ParseFromCodedStream(io::CodedInputStream* input);
+  bool ParseFromZeroCopyStream(io::ZeroCopyInputStream* input);
+  bool ParseFromArray(const void* data, int size);
+  inline bool ParseFromString(const string& data) {
+    return ParseFromArray(data.data(), static_cast<int>(data.size()));
+  }
+
+ private:
+
+  void ClearFallback();
+
+  std::vector<UnknownField>* fields_;
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UnknownFieldSet);
+};
+
+// Represents one field in an UnknownFieldSet.
+class LIBPROTOBUF_EXPORT UnknownField {
+ public:
+  enum Type {
+    TYPE_VARINT,
+    TYPE_FIXED32,
+    TYPE_FIXED64,
+    TYPE_LENGTH_DELIMITED,
+    TYPE_GROUP
+  };
+
+  // The field's tag number, as seen on the wire.
+  inline int number() const;
+
+  // The field type.
+  inline Type type() const;
+
+  // Accessors -------------------------------------------------------
+  // Each method works only for UnknownFields of the corresponding type.
+
+  inline uint64 varint() const;
+  inline uint32 fixed32() const;
+  inline uint64 fixed64() const;
+  inline const string& length_delimited() const;
+  inline const UnknownFieldSet& group() const;
+
+  inline void set_varint(uint64 value);
+  inline void set_fixed32(uint32 value);
+  inline void set_fixed64(uint64 value);
+  inline void set_length_delimited(const string& value);
+  inline string* mutable_length_delimited();
+  inline UnknownFieldSet* mutable_group();
+
+  // Serialization API.
+  // These methods can take advantage of the underlying implementation and may
+  // archieve a better performance than using getters to retrieve the data and
+  // do the serialization yourself.
+  void SerializeLengthDelimitedNoTag(io::CodedOutputStream* output) const;
+  uint8* SerializeLengthDelimitedNoTagToArray(uint8* target) const;
+
+  inline int GetLengthDelimitedSize() const;
+
+ private:
+  friend class UnknownFieldSet;
+
+  // If this UnknownField contains a pointer, delete it.
+  void Delete();
+
+  // Make a deep copy of any pointers in this UnknownField.
+  void DeepCopy();
+
+  // Set the wire type of this UnknownField. Should only be used when this
+  // UnknownField is being created.
+  inline void SetType(Type type);
+
+  uint32 number_;
+  uint32 type_;
+  union {
+    uint64 varint_;
+    uint32 fixed32_;
+    uint64 fixed64_;
+    mutable union {
+      string* string_value_;
+    } length_delimited_;
+    UnknownFieldSet* group_;
+  };
+};
+
+// ===================================================================
+// inline implementations
+
+inline void UnknownFieldSet::Clear() {
+  if (fields_ != NULL) {
+    ClearFallback();
+  }
+}
+
+inline bool UnknownFieldSet::empty() const {
+  return fields_ == NULL || fields_->empty();
+}
+
+inline void UnknownFieldSet::Swap(UnknownFieldSet* x) {
+  std::swap(fields_, x->fields_);
+}
+
+inline int UnknownFieldSet::field_count() const {
+  return (fields_ == NULL) ? 0 : static_cast<int>(fields_->size());
+}
+inline const UnknownField& UnknownFieldSet::field(int index) const {
+  return (*fields_)[index];
+}
+inline UnknownField* UnknownFieldSet::mutable_field(int index) {
+  return &(*fields_)[index];
+}
+
+inline void UnknownFieldSet::AddLengthDelimited(
+    int number, const string& value) {
+  AddLengthDelimited(number)->assign(value);
+}
+
+
+inline int UnknownField::number() const { return number_; }
+inline UnknownField::Type UnknownField::type() const {
+  return static_cast<Type>(type_);
+}
+
+inline uint64 UnknownField::varint() const {
+  assert(type() == TYPE_VARINT);
+  return varint_;
+}
+inline uint32 UnknownField::fixed32() const {
+  assert(type() == TYPE_FIXED32);
+  return fixed32_;
+}
+inline uint64 UnknownField::fixed64() const {
+  assert(type() == TYPE_FIXED64);
+  return fixed64_;
+}
+inline const string& UnknownField::length_delimited() const {
+  assert(type() == TYPE_LENGTH_DELIMITED);
+  return *length_delimited_.string_value_;
+}
+inline const UnknownFieldSet& UnknownField::group() const {
+  assert(type() == TYPE_GROUP);
+  return *group_;
+}
+
+inline void UnknownField::set_varint(uint64 value) {
+  assert(type() == TYPE_VARINT);
+  varint_ = value;
+}
+inline void UnknownField::set_fixed32(uint32 value) {
+  assert(type() == TYPE_FIXED32);
+  fixed32_ = value;
+}
+inline void UnknownField::set_fixed64(uint64 value) {
+  assert(type() == TYPE_FIXED64);
+  fixed64_ = value;
+}
+inline void UnknownField::set_length_delimited(const string& value) {
+  assert(type() == TYPE_LENGTH_DELIMITED);
+  length_delimited_.string_value_->assign(value);
+}
+inline string* UnknownField::mutable_length_delimited() {
+  assert(type() == TYPE_LENGTH_DELIMITED);
+  return length_delimited_.string_value_;
+}
+inline UnknownFieldSet* UnknownField::mutable_group() {
+  assert(type() == TYPE_GROUP);
+  return group_;
+}
+
+inline int UnknownField::GetLengthDelimitedSize() const {
+  GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type());
+  return static_cast<int>(length_delimited_.string_value_->size());
+}
+
+inline void UnknownField::SetType(Type type) {
+  type_ = type;
+}
+
+
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_UNKNOWN_FIELD_SET_H__
diff --git a/protobuf/src/google/protobuf/unknown_field_set_unittest.cc b/protobuf/src/google/protobuf/unknown_field_set_unittest.cc
new file mode 100644
index 0000000..aaaa2e8
--- /dev/null
+++ b/protobuf/src/google/protobuf/unknown_field_set_unittest.cc
@@ -0,0 +1,599 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.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>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+
+using internal::WireFormat;
+
+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;
+    for (int i = 0; i < unknown_fields_->field_count(); i++) {
+      if (unknown_fields_->field(i).number() == field->number()) {
+        return &unknown_fields_->field(i);
+      }
+    }
+    return NULL;
+  }
+
+  // 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);
+      if (unknown_field.type() == UnknownField::TYPE_VARINT) {
+        bizarro_unknown_fields->AddFixed32(unknown_field.number(), 1);
+      } else {
+        bizarro_unknown_fields->AddVarint(unknown_field.number(), 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_;
+};
+
+namespace {
+
+TEST_F(UnknownFieldSetTest, AllFieldsPresent) {
+  // All fields of TestAllTypes should be present, in numeric order (because
+  // that's the order we parsed them in).  Fields that are not valid field
+  // numbers of TestAllTypes should NOT be present.
+
+  int pos = 0;
+
+  for (int i = 0; i < 1000; i++) {
+    const FieldDescriptor* field = descriptor_->FindFieldByNumber(i);
+    if (field != NULL) {
+      ASSERT_LT(pos, unknown_fields_->field_count());
+      // Do not check oneof field if it is not set.
+      if (field->containing_oneof() == NULL) {
+        EXPECT_EQ(i, unknown_fields_->field(pos++).number());
+      } else if (i == unknown_fields_->field(pos).number()) {
+        pos++;
+      }
+      if (field->is_repeated()) {
+        // Should have a second instance.
+        ASSERT_LT(pos, unknown_fields_->field_count());
+        EXPECT_EQ(i, unknown_fields_->field(pos++).number());
+      }
+    }
+  }
+  EXPECT_EQ(unknown_fields_->field_count(), pos);
+}
+
+TEST_F(UnknownFieldSetTest, Varint) {
+  const UnknownField* field = GetField("optional_int32");
+  ASSERT_TRUE(field != NULL);
+
+  ASSERT_EQ(UnknownField::TYPE_VARINT, field->type());
+  EXPECT_EQ(all_fields_.optional_int32(), field->varint());
+}
+
+TEST_F(UnknownFieldSetTest, Fixed32) {
+  const UnknownField* field = GetField("optional_fixed32");
+  ASSERT_TRUE(field != NULL);
+
+  ASSERT_EQ(UnknownField::TYPE_FIXED32, field->type());
+  EXPECT_EQ(all_fields_.optional_fixed32(), field->fixed32());
+}
+
+TEST_F(UnknownFieldSetTest, Fixed64) {
+  const UnknownField* field = GetField("optional_fixed64");
+  ASSERT_TRUE(field != NULL);
+
+  ASSERT_EQ(UnknownField::TYPE_FIXED64, field->type());
+  EXPECT_EQ(all_fields_.optional_fixed64(), field->fixed64());
+}
+
+TEST_F(UnknownFieldSetTest, LengthDelimited) {
+  const UnknownField* field = GetField("optional_string");
+  ASSERT_TRUE(field != NULL);
+
+  ASSERT_EQ(UnknownField::TYPE_LENGTH_DELIMITED, field->type());
+  EXPECT_EQ(all_fields_.optional_string(), field->length_delimited());
+}
+
+TEST_F(UnknownFieldSetTest, Group) {
+  const UnknownField* field = GetField("optionalgroup");
+  ASSERT_TRUE(field != NULL);
+
+  ASSERT_EQ(UnknownField::TYPE_GROUP, field->type());
+  ASSERT_EQ(1, field->group().field_count());
+
+  const UnknownField& nested_field = field->group().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());
+  ASSERT_EQ(UnknownField::TYPE_VARINT, nested_field.type());
+  EXPECT_EQ(all_fields_.optionalgroup().a(), nested_field.varint());
+}
+
+TEST_F(UnknownFieldSetTest, SerializeFastAndSlowAreEquivalent) {
+  int size = WireFormat::ComputeUnknownFieldsSize(
+      empty_message_.unknown_fields());
+  string slow_buffer;
+  string fast_buffer;
+  slow_buffer.resize(size);
+  fast_buffer.resize(size);
+
+  uint8* target = reinterpret_cast<uint8*>(string_as_array(&fast_buffer));
+  uint8* result = WireFormat::SerializeUnknownFieldsToArray(
+          empty_message_.unknown_fields(), target);
+  EXPECT_EQ(size, result - target);
+
+  {
+    io::ArrayOutputStream raw_stream(string_as_array(&slow_buffer), size, 1);
+    io::CodedOutputStream output_stream(&raw_stream);
+    WireFormat::SerializeUnknownFields(empty_message_.unknown_fields(),
+                                       &output_stream);
+    ASSERT_FALSE(output_stream.HadError());
+  }
+  EXPECT_TRUE(fast_buffer == slow_buffer);
+}
+
+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(&input, &message));
+
+  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_);
+    WireFormat::SerializeWithCachedSizes(empty_message_, size, &output);
+    ASSERT_FALSE(output.HadError());
+  }
+
+  // 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, Swap) {
+  unittest::TestEmptyMessage other_message;
+  ASSERT_TRUE(other_message.ParseFromString(GetBizarroData()));
+
+  EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
+  EXPECT_GT(other_message.unknown_fields().field_count(), 0);
+  const string debug_string = empty_message_.DebugString();
+  const string other_debug_string = other_message.DebugString();
+  EXPECT_NE(debug_string, other_debug_string);
+
+  empty_message_.Swap(&other_message);
+  EXPECT_EQ(debug_string, other_message.DebugString());
+  EXPECT_EQ(other_debug_string, empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, SwapWithSelf) {
+  const string debug_string = empty_message_.DebugString();
+  EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
+
+  empty_message_.Swap(&empty_message_);
+  EXPECT_GT(empty_message_.unknown_fields().field_count(), 0);
+  EXPECT_EQ(debug_string, empty_message_.DebugString());
+}
+
+TEST_F(UnknownFieldSetTest, MergeFrom) {
+  unittest::TestEmptyMessage source, destination;
+
+  destination.mutable_unknown_fields()->AddVarint(1, 1);
+  destination.mutable_unknown_fields()->AddVarint(3, 2);
+  source.mutable_unknown_fields()->AddVarint(2, 3);
+  source.mutable_unknown_fields()->AddVarint(3, 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"
+    "2: 3\n"
+    "3: 4\n",
+    destination.DebugString());
+}
+
+
+TEST_F(UnknownFieldSetTest, Clear) {
+  // Clear the set.
+  empty_message_.Clear();
+  EXPECT_EQ(0, unknown_fields_->field_count());
+}
+
+TEST_F(UnknownFieldSetTest, ClearAndFreeMemory) {
+  EXPECT_GT(unknown_fields_->field_count(), 0);
+  unknown_fields_->ClearAndFreeMemory();
+  EXPECT_EQ(0, unknown_fields_->field_count());
+  unknown_fields_->AddVarint(123456, 654321);
+  EXPECT_EQ(1, unknown_fields_->field_count());
+}
+
+TEST_F(UnknownFieldSetTest, ParseKnownAndUnknown) {
+  // Test mixing known and unknown fields when parsing.
+
+  unittest::TestEmptyMessage source;
+  source.mutable_unknown_fields()->AddVarint(123456, 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(UnknownField::TYPE_VARINT,
+            destination.unknown_fields().field(0).type());
+  EXPECT_EQ(654321, destination.unknown_fields().field(0).varint());
+}
+
+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(&input, &all_types_message));
+  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(&input, &message));
+
+  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();
+    unknown_fields->AddVarint(singular_field->number(), TestAllTypes::BAR);
+    unknown_fields->AddVarint(singular_field->number(), 5);  // not valid
+    unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::FOO);
+    unknown_fields->AddVarint(repeated_field->number(), 4);  // not valid
+    unknown_fields->AddVarint(repeated_field->number(), TestAllTypes::BAZ);
+    unknown_fields->AddVarint(repeated_field->number(), 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(3, unknown_fields.field_count());
+
+    EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number());
+    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type());
+    EXPECT_EQ(5, unknown_fields.field(0).varint());
+
+    EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number());
+    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type());
+    EXPECT_EQ(4, unknown_fields.field(1).varint());
+
+    EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number());
+    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type());
+    EXPECT_EQ(6, unknown_fields.field(2).varint());
+  }
+
+  {
+    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(3, unknown_fields.field_count());
+
+    EXPECT_EQ(singular_field->number(), unknown_fields.field(0).number());
+    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(0).type());
+    EXPECT_EQ(5, unknown_fields.field(0).varint());
+
+    EXPECT_EQ(repeated_field->number(), unknown_fields.field(1).number());
+    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(1).type());
+    EXPECT_EQ(4, unknown_fields.field(1).varint());
+
+    EXPECT_EQ(repeated_field->number(), unknown_fields.field(2).number());
+    ASSERT_EQ(UnknownField::TYPE_VARINT, unknown_fields.field(2).type());
+    EXPECT_EQ(6, unknown_fields.field(2).varint());
+  }
+}
+
+TEST_F(UnknownFieldSetTest, SpaceUsed) {
+  unittest::TestEmptyMessage empty_message;
+
+  // Make sure an unknown field set has zero space used until a field is
+  // actually added.
+  int base_size = empty_message.SpaceUsed();
+  UnknownFieldSet* unknown_fields = empty_message.mutable_unknown_fields();
+  EXPECT_EQ(base_size, empty_message.SpaceUsed());
+
+  // Make sure each thing we add to the set increases the SpaceUsed().
+  unknown_fields->AddVarint(1, 0);
+  EXPECT_LT(base_size, empty_message.SpaceUsed());
+  base_size = empty_message.SpaceUsed();
+
+  string* str = unknown_fields->AddLengthDelimited(1);
+  EXPECT_LT(base_size, empty_message.SpaceUsed());
+  base_size = empty_message.SpaceUsed();
+
+  str->assign(sizeof(string) + 1, 'x');
+  EXPECT_LT(base_size, empty_message.SpaceUsed());
+  base_size = empty_message.SpaceUsed();
+
+  UnknownFieldSet* group = unknown_fields->AddGroup(1);
+  EXPECT_LT(base_size, empty_message.SpaceUsed());
+  base_size = empty_message.SpaceUsed();
+
+  group->AddVarint(1, 0);
+  EXPECT_LT(base_size, empty_message.SpaceUsed());
+}
+
+
+TEST_F(UnknownFieldSetTest, Empty) {
+  UnknownFieldSet unknown_fields;
+  EXPECT_TRUE(unknown_fields.empty());
+  unknown_fields.AddVarint(6, 123);
+  EXPECT_FALSE(unknown_fields.empty());
+  unknown_fields.Clear();
+  EXPECT_TRUE(unknown_fields.empty());
+}
+
+TEST_F(UnknownFieldSetTest, DeleteSubrange) {
+  // Exhaustively test the deletion of every possible subrange in arrays of all
+  // sizes from 0 through 9.
+  for (int size = 0; size < 10; ++size) {
+    for (int num = 0; num <= size; ++num) {
+      for (int start = 0; start < size - num; ++start) {
+        // Create a set with "size" fields.
+        UnknownFieldSet unknown;
+        for (int i = 0; i < size; ++i) {
+          unknown.AddFixed32(i, i);
+        }
+        // Delete the specified subrange.
+        unknown.DeleteSubrange(start, num);
+        // Make sure the resulting field values are still correct.
+        EXPECT_EQ(size - num, unknown.field_count());
+        for (int i = 0; i < unknown.field_count(); ++i) {
+          if (i < start) {
+            EXPECT_EQ(i, unknown.field(i).fixed32());
+          } else {
+            EXPECT_EQ(i + num, unknown.field(i).fixed32());
+          }
+        }
+      }
+    }
+  }
+}
+
+void CheckDeleteByNumber(const vector<int>& field_numbers, int deleted_number,
+                        const vector<int>& expected_field_nubmers) {
+  UnknownFieldSet unknown_fields;
+  for (int i = 0; i < field_numbers.size(); ++i) {
+    unknown_fields.AddFixed32(field_numbers[i], i);
+  }
+  unknown_fields.DeleteByNumber(deleted_number);
+  ASSERT_EQ(expected_field_nubmers.size(), unknown_fields.field_count());
+  for (int i = 0; i < expected_field_nubmers.size(); ++i) {
+    EXPECT_EQ(expected_field_nubmers[i],
+              unknown_fields.field(i).number());
+  }
+}
+
+#define MAKE_VECTOR(x) vector<int>(x, x + GOOGLE_ARRAYSIZE(x))
+TEST_F(UnknownFieldSetTest, DeleteByNumber) {
+  CheckDeleteByNumber(vector<int>(), 1, vector<int>());
+  static const int kTestFieldNumbers1[] = {1, 2, 3};
+  static const int kFieldNumberToDelete1 = 1;
+  static const int kExpectedFieldNumbers1[] = {2, 3};
+  CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers1), kFieldNumberToDelete1,
+                      MAKE_VECTOR(kExpectedFieldNumbers1));
+  static const int kTestFieldNumbers2[] = {1, 2, 3};
+  static const int kFieldNumberToDelete2 = 2;
+  static const int kExpectedFieldNumbers2[] = {1, 3};
+  CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers2), kFieldNumberToDelete2,
+                      MAKE_VECTOR(kExpectedFieldNumbers2));
+  static const int kTestFieldNumbers3[] = {1, 2, 3};
+  static const int kFieldNumberToDelete3 = 3;
+  static const int kExpectedFieldNumbers3[] = {1, 2};
+  CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers3), kFieldNumberToDelete3,
+                      MAKE_VECTOR(kExpectedFieldNumbers3));
+  static const int kTestFieldNumbers4[] = {1, 2, 1, 4, 1};
+  static const int kFieldNumberToDelete4 = 1;
+  static const int kExpectedFieldNumbers4[] = {2, 4};
+  CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers4), kFieldNumberToDelete4,
+                      MAKE_VECTOR(kExpectedFieldNumbers4));
+  static const int kTestFieldNumbers5[] = {1, 2, 3, 4, 5};
+  static const int kFieldNumberToDelete5 = 6;
+  static const int kExpectedFieldNumbers5[] = {1, 2, 3, 4, 5};
+  CheckDeleteByNumber(MAKE_VECTOR(kTestFieldNumbers5), kFieldNumberToDelete5,
+                      MAKE_VECTOR(kExpectedFieldNumbers5));
+}
+#undef MAKE_VECTOR
+}  // namespace
+
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/wire_format.cc b/protobuf/src/google/protobuf/wire_format.cc
new file mode 100644
index 0000000..6bdfcd6
--- /dev/null
+++ b/protobuf/src/google/protobuf/wire_format.cc
@@ -0,0 +1,1101 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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.h>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/wire_format_lite_inl.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();
+}
+
+}  // anonymous namespace
+
+// ===================================================================
+
+bool UnknownFieldSetFieldSkipper::SkipField(
+    io::CodedInputStream* input, uint32 tag) {
+  return WireFormat::SkipField(input, tag, unknown_fields_);
+}
+
+bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) {
+  return WireFormat::SkipMessage(input, unknown_fields_);
+}
+
+void UnknownFieldSetFieldSkipper::SkipUnknownEnum(
+    int field_number, int value) {
+  unknown_fields_->AddVarint(field_number, value);
+}
+
+bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag,
+                           UnknownFieldSet* unknown_fields) {
+  int number = WireFormatLite::GetTagFieldNumber(tag);
+
+  switch (WireFormatLite::GetTagWireType(tag)) {
+    case WireFormatLite::WIRETYPE_VARINT: {
+      uint64 value;
+      if (!input->ReadVarint64(&value)) return false;
+      if (unknown_fields != NULL) unknown_fields->AddVarint(number, value);
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_FIXED64: {
+      uint64 value;
+      if (!input->ReadLittleEndian64(&value)) return false;
+      if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value);
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+      uint32 length;
+      if (!input->ReadVarint32(&length)) return false;
+      if (unknown_fields == NULL) {
+        if (!input->Skip(length)) return false;
+      } else {
+        if (!input->ReadString(unknown_fields->AddLengthDelimited(number),
+                               length)) {
+          return false;
+        }
+      }
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_START_GROUP: {
+      if (!input->IncrementRecursionDepth()) return false;
+      if (!SkipMessage(input, (unknown_fields == NULL) ?
+                              NULL : unknown_fields->AddGroup(number))) {
+        return false;
+      }
+      input->DecrementRecursionDepth();
+      // Check that the ending tag matched the starting tag.
+      if (!input->LastTagWas(WireFormatLite::MakeTag(
+          WireFormatLite::GetTagFieldNumber(tag),
+          WireFormatLite::WIRETYPE_END_GROUP))) {
+        return false;
+      }
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_END_GROUP: {
+      return false;
+    }
+    case WireFormatLite::WIRETYPE_FIXED32: {
+      uint32 value;
+      if (!input->ReadLittleEndian32(&value)) return false;
+      if (unknown_fields != NULL) unknown_fields->AddFixed32(number, 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;
+    }
+
+    WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
+
+    if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
+      // Must be the end of the message.
+      return true;
+    }
+
+    if (!SkipField(input, tag, unknown_fields)) return false;
+  }
+}
+
+void 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);
+    switch (field.type()) {
+      case UnknownField::TYPE_VARINT:
+        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_VARINT));
+        output->WriteVarint64(field.varint());
+        break;
+      case UnknownField::TYPE_FIXED32:
+        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_FIXED32));
+        output->WriteLittleEndian32(field.fixed32());
+        break;
+      case UnknownField::TYPE_FIXED64:
+        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_FIXED64));
+        output->WriteLittleEndian64(field.fixed64());
+        break;
+      case UnknownField::TYPE_LENGTH_DELIMITED:
+        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
+        output->WriteVarint32(field.length_delimited().size());
+        output->WriteRawMaybeAliased(field.length_delimited().data(),
+                                     field.length_delimited().size());
+        break;
+      case UnknownField::TYPE_GROUP:
+        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_START_GROUP));
+        SerializeUnknownFields(field.group(), output);
+        output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_END_GROUP));
+        break;
+    }
+  }
+}
+
+uint8* WireFormat::SerializeUnknownFieldsToArray(
+    const UnknownFieldSet& unknown_fields,
+    uint8* target) {
+  for (int i = 0; i < unknown_fields.field_count(); i++) {
+    const UnknownField& field = unknown_fields.field(i);
+
+    switch (field.type()) {
+      case UnknownField::TYPE_VARINT:
+        target = WireFormatLite::WriteInt64ToArray(
+            field.number(), field.varint(), target);
+        break;
+      case UnknownField::TYPE_FIXED32:
+        target = WireFormatLite::WriteFixed32ToArray(
+            field.number(), field.fixed32(), target);
+        break;
+      case UnknownField::TYPE_FIXED64:
+        target = WireFormatLite::WriteFixed64ToArray(
+            field.number(), field.fixed64(), target);
+        break;
+      case UnknownField::TYPE_LENGTH_DELIMITED:
+        target = WireFormatLite::WriteBytesToArray(
+            field.number(), field.length_delimited(), target);
+        break;
+      case UnknownField::TYPE_GROUP:
+        target = WireFormatLite::WriteTagToArray(
+            field.number(), WireFormatLite::WIRETYPE_START_GROUP, target);
+        target = SerializeUnknownFieldsToArray(field.group(), target);
+        target = WireFormatLite::WriteTagToArray(
+            field.number(), WireFormatLite::WIRETYPE_END_GROUP, target);
+        break;
+    }
+  }
+  return target;
+}
+
+void 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);
+    // The only unknown fields that are allowed to exist in a MessageSet are
+    // messages, which are length-delimited.
+    if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
+      // Start group.
+      output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
+
+      // Write type ID.
+      output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
+      output->WriteVarint32(field.number());
+
+      // Write message.
+      output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
+      field.SerializeLengthDelimitedNoTag(output);
+
+      // End group.
+      output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
+    }
+  }
+}
+
+uint8* WireFormat::SerializeUnknownMessageSetItemsToArray(
+    const UnknownFieldSet& unknown_fields,
+    uint8* target) {
+  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.
+    if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
+      // Start group.
+      target = io::CodedOutputStream::WriteTagToArray(
+          WireFormatLite::kMessageSetItemStartTag, target);
+
+      // Write type ID.
+      target = io::CodedOutputStream::WriteTagToArray(
+          WireFormatLite::kMessageSetTypeIdTag, target);
+      target = io::CodedOutputStream::WriteVarint32ToArray(
+          field.number(), target);
+
+      // Write message.
+      target = io::CodedOutputStream::WriteTagToArray(
+          WireFormatLite::kMessageSetMessageTag, target);
+      target = field.SerializeLengthDelimitedNoTagToArray(target);
+
+      // End group.
+      target = io::CodedOutputStream::WriteTagToArray(
+          WireFormatLite::kMessageSetItemEndTag, target);
+    }
+  }
+
+  return target;
+}
+
+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);
+
+    switch (field.type()) {
+      case UnknownField::TYPE_VARINT:
+        size += io::CodedOutputStream::VarintSize32(
+            WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_VARINT));
+        size += io::CodedOutputStream::VarintSize64(field.varint());
+        break;
+      case UnknownField::TYPE_FIXED32:
+        size += io::CodedOutputStream::VarintSize32(
+            WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_FIXED32));
+        size += sizeof(int32);
+        break;
+      case UnknownField::TYPE_FIXED64:
+        size += io::CodedOutputStream::VarintSize32(
+            WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_FIXED64));
+        size += sizeof(int64);
+        break;
+      case UnknownField::TYPE_LENGTH_DELIMITED:
+        size += io::CodedOutputStream::VarintSize32(
+            WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
+        size += io::CodedOutputStream::VarintSize32(
+            field.length_delimited().size());
+        size += field.length_delimited().size();
+        break;
+      case UnknownField::TYPE_GROUP:
+        size += io::CodedOutputStream::VarintSize32(
+            WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_START_GROUP));
+        size += ComputeUnknownFieldsSize(field.group());
+        size += io::CodedOutputStream::VarintSize32(
+            WireFormatLite::MakeTag(field.number(),
+            WireFormatLite::WIRETYPE_END_GROUP));
+        break;
+    }
+  }
+
+  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.
+    if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
+      size += WireFormatLite::kMessageSetItemTagsSize;
+      size += io::CodedOutputStream::VarintSize32(field.number());
+
+      int field_size = field.GetLengthDelimitedSize();
+      size += io::CodedOutputStream::VarintSize32(field_size);
+      size += field_size;
+    }
+  }
+
+  return size;
+}
+
+// ===================================================================
+
+bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
+                                      Message* message) {
+  const Descriptor* descriptor = message->GetDescriptor();
+  const Reflection* message_reflection = message->GetReflection();
+
+  while(true) {
+    uint32 tag = input->ReadTag();
+    if (tag == 0) {
+      // End of input.  This is a valid place to end, so return true.
+      return true;
+    }
+
+    if (WireFormatLite::GetTagWireType(tag) ==
+        WireFormatLite::WIRETYPE_END_GROUP) {
+      // Must be the end of the message.
+      return true;
+    }
+
+    const FieldDescriptor* field = NULL;
+
+    if (descriptor != NULL) {
+      int field_number = WireFormatLite::GetTagFieldNumber(tag);
+      field = descriptor->FindFieldByNumber(field_number);
+
+      // If that failed, check if the field is an extension.
+      if (field == NULL && descriptor->IsExtensionNumber(field_number)) {
+        if (input->GetExtensionPool() == NULL) {
+          field = message_reflection->FindKnownExtensionByNumber(field_number);
+        } else {
+          field = input->GetExtensionPool()
+                       ->FindExtensionByNumber(descriptor, 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 == WireFormatLite::kMessageSetItemStartTag) {
+        if (!ParseAndMergeMessageSetItem(input, message)) {
+          return false;
+        }
+        continue;  // Skip ParseAndMergeField(); already taken care of.
+      }
+    }
+
+    if (!ParseAndMergeField(tag, field, message, input)) {
+      return false;
+    }
+  }
+}
+
+bool WireFormat::SkipMessageSetField(io::CodedInputStream* input,
+                                     uint32 field_number,
+                                     UnknownFieldSet* unknown_fields) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  return input->ReadString(
+      unknown_fields->AddLengthDelimited(field_number), length);
+}
+
+bool WireFormat::ParseAndMergeMessageSetField(uint32 field_number,
+                                              const FieldDescriptor* field,
+                                              Message* message,
+                                              io::CodedInputStream* input) {
+  const Reflection* message_reflection = message->GetReflection();
+  if (field == NULL) {
+    // We store unknown MessageSet extensions as groups.
+    return SkipMessageSetField(
+        input, field_number, message_reflection->MutableUnknownFields(message));
+  } else if (field->is_repeated() ||
+             field->type() != FieldDescriptor::TYPE_MESSAGE) {
+    // This shouldn't happen as we only allow optional message extensions to
+    // MessageSet.
+    GOOGLE_LOG(ERROR) << "Extensions of MessageSets must be optional messages.";
+    return false;
+  } else {
+    Message* sub_message = message_reflection->MutableMessage(
+        message, field, input->GetExtensionFactory());
+    return WireFormatLite::ReadMessage(input, sub_message);
+  }
+}
+
+bool WireFormat::ParseAndMergeField(
+    uint32 tag,
+    const FieldDescriptor* field,        // May be NULL for unknown
+    Message* message,
+    io::CodedInputStream* input) {
+  const Reflection* message_reflection = message->GetReflection();
+
+  enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format;
+
+  if (field == NULL) {
+    value_format = UNKNOWN;
+  } else if (WireFormatLite::GetTagWireType(tag) ==
+             WireTypeForFieldType(field->type())) {
+    value_format = NORMAL_FORMAT;
+  } else if (field->is_packable() &&
+             WireFormatLite::GetTagWireType(tag) ==
+             WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+    value_format = PACKED_FORMAT;
+  } else {
+    // 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.
+    value_format = UNKNOWN;
+  }
+
+  if (value_format == UNKNOWN) {
+    return SkipField(input, tag,
+                     message_reflection->MutableUnknownFields(message));
+  } else if (value_format == PACKED_FORMAT) {
+    uint32 length;
+    if (!input->ReadVarint32(&length)) return false;
+    io::CodedInputStream::Limit limit = input->PushLimit(length);
+
+    switch (field->type()) {
+#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                      \
+      case FieldDescriptor::TYPE_##TYPE: {                                     \
+        while (input->BytesUntilLimit() > 0) {                                 \
+          CPPTYPE value;                                                       \
+          if (!WireFormatLite::ReadPrimitive<                                  \
+                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value))          \
+            return false;                                                      \
+          message_reflection->Add##CPPTYPE_METHOD(message, field, value);      \
+        }                                                                      \
+        break;                                                                 \
+      }
+
+      HANDLE_PACKED_TYPE( INT32,  int32,  Int32)
+      HANDLE_PACKED_TYPE( INT64,  int64,  Int64)
+      HANDLE_PACKED_TYPE(SINT32,  int32,  Int32)
+      HANDLE_PACKED_TYPE(SINT64,  int64,  Int64)
+      HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
+      HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)
+
+      HANDLE_PACKED_TYPE( FIXED32, uint32, UInt32)
+      HANDLE_PACKED_TYPE( FIXED64, uint64, UInt64)
+      HANDLE_PACKED_TYPE(SFIXED32,  int32,  Int32)
+      HANDLE_PACKED_TYPE(SFIXED64,  int64,  Int64)
+
+      HANDLE_PACKED_TYPE(FLOAT , float , Float )
+      HANDLE_PACKED_TYPE(DOUBLE, double, Double)
+
+      HANDLE_PACKED_TYPE(BOOL, bool, Bool)
+#undef HANDLE_PACKED_TYPE
+
+      case FieldDescriptor::TYPE_ENUM: {
+        while (input->BytesUntilLimit() > 0) {
+          int value;
+          if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+                  input, &value)) return false;
+          const EnumValueDescriptor* enum_value =
+              field->enum_type()->FindValueByNumber(value);
+          if (enum_value != NULL) {
+            message_reflection->AddEnum(message, field, enum_value);
+          }
+        }
+
+        break;
+      }
+
+      case FieldDescriptor::TYPE_STRING:
+      case FieldDescriptor::TYPE_GROUP:
+      case FieldDescriptor::TYPE_MESSAGE:
+      case FieldDescriptor::TYPE_BYTES:
+        // Can't have packed fields of these types: these should be caught by
+        // the protocol compiler.
+        return false;
+        break;
+    }
+
+    input->PopLimit(limit);
+  } else {
+    // Non-packed value (value_format == NORMAL_FORMAT)
+    switch (field->type()) {
+#define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                            \
+      case FieldDescriptor::TYPE_##TYPE: {                                    \
+        CPPTYPE value;                                                        \
+        if (!WireFormatLite::ReadPrimitive<                                   \
+                CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value))         \
+          return false;                                                       \
+        if (field->is_repeated()) {                                           \
+          message_reflection->Add##CPPTYPE_METHOD(message, field, value);     \
+        } else {                                                              \
+          message_reflection->Set##CPPTYPE_METHOD(message, field, value);     \
+        }                                                                     \
+        break;                                                                \
+      }
+
+      HANDLE_TYPE( INT32,  int32,  Int32)
+      HANDLE_TYPE( INT64,  int64,  Int64)
+      HANDLE_TYPE(SINT32,  int32,  Int32)
+      HANDLE_TYPE(SINT64,  int64,  Int64)
+      HANDLE_TYPE(UINT32, uint32, UInt32)
+      HANDLE_TYPE(UINT64, uint64, UInt64)
+
+      HANDLE_TYPE( FIXED32, uint32, UInt32)
+      HANDLE_TYPE( FIXED64, uint64, UInt64)
+      HANDLE_TYPE(SFIXED32,  int32,  Int32)
+      HANDLE_TYPE(SFIXED64,  int64,  Int64)
+
+      HANDLE_TYPE(FLOAT , float , Float )
+      HANDLE_TYPE(DOUBLE, double, Double)
+
+      HANDLE_TYPE(BOOL, bool, Bool)
+#undef HANDLE_TYPE
+
+      case FieldDescriptor::TYPE_ENUM: {
+        int value;
+        if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+                input, &value)) return false;
+        const EnumValueDescriptor* enum_value =
+          field->enum_type()->FindValueByNumber(value);
+        if (enum_value != NULL) {
+          if (field->is_repeated()) {
+            message_reflection->AddEnum(message, field, enum_value);
+          } else {
+            message_reflection->SetEnum(message, field, enum_value);
+          }
+        } else {
+          // The enum value is not one of the known values.  Add it to the
+          // UnknownFieldSet.
+          int64 sign_extended_value = static_cast<int64>(value);
+          message_reflection->MutableUnknownFields(message)
+                            ->AddVarint(WireFormatLite::GetTagFieldNumber(tag),
+                                        sign_extended_value);
+        }
+        break;
+      }
+
+      // Handle strings separately so that we can optimize the ctype=CORD case.
+      case FieldDescriptor::TYPE_STRING: {
+        string value;
+        if (!WireFormatLite::ReadString(input, &value)) return false;
+        VerifyUTF8StringNamedField(value.data(), value.length(), PARSE,
+                                   field->name().c_str());
+        if (field->is_repeated()) {
+          message_reflection->AddString(message, field, value);
+        } else {
+          message_reflection->SetString(message, field, value);
+        }
+        break;
+      }
+
+      case FieldDescriptor::TYPE_BYTES: {
+        string value;
+        if (!WireFormatLite::ReadBytes(input, &value)) return false;
+        if (field->is_repeated()) {
+          message_reflection->AddString(message, field, value);
+        } else {
+          message_reflection->SetString(message, field, value);
+        }
+        break;
+      }
+
+      case FieldDescriptor::TYPE_GROUP: {
+        Message* sub_message;
+        if (field->is_repeated()) {
+          sub_message = message_reflection->AddMessage(
+              message, field, input->GetExtensionFactory());
+        } else {
+          sub_message = message_reflection->MutableMessage(
+              message, field, input->GetExtensionFactory());
+        }
+
+        if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag),
+                                       input, sub_message))
+          return false;
+        break;
+      }
+
+      case FieldDescriptor::TYPE_MESSAGE: {
+        Message* sub_message;
+        if (field->is_repeated()) {
+          sub_message = message_reflection->AddMessage(
+              message, field, input->GetExtensionFactory());
+        } else {
+          sub_message = message_reflection->MutableMessage(
+              message, field, input->GetExtensionFactory());
+        }
+
+        if (!WireFormatLite::ReadMessage(input, sub_message)) return false;
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+bool WireFormat::ParseAndMergeMessageSetItem(
+    io::CodedInputStream* input,
+    Message* message) {
+  const Reflection* message_reflection = message->GetReflection();
+
+  // This method parses a group which should contain two fields:
+  //   required int32 type_id = 2;
+  //   required data message = 3;
+
+  uint32 last_type_id = 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.
+  string message_data;
+
+  while (true) {
+    uint32 tag = input->ReadTag();
+    if (tag == 0) return false;
+
+    switch (tag) {
+      case WireFormatLite::kMessageSetTypeIdTag: {
+        uint32 type_id;
+        if (!input->ReadVarint32(&type_id)) return false;
+        last_type_id = type_id;
+        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 (!ParseAndMergeMessageSetField(last_type_id, field, message,
+                                            &sub_input)) {
+            return false;
+          }
+          message_data.clear();
+        }
+
+        break;
+      }
+
+      case WireFormatLite::kMessageSetMessageTag: {
+        if (last_type_id == 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;
+          io::StringOutputStream output_stream(&message_data);
+          io::CodedOutputStream coded_output(&output_stream);
+          coded_output.WriteVarint32(length);
+          coded_output.WriteString(temp);
+        } else {
+          // Already saw type_id, so we can parse this directly.
+          if (!ParseAndMergeMessageSetField(last_type_id, field, message,
+                                            input)) {
+            return false;
+          }
+        }
+
+        break;
+      }
+
+      case WireFormatLite::kMessageSetItemEndTag: {
+        return true;
+      }
+
+      default: {
+        if (!SkipField(input, tag, NULL)) return false;
+      }
+    }
+  }
+}
+
+// ===================================================================
+
+void WireFormat::SerializeWithCachedSizes(
+    const Message& message,
+    int size, io::CodedOutputStream* output) {
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* message_reflection = message.GetReflection();
+  int expected_endpoint = output->ByteCount() + size;
+
+  vector<const FieldDescriptor*> fields;
+  message_reflection->ListFields(message, &fields);
+  for (int i = 0; i < fields.size(); i++) {
+    SerializeFieldWithCachedSizes(fields[i], message, output);
+  }
+
+  if (descriptor->options().message_set_wire_format()) {
+    SerializeUnknownMessageSetItems(
+        message_reflection->GetUnknownFields(message), output);
+  } else {
+    SerializeUnknownFields(
+        message_reflection->GetUnknownFields(message), output);
+  }
+
+  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?";
+}
+
+void WireFormat::SerializeFieldWithCachedSizes(
+    const FieldDescriptor* field,
+    const Message& message,
+    io::CodedOutputStream* output) {
+  const Reflection* message_reflection = message.GetReflection();
+
+  if (field->is_extension() &&
+      field->containing_type()->options().message_set_wire_format() &&
+      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+      !field->is_repeated()) {
+    SerializeMessageSetItemWithCachedSizes(field, message, output);
+    return;
+  }
+
+  int count = 0;
+
+  if (field->is_repeated()) {
+    count = message_reflection->FieldSize(message, field);
+  } else if (message_reflection->HasField(message, field)) {
+    count = 1;
+  }
+
+  const bool is_packed = field->options().packed();
+  if (is_packed && count > 0) {
+    WireFormatLite::WriteTag(field->number(),
+        WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+    const int data_size = FieldDataOnlyByteSize(field, message);
+    output->WriteVarint32(data_size);
+  }
+
+  for (int j = 0; j < count; j++) {
+    switch (field->type()) {
+#define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD)      \
+      case FieldDescriptor::TYPE_##TYPE: {                                     \
+        const CPPTYPE value = field->is_repeated() ?                           \
+                              message_reflection->GetRepeated##CPPTYPE_METHOD( \
+                                message, field, j) :                           \
+                              message_reflection->Get##CPPTYPE_METHOD(         \
+                                message, field);                               \
+        if (is_packed) {                                                       \
+          WireFormatLite::Write##TYPE_METHOD##NoTag(value, output);            \
+        } else {                                                               \
+          WireFormatLite::Write##TYPE_METHOD(field->number(), value, output);  \
+        }                                                                      \
+        break;                                                                 \
+      }
+
+      HANDLE_PRIMITIVE_TYPE( INT32,  int32,  Int32,  Int32)
+      HANDLE_PRIMITIVE_TYPE( INT64,  int64,  Int64,  Int64)
+      HANDLE_PRIMITIVE_TYPE(SINT32,  int32, SInt32,  Int32)
+      HANDLE_PRIMITIVE_TYPE(SINT64,  int64, SInt64,  Int64)
+      HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32)
+      HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64)
+
+      HANDLE_PRIMITIVE_TYPE( FIXED32, uint32,  Fixed32, UInt32)
+      HANDLE_PRIMITIVE_TYPE( FIXED64, uint64,  Fixed64, UInt64)
+      HANDLE_PRIMITIVE_TYPE(SFIXED32,  int32, SFixed32,  Int32)
+      HANDLE_PRIMITIVE_TYPE(SFIXED64,  int64, SFixed64,  Int64)
+
+      HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float )
+      HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
+
+      HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
+#undef HANDLE_PRIMITIVE_TYPE
+
+#define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                       \
+      case FieldDescriptor::TYPE_##TYPE:                                     \
+        WireFormatLite::Write##TYPE_METHOD(                                  \
+              field->number(),                                               \
+              field->is_repeated() ?                                         \
+                message_reflection->GetRepeated##CPPTYPE_METHOD(             \
+                  message, field, j) :                                       \
+                message_reflection->Get##CPPTYPE_METHOD(message, field),     \
+              output);                                                       \
+        break;
+
+      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(message, field, j) :
+          message_reflection->GetEnum(message, field);
+        if (is_packed) {
+          WireFormatLite::WriteEnumNoTag(value->number(), output);
+        } else {
+          WireFormatLite::WriteEnum(field->number(), value->number(), output);
+        }
+        break;
+      }
+
+      // Handle strings separately so that we can get string references
+      // instead of copying.
+      case FieldDescriptor::TYPE_STRING: {
+        string scratch;
+        const string& value = field->is_repeated() ?
+          message_reflection->GetRepeatedStringReference(
+            message, field, j, &scratch) :
+          message_reflection->GetStringReference(message, field, &scratch);
+        VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE,
+                                   field->name().c_str());
+        WireFormatLite::WriteString(field->number(), value, output);
+        break;
+      }
+
+      case FieldDescriptor::TYPE_BYTES: {
+        string scratch;
+        const string& value = field->is_repeated() ?
+          message_reflection->GetRepeatedStringReference(
+            message, field, j, &scratch) :
+          message_reflection->GetStringReference(message, field, &scratch);
+        WireFormatLite::WriteBytes(field->number(), value, output);
+        break;
+      }
+    }
+  }
+}
+
+void WireFormat::SerializeMessageSetItemWithCachedSizes(
+    const FieldDescriptor* field,
+    const Message& message,
+    io::CodedOutputStream* output) {
+  const Reflection* message_reflection = message.GetReflection();
+
+  // Start group.
+  output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
+
+  // Write type ID.
+  output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
+  output->WriteVarint32(field->number());
+
+  // Write message.
+  output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
+
+  const Message& sub_message = message_reflection->GetMessage(message, field);
+  output->WriteVarint32(sub_message.GetCachedSize());
+  sub_message.SerializeWithCachedSizes(output);
+
+  // End group.
+  output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
+}
+
+// ===================================================================
+
+int WireFormat::ByteSize(const Message& message) {
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* message_reflection = message.GetReflection();
+
+  int our_size = 0;
+
+  vector<const FieldDescriptor*> fields;
+  message_reflection->ListFields(message, &fields);
+  for (int i = 0; i < fields.size(); i++) {
+    our_size += FieldByteSize(fields[i], message);
+  }
+
+  if (descriptor->options().message_set_wire_format()) {
+    our_size += ComputeUnknownMessageSetItemsSize(
+      message_reflection->GetUnknownFields(message));
+  } else {
+    our_size += ComputeUnknownFieldsSize(
+      message_reflection->GetUnknownFields(message));
+  }
+
+  return our_size;
+}
+
+int WireFormat::FieldByteSize(
+    const FieldDescriptor* field,
+    const Message& message) {
+  const Reflection* message_reflection = message.GetReflection();
+
+  if (field->is_extension() &&
+      field->containing_type()->options().message_set_wire_format() &&
+      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+      !field->is_repeated()) {
+    return MessageSetItemByteSize(field, message);
+  }
+
+  int count = 0;
+  if (field->is_repeated()) {
+    count = message_reflection->FieldSize(message, field);
+  } else if (message_reflection->HasField(message, field)) {
+    count = 1;
+  }
+
+  const int data_size = FieldDataOnlyByteSize(field, message);
+  int our_size = data_size;
+  if (field->options().packed()) {
+    if (data_size > 0) {
+      // Packed fields get serialized like a string, not their native type.
+      // Technically this doesn't really matter; the size only changes if it's
+      // a GROUP
+      our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
+      our_size += io::CodedOutputStream::VarintSize32(data_size);
+    }
+  } else {
+    our_size += count * TagSize(field->number(), field->type());
+  }
+  return our_size;
+}
+
+int WireFormat::FieldDataOnlyByteSize(
+    const FieldDescriptor* field,
+    const Message& message) {
+  const Reflection* message_reflection = message.GetReflection();
+
+  int count = 0;
+  if (field->is_repeated()) {
+    count = message_reflection->FieldSize(message, field);
+  } else if (message_reflection->HasField(message, field)) {
+    count = 1;
+  }
+
+  int data_size = 0;
+  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++) {                                  \
+          data_size += WireFormatLite::TYPE_METHOD##Size(                  \
+            message_reflection->GetRepeated##CPPTYPE_METHOD(               \
+              message, field, j));                                         \
+        }                                                                  \
+      } else {                                                             \
+        data_size += WireFormatLite::TYPE_METHOD##Size(                    \
+          message_reflection->Get##CPPTYPE_METHOD(message, field));        \
+      }                                                                    \
+      break;
+
+#define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD)                               \
+    case FieldDescriptor::TYPE_##TYPE:                                     \
+      data_size += count * WireFormatLite::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++) {
+          data_size += WireFormatLite::EnumSize(
+            message_reflection->GetRepeatedEnum(message, field, j)->number());
+        }
+      } else {
+        data_size += WireFormatLite::EnumSize(
+          message_reflection->GetEnum(message, 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(
+            message, field, j, &scratch) :
+          message_reflection->GetStringReference(message, field, &scratch);
+        data_size += WireFormatLite::StringSize(value);
+      }
+      break;
+    }
+  }
+  return data_size;
+}
+
+int WireFormat::MessageSetItemByteSize(
+    const FieldDescriptor* field,
+    const Message& message) {
+  const Reflection* message_reflection = message.GetReflection();
+
+  int our_size = WireFormatLite::kMessageSetItemTagsSize;
+
+  // type_id
+  our_size += io::CodedOutputStream::VarintSize32(field->number());
+
+  // message
+  const Message& sub_message = message_reflection->GetMessage(message, field);
+  int message_size = sub_message.ByteSize();
+
+  our_size += io::CodedOutputStream::VarintSize32(message_size);
+  our_size += message_size;
+
+  return our_size;
+}
+
+void WireFormat::VerifyUTF8StringFallback(const char* data,
+                                          int size,
+                                          Operation op,
+                                          const char* field_name) {
+  if (!IsStructurallyValidUTF8(data, size)) {
+    const char* operation_str = NULL;
+    switch (op) {
+      case PARSE:
+        operation_str = "parsing";
+        break;
+      case SERIALIZE:
+        operation_str = "serializing";
+        break;
+      // no default case: have the compiler warn if a case is not covered.
+    }
+    string quoted_field_name = "";
+    if (field_name != NULL) {
+      quoted_field_name = StringPrintf(" '%s'", field_name);
+    }
+    // no space below to avoid double space when the field name is missing.
+    GOOGLE_LOG(ERROR) << "String field" << quoted_field_name << " contains invalid "
+               << "UTF-8 data when " << operation_str << " a protocol "
+               << "buffer. Use the 'bytes' type if you intend to send raw "
+               << "bytes. ";
+  }
+}
+
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/wire_format.h b/protobuf/src/google/protobuf/wire_format.h
new file mode 100644
index 0000000..9f26eb2
--- /dev/null
+++ b/protobuf/src/google/protobuf/wire_format.h
@@ -0,0 +1,336 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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/stubs/common.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/wire_format_lite.h>
+
+// Do UTF-8 validation on string type in Debug build only
+#ifndef NDEBUG
+#define GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+#endif
+
+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 code for implementing the binary protocol buffer
+// wire format via reflection.  The WireFormatLite class implements the
+// non-reflection based routines.
+//
+// This class is really a namespace that contains only static methods
+class LIBPROTOBUF_EXPORT WireFormat {
+ public:
+
+  // Given a field return its WireType
+  static inline WireFormatLite::WireType WireTypeForField(
+      const FieldDescriptor* field);
+
+  // Given a FieldDescriptor::Type return its WireType
+  static inline WireFormatLite::WireType WireTypeForFieldType(
+      FieldDescriptor::Type type);
+
+  // Compute the byte size of a tag.  For groups, this includes both the start
+  // and end tags.
+  static inline int TagSize(int field_number, FieldDescriptor::Type type);
+
+  // 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 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(io::CodedInputStream* input,
+                                   Message* message);
+
+  // 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 void SerializeWithCachedSizes(
+      const Message& message,
+      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 Message& message);
+
+  // -----------------------------------------------------------------
+  // 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 void SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
+                                     io::CodedOutputStream* output);
+  // Same as above, except writing directly to the provided buffer.
+  // Requires that the buffer have sufficient capacity for
+  // ComputeUnknownFieldsSize(unknown_fields).
+  //
+  // Returns a pointer past the last written byte.
+  static uint8* SerializeUnknownFieldsToArray(
+      const UnknownFieldSet& unknown_fields,
+      uint8* target);
+
+  // Same thing except for messages that have the message_set_wire_format
+  // option.
+  static void SerializeUnknownMessageSetItems(
+      const UnknownFieldSet& unknown_fields,
+      io::CodedOutputStream* output);
+  // Same as above, except writing directly to the provided buffer.
+  // Requires that the buffer have sufficient capacity for
+  // ComputeUnknownMessageSetItemsSize(unknown_fields).
+  //
+  // Returns a pointer past the last written byte.
+  static uint8* SerializeUnknownMessageSetItemsToArray(
+      const UnknownFieldSet& unknown_fields,
+      uint8* target);
+
+  // 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 functions for encoding and decoding tags.  (Inlined below and in
+  // _inl.h)
+  //
+  // This is different from MakeTag(field->number(), field->type()) in the case
+  // of packed repeated fields.
+  static uint32 MakeTag(const FieldDescriptor* field);
+
+  // Parse a single field.  The input should start out positioned immediately
+  // after the tag.
+  static bool ParseAndMergeField(
+      uint32 tag,
+      const FieldDescriptor* field,        // May be NULL for unknown
+      Message* message,
+      io::CodedInputStream* input);
+
+  // Serialize a single field.
+  static void SerializeFieldWithCachedSizes(
+      const FieldDescriptor* field,        // Cannot be NULL
+      const Message& message,
+      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& message);
+
+  // Parse/serialize a MessageSet::Item group.  Used with messages that use
+  // opion message_set_wire_format = true.
+  static bool ParseAndMergeMessageSetItem(
+      io::CodedInputStream* input,
+      Message* message);
+  static void SerializeMessageSetItemWithCachedSizes(
+      const FieldDescriptor* field,
+      const Message& message,
+      io::CodedOutputStream* output);
+  static int MessageSetItemByteSize(
+      const FieldDescriptor* field,
+      const Message& message);
+
+  // Computes the byte size of a field, excluding tags. For packed fields, it
+  // only includes the size of the raw data, and not the size of the total
+  // length, but for other length-delimited types, the size of the length is
+  // included.
+  static int FieldDataOnlyByteSize(
+      const FieldDescriptor* field,        // Cannot be NULL
+      const Message& message);
+
+  enum Operation {
+    PARSE,
+    SERIALIZE,
+  };
+
+  // Verifies that a string field is valid UTF8, logging an error if not.
+  // This function will not be called by newly generated protobuf code
+  // but remains present to support existing code.
+  static void VerifyUTF8String(const char* data, int size, Operation op);
+  // The NamedField variant takes a field name in order to produce an
+  // informative error message if verification fails.
+  static void VerifyUTF8StringNamedField(const char* data,
+                                         int size,
+                                         Operation op,
+                                         const char* field_name);
+
+ private:
+  // Verifies that a string field is valid UTF8, logging an error if not.
+  static void VerifyUTF8StringFallback(
+      const char* data,
+      int size,
+      Operation op,
+      const char* field_name);
+
+  // Skip a MessageSet field.
+  static bool SkipMessageSetField(io::CodedInputStream* input,
+                                  uint32 field_number,
+                                  UnknownFieldSet* unknown_fields);
+
+  // Parse a MessageSet field.
+  static bool ParseAndMergeMessageSetField(uint32 field_number,
+                                           const FieldDescriptor* field,
+                                           Message* message,
+                                           io::CodedInputStream* input);
+
+
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat);
+};
+
+// Subclass of FieldSkipper which saves skipped fields to an UnknownFieldSet.
+class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper {
+ public:
+  UnknownFieldSetFieldSkipper(UnknownFieldSet* unknown_fields)
+      : unknown_fields_(unknown_fields) {}
+  virtual ~UnknownFieldSetFieldSkipper() {}
+
+  // implements FieldSkipper -----------------------------------------
+  virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
+  virtual bool SkipMessage(io::CodedInputStream* input);
+  virtual void SkipUnknownEnum(int field_number, int value);
+
+ protected:
+  UnknownFieldSet* unknown_fields_;
+};
+
+// inline methods ====================================================
+
+inline WireFormatLite::WireType WireFormat::WireTypeForField(
+    const FieldDescriptor* field) {
+  if (field->options().packed()) {
+    return WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+  } else {
+    return WireTypeForFieldType(field->type());
+  }
+}
+
+inline WireFormatLite::WireType WireFormat::WireTypeForFieldType(
+    FieldDescriptor::Type type) {
+  // Some compilers don't like enum -> enum casts, so we implicit_cast to
+  // int first.
+  return WireFormatLite::WireTypeForFieldType(
+      static_cast<WireFormatLite::FieldType>(
+        implicit_cast<int>(type)));
+}
+
+inline uint32 WireFormat::MakeTag(const FieldDescriptor* field) {
+  return WireFormatLite::MakeTag(field->number(), WireTypeForField(field));
+}
+
+inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) {
+  // Some compilers don't like enum -> enum casts, so we implicit_cast to
+  // int first.
+  return WireFormatLite::TagSize(field_number,
+      static_cast<WireFormatLite::FieldType>(
+        implicit_cast<int>(type)));
+}
+
+inline void WireFormat::VerifyUTF8String(const char* data, int size,
+    WireFormat::Operation op) {
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+  WireFormat::VerifyUTF8StringFallback(data, size, op, NULL);
+#else
+  // Avoid the compiler warning about unsued variables.
+  (void)data; (void)size; (void)op;
+#endif
+}
+
+inline void WireFormat::VerifyUTF8StringNamedField(
+    const char* data, int size, WireFormat::Operation op,
+    const char* field_name) {
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+  WireFormat::VerifyUTF8StringFallback(data, size, op, field_name);
+#endif
+}
+
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_H__
diff --git a/protobuf/src/google/protobuf/wire_format_lite.cc b/protobuf/src/google/protobuf/wire_format_lite.cc
new file mode 100644
index 0000000..8de8278
--- /dev/null
+++ b/protobuf/src/google/protobuf/wire_format_lite.cc
@@ -0,0 +1,471 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <google/protobuf/wire_format_lite_inl.h>
+
+#include <stack>
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/io/coded_stream_inl.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+#ifndef _MSC_VER    // MSVC doesn't like definitions of inline constants, GCC
+                    // requires them.
+const int WireFormatLite::kMessageSetItemStartTag;
+const int WireFormatLite::kMessageSetItemEndTag;
+const int WireFormatLite::kMessageSetTypeIdTag;
+const int WireFormatLite::kMessageSetMessageTag;
+
+#endif
+
+const int WireFormatLite::kMessageSetItemTagsSize =
+  io::CodedOutputStream::StaticVarintSize32<kMessageSetItemStartTag>::value +
+  io::CodedOutputStream::StaticVarintSize32<kMessageSetItemEndTag>::value +
+  io::CodedOutputStream::StaticVarintSize32<kMessageSetTypeIdTag>::value +
+  io::CodedOutputStream::StaticVarintSize32<kMessageSetMessageTag>::value;
+
+const WireFormatLite::CppType
+WireFormatLite::kFieldTypeToCppTypeMap[MAX_FIELD_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 WireFormatLite::WireType
+WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = {
+  static_cast<WireFormatLite::WireType>(-1),  // invalid
+  WireFormatLite::WIRETYPE_FIXED64,           // TYPE_DOUBLE
+  WireFormatLite::WIRETYPE_FIXED32,           // TYPE_FLOAT
+  WireFormatLite::WIRETYPE_VARINT,            // TYPE_INT64
+  WireFormatLite::WIRETYPE_VARINT,            // TYPE_UINT64
+  WireFormatLite::WIRETYPE_VARINT,            // TYPE_INT32
+  WireFormatLite::WIRETYPE_FIXED64,           // TYPE_FIXED64
+  WireFormatLite::WIRETYPE_FIXED32,           // TYPE_FIXED32
+  WireFormatLite::WIRETYPE_VARINT,            // TYPE_BOOL
+  WireFormatLite::WIRETYPE_LENGTH_DELIMITED,  // TYPE_STRING
+  WireFormatLite::WIRETYPE_START_GROUP,       // TYPE_GROUP
+  WireFormatLite::WIRETYPE_LENGTH_DELIMITED,  // TYPE_MESSAGE
+  WireFormatLite::WIRETYPE_LENGTH_DELIMITED,  // TYPE_BYTES
+  WireFormatLite::WIRETYPE_VARINT,            // TYPE_UINT32
+  WireFormatLite::WIRETYPE_VARINT,            // TYPE_ENUM
+  WireFormatLite::WIRETYPE_FIXED32,           // TYPE_SFIXED32
+  WireFormatLite::WIRETYPE_FIXED64,           // TYPE_SFIXED64
+  WireFormatLite::WIRETYPE_VARINT,            // TYPE_SINT32
+  WireFormatLite::WIRETYPE_VARINT,            // TYPE_SINT64
+};
+
+bool WireFormatLite::SkipField(
+    io::CodedInputStream* input, uint32 tag) {
+  switch (WireFormatLite::GetTagWireType(tag)) {
+    case WireFormatLite::WIRETYPE_VARINT: {
+      uint64 value;
+      if (!input->ReadVarint64(&value)) return false;
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_FIXED64: {
+      uint64 value;
+      if (!input->ReadLittleEndian64(&value)) return false;
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+      uint32 length;
+      if (!input->ReadVarint32(&length)) return false;
+      if (!input->Skip(length)) return false;
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_START_GROUP: {
+      if (!input->IncrementRecursionDepth()) return false;
+      if (!SkipMessage(input)) return false;
+      input->DecrementRecursionDepth();
+      // Check that the ending tag matched the starting tag.
+      if (!input->LastTagWas(WireFormatLite::MakeTag(
+          WireFormatLite::GetTagFieldNumber(tag),
+          WireFormatLite::WIRETYPE_END_GROUP))) {
+        return false;
+      }
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_END_GROUP: {
+      return false;
+    }
+    case WireFormatLite::WIRETYPE_FIXED32: {
+      uint32 value;
+      if (!input->ReadLittleEndian32(&value)) return false;
+      return true;
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+bool WireFormatLite::SkipField(
+    io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) {
+  switch (WireFormatLite::GetTagWireType(tag)) {
+    case WireFormatLite::WIRETYPE_VARINT: {
+      uint64 value;
+      if (!input->ReadVarint64(&value)) return false;
+      output->WriteVarint32(tag);
+      output->WriteVarint64(value);
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_FIXED64: {
+      uint64 value;
+      if (!input->ReadLittleEndian64(&value)) return false;
+      output->WriteVarint32(tag);
+      output->WriteLittleEndian64(value);
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
+      uint32 length;
+      if (!input->ReadVarint32(&length)) return false;
+      output->WriteVarint32(tag);
+      output->WriteVarint32(length);
+      // TODO(mkilavuz): Provide API to prevent extra string copying.
+      string temp;
+      if (!input->ReadString(&temp, length)) return false;
+      output->WriteString(temp);
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_START_GROUP: {
+      output->WriteVarint32(tag);
+      if (!input->IncrementRecursionDepth()) return false;
+      if (!SkipMessage(input, output)) return false;
+      input->DecrementRecursionDepth();
+      // Check that the ending tag matched the starting tag.
+      if (!input->LastTagWas(WireFormatLite::MakeTag(
+          WireFormatLite::GetTagFieldNumber(tag),
+          WireFormatLite::WIRETYPE_END_GROUP))) {
+        return false;
+      }
+      return true;
+    }
+    case WireFormatLite::WIRETYPE_END_GROUP: {
+      return false;
+    }
+    case WireFormatLite::WIRETYPE_FIXED32: {
+      uint32 value;
+      if (!input->ReadLittleEndian32(&value)) return false;
+      output->WriteVarint32(tag);
+      output->WriteLittleEndian32(value);
+      return true;
+    }
+    default: {
+      return false;
+    }
+  }
+}
+
+bool WireFormatLite::SkipMessage(io::CodedInputStream* input) {
+  while (true) {
+    uint32 tag = input->ReadTag();
+    if (tag == 0) {
+      // End of input.  This is a valid place to end, so return true.
+      return true;
+    }
+
+    WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
+
+    if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
+      // Must be the end of the message.
+      return true;
+    }
+
+    if (!SkipField(input, tag)) return false;
+  }
+}
+
+bool WireFormatLite::SkipMessage(io::CodedInputStream* input,
+    io::CodedOutputStream* output) {
+  while (true) {
+    uint32 tag = input->ReadTag();
+    if (tag == 0) {
+      // End of input.  This is a valid place to end, so return true.
+      return true;
+    }
+
+    WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
+
+    if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
+      output->WriteVarint32(tag);
+      // Must be the end of the message.
+      return true;
+    }
+
+    if (!SkipField(input, tag, output)) return false;
+  }
+}
+
+bool FieldSkipper::SkipField(
+    io::CodedInputStream* input, uint32 tag) {
+  return WireFormatLite::SkipField(input, tag);
+}
+
+bool FieldSkipper::SkipMessage(io::CodedInputStream* input) {
+  return WireFormatLite::SkipMessage(input);
+}
+
+void FieldSkipper::SkipUnknownEnum(
+    int /* field_number */, int /* value */) {
+  // Nothing.
+}
+
+bool CodedOutputStreamFieldSkipper::SkipField(
+    io::CodedInputStream* input, uint32 tag) {
+  return WireFormatLite::SkipField(input, tag, unknown_fields_);
+}
+
+bool CodedOutputStreamFieldSkipper::SkipMessage(io::CodedInputStream* input) {
+  return WireFormatLite::SkipMessage(input, unknown_fields_);
+}
+
+void CodedOutputStreamFieldSkipper::SkipUnknownEnum(
+    int field_number, int value) {
+  unknown_fields_->WriteVarint32(field_number);
+  unknown_fields_->WriteVarint64(value);
+}
+
+bool WireFormatLite::ReadPackedEnumNoInline(io::CodedInputStream* input,
+                                            bool (*is_valid)(int),
+                                            RepeatedField<int>* values) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  io::CodedInputStream::Limit limit = input->PushLimit(length);
+  while (input->BytesUntilLimit() > 0) {
+    int value;
+    if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
+        int, WireFormatLite::TYPE_ENUM>(input, &value)) {
+      return false;
+    }
+    if (is_valid(value)) {
+      values->Add(value);
+    }
+  }
+  input->PopLimit(limit);
+  return true;
+}
+
+void WireFormatLite::WriteInt32(int field_number, int32 value,
+                                io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_VARINT, output);
+  WriteInt32NoTag(value, output);
+}
+void WireFormatLite::WriteInt64(int field_number, int64 value,
+                                io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_VARINT, output);
+  WriteInt64NoTag(value, output);
+}
+void WireFormatLite::WriteUInt32(int field_number, uint32 value,
+                                 io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_VARINT, output);
+  WriteUInt32NoTag(value, output);
+}
+void WireFormatLite::WriteUInt64(int field_number, uint64 value,
+                                 io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_VARINT, output);
+  WriteUInt64NoTag(value, output);
+}
+void WireFormatLite::WriteSInt32(int field_number, int32 value,
+                                 io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_VARINT, output);
+  WriteSInt32NoTag(value, output);
+}
+void WireFormatLite::WriteSInt64(int field_number, int64 value,
+                                 io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_VARINT, output);
+  WriteSInt64NoTag(value, output);
+}
+void WireFormatLite::WriteFixed32(int field_number, uint32 value,
+                                  io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_FIXED32, output);
+  WriteFixed32NoTag(value, output);
+}
+void WireFormatLite::WriteFixed64(int field_number, uint64 value,
+                                  io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_FIXED64, output);
+  WriteFixed64NoTag(value, output);
+}
+void WireFormatLite::WriteSFixed32(int field_number, int32 value,
+                                   io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_FIXED32, output);
+  WriteSFixed32NoTag(value, output);
+}
+void WireFormatLite::WriteSFixed64(int field_number, int64 value,
+                                   io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_FIXED64, output);
+  WriteSFixed64NoTag(value, output);
+}
+void WireFormatLite::WriteFloat(int field_number, float value,
+                                io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_FIXED32, output);
+  WriteFloatNoTag(value, output);
+}
+void WireFormatLite::WriteDouble(int field_number, double value,
+                                 io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_FIXED64, output);
+  WriteDoubleNoTag(value, output);
+}
+void WireFormatLite::WriteBool(int field_number, bool value,
+                               io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_VARINT, output);
+  WriteBoolNoTag(value, output);
+}
+void WireFormatLite::WriteEnum(int field_number, int value,
+                               io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_VARINT, output);
+  WriteEnumNoTag(value, output);
+}
+
+void WireFormatLite::WriteString(int field_number, const string& value,
+                                 io::CodedOutputStream* output) {
+  // String is for UTF-8 text only
+  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+  GOOGLE_CHECK(value.size() <= kint32max);
+  output->WriteVarint32(value.size());
+  output->WriteString(value);
+}
+void WireFormatLite::WriteStringMaybeAliased(
+    int field_number, const string& value,
+    io::CodedOutputStream* output) {
+  // String is for UTF-8 text only
+  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+  GOOGLE_CHECK(value.size() <= kint32max);
+  output->WriteVarint32(value.size());
+  output->WriteRawMaybeAliased(value.data(), value.size());
+}
+void WireFormatLite::WriteBytes(int field_number, const string& value,
+                                io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+  GOOGLE_CHECK(value.size() <= kint32max);
+  output->WriteVarint32(value.size());
+  output->WriteString(value);
+}
+void WireFormatLite::WriteBytesMaybeAliased(
+    int field_number, const string& value,
+    io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+  GOOGLE_CHECK(value.size() <= kint32max);
+  output->WriteVarint32(value.size());
+  output->WriteRawMaybeAliased(value.data(), value.size());
+}
+
+
+void WireFormatLite::WriteGroup(int field_number,
+                                const MessageLite& value,
+                                io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_START_GROUP, output);
+  value.SerializeWithCachedSizes(output);
+  WriteTag(field_number, WIRETYPE_END_GROUP, output);
+}
+
+void WireFormatLite::WriteMessage(int field_number,
+                                  const MessageLite& value,
+                                  io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+  const int size = value.GetCachedSize();
+  output->WriteVarint32(size);
+  value.SerializeWithCachedSizes(output);
+}
+
+void WireFormatLite::WriteGroupMaybeToArray(int field_number,
+                                            const MessageLite& value,
+                                            io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_START_GROUP, output);
+  const int size = value.GetCachedSize();
+  uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
+  if (target != NULL) {
+    uint8* end = value.SerializeWithCachedSizesToArray(target);
+    GOOGLE_DCHECK_EQ(end - target, size);
+  } else {
+    value.SerializeWithCachedSizes(output);
+  }
+  WriteTag(field_number, WIRETYPE_END_GROUP, output);
+}
+
+void WireFormatLite::WriteMessageMaybeToArray(int field_number,
+                                              const MessageLite& value,
+                                              io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+  const int size = value.GetCachedSize();
+  output->WriteVarint32(size);
+  uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
+  if (target != NULL) {
+    uint8* end = value.SerializeWithCachedSizesToArray(target);
+    GOOGLE_DCHECK_EQ(end - target, size);
+  } else {
+    value.SerializeWithCachedSizes(output);
+  }
+}
+
+bool WireFormatLite::ReadString(io::CodedInputStream* input,
+                                string* value) {
+  // String is for UTF-8 text only
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  if (!input->InternalReadStringInline(value, length)) return false;
+  return true;
+}
+bool WireFormatLite::ReadBytes(io::CodedInputStream* input,
+                               string* value) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  return input->InternalReadStringInline(value, length);
+}
+
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/google/protobuf/wire_format_lite.h b/protobuf/src/google/protobuf/wire_format_lite.h
new file mode 100644
index 0000000..21aa488
--- /dev/null
+++ b/protobuf/src/google/protobuf/wire_format_lite.h
@@ -0,0 +1,661 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//         atenasio@google.com (Chris Atenasio) (ZigZag transform)
+//         wink@google.com (Wink Saville) (refactored from wire_format.h)
+//  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_LITE_H__
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/io/coded_stream.h>  // for CodedOutputStream::Varint32Size
+
+namespace google {
+
+namespace protobuf {
+  template <typename T> class RepeatedField;  // repeated_field.h
+}
+
+namespace protobuf {
+namespace internal {
+
+class StringPieceField;
+
+// 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 without the need for reflection. Use WireFormat when using
+// reflection.
+//
+// This class is really a namespace that contains only static methods.
+class LIBPROTOBUF_EXPORT WireFormatLite {
+ public:
+
+  // -----------------------------------------------------------------
+  // 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,
+  };
+
+  // Lite alternative to FieldDescriptor::Type.  Must be kept in sync.
+  enum FieldType {
+    TYPE_DOUBLE         = 1,
+    TYPE_FLOAT          = 2,
+    TYPE_INT64          = 3,
+    TYPE_UINT64         = 4,
+    TYPE_INT32          = 5,
+    TYPE_FIXED64        = 6,
+    TYPE_FIXED32        = 7,
+    TYPE_BOOL           = 8,
+    TYPE_STRING         = 9,
+    TYPE_GROUP          = 10,
+    TYPE_MESSAGE        = 11,
+    TYPE_BYTES          = 12,
+    TYPE_UINT32         = 13,
+    TYPE_ENUM           = 14,
+    TYPE_SFIXED32       = 15,
+    TYPE_SFIXED64       = 16,
+    TYPE_SINT32         = 17,
+    TYPE_SINT64         = 18,
+    MAX_FIELD_TYPE      = 18,
+  };
+
+  // Lite alternative to FieldDescriptor::CppType.  Must be kept in sync.
+  enum CppType {
+    CPPTYPE_INT32       = 1,
+    CPPTYPE_INT64       = 2,
+    CPPTYPE_UINT32      = 3,
+    CPPTYPE_UINT64      = 4,
+    CPPTYPE_DOUBLE      = 5,
+    CPPTYPE_FLOAT       = 6,
+    CPPTYPE_BOOL        = 7,
+    CPPTYPE_ENUM        = 8,
+    CPPTYPE_STRING      = 9,
+    CPPTYPE_MESSAGE     = 10,
+    MAX_CPPTYPE         = 10,
+  };
+
+  // Helper method to get the CppType for a particular Type.
+  static CppType FieldTypeToCppType(FieldType type);
+
+  // Given a FieldSescriptor::Type return its WireType
+  static inline WireFormatLite::WireType WireTypeForFieldType(
+      WireFormatLite::FieldType 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 and in
+  // _inl.h)
+  //
+  // This is different from MakeTag(field->number(), field->type()) in the case
+  // of packed repeated fields.
+  static uint32 MakeTag(int field_number, WireType type);
+  static WireType GetTagWireType(uint32 tag);
+  static int GetTagFieldNumber(uint32 tag);
+
+  // Compute the byte size of a tag.  For groups, this includes both the start
+  // and end tags.
+  static inline int TagSize(int field_number, WireFormatLite::FieldType type);
+
+  // Skips a field value with the given tag.  The input should start
+  // positioned immediately after the tag.  Skipped values are simply discarded,
+  // not recorded anywhere.  See WireFormat::SkipField() for a version that
+  // records to an UnknownFieldSet.
+  static bool SkipField(io::CodedInputStream* input, uint32 tag);
+
+  // Skips a field value with the given tag.  The input should start
+  // positioned immediately after the tag. Skipped values are recorded to a
+  // CodedOutputStream.
+  static bool SkipField(io::CodedInputStream* input, uint32 tag,
+                        io::CodedOutputStream* output);
+
+  // Reads and ignores a message from the input.  Skipped values are simply
+  // discarded, not recorded anywhere.  See WireFormat::SkipMessage() for a
+  // version that records to an UnknownFieldSet.
+  static bool SkipMessage(io::CodedInputStream* input);
+
+  // Reads and ignores a message from the input.  Skipped values are recorded
+  // to a CodedOutputStream.
+  static bool SkipMessage(io::CodedInputStream* input,
+                          io::CodedOutputStream* output);
+
+// This macro does the same thing as WireFormatLite::MakeTag(), but the
+// result is usable as a compile-time constant, which makes it usable
+// as a switch case or a template input.  WireFormatLite::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::WireFormatLite::kTagTypeBits) \
+      | (TYPE))
+
+  // 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;
+  //     }
+  //   }
+  static const int kMessageSetItemNumber = 1;
+  static const int kMessageSetTypeIdNumber = 2;
+  static const int kMessageSetMessageNumber = 3;
+  static const int kMessageSetItemStartTag =
+    GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber,
+                                WireFormatLite::WIRETYPE_START_GROUP);
+  static const int kMessageSetItemEndTag =
+    GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetItemNumber,
+                                WireFormatLite::WIRETYPE_END_GROUP);
+  static const int kMessageSetTypeIdTag =
+    GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetTypeIdNumber,
+                                WireFormatLite::WIRETYPE_VARINT);
+  static const int kMessageSetMessageTag =
+    GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(kMessageSetMessageNumber,
+                                WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
+
+  // Byte size of all tags of a MessageSet::Item combined.
+  static const int kMessageSetItemTagsSize;
+
+  // 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);
+
+  // =================================================================
+  // Methods for reading/writing individual field.  The implementations
+  // of these methods are defined in wire_format_lite_inl.h; you must #include
+  // that file to use these.
+
+// Avoid ugly line wrapping
+#define input  io::CodedInputStream*  input_arg
+#define output io::CodedOutputStream* output_arg
+#define field_number int field_number_arg
+#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.
+
+  // For primitive fields, we just use a templatized routine parameterized by
+  // the represented type and the FieldType. These are specialized with the
+  // appropriate definition for each declared type.
+  template <typename CType, enum FieldType DeclaredType>
+  static inline bool ReadPrimitive(input, CType* value) INL;
+
+  // Reads repeated primitive values, with optimizations for repeats.
+  // tag_size and tag should both be compile-time constants provided by the
+  // protocol compiler.
+  template <typename CType, enum FieldType DeclaredType>
+  static inline bool ReadRepeatedPrimitive(int tag_size,
+                                           uint32 tag,
+                                           input,
+                                           RepeatedField<CType>* value) INL;
+
+  // Identical to ReadRepeatedPrimitive, except will not inline the
+  // implementation.
+  template <typename CType, enum FieldType DeclaredType>
+  static bool ReadRepeatedPrimitiveNoInline(int tag_size,
+                                            uint32 tag,
+                                            input,
+                                            RepeatedField<CType>* value);
+
+  // Reads a primitive value directly from the provided buffer. It returns a
+  // pointer past the segment of data that was read.
+  //
+  // This is only implemented for the types with fixed wire size, e.g.
+  // float, double, and the (s)fixed* types.
+  template <typename CType, enum FieldType DeclaredType>
+  static inline const uint8* ReadPrimitiveFromArray(const uint8* buffer,
+                                                    CType* value) INL;
+
+  // Reads a primitive packed field.
+  //
+  // This is only implemented for packable types.
+  template <typename CType, enum FieldType DeclaredType>
+  static inline bool ReadPackedPrimitive(input,
+                                         RepeatedField<CType>* value) INL;
+
+  // Identical to ReadPackedPrimitive, except will not inline the
+  // implementation.
+  template <typename CType, enum FieldType DeclaredType>
+  static bool ReadPackedPrimitiveNoInline(input, RepeatedField<CType>* value);
+
+  // Read a packed enum field. Values for which is_valid() returns false are
+  // dropped.
+  static bool ReadPackedEnumNoInline(input,
+                                     bool (*is_valid)(int),
+                                     RepeatedField<int>* value);
+
+  static bool ReadString(input, string* value);
+  static bool ReadBytes (input, string* value);
+
+  static inline bool ReadGroup  (field_number, input, MessageLite* value);
+  static inline bool ReadMessage(input, MessageLite* 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 typically include the tag, so
+  // normally there's no need to call this unless using the Write*NoTag()
+  // variants.
+  static inline void WriteTag(field_number, WireType type, output) INL;
+
+  // Write fields, without tags.
+  static inline void WriteInt32NoTag   (int32 value, output) INL;
+  static inline void WriteInt64NoTag   (int64 value, output) INL;
+  static inline void WriteUInt32NoTag  (uint32 value, output) INL;
+  static inline void WriteUInt64NoTag  (uint64 value, output) INL;
+  static inline void WriteSInt32NoTag  (int32 value, output) INL;
+  static inline void WriteSInt64NoTag  (int64 value, output) INL;
+  static inline void WriteFixed32NoTag (uint32 value, output) INL;
+  static inline void WriteFixed64NoTag (uint64 value, output) INL;
+  static inline void WriteSFixed32NoTag(int32 value, output) INL;
+  static inline void WriteSFixed64NoTag(int64 value, output) INL;
+  static inline void WriteFloatNoTag   (float value, output) INL;
+  static inline void WriteDoubleNoTag  (double value, output) INL;
+  static inline void WriteBoolNoTag    (bool value, output) INL;
+  static inline void WriteEnumNoTag    (int value, output) INL;
+
+  // Write fields, including tags.
+  static void WriteInt32   (field_number,  int32 value, output);
+  static void WriteInt64   (field_number,  int64 value, output);
+  static void WriteUInt32  (field_number, uint32 value, output);
+  static void WriteUInt64  (field_number, uint64 value, output);
+  static void WriteSInt32  (field_number,  int32 value, output);
+  static void WriteSInt64  (field_number,  int64 value, output);
+  static void WriteFixed32 (field_number, uint32 value, output);
+  static void WriteFixed64 (field_number, uint64 value, output);
+  static void WriteSFixed32(field_number,  int32 value, output);
+  static void WriteSFixed64(field_number,  int64 value, output);
+  static void WriteFloat   (field_number,  float value, output);
+  static void WriteDouble  (field_number, double value, output);
+  static void WriteBool    (field_number,   bool value, output);
+  static void WriteEnum    (field_number,    int value, output);
+
+  static void WriteString(field_number, const string& value, output);
+  static void WriteBytes (field_number, const string& value, output);
+  static void WriteStringMaybeAliased(
+      field_number, const string& value, output);
+  static void WriteBytesMaybeAliased(
+      field_number, const string& value, output);
+
+  static void WriteGroup(
+    field_number, const MessageLite& value, output);
+  static void WriteMessage(
+    field_number, const MessageLite& value, output);
+  // Like above, but these will check if the output stream has enough
+  // space to write directly to a flat array.
+  static void WriteGroupMaybeToArray(
+    field_number, const MessageLite& value, output);
+  static void WriteMessageMaybeToArray(
+    field_number, const MessageLite& value, output);
+
+  // 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 void WriteGroupNoVirtual(
+    field_number, const MessageType& value, output);
+  template<typename MessageType>
+  static inline void WriteMessageNoVirtual(
+    field_number, const MessageType& value, output);
+
+#undef output
+#define output uint8* target
+
+  // Like above, but use only *ToArray methods of CodedOutputStream.
+  static inline uint8* WriteTagToArray(field_number, WireType type, output) INL;
+
+  // Write fields, without tags.
+  static inline uint8* WriteInt32NoTagToArray   (int32 value, output) INL;
+  static inline uint8* WriteInt64NoTagToArray   (int64 value, output) INL;
+  static inline uint8* WriteUInt32NoTagToArray  (uint32 value, output) INL;
+  static inline uint8* WriteUInt64NoTagToArray  (uint64 value, output) INL;
+  static inline uint8* WriteSInt32NoTagToArray  (int32 value, output) INL;
+  static inline uint8* WriteSInt64NoTagToArray  (int64 value, output) INL;
+  static inline uint8* WriteFixed32NoTagToArray (uint32 value, output) INL;
+  static inline uint8* WriteFixed64NoTagToArray (uint64 value, output) INL;
+  static inline uint8* WriteSFixed32NoTagToArray(int32 value, output) INL;
+  static inline uint8* WriteSFixed64NoTagToArray(int64 value, output) INL;
+  static inline uint8* WriteFloatNoTagToArray   (float value, output) INL;
+  static inline uint8* WriteDoubleNoTagToArray  (double value, output) INL;
+  static inline uint8* WriteBoolNoTagToArray    (bool value, output) INL;
+  static inline uint8* WriteEnumNoTagToArray    (int value, output) INL;
+
+  // Write fields, including tags.
+  static inline uint8* WriteInt32ToArray(
+    field_number, int32 value, output) INL;
+  static inline uint8* WriteInt64ToArray(
+    field_number, int64 value, output) INL;
+  static inline uint8* WriteUInt32ToArray(
+    field_number, uint32 value, output) INL;
+  static inline uint8* WriteUInt64ToArray(
+    field_number, uint64 value, output) INL;
+  static inline uint8* WriteSInt32ToArray(
+    field_number, int32 value, output) INL;
+  static inline uint8* WriteSInt64ToArray(
+    field_number, int64 value, output) INL;
+  static inline uint8* WriteFixed32ToArray(
+    field_number, uint32 value, output) INL;
+  static inline uint8* WriteFixed64ToArray(
+    field_number, uint64 value, output) INL;
+  static inline uint8* WriteSFixed32ToArray(
+    field_number, int32 value, output) INL;
+  static inline uint8* WriteSFixed64ToArray(
+    field_number, int64 value, output) INL;
+  static inline uint8* WriteFloatToArray(
+    field_number, float value, output) INL;
+  static inline uint8* WriteDoubleToArray(
+    field_number, double value, output) INL;
+  static inline uint8* WriteBoolToArray(
+    field_number, bool value, output) INL;
+  static inline uint8* WriteEnumToArray(
+    field_number, int value, output) INL;
+
+  static inline uint8* WriteStringToArray(
+    field_number, const string& value, output) INL;
+  static inline uint8* WriteBytesToArray(
+    field_number, const string& value, output) INL;
+
+  static inline uint8* WriteGroupToArray(
+      field_number, const MessageLite& value, output) INL;
+  static inline uint8* WriteMessageToArray(
+      field_number, const MessageLite& 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 uint8* WriteGroupNoVirtualToArray(
+    field_number, const MessageType& value, output) INL;
+  template<typename MessageType>
+  static inline uint8* WriteMessageNoVirtualToArray(
+    field_number, const MessageType& value, output) INL;
+
+#undef output
+#undef input
+#undef INL
+
+#undef field_number
+
+  // 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 MessageLite& value);
+  static inline int MessageSize(const MessageLite& 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);
+
+  // Given the length of data, calculate the byte size of the data on the
+  // wire if we encode the data as a length delimited field.
+  static inline int LengthDelimitedSize(int length);
+
+ private:
+  // A helper method for the repeated primitive reader. This method has
+  // optimizations for primitive types that have fixed size on the wire, and
+  // can be read using potentially faster paths.
+  template <typename CType, enum FieldType DeclaredType>
+  static inline bool ReadRepeatedFixedSizePrimitive(
+      int tag_size,
+      uint32 tag,
+      google::protobuf::io::CodedInputStream* input,
+      RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+  // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields.
+  template <typename CType, enum FieldType DeclaredType>
+  static inline bool ReadPackedFixedSizePrimitive(
+      google::protobuf::io::CodedInputStream* input,
+      RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+
+  static const CppType kFieldTypeToCppTypeMap[];
+  static const WireFormatLite::WireType kWireTypeForFieldType[];
+
+  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormatLite);
+};
+
+// A class which deals with unknown values.  The default implementation just
+// discards them.  WireFormat defines a subclass which writes to an
+// UnknownFieldSet.  This class is used by ExtensionSet::ParseField(), since
+// ExtensionSet is part of the lite library but UnknownFieldSet is not.
+class LIBPROTOBUF_EXPORT FieldSkipper {
+ public:
+  FieldSkipper() {}
+  virtual ~FieldSkipper() {}
+
+  // Skip a field whose tag has already been consumed.
+  virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
+
+  // Skip an entire message or group, up to an end-group tag (which is consumed)
+  // or end-of-stream.
+  virtual bool SkipMessage(io::CodedInputStream* input);
+
+  // Deal with an already-parsed unrecognized enum value.  The default
+  // implementation does nothing, but the UnknownFieldSet-based implementation
+  // saves it as an unknown varint.
+  virtual void SkipUnknownEnum(int field_number, int value);
+};
+
+// Subclass of FieldSkipper which saves skipped fields to a CodedOutputStream.
+
+class LIBPROTOBUF_EXPORT CodedOutputStreamFieldSkipper : public FieldSkipper {
+ public:
+  explicit CodedOutputStreamFieldSkipper(io::CodedOutputStream* unknown_fields)
+      : unknown_fields_(unknown_fields) {}
+  virtual ~CodedOutputStreamFieldSkipper() {}
+
+  // implements FieldSkipper -----------------------------------------
+  virtual bool SkipField(io::CodedInputStream* input, uint32 tag);
+  virtual bool SkipMessage(io::CodedInputStream* input);
+  virtual void SkipUnknownEnum(int field_number, int value);
+
+ protected:
+  io::CodedOutputStream* unknown_fields_;
+};
+
+
+// inline methods ====================================================
+
+inline WireFormatLite::CppType
+WireFormatLite::FieldTypeToCppType(FieldType type) {
+  return kFieldTypeToCppTypeMap[type];
+}
+
+inline uint32 WireFormatLite::MakeTag(int field_number, WireType type) {
+  return GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(field_number, type);
+}
+
+inline WireFormatLite::WireType WireFormatLite::GetTagWireType(uint32 tag) {
+  return static_cast<WireType>(tag & kTagTypeMask);
+}
+
+inline int WireFormatLite::GetTagFieldNumber(uint32 tag) {
+  return static_cast<int>(tag >> kTagTypeBits);
+}
+
+inline int WireFormatLite::TagSize(int field_number,
+                                   WireFormatLite::FieldType type) {
+  int result = io::CodedOutputStream::VarintSize32(
+    field_number << kTagTypeBits);
+  if (type == TYPE_GROUP) {
+    // Groups have both a start and an end tag.
+    return result * 2;
+  } else {
+    return result;
+  }
+}
+
+inline uint32 WireFormatLite::EncodeFloat(float value) {
+  union {float f; uint32 i;};
+  f = value;
+  return i;
+}
+
+inline float WireFormatLite::DecodeFloat(uint32 value) {
+  union {float f; uint32 i;};
+  i = value;
+  return f;
+}
+
+inline uint64 WireFormatLite::EncodeDouble(double value) {
+  union {double f; uint64 i;};
+  f = value;
+  return i;
+}
+
+inline double WireFormatLite::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 WireFormatLite::ZigZagEncode32(int32 n) {
+  // Note:  the right-shift must be arithmetic
+  return (n << 1) ^ (n >> 31);
+}
+
+inline int32 WireFormatLite::ZigZagDecode32(uint32 n) {
+  return (n >> 1) ^ -static_cast<int32>(n & 1);
+}
+
+inline uint64 WireFormatLite::ZigZagEncode64(int64 n) {
+  // Note:  the right-shift must be arithmetic
+  return (n << 1) ^ (n >> 63);
+}
+
+inline int64 WireFormatLite::ZigZagDecode64(uint64 n) {
+  return (n >> 1) ^ -static_cast<int64>(n & 1);
+}
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_H__
diff --git a/protobuf/src/google/protobuf/wire_format_lite_inl.h b/protobuf/src/google/protobuf/wire_format_lite_inl.h
new file mode 100644
index 0000000..feb2254
--- /dev/null
+++ b/protobuf/src/google/protobuf/wire_format_lite_inl.h
@@ -0,0 +1,860 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//         wink@google.com (Wink Saville) (refactored from wire_format.h)
+//  Based on original Protocol Buffers design by
+//  Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
+#define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
+
+#ifdef _MSC_VER
+// This is required for min/max on VS2013 only.
+#include <algorithm>
+#endif
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/message_lite.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/wire_format_lite.h>
+#include <google/protobuf/io/coded_stream.h>
+
+
+namespace google {
+namespace protobuf {
+namespace internal {
+
+// Implementation details of ReadPrimitive.
+
+template <>
+inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(
+    io::CodedInputStream* input,
+    int32* value) {
+  uint32 temp;
+  if (!input->ReadVarint32(&temp)) return false;
+  *value = static_cast<int32>(temp);
+  return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_INT64>(
+    io::CodedInputStream* input,
+    int64* value) {
+  uint64 temp;
+  if (!input->ReadVarint64(&temp)) return false;
+  *value = static_cast<int64>(temp);
+  return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(
+    io::CodedInputStream* input,
+    uint32* value) {
+  return input->ReadVarint32(value);
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_UINT64>(
+    io::CodedInputStream* input,
+    uint64* value) {
+  return input->ReadVarint64(value);
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(
+    io::CodedInputStream* input,
+    int32* value) {
+  uint32 temp;
+  if (!input->ReadVarint32(&temp)) return false;
+  *value = ZigZagDecode32(temp);
+  return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(
+    io::CodedInputStream* input,
+    int64* value) {
+  uint64 temp;
+  if (!input->ReadVarint64(&temp)) return false;
+  *value = ZigZagDecode64(temp);
+  return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_FIXED32>(
+    io::CodedInputStream* input,
+    uint32* value) {
+  return input->ReadLittleEndian32(value);
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<uint64, WireFormatLite::TYPE_FIXED64>(
+    io::CodedInputStream* input,
+    uint64* value) {
+  return input->ReadLittleEndian64(value);
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SFIXED32>(
+    io::CodedInputStream* input,
+    int32* value) {
+  uint32 temp;
+  if (!input->ReadLittleEndian32(&temp)) return false;
+  *value = static_cast<int32>(temp);
+  return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SFIXED64>(
+    io::CodedInputStream* input,
+    int64* value) {
+  uint64 temp;
+  if (!input->ReadLittleEndian64(&temp)) return false;
+  *value = static_cast<int64>(temp);
+  return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<float, WireFormatLite::TYPE_FLOAT>(
+    io::CodedInputStream* input,
+    float* value) {
+  uint32 temp;
+  if (!input->ReadLittleEndian32(&temp)) return false;
+  *value = DecodeFloat(temp);
+  return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<double, WireFormatLite::TYPE_DOUBLE>(
+    io::CodedInputStream* input,
+    double* value) {
+  uint64 temp;
+  if (!input->ReadLittleEndian64(&temp)) return false;
+  *value = DecodeDouble(temp);
+  return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(
+    io::CodedInputStream* input,
+    bool* value) {
+  uint64 temp;
+  if (!input->ReadVarint64(&temp)) return false;
+  *value = temp != 0;
+  return true;
+}
+template <>
+inline bool WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
+    io::CodedInputStream* input,
+    int* value) {
+  uint32 temp;
+  if (!input->ReadVarint32(&temp)) return false;
+  *value = static_cast<int>(temp);
+  return true;
+}
+
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+  uint32, WireFormatLite::TYPE_FIXED32>(
+    const uint8* buffer,
+    uint32* value) {
+  return io::CodedInputStream::ReadLittleEndian32FromArray(buffer, value);
+}
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+  uint64, WireFormatLite::TYPE_FIXED64>(
+    const uint8* buffer,
+    uint64* value) {
+  return io::CodedInputStream::ReadLittleEndian64FromArray(buffer, value);
+}
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+  int32, WireFormatLite::TYPE_SFIXED32>(
+    const uint8* buffer,
+    int32* value) {
+  uint32 temp;
+  buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
+  *value = static_cast<int32>(temp);
+  return buffer;
+}
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+  int64, WireFormatLite::TYPE_SFIXED64>(
+    const uint8* buffer,
+    int64* value) {
+  uint64 temp;
+  buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
+  *value = static_cast<int64>(temp);
+  return buffer;
+}
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+  float, WireFormatLite::TYPE_FLOAT>(
+    const uint8* buffer,
+    float* value) {
+  uint32 temp;
+  buffer = io::CodedInputStream::ReadLittleEndian32FromArray(buffer, &temp);
+  *value = DecodeFloat(temp);
+  return buffer;
+}
+template <>
+inline const uint8* WireFormatLite::ReadPrimitiveFromArray<
+  double, WireFormatLite::TYPE_DOUBLE>(
+    const uint8* buffer,
+    double* value) {
+  uint64 temp;
+  buffer = io::CodedInputStream::ReadLittleEndian64FromArray(buffer, &temp);
+  *value = DecodeDouble(temp);
+  return buffer;
+}
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+inline bool WireFormatLite::ReadRepeatedPrimitive(
+    int,  // tag_size, unused.
+    uint32 tag,
+    io::CodedInputStream* input,
+    RepeatedField<CType>* values) {
+  CType value;
+  if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
+  values->Add(value);
+  int elements_already_reserved = values->Capacity() - values->size();
+  while (elements_already_reserved > 0 && input->ExpectTag(tag)) {
+    if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
+    values->AddAlreadyReserved(value);
+    elements_already_reserved--;
+  }
+  return true;
+}
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+inline bool WireFormatLite::ReadRepeatedFixedSizePrimitive(
+    int tag_size,
+    uint32 tag,
+    io::CodedInputStream* input,
+    RepeatedField<CType>* values) {
+  GOOGLE_DCHECK_EQ(UInt32Size(tag), tag_size);
+  CType value;
+  if (!ReadPrimitive<CType, DeclaredType>(input, &value))
+    return false;
+  values->Add(value);
+
+  // For fixed size values, repeated values can be read more quickly by
+  // reading directly from a raw array.
+  //
+  // We can get a tight loop by only reading as many elements as can be
+  // added to the RepeatedField without having to do any resizing. Additionally,
+  // we only try to read as many elements as are available from the current
+  // buffer space. Doing so avoids having to perform boundary checks when
+  // reading the value: the maximum number of elements that can be read is
+  // known outside of the loop.
+  const void* void_pointer;
+  int size;
+  input->GetDirectBufferPointerInline(&void_pointer, &size);
+  if (size > 0) {
+    const uint8* buffer = reinterpret_cast<const uint8*>(void_pointer);
+    // The number of bytes each type occupies on the wire.
+    const int per_value_size = tag_size + sizeof(value);
+
+    int elements_available = min(values->Capacity() - values->size(),
+                                 size / per_value_size);
+    int num_read = 0;
+    while (num_read < elements_available &&
+           (buffer = io::CodedInputStream::ExpectTagFromArray(
+               buffer, tag)) != NULL) {
+      buffer = ReadPrimitiveFromArray<CType, DeclaredType>(buffer, &value);
+      values->AddAlreadyReserved(value);
+      ++num_read;
+    }
+    const int read_bytes = num_read * per_value_size;
+    if (read_bytes > 0) {
+      input->Skip(read_bytes);
+    }
+  }
+  return true;
+}
+
+// Specializations of ReadRepeatedPrimitive for the fixed size types, which use
+// the optimized code path.
+#define READ_REPEATED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)             \
+template <>                                                                    \
+inline bool WireFormatLite::ReadRepeatedPrimitive<                             \
+  CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                     \
+    int tag_size,                                                              \
+    uint32 tag,                                                                \
+    io::CodedInputStream* input,                                               \
+    RepeatedField<CPPTYPE>* values) {                                          \
+  return ReadRepeatedFixedSizePrimitive<                                       \
+    CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                   \
+      tag_size, tag, input, values);                                           \
+}
+
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT)
+READ_REPEATED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE)
+
+#undef READ_REPEATED_FIXED_SIZE_PRIMITIVE
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+bool WireFormatLite::ReadRepeatedPrimitiveNoInline(
+    int tag_size,
+    uint32 tag,
+    io::CodedInputStream* input,
+    RepeatedField<CType>* value) {
+  return ReadRepeatedPrimitive<CType, DeclaredType>(
+      tag_size, tag, input, value);
+}
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+inline bool WireFormatLite::ReadPackedPrimitive(io::CodedInputStream* input,
+                                                RepeatedField<CType>* values) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  io::CodedInputStream::Limit limit = input->PushLimit(length);
+  while (input->BytesUntilLimit() > 0) {
+    CType value;
+    if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
+    values->Add(value);
+  }
+  input->PopLimit(limit);
+  return true;
+}
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
+    io::CodedInputStream* input, RepeatedField<CType>* values) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  const uint32 old_entries = values->size();
+  const uint32 new_entries = length / sizeof(CType);
+  const uint32 new_bytes = new_entries * sizeof(CType);
+  if (new_bytes != length) return false;
+  // We would *like* to pre-allocate the buffer to write into (for
+  // speed), but *must* avoid performing a very large allocation due
+  // to a malicious user-supplied "length" above.  So we have a fast
+  // path that pre-allocates when the "length" is less than a bound.
+  // We determine the bound by calling BytesUntilTotalBytesLimit() and
+  // BytesUntilLimit().  These return -1 to mean "no limit set".
+  // There are four cases:
+  // TotalBytesLimit  Limit
+  // -1               -1     Use slow path.
+  // -1               >= 0   Use fast path if length <= Limit.
+  // >= 0             -1     Use slow path.
+  // >= 0             >= 0   Use fast path if length <= min(both limits).
+  int64 bytes_limit = input->BytesUntilTotalBytesLimit();
+  if (bytes_limit == -1) {
+    bytes_limit = input->BytesUntilLimit();
+  } else {
+    bytes_limit =
+        min(bytes_limit, static_cast<int64>(input->BytesUntilLimit()));
+  }
+  if (bytes_limit >= new_bytes) {
+    // Fast-path that pre-allocates *values to the final size.
+#if defined(PROTOBUF_LITTLE_ENDIAN)
+    values->Resize(old_entries + new_entries, 0);
+    // values->mutable_data() may change after Resize(), so do this after:
+    void* dest = reinterpret_cast<void*>(values->mutable_data() + old_entries);
+    if (!input->ReadRaw(dest, new_bytes)) {
+      values->Truncate(old_entries);
+      return false;
+    }
+#else
+    values->Reserve(old_entries + new_entries);
+    CType value;
+    for (uint32 i = 0; i < new_entries; ++i) {
+      if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
+      values->AddAlreadyReserved(value);
+    }
+#endif
+  } else {
+    // This is the slow-path case where "length" may be too large to
+    // safely allocate.  We read as much as we can into *values
+    // without pre-allocating "length" bytes.
+    CType value;
+    for (uint32 i = 0; i < new_entries; ++i) {
+      if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
+      values->Add(value);
+    }
+  }
+  return true;
+}
+
+// Specializations of ReadPackedPrimitive for the fixed size types, which use
+// an optimized code path.
+#define READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(CPPTYPE, DECLARED_TYPE)      \
+template <>                                                                    \
+inline bool WireFormatLite::ReadPackedPrimitive<                               \
+  CPPTYPE, WireFormatLite::DECLARED_TYPE>(                                     \
+    io::CodedInputStream* input,                                               \
+    RepeatedField<CPPTYPE>* values) {                                          \
+  return ReadPackedFixedSizePrimitive<                                         \
+      CPPTYPE, WireFormatLite::DECLARED_TYPE>(input, values);                  \
+}
+
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint32, TYPE_FIXED32);
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(uint64, TYPE_FIXED64);
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int32, TYPE_SFIXED32);
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(int64, TYPE_SFIXED64);
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(float, TYPE_FLOAT);
+READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE(double, TYPE_DOUBLE);
+
+#undef READ_REPEATED_PACKED_FIXED_SIZE_PRIMITIVE
+
+template <typename CType, enum WireFormatLite::FieldType DeclaredType>
+bool WireFormatLite::ReadPackedPrimitiveNoInline(io::CodedInputStream* input,
+                                                 RepeatedField<CType>* values) {
+  return ReadPackedPrimitive<CType, DeclaredType>(input, values);
+}
+
+
+inline bool WireFormatLite::ReadGroup(int field_number,
+                                      io::CodedInputStream* input,
+                                      MessageLite* 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 WireFormatLite::ReadMessage(io::CodedInputStream* input,
+                                        MessageLite* 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;
+}
+
+// We name the template parameter something long and extremely unlikely to occur
+// elsewhere because a *qualified* member access expression designed to avoid
+// virtual dispatch, C++03 [basic.lookup.classref] 3.4.5/4 requires that the
+// name of the qualifying class to be looked up both in the context of the full
+// expression (finding the template parameter) and in the context of the object
+// whose member we are accessing. This could potentially find a nested type
+// within that object. The standard goes on to require these names to refer to
+// the same entity, which this collision would violate. The lack of a safe way
+// to avoid this collision appears to be a defect in the standard, but until it
+// is corrected, we choose the name to avoid accidental collisions.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline bool WireFormatLite::ReadGroupNoVirtual(
+    int field_number, io::CodedInputStream* input,
+    MessageType_WorkAroundCppLookupDefect* value) {
+  if (!input->IncrementRecursionDepth()) return false;
+  if (!value->
+      MessageType_WorkAroundCppLookupDefect::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_WorkAroundCppLookupDefect>
+inline bool WireFormatLite::ReadMessageNoVirtual(
+    io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) {
+  uint32 length;
+  if (!input->ReadVarint32(&length)) return false;
+  if (!input->IncrementRecursionDepth()) return false;
+  io::CodedInputStream::Limit limit = input->PushLimit(length);
+  if (!value->
+      MessageType_WorkAroundCppLookupDefect::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 void WireFormatLite::WriteTag(int field_number, WireType type,
+                                     io::CodedOutputStream* output) {
+  output->WriteTag(MakeTag(field_number, type));
+}
+
+inline void WireFormatLite::WriteInt32NoTag(int32 value,
+                                            io::CodedOutputStream* output) {
+  output->WriteVarint32SignExtended(value);
+}
+inline void WireFormatLite::WriteInt64NoTag(int64 value,
+                                            io::CodedOutputStream* output) {
+  output->WriteVarint64(static_cast<uint64>(value));
+}
+inline void WireFormatLite::WriteUInt32NoTag(uint32 value,
+                                             io::CodedOutputStream* output) {
+  output->WriteVarint32(value);
+}
+inline void WireFormatLite::WriteUInt64NoTag(uint64 value,
+                                             io::CodedOutputStream* output) {
+  output->WriteVarint64(value);
+}
+inline void WireFormatLite::WriteSInt32NoTag(int32 value,
+                                             io::CodedOutputStream* output) {
+  output->WriteVarint32(ZigZagEncode32(value));
+}
+inline void WireFormatLite::WriteSInt64NoTag(int64 value,
+                                             io::CodedOutputStream* output) {
+  output->WriteVarint64(ZigZagEncode64(value));
+}
+inline void WireFormatLite::WriteFixed32NoTag(uint32 value,
+                                              io::CodedOutputStream* output) {
+  output->WriteLittleEndian32(value);
+}
+inline void WireFormatLite::WriteFixed64NoTag(uint64 value,
+                                              io::CodedOutputStream* output) {
+  output->WriteLittleEndian64(value);
+}
+inline void WireFormatLite::WriteSFixed32NoTag(int32 value,
+                                               io::CodedOutputStream* output) {
+  output->WriteLittleEndian32(static_cast<uint32>(value));
+}
+inline void WireFormatLite::WriteSFixed64NoTag(int64 value,
+                                               io::CodedOutputStream* output) {
+  output->WriteLittleEndian64(static_cast<uint64>(value));
+}
+inline void WireFormatLite::WriteFloatNoTag(float value,
+                                            io::CodedOutputStream* output) {
+  output->WriteLittleEndian32(EncodeFloat(value));
+}
+inline void WireFormatLite::WriteDoubleNoTag(double value,
+                                             io::CodedOutputStream* output) {
+  output->WriteLittleEndian64(EncodeDouble(value));
+}
+inline void WireFormatLite::WriteBoolNoTag(bool value,
+                                           io::CodedOutputStream* output) {
+  output->WriteVarint32(value ? 1 : 0);
+}
+inline void WireFormatLite::WriteEnumNoTag(int value,
+                                           io::CodedOutputStream* output) {
+  output->WriteVarint32SignExtended(value);
+}
+
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline void WireFormatLite::WriteGroupNoVirtual(
+    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+    io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_START_GROUP, output);
+  value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
+  WriteTag(field_number, WIRETYPE_END_GROUP, output);
+}
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline void WireFormatLite::WriteMessageNoVirtual(
+    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+    io::CodedOutputStream* output) {
+  WriteTag(field_number, WIRETYPE_LENGTH_DELIMITED, output);
+  output->WriteVarint32(
+      value.MessageType_WorkAroundCppLookupDefect::GetCachedSize());
+  value.MessageType_WorkAroundCppLookupDefect::SerializeWithCachedSizes(output);
+}
+
+// ===================================================================
+
+inline uint8* WireFormatLite::WriteTagToArray(int field_number,
+                                              WireType type,
+                                              uint8* target) {
+  return io::CodedOutputStream::WriteTagToArray(MakeTag(field_number, type),
+                                                target);
+}
+
+inline uint8* WireFormatLite::WriteInt32NoTagToArray(int32 value,
+                                                     uint8* target) {
+  return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteInt64NoTagToArray(int64 value,
+                                                     uint8* target) {
+  return io::CodedOutputStream::WriteVarint64ToArray(
+      static_cast<uint64>(value), target);
+}
+inline uint8* WireFormatLite::WriteUInt32NoTagToArray(uint32 value,
+                                                      uint8* target) {
+  return io::CodedOutputStream::WriteVarint32ToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteUInt64NoTagToArray(uint64 value,
+                                                      uint8* target) {
+  return io::CodedOutputStream::WriteVarint64ToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSInt32NoTagToArray(int32 value,
+                                                      uint8* target) {
+  return io::CodedOutputStream::WriteVarint32ToArray(ZigZagEncode32(value),
+                                                     target);
+}
+inline uint8* WireFormatLite::WriteSInt64NoTagToArray(int64 value,
+                                                      uint8* target) {
+  return io::CodedOutputStream::WriteVarint64ToArray(ZigZagEncode64(value),
+                                                     target);
+}
+inline uint8* WireFormatLite::WriteFixed32NoTagToArray(uint32 value,
+                                                       uint8* target) {
+  return io::CodedOutputStream::WriteLittleEndian32ToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteFixed64NoTagToArray(uint64 value,
+                                                       uint8* target) {
+  return io::CodedOutputStream::WriteLittleEndian64ToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSFixed32NoTagToArray(int32 value,
+                                                        uint8* target) {
+  return io::CodedOutputStream::WriteLittleEndian32ToArray(
+      static_cast<uint32>(value), target);
+}
+inline uint8* WireFormatLite::WriteSFixed64NoTagToArray(int64 value,
+                                                        uint8* target) {
+  return io::CodedOutputStream::WriteLittleEndian64ToArray(
+      static_cast<uint64>(value), target);
+}
+inline uint8* WireFormatLite::WriteFloatNoTagToArray(float value,
+                                                     uint8* target) {
+  return io::CodedOutputStream::WriteLittleEndian32ToArray(EncodeFloat(value),
+                                                           target);
+}
+inline uint8* WireFormatLite::WriteDoubleNoTagToArray(double value,
+                                                      uint8* target) {
+  return io::CodedOutputStream::WriteLittleEndian64ToArray(EncodeDouble(value),
+                                                           target);
+}
+inline uint8* WireFormatLite::WriteBoolNoTagToArray(bool value,
+                                                    uint8* target) {
+  return io::CodedOutputStream::WriteVarint32ToArray(value ? 1 : 0, target);
+}
+inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value,
+                                                    uint8* target) {
+  return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target);
+}
+
+inline uint8* WireFormatLite::WriteInt32ToArray(int field_number,
+                                                int32 value,
+                                                uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+  return WriteInt32NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteInt64ToArray(int field_number,
+                                                int64 value,
+                                                uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+  return WriteInt64NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteUInt32ToArray(int field_number,
+                                                 uint32 value,
+                                                 uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+  return WriteUInt32NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteUInt64ToArray(int field_number,
+                                                 uint64 value,
+                                                 uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+  return WriteUInt64NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSInt32ToArray(int field_number,
+                                                 int32 value,
+                                                 uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+  return WriteSInt32NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSInt64ToArray(int field_number,
+                                                 int64 value,
+                                                 uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+  return WriteSInt64NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteFixed32ToArray(int field_number,
+                                                  uint32 value,
+                                                  uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
+  return WriteFixed32NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteFixed64ToArray(int field_number,
+                                                  uint64 value,
+                                                  uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
+  return WriteFixed64NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSFixed32ToArray(int field_number,
+                                                   int32 value,
+                                                   uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
+  return WriteSFixed32NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteSFixed64ToArray(int field_number,
+                                                   int64 value,
+                                                   uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
+  return WriteSFixed64NoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteFloatToArray(int field_number,
+                                                float value,
+                                                uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_FIXED32, target);
+  return WriteFloatNoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteDoubleToArray(int field_number,
+                                                 double value,
+                                                 uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_FIXED64, target);
+  return WriteDoubleNoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteBoolToArray(int field_number,
+                                               bool value,
+                                               uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+  return WriteBoolNoTagToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteEnumToArray(int field_number,
+                                               int value,
+                                               uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_VARINT, target);
+  return WriteEnumNoTagToArray(value, target);
+}
+
+inline uint8* WireFormatLite::WriteStringToArray(int field_number,
+                                                 const string& value,
+                                                 uint8* target) {
+  // String is for UTF-8 text only
+  // 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.
+  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+  return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
+}
+inline uint8* WireFormatLite::WriteBytesToArray(int field_number,
+                                                const string& value,
+                                                uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+  return io::CodedOutputStream::WriteStringWithSizeToArray(value, target);
+}
+
+
+inline uint8* WireFormatLite::WriteGroupToArray(int field_number,
+                                                const MessageLite& value,
+                                                uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
+  target = value.SerializeWithCachedSizesToArray(target);
+  return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
+}
+inline uint8* WireFormatLite::WriteMessageToArray(int field_number,
+                                                  const MessageLite& value,
+                                                  uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+  target = io::CodedOutputStream::WriteVarint32ToArray(
+    value.GetCachedSize(), target);
+  return value.SerializeWithCachedSizesToArray(target);
+}
+
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline uint8* WireFormatLite::WriteGroupNoVirtualToArray(
+    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+    uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target);
+  target = value.MessageType_WorkAroundCppLookupDefect
+      ::SerializeWithCachedSizesToArray(target);
+  return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target);
+}
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline uint8* WireFormatLite::WriteMessageNoVirtualToArray(
+    int field_number, const MessageType_WorkAroundCppLookupDefect& value,
+    uint8* target) {
+  target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target);
+  target = io::CodedOutputStream::WriteVarint32ToArray(
+    value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target);
+  return value.MessageType_WorkAroundCppLookupDefect
+      ::SerializeWithCachedSizesToArray(target);
+}
+
+// ===================================================================
+
+inline int WireFormatLite::Int32Size(int32 value) {
+  return io::CodedOutputStream::VarintSize32SignExtended(value);
+}
+inline int WireFormatLite::Int64Size(int64 value) {
+  return io::CodedOutputStream::VarintSize64(static_cast<uint64>(value));
+}
+inline int WireFormatLite::UInt32Size(uint32 value) {
+  return io::CodedOutputStream::VarintSize32(value);
+}
+inline int WireFormatLite::UInt64Size(uint64 value) {
+  return io::CodedOutputStream::VarintSize64(value);
+}
+inline int WireFormatLite::SInt32Size(int32 value) {
+  return io::CodedOutputStream::VarintSize32(ZigZagEncode32(value));
+}
+inline int WireFormatLite::SInt64Size(int64 value) {
+  return io::CodedOutputStream::VarintSize64(ZigZagEncode64(value));
+}
+inline int WireFormatLite::EnumSize(int value) {
+  return io::CodedOutputStream::VarintSize32SignExtended(value);
+}
+
+inline int WireFormatLite::StringSize(const string& value) {
+  return io::CodedOutputStream::VarintSize32(value.size()) +
+         value.size();
+}
+inline int WireFormatLite::BytesSize(const string& value) {
+  return io::CodedOutputStream::VarintSize32(value.size()) +
+         value.size();
+}
+
+
+inline int WireFormatLite::GroupSize(const MessageLite& value) {
+  return value.ByteSize();
+}
+inline int WireFormatLite::MessageSize(const MessageLite& value) {
+  return LengthDelimitedSize(value.ByteSize());
+}
+
+// See comment on ReadGroupNoVirtual to understand the need for this template
+// parameter name.
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline int WireFormatLite::GroupSizeNoVirtual(
+    const MessageType_WorkAroundCppLookupDefect& value) {
+  return value.MessageType_WorkAroundCppLookupDefect::ByteSize();
+}
+template<typename MessageType_WorkAroundCppLookupDefect>
+inline int WireFormatLite::MessageSizeNoVirtual(
+    const MessageType_WorkAroundCppLookupDefect& value) {
+  return LengthDelimitedSize(
+      value.MessageType_WorkAroundCppLookupDefect::ByteSize());
+}
+
+inline int WireFormatLite::LengthDelimitedSize(int length) {
+  return io::CodedOutputStream::VarintSize32(length) + length;
+}
+
+}  // namespace internal
+}  // namespace protobuf
+
+}  // namespace google
+#endif  // GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__
diff --git a/protobuf/src/google/protobuf/wire_format_unittest.cc b/protobuf/src/google/protobuf/wire_format_unittest.cc
new file mode 100644
index 0000000..81a024b
--- /dev/null
+++ b/protobuf/src/google/protobuf/wire_format_unittest.cc
@@ -0,0 +1,1120 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: 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_lite_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>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+namespace internal {
+namespace {
+
+TEST(WireFormatTest, EnumsInSync) {
+  // Verify that WireFormatLite::FieldType and WireFormatLite::CppType match
+  // FieldDescriptor::Type and FieldDescriptor::CppType.
+
+  EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_TYPE),
+            implicit_cast<int>(WireFormatLite::MAX_FIELD_TYPE));
+  EXPECT_EQ(implicit_cast<int>(FieldDescriptor::MAX_CPPTYPE),
+            implicit_cast<int>(WireFormatLite::MAX_CPPTYPE));
+
+  for (int i = 1; i <= WireFormatLite::MAX_FIELD_TYPE; i++) {
+    EXPECT_EQ(
+      implicit_cast<int>(FieldDescriptor::TypeToCppType(
+        static_cast<FieldDescriptor::Type>(i))),
+      implicit_cast<int>(WireFormatLite::FieldTypeToCppType(
+        static_cast<WireFormatLite::FieldType>(i))));
+  }
+}
+
+TEST(WireFormatTest, MaxFieldNumber) {
+  // Make sure the max field number constant is accurate.
+  EXPECT_EQ((1 << (32 - WireFormatLite::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(&input, &dest);
+
+  // 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(&input, &dest);
+
+  // Check.
+  TestUtil::ExpectAllExtensionsSet(dest);
+}
+
+TEST(WireFormatTest, ParsePacked) {
+  unittest::TestPackedTypes source, dest;
+  string data;
+
+  // Serialize using the generated code.
+  TestUtil::SetPackedFields(&source);
+  source.SerializeToString(&data);
+
+  // Parse using WireFormat.
+  io::ArrayInputStream raw_input(data.data(), data.size());
+  io::CodedInputStream input(&raw_input);
+  WireFormat::ParseAndMergePartial(&input, &dest);
+
+  // Check.
+  TestUtil::ExpectPackedFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParsePackedFromUnpacked) {
+  // Serialize using the generated code.
+  unittest::TestUnpackedTypes source;
+  TestUtil::SetUnpackedFields(&source);
+  string data = source.SerializeAsString();
+
+  // Parse using WireFormat.
+  unittest::TestPackedTypes dest;
+  io::ArrayInputStream raw_input(data.data(), data.size());
+  io::CodedInputStream input(&raw_input);
+  WireFormat::ParseAndMergePartial(&input, &dest);
+
+  // Check.
+  TestUtil::ExpectPackedFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParseUnpackedFromPacked) {
+  // Serialize using the generated code.
+  unittest::TestPackedTypes source;
+  TestUtil::SetPackedFields(&source);
+  string data = source.SerializeAsString();
+
+  // Parse using WireFormat.
+  unittest::TestUnpackedTypes dest;
+  io::ArrayInputStream raw_input(data.data(), data.size());
+  io::CodedInputStream input(&raw_input);
+  WireFormat::ParseAndMergePartial(&input, &dest);
+
+  // Check.
+  TestUtil::ExpectUnpackedFieldsSet(dest);
+}
+
+TEST(WireFormatTest, ParsePackedExtensions) {
+  unittest::TestPackedExtensions source, dest;
+  string data;
+
+  // Serialize using the generated code.
+  TestUtil::SetPackedExtensions(&source);
+  source.SerializeToString(&data);
+
+  // Parse using WireFormat.
+  io::ArrayInputStream raw_input(data.data(), data.size());
+  io::CodedInputStream input(&raw_input);
+  WireFormat::ParseAndMergePartial(&input, &dest);
+
+  // Check.
+  TestUtil::ExpectPackedExtensionsSet(dest);
+}
+
+TEST(WireFormatTest, ParseOneof) {
+  unittest::TestOneof2 source, dest;
+  string data;
+
+  // Serialize using the generated code.
+  TestUtil::SetOneof1(&source);
+  source.SerializeToString(&data);
+
+  // Parse using WireFormat.
+  io::ArrayInputStream raw_input(data.data(), data.size());
+  io::CodedInputStream input(&raw_input);
+  WireFormat::ParseAndMergePartial(&input, &dest);
+
+  // Check.
+  TestUtil::ExpectOneofSet1(dest);
+}
+
+TEST(WireFormatTest, OneofOnlySetLast) {
+  unittest::TestOneofBackwardsCompatible source;
+  unittest::TestOneof oneof_dest;
+  string data;
+
+  // Set two fields
+  source.set_foo_int(100);
+  source.set_foo_string("101");
+
+  // Serialize and parse to oneof message.
+  source.SerializeToString(&data);
+  io::ArrayInputStream raw_input(data.data(), data.size());
+  io::CodedInputStream input(&raw_input);
+  WireFormat::ParseAndMergePartial(&input, &oneof_dest);
+
+  // Only the last field is set.
+  EXPECT_FALSE(oneof_dest.has_foo_int());
+  EXPECT_TRUE(oneof_dest.has_foo_string());
+}
+
+TEST(WireFormatTest, ByteSize) {
+  unittest::TestAllTypes message;
+  TestUtil::SetAllFields(&message);
+
+  EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
+  message.Clear();
+  EXPECT_EQ(0, message.ByteSize());
+  EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizeExtensions) {
+  unittest::TestAllExtensions message;
+  TestUtil::SetAllExtensions(&message);
+
+  EXPECT_EQ(message.ByteSize(),
+            WireFormat::ByteSize(message));
+  message.Clear();
+  EXPECT_EQ(0, message.ByteSize());
+  EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizePacked) {
+  unittest::TestPackedTypes message;
+  TestUtil::SetPackedFields(&message);
+
+  EXPECT_EQ(message.ByteSize(), WireFormat::ByteSize(message));
+  message.Clear();
+  EXPECT_EQ(0, message.ByteSize());
+  EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizePackedExtensions) {
+  unittest::TestPackedExtensions message;
+  TestUtil::SetPackedExtensions(&message);
+
+  EXPECT_EQ(message.ByteSize(),
+            WireFormat::ByteSize(message));
+  message.Clear();
+  EXPECT_EQ(0, message.ByteSize());
+  EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+TEST(WireFormatTest, ByteSizeOneof) {
+  unittest::TestOneof2 message;
+  TestUtil::SetOneof1(&message);
+
+  EXPECT_EQ(message.ByteSize(),
+  WireFormat::ByteSize(message));
+  message.Clear();
+
+  EXPECT_EQ(0, message.ByteSize());
+  EXPECT_EQ(0, WireFormat::ByteSize(message));
+}
+
+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);
+    ASSERT_FALSE(output.HadError());
+  }
+
+  // Serialize using WireFormat.
+  {
+    io::StringOutputStream raw_output(&dynamic_data);
+    io::CodedOutputStream output(&raw_output);
+    WireFormat::SerializeWithCachedSizes(message, size, &output);
+    ASSERT_FALSE(output.HadError());
+  }
+
+  // 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);
+    ASSERT_FALSE(output.HadError());
+  }
+
+  // Serialize using WireFormat.
+  {
+    io::StringOutputStream raw_output(&dynamic_data);
+    io::CodedOutputStream output(&raw_output);
+    WireFormat::SerializeWithCachedSizes(message, size, &output);
+    ASSERT_FALSE(output.HadError());
+  }
+
+  // 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);
+    ASSERT_FALSE(output.HadError());
+  }
+
+  // Serialize using WireFormat.
+  {
+    io::StringOutputStream raw_output(&dynamic_data);
+    io::CodedOutputStream output(&raw_output);
+    WireFormat::SerializeWithCachedSizes(message, size, &output);
+    ASSERT_FALSE(output.HadError());
+  }
+
+  // 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);
+}
+
+TEST(WireFormatTest, SerializeOneof) {
+  unittest::TestOneof2 message;
+  string generated_data;
+  string dynamic_data;
+
+  TestUtil::SetOneof1(&message);
+  int size = message.ByteSize();
+
+  // Serialize using the generated code.
+  {
+    io::StringOutputStream raw_output(&generated_data);
+    io::CodedOutputStream output(&raw_output);
+    message.SerializeWithCachedSizes(&output);
+    ASSERT_FALSE(output.HadError());
+  }
+
+  // Serialize using WireFormat.
+  {
+    io::StringOutputStream raw_output(&dynamic_data);
+    io::CodedOutputStream output(&raw_output);
+    WireFormat::SerializeWithCachedSizes(message, size, &output);
+    ASSERT_FALSE(output.HadError());
+  }
+
+  // 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, ParseMultipleExtensionRanges) {
+  // Make sure we can parse a message that contains multiple extensions ranges.
+  unittest::TestFieldOrderings source;
+  string data;
+
+  TestUtil::SetAllFieldsAndExtensions(&source);
+  source.SerializeToString(&data);
+
+  {
+    unittest::TestFieldOrderings dest;
+    EXPECT_TRUE(dest.ParseFromString(data));
+    EXPECT_EQ(source.DebugString(), dest.DebugString());
+  }
+
+  // Also test using reflection-based parsing.
+  {
+    unittest::TestFieldOrderings dest;
+    io::ArrayInputStream raw_input(data.data(), data.size());
+    io::CodedInputStream coded_input(&raw_input);
+    EXPECT_TRUE(WireFormat::ParseAndMergePartial(&coded_input, &dest));
+    EXPECT_EQ(source.DebugString(), dest.DebugString());
+  }
+}
+
+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()->AddLengthDelimited(
+    kUnknownTypeId, "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, SerializeMessageSetVariousWaysAreEqual) {
+  // Serialize a MessageSet to a stream and to a flat array using generated
+  // code, and also using WireFormat, and check that the results are equal.
+  // Set up a TestMessageSet with two known messages and an unknown one, as
+  // above.
+
+  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()->AddLengthDelimited(
+    kUnknownTypeId, "bar");
+
+  int size = message_set.ByteSize();
+  EXPECT_EQ(size, message_set.GetCachedSize());
+  ASSERT_EQ(size, WireFormat::ByteSize(message_set));
+
+  string flat_data;
+  string stream_data;
+  string dynamic_data;
+  flat_data.resize(size);
+  stream_data.resize(size);
+
+  // Serialize to flat array
+  {
+    uint8* target = reinterpret_cast<uint8*>(string_as_array(&flat_data));
+    uint8* end = message_set.SerializeWithCachedSizesToArray(target);
+    EXPECT_EQ(size, end - target);
+  }
+
+  // Serialize to buffer
+  {
+    io::ArrayOutputStream array_stream(string_as_array(&stream_data), size, 1);
+    io::CodedOutputStream output_stream(&array_stream);
+    message_set.SerializeWithCachedSizes(&output_stream);
+    ASSERT_FALSE(output_stream.HadError());
+  }
+
+  // Serialize to buffer with WireFormat.
+  {
+    io::StringOutputStream string_stream(&dynamic_data);
+    io::CodedOutputStream output_stream(&string_stream);
+    WireFormat::SerializeWithCachedSizes(message_set, size, &output_stream);
+    ASSERT_FALSE(output_stream.HadError());
+  }
+
+  EXPECT_TRUE(flat_data == stream_data);
+  EXPECT_TRUE(flat_data == dynamic_data);
+}
+
+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(UnknownField::TYPE_LENGTH_DELIMITED,
+            message_set.unknown_fields().field(0).type());
+  EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited());
+
+  // Also parse using WireFormat.
+  unittest::TestMessageSet dynamic_message_set;
+  io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()),
+                             data.size());
+  ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set));
+  EXPECT_EQ(message_set.DebugString(), dynamic_message_set.DebugString());
+}
+
+TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
+  string data;
+  {
+    unittest::TestMessageSetExtension1 message;
+    message.set_i(123);
+    // Build a MessageSet manually with its message content put before its
+    // type_id.
+    io::StringOutputStream output_stream(&data);
+    io::CodedOutputStream coded_output(&output_stream);
+    coded_output.WriteTag(WireFormatLite::kMessageSetItemStartTag);
+    // Write the message content first.
+    WireFormatLite::WriteTag(WireFormatLite::kMessageSetMessageNumber,
+                             WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+                             &coded_output);
+    coded_output.WriteVarint32(message.ByteSize());
+    message.SerializeWithCachedSizes(&coded_output);
+    // Write the type id.
+    uint32 type_id = message.GetDescriptor()->extension(0)->number();
+    WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
+                                type_id, &coded_output);
+    coded_output.WriteTag(WireFormatLite::kMessageSetItemEndTag);
+  }
+  {
+    unittest::TestMessageSet message_set;
+    ASSERT_TRUE(message_set.ParseFromString(data));
+
+    EXPECT_EQ(123, message_set.GetExtension(
+        unittest::TestMessageSetExtension1::message_set_extension).i());
+  }
+  {
+    // Test parse the message via Reflection.
+    unittest::TestMessageSet message_set;
+    io::CodedInputStream input(
+        reinterpret_cast<const uint8*>(data.data()), data.size());
+    EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set));
+    EXPECT_TRUE(input.ConsumedEntireMessage());
+
+    EXPECT_EQ(123, message_set.GetExtension(
+        unittest::TestMessageSetExtension1::message_set_extension).i());
+  }
+}
+
+TEST(WireFormatTest, ParseBrokenMessageSet) {
+  unittest::TestMessageSet message_set;
+  string input("goodbye");  // Invalid wire format data.
+  EXPECT_FALSE(message_set.ParseFromString(input));
+}
+
+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()
+        ->AddGroup(1234)
+        ->AddGroup(1234)
+        ->AddGroup(1234)
+        ->AddGroup(1234)
+        ->AddVarint(1234, 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) WireFormatLite::ZigZagEncode32(x)
+#define ZigZagDecode32(x) WireFormatLite::ZigZagDecode32(x)
+#define ZigZagEncode64(x) WireFormatLite::ZigZagEncode64(x)
+#define ZigZagDecode64(x) WireFormatLite::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))));
+}
+
+TEST(WireFormatTest, RepeatedScalarsDifferentTagSizes) {
+  // At one point checks would trigger when parsing repeated fixed scalar
+  // fields.
+  protobuf_unittest::TestRepeatedScalarDifferentTagSizes msg1, msg2;
+  for (int i = 0; i < 100; ++i) {
+    msg1.add_repeated_fixed32(i);
+    msg1.add_repeated_int32(i);
+    msg1.add_repeated_fixed64(i);
+    msg1.add_repeated_int64(i);
+    msg1.add_repeated_float(i);
+    msg1.add_repeated_uint64(i);
+  }
+
+  // Make sure that we have a variety of tag sizes.
+  const google::protobuf::Descriptor* desc = msg1.GetDescriptor();
+  const google::protobuf::FieldDescriptor* field;
+  field = desc->FindFieldByName("repeated_fixed32");
+  ASSERT_TRUE(field != NULL);
+  ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
+  field = desc->FindFieldByName("repeated_int32");
+  ASSERT_TRUE(field != NULL);
+  ASSERT_EQ(1, WireFormat::TagSize(field->number(), field->type()));
+  field = desc->FindFieldByName("repeated_fixed64");
+  ASSERT_TRUE(field != NULL);
+  ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
+  field = desc->FindFieldByName("repeated_int64");
+  ASSERT_TRUE(field != NULL);
+  ASSERT_EQ(2, WireFormat::TagSize(field->number(), field->type()));
+  field = desc->FindFieldByName("repeated_float");
+  ASSERT_TRUE(field != NULL);
+  ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
+  field = desc->FindFieldByName("repeated_uint64");
+  ASSERT_TRUE(field != NULL);
+  ASSERT_EQ(3, WireFormat::TagSize(field->number(), field->type()));
+
+  EXPECT_TRUE(msg2.ParseFromString(msg1.SerializeAsString()));
+  EXPECT_EQ(msg1.DebugString(), msg2.DebugString());
+}
+
+TEST(WireFormatTest, CompatibleTypes) {
+  const int64 data = 0x100000000;
+  unittest::Int64Message msg1;
+  msg1.set_data(data);
+  string serialized;
+  msg1.SerializeToString(&serialized);
+
+  // Test int64 is compatible with bool
+  unittest::BoolMessage msg2;
+  ASSERT_TRUE(msg2.ParseFromString(serialized));
+  ASSERT_EQ(static_cast<bool>(data), msg2.data());
+
+  // Test int64 is compatible with uint64
+  unittest::Uint64Message msg3;
+  ASSERT_TRUE(msg3.ParseFromString(serialized));
+  ASSERT_EQ(static_cast<uint64>(data), msg3.data());
+
+  // Test int64 is compatible with int32
+  unittest::Int32Message msg4;
+  ASSERT_TRUE(msg4.ParseFromString(serialized));
+  ASSERT_EQ(static_cast<int32>(data), msg4.data());
+
+  // Test int64 is compatible with uint32
+  unittest::Uint32Message msg5;
+  ASSERT_TRUE(msg5.ParseFromString(serialized));
+  ASSERT_EQ(static_cast<uint32>(data), msg5.data());
+}
+
+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);
+
+      WireFormatLite::WriteBytes(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);
+
+      output.WriteVarint32(WireFormat::MakeTag(field));
+      output.WriteString(string(bytes, size));
+      if (include_end_tag) {
+        output.WriteVarint32(WireFormatLite::MakeTag(
+          field->number(), WireFormatLite::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 TestEmptyMessage so that the group made by MakeInvalidGroup will not
+  // be a known tag number.
+  unittest::TestEmptyMessage 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, InvalidStringInUnknownGroup) {
+  // Test a bug fix:  SkipMessage should fail if the message contains a string
+  // whose length would extend beyond the message end.
+
+  unittest::TestAllTypes message;
+  message.set_optional_string("foo foo foo foo");
+  string data;
+  message.SerializeToString(&data);
+
+  // Chop some bytes off the end.
+  data.resize(data.size() - 4);
+
+  // Try to skip it.  Note that the bug was only present when parsing to an
+  // UnknownFieldSet.
+  io::ArrayInputStream raw_input(data.data(), data.size());
+  io::CodedInputStream coded_input(&raw_input);
+  UnknownFieldSet unknown_fields;
+  EXPECT_FALSE(WireFormat::SkipMessage(&coded_input, &unknown_fields));
+}
+
+// Test differences between string and bytes.
+// Value of a string type must be valid UTF-8 string.  When UTF-8
+// validation is enabled (GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED):
+// WriteInvalidUTF8String:  see error message.
+// ReadInvalidUTF8String:  see error message.
+// WriteValidUTF8String: fine.
+// ReadValidUTF8String:  fine.
+// WriteAnyBytes: fine.
+// ReadAnyBytes: fine.
+const char * kInvalidUTF8String = "Invalid UTF-8: \xA0\xB0\xC0\xD0";
+// This used to be "Valid UTF-8: \x01\x02\u8C37\u6B4C", but MSVC seems to
+// interpret \u differently from GCC.
+const char * kValidUTF8String = "Valid UTF-8: \x01\x02\350\260\267\346\255\214";
+
+template<typename T>
+bool WriteMessage(const char *value, T *message, string *wire_buffer) {
+  message->set_data(value);
+  wire_buffer->clear();
+  message->AppendToString(wire_buffer);
+  return (wire_buffer->size() > 0);
+}
+
+template<typename T>
+bool ReadMessage(const string &wire_buffer, T *message) {
+  return message->ParseFromArray(wire_buffer.data(), wire_buffer.size());
+}
+
+bool StartsWith(const string& s, const string& prefix) {
+  return s.substr(0, prefix.length()) == prefix;
+}
+
+class Utf8ValidationTest : public ::testing::Test {
+ protected:
+  Utf8ValidationTest() {}
+  virtual ~Utf8ValidationTest() {}
+  virtual void SetUp() {
+  }
+
+};
+
+TEST_F(Utf8ValidationTest, WriteInvalidUTF8String) {
+  string wire_buffer;
+  protobuf_unittest::OneString input;
+  vector<string> errors;
+  {
+    ScopedMemoryLog log;
+    WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+    errors = log.GetMessages(ERROR);
+  }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+  ASSERT_EQ(1, errors.size());
+  EXPECT_TRUE(StartsWith(errors[0],
+                         "String field 'data' contains invalid UTF-8 data when "
+                         "serializing a protocol buffer. Use the "
+                         "'bytes' type if you intend to send raw bytes."));
+#else
+  ASSERT_EQ(0, errors.size());
+#endif  // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+}
+
+
+TEST_F(Utf8ValidationTest, ReadInvalidUTF8String) {
+  string wire_buffer;
+  protobuf_unittest::OneString input;
+  WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+  protobuf_unittest::OneString output;
+  vector<string> errors;
+  {
+    ScopedMemoryLog log;
+    ReadMessage(wire_buffer, &output);
+    errors = log.GetMessages(ERROR);
+  }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+  ASSERT_EQ(1, errors.size());
+  EXPECT_TRUE(StartsWith(errors[0],
+                         "String field 'data' contains invalid UTF-8 data when "
+                         "parsing a protocol buffer. Use the "
+                         "'bytes' type if you intend to send raw bytes."));
+
+#else
+  ASSERT_EQ(0, errors.size());
+#endif  // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+}
+
+
+TEST_F(Utf8ValidationTest, WriteValidUTF8String) {
+  string wire_buffer;
+  protobuf_unittest::OneString input;
+  vector<string> errors;
+  {
+    ScopedMemoryLog log;
+    WriteMessage(kValidUTF8String, &input, &wire_buffer);
+    errors = log.GetMessages(ERROR);
+  }
+  ASSERT_EQ(0, errors.size());
+}
+
+TEST_F(Utf8ValidationTest, ReadValidUTF8String) {
+  string wire_buffer;
+  protobuf_unittest::OneString input;
+  WriteMessage(kValidUTF8String, &input, &wire_buffer);
+  protobuf_unittest::OneString output;
+  vector<string> errors;
+  {
+    ScopedMemoryLog log;
+    ReadMessage(wire_buffer, &output);
+    errors = log.GetMessages(ERROR);
+  }
+  ASSERT_EQ(0, errors.size());
+  EXPECT_EQ(input.data(), output.data());
+}
+
+// Bytes: anything can pass as bytes, use invalid UTF-8 string to test
+TEST_F(Utf8ValidationTest, WriteArbitraryBytes) {
+  string wire_buffer;
+  protobuf_unittest::OneBytes input;
+  vector<string> errors;
+  {
+    ScopedMemoryLog log;
+    WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+    errors = log.GetMessages(ERROR);
+  }
+  ASSERT_EQ(0, errors.size());
+}
+
+TEST_F(Utf8ValidationTest, ReadArbitraryBytes) {
+  string wire_buffer;
+  protobuf_unittest::OneBytes input;
+  WriteMessage(kInvalidUTF8String, &input, &wire_buffer);
+  protobuf_unittest::OneBytes output;
+  vector<string> errors;
+  {
+    ScopedMemoryLog log;
+    ReadMessage(wire_buffer, &output);
+    errors = log.GetMessages(ERROR);
+  }
+  ASSERT_EQ(0, errors.size());
+  EXPECT_EQ(input.data(), output.data());
+}
+
+TEST_F(Utf8ValidationTest, ParseRepeatedString) {
+  protobuf_unittest::MoreBytes input;
+  input.add_data(kValidUTF8String);
+  input.add_data(kInvalidUTF8String);
+  input.add_data(kInvalidUTF8String);
+  string wire_buffer = input.SerializeAsString();
+
+  protobuf_unittest::MoreString output;
+  vector<string> errors;
+  {
+    ScopedMemoryLog log;
+    ReadMessage(wire_buffer, &output);
+    errors = log.GetMessages(ERROR);
+  }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+  ASSERT_EQ(2, errors.size());
+#else
+  ASSERT_EQ(0, errors.size());
+#endif  // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+  EXPECT_EQ(wire_buffer, output.SerializeAsString());
+}
+
+// Test the old VerifyUTF8String() function, which may still be called by old
+// generated code.
+TEST_F(Utf8ValidationTest, OldVerifyUTF8String) {
+  string data(kInvalidUTF8String);
+
+  vector<string> errors;
+  {
+    ScopedMemoryLog log;
+    WireFormat::VerifyUTF8String(data.data(), data.size(),
+                                 WireFormat::SERIALIZE);
+    errors = log.GetMessages(ERROR);
+  }
+#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
+  ASSERT_EQ(1, errors.size());
+  EXPECT_TRUE(StartsWith(errors[0],
+                         "String field contains invalid UTF-8 data when "
+                         "serializing a protocol buffer. Use the "
+                         "'bytes' type if you intend to send raw bytes."));
+#else
+  ASSERT_EQ(0, errors.size());
+#endif
+}
+
+
+}  // namespace
+}  // namespace internal
+}  // namespace protobuf
+}  // namespace google
diff --git a/protobuf/src/solaris/libstdc++.la b/protobuf/src/solaris/libstdc++.la
new file mode 100644
index 0000000..3edf425
--- /dev/null
+++ b/protobuf/src/solaris/libstdc++.la
@@ -0,0 +1,51 @@
+# libstdc++.la - a libtool library file
+# Generated by ltmain.sh - GNU libtool 1.4a-GCC3.0 (1.641.2.256 2001/05/28 20:09:07 with GCC-local changes)
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# ---
+# NOTE: This file lives in /usr/sfw/lib on Solaris 10.  Unfortunately,
+# due to an apparent bug in the Solaris 10 6/06 release,
+# /usr/sfw/lib/libstdc++.la is empty.  Below is the correct content,
+# according to
+#    http://forum.java.sun.com/thread.jspa?threadID=5073150
+# By passing LDFLAGS='-Lsrc/solaris' to configure, make will pick up
+# this copy of the file rather than the empty copy in /usr/sfw/lib.
+#
+# Also see
+#   http://www.technicalarticles.org/index.php/Compiling_MySQL_5.0_on_Solaris_10
+#
+# Note: this is for 32-bit systems.  If you have a 64-bit system,
+# uncomment the appropriate dependency_libs line below.
+# ----
+
+# The name that we can dlopen(3).
+dlname='libstdc++.so.6'
+
+# Names of this library.
+library_names='libstdc++.so.6.0.3 libstdc++.so.6 libstdc++.so'
+
+# The name of the static archive.
+old_library='libstdc++.a'
+
+# Libraries that this one depends upon.
+# 32-bit version:
+dependency_libs='-lc -lm -L/usr/sfw/lib -lgcc_s'
+# 64-bit version:
+#dependency_libs='-L/lib/64 -lc -lm -L/usr/sfw/lib/64 -lgcc_s'
+
+# Version information for libstdc++.
+current=6
+age=0
+revision=3
+
+# Is this an already installed library?
+installed=yes
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/usr/sfw/lib'
diff --git a/protobuf/test-driver b/protobuf/test-driver
new file mode 100755
index 0000000..d306056
--- /dev/null
+++ b/protobuf/test-driver
@@ -0,0 +1,139 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2013-07-13.22; # UTC
+
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+# Make unconditional expansion of undefined variables an error.  This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+  echo "$0: $*" >&2
+  print_usage >&2
+  exit 2
+}
+
+print_usage ()
+{
+  cat <<END
+Usage:
+  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+              [--expect-failure={yes|no}] [--color-tests={yes|no}]
+              [--enable-hard-errors={yes|no}] [--]
+              TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+test_name= # Used for reporting.
+log_file=  # Where to save the output of the test script.
+trs_file=  # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+  case $1 in
+  --help) print_usage; exit $?;;
+  --version) echo "test-driver $scriptversion"; exit $?;;
+  --test-name) test_name=$2; shift;;
+  --log-file) log_file=$2; shift;;
+  --trs-file) trs_file=$2; shift;;
+  --color-tests) color_tests=$2; shift;;
+  --expect-failure) expect_failure=$2; shift;;
+  --enable-hard-errors) enable_hard_errors=$2; shift;;
+  --) shift; break;;
+  -*) usage_error "invalid option: '$1'";;
+   *) break;;
+  esac
+  shift
+done
+
+missing_opts=
+test x"$test_name" = x && missing_opts="$missing_opts --test-name"
+test x"$log_file"  = x && missing_opts="$missing_opts --log-file"
+test x"$trs_file"  = x && missing_opts="$missing_opts --trs-file"
+if test x"$missing_opts" != x; then
+  usage_error "the following mandatory options are missing:$missing_opts"
+fi
+
+if test $# -eq 0; then
+  usage_error "missing argument"
+fi
+
+if test $color_tests = yes; then
+  # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+  red='' # Red.
+  grn='' # Green.
+  lgn='' # Light green.
+  blu='' # Blue.
+  mgn='' # Magenta.
+  std=''     # No color.
+else
+  red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+  estatus=1
+fi
+
+case $estatus:$expect_failure in
+  0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+  0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
+  77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
+  99:*)  col=$mgn res=ERROR recheck=yes gcopy=yes;;
+  *:yes) col=$lgn res=XFAIL recheck=no  gcopy=yes;;
+  *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;
+esac
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/protobuf/vsprojects/config.h b/protobuf/vsprojects/config.h
new file mode 100644
index 0000000..2c64450
--- /dev/null
+++ b/protobuf/vsprojects/config.h
@@ -0,0 +1,29 @@
+/* protobuf config.h for MSVC.  On other platforms, this is generated
+ * automatically by autoheader / autoconf / configure. */
+
+/* the location of <hash_map> */
+#define HASH_MAP_H <hash_map>
+
+/* the namespace of hash_map/hash_set */
+// Apparently Microsoft decided to move hash_map *back* to the std namespace
+// in MSVC 2010:
+//   http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
+// TODO(kenton):  Use unordered_map instead, which is available in MSVC 2010.
+#if _MSC_VER < 1310 || _MSC_VER >= 1600
+#define HASH_NAMESPACE std
+#else
+#define HASH_NAMESPACE stdext
+#endif
+
+/* the location of <hash_set> */
+#define HASH_SET_H <hash_set>
+
+/* define if the compiler has hash_map */
+#define HAVE_HASH_MAP 1
+
+/* define if the compiler has hash_set */
+#define HAVE_HASH_SET 1
+
+/* define if you want to use zlib.  See readme.txt for additional
+ * requirements. */
+// #define HAVE_ZLIB 1
diff --git a/protobuf/vsprojects/convert2008to2005.sh b/protobuf/vsprojects/convert2008to2005.sh
new file mode 100755
index 0000000..60eccaf
--- /dev/null
+++ b/protobuf/vsprojects/convert2008to2005.sh
@@ -0,0 +1,20 @@
+#! /bin/sh -e
+
+# This script downgrades MSVC 2008 projects to MSVC 2005 projects, allowing
+# people with MSVC 2005 to open them.  Otherwise, MSVC 2005 simply refuses to
+# open projects created with 2008.  We run this as part of our release process.
+# If you obtained the code direct from version control and you want to use
+# MSVC 2005, you may have to run this manually.  (Hint:  Use Cygwin or MSYS.)
+
+for file in *.sln; do
+  echo "downgrading $file..."
+  sed -i -re 's/Format Version 10.00/Format Version 9.00/g;
+              s/Visual Studio 2008/Visual Studio 2005/g;' $file
+done
+
+for file in *.vcproj; do
+  echo "downgrading $file..."
+  sed -i -re 's/Version="9.00"/Version="8.00"/g;' $file
+done
+
+# Yes, really, that's it.
diff --git a/protobuf/vsprojects/extract_includes.bat b/protobuf/vsprojects/extract_includes.bat
new file mode 100755
index 0000000..beab8c4
--- /dev/null
+++ b/protobuf/vsprojects/extract_includes.bat
@@ -0,0 +1,50 @@
+md include
+md include\google
+md include\google\protobuf
+md include\google\protobuf\stubs
+md include\google\protobuf\io
+md include\google\protobuf\compiler
+md include\google\protobuf\compiler\cpp
+md include\google\protobuf\compiler\java
+md include\google\protobuf\compiler\python
+copy ..\src\google\protobuf\stubs\atomicops.h include\google\protobuf\stubs\atomicops.h
+copy ..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h include\google\protobuf\stubs\atomicops_internals_x86_msvc.h
+copy ..\src\google\protobuf\stubs\common.h include\google\protobuf\stubs\common.h
+copy ..\src\google\protobuf\stubs\once.h include\google\protobuf\stubs\once.h
+copy ..\src\google\protobuf\stubs\platform_macros.h include\google\protobuf\stubs\platform_macros.h
+copy ..\src\google\protobuf\stubs\template_util.h include\google\protobuf\stubs\template_util.h
+copy ..\src\google\protobuf\stubs\type_traits.h include\google\protobuf\stubs\type_traits.h
+copy ..\src\google\protobuf\descriptor.h include\google\protobuf\descriptor.h
+copy ..\src\google\protobuf\descriptor.pb.h include\google\protobuf\descriptor.pb.h
+copy ..\src\google\protobuf\descriptor_database.h include\google\protobuf\descriptor_database.h
+copy ..\src\google\protobuf\dynamic_message.h include\google\protobuf\dynamic_message.h
+copy ..\src\google\protobuf\extension_set.h include\google\protobuf\extension_set.h
+copy ..\src\google\protobuf\generated_enum_reflection.h include\google\protobuf\generated_enum_reflection.h
+copy ..\src\google\protobuf\generated_message_util.h include\google\protobuf\generated_message_util.h
+copy ..\src\google\protobuf\generated_message_reflection.h include\google\protobuf\generated_message_reflection.h
+copy ..\src\google\protobuf\message.h include\google\protobuf\message.h
+copy ..\src\google\protobuf\message_lite.h include\google\protobuf\message_lite.h
+copy ..\src\google\protobuf\reflection_ops.h include\google\protobuf\reflection_ops.h
+copy ..\src\google\protobuf\repeated_field.h include\google\protobuf\repeated_field.h
+copy ..\src\google\protobuf\service.h include\google\protobuf\service.h
+copy ..\src\google\protobuf\text_format.h include\google\protobuf\text_format.h
+copy ..\src\google\protobuf\unknown_field_set.h include\google\protobuf\unknown_field_set.h
+copy ..\src\google\protobuf\wire_format.h include\google\protobuf\wire_format.h
+copy ..\src\google\protobuf\wire_format_lite.h include\google\protobuf\wire_format_lite.h
+copy ..\src\google\protobuf\wire_format_lite_inl.h include\google\protobuf\wire_format_lite_inl.h
+copy ..\src\google\protobuf\io\coded_stream.h include\google\protobuf\io\coded_stream.h
+copy ..\src\google\protobuf\io\gzip_stream.h include\google\protobuf\io\gzip_stream.h
+copy ..\src\google\protobuf\io\printer.h include\google\protobuf\io\printer.h
+copy ..\src\google\protobuf\io\strtod.h include\google\protobuf\io\strtod.h
+copy ..\src\google\protobuf\io\tokenizer.h include\google\protobuf\io\tokenizer.h
+copy ..\src\google\protobuf\io\zero_copy_stream.h include\google\protobuf\io\zero_copy_stream.h
+copy ..\src\google\protobuf\io\zero_copy_stream_impl.h include\google\protobuf\io\zero_copy_stream_impl.h
+copy ..\src\google\protobuf\io\zero_copy_stream_impl_lite.h include\google\protobuf\io\zero_copy_stream_impl_lite.h
+copy ..\src\google\protobuf\compiler\code_generator.h include\google\protobuf\compiler\code_generator.h
+copy ..\src\google\protobuf\compiler\command_line_interface.h include\google\protobuf\compiler\command_line_interface.h
+copy ..\src\google\protobuf\compiler\importer.h include\google\protobuf\compiler\importer.h
+copy ..\src\google\protobuf\compiler\parser.h include\google\protobuf\compiler\parser.h
+copy ..\src\google\protobuf\compiler\cpp\cpp_generator.h include\google\protobuf\compiler\cpp\cpp_generator.h
+copy ..\src\google\protobuf\compiler\java\java_generator.h include\google\protobuf\compiler\java\java_generator.h
+copy ..\src\google\protobuf\compiler\python\python_generator.h include\google\protobuf\compiler\python\python_generator.h
+copy ..\src\google\protobuf\compiler\plugin.h include\google\protobuf\compiler\plugin.h
diff --git a/protobuf/vsprojects/libprotobuf-lite.vcproj b/protobuf/vsprojects/libprotobuf-lite.vcproj
new file mode 100644
index 0000000..06b1598
--- /dev/null
+++ b/protobuf/vsprojects/libprotobuf-lite.vcproj
@@ -0,0 +1,302 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="libprotobuf-lite"
+	ProjectGUID="{49EA010D-706F-4BE2-A397-77854B72A040}"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="0"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="4"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				Optimization="0"
+				AdditionalIncludeDirectories="../src;."
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="4"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				AdditionalIncludeDirectories="../src;."
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\io\coded_stream.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\coded_stream_inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\common.h"
+				>
+			</File>
+			<File
+				RelativePath=".\config.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\extension_set.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\generated_message_util.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\hash.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\map-util.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\message_lite.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\once.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\atomicops.h"
+			>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h"
+			>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\platform_macros.h"
+			>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\repeated_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\stl_util.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\wire_format_lite.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\wire_format_lite_inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\stringprintf.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\template_util.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\type_traits.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\io\coded_stream.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\common.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\extension_set.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\generated_message_util.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\message_lite.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\once.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\repeated_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\wire_format_lite.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\stringprintf.cc"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/protobuf/vsprojects/libprotobuf.vcproj b/protobuf/vsprojects/libprotobuf.vcproj
new file mode 100644
index 0000000..1a488f7
--- /dev/null
+++ b/protobuf/vsprojects/libprotobuf.vcproj
@@ -0,0 +1,470 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="libprotobuf"
+	ProjectGUID="{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="0"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="4"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				Optimization="0"
+				AdditionalIncludeDirectories="../src;."
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="4"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				AdditionalIncludeDirectories="../src;."
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOBUF_EXPORTS;"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\io\coded_stream.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\coded_stream_inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\common.h"
+				>
+			</File>
+			<File
+				RelativePath=".\config.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\descriptor.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\descriptor.pb.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\descriptor_database.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\dynamic_message.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\extension_set.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\generated_message_reflection.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\generated_message_util.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\gzip_stream.h"
+				>
+			</File>
+			<File
+			        RelativePath="..\src\google\protobuf\io\strtod.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\hash.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\importer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\map_util.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\message.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\message_lite.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\atomicops.h"
+			>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.h"
+			>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\platform_macros.h"
+			>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\once.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\parser.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\printer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\reflection_ops.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\repeated_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\service.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\stl_util.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\stringprintf.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\template_util.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\type_traits.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\strutil.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\substitute.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\text_format.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\tokenizer.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\unknown_field_set.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\wire_format.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\wire_format_lite.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\wire_format_lite_inl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\io\coded_stream.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\common.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\descriptor.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\descriptor.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\descriptor_database.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\dynamic_message.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\extension_set.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\extension_set_heavy.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\generated_message_reflection.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\generated_message_util.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\gzip_stream.cc"
+				>
+			</File>
+			<File
+			        RelativePath="..\src\google\protobuf\io\strtod.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\importer.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\message.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\message_lite.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\once.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\atomicops_internals_x86_msvc.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\parser.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\printer.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\reflection_ops.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\repeated_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\service.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\structurally_valid.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\strutil.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\substitute.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\text_format.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\tokenizer.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\unknown_field_set.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\wire_format.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\wire_format_lite.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream_impl_lite.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\stringprintf.cc"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/protobuf/vsprojects/libprotoc.vcproj b/protobuf/vsprojects/libprotoc.vcproj
new file mode 100644
index 0000000..ccbc0b3
--- /dev/null
+++ b/protobuf/vsprojects/libprotoc.vcproj
@@ -0,0 +1,466 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="libprotoc"
+	ProjectGUID="{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="0"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="4"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				Optimization="0"
+				AdditionalIncludeDirectories="../src;."
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPROTOC_EXPORTS;"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="4"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				AdditionalIncludeDirectories="../src;."
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBPROTOC_EXPORTS;"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\code_generator.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\command_line_interface.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\subprocess.h"
+				>
+			</File>
+      <File
+        RelativePath="..\src\google\protobuf\compiler\zip_writer.h"
+        >
+      </File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\plugin.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\plugin.pb.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_extension.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_file.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_generator.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_helpers.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_options.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_primitive_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_service.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_string_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_context.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_enum.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_enum_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_extension.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_file.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_generator.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_generator_factory.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_helpers.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_lazy_message_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_message.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_message_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_name_resolver.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_primitive_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_service.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_shared_code_generator.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_string_field.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_doc_comment.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_doc_comment.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\python\python_generator.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\code_generator.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\command_line_interface.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\subprocess.cc"
+				>
+			</File>
+      <File
+        RelativePath="..\src\google\protobuf\compiler\zip_writer.cc"
+        >
+      </File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\plugin.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\plugin.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_enum_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_extension.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_file.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_generator.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_helpers.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_message_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_primitive_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_service.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_string_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_context.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_enum.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_enum_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_extension.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_file.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_generator.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_generator_factory.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_helpers.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_lazy_message_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_message.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_message_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_name_resolver.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_primitive_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_service.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_shared_code_generator.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_string_field.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\python\python_generator.cc"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/protobuf/vsprojects/lite-test.vcproj b/protobuf/vsprojects/lite-test.vcproj
new file mode 100644
index 0000000..0314b36
--- /dev/null
+++ b/protobuf/vsprojects/lite-test.vcproj
@@ -0,0 +1,305 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="lite-test"
+	ProjectGUID="{12015ACE-42BE-4952-A5A0-44A9A46908E2}"
+	RootNamespace="tests"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="0"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description=""
+				CommandLine=""
+				AdditionalDependencies=""
+				Outputs=""
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				Optimization="0"
+				AdditionalIncludeDirectories="../src;.;../gtest/include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_VARIADIC_MAX=10;"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description=""
+				CommandLine=""
+				AdditionalDependencies=""
+				Outputs=""
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				AdditionalIncludeDirectories="../src;.;../gtest/include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_VARIADIC_MAX=10;"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\test_util_lite.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_lite.pb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_import_lite.pb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_import_public_lite.pb.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\lite_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\test_util_lite.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_lite.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_import_lite.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_import_public_lite.pb.cc"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_lite.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_lite.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_lite.pb.h;google\protobuf\unittest_lite.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_lite.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_lite.pb.h;google\protobuf\unittest_lite.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_import_lite.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_import_lite.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_lite.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_import_lite.pb.h;google\protobuf\unittest_import_lite.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_import_lite.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_lite.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_import_lite.pb.h;google\protobuf\unittest_import_lite.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_import_public_lite.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_import_public_lite.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_public_lite.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_import_public_lite.pb.h;google\protobuf\unittest_import_public_lite.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_import_public_lite.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_public_lite.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_import_public_lite.pb.h;google\protobuf\unittest_import_public_lite.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/protobuf/vsprojects/protobuf.sln b/protobuf/vsprojects/protobuf.sln
new file mode 100644
index 0000000..567dee6
--- /dev/null
+++ b/protobuf/vsprojects/protobuf.sln
@@ -0,0 +1,92 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf", "libprotobuf.vcproj", "{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotoc", "libprotoc.vcproj", "{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}"
+	ProjectSection(ProjectDependencies) = postProject
+		{3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "protoc", "protoc.vcproj", "{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}
+		{3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcproj", "{4DF72760-C055-40A5-A77E-30A17E2AC2DB}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}
+		{3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}
+		{3AF54C8A-10BF-4332-9147-F68ED9862032} = {3AF54C8A-10BF-4332-9147-F68ED9862032}
+		{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32} = {CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}
+		{1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "..\gtest\msvc\gtest.vcproj", "{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest_main", "..\gtest\msvc\gtest_main.vcproj", "{3AF54C8A-10BF-4332-9147-F68ED9862032}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf-lite", "libprotobuf-lite.vcproj", "{49EA010D-706F-4BE2-A397-77854B72A040}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lite-test", "lite-test.vcproj", "{12015ACE-42BE-4952-A5A0-44A9A46908E2}"
+	ProjectSection(ProjectDependencies) = postProject
+		{49EA010D-706F-4BE2-A397-77854B72A040} = {49EA010D-706F-4BE2-A397-77854B72A040}
+		{1738D5F6-ED1E-47E0-B2F0-456864B93C1E} = {1738D5F6-ED1E-47E0-B2F0-456864B93C1E}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_plugin", "test_plugin.vcproj", "{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}"
+	ProjectSection(ProjectDependencies) = postProject
+		{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE} = {B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}
+		{3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}
+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7} = {C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.ActiveCfg = Debug|Win32
+		{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.Build.0 = Debug|Win32
+		{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.ActiveCfg = Release|Win32
+		{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.Build.0 = Release|Win32
+		{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Debug|Win32.Build.0 = Debug|Win32
+		{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.ActiveCfg = Release|Win32
+		{B84FF31A-5F9A-46F8-AB22-DBFC9BECE3BE}.Release|Win32.Build.0 = Release|Win32
+		{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Debug|Win32.Build.0 = Debug|Win32
+		{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.ActiveCfg = Release|Win32
+		{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}.Release|Win32.Build.0 = Release|Win32
+		{4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Debug|Win32.Build.0 = Debug|Win32
+		{4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.ActiveCfg = Release|Win32
+		{4DF72760-C055-40A5-A77E-30A17E2AC2DB}.Release|Win32.Build.0 = Release|Win32
+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Debug|Win32.Build.0 = Debug|Win32
+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.ActiveCfg = Release|Win32
+		{C8F6C172-56F2-4E76-B5FA-C3B423B31BE7}.Release|Win32.Build.0 = Release|Win32
+		{3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.ActiveCfg = Debug|Win32
+		{3AF54C8A-10BF-4332-9147-F68ED9862032}.Debug|Win32.Build.0 = Debug|Win32
+		{3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.ActiveCfg = Release|Win32
+		{3AF54C8A-10BF-4332-9147-F68ED9862032}.Release|Win32.Build.0 = Release|Win32
+		{49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.ActiveCfg = Debug|Win32
+		{49EA010D-706F-4BE2-A397-77854B72A040}.Debug|Win32.Build.0 = Debug|Win32
+		{49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.ActiveCfg = Release|Win32
+		{49EA010D-706F-4BE2-A397-77854B72A040}.Release|Win32.Build.0 = Release|Win32
+		{12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{12015ACE-42BE-4952-A5A0-44A9A46908E2}.Debug|Win32.Build.0 = Debug|Win32
+		{12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.ActiveCfg = Release|Win32
+		{12015ACE-42BE-4952-A5A0-44A9A46908E2}.Release|Win32.Build.0 = Release|Win32
+		{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Debug|Win32.Build.0 = Debug|Win32
+		{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.ActiveCfg = Release|Win32
+		{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/protobuf/vsprojects/protoc.vcproj b/protobuf/vsprojects/protoc.vcproj
new file mode 100644
index 0000000..17e8474
--- /dev/null
+++ b/protobuf/vsprojects/protoc.vcproj
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="protoc"
+	ProjectGUID="{1738D5F6-ED1E-47E0-B2F0-456864B93C1E}"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="0"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				Optimization="0"
+				AdditionalIncludeDirectories="../src;."
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				AdditionalIncludeDirectories="../src;."
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\main.cc"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/protobuf/vsprojects/readme.txt b/protobuf/vsprojects/readme.txt
new file mode 100644
index 0000000..288345a
--- /dev/null
+++ b/protobuf/vsprojects/readme.txt
@@ -0,0 +1,114 @@
+This directory contains project files for compiling Protocol Buffers using
+MSVC.  This is not the recommended way to do Protocol Buffer development --
+we prefer to develop under a Unix-like environment -- but it may be more
+accessible to those who primarily work with MSVC.
+
+Compiling and Installing
+========================
+
+1) Open protobuf.sln in Microsoft Visual Studio.
+2) Choose "Debug" or "Release" configuration as desired.*
+3) From the Build menu, choose "Build Solution".  Wait for compiling to finish.
+4) From a command shell, run tests.exe and lite-test.exe and check that all
+   tests pass.
+5) Run extract_includes.bat to copy all the public headers into a separate
+   "include" directory (under the top-level package directory).
+6) Copy the contents of the include directory to wherever you want to put
+   headers.
+7) Copy protoc.exe wherever you put build tools (probably somewhere in your
+   PATH).
+8) Copy libprotobuf.lib, libprotobuf-lite.lib, and libprotoc.lib wherever you
+   put libraries.
+
+* To avoid conflicts between the MSVC debug and release runtime libraries, when
+  compiling a debug build of your application, you may need to link against a
+  debug build of libprotobuf.lib.  Similarly, release builds should link against
+  release libs.
+
+DLLs vs. static linking
+=======================
+
+Static linking is now the default for the Protocol Buffer libraries.  Due to
+issues with Win32's use of a separate heap for each DLL, as well as binary
+compatibility issues between different versions of MSVC's STL library, it is
+recommended that you use static linkage only.  However, it is possible to
+build libprotobuf and libprotoc as DLLs if you really want.  To do this,
+do the following:
+
+  1) Open protobuf.sln in MSVC.
+  2) For each of the projects libprotobuf, libprotobuf-lite, and libprotoc, do
+     the following:
+    2a) Right-click the project and choose "properties".
+    2b) From the side bar, choose "General", under "Configuration Properties".
+    2c) Change the "Configuration Type" to "Dynamic Library (.dll)".
+    2d) From the side bar, choose "Preprocessor", under "C/C++".
+    2e) Add PROTOBUF_USE_DLLS to the list of preprocessor defines.
+  3) When compiling your project, make sure to #define PROTOBUF_USE_DLLS.
+
+When distributing your software to end users, we strongly recommend that you
+do NOT install libprotobuf.dll or libprotoc.dll to any shared location.
+Instead, keep these libraries next to your binaries, in your application's
+own install directory.  C++ makes it very difficult to maintain binary
+compatibility between releases, so it is likely that future versions of these
+libraries will *not* be usable as drop-in replacements.
+
+If your project is itself a DLL intended for use by third-party software, we
+recommend that you do NOT expose protocol buffer objects in your library's
+public interface, and that you statically link protocol buffers into your
+library.
+
+ZLib support
+============
+
+If you want to include GzipInputStream and GzipOutputStream
+(google/protobuf/io/gzip_stream.h) in libprotoc, you will need to do a few
+additional steps:
+
+1) Obtain a copy of the zlib library.  The pre-compiled DLL at zlib.net works.
+2) Make sure zlib's two headers are in your include path and that the .lib file
+   is in your library path.  You could place all three files directly into the
+   vsproject directory to compile libprotobuf, but they need to be visible to
+   your own project as well, so you should probably just put them into the
+   VC shared icnlude and library directories.
+3) Right-click on the "tests" project and choose "properties".  Navigate the
+   sidebar to "Configuration Properties" -> "Linker" -> "Input".
+4) Under "Additional Dependencies", add the name of the zlib .lib file (e.g.
+   zdll.lib).  Make sure to update both the Debug and Release configurations.
+5) If you are compiling libprotobuf and libprotoc as DLLs (see previous
+   section), repeat steps 2 and 3 for the libprotobuf and libprotoc projects.
+   If you are compiling them as static libraries, then you will need to link
+   against the zlib library directly from your own app.
+6) Edit config.h (in the vsprojects directory) and un-comment the line that
+   #defines HAVE_ZLIB.  (Or, alternatively, define this macro via the project
+   settings.)
+
+Notes on Compiler Warnings
+==========================
+
+The following warnings have been disabled while building the protobuf libraries
+and compiler.  You may have to disable some of them in your own project as
+well, or live with them.
+
+C4018 - 'expression' : signed/unsigned mismatch
+C4146 - unary minus operator applied to unsigned type, result still unsigned
+C4244 - Conversion from 'type1' to 'type2', possible loss of data.
+C4251 - 'identifier' : class 'type' needs to have dll-interface to be used by
+        clients of class 'type2'
+C4267 - Conversion from 'size_t' to 'type', possible loss of data.
+C4305 - 'identifier' : truncation from 'type1' to 'type2'
+C4355 - 'this' : used in base member initializer list
+C4800 - 'type' : forcing value to bool 'true' or 'false' (performance warning)
+C4996 - 'function': was declared deprecated
+
+C4251 is of particular note, if you are compiling the Protocol Buffer library
+as a DLL (see previous section).  The protocol buffer library uses templates in
+its public interfaces.  MSVC does not provide any reasonable way to export
+template classes from a DLL.  However, in practice, it appears that exporting
+templates is not necessary anyway.  Since the complete definition of any
+template is available in the header files, anyone importing the DLL will just
+end up compiling instances of the templates into their own binary.  The
+Protocol Buffer implementation does not rely on static template members being
+unique, so there should be no problem with this, but MSVC prints warning
+nevertheless.  So, we disable it.  Unfortunately, this warning will also be
+produced when compiling code which merely uses protocol buffers, meaning you
+may have to disable it in your code too.
diff --git a/protobuf/vsprojects/test_plugin.vcproj b/protobuf/vsprojects/test_plugin.vcproj
new file mode 100755
index 0000000..2dcf2ad
--- /dev/null
+++ b/protobuf/vsprojects/test_plugin.vcproj
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="test_plugin"
+	ProjectGUID="{CBBD34E5-02B0-40D5-B6D8-BFEA83E18B32}"
+	RootNamespace="test_plugin"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description=""
+				CommandLine=""
+				AdditionalDependencies=""
+				Outputs=""
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				Optimization="0"
+				AdditionalIncludeDirectories="../src;.;../gtest/include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_VARIADIC_MAX=10;"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description=""
+				CommandLine=""
+				AdditionalDependencies=""
+				Outputs=""
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				AdditionalIncludeDirectories="../src;.;../gtest/include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_VARIADIC_MAX=10;"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\mock_code_generator.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\testing\file.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\test_plugin.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\mock_code_generator.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\testing\file.cc"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/protobuf/vsprojects/tests.vcproj b/protobuf/vsprojects/tests.vcproj
new file mode 100644
index 0000000..fb815b5
--- /dev/null
+++ b/protobuf/vsprojects/tests.vcproj
@@ -0,0 +1,681 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="tests"
+	ProjectGUID="{4DF72760-C055-40A5-A77E-30A17E2AC2DB}"
+	RootNamespace="tests"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="0"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description=""
+				CommandLine=""
+				AdditionalDependencies=""
+				Outputs=""
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				Optimization="0"
+				AdditionalIncludeDirectories="../src;.;../gtest/include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_VARIADIC_MAX=10;"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+				Description=""
+				CommandLine=""
+				AdditionalDependencies=""
+				Outputs=""
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/wd4244 /wd4267 /wd4018 /wd4355 /wd4800 /wd4251 /wd4996 /wd4146 /wd4305"
+				AdditionalIncludeDirectories="../src;.;../gtest/include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_VARIADIC_MAX=10;"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="2"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\testing\file.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\testing\googletest.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\test_util.h"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\mock_code_generator.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest.pb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_custom_options.pb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_embed_optimize_for.pb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_import.pb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_import_public.pb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_lite_imports_nonline.pb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_mset.pb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_optimize_for.pb.h"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_no_generic_services.pb.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\src\google\protobuf\io\coded_stream_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\command_line_interface_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\mock_code_generator.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\common_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_bootstrap_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\cpp\cpp_plugin_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_plugin_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\java\java_doc_comment_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\python\python_plugin_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\descriptor_database_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\descriptor_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\dynamic_message_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\extension_set_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\testing\file.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\generated_message_reflection_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\testing\googletest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\importer_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\message_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\once_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\compiler\parser_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\printer_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\reflection_ops_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\repeated_field_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\repeated_field_reflection_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\structurally_valid_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\stringprintf_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\template_util_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\type_traits_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\stubs\strutil_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\test_util.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\text_format_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\tokenizer_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_custom_options.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_embed_optimize_for.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_import.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_import_public.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_lite_imports_nonlite.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_mset.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_optimize_for.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath=".\google\protobuf\unittest_no_generic_services.pb.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\unknown_field_set_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\wire_format_unittest.cc"
+				>
+			</File>
+			<File
+				RelativePath="..\src\google\protobuf\io\zero_copy_stream_unittest.cc"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath="..\src\google\protobuf\compiler\cpp\cpp_test_bad_identifiers.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating cpp_test_bad_identifiers.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h;google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating cpp_test_bad_identifiers.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.h;google\protobuf\compiler\cpp\cpp_test_bad_identifiers.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest.pb.h;google\protobuf\unittest.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest.pb.h;google\protobuf\unittest.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_custom_options.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_custom_options.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_custom_options.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_custom_options.pb.h;google\protobuf\unittest_custom_options.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_custom_options.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_custom_options.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_custom_options.pb.h;google\protobuf\unittest_custom_options.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_embed_optimize_for.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_embed_optimize_for.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_embed_optimize_for.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_embed_optimize_for.pb.h;google\protobuf\unittest_embed_optimize_for.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_embed_optimize_for.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_embed_optimize_for.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_embed_optimize_for.pb.h;google\protobuf\unittest_embed_optimize_for.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_import.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_import.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_import.pb.h;google\protobuf\unittest_import.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_import.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_import.pb.h;google\protobuf\unittest_import.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_import_public.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_import_public.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_public.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_import_public.pb.h;google\protobuf\unittest_import_public.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_import_public.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_import_public.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_import_public.pb.h;google\protobuf\unittest_import_public.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_lite_imports_nonlite.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_lite_imports_nonlite.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite_imports_nonlite.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_lite_imports_nonlite.pb.h;google\protobuf\unittest_lite_imports_nonlite.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_lite_imports_nonlite.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_lite_imports_nonlite.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_lite_imports_nonlite.pb.h;google\protobuf\unittest_lite_imports_nonlite.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_mset.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_mset.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_mset.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_mset.pb.h;google\protobuf\unittest_mset.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_mset.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_mset.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_mset.pb.h;google\protobuf\unittest_mset.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_optimize_for.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_optimize_for.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_optimize_for.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_optimize_for.pb.h;google\protobuf\unittest_optimize_for.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_optimize_for.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_optimize_for.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_optimize_for.pb.h;google\protobuf\unittest_optimize_for.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+		<File
+			RelativePath="..\src\google\protobuf\unittest_no_generic_services.proto"
+			>
+			<FileConfiguration
+				Name="Debug|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_no_generic_services.pb.{h,cc}..."
+					CommandLine="Debug\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_no_generic_services.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_no_generic_services.pb.h;google\protobuf\unittest_no_generic_services.pb.cc"
+				/>
+			</FileConfiguration>
+			<FileConfiguration
+				Name="Release|Win32"
+				>
+				<Tool
+					Name="VCCustomBuildTool"
+					Description="Generating unittest_no_generic_services.pb.{h,cc}..."
+					CommandLine="Release\protoc -I../src --cpp_out=. ../src/google/protobuf/unittest_no_generic_services.proto&#x0D;&#x0A;"
+					Outputs="google\protobuf\unittest_no_generic_services.pb.h;google\protobuf\unittest_no_generic_services.pb.cc"
+				/>
+			</FileConfiguration>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>